Completed
Push — master ( c9f7e7...e4067b )
by Alex
45s queued 16s
created
src/Former/Former.php 1 patch
Indentation   +486 added lines, -486 removed lines patch added patch discarded remove patch
@@ -14,490 +14,490 @@
 block discarded – undo
14 14
  */
15 15
 class Former
16 16
 {
17
-	// Instances
18
-	////////////////////////////////////////////////////////////////////
19
-
20
-
21
-	/**
22
-	 * The current environment
23
-	 *
24
-	 * @var \Illuminate\Container\Container
25
-	 */
26
-	protected $app;
27
-
28
-	/**
29
-	 * The Method Dispatcher
30
-	 *
31
-	 * @var MethodDispatcher
32
-	 */
33
-	protected $dispatch;
34
-
35
-	// Informations
36
-	////////////////////////////////////////////////////////////////////
37
-
38
-	/**
39
-	 * The form's errors
40
-	 *
41
-	 * @var Message
42
-	 */
43
-	protected $errors;
44
-
45
-	/**
46
-	 * An array of rules to use
47
-	 *
48
-	 * @var array
49
-	 */
50
-	protected $rules = array();
51
-
52
-	/**
53
-	 * An array of field macros
54
-	 *
55
-	 * @var array
56
-	 */
57
-	protected $macros = array();
58
-
59
-	/**
60
-	 * The labels created so far
61
-	 *
62
-	 * @var array
63
-	 */
64
-	public $labels = array();
65
-
66
-	/**
67
-	 * The IDs created so far
68
-	 *
69
-	 * @var array
70
-	 */
71
-	public $ids = array();
72
-
73
-	/**
74
-	 * A lookup table where the key is the input name,
75
-	 * and the value is number of times seen. This is
76
-	 * used to calculate unique ids.
77
-	 *
78
-	 * @var array
79
-	 */
80
-	public $names = array();
81
-
82
-	// Namespaces
83
-	////////////////////////////////////////////////////////////////////
84
-
85
-	/**
86
-	 * The namespace of Form elements
87
-	 */
88
-	const FORMSPACE = 'Former\Form\\';
89
-
90
-	/**
91
-	 * The namespace of fields
92
-	 */
93
-	const FIELDSPACE = 'Former\Form\Fields\\';
94
-
95
-	/**
96
-	 * Build a new Former instance
97
-	 *
98
-	 * @param Container        $app
99
-	 * @param MethodDispatcher $dispatcher
100
-	 */
101
-	public function __construct(Container $app, MethodDispatcher $dispatcher)
102
-	{
103
-		$this->app      = $app;
104
-		$this->dispatch = $dispatcher;
105
-	}
106
-
107
-	////////////////////////////////////////////////////////////////////
108
-	//////////////////////////// INTERFACE /////////////////////////////
109
-	////////////////////////////////////////////////////////////////////
110
-
111
-	/**
112
-	 * Acts as a router that redirects methods to all of Former classes
113
-	 *
114
-	 * @param  string $method     The method called
115
-	 * @param  array  $parameters An array of parameters
116
-	 *
117
-	 * @return mixed
118
-	 */
119
-	public function __call($method, $parameters)
120
-	{
121
-		// Dispatch to Form\Elements
122
-		// Explicitly check false since closeGroup() may return an empty string
123
-		if (($element = $this->dispatch->toElements($method, $parameters)) !== false) {
124
-			return $element;
125
-		}
126
-
127
-		// Dispatch to Form\Form
128
-		if ($form = $this->dispatch->toForm($method, $parameters)) {
129
-			$this->app->instance('former.form', $form);
130
-
131
-			return $this->app['former.form'];
132
-		}
133
-
134
-		// Dispatch to Form\Group
135
-		if ($group = $this->dispatch->toGroup($method, $parameters)) {
136
-			return $group;
137
-		}
138
-
139
-		// Dispatch to Form\Actions
140
-		if ($actions = $this->dispatch->toActions($method, $parameters)) {
141
-			return $actions;
142
-		}
143
-
144
-		// Dispatch to macros
145
-		if ($macro = $this->dispatch->toMacros($method, $parameters)) {
146
-			return $macro;
147
-		}
148
-
149
-		// Checking for any supplementary classes
150
-		$modifiers = explode('_', $method);
151
-		$method  = array_pop($modifiers);
152
-
153
-		// Dispatch to the different Form\Fields
154
-		$field     = $this->dispatch->toFields($method, $parameters);
155
-		$field->setModifiers($modifiers);
156
-		$field->addClass('');
157
-
158
-		// Else bind field
159
-		$this->app->instance('former.field', $field);
160
-
161
-		return $this->app['former.field'];
162
-	}
163
-
164
-	////////////////////////////////////////////////////////////////////
165
-	//////////////////////////////// MACROS ////////////////////////////
166
-	////////////////////////////////////////////////////////////////////
167
-
168
-	/**
169
-	 * Register a macro with Former
170
-	 *
171
-	 * @param  string   $name  The name of the macro
172
-	 * @param  Callable $macro The macro itself
173
-	 *
174
-	 * @return mixed
175
-	 */
176
-	public function macro($name, $macro)
177
-	{
178
-		$this->macros[$name] = $macro;
179
-	}
180
-
181
-	/**
182
-	 * Check if a macro exists
183
-	 *
184
-	 * @param  string $name
185
-	 *
186
-	 * @return boolean
187
-	 */
188
-	public function hasMacro($name)
189
-	{
190
-		return isset($this->macros[$name]);
191
-	}
192
-
193
-	/**
194
-	 * Get a registered macro
195
-	 *
196
-	 * @param  string $name
197
-	 *
198
-	 * @return Closure
199
-	 */
200
-	public function getMacro($name)
201
-	{
202
-		return $this->macros[$name];
203
-	}
204
-
205
-	////////////////////////////////////////////////////////////////////
206
-	///////////////////////////// POPULATOR ////////////////////////////
207
-	////////////////////////////////////////////////////////////////////
208
-
209
-	/**
210
-	 * Add values to populate the array
211
-	 *
212
-	 * @param mixed $values Can be an Eloquent object or an array
213
-	 */
214
-	public function populate($values)
215
-	{
216
-		$this->app['former.populator']->replace($values);
217
-	}
218
-
219
-	/**
220
-	 * Set the value of a particular field
221
-	 *
222
-	 * @param string $field The field's name
223
-	 * @param mixed  $value Its new value
224
-	 */
225
-	public function populateField($field, $value)
226
-	{
227
-		$this->app['former.populator']->put($field, $value);
228
-	}
229
-
230
-	/**
231
-	 * Get the value of a field
232
-	 *
233
-	 * @param string $field The field's name
234
-	 * @param null   $fallback
235
-	 *
236
-	 * @return mixed
237
-	 */
238
-	public function getValue($field, $fallback = null)
239
-	{
240
-		return $this->app['former.populator']->get($field, $fallback);
241
-	}
242
-
243
-	/**
244
-	 * Fetch a field value from both the new and old POST array
245
-	 *
246
-	 * @param  string $name     A field name
247
-	 * @param  string $fallback A fallback if nothing was found
248
-	 *
249
-	 * @return string           The results
250
-	 */
251
-	public function getPost($name, $fallback = null)
252
-	{
253
-		$name     = str_replace(array('[', ']'), array('.', ''), $name ?? '');
254
-		$name     = trim($name, '.');
255
-		$oldValue = $this->app['request']->old($name, $fallback);
256
-
257
-		return $this->app['request']->input($name, $oldValue, true);
258
-	}
259
-
260
-	////////////////////////////////////////////////////////////////////
261
-	////////////////////////////// TOOLKIT /////////////////////////////
262
-	////////////////////////////////////////////////////////////////////
263
-
264
-	/**
265
-	 * Set the errors to use for validations
266
-	 *
267
-	 * @param Message $validator The result from a validation
268
-	 *
269
-	 * @return  void
270
-	 */
271
-	public function withErrors($validator = null)
272
-	{
273
-		// Try to get the errors form the session
274
-		if ($this->app['session']->has('errors')) {
275
-			$this->errors = $this->app['session']->get('errors');
276
-		}
277
-
278
-		// If we're given a raw Validator, go fetch the errors in it
279
-		if ($validator instanceof Validator) {
280
-			$this->errors = $validator->getMessageBag();
281
-		} else {
282
-			if ($validator instanceof MessageBag) {
283
-				$this->errors = $validator;
284
-			}
285
-		}
286
-
287
-		return $this->errors;
288
-	}
289
-
290
-	/**
291
-	 * Add live validation rules
292
-	 *
293
-	 * @param  array *$rules An array of Laravel rules
294
-	 *
295
-	 * @return  void
296
-	 */
297
-	public function withRules()
298
-	{
299
-		$rules = call_user_func_array('array_merge', func_get_args());
300
-
301
-		// Parse the rules according to Laravel conventions
302
-		foreach ($rules as $name => $fieldRules) {
303
-			$expFieldRules = $fieldRules;
304
-			if (!is_array($expFieldRules)) {
305
-				if (is_object($expFieldRules)) {
306
-					continue;
307
-				}
308
-
309
-				$expFieldRules = explode('|', $expFieldRules);
310
-				$expFieldRules = array_map('trim', $expFieldRules);
311
-			}
312
-
313
-			foreach ($expFieldRules as $rule) {
314
-				if (is_object($rule)) {
315
-					continue;
316
-				}
317
-
318
-				$parameters = null;
319
-
320
-				if (($colon = strpos($rule, ':')) !== false) {
321
-					$rulename = substr($rule, 0, $colon);
322
-
323
-					/**
324
-					 * Regular expressions may contain commas and should not be divided by str_getcsv.
325
-					 * For regular expressions we are just using the complete expression as a parameter.
326
-					 */
327
-					if ($rulename !== 'regex') {
328
-						$parameters = str_getcsv(substr($rule, $colon + 1));
329
-					} else {
330
-						$parameters = [substr($rule, $colon + 1)];
331
-					}
332
-				}
333
-
334
-				// Exclude unsupported rules
335
-				$rule = is_numeric($colon) ? substr($rule, 0, $colon) : $rule;
336
-
337
-				// Store processed rule in Former's array
338
-				if (!isset($parameters)) {
339
-					$parameters = array();
340
-				}
341
-
342
-				$this->rules[$name][$rule] = $parameters;
343
-			}
344
-		}
345
-	}
346
-
347
-	/**
348
-	 * Switch the framework used by Former
349
-	 *
350
-	 * @param string $framework The name of the framework to use
351
-	 */
352
-	public function framework($framework = null)
353
-	{
354
-		if (!$framework) {
355
-			return $this->app['former.framework']->current();
356
-		}
357
-
358
-		$this->setOption('framework', $framework);
359
-
360
-		$framework = $this->getFrameworkInstance($framework);
361
-		$this->app->bind('former.framework', function ($app) use ($framework) {
362
-			return $framework;
363
-		});
364
-	}
365
-
366
-	/**
367
-	 * Get a new framework instance
368
-	 *
369
-	 * @param string $framework
370
-	 *
371
-	 * @throws Exceptions\InvalidFrameworkException
372
-	 * @return \Former\Interfaces\FrameworkInterface
373
-	 */
374
-	public function getFrameworkInstance($framework)
375
-	{
376
-		$formerClass = __NAMESPACE__.'\Framework\\'.$framework;
377
-
378
-		//get interfaces of the given framework
379
-		$interfaces = class_exists($framework) ? class_implements($framework) : array();
380
-
381
-		if(class_exists($formerClass)) {
382
-			$returnClass = $formerClass;
383
-		} elseif(class_exists($framework) && isset($interfaces['Former\Interfaces\FrameworkInterface'])) {
384
-			// We have some outside class, lets return it.
385
-			$returnClass = $framework;
386
-		} else {
387
-			throw (new InvalidFrameworkException())->setFramework($framework);
388
-		}
389
-
390
-		return new $returnClass($this->app);
391
-	}
392
-
393
-	/**
394
-	 * Get an option from the config
395
-	 *
396
-	 * @param string $option  The option
397
-	 * @param mixed  $default Optional fallback
398
-	 *
399
-	 * @return mixed
400
-	 */
401
-	public function getOption($option, $default = null)
402
-	{
403
-		return $this->app['config']->get('former.'.$option, $default);
404
-	}
405
-
406
-	/**
407
-	 * Set an option on the config
408
-	 *
409
-	 * @param string $option
410
-	 * @param string $value
411
-	 */
412
-	public function setOption($option, $value)
413
-	{
414
-		return $this->app['config']->set('former.'.$option, $value);
415
-	}
416
-
417
-	////////////////////////////////////////////////////////////////////
418
-	////////////////////////////// BUILDERS ////////////////////////////
419
-	////////////////////////////////////////////////////////////////////
420
-
421
-	/**
422
-	 * Closes a form
423
-	 *
424
-	 * @return string A form closing tag
425
-	 */
426
-	public function close()
427
-	{
428
-		if ($this->app->bound('former.form')) {
429
-			$closing = $this->app['former.form']->close();
430
-		}
431
-
432
-		// Destroy instances
433
-		$instances = array('former.form', 'former.form.framework');
434
-		foreach ($instances as $instance) {
435
-			$this->app[$instance] = null;
436
-			unset($this->app[$instance]);
437
-		}
438
-
439
-		// Reset populator
440
-		$this->app['former.populator']->reset();
441
-
442
-		// Reset all values
443
-		$this->errors = null;
444
-		$this->rules  = array();
445
-
446
-		return isset($closing) ? $closing : null;
447
-	}
448
-
449
-	////////////////////////////////////////////////////////////////////
450
-	////////////////////////////// HELPERS /////////////////////////////
451
-	////////////////////////////////////////////////////////////////////
452
-
453
-	/**
454
-	 * Get the errors for the current field
455
-	 *
456
-	 * @param  string $name A field name
457
-	 *
458
-	 * @return string       An error message
459
-	 */
460
-	public function getErrors($name = null)
461
-	{
462
-		// Get name and translate array notation
463
-		if (!$name and $this->app['former.field']) {
464
-			$name = $this->app['former.field']->getName();
465
-
466
-			// Always return empty string for anonymous fields (i.e. fields with no name/id)
467
-			if (!$name) {
468
-				return '';
469
-			}
470
-		}
471
-
472
-		if ($this->errors and $name) {
473
-			$name = str_replace(array('[', ']'), array('.', ''), $name);
474
-			$name = trim($name, '.');
475
-
476
-			return $this->errors->first($name);
477
-		}
478
-
479
-		return $this->errors;
480
-	}
481
-
482
-	/**
483
-	 * Get a rule from the Rules array
484
-	 *
485
-	 * @param  string $name The field to fetch
486
-	 *
487
-	 * @return array        An array of rules
488
-	 */
489
-	public function getRules($name)
490
-	{
491
-		// Check the rules for the name as given
492
-		$ruleset = Arr::get($this->rules, $name);
493
-
494
-		// If no rules found, convert to dot notation and try again
495
-		if (is_null($ruleset)) {
496
-			$name = str_replace(array('[', ']'), array('.', ''), $name);
497
-			$name = trim($name, '.');
498
-			$ruleset = Arr::get($this->rules, $name);
499
-		}
500
-
501
-		return $ruleset;
502
-	}
17
+    // Instances
18
+    ////////////////////////////////////////////////////////////////////
19
+
20
+
21
+    /**
22
+     * The current environment
23
+     *
24
+     * @var \Illuminate\Container\Container
25
+     */
26
+    protected $app;
27
+
28
+    /**
29
+     * The Method Dispatcher
30
+     *
31
+     * @var MethodDispatcher
32
+     */
33
+    protected $dispatch;
34
+
35
+    // Informations
36
+    ////////////////////////////////////////////////////////////////////
37
+
38
+    /**
39
+     * The form's errors
40
+     *
41
+     * @var Message
42
+     */
43
+    protected $errors;
44
+
45
+    /**
46
+     * An array of rules to use
47
+     *
48
+     * @var array
49
+     */
50
+    protected $rules = array();
51
+
52
+    /**
53
+     * An array of field macros
54
+     *
55
+     * @var array
56
+     */
57
+    protected $macros = array();
58
+
59
+    /**
60
+     * The labels created so far
61
+     *
62
+     * @var array
63
+     */
64
+    public $labels = array();
65
+
66
+    /**
67
+     * The IDs created so far
68
+     *
69
+     * @var array
70
+     */
71
+    public $ids = array();
72
+
73
+    /**
74
+     * A lookup table where the key is the input name,
75
+     * and the value is number of times seen. This is
76
+     * used to calculate unique ids.
77
+     *
78
+     * @var array
79
+     */
80
+    public $names = array();
81
+
82
+    // Namespaces
83
+    ////////////////////////////////////////////////////////////////////
84
+
85
+    /**
86
+     * The namespace of Form elements
87
+     */
88
+    const FORMSPACE = 'Former\Form\\';
89
+
90
+    /**
91
+     * The namespace of fields
92
+     */
93
+    const FIELDSPACE = 'Former\Form\Fields\\';
94
+
95
+    /**
96
+     * Build a new Former instance
97
+     *
98
+     * @param Container        $app
99
+     * @param MethodDispatcher $dispatcher
100
+     */
101
+    public function __construct(Container $app, MethodDispatcher $dispatcher)
102
+    {
103
+        $this->app      = $app;
104
+        $this->dispatch = $dispatcher;
105
+    }
106
+
107
+    ////////////////////////////////////////////////////////////////////
108
+    //////////////////////////// INTERFACE /////////////////////////////
109
+    ////////////////////////////////////////////////////////////////////
110
+
111
+    /**
112
+     * Acts as a router that redirects methods to all of Former classes
113
+     *
114
+     * @param  string $method     The method called
115
+     * @param  array  $parameters An array of parameters
116
+     *
117
+     * @return mixed
118
+     */
119
+    public function __call($method, $parameters)
120
+    {
121
+        // Dispatch to Form\Elements
122
+        // Explicitly check false since closeGroup() may return an empty string
123
+        if (($element = $this->dispatch->toElements($method, $parameters)) !== false) {
124
+            return $element;
125
+        }
126
+
127
+        // Dispatch to Form\Form
128
+        if ($form = $this->dispatch->toForm($method, $parameters)) {
129
+            $this->app->instance('former.form', $form);
130
+
131
+            return $this->app['former.form'];
132
+        }
133
+
134
+        // Dispatch to Form\Group
135
+        if ($group = $this->dispatch->toGroup($method, $parameters)) {
136
+            return $group;
137
+        }
138
+
139
+        // Dispatch to Form\Actions
140
+        if ($actions = $this->dispatch->toActions($method, $parameters)) {
141
+            return $actions;
142
+        }
143
+
144
+        // Dispatch to macros
145
+        if ($macro = $this->dispatch->toMacros($method, $parameters)) {
146
+            return $macro;
147
+        }
148
+
149
+        // Checking for any supplementary classes
150
+        $modifiers = explode('_', $method);
151
+        $method  = array_pop($modifiers);
152
+
153
+        // Dispatch to the different Form\Fields
154
+        $field     = $this->dispatch->toFields($method, $parameters);
155
+        $field->setModifiers($modifiers);
156
+        $field->addClass('');
157
+
158
+        // Else bind field
159
+        $this->app->instance('former.field', $field);
160
+
161
+        return $this->app['former.field'];
162
+    }
163
+
164
+    ////////////////////////////////////////////////////////////////////
165
+    //////////////////////////////// MACROS ////////////////////////////
166
+    ////////////////////////////////////////////////////////////////////
167
+
168
+    /**
169
+     * Register a macro with Former
170
+     *
171
+     * @param  string   $name  The name of the macro
172
+     * @param  Callable $macro The macro itself
173
+     *
174
+     * @return mixed
175
+     */
176
+    public function macro($name, $macro)
177
+    {
178
+        $this->macros[$name] = $macro;
179
+    }
180
+
181
+    /**
182
+     * Check if a macro exists
183
+     *
184
+     * @param  string $name
185
+     *
186
+     * @return boolean
187
+     */
188
+    public function hasMacro($name)
189
+    {
190
+        return isset($this->macros[$name]);
191
+    }
192
+
193
+    /**
194
+     * Get a registered macro
195
+     *
196
+     * @param  string $name
197
+     *
198
+     * @return Closure
199
+     */
200
+    public function getMacro($name)
201
+    {
202
+        return $this->macros[$name];
203
+    }
204
+
205
+    ////////////////////////////////////////////////////////////////////
206
+    ///////////////////////////// POPULATOR ////////////////////////////
207
+    ////////////////////////////////////////////////////////////////////
208
+
209
+    /**
210
+     * Add values to populate the array
211
+     *
212
+     * @param mixed $values Can be an Eloquent object or an array
213
+     */
214
+    public function populate($values)
215
+    {
216
+        $this->app['former.populator']->replace($values);
217
+    }
218
+
219
+    /**
220
+     * Set the value of a particular field
221
+     *
222
+     * @param string $field The field's name
223
+     * @param mixed  $value Its new value
224
+     */
225
+    public function populateField($field, $value)
226
+    {
227
+        $this->app['former.populator']->put($field, $value);
228
+    }
229
+
230
+    /**
231
+     * Get the value of a field
232
+     *
233
+     * @param string $field The field's name
234
+     * @param null   $fallback
235
+     *
236
+     * @return mixed
237
+     */
238
+    public function getValue($field, $fallback = null)
239
+    {
240
+        return $this->app['former.populator']->get($field, $fallback);
241
+    }
242
+
243
+    /**
244
+     * Fetch a field value from both the new and old POST array
245
+     *
246
+     * @param  string $name     A field name
247
+     * @param  string $fallback A fallback if nothing was found
248
+     *
249
+     * @return string           The results
250
+     */
251
+    public function getPost($name, $fallback = null)
252
+    {
253
+        $name     = str_replace(array('[', ']'), array('.', ''), $name ?? '');
254
+        $name     = trim($name, '.');
255
+        $oldValue = $this->app['request']->old($name, $fallback);
256
+
257
+        return $this->app['request']->input($name, $oldValue, true);
258
+    }
259
+
260
+    ////////////////////////////////////////////////////////////////////
261
+    ////////////////////////////// TOOLKIT /////////////////////////////
262
+    ////////////////////////////////////////////////////////////////////
263
+
264
+    /**
265
+     * Set the errors to use for validations
266
+     *
267
+     * @param Message $validator The result from a validation
268
+     *
269
+     * @return  void
270
+     */
271
+    public function withErrors($validator = null)
272
+    {
273
+        // Try to get the errors form the session
274
+        if ($this->app['session']->has('errors')) {
275
+            $this->errors = $this->app['session']->get('errors');
276
+        }
277
+
278
+        // If we're given a raw Validator, go fetch the errors in it
279
+        if ($validator instanceof Validator) {
280
+            $this->errors = $validator->getMessageBag();
281
+        } else {
282
+            if ($validator instanceof MessageBag) {
283
+                $this->errors = $validator;
284
+            }
285
+        }
286
+
287
+        return $this->errors;
288
+    }
289
+
290
+    /**
291
+     * Add live validation rules
292
+     *
293
+     * @param  array *$rules An array of Laravel rules
294
+     *
295
+     * @return  void
296
+     */
297
+    public function withRules()
298
+    {
299
+        $rules = call_user_func_array('array_merge', func_get_args());
300
+
301
+        // Parse the rules according to Laravel conventions
302
+        foreach ($rules as $name => $fieldRules) {
303
+            $expFieldRules = $fieldRules;
304
+            if (!is_array($expFieldRules)) {
305
+                if (is_object($expFieldRules)) {
306
+                    continue;
307
+                }
308
+
309
+                $expFieldRules = explode('|', $expFieldRules);
310
+                $expFieldRules = array_map('trim', $expFieldRules);
311
+            }
312
+
313
+            foreach ($expFieldRules as $rule) {
314
+                if (is_object($rule)) {
315
+                    continue;
316
+                }
317
+
318
+                $parameters = null;
319
+
320
+                if (($colon = strpos($rule, ':')) !== false) {
321
+                    $rulename = substr($rule, 0, $colon);
322
+
323
+                    /**
324
+                     * Regular expressions may contain commas and should not be divided by str_getcsv.
325
+                     * For regular expressions we are just using the complete expression as a parameter.
326
+                     */
327
+                    if ($rulename !== 'regex') {
328
+                        $parameters = str_getcsv(substr($rule, $colon + 1));
329
+                    } else {
330
+                        $parameters = [substr($rule, $colon + 1)];
331
+                    }
332
+                }
333
+
334
+                // Exclude unsupported rules
335
+                $rule = is_numeric($colon) ? substr($rule, 0, $colon) : $rule;
336
+
337
+                // Store processed rule in Former's array
338
+                if (!isset($parameters)) {
339
+                    $parameters = array();
340
+                }
341
+
342
+                $this->rules[$name][$rule] = $parameters;
343
+            }
344
+        }
345
+    }
346
+
347
+    /**
348
+     * Switch the framework used by Former
349
+     *
350
+     * @param string $framework The name of the framework to use
351
+     */
352
+    public function framework($framework = null)
353
+    {
354
+        if (!$framework) {
355
+            return $this->app['former.framework']->current();
356
+        }
357
+
358
+        $this->setOption('framework', $framework);
359
+
360
+        $framework = $this->getFrameworkInstance($framework);
361
+        $this->app->bind('former.framework', function ($app) use ($framework) {
362
+            return $framework;
363
+        });
364
+    }
365
+
366
+    /**
367
+     * Get a new framework instance
368
+     *
369
+     * @param string $framework
370
+     *
371
+     * @throws Exceptions\InvalidFrameworkException
372
+     * @return \Former\Interfaces\FrameworkInterface
373
+     */
374
+    public function getFrameworkInstance($framework)
375
+    {
376
+        $formerClass = __NAMESPACE__.'\Framework\\'.$framework;
377
+
378
+        //get interfaces of the given framework
379
+        $interfaces = class_exists($framework) ? class_implements($framework) : array();
380
+
381
+        if(class_exists($formerClass)) {
382
+            $returnClass = $formerClass;
383
+        } elseif(class_exists($framework) && isset($interfaces['Former\Interfaces\FrameworkInterface'])) {
384
+            // We have some outside class, lets return it.
385
+            $returnClass = $framework;
386
+        } else {
387
+            throw (new InvalidFrameworkException())->setFramework($framework);
388
+        }
389
+
390
+        return new $returnClass($this->app);
391
+    }
392
+
393
+    /**
394
+     * Get an option from the config
395
+     *
396
+     * @param string $option  The option
397
+     * @param mixed  $default Optional fallback
398
+     *
399
+     * @return mixed
400
+     */
401
+    public function getOption($option, $default = null)
402
+    {
403
+        return $this->app['config']->get('former.'.$option, $default);
404
+    }
405
+
406
+    /**
407
+     * Set an option on the config
408
+     *
409
+     * @param string $option
410
+     * @param string $value
411
+     */
412
+    public function setOption($option, $value)
413
+    {
414
+        return $this->app['config']->set('former.'.$option, $value);
415
+    }
416
+
417
+    ////////////////////////////////////////////////////////////////////
418
+    ////////////////////////////// BUILDERS ////////////////////////////
419
+    ////////////////////////////////////////////////////////////////////
420
+
421
+    /**
422
+     * Closes a form
423
+     *
424
+     * @return string A form closing tag
425
+     */
426
+    public function close()
427
+    {
428
+        if ($this->app->bound('former.form')) {
429
+            $closing = $this->app['former.form']->close();
430
+        }
431
+
432
+        // Destroy instances
433
+        $instances = array('former.form', 'former.form.framework');
434
+        foreach ($instances as $instance) {
435
+            $this->app[$instance] = null;
436
+            unset($this->app[$instance]);
437
+        }
438
+
439
+        // Reset populator
440
+        $this->app['former.populator']->reset();
441
+
442
+        // Reset all values
443
+        $this->errors = null;
444
+        $this->rules  = array();
445
+
446
+        return isset($closing) ? $closing : null;
447
+    }
448
+
449
+    ////////////////////////////////////////////////////////////////////
450
+    ////////////////////////////// HELPERS /////////////////////////////
451
+    ////////////////////////////////////////////////////////////////////
452
+
453
+    /**
454
+     * Get the errors for the current field
455
+     *
456
+     * @param  string $name A field name
457
+     *
458
+     * @return string       An error message
459
+     */
460
+    public function getErrors($name = null)
461
+    {
462
+        // Get name and translate array notation
463
+        if (!$name and $this->app['former.field']) {
464
+            $name = $this->app['former.field']->getName();
465
+
466
+            // Always return empty string for anonymous fields (i.e. fields with no name/id)
467
+            if (!$name) {
468
+                return '';
469
+            }
470
+        }
471
+
472
+        if ($this->errors and $name) {
473
+            $name = str_replace(array('[', ']'), array('.', ''), $name);
474
+            $name = trim($name, '.');
475
+
476
+            return $this->errors->first($name);
477
+        }
478
+
479
+        return $this->errors;
480
+    }
481
+
482
+    /**
483
+     * Get a rule from the Rules array
484
+     *
485
+     * @param  string $name The field to fetch
486
+     *
487
+     * @return array        An array of rules
488
+     */
489
+    public function getRules($name)
490
+    {
491
+        // Check the rules for the name as given
492
+        $ruleset = Arr::get($this->rules, $name);
493
+
494
+        // If no rules found, convert to dot notation and try again
495
+        if (is_null($ruleset)) {
496
+            $name = str_replace(array('[', ']'), array('.', ''), $name);
497
+            $name = trim($name, '.');
498
+            $ruleset = Arr::get($this->rules, $name);
499
+        }
500
+
501
+        return $ruleset;
502
+    }
503 503
 }
Please login to merge, or discard this patch.
src/Former/Form/Group.php 1 patch
Indentation   +551 added lines, -551 removed lines patch added patch discarded remove patch
@@ -14,555 +14,555 @@
 block discarded – undo
14 14
  */
15 15
 class Group extends Tag
16 16
 {
17
-	/**
18
-	 * The Container
19
-	 *
20
-	 * @var Container
21
-	 */
22
-	protected $app;
23
-
24
-	/**
25
-	 * The current state of the group
26
-	 *
27
-	 * @var string
28
-	 */
29
-	protected $state = null;
30
-
31
-	/**
32
-	 * Whether the field should be displayed raw or not
33
-	 *
34
-	 * @var boolean
35
-	 */
36
-	protected $raw = false;
37
-
38
-	/**
39
-	 * The group label
40
-	 *
41
-	 * @var Element
42
-	 */
43
-	protected $label;
44
-
45
-	/**
46
-	 * The group help
47
-	 *
48
-	 * @var array
49
-	 */
50
-	protected $help = array();
51
-
52
-	/**
53
-	 * An array of elements to preprend the field
54
-	 *
55
-	 * @var array
56
-	 */
57
-	protected $prepend = array();
58
-
59
-	/**
60
-	 * An array of elements to append the field
61
-	 *
62
-	 * @var array
63
-	 */
64
-	protected $append = array();
65
-
66
-	/**
67
-	 * The field validations to be checked for errors
68
-	 *
69
-	 * @var array
70
-	 */
71
-	protected $validations = array();
72
-
73
-	/**
74
-	 * The group's element
75
-	 *
76
-	 * @var string
77
-	 */
78
-	protected $element = 'div';
79
-
80
-	/**
81
-	 * Whether a custom group is opened or not
82
-	 *
83
-	 * @var boolean
84
-	 */
85
-	public static $opened = false;
86
-
87
-	/**
88
-	 * The custom group that is open
89
-	 *
90
-	 * @var Former\Form\Group
91
-	 */
92
-	public static $openGroup = null;
93
-
94
-	////////////////////////////////////////////////////////////////////
95
-	/////////////////////////// CORE METHODS ///////////////////////////
96
-	////////////////////////////////////////////////////////////////////
97
-
98
-	/**
99
-	 * Creates a group
100
-	 *
101
-	 * @param string $label Its label
102
-	 */
103
-	public function __construct(Container $app, $label, $validations = null)
104
-	{
105
-		// Get special classes
106
-		$this->app = $app;
107
-		$this->addClass($this->app['former.framework']->getGroupClasses());
108
-
109
-		// Invisible if Nude
110
-		if ($this->app['former.framework']->is('Nude')) {
111
-			$this->element = '';
112
-		}
113
-
114
-		// Set group label
115
-		if ($label) {
116
-			$this->setLabel($label);
117
-		}
118
-
119
-		// Set validations used to override groups own conclusions
120
-		$this->validations = (array) $validations;
121
-	}
122
-
123
-	/**
124
-	 * Prints out the opening of the Control Group
125
-	 *
126
-	 * @return string A control group opening tag
127
-	 */
128
-	public function __toString()
129
-	{
130
-		return $this->open().$this->getFormattedLabel();
131
-	}
132
-
133
-	/**
134
-	 * Opens a group
135
-	 *
136
-	 * @return string Opening tag
137
-	 */
138
-	public function open()
139
-	{
140
-		if ($this->getErrors()) {
141
-			$this->state($this->app['former.framework']->errorState());
142
-		}
143
-
144
-		// Retrieve state and append it to classes
145
-		if ($this->state) {
146
-			$this->addClass($this->state);
147
-		}
148
-
149
-		// Required state
150
-		if ($this->app->bound('former.field') and $this->app['former.field']->isRequired()) {
151
-			$this->addClass($this->app['former']->getOption('required_class'));
152
-		}
153
-
154
-		return parent::open();
155
-	}
156
-
157
-	/**
158
-	 * Set the contents of the current group
159
-	 *
160
-	 * @param string $contents The group contents
161
-	 *
162
-	 * @return string A group
163
-	 */
164
-	public function contents($contents)
165
-	{
166
-		return $this->wrap($contents, $this->getFormattedLabel());
167
-	}
168
-
169
-	/**
170
-	 * Wrap a Field with the current group
171
-	 *
172
-	 * @param  \Former\Traits\Field $field A Field instance
173
-	 *
174
-	 * @return string        A group
175
-	 */
176
-	public function wrapField($field)
177
-	{
178
-		$label = $this->getLabel($field);
179
-		$help = $this->getHelp();
180
-		if ($field->isCheckable() &&
181
-			in_array($this->app['former']->framework(), ['TwitterBootstrap4', 'TwitterBootstrap5'])
182
-		) {
183
-			$wrapperClass = null;
184
-			if ($this->app['former']->framework() === 'TwitterBootstrap4') {
185
-				$wrapperClass = $field->isInline() ? 'form-check form-check-inline' : 'form-check';
186
-			}
187
-			if ($this->app['former']->getErrors($field->getName())) {
188
-				$hiddenInput = Input::create('hidden')->addClass('form-check-input is-invalid');
189
-				$help = $hiddenInput.$help;
190
-			}
191
-			$help = $help ? Element::create('div', $help)->addClass($wrapperClass) : '';
192
-		}
193
-		$withFloatingLabel = $field->withFloatingLabel();
194
-
195
-		$field = $this->prependAppend($field);
196
-		$field .= $help;
197
-
198
-		if ($withFloatingLabel &&
199
-			$this->app['former']->framework() === 'TwitterBootstrap5'
200
-		) {
201
-			return $this->wrapWithFloatingLabel($field, $label);
202
-		}
203
-
204
-		return $this->wrap($field, $label);
205
-	}
206
-
207
-	////////////////////////////////////////////////////////////////////
208
-	//////////////////////////// FIELD METHODS /////////////////////////
209
-	////////////////////////////////////////////////////////////////////
210
-
211
-	/**
212
-	 * Set the state of the group
213
-	 *
214
-	 * @param  string $state A Bootstrap state class
215
-	 */
216
-	public function state($state)
217
-	{
218
-		// Filter state
219
-		$state = $this->app['former.framework']->filterState($state);
220
-
221
-		$this->state = $state;
222
-	}
223
-
224
-	/**
225
-	 * Set a class on the Group
226
-	 *
227
-	 * @param string $class The class(es) to add on the Group
228
-	 */
229
-	public function addGroupClass($class)
230
-	{
231
-		$this->addClass($class);
232
-	}
233
-
234
-	/**
235
-	 * Remove one or more classes on the Group
236
-	 *
237
-	 * @param string $class The class(es) to remove on the Group
238
-	 */
239
-	public function removeGroupClass($class)
240
-	{
241
-		$this->removeClass($class);
242
-	}
243
-
244
-	/**
245
-	 * Set a class on the Label
246
-	 *
247
-	 * @param string $class The class(es) to add on the Label
248
-	 */
249
-	public function addLabelClass($class)
250
-	{
251
-		// Don't add a label class if it isn't an Element instance
252
-		if (!$this->label instanceof Element) {
253
-			return $this;
254
-		}
255
-
256
-		$this->label->addClass($class);
257
-
258
-		return $this;
259
-	}
260
-
261
-	/**
262
-	 * Remove one or more classes on the Label
263
-	 *
264
-	 * @param string $class The class(es) to remove on the Label
265
-	 */
266
-	public function removeLabelClass($class)
267
-	{
268
-		// Don't remove a label class if it isn't an Element instance
269
-		if (!$this->label instanceof Element) {
270
-			return $this;
271
-		}
272
-
273
-		$this->label->removeClass($class);
274
-
275
-		return $this;
276
-	}
277
-
278
-	/**
279
-	 * Adds a label to the group
280
-	 *
281
-	 * @param  string $label A label
282
-	 */
283
-	public function setLabel($label)
284
-	{
285
-		if (!$label instanceof Element) {
286
-			$label = Helpers::translate($label);
287
-			$label = Element::create('label', $label)->for($label);
288
-		}
289
-
290
-		$this->label = $label;
291
-	}
292
-
293
-	/**
294
-	 * Get the formatted group label
295
-	 *
296
-	 * @return string|null
297
-	 */
298
-	public function getFormattedLabel()
299
-	{
300
-		if (!$this->label) {
301
-			return false;
302
-		}
303
-
304
-		return $this->label->addClass($this->app['former.framework']->getLabelClasses());
305
-	}
306
-
307
-	/**
308
-	 * Disables the control group for the current field
309
-	 */
310
-	public function raw()
311
-	{
312
-		$this->raw = true;
313
-	}
314
-
315
-	/**
316
-	 * Check if the current group is to be displayed or not
317
-	 *
318
-	 * @return boolean
319
-	 */
320
-	public function isRaw()
321
-	{
322
-		return (bool) $this->raw;
323
-	}
324
-
325
-	////////////////////////////////////////////////////////////////////
326
-	///////////////////////////// HELP BLOCKS //////////////////////////
327
-	////////////////////////////////////////////////////////////////////
328
-
329
-	/**
330
-	 * Alias for inlineHelp
331
-	 *
332
-	 * @param  string $help       The help text
333
-	 * @param  array  $attributes Facultative attributes
334
-	 */
335
-	public function help($help, $attributes = array())
336
-	{
337
-		return $this->inlineHelp($help, $attributes);
338
-	}
339
-
340
-	/**
341
-	 * Add an inline help
342
-	 *
343
-	 * @param  string $help       The help text
344
-	 * @param  array  $attributes Facultative attributes
345
-	 */
346
-	public function inlineHelp($help, $attributes = array())
347
-	{
348
-		// If no help text, do nothing
349
-		if (!$help) {
350
-			return false;
351
-		}
352
-
353
-		$this->help['inline'] = $this->app['former.framework']->createHelp($help, $attributes);
354
-	}
355
-
356
-	/**
357
-	 * Add an block help
358
-	 *
359
-	 * @param  string $help       The help text
360
-	 * @param  array  $attributes Facultative attributes
361
-	 */
362
-	public function blockHelp($help, $attributes = array())
363
-	{
364
-		// Reserved method
365
-		if ($this->app['former.framework']->isnt('TwitterBootstrap') &&
366
-			$this->app['former.framework']->isnt('TwitterBootstrap3') &&
367
-			$this->app['former.framework']->isnt('TwitterBootstrap4') &&
368
-			$this->app['former.framework']->isnt('TwitterBootstrap5')
369
-		) {
370
-			throw new BadMethodCallException('This method is only available on the Bootstrap framework');
371
-		}
372
-
373
-		// If no help text, do nothing
374
-		if (!$help) {
375
-			return false;
376
-		}
377
-
378
-		$this->help['block'] = $this->app['former.framework']->createBlockHelp($help, $attributes);
379
-	}
380
-
381
-	////////////////////////////////////////////////////////////////////
382
-	///////////////////////// PREPEND/APPEND METHODS ///////////////////
383
-	////////////////////////////////////////////////////////////////////
384
-
385
-	/**
386
-	 * Prepend elements to the field
387
-	 */
388
-	public function prepend()
389
-	{
390
-		$this->placeAround(func_get_args(), 'prepend');
391
-	}
392
-
393
-	/**
394
-	 * Append elements to the field
395
-	 */
396
-	public function append()
397
-	{
398
-		$this->placeAround(func_get_args(), 'append');
399
-	}
400
-
401
-	/**
402
-	 * Prepends an icon to a field
403
-	 *
404
-	 * @param string $icon       The icon to prepend
405
-	 * @param array  $attributes Its attributes
406
-	 */
407
-	public function prependIcon($icon, $attributes = array(), $iconSettings = array())
408
-	{
409
-		$icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
410
-
411
-		$this->prepend($icon);
412
-	}
413
-
414
-	/**
415
-	 * Append an icon to a field
416
-	 *
417
-	 * @param string $icon       The icon to prepend
418
-	 * @param array  $attributes Its attributes
419
-	 */
420
-	public function appendIcon($icon, $attributes = array(), $iconSettings = array())
421
-	{
422
-		$icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
423
-
424
-		$this->append($icon);
425
-	}
426
-
427
-	////////////////////////////////////////////////////////////////////
428
-	//////////////////////////////// HELPERS ///////////////////////////
429
-	////////////////////////////////////////////////////////////////////
430
-
431
-	/**
432
-	 * Get the errors for the group
433
-	 *
434
-	 * @return string
435
-	 */
436
-	public function getErrors()
437
-	{
438
-		$errors = '';
439
-
440
-		if (!self::$opened) {
441
-
442
-			// for non-custom groups, normal error handling applies
443
-			$errors = $this->app['former']->getErrors();
444
-		} elseif (!empty($this->validations)) {
445
-
446
-			// error handling only when validations specified for custom groups
447
-			foreach ($this->validations as $validation) {
448
-				$errors .= $this->app['former']->getErrors($validation);
449
-			}
450
-		}
451
-
452
-		return $errors;
453
-	}
454
-
455
-	/**
456
-	 * Wraps content in a group
457
-	 *
458
-	 * @param string $contents The content
459
-	 * @param string $label    The label to add
460
-	 *
461
-	 * @return string A group
462
-	 */
463
-	public function wrap($contents, $label = null)
464
-	{
465
-		$group = $this->open();
466
-		$group .= $label;
467
-		$group .= $this->app['former.framework']->wrapField($contents);
468
-		$group .= $this->close();
469
-
470
-		return $group;
471
-	}
472
-
473
-	/**
474
-	 * Wraps content in a group with floating label
475
-	 *
476
-	 * @param string $contents The content
477
-	 * @param string $label    The label to add
478
-	 *
479
-	 * @return string A group
480
-	 */
481
-	public function wrapWithFloatingLabel($contents, $label = null)
482
-	{
483
-		$floatingLabelClass = $this->app['former.framework']->getFloatingLabelClass();
484
-		if ($floatingLabelClass) {
485
-			$this->addClass($floatingLabelClass);
486
-		}
487
-		return $this->wrap($label, $contents);
488
-	}
489
-
490
-	/**
491
-	 * Prints out the current label
492
-	 *
493
-	 * @param  string $field The field to create a label for
494
-	 *
495
-	 * @return string        A <label> tag
496
-	 */
497
-	 protected function getLabel($field = null)
498
- 	{
499
- 		// Don't create a label if none exist
500
- 		if (!$field or !$this->label) {
501
- 			return null;
502
- 		}
503
-
504
- 		// Wrap label in framework classes
505
- 		$labelClasses = $this->app['former.framework']->getLabelClasses();
506
- 		if ($field->isCheckable() &&
507
- 			in_array($this->app['former']->framework(), ['TwitterBootstrap4', 'TwitterBootstrap5']) &&
508
- 			$this->app['former.form']->isOfType('horizontal')
509
- 		) {
510
- 			$labelClasses = array_merge($labelClasses, array('pt-0'));
511
- 		}
512
- 		$this->label->addClass($labelClasses);
513
- 		$this->label = $this->app['former.framework']->createLabelOf($field, $this->label);
514
- 		$this->label = $this->app['former.framework']->wrapLabel($this->label);
515
-
516
- 		return $this->label;
517
- 	}
518
-
519
-	/**
520
-	 * Prints out the current help
521
-	 *
522
-	 * @return string A .help-block or .help-inline
523
-	 */
524
-	protected function getHelp()
525
-	{
526
-		$inline = Arr::get($this->help, 'inline');
527
-		$block  = Arr::get($this->help, 'block');
528
-
529
-		// Replace help text with error if any found
530
-		$errors = $this->app['former']->getErrors();
531
-		if ($errors and $this->app['former']->getOption('error_messages')) {
532
-			$inline = $this->app['former.framework']->createValidationError($errors);
533
-		}
534
-
535
-		return implode('', array($inline, $block));
536
-	}
537
-
538
-	/**
539
-	 * Format the field with prepended/appended elements
540
-	 *
541
-	 * @param  Field $field The field to format
542
-	 *
543
-	 * @return string        Field plus supplementary elements
544
-	 */
545
-	protected function prependAppend($field)
546
-	{
547
-		if (!$this->prepend and !$this->append) {
548
-			return $field->render();
549
-		}
550
-
551
-		return $this->app['former.framework']->prependAppend($field, $this->prepend, $this->append);
552
-	}
553
-
554
-	/**
555
-	 * Place elements around the field
556
-	 *
557
-	 * @param  array  $items An array of items to place
558
-	 * @param  string $place Where they should end up (prepend|append)
559
-	 */
560
-	protected function placeAround($items, $place)
561
-	{
562
-		// Iterate over the items and place them where they should
563
-		foreach ((array) $items as $item) {
564
-			$item             = $this->app['former.framework']->placeAround($item, $place);
565
-			$this->{$place}[] = $item;
566
-		}
567
-	}
17
+    /**
18
+     * The Container
19
+     *
20
+     * @var Container
21
+     */
22
+    protected $app;
23
+
24
+    /**
25
+     * The current state of the group
26
+     *
27
+     * @var string
28
+     */
29
+    protected $state = null;
30
+
31
+    /**
32
+     * Whether the field should be displayed raw or not
33
+     *
34
+     * @var boolean
35
+     */
36
+    protected $raw = false;
37
+
38
+    /**
39
+     * The group label
40
+     *
41
+     * @var Element
42
+     */
43
+    protected $label;
44
+
45
+    /**
46
+     * The group help
47
+     *
48
+     * @var array
49
+     */
50
+    protected $help = array();
51
+
52
+    /**
53
+     * An array of elements to preprend the field
54
+     *
55
+     * @var array
56
+     */
57
+    protected $prepend = array();
58
+
59
+    /**
60
+     * An array of elements to append the field
61
+     *
62
+     * @var array
63
+     */
64
+    protected $append = array();
65
+
66
+    /**
67
+     * The field validations to be checked for errors
68
+     *
69
+     * @var array
70
+     */
71
+    protected $validations = array();
72
+
73
+    /**
74
+     * The group's element
75
+     *
76
+     * @var string
77
+     */
78
+    protected $element = 'div';
79
+
80
+    /**
81
+     * Whether a custom group is opened or not
82
+     *
83
+     * @var boolean
84
+     */
85
+    public static $opened = false;
86
+
87
+    /**
88
+     * The custom group that is open
89
+     *
90
+     * @var Former\Form\Group
91
+     */
92
+    public static $openGroup = null;
93
+
94
+    ////////////////////////////////////////////////////////////////////
95
+    /////////////////////////// CORE METHODS ///////////////////////////
96
+    ////////////////////////////////////////////////////////////////////
97
+
98
+    /**
99
+     * Creates a group
100
+     *
101
+     * @param string $label Its label
102
+     */
103
+    public function __construct(Container $app, $label, $validations = null)
104
+    {
105
+        // Get special classes
106
+        $this->app = $app;
107
+        $this->addClass($this->app['former.framework']->getGroupClasses());
108
+
109
+        // Invisible if Nude
110
+        if ($this->app['former.framework']->is('Nude')) {
111
+            $this->element = '';
112
+        }
113
+
114
+        // Set group label
115
+        if ($label) {
116
+            $this->setLabel($label);
117
+        }
118
+
119
+        // Set validations used to override groups own conclusions
120
+        $this->validations = (array) $validations;
121
+    }
122
+
123
+    /**
124
+     * Prints out the opening of the Control Group
125
+     *
126
+     * @return string A control group opening tag
127
+     */
128
+    public function __toString()
129
+    {
130
+        return $this->open().$this->getFormattedLabel();
131
+    }
132
+
133
+    /**
134
+     * Opens a group
135
+     *
136
+     * @return string Opening tag
137
+     */
138
+    public function open()
139
+    {
140
+        if ($this->getErrors()) {
141
+            $this->state($this->app['former.framework']->errorState());
142
+        }
143
+
144
+        // Retrieve state and append it to classes
145
+        if ($this->state) {
146
+            $this->addClass($this->state);
147
+        }
148
+
149
+        // Required state
150
+        if ($this->app->bound('former.field') and $this->app['former.field']->isRequired()) {
151
+            $this->addClass($this->app['former']->getOption('required_class'));
152
+        }
153
+
154
+        return parent::open();
155
+    }
156
+
157
+    /**
158
+     * Set the contents of the current group
159
+     *
160
+     * @param string $contents The group contents
161
+     *
162
+     * @return string A group
163
+     */
164
+    public function contents($contents)
165
+    {
166
+        return $this->wrap($contents, $this->getFormattedLabel());
167
+    }
168
+
169
+    /**
170
+     * Wrap a Field with the current group
171
+     *
172
+     * @param  \Former\Traits\Field $field A Field instance
173
+     *
174
+     * @return string        A group
175
+     */
176
+    public function wrapField($field)
177
+    {
178
+        $label = $this->getLabel($field);
179
+        $help = $this->getHelp();
180
+        if ($field->isCheckable() &&
181
+            in_array($this->app['former']->framework(), ['TwitterBootstrap4', 'TwitterBootstrap5'])
182
+        ) {
183
+            $wrapperClass = null;
184
+            if ($this->app['former']->framework() === 'TwitterBootstrap4') {
185
+                $wrapperClass = $field->isInline() ? 'form-check form-check-inline' : 'form-check';
186
+            }
187
+            if ($this->app['former']->getErrors($field->getName())) {
188
+                $hiddenInput = Input::create('hidden')->addClass('form-check-input is-invalid');
189
+                $help = $hiddenInput.$help;
190
+            }
191
+            $help = $help ? Element::create('div', $help)->addClass($wrapperClass) : '';
192
+        }
193
+        $withFloatingLabel = $field->withFloatingLabel();
194
+
195
+        $field = $this->prependAppend($field);
196
+        $field .= $help;
197
+
198
+        if ($withFloatingLabel &&
199
+            $this->app['former']->framework() === 'TwitterBootstrap5'
200
+        ) {
201
+            return $this->wrapWithFloatingLabel($field, $label);
202
+        }
203
+
204
+        return $this->wrap($field, $label);
205
+    }
206
+
207
+    ////////////////////////////////////////////////////////////////////
208
+    //////////////////////////// FIELD METHODS /////////////////////////
209
+    ////////////////////////////////////////////////////////////////////
210
+
211
+    /**
212
+     * Set the state of the group
213
+     *
214
+     * @param  string $state A Bootstrap state class
215
+     */
216
+    public function state($state)
217
+    {
218
+        // Filter state
219
+        $state = $this->app['former.framework']->filterState($state);
220
+
221
+        $this->state = $state;
222
+    }
223
+
224
+    /**
225
+     * Set a class on the Group
226
+     *
227
+     * @param string $class The class(es) to add on the Group
228
+     */
229
+    public function addGroupClass($class)
230
+    {
231
+        $this->addClass($class);
232
+    }
233
+
234
+    /**
235
+     * Remove one or more classes on the Group
236
+     *
237
+     * @param string $class The class(es) to remove on the Group
238
+     */
239
+    public function removeGroupClass($class)
240
+    {
241
+        $this->removeClass($class);
242
+    }
243
+
244
+    /**
245
+     * Set a class on the Label
246
+     *
247
+     * @param string $class The class(es) to add on the Label
248
+     */
249
+    public function addLabelClass($class)
250
+    {
251
+        // Don't add a label class if it isn't an Element instance
252
+        if (!$this->label instanceof Element) {
253
+            return $this;
254
+        }
255
+
256
+        $this->label->addClass($class);
257
+
258
+        return $this;
259
+    }
260
+
261
+    /**
262
+     * Remove one or more classes on the Label
263
+     *
264
+     * @param string $class The class(es) to remove on the Label
265
+     */
266
+    public function removeLabelClass($class)
267
+    {
268
+        // Don't remove a label class if it isn't an Element instance
269
+        if (!$this->label instanceof Element) {
270
+            return $this;
271
+        }
272
+
273
+        $this->label->removeClass($class);
274
+
275
+        return $this;
276
+    }
277
+
278
+    /**
279
+     * Adds a label to the group
280
+     *
281
+     * @param  string $label A label
282
+     */
283
+    public function setLabel($label)
284
+    {
285
+        if (!$label instanceof Element) {
286
+            $label = Helpers::translate($label);
287
+            $label = Element::create('label', $label)->for($label);
288
+        }
289
+
290
+        $this->label = $label;
291
+    }
292
+
293
+    /**
294
+     * Get the formatted group label
295
+     *
296
+     * @return string|null
297
+     */
298
+    public function getFormattedLabel()
299
+    {
300
+        if (!$this->label) {
301
+            return false;
302
+        }
303
+
304
+        return $this->label->addClass($this->app['former.framework']->getLabelClasses());
305
+    }
306
+
307
+    /**
308
+     * Disables the control group for the current field
309
+     */
310
+    public function raw()
311
+    {
312
+        $this->raw = true;
313
+    }
314
+
315
+    /**
316
+     * Check if the current group is to be displayed or not
317
+     *
318
+     * @return boolean
319
+     */
320
+    public function isRaw()
321
+    {
322
+        return (bool) $this->raw;
323
+    }
324
+
325
+    ////////////////////////////////////////////////////////////////////
326
+    ///////////////////////////// HELP BLOCKS //////////////////////////
327
+    ////////////////////////////////////////////////////////////////////
328
+
329
+    /**
330
+     * Alias for inlineHelp
331
+     *
332
+     * @param  string $help       The help text
333
+     * @param  array  $attributes Facultative attributes
334
+     */
335
+    public function help($help, $attributes = array())
336
+    {
337
+        return $this->inlineHelp($help, $attributes);
338
+    }
339
+
340
+    /**
341
+     * Add an inline help
342
+     *
343
+     * @param  string $help       The help text
344
+     * @param  array  $attributes Facultative attributes
345
+     */
346
+    public function inlineHelp($help, $attributes = array())
347
+    {
348
+        // If no help text, do nothing
349
+        if (!$help) {
350
+            return false;
351
+        }
352
+
353
+        $this->help['inline'] = $this->app['former.framework']->createHelp($help, $attributes);
354
+    }
355
+
356
+    /**
357
+     * Add an block help
358
+     *
359
+     * @param  string $help       The help text
360
+     * @param  array  $attributes Facultative attributes
361
+     */
362
+    public function blockHelp($help, $attributes = array())
363
+    {
364
+        // Reserved method
365
+        if ($this->app['former.framework']->isnt('TwitterBootstrap') &&
366
+            $this->app['former.framework']->isnt('TwitterBootstrap3') &&
367
+            $this->app['former.framework']->isnt('TwitterBootstrap4') &&
368
+            $this->app['former.framework']->isnt('TwitterBootstrap5')
369
+        ) {
370
+            throw new BadMethodCallException('This method is only available on the Bootstrap framework');
371
+        }
372
+
373
+        // If no help text, do nothing
374
+        if (!$help) {
375
+            return false;
376
+        }
377
+
378
+        $this->help['block'] = $this->app['former.framework']->createBlockHelp($help, $attributes);
379
+    }
380
+
381
+    ////////////////////////////////////////////////////////////////////
382
+    ///////////////////////// PREPEND/APPEND METHODS ///////////////////
383
+    ////////////////////////////////////////////////////////////////////
384
+
385
+    /**
386
+     * Prepend elements to the field
387
+     */
388
+    public function prepend()
389
+    {
390
+        $this->placeAround(func_get_args(), 'prepend');
391
+    }
392
+
393
+    /**
394
+     * Append elements to the field
395
+     */
396
+    public function append()
397
+    {
398
+        $this->placeAround(func_get_args(), 'append');
399
+    }
400
+
401
+    /**
402
+     * Prepends an icon to a field
403
+     *
404
+     * @param string $icon       The icon to prepend
405
+     * @param array  $attributes Its attributes
406
+     */
407
+    public function prependIcon($icon, $attributes = array(), $iconSettings = array())
408
+    {
409
+        $icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
410
+
411
+        $this->prepend($icon);
412
+    }
413
+
414
+    /**
415
+     * Append an icon to a field
416
+     *
417
+     * @param string $icon       The icon to prepend
418
+     * @param array  $attributes Its attributes
419
+     */
420
+    public function appendIcon($icon, $attributes = array(), $iconSettings = array())
421
+    {
422
+        $icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
423
+
424
+        $this->append($icon);
425
+    }
426
+
427
+    ////////////////////////////////////////////////////////////////////
428
+    //////////////////////////////// HELPERS ///////////////////////////
429
+    ////////////////////////////////////////////////////////////////////
430
+
431
+    /**
432
+     * Get the errors for the group
433
+     *
434
+     * @return string
435
+     */
436
+    public function getErrors()
437
+    {
438
+        $errors = '';
439
+
440
+        if (!self::$opened) {
441
+
442
+            // for non-custom groups, normal error handling applies
443
+            $errors = $this->app['former']->getErrors();
444
+        } elseif (!empty($this->validations)) {
445
+
446
+            // error handling only when validations specified for custom groups
447
+            foreach ($this->validations as $validation) {
448
+                $errors .= $this->app['former']->getErrors($validation);
449
+            }
450
+        }
451
+
452
+        return $errors;
453
+    }
454
+
455
+    /**
456
+     * Wraps content in a group
457
+     *
458
+     * @param string $contents The content
459
+     * @param string $label    The label to add
460
+     *
461
+     * @return string A group
462
+     */
463
+    public function wrap($contents, $label = null)
464
+    {
465
+        $group = $this->open();
466
+        $group .= $label;
467
+        $group .= $this->app['former.framework']->wrapField($contents);
468
+        $group .= $this->close();
469
+
470
+        return $group;
471
+    }
472
+
473
+    /**
474
+     * Wraps content in a group with floating label
475
+     *
476
+     * @param string $contents The content
477
+     * @param string $label    The label to add
478
+     *
479
+     * @return string A group
480
+     */
481
+    public function wrapWithFloatingLabel($contents, $label = null)
482
+    {
483
+        $floatingLabelClass = $this->app['former.framework']->getFloatingLabelClass();
484
+        if ($floatingLabelClass) {
485
+            $this->addClass($floatingLabelClass);
486
+        }
487
+        return $this->wrap($label, $contents);
488
+    }
489
+
490
+    /**
491
+     * Prints out the current label
492
+     *
493
+     * @param  string $field The field to create a label for
494
+     *
495
+     * @return string        A <label> tag
496
+     */
497
+        protected function getLabel($field = null)
498
+        {
499
+            // Don't create a label if none exist
500
+            if (!$field or !$this->label) {
501
+                return null;
502
+            }
503
+
504
+            // Wrap label in framework classes
505
+            $labelClasses = $this->app['former.framework']->getLabelClasses();
506
+            if ($field->isCheckable() &&
507
+             in_array($this->app['former']->framework(), ['TwitterBootstrap4', 'TwitterBootstrap5']) &&
508
+             $this->app['former.form']->isOfType('horizontal')
509
+            ) {
510
+                $labelClasses = array_merge($labelClasses, array('pt-0'));
511
+            }
512
+            $this->label->addClass($labelClasses);
513
+            $this->label = $this->app['former.framework']->createLabelOf($field, $this->label);
514
+            $this->label = $this->app['former.framework']->wrapLabel($this->label);
515
+
516
+            return $this->label;
517
+        }
518
+
519
+    /**
520
+     * Prints out the current help
521
+     *
522
+     * @return string A .help-block or .help-inline
523
+     */
524
+    protected function getHelp()
525
+    {
526
+        $inline = Arr::get($this->help, 'inline');
527
+        $block  = Arr::get($this->help, 'block');
528
+
529
+        // Replace help text with error if any found
530
+        $errors = $this->app['former']->getErrors();
531
+        if ($errors and $this->app['former']->getOption('error_messages')) {
532
+            $inline = $this->app['former.framework']->createValidationError($errors);
533
+        }
534
+
535
+        return implode('', array($inline, $block));
536
+    }
537
+
538
+    /**
539
+     * Format the field with prepended/appended elements
540
+     *
541
+     * @param  Field $field The field to format
542
+     *
543
+     * @return string        Field plus supplementary elements
544
+     */
545
+    protected function prependAppend($field)
546
+    {
547
+        if (!$this->prepend and !$this->append) {
548
+            return $field->render();
549
+        }
550
+
551
+        return $this->app['former.framework']->prependAppend($field, $this->prepend, $this->append);
552
+    }
553
+
554
+    /**
555
+     * Place elements around the field
556
+     *
557
+     * @param  array  $items An array of items to place
558
+     * @param  string $place Where they should end up (prepend|append)
559
+     */
560
+    protected function placeAround($items, $place)
561
+    {
562
+        // Iterate over the items and place them where they should
563
+        foreach ((array) $items as $item) {
564
+            $item             = $this->app['former.framework']->placeAround($item, $place);
565
+            $this->{$place}[] = $item;
566
+        }
567
+    }
568 568
 }
Please login to merge, or discard this patch.
src/Former/Form/Fields/Choice.php 1 patch
Indentation   +468 added lines, -468 removed lines patch added patch discarded remove patch
@@ -13,477 +13,477 @@
 block discarded – undo
13 13
  */
14 14
 class Choice extends Field
15 15
 {
16
-	/**
17
-	 * Renders the checkables as inline
18
-	 *
19
-	 * @var boolean
20
-	 */
21
-	protected $inline = false;
22
-
23
-	/**
24
-	 * The choice's placeholder
25
-	 *
26
-	 * @var string
27
-	 */
28
-	private $placeholder = null;
29
-
30
-	/**
31
-	 * The choice's options
32
-	 *
33
-	 * @var array
34
-	 */
35
-	protected $options = [
16
+    /**
17
+     * Renders the checkables as inline
18
+     *
19
+     * @var boolean
20
+     */
21
+    protected $inline = false;
22
+
23
+    /**
24
+     * The choice's placeholder
25
+     *
26
+     * @var string
27
+     */
28
+    private $placeholder = null;
29
+
30
+    /**
31
+     * The choice's options
32
+     *
33
+     * @var array
34
+     */
35
+    protected $options = [
36 36
         'isMultiple' => false,
37 37
         'isExpanded' => false,
38 38
     ];
39 39
 
40
-	/**
41
-	 * The choice's choices
42
-	 *
43
-	 * @var array
44
-	 */
45
-	protected $choices = [];
46
-
47
-	/**
48
-	 * The choice's element
49
-	 *
50
-	 * @var string
51
-	 */
52
-	protected $element = 'choice';
53
-
54
-	/**
55
-	 * The choice's self-closing state
56
-	 *
57
-	 * @var boolean
58
-	 */
59
-	protected $isSelfClosing = false;
60
-
61
-	////////////////////////////////////////////////////////////////////
62
-	/////////////////////////// CORE METHODS ///////////////////////////
63
-	////////////////////////////////////////////////////////////////////
64
-
65
-	/**
66
-	 * Easier arguments order for selects
67
-	 *
68
-	 * @param Container $app        The Container instance
69
-	 * @param string    $type       select
70
-	 * @param string    $name       Field name
71
-	 * @param string    $label      Its label
72
-	 * @param array     $choices    The choice's choices
73
-	 * @param string    $selected   The selected choice(s)
74
-	 * @param array     $attributes Attributes
75
-	 */
76
-	public function __construct(Container $app, $type, $name, $label, $choices, $selected, $attributes)
77
-	{
78
-		if ($selected) {
79
-			$this->value = $selected;
80
-		}
81
-		if ($choices) {
82
-			$this->choices($choices);
83
-		}
84
-
85
-		parent::__construct($app, $type, $name, $label, $selected, $attributes);
86
-
87
-		$this->setChoiceType();
88
-
89
-		// Nested models population
90
-		if (Str::contains($this->name, '.') and is_array($this->value) and !empty($this->value) and is_string($this->value[key($this->value)])) {
91
-			$this->fromQuery($this->value);
92
-			$this->value = $selected ?: null;
93
-		}
94
-	}
95
-
96
-	/**
97
-	 * Renders the choice
98
-	 *
99
-	 * @return string A <select> tag
100
-	 */
101
-	public function render()
102
-	{
103
-		$choiceType = $this->getType();
104
-		$this->setFieldClasses();
105
-
106
-		if (!isset($this->attributes['id'])) {
107
-			$this->setAttribute('id', $this->name);
108
-		}
109
-
110
-		switch ($choiceType) {
111
-			case 'select':
112
-				$field = $this->getSelect();
113
-				break;
114
-			case 'checkbox':
115
-			case 'radio':
116
-				$field = $this->getCheckables($choiceType);
117
-				break;
118
-		}
119
-		$this->value = null;
120
-		$content = $field->render();
121
-		return $content;
122
-	}
123
-
124
-	public function getSelect()
125
-	{
126
-		$field = Element::create('select', null, $this->attributes);
127
-
128
-		$name = $this->name;
129
-		if ($this->options['isMultiple']) {
130
-			$field->multiple();
131
-			$name .= '[]';
132
-		}
133
-
134
-		$field->setAttribute('name', $name);
135
-
136
-		$field->nest($this->getOptions());
137
-
138
-		return $field;
139
-	}
140
-
141
-	public function getOptions()
142
-	{
143
-		$children = [];
144
-
145
-		// Add placeholder text if any
146
-		if ($placeholder = $this->getPlaceholder()) {
147
-			$children[] = $placeholder;
148
-		}
149
-
150
-		foreach ($this->choices as $key => $value) {
151
-			if (is_array($value) and !isset($value['value'])) {
152
-				$children[] = $this->getOptGroup($key, $value);
153
-			} else {
154
-				$children[] = $this->getOption($key, $value);
155
-			}
156
-		}
157
-		return $children;
158
-	}
159
-
160
-	public function getOptGroup($label, $options)
161
-	{
162
-		$element = Element::create('optgroup')->label($label);
163
-		$children = [];
164
-		foreach ($options as $key => $value) {
165
-			$option = $this->getOption($key, $value);
166
-			$children[] = $option;
167
-		}
168
-		$element->nest($children);
169
-
170
-		return $element;
171
-	}
172
-
173
-	public function getOption($key, $value)
174
-	{
175
-		if (is_array($value) and isset($value['value'])) {
176
-			$attributes = $value;
177
-			$text = $key;
178
-			$key = null;
179
-		} else {
180
-			$attributes = array('value' => $key);
181
-			$text = $value;
182
-		}
183
-
184
-		$element = Element::create('option', $text, $attributes);
185
-		if ($this->hasValue($attributes['value'])) {
186
-			$element->selected('selected');
187
-		}
188
-
189
-		return $element;
190
-	}
191
-
192
-	public function getCheckables($choiceType)
193
-	{
194
-		if ($this->value !== null && !(is_array($this->value) || $this->value instanceof \ArrayAccess)) {
195
-			$this->value = explode(',', $this->value);
196
-		}
197
-
198
-		$disabled = isset($this->attributes['disabled']);
199
-		unset($this->attributes['disabled']);
200
-
201
-		$field = Element::create('div', null, $this->attributes);
202
-
203
-		$children = [];
204
-		foreach ($this->choices as $key => $value) {
205
-			$attributes = [];
206
-
207
-			if (is_array($value) and isset($value['value'])) {
208
-				$attributes = $value;
209
-				$label = $key;
210
-				$inputValue = $value['value'];
211
-			} else {
212
-				$attributes = [];
213
-				$label = $value;
214
-				$inputValue = $key;
215
-			}
216
-
217
-			if ($disabled) {
218
-				$attributes['disabled'] = true;
219
-			}
220
-
221
-			if(isset($attributes['name'])) {
222
-				$name = $attributes['name'];
223
-				unset($attributes['name']);
224
-			} else {
225
-				$name = $this->name;
226
-			}
227
-			if ($this->options['isMultiple']) {
228
-				$name .= '[]';
229
-			}
230
-
231
-			if(!isset($attributes['id'])) {
232
-				$attributes['id'] = $this->id.'_'.count($children);
233
-			}
234
-
235
-			// If inline items, add class
236
-			$isInline = $this->inline ? ' '.$this->app['former.framework']->getInlineLabelClass($this) : '';
237
-
238
-			// In Bootsrap 3, don't append the the checkable type (radio/checkbox) as a class if
239
-			// rendering inline.
240
-			$class = $this->app['former']->framework() == 'TwitterBootstrap3' ? trim($isInline) : $choiceType.$isInline;
241
-
242
-			$element = Input::create($choiceType, $name, $inputValue, $attributes);
243
-
244
-			// $element->setAttribute('name', $name);
245
-
246
-			if ($this->hasValue($inputValue)) {
247
-				$element->checked('checked');
248
-			}
249
-			// $attributes['value'] = $key;
250
-			if (!$label) {
251
-				$element = (is_object($field)) ? $field->render() : $field;
252
-			} else {
253
-				$rendered = $element->render();
254
-				$labelElement = Element::create('label', $rendered.$label);
255
-				$element = $labelElement->for($attributes['id'])->class($class);
256
-			}
257
-
258
-			// If BS3, if checkables are stacked, wrap them in a div with the checkable type
259
-			if (!$isInline && $this->app['former']->framework() == 'TwitterBootstrap3') {
260
-				$wrapper = Element::create('div', $element->render())->class($choiceType);
261
-				if ($disabled) {
262
-					$wrapper->addClass('disabled');
263
-				}
264
-				$element = $wrapper;
265
-			}
266
-
267
-			$children[] = $element;
268
-		}
269
-		$field->nest($children);
270
-
271
-		return $field;
272
-	}
273
-
274
-	/**
275
-	 * Get the choice's placeholder
276
-	 *
277
-	 * @return Element
278
-	 */
279
-	protected function getPlaceholder()
280
-	{
281
-		if (!$this->placeholder) {
282
-			return false;
283
-		}
284
-
285
-		$attributes = array('value' => '', 'disabled' => 'disabled');
286
-		if (!(array)$this->value) {
287
-			$attributes['selected'] = 'selected';
288
-		}
289
-
290
-		return Element::create('option', $this->placeholder, $attributes);
291
-	}
292
-
293
-	/**
294
-	 * Sets the element's type based on options
295
-	 *
296
-	 * @return this
297
-	 */
298
-	protected function setChoiceType()
299
-	{
300
-		if ($this->options['isExpanded'] && !$this->options['isMultiple']) {
301
-			$this->setType('radio');
302
-		} elseif ($this->options['isExpanded'] && $this->options['isMultiple']) {
303
-			$this->setType('checkbox');
304
-		} else {
305
-			$this->setType('select');
306
-		}
307
-		return $this;
308
-	}
309
-
310
-	/**
311
-	 * Select a value in the field's children
312
-	 *
313
-	 * @param mixed   $value
314
-	 *
315
-	 * @return bool
316
-	 */
317
-	protected function hasValue($choiceValue)
318
-	{
319
-		foreach ((array)$this->value as $key => $value) {
320
-			if (is_object($value) && method_exists($value, 'getKey')) {
321
-				$value = $value->getKey();
322
-			}
323
-			if ($choiceValue === $value || is_numeric($value) && $choiceValue === (int)$value) {
324
-				return true;
325
-			}
326
-		}
327
-		return false;
328
-	}
329
-
330
-	////////////////////////////////////////////////////////////////////
331
-	////////////////////////// FIELD METHODS ///////////////////////////
332
-	////////////////////////////////////////////////////////////////////
333
-
334
-	/**
335
-	 * Set the choices
336
-	 *
337
-	 * @param  array   $_choices     The choices as an array
338
-	 * @param  mixed   $selected     Facultative selected entry
339
-	 * @param  boolean $valuesAsKeys Whether the array's values should be used as
340
-	 *                               the option's values instead of the array's keys
341
-	 */
342
-	public function addChoice($value, $key = null)
343
-	{
344
-		$this->choices[$key ?? $value] = $value;
345
-
346
-		return $this;
347
-	}
348
-
349
-	/**
350
-	 * Set the choices
351
-	 *
352
-	 * @param  array   $_choices     The choices as an array
353
-	 * @param  mixed   $selected     Facultative selected entry
354
-	 * @param  boolean $valuesAsKeys Whether the array's values should be used as
355
-	 *                               the option's values instead of the array's keys
356
-	 */
357
-	public function choices($_choices, $valuesAsKeys = false)
358
-	{
359
-		$choices = (array) $_choices;
360
-
361
-		// If valuesAsKeys is true, use the values as keys
362
-		if ($valuesAsKeys) {
363
-			foreach ($choices as $value) {
364
-				$this->addChoice($value, $value);
365
-			}
366
-		} else {
367
-			foreach ($choices as $key => $value) {
368
-				$this->addChoice($value, $key);
369
-			}
370
-		}
371
-
372
-		return $this;
373
-	}
374
-
375
-	/**
376
-	 * Creates a list of choices from a range
377
-	 *
378
-	 * @param  integer $from
379
-	 * @param  integer $to
380
-	 * @param  integer $step
381
-	 */
382
-	public function range($from, $to, $step = 1)
383
-	{
384
-		$range = range($from, $to, $step);
385
-		$this->choices($range, true);
386
-
387
-		return $this;
388
-	}
389
-
390
-	/**
391
-	 * Use the results from a Fluent/Eloquent query as choices
392
-	 *
393
-	 * @param  array           $results    An array of Eloquent models
394
-	 * @param  string|function $text       The value to use as text
395
-	 * @param  string|array    $attributes The data to use as attributes
396
-	 * @param  string	       $selected   The default selected item
397
-	 */
398
-	public function fromQuery($results, $text = null, $attributes = null, $selected = null)
399
-	{
400
-		$this->choices(Helpers::queryToArray($results, $text, $attributes))->value($selected);
401
-
402
-		return $this;
403
-	}
404
-
405
-	/**
406
-	 * Add a placeholder to the current select
407
-	 *
408
-	 * @param  string $placeholder The placeholder text
409
-	 */
410
-	public function placeholder($placeholder)
411
-	{
412
-		$this->placeholder = Helpers::translate($placeholder);
413
-
414
-		return $this;
415
-	}
416
-
417
-	/**
418
-	 * Set isMultiple
419
-	 *
420
-	 * @param boolean $isMultiple
421
-	 * @return $this
422
-	 */
423
-	public function multiple($isMultiple = true)
424
-	{
425
-		$this->options['isMultiple'] = $isMultiple;
426
-		$this->setChoiceType();
427
-
428
-		return $this;
429
-	}
430
-
431
-	/**
432
-	 * Set isExpanded
433
-	 *
434
-	 * @param boolean $isExpanded
435
-	 * @return $this
436
-	 */
437
-	public function expanded($isExpanded = true)
438
-	{
439
-		$this->options['isExpanded'] = $isExpanded;
440
-		$this->setChoiceType();
441
-
442
-		return $this;
443
-	}
444
-
445
-	/**
446
-	 * Set the choices as inline (for expanded items)
447
-	 */
448
-	public function inline($isInline = true)
449
-	{
450
-		$this->inline = $isInline;
451
-
452
-		return $this;
453
-	}
454
-
455
-	/**
456
-	 * Set the choices as stacked (for expanded items)
457
-	 */
458
-	public function stacked($isStacked = true)
459
-	{
460
-		$this->inline = !$isStacked;
461
-
462
-		return $this;
463
-	}
464
-
465
-	/**
466
-	 * Check if field is a checkbox or a radio
467
-	 *
468
-	 * @return boolean
469
-	 */
470
-	public function isCheckable()
471
-	{
472
-		return $this->options['isExpanded'];
473
-	}
474
-
475
-	////////////////////////////////////////////////////////////////////
476
-	////////////////////////////// HELPERS /////////////////////////////
477
-	////////////////////////////////////////////////////////////////////
478
-
479
-	/**
480
-	 * Returns the current choices in memory for manipulations
481
-	 *
482
-	 * @return array The current choices array
483
-	 */
484
-	public function getChoices()
485
-	{
486
-		return $this->choices;
487
-	}
40
+    /**
41
+     * The choice's choices
42
+     *
43
+     * @var array
44
+     */
45
+    protected $choices = [];
46
+
47
+    /**
48
+     * The choice's element
49
+     *
50
+     * @var string
51
+     */
52
+    protected $element = 'choice';
53
+
54
+    /**
55
+     * The choice's self-closing state
56
+     *
57
+     * @var boolean
58
+     */
59
+    protected $isSelfClosing = false;
60
+
61
+    ////////////////////////////////////////////////////////////////////
62
+    /////////////////////////// CORE METHODS ///////////////////////////
63
+    ////////////////////////////////////////////////////////////////////
64
+
65
+    /**
66
+     * Easier arguments order for selects
67
+     *
68
+     * @param Container $app        The Container instance
69
+     * @param string    $type       select
70
+     * @param string    $name       Field name
71
+     * @param string    $label      Its label
72
+     * @param array     $choices    The choice's choices
73
+     * @param string    $selected   The selected choice(s)
74
+     * @param array     $attributes Attributes
75
+     */
76
+    public function __construct(Container $app, $type, $name, $label, $choices, $selected, $attributes)
77
+    {
78
+        if ($selected) {
79
+            $this->value = $selected;
80
+        }
81
+        if ($choices) {
82
+            $this->choices($choices);
83
+        }
84
+
85
+        parent::__construct($app, $type, $name, $label, $selected, $attributes);
86
+
87
+        $this->setChoiceType();
88
+
89
+        // Nested models population
90
+        if (Str::contains($this->name, '.') and is_array($this->value) and !empty($this->value) and is_string($this->value[key($this->value)])) {
91
+            $this->fromQuery($this->value);
92
+            $this->value = $selected ?: null;
93
+        }
94
+    }
95
+
96
+    /**
97
+     * Renders the choice
98
+     *
99
+     * @return string A <select> tag
100
+     */
101
+    public function render()
102
+    {
103
+        $choiceType = $this->getType();
104
+        $this->setFieldClasses();
105
+
106
+        if (!isset($this->attributes['id'])) {
107
+            $this->setAttribute('id', $this->name);
108
+        }
109
+
110
+        switch ($choiceType) {
111
+            case 'select':
112
+                $field = $this->getSelect();
113
+                break;
114
+            case 'checkbox':
115
+            case 'radio':
116
+                $field = $this->getCheckables($choiceType);
117
+                break;
118
+        }
119
+        $this->value = null;
120
+        $content = $field->render();
121
+        return $content;
122
+    }
123
+
124
+    public function getSelect()
125
+    {
126
+        $field = Element::create('select', null, $this->attributes);
127
+
128
+        $name = $this->name;
129
+        if ($this->options['isMultiple']) {
130
+            $field->multiple();
131
+            $name .= '[]';
132
+        }
133
+
134
+        $field->setAttribute('name', $name);
135
+
136
+        $field->nest($this->getOptions());
137
+
138
+        return $field;
139
+    }
140
+
141
+    public function getOptions()
142
+    {
143
+        $children = [];
144
+
145
+        // Add placeholder text if any
146
+        if ($placeholder = $this->getPlaceholder()) {
147
+            $children[] = $placeholder;
148
+        }
149
+
150
+        foreach ($this->choices as $key => $value) {
151
+            if (is_array($value) and !isset($value['value'])) {
152
+                $children[] = $this->getOptGroup($key, $value);
153
+            } else {
154
+                $children[] = $this->getOption($key, $value);
155
+            }
156
+        }
157
+        return $children;
158
+    }
159
+
160
+    public function getOptGroup($label, $options)
161
+    {
162
+        $element = Element::create('optgroup')->label($label);
163
+        $children = [];
164
+        foreach ($options as $key => $value) {
165
+            $option = $this->getOption($key, $value);
166
+            $children[] = $option;
167
+        }
168
+        $element->nest($children);
169
+
170
+        return $element;
171
+    }
172
+
173
+    public function getOption($key, $value)
174
+    {
175
+        if (is_array($value) and isset($value['value'])) {
176
+            $attributes = $value;
177
+            $text = $key;
178
+            $key = null;
179
+        } else {
180
+            $attributes = array('value' => $key);
181
+            $text = $value;
182
+        }
183
+
184
+        $element = Element::create('option', $text, $attributes);
185
+        if ($this->hasValue($attributes['value'])) {
186
+            $element->selected('selected');
187
+        }
188
+
189
+        return $element;
190
+    }
191
+
192
+    public function getCheckables($choiceType)
193
+    {
194
+        if ($this->value !== null && !(is_array($this->value) || $this->value instanceof \ArrayAccess)) {
195
+            $this->value = explode(',', $this->value);
196
+        }
197
+
198
+        $disabled = isset($this->attributes['disabled']);
199
+        unset($this->attributes['disabled']);
200
+
201
+        $field = Element::create('div', null, $this->attributes);
202
+
203
+        $children = [];
204
+        foreach ($this->choices as $key => $value) {
205
+            $attributes = [];
206
+
207
+            if (is_array($value) and isset($value['value'])) {
208
+                $attributes = $value;
209
+                $label = $key;
210
+                $inputValue = $value['value'];
211
+            } else {
212
+                $attributes = [];
213
+                $label = $value;
214
+                $inputValue = $key;
215
+            }
216
+
217
+            if ($disabled) {
218
+                $attributes['disabled'] = true;
219
+            }
220
+
221
+            if(isset($attributes['name'])) {
222
+                $name = $attributes['name'];
223
+                unset($attributes['name']);
224
+            } else {
225
+                $name = $this->name;
226
+            }
227
+            if ($this->options['isMultiple']) {
228
+                $name .= '[]';
229
+            }
230
+
231
+            if(!isset($attributes['id'])) {
232
+                $attributes['id'] = $this->id.'_'.count($children);
233
+            }
234
+
235
+            // If inline items, add class
236
+            $isInline = $this->inline ? ' '.$this->app['former.framework']->getInlineLabelClass($this) : '';
237
+
238
+            // In Bootsrap 3, don't append the the checkable type (radio/checkbox) as a class if
239
+            // rendering inline.
240
+            $class = $this->app['former']->framework() == 'TwitterBootstrap3' ? trim($isInline) : $choiceType.$isInline;
241
+
242
+            $element = Input::create($choiceType, $name, $inputValue, $attributes);
243
+
244
+            // $element->setAttribute('name', $name);
245
+
246
+            if ($this->hasValue($inputValue)) {
247
+                $element->checked('checked');
248
+            }
249
+            // $attributes['value'] = $key;
250
+            if (!$label) {
251
+                $element = (is_object($field)) ? $field->render() : $field;
252
+            } else {
253
+                $rendered = $element->render();
254
+                $labelElement = Element::create('label', $rendered.$label);
255
+                $element = $labelElement->for($attributes['id'])->class($class);
256
+            }
257
+
258
+            // If BS3, if checkables are stacked, wrap them in a div with the checkable type
259
+            if (!$isInline && $this->app['former']->framework() == 'TwitterBootstrap3') {
260
+                $wrapper = Element::create('div', $element->render())->class($choiceType);
261
+                if ($disabled) {
262
+                    $wrapper->addClass('disabled');
263
+                }
264
+                $element = $wrapper;
265
+            }
266
+
267
+            $children[] = $element;
268
+        }
269
+        $field->nest($children);
270
+
271
+        return $field;
272
+    }
273
+
274
+    /**
275
+     * Get the choice's placeholder
276
+     *
277
+     * @return Element
278
+     */
279
+    protected function getPlaceholder()
280
+    {
281
+        if (!$this->placeholder) {
282
+            return false;
283
+        }
284
+
285
+        $attributes = array('value' => '', 'disabled' => 'disabled');
286
+        if (!(array)$this->value) {
287
+            $attributes['selected'] = 'selected';
288
+        }
289
+
290
+        return Element::create('option', $this->placeholder, $attributes);
291
+    }
292
+
293
+    /**
294
+     * Sets the element's type based on options
295
+     *
296
+     * @return this
297
+     */
298
+    protected function setChoiceType()
299
+    {
300
+        if ($this->options['isExpanded'] && !$this->options['isMultiple']) {
301
+            $this->setType('radio');
302
+        } elseif ($this->options['isExpanded'] && $this->options['isMultiple']) {
303
+            $this->setType('checkbox');
304
+        } else {
305
+            $this->setType('select');
306
+        }
307
+        return $this;
308
+    }
309
+
310
+    /**
311
+     * Select a value in the field's children
312
+     *
313
+     * @param mixed   $value
314
+     *
315
+     * @return bool
316
+     */
317
+    protected function hasValue($choiceValue)
318
+    {
319
+        foreach ((array)$this->value as $key => $value) {
320
+            if (is_object($value) && method_exists($value, 'getKey')) {
321
+                $value = $value->getKey();
322
+            }
323
+            if ($choiceValue === $value || is_numeric($value) && $choiceValue === (int)$value) {
324
+                return true;
325
+            }
326
+        }
327
+        return false;
328
+    }
329
+
330
+    ////////////////////////////////////////////////////////////////////
331
+    ////////////////////////// FIELD METHODS ///////////////////////////
332
+    ////////////////////////////////////////////////////////////////////
333
+
334
+    /**
335
+     * Set the choices
336
+     *
337
+     * @param  array   $_choices     The choices as an array
338
+     * @param  mixed   $selected     Facultative selected entry
339
+     * @param  boolean $valuesAsKeys Whether the array's values should be used as
340
+     *                               the option's values instead of the array's keys
341
+     */
342
+    public function addChoice($value, $key = null)
343
+    {
344
+        $this->choices[$key ?? $value] = $value;
345
+
346
+        return $this;
347
+    }
348
+
349
+    /**
350
+     * Set the choices
351
+     *
352
+     * @param  array   $_choices     The choices as an array
353
+     * @param  mixed   $selected     Facultative selected entry
354
+     * @param  boolean $valuesAsKeys Whether the array's values should be used as
355
+     *                               the option's values instead of the array's keys
356
+     */
357
+    public function choices($_choices, $valuesAsKeys = false)
358
+    {
359
+        $choices = (array) $_choices;
360
+
361
+        // If valuesAsKeys is true, use the values as keys
362
+        if ($valuesAsKeys) {
363
+            foreach ($choices as $value) {
364
+                $this->addChoice($value, $value);
365
+            }
366
+        } else {
367
+            foreach ($choices as $key => $value) {
368
+                $this->addChoice($value, $key);
369
+            }
370
+        }
371
+
372
+        return $this;
373
+    }
374
+
375
+    /**
376
+     * Creates a list of choices from a range
377
+     *
378
+     * @param  integer $from
379
+     * @param  integer $to
380
+     * @param  integer $step
381
+     */
382
+    public function range($from, $to, $step = 1)
383
+    {
384
+        $range = range($from, $to, $step);
385
+        $this->choices($range, true);
386
+
387
+        return $this;
388
+    }
389
+
390
+    /**
391
+     * Use the results from a Fluent/Eloquent query as choices
392
+     *
393
+     * @param  array           $results    An array of Eloquent models
394
+     * @param  string|function $text       The value to use as text
395
+     * @param  string|array    $attributes The data to use as attributes
396
+     * @param  string	       $selected   The default selected item
397
+     */
398
+    public function fromQuery($results, $text = null, $attributes = null, $selected = null)
399
+    {
400
+        $this->choices(Helpers::queryToArray($results, $text, $attributes))->value($selected);
401
+
402
+        return $this;
403
+    }
404
+
405
+    /**
406
+     * Add a placeholder to the current select
407
+     *
408
+     * @param  string $placeholder The placeholder text
409
+     */
410
+    public function placeholder($placeholder)
411
+    {
412
+        $this->placeholder = Helpers::translate($placeholder);
413
+
414
+        return $this;
415
+    }
416
+
417
+    /**
418
+     * Set isMultiple
419
+     *
420
+     * @param boolean $isMultiple
421
+     * @return $this
422
+     */
423
+    public function multiple($isMultiple = true)
424
+    {
425
+        $this->options['isMultiple'] = $isMultiple;
426
+        $this->setChoiceType();
427
+
428
+        return $this;
429
+    }
430
+
431
+    /**
432
+     * Set isExpanded
433
+     *
434
+     * @param boolean $isExpanded
435
+     * @return $this
436
+     */
437
+    public function expanded($isExpanded = true)
438
+    {
439
+        $this->options['isExpanded'] = $isExpanded;
440
+        $this->setChoiceType();
441
+
442
+        return $this;
443
+    }
444
+
445
+    /**
446
+     * Set the choices as inline (for expanded items)
447
+     */
448
+    public function inline($isInline = true)
449
+    {
450
+        $this->inline = $isInline;
451
+
452
+        return $this;
453
+    }
454
+
455
+    /**
456
+     * Set the choices as stacked (for expanded items)
457
+     */
458
+    public function stacked($isStacked = true)
459
+    {
460
+        $this->inline = !$isStacked;
461
+
462
+        return $this;
463
+    }
464
+
465
+    /**
466
+     * Check if field is a checkbox or a radio
467
+     *
468
+     * @return boolean
469
+     */
470
+    public function isCheckable()
471
+    {
472
+        return $this->options['isExpanded'];
473
+    }
474
+
475
+    ////////////////////////////////////////////////////////////////////
476
+    ////////////////////////////// HELPERS /////////////////////////////
477
+    ////////////////////////////////////////////////////////////////////
478
+
479
+    /**
480
+     * Returns the current choices in memory for manipulations
481
+     *
482
+     * @return array The current choices array
483
+     */
484
+    public function getChoices()
485
+    {
486
+        return $this->choices;
487
+    }
488 488
 
489 489
 }
Please login to merge, or discard this patch.
src/Former/Form/Elements.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -12,106 +12,106 @@
 block discarded – undo
12 12
  */
13 13
 class Elements
14 14
 {
15
-	/**
16
-	 * The Container
17
-	 *
18
-	 * @var Container
19
-	 */
20
-	protected $app;
21
-
22
-	/**
23
-	 * The Session instance
24
-	 *
25
-	 * @var Session
26
-	 */
27
-	protected $session;
28
-
29
-	/**
30
-	 * Build a new Element
31
-	 *
32
-	 * @param Container $app
33
-	 */
34
-	public function __construct(Container $app, $session)
35
-	{
36
-		$this->app     = $app;
37
-		$this->session = $session;
38
-	}
39
-
40
-	/**
41
-	 * Generate a hidden field containing the current CSRF token.
42
-	 *
43
-	 * @return string
44
-	 */
45
-	public function token()
46
-	{
47
-		$csrf = method_exists($this->session, 'getToken') ? $this->session->getToken() : $this->session->token();
48
-
49
-		return (string) $this->app['former']->hidden('_token', $csrf);
50
-	}
51
-
52
-	/**
53
-	 * Creates a label tag
54
-	 *
55
-	 * @param  string $label      The label content
56
-	 * @param  string $for        The field the label's for
57
-	 * @param  array  $attributes The label's attributes
58
-	 *
59
-	 * @return Element             A <label> tag
60
-	 */
61
-	public function label($label, $for = null, $attributes = array())
62
-	{
63
-		if (!$label instanceof Htmlable) {
64
-			$oldLabel = (string) $label;
65
-			$label    = Helpers::translate($oldLabel, '');
66
-
67
-			// If there was no change to the label,
68
-			// then a Laravel translation did not occur
69
-			if (lcfirst($label) == $oldLabel) {
70
-				$label = str_replace('_', ' ', $label);
71
-			}
72
-		} else {
73
-			$label = $label->toHtml();
74
-		}
75
-
76
-		$attributes['for']             = $for;
77
-		$this->app['former']->labels[] = $for;
78
-
79
-		return Element::create('label', $label, $attributes);
80
-	}
81
-
82
-	/**
83
-	 * Creates a form legend
84
-	 *
85
-	 * @param  string $legend     The text
86
-	 * @param  array  $attributes Its attributes
87
-	 *
88
-	 * @return Element             A <legend> tag
89
-	 */
90
-	public function legend($legend, $attributes = array())
91
-	{
92
-		$legend = Helpers::translate($legend);
93
-
94
-		return Element::create('legend', $legend, $attributes);
95
-	}
96
-
97
-	/**
98
-	 * Close a field group
99
-	 *
100
-	 * @return string
101
-	 */
102
-	public function closeGroup()
103
-	{
104
-		$closing = '';
105
-		if (Group::$opened && isset(Group::$openGroup)) {
106
-			$closing = Group::$openGroup->close();
107
-		}
108
-
109
-		// Close custom group
110
-		Group::$opened = false;
111
-
112
-		// Reset custom group reference
113
-		Group::$openGroup = null;
114
-
115
-		return $closing;
116
-	}
15
+    /**
16
+     * The Container
17
+     *
18
+     * @var Container
19
+     */
20
+    protected $app;
21
+
22
+    /**
23
+     * The Session instance
24
+     *
25
+     * @var Session
26
+     */
27
+    protected $session;
28
+
29
+    /**
30
+     * Build a new Element
31
+     *
32
+     * @param Container $app
33
+     */
34
+    public function __construct(Container $app, $session)
35
+    {
36
+        $this->app     = $app;
37
+        $this->session = $session;
38
+    }
39
+
40
+    /**
41
+     * Generate a hidden field containing the current CSRF token.
42
+     *
43
+     * @return string
44
+     */
45
+    public function token()
46
+    {
47
+        $csrf = method_exists($this->session, 'getToken') ? $this->session->getToken() : $this->session->token();
48
+
49
+        return (string) $this->app['former']->hidden('_token', $csrf);
50
+    }
51
+
52
+    /**
53
+     * Creates a label tag
54
+     *
55
+     * @param  string $label      The label content
56
+     * @param  string $for        The field the label's for
57
+     * @param  array  $attributes The label's attributes
58
+     *
59
+     * @return Element             A <label> tag
60
+     */
61
+    public function label($label, $for = null, $attributes = array())
62
+    {
63
+        if (!$label instanceof Htmlable) {
64
+            $oldLabel = (string) $label;
65
+            $label    = Helpers::translate($oldLabel, '');
66
+
67
+            // If there was no change to the label,
68
+            // then a Laravel translation did not occur
69
+            if (lcfirst($label) == $oldLabel) {
70
+                $label = str_replace('_', ' ', $label);
71
+            }
72
+        } else {
73
+            $label = $label->toHtml();
74
+        }
75
+
76
+        $attributes['for']             = $for;
77
+        $this->app['former']->labels[] = $for;
78
+
79
+        return Element::create('label', $label, $attributes);
80
+    }
81
+
82
+    /**
83
+     * Creates a form legend
84
+     *
85
+     * @param  string $legend     The text
86
+     * @param  array  $attributes Its attributes
87
+     *
88
+     * @return Element             A <legend> tag
89
+     */
90
+    public function legend($legend, $attributes = array())
91
+    {
92
+        $legend = Helpers::translate($legend);
93
+
94
+        return Element::create('legend', $legend, $attributes);
95
+    }
96
+
97
+    /**
98
+     * Close a field group
99
+     *
100
+     * @return string
101
+     */
102
+    public function closeGroup()
103
+    {
104
+        $closing = '';
105
+        if (Group::$opened && isset(Group::$openGroup)) {
106
+            $closing = Group::$openGroup->close();
107
+        }
108
+
109
+        // Close custom group
110
+        Group::$opened = false;
111
+
112
+        // Reset custom group reference
113
+        Group::$openGroup = null;
114
+
115
+        return $closing;
116
+    }
117 117
 }
Please login to merge, or discard this patch.
src/Former/Helpers.php 1 patch
Indentation   +191 added lines, -191 removed lines patch added patch discarded remove patch
@@ -9,195 +9,195 @@
 block discarded – undo
9 9
  */
10 10
 class Helpers
11 11
 {
12
-	/**
13
-	 * The IoC Container
14
-	 *
15
-	 * @var Container
16
-	 */
17
-	protected static $app;
18
-
19
-	/**
20
-	 * Bind a Container to the Helpers class
21
-	 *
22
-	 * @param Container $app
23
-	 */
24
-	public static function setApp(Container $app)
25
-	{
26
-		static::$app = $app;
27
-	}
28
-
29
-	/**
30
-	 * Encodes HTML
31
-	 *
32
-	 * @param string|null $value The string to encode
33
-	 *
34
-	 * @return string
35
-	 */
36
-	public static function encode($value)
37
-	{
38
-		if ($value === null) {
39
-			return '';
40
-		}
41
-
42
-		return htmlentities($value, ENT_QUOTES, 'UTF-8', true);
43
-	}
44
-
45
-	////////////////////////////////////////////////////////////////////
46
-	///////////////////////// LOCALIZATION HELPERS /////////////////////
47
-	////////////////////////////////////////////////////////////////////
48
-
49
-	/**
50
-	 * Translates a string by trying several fallbacks
51
-	 *
52
-	 * @param  string $key      The key to translate
53
-	 * @param  string $fallback The ultimate fallback
54
-	 *
55
-	 * @return string           A translated string
56
-	 */
57
-	public static function translate($key, $fallback = null)
58
-	{
59
-		// If nothing was given, return nothing, bitch
60
-		if (!$key) {
61
-			return $fallback;
62
-		}
63
-
64
-		// If no fallback, use the key
65
-		if (!$fallback) {
66
-			$fallback = $key;
67
-		}
68
-
69
-		// Assure we don't already have a Lang object
70
-		if (is_object($key) and method_exists($key, 'get')) {
71
-			return $key->get();
72
-		}
73
-
74
-		$translation   = null;
75
-		$translateFrom = static::$app['former']->getOption('translate_from');
76
-		if (substr($translateFrom, -1) !== '/') {
77
-			$translateFrom .= '.';
78
-		}
79
-		$translateFrom .= $key;
80
-
81
-		// Convert a[b[c]] to a.b.c for nested translations [a => [b => 'B!']]
82
-		if (strpos($translateFrom, ']') !== false) {
83
-			$translateFrom = str_replace(array(']', '['), array('', '.'), $translateFrom);
84
-		}
85
-
86
-		// Search for the key itself, if it is valid
87
-		$validKey = preg_match("/^[a-z0-9_-]+([.][a-z0-9 _-]+)+$/i", $key) === 1;
88
-		if ($validKey && static::$app['translator']->has($key)) {
89
-			$translation = static::$app['translator']->get($key);
90
-		} elseif (static::$app['translator']->has($translateFrom)) {
91
-			$translation = static::$app['translator']->get($translateFrom);
92
-		}
93
-
94
-		// Replace by fallback if invalid
95
-		if (!$translation or is_array($translation)) {
96
-			$translation = $fallback;
97
-		}
98
-
99
-		// Capitalize
100
-		$capitalize = static::$app['former']->getOption('capitalize_translations');
101
-
102
-		return $capitalize ? ucfirst($translation) : $translation;
103
-	}
104
-
105
-	////////////////////////////////////////////////////////////////////
106
-	////////////////////////// DATABASE HELPERS ////////////////////////
107
-	////////////////////////////////////////////////////////////////////
108
-
109
-	/**
110
-	 * Transforms an array of models into an associative array
111
-	 *
112
-	 * @param  array|object    $query      The array of results
113
-	 * @param  string|function $text       The value to use as text
114
-	 * @param  string|array    $attributes The data to use as attributes
115
-	 *
116
-	 * @return array               A data array
117
-	 */
118
-	public static function queryToArray($query, $text = null, $attributes = null)
119
-	{
120
-		// Automatically fetch Lang objects for people who store translated options lists
121
-		// Same of unfetched queries
122
-		if (!$query instanceof Collection) {
123
-			if ((is_object($query) || is_string($query)) && method_exists($query, 'get')) {
124
-				$query = $query->get();
125
-			}
126
-			if (!is_array($query)) {
127
-				$query = (array) $query;
128
-			}
129
-		}
130
-
131
-		//Convert parametrs of old format to new format
132
-		if (!is_callable($text)) {
133
-			$optionTextValue = $text;
134
-			$text = function ($model) use ($optionTextValue) {
135
-				if ($optionTextValue and isset($model->$optionTextValue)) {
136
-					return $model->$optionTextValue;
137
-				} elseif ((is_object($model) || is_string($model)) && method_exists($model, '__toString')) {
138
-					return  $model->__toString();
139
-				} else {
140
-					return null;
141
-				}
142
-			};
143
-		}
144
-
145
-		if (!is_array($attributes)) {
146
-			if (is_string($attributes)) {
147
-				$attributes = ['value' => $attributes];
148
-			} else {
149
-				$attributes = ['value' => null];
150
-			}
151
-		}
152
-
153
-		if (!isset($attributes['value'])) {
154
-			$attributes['value'] = null;
155
-		}
156
-		//-------------------------------------------------
157
-
158
-		// Populates the new options
159
-		foreach ($query as $model) {
160
-			// If it's an array, convert to object
161
-			if (is_array($model)) {
162
-				$model = (object) $model;
163
-			}
164
-
165
-			// Calculate option text
166
-			$optionText = $text($model);
167
-
168
-			// Skip if no text value found
169
-			if (!$optionText) {
170
-				continue;
171
-			}
172
-
173
-			//Collect option attributes
174
-			foreach ($attributes as $optionAttributeName => $modelAttributeName) {
175
-				if (is_callable($modelAttributeName)) {
176
-					$optionAttributeValue = $modelAttributeName($model);
177
-				} elseif ($modelAttributeName and isset($model->$modelAttributeName)) {
178
-					$optionAttributeValue = $model->$modelAttributeName;
179
-				} elseif($optionAttributeName === 'value') {
180
-					//For backward compatibility
181
-					if (method_exists($model, 'getKey')) {
182
-						$optionAttributeValue = $model->getKey();
183
-					} elseif (isset($model->id)) {
184
-						$optionAttributeValue = $model->id;
185
-					} else {
186
-						$optionAttributeValue = $optionText;
187
-					}
188
-				} else {
189
-					$optionAttributeValue = '';
190
-				}
191
-
192
-				//For backward compatibility
193
-				if (count($attributes) === 1) {
194
-					$array[$optionAttributeValue] = (string) $optionText;
195
-				} else {
196
-					$array[$optionText][$optionAttributeName] = (string) $optionAttributeValue;
197
-				}
198
-			}
199
-		}
200
-
201
-		return !empty($array) ? $array : $query;
202
-	}
12
+    /**
13
+     * The IoC Container
14
+     *
15
+     * @var Container
16
+     */
17
+    protected static $app;
18
+
19
+    /**
20
+     * Bind a Container to the Helpers class
21
+     *
22
+     * @param Container $app
23
+     */
24
+    public static function setApp(Container $app)
25
+    {
26
+        static::$app = $app;
27
+    }
28
+
29
+    /**
30
+     * Encodes HTML
31
+     *
32
+     * @param string|null $value The string to encode
33
+     *
34
+     * @return string
35
+     */
36
+    public static function encode($value)
37
+    {
38
+        if ($value === null) {
39
+            return '';
40
+        }
41
+
42
+        return htmlentities($value, ENT_QUOTES, 'UTF-8', true);
43
+    }
44
+
45
+    ////////////////////////////////////////////////////////////////////
46
+    ///////////////////////// LOCALIZATION HELPERS /////////////////////
47
+    ////////////////////////////////////////////////////////////////////
48
+
49
+    /**
50
+     * Translates a string by trying several fallbacks
51
+     *
52
+     * @param  string $key      The key to translate
53
+     * @param  string $fallback The ultimate fallback
54
+     *
55
+     * @return string           A translated string
56
+     */
57
+    public static function translate($key, $fallback = null)
58
+    {
59
+        // If nothing was given, return nothing, bitch
60
+        if (!$key) {
61
+            return $fallback;
62
+        }
63
+
64
+        // If no fallback, use the key
65
+        if (!$fallback) {
66
+            $fallback = $key;
67
+        }
68
+
69
+        // Assure we don't already have a Lang object
70
+        if (is_object($key) and method_exists($key, 'get')) {
71
+            return $key->get();
72
+        }
73
+
74
+        $translation   = null;
75
+        $translateFrom = static::$app['former']->getOption('translate_from');
76
+        if (substr($translateFrom, -1) !== '/') {
77
+            $translateFrom .= '.';
78
+        }
79
+        $translateFrom .= $key;
80
+
81
+        // Convert a[b[c]] to a.b.c for nested translations [a => [b => 'B!']]
82
+        if (strpos($translateFrom, ']') !== false) {
83
+            $translateFrom = str_replace(array(']', '['), array('', '.'), $translateFrom);
84
+        }
85
+
86
+        // Search for the key itself, if it is valid
87
+        $validKey = preg_match("/^[a-z0-9_-]+([.][a-z0-9 _-]+)+$/i", $key) === 1;
88
+        if ($validKey && static::$app['translator']->has($key)) {
89
+            $translation = static::$app['translator']->get($key);
90
+        } elseif (static::$app['translator']->has($translateFrom)) {
91
+            $translation = static::$app['translator']->get($translateFrom);
92
+        }
93
+
94
+        // Replace by fallback if invalid
95
+        if (!$translation or is_array($translation)) {
96
+            $translation = $fallback;
97
+        }
98
+
99
+        // Capitalize
100
+        $capitalize = static::$app['former']->getOption('capitalize_translations');
101
+
102
+        return $capitalize ? ucfirst($translation) : $translation;
103
+    }
104
+
105
+    ////////////////////////////////////////////////////////////////////
106
+    ////////////////////////// DATABASE HELPERS ////////////////////////
107
+    ////////////////////////////////////////////////////////////////////
108
+
109
+    /**
110
+     * Transforms an array of models into an associative array
111
+     *
112
+     * @param  array|object    $query      The array of results
113
+     * @param  string|function $text       The value to use as text
114
+     * @param  string|array    $attributes The data to use as attributes
115
+     *
116
+     * @return array               A data array
117
+     */
118
+    public static function queryToArray($query, $text = null, $attributes = null)
119
+    {
120
+        // Automatically fetch Lang objects for people who store translated options lists
121
+        // Same of unfetched queries
122
+        if (!$query instanceof Collection) {
123
+            if ((is_object($query) || is_string($query)) && method_exists($query, 'get')) {
124
+                $query = $query->get();
125
+            }
126
+            if (!is_array($query)) {
127
+                $query = (array) $query;
128
+            }
129
+        }
130
+
131
+        //Convert parametrs of old format to new format
132
+        if (!is_callable($text)) {
133
+            $optionTextValue = $text;
134
+            $text = function ($model) use ($optionTextValue) {
135
+                if ($optionTextValue and isset($model->$optionTextValue)) {
136
+                    return $model->$optionTextValue;
137
+                } elseif ((is_object($model) || is_string($model)) && method_exists($model, '__toString')) {
138
+                    return  $model->__toString();
139
+                } else {
140
+                    return null;
141
+                }
142
+            };
143
+        }
144
+
145
+        if (!is_array($attributes)) {
146
+            if (is_string($attributes)) {
147
+                $attributes = ['value' => $attributes];
148
+            } else {
149
+                $attributes = ['value' => null];
150
+            }
151
+        }
152
+
153
+        if (!isset($attributes['value'])) {
154
+            $attributes['value'] = null;
155
+        }
156
+        //-------------------------------------------------
157
+
158
+        // Populates the new options
159
+        foreach ($query as $model) {
160
+            // If it's an array, convert to object
161
+            if (is_array($model)) {
162
+                $model = (object) $model;
163
+            }
164
+
165
+            // Calculate option text
166
+            $optionText = $text($model);
167
+
168
+            // Skip if no text value found
169
+            if (!$optionText) {
170
+                continue;
171
+            }
172
+
173
+            //Collect option attributes
174
+            foreach ($attributes as $optionAttributeName => $modelAttributeName) {
175
+                if (is_callable($modelAttributeName)) {
176
+                    $optionAttributeValue = $modelAttributeName($model);
177
+                } elseif ($modelAttributeName and isset($model->$modelAttributeName)) {
178
+                    $optionAttributeValue = $model->$modelAttributeName;
179
+                } elseif($optionAttributeName === 'value') {
180
+                    //For backward compatibility
181
+                    if (method_exists($model, 'getKey')) {
182
+                        $optionAttributeValue = $model->getKey();
183
+                    } elseif (isset($model->id)) {
184
+                        $optionAttributeValue = $model->id;
185
+                    } else {
186
+                        $optionAttributeValue = $optionText;
187
+                    }
188
+                } else {
189
+                    $optionAttributeValue = '';
190
+                }
191
+
192
+                //For backward compatibility
193
+                if (count($attributes) === 1) {
194
+                    $array[$optionAttributeValue] = (string) $optionText;
195
+                } else {
196
+                    $array[$optionText][$optionAttributeName] = (string) $optionAttributeValue;
197
+                }
198
+            }
199
+        }
200
+
201
+        return !empty($array) ? $array : $query;
202
+    }
203 203
 }
Please login to merge, or discard this patch.
src/Former/Framework/TwitterBootstrap3.php 1 patch
Indentation   +433 added lines, -433 removed lines patch added patch discarded remove patch
@@ -13,437 +13,437 @@
 block discarded – undo
13 13
  */
14 14
 class TwitterBootstrap3 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
-		'default',
35
-		'primary',
36
-		'warning',
37
-		'danger',
38
-		'success',
39
-		'info',
40
-	);
41
-
42
-	/**
43
-	 * The field sizes available
44
-	 *
45
-	 * @var array
46
-	 */
47
-	private $fields = array(
48
-		'lg',
49
-		'sm',
50
-		// 'col-xs-1', 'col-xs-2', 'col-xs-3', 'col-xs-4', 'col-xs-5', 'col-xs-6',
51
-		// 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12',
52
-		// 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6',
53
-		// 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12',
54
-		// 'col-md-1', 'col-md-2', 'col-md-3', 'col-md-4', 'col-md-5', 'col-md-6',
55
-		// 'col-md-7', 'col-md-8', 'col-md-9', 'col-md-10', 'col-md-11', 'col-md-12',
56
-		// 'col-lg-1', 'col-lg-2', 'col-lg-3', 'col-lg-4', 'col-lg-5', 'col-lg-6',
57
-		// 'col-lg-7', 'col-lg-8', 'col-lg-9', 'col-lg-10', 'col-lg-11', 'col-lg-12',
58
-	);
59
-
60
-	/**
61
-	 * The field states available
62
-	 *
63
-	 * @var array
64
-	 */
65
-	protected $states = array(
66
-		'has-warning',
67
-		'has-error',
68
-		'has-success',
69
-	);
70
-
71
-	/**
72
-	 * The default HTML tag used for icons
73
-	 *
74
-	 * @var string
75
-	 */
76
-	protected $iconTag = 'span';
77
-
78
-	/**
79
-	 * The default set for icon fonts
80
-	 * By default Bootstrap 3 offers only 'glyphicon'
81
-	 * See Former docs to use 'social' and 'filetypes' sets for specific icons.
82
-	 *
83
-	 * @var string
84
-	 */
85
-	protected $iconSet = 'glyphicon';
86
-
87
-	/**
88
-	 * The default prefix icon names
89
-	 * "icon" works for Bootstrap 2 and Font-awesome
90
-	 *
91
-	 * @var string
92
-	 */
93
-	protected $iconPrefix = 'glyphicon';
94
-
95
-	/**
96
-	 * Create a new TwitterBootstrap instance
97
-	 *
98
-	 * @param \Illuminate\Container\Container $app
99
-	 */
100
-	public function __construct(Container $app)
101
-	{
102
-		$this->app = $app;
103
-		$this->setFrameworkDefaults();
104
-	}
105
-
106
-	////////////////////////////////////////////////////////////////////
107
-	/////////////////////////// FILTER ARRAYS //////////////////////////
108
-	////////////////////////////////////////////////////////////////////
109
-
110
-	/**
111
-	 * Filter buttons classes
112
-	 *
113
-	 * @param  array $classes An array of classes
114
-	 *
115
-	 * @return string[] A filtered array
116
-	 */
117
-	public function filterButtonClasses($classes)
118
-	{
119
-		// Filter classes
120
-		// $classes = array_intersect($classes, $this->buttons);
121
-
122
-		// Prepend button type
123
-		$classes   = $this->prependWith($classes, 'btn-');
124
-		$classes[] = 'btn';
125
-
126
-		return $classes;
127
-	}
128
-
129
-	/**
130
-	 * Filter field classes
131
-	 *
132
-	 * @param  array $classes An array of classes
133
-	 *
134
-	 * @return array A filtered array
135
-	 */
136
-	public function filterFieldClasses($classes)
137
-	{
138
-		// Filter classes
139
-		$classes = array_intersect($classes, $this->fields);
140
-
141
-		// Prepend field type
142
-		$classes = array_map(function ($class) {
143
-			return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
144
-		}, $classes);
145
-
146
-		return $classes;
147
-	}
148
-
149
-	////////////////////////////////////////////////////////////////////
150
-	///////////////////// EXPOSE FRAMEWORK SPECIFICS ///////////////////
151
-	////////////////////////////////////////////////////////////////////
152
-
153
-	/**
154
-	 * Framework error state
155
-	 *
156
-	 * @return string
157
-	 */
158
-	public function errorState()
159
-	{
160
-		return 'has-error';
161
-	}
162
-
163
-	/**
164
-	 * Returns corresponding inline class of a field
165
-	 *
166
-	 * @param Field $field
167
-	 *
168
-	 * @return string
169
-	 */
170
-	public function getInlineLabelClass($field)
171
-	{
172
-		$inlineClass = parent::getInlineLabelClass($field);
173
-		if ($field->isOfType('checkbox', 'checkboxes')) {
174
-			$inlineClass = 'checkbox-'.$inlineClass;
175
-		} elseif ($field->isOfType('radio', 'radios')) {
176
-			$inlineClass = 'radio-'.$inlineClass;
177
-		}
178
-
179
-		return $inlineClass;
180
-	}
181
-
182
-	/**
183
-	 * Set the fields width from a label width
184
-	 *
185
-	 * @param array $labelWidths
186
-	 */
187
-	protected function setFieldWidths($labelWidths)
188
-	{
189
-		$labelWidthClass = $fieldWidthClass = $fieldOffsetClass = '';
190
-
191
-		$viewports = $this->getFrameworkOption('viewports');
192
-		foreach ($labelWidths as $viewport => $columns) {
193
-			if ($viewport) {
194
-				$labelWidthClass .= " col-$viewports[$viewport]-$columns";
195
-				$fieldWidthClass .= " col-$viewports[$viewport]-".(12 - $columns);
196
-				$fieldOffsetClass .= " col-$viewports[$viewport]-offset-$columns";
197
-			}
198
-		}
199
-
200
-		$this->labelWidth  = ltrim($labelWidthClass);
201
-		$this->fieldWidth  = ltrim($fieldWidthClass);
202
-		$this->fieldOffset = ltrim($fieldOffsetClass);
203
-	}
204
-
205
-	////////////////////////////////////////////////////////////////////
206
-	///////////////////////////// ADD CLASSES //////////////////////////
207
-	////////////////////////////////////////////////////////////////////
208
-
209
-	/**
210
-	 * Add classes to a field
211
-	 *
212
-	 * @param Field $field
213
-	 * @param array $classes The possible classes to add
214
-	 *
215
-	 * @return Field
216
-	 */
217
-	public function getFieldClasses(Field $field, $classes)
218
-	{
219
-		// Add inline class for checkables
220
-		if ($field->isCheckable() and in_array('inline', $classes)) {
221
-			$field->inline();
222
-		}
223
-
224
-		// Filter classes according to field type
225
-		if ($field->isButton()) {
226
-			$classes = $this->filterButtonClasses($classes);
227
-		} else {
228
-			$classes = $this->filterFieldClasses($classes);
229
-		}
230
-
231
-		// Add form-control class for text-type, textarea and select fields
232
-		// As text-type is open-ended we instead exclude those that shouldn't receive the class
233
-		if (!$field->isCheckable() and !$field->isButton() and !in_array($field->getType(), array(
234
-					'file',
235
-					'plaintext',
236
-				)) and !in_array('form-control', $classes)
237
-		) {
238
-			$classes[] = 'form-control';
239
-		}
240
-
241
-		return $this->addClassesToField($field, $classes);
242
-	}
243
-
244
-	/**
245
-	 * Add group classes
246
-	 *
247
-	 * @return string A list of group classes
248
-	 */
249
-	public function getGroupClasses()
250
-	{
251
-		return 'form-group';
252
-	}
253
-
254
-	/**
255
-	 * Add label classes
256
-	 *
257
-	 * @return string[] An array of attributes with the label class
258
-	 */
259
-	public function getLabelClasses()
260
-	{
261
-		if ($this->app['former.form']->isOfType('horizontal')) {
262
-			return array('control-label', $this->labelWidth);
263
-		} elseif ($this->app['former.form']->isOfType('inline')) {
264
-			return array('sr-only');
265
-		} else {
266
-			return array('control-label');
267
-		}
268
-	}
269
-
270
-	/**
271
-	 * Add uneditable field classes
272
-	 *
273
-	 * @return string An array of attributes with the uneditable class
274
-	 */
275
-	public function getUneditableClasses()
276
-	{
277
-		return '';
278
-	}
279
-
280
-	/**
281
-	 * Add plain text field classes
282
-	 *
283
-	 * @return string An array of attributes with the plain text class
284
-	 */
285
-	public function getPlainTextClasses()
286
-	{
287
-		return 'form-control-static';
288
-	}
289
-
290
-	/**
291
-	 * Add form class
292
-	 *
293
-	 * @param  string $type The type of form to add
294
-	 *
295
-	 * @return string|null
296
-	 */
297
-	public function getFormClasses($type)
298
-	{
299
-		return $type ? 'form-'.$type : null;
300
-	}
301
-
302
-	/**
303
-	 * Add actions block class
304
-	 *
305
-	 * @return string|null
306
-	 */
307
-	public function getActionClasses()
308
-	{
309
-		if ($this->app['former.form']->isOfType('horizontal') || $this->app['former.form']->isOfType('inline')) {
310
-			return 'form-group';
311
-		}
312
-
313
-		return null;
314
-	}
315
-
316
-	////////////////////////////////////////////////////////////////////
317
-	//////////////////////////// RENDER BLOCKS /////////////////////////
318
-	////////////////////////////////////////////////////////////////////
319
-
320
-	/**
321
-	 * Render an help text
322
-	 *
323
-	 * @param string $text
324
-	 * @param array  $attributes
325
-	 *
326
-	 * @return Element
327
-	 */
328
-	public function createHelp($text, $attributes = array())
329
-	{
330
-		return Element::create('span', $text, $attributes)->addClass('help-block');
331
-	}
332
-
333
-	/**
334
-	 * Render an help text
335
-	 *
336
-	 * @param string $text
337
-	 * @param array  $attributes
338
-	 *
339
-	 * @return Element
340
-	 */
341
-	public function createBlockHelp($text, $attributes = array())
342
-	{
343
-		return Element::create('p', $text, $attributes)->addClass('help-block');
344
-	}
345
-
346
-	/**
347
-	 * Render a disabled field
348
-	 *
349
-	 * @param Field $field
350
-	 *
351
-	 * @return Element
352
-	 */
353
-	public function createDisabledField(Field $field)
354
-	{
355
-		return Element::create('span', $field->getValue(), $field->getAttributes());
356
-	}
357
-
358
-	/**
359
-	 * Render a plain text field
360
-	 *
361
-	 * @param Field $field
362
-	 *
363
-	 * @return Element
364
-	 */
365
-	public function createPlainTextField(Field $field)
366
-	{
367
-		$label = $field->getLabel();
368
-		if ($label) {
369
-			$label->for('');
370
-		}
371
-
372
-		return Element::create('div', $field->getValue(), $field->getAttributes());
373
-	}
374
-
375
-	////////////////////////////////////////////////////////////////////
376
-	//////////////////////////// WRAP BLOCKS ///////////////////////////
377
-	////////////////////////////////////////////////////////////////////
378
-
379
-	/**
380
-	 * Wrap an item to be prepended or appended to the current field
381
-	 *
382
-	 * @return Element A wrapped item
383
-	 */
384
-	public function placeAround($item)
385
-	{
386
-		// Render object
387
-		if (is_object($item) and method_exists($item, '__toString')) {
388
-			$item = $item->__toString();
389
-		}
390
-
391
-		// Get class to use
392
-		$class = (strpos($item, '<button') !== false) ? 'btn' : 'addon';
393
-
394
-		return Element::create('span', $item)->addClass('input-group-'.$class);
395
-	}
396
-
397
-	/**
398
-	 * Wrap a field with prepended and appended items
399
-	 *
400
-	 * @param  Field $field
401
-	 * @param  array $prepend
402
-	 * @param  array $append
403
-	 *
404
-	 * @return string A field concatented with prepended and/or appended items
405
-	 */
406
-	public function prependAppend($field, $prepend, $append)
407
-	{
408
-		$return = '<div class="input-group">';
409
-		$return .= implode('', $prepend);
410
-		$return .= $field->render();
411
-		$return .= implode('', $append);
412
-		$return .= '</div>';
413
-
414
-		return $return;
415
-	}
416
-
417
-	/**
418
-	 * Wrap a field with potential additional tags
419
-	 *
420
-	 * @param  Field $field
421
-	 *
422
-	 * @return Element A wrapped field
423
-	 */
424
-	public function wrapField($field)
425
-	{
426
-		if ($this->app['former.form']->isOfType('horizontal')) {
427
-			return Element::create('div', $field)->addClass($this->fieldWidth);
428
-		}
429
-
430
-		return $field;
431
-	}
432
-
433
-	/**
434
-	 * Wrap actions block with potential additional tags
435
-	 *
436
-	 * @param  Actions $actions
437
-	 *
438
-	 * @return string A wrapped actions block
439
-	 */
440
-	public function wrapActions($actions)
441
-	{
442
-		// For horizontal forms, we wrap the actions in a div
443
-		if ($this->app['former.form']->isOfType('horizontal')) {
444
-			return Element::create('div', $actions)->addClass(array($this->fieldOffset, $this->fieldWidth));
445
-		}
446
-
447
-		return $actions;
448
-	}
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
+        'default',
35
+        'primary',
36
+        'warning',
37
+        'danger',
38
+        'success',
39
+        'info',
40
+    );
41
+
42
+    /**
43
+     * The field sizes available
44
+     *
45
+     * @var array
46
+     */
47
+    private $fields = array(
48
+        'lg',
49
+        'sm',
50
+        // 'col-xs-1', 'col-xs-2', 'col-xs-3', 'col-xs-4', 'col-xs-5', 'col-xs-6',
51
+        // 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12',
52
+        // 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6',
53
+        // 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12',
54
+        // 'col-md-1', 'col-md-2', 'col-md-3', 'col-md-4', 'col-md-5', 'col-md-6',
55
+        // 'col-md-7', 'col-md-8', 'col-md-9', 'col-md-10', 'col-md-11', 'col-md-12',
56
+        // 'col-lg-1', 'col-lg-2', 'col-lg-3', 'col-lg-4', 'col-lg-5', 'col-lg-6',
57
+        // 'col-lg-7', 'col-lg-8', 'col-lg-9', 'col-lg-10', 'col-lg-11', 'col-lg-12',
58
+    );
59
+
60
+    /**
61
+     * The field states available
62
+     *
63
+     * @var array
64
+     */
65
+    protected $states = array(
66
+        'has-warning',
67
+        'has-error',
68
+        'has-success',
69
+    );
70
+
71
+    /**
72
+     * The default HTML tag used for icons
73
+     *
74
+     * @var string
75
+     */
76
+    protected $iconTag = 'span';
77
+
78
+    /**
79
+     * The default set for icon fonts
80
+     * By default Bootstrap 3 offers only 'glyphicon'
81
+     * See Former docs to use 'social' and 'filetypes' sets for specific icons.
82
+     *
83
+     * @var string
84
+     */
85
+    protected $iconSet = 'glyphicon';
86
+
87
+    /**
88
+     * The default prefix icon names
89
+     * "icon" works for Bootstrap 2 and Font-awesome
90
+     *
91
+     * @var string
92
+     */
93
+    protected $iconPrefix = 'glyphicon';
94
+
95
+    /**
96
+     * Create a new TwitterBootstrap instance
97
+     *
98
+     * @param \Illuminate\Container\Container $app
99
+     */
100
+    public function __construct(Container $app)
101
+    {
102
+        $this->app = $app;
103
+        $this->setFrameworkDefaults();
104
+    }
105
+
106
+    ////////////////////////////////////////////////////////////////////
107
+    /////////////////////////// FILTER ARRAYS //////////////////////////
108
+    ////////////////////////////////////////////////////////////////////
109
+
110
+    /**
111
+     * Filter buttons classes
112
+     *
113
+     * @param  array $classes An array of classes
114
+     *
115
+     * @return string[] A filtered array
116
+     */
117
+    public function filterButtonClasses($classes)
118
+    {
119
+        // Filter classes
120
+        // $classes = array_intersect($classes, $this->buttons);
121
+
122
+        // Prepend button type
123
+        $classes   = $this->prependWith($classes, 'btn-');
124
+        $classes[] = 'btn';
125
+
126
+        return $classes;
127
+    }
128
+
129
+    /**
130
+     * Filter field classes
131
+     *
132
+     * @param  array $classes An array of classes
133
+     *
134
+     * @return array A filtered array
135
+     */
136
+    public function filterFieldClasses($classes)
137
+    {
138
+        // Filter classes
139
+        $classes = array_intersect($classes, $this->fields);
140
+
141
+        // Prepend field type
142
+        $classes = array_map(function ($class) {
143
+            return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
144
+        }, $classes);
145
+
146
+        return $classes;
147
+    }
148
+
149
+    ////////////////////////////////////////////////////////////////////
150
+    ///////////////////// EXPOSE FRAMEWORK SPECIFICS ///////////////////
151
+    ////////////////////////////////////////////////////////////////////
152
+
153
+    /**
154
+     * Framework error state
155
+     *
156
+     * @return string
157
+     */
158
+    public function errorState()
159
+    {
160
+        return 'has-error';
161
+    }
162
+
163
+    /**
164
+     * Returns corresponding inline class of a field
165
+     *
166
+     * @param Field $field
167
+     *
168
+     * @return string
169
+     */
170
+    public function getInlineLabelClass($field)
171
+    {
172
+        $inlineClass = parent::getInlineLabelClass($field);
173
+        if ($field->isOfType('checkbox', 'checkboxes')) {
174
+            $inlineClass = 'checkbox-'.$inlineClass;
175
+        } elseif ($field->isOfType('radio', 'radios')) {
176
+            $inlineClass = 'radio-'.$inlineClass;
177
+        }
178
+
179
+        return $inlineClass;
180
+    }
181
+
182
+    /**
183
+     * Set the fields width from a label width
184
+     *
185
+     * @param array $labelWidths
186
+     */
187
+    protected function setFieldWidths($labelWidths)
188
+    {
189
+        $labelWidthClass = $fieldWidthClass = $fieldOffsetClass = '';
190
+
191
+        $viewports = $this->getFrameworkOption('viewports');
192
+        foreach ($labelWidths as $viewport => $columns) {
193
+            if ($viewport) {
194
+                $labelWidthClass .= " col-$viewports[$viewport]-$columns";
195
+                $fieldWidthClass .= " col-$viewports[$viewport]-".(12 - $columns);
196
+                $fieldOffsetClass .= " col-$viewports[$viewport]-offset-$columns";
197
+            }
198
+        }
199
+
200
+        $this->labelWidth  = ltrim($labelWidthClass);
201
+        $this->fieldWidth  = ltrim($fieldWidthClass);
202
+        $this->fieldOffset = ltrim($fieldOffsetClass);
203
+    }
204
+
205
+    ////////////////////////////////////////////////////////////////////
206
+    ///////////////////////////// ADD CLASSES //////////////////////////
207
+    ////////////////////////////////////////////////////////////////////
208
+
209
+    /**
210
+     * Add classes to a field
211
+     *
212
+     * @param Field $field
213
+     * @param array $classes The possible classes to add
214
+     *
215
+     * @return Field
216
+     */
217
+    public function getFieldClasses(Field $field, $classes)
218
+    {
219
+        // Add inline class for checkables
220
+        if ($field->isCheckable() and in_array('inline', $classes)) {
221
+            $field->inline();
222
+        }
223
+
224
+        // Filter classes according to field type
225
+        if ($field->isButton()) {
226
+            $classes = $this->filterButtonClasses($classes);
227
+        } else {
228
+            $classes = $this->filterFieldClasses($classes);
229
+        }
230
+
231
+        // Add form-control class for text-type, textarea and select fields
232
+        // As text-type is open-ended we instead exclude those that shouldn't receive the class
233
+        if (!$field->isCheckable() and !$field->isButton() and !in_array($field->getType(), array(
234
+                    'file',
235
+                    'plaintext',
236
+                )) and !in_array('form-control', $classes)
237
+        ) {
238
+            $classes[] = 'form-control';
239
+        }
240
+
241
+        return $this->addClassesToField($field, $classes);
242
+    }
243
+
244
+    /**
245
+     * Add group classes
246
+     *
247
+     * @return string A list of group classes
248
+     */
249
+    public function getGroupClasses()
250
+    {
251
+        return 'form-group';
252
+    }
253
+
254
+    /**
255
+     * Add label classes
256
+     *
257
+     * @return string[] An array of attributes with the label class
258
+     */
259
+    public function getLabelClasses()
260
+    {
261
+        if ($this->app['former.form']->isOfType('horizontal')) {
262
+            return array('control-label', $this->labelWidth);
263
+        } elseif ($this->app['former.form']->isOfType('inline')) {
264
+            return array('sr-only');
265
+        } else {
266
+            return array('control-label');
267
+        }
268
+    }
269
+
270
+    /**
271
+     * Add uneditable field classes
272
+     *
273
+     * @return string An array of attributes with the uneditable class
274
+     */
275
+    public function getUneditableClasses()
276
+    {
277
+        return '';
278
+    }
279
+
280
+    /**
281
+     * Add plain text field classes
282
+     *
283
+     * @return string An array of attributes with the plain text class
284
+     */
285
+    public function getPlainTextClasses()
286
+    {
287
+        return 'form-control-static';
288
+    }
289
+
290
+    /**
291
+     * Add form class
292
+     *
293
+     * @param  string $type The type of form to add
294
+     *
295
+     * @return string|null
296
+     */
297
+    public function getFormClasses($type)
298
+    {
299
+        return $type ? 'form-'.$type : null;
300
+    }
301
+
302
+    /**
303
+     * Add actions block class
304
+     *
305
+     * @return string|null
306
+     */
307
+    public function getActionClasses()
308
+    {
309
+        if ($this->app['former.form']->isOfType('horizontal') || $this->app['former.form']->isOfType('inline')) {
310
+            return 'form-group';
311
+        }
312
+
313
+        return null;
314
+    }
315
+
316
+    ////////////////////////////////////////////////////////////////////
317
+    //////////////////////////// RENDER BLOCKS /////////////////////////
318
+    ////////////////////////////////////////////////////////////////////
319
+
320
+    /**
321
+     * Render an help text
322
+     *
323
+     * @param string $text
324
+     * @param array  $attributes
325
+     *
326
+     * @return Element
327
+     */
328
+    public function createHelp($text, $attributes = array())
329
+    {
330
+        return Element::create('span', $text, $attributes)->addClass('help-block');
331
+    }
332
+
333
+    /**
334
+     * Render an help text
335
+     *
336
+     * @param string $text
337
+     * @param array  $attributes
338
+     *
339
+     * @return Element
340
+     */
341
+    public function createBlockHelp($text, $attributes = array())
342
+    {
343
+        return Element::create('p', $text, $attributes)->addClass('help-block');
344
+    }
345
+
346
+    /**
347
+     * Render a disabled field
348
+     *
349
+     * @param Field $field
350
+     *
351
+     * @return Element
352
+     */
353
+    public function createDisabledField(Field $field)
354
+    {
355
+        return Element::create('span', $field->getValue(), $field->getAttributes());
356
+    }
357
+
358
+    /**
359
+     * Render a plain text field
360
+     *
361
+     * @param Field $field
362
+     *
363
+     * @return Element
364
+     */
365
+    public function createPlainTextField(Field $field)
366
+    {
367
+        $label = $field->getLabel();
368
+        if ($label) {
369
+            $label->for('');
370
+        }
371
+
372
+        return Element::create('div', $field->getValue(), $field->getAttributes());
373
+    }
374
+
375
+    ////////////////////////////////////////////////////////////////////
376
+    //////////////////////////// WRAP BLOCKS ///////////////////////////
377
+    ////////////////////////////////////////////////////////////////////
378
+
379
+    /**
380
+     * Wrap an item to be prepended or appended to the current field
381
+     *
382
+     * @return Element A wrapped item
383
+     */
384
+    public function placeAround($item)
385
+    {
386
+        // Render object
387
+        if (is_object($item) and method_exists($item, '__toString')) {
388
+            $item = $item->__toString();
389
+        }
390
+
391
+        // Get class to use
392
+        $class = (strpos($item, '<button') !== false) ? 'btn' : 'addon';
393
+
394
+        return Element::create('span', $item)->addClass('input-group-'.$class);
395
+    }
396
+
397
+    /**
398
+     * Wrap a field with prepended and appended items
399
+     *
400
+     * @param  Field $field
401
+     * @param  array $prepend
402
+     * @param  array $append
403
+     *
404
+     * @return string A field concatented with prepended and/or appended items
405
+     */
406
+    public function prependAppend($field, $prepend, $append)
407
+    {
408
+        $return = '<div class="input-group">';
409
+        $return .= implode('', $prepend);
410
+        $return .= $field->render();
411
+        $return .= implode('', $append);
412
+        $return .= '</div>';
413
+
414
+        return $return;
415
+    }
416
+
417
+    /**
418
+     * Wrap a field with potential additional tags
419
+     *
420
+     * @param  Field $field
421
+     *
422
+     * @return Element A wrapped field
423
+     */
424
+    public function wrapField($field)
425
+    {
426
+        if ($this->app['former.form']->isOfType('horizontal')) {
427
+            return Element::create('div', $field)->addClass($this->fieldWidth);
428
+        }
429
+
430
+        return $field;
431
+    }
432
+
433
+    /**
434
+     * Wrap actions block with potential additional tags
435
+     *
436
+     * @param  Actions $actions
437
+     *
438
+     * @return string A wrapped actions block
439
+     */
440
+    public function wrapActions($actions)
441
+    {
442
+        // For horizontal forms, we wrap the actions in a div
443
+        if ($this->app['former.form']->isOfType('horizontal')) {
444
+            return Element::create('div', $actions)->addClass(array($this->fieldOffset, $this->fieldWidth));
445
+        }
446
+
447
+        return $actions;
448
+    }
449 449
 }
Please login to merge, or discard this patch.
src/Former/Framework/TwitterBootstrap.php 1 patch
Indentation   +370 added lines, -370 removed lines patch added patch discarded remove patch
@@ -14,374 +14,374 @@
 block discarded – undo
14 14
  */
15 15
 class TwitterBootstrap extends Framework implements FrameworkInterface
16 16
 {
17
-	/**
18
-	 * Form types that trigger special styling for this Framework
19
-	 *
20
-	 * @var array
21
-	 */
22
-	protected $availableTypes = array('horizontal', 'vertical', 'inline', 'search');
23
-
24
-	/**
25
-	 * The button types available
26
-	 *
27
-	 * @var array
28
-	 */
29
-	private $buttons = array(
30
-		'large',
31
-		'small',
32
-		'mini',
33
-		'block',
34
-		'danger',
35
-		'info',
36
-		'inverse',
37
-		'link',
38
-		'primary',
39
-		'success',
40
-		'warning',
41
-	);
42
-
43
-	/**
44
-	 * The field sizes available
45
-	 *
46
-	 * @var array
47
-	 */
48
-	private $fields = array(
49
-		'mini',
50
-		'small',
51
-		'medium',
52
-		'large',
53
-		'xlarge',
54
-		'xxlarge',
55
-		'span1',
56
-		'span2',
57
-		'span3',
58
-		'span4',
59
-		'span5',
60
-		'span6',
61
-		'span7',
62
-		'span8',
63
-		'span9',
64
-		'span10',
65
-		'span11',
66
-		'span12',
67
-	);
68
-
69
-	/**
70
-	 * The field states available
71
-	 *
72
-	 * @var array
73
-	 */
74
-	protected $states = array(
75
-		'success',
76
-		'warning',
77
-		'error',
78
-		'info',
79
-	);
80
-
81
-	/**
82
-	 * Create a new TwitterBootstrap instance
83
-	 *
84
-	 * @param \Illuminate\Container\Container $app
85
-	 */
86
-	public function __construct(Container $app)
87
-	{
88
-		$this->app = $app;
89
-		$this->setFrameworkDefaults();
90
-	}
91
-
92
-	////////////////////////////////////////////////////////////////////
93
-	/////////////////////////// FILTER ARRAYS //////////////////////////
94
-	////////////////////////////////////////////////////////////////////
95
-
96
-	/**
97
-	 * Filter buttons classes
98
-	 *
99
-	 * @param  array $classes An array of classes
100
-	 *
101
-	 * @return string[] A filtered array
102
-	 */
103
-	public function filterButtonClasses($classes)
104
-	{
105
-		// Filter classes
106
-		// $classes = array_intersect($classes, $this->buttons);
107
-
108
-		// Prepend button type
109
-		$classes   = $this->prependWith($classes, 'btn-');
110
-		$classes[] = 'btn';
111
-
112
-		return $classes;
113
-	}
114
-
115
-	/**
116
-	 * Filter field classes
117
-	 *
118
-	 * @param  array $classes An array of classes
119
-	 *
120
-	 * @return array A filtered array
121
-	 */
122
-	public function filterFieldClasses($classes)
123
-	{
124
-		// Filter classes
125
-		$classes = array_intersect($classes, $this->fields);
126
-
127
-		// Prepend field type
128
-		$classes = array_map(function ($class) {
129
-			return Str::startsWith($class, 'span') ? $class : 'input-'.$class;
130
-		}, $classes);
131
-
132
-		return $classes;
133
-	}
134
-
135
-	////////////////////////////////////////////////////////////////////
136
-	///////////////////////////// ADD CLASSES //////////////////////////
137
-	////////////////////////////////////////////////////////////////////
138
-
139
-	/**
140
-	 * Add classes to a field
141
-	 *
142
-	 * @param Field $field
143
-	 * @param array $classes The possible classes to add
144
-	 *
145
-	 * @return Field
146
-	 */
147
-	public function getFieldClasses(Field $field, $classes)
148
-	{
149
-		// Add inline class for checkables
150
-		if ($field->isCheckable() and in_array('inline', $classes)) {
151
-			$field->inline();
152
-		}
153
-
154
-		// Filter classes according to field type
155
-		if ($field->isButton()) {
156
-			$classes = $this->filterButtonClasses($classes);
157
-		} else {
158
-			$classes = $this->filterFieldClasses($classes);
159
-		}
160
-
161
-		return $this->addClassesToField($field, $classes);
162
-	}
163
-
164
-	/**
165
-	 * Add group classes
166
-	 *
167
-	 * @return string A list of group classes
168
-	 */
169
-	public function getGroupClasses()
170
-	{
171
-		return 'control-group';
172
-	}
173
-
174
-	/**
175
-	 * Add label classes
176
-	 *
177
-	 * @return string An array of attributes with the label class
178
-	 */
179
-	public function getLabelClasses()
180
-	{
181
-		return 'control-label';
182
-	}
183
-
184
-	/**
185
-	 * Add uneditable field classes
186
-	 *
187
-	 * @return string An array of attributes with the uneditable class
188
-	 */
189
-	public function getUneditableClasses()
190
-	{
191
-		return 'uneditable-input';
192
-	}
193
-
194
-	public function getPlainTextClasses()
195
-	{
196
-		return null;
197
-	}
198
-
199
-	/**
200
-	 * Add form class
201
-	 *
202
-	 * @param  string $type The type of form to add
203
-	 *
204
-	 * @return string|null
205
-	 */
206
-	public function getFormClasses($type)
207
-	{
208
-		return $type ? 'form-'.$type : null;
209
-	}
210
-
211
-	/**
212
-	 * Add actions block class
213
-	 *
214
-	 * @return string
215
-	 */
216
-	public function getActionClasses()
217
-	{
218
-		return 'form-actions';
219
-	}
220
-
221
-	////////////////////////////////////////////////////////////////////
222
-	//////////////////////////// RENDER BLOCKS /////////////////////////
223
-	////////////////////////////////////////////////////////////////////
224
-
225
-	/**
226
-	 * Render an help text
227
-	 *
228
-	 * @param string $text
229
-	 * @param array  $attributes
230
-	 *
231
-	 * @return Element
232
-	 */
233
-	public function createHelp($text, $attributes = array())
234
-	{
235
-		return Element::create('span', $text, $attributes)->addClass('help-inline');
236
-	}
237
-
238
-	/**
239
-	 * Render a block help text
240
-	 *
241
-	 * @param string $text
242
-	 * @param array  $attributes
243
-	 *
244
-	 * @return Element
245
-	 */
246
-	public function createBlockHelp($text, $attributes = array())
247
-	{
248
-		return Element::create('p', $text, $attributes)->addClass('help-block');
249
-	}
250
-
251
-	/**
252
-	 * Render a disabled field
253
-	 *
254
-	 * @param Field $field
255
-	 *
256
-	 * @return Element
257
-	 */
258
-	public function createDisabledField(Field $field)
259
-	{
260
-		return Element::create('span', $field->getValue(), $field->getAttributes());
261
-	}
262
-
263
-	/**
264
-	 * Render a plain text field
265
-	 * Which fallback to a disabled field
266
-	 *
267
-	 * @param Field $field
268
-	 *
269
-	 * @return Element
270
-	 */
271
-	public function createPlainTextField(Field $field)
272
-	{
273
-		return $this->createDisabledField($field);
274
-	}
275
-
276
-	/**
277
-	 * Render an icon
278
-	 *
279
-	 * @param array $attributes Its general attributes
280
-	 *
281
-	 * @return string
282
-	 */
283
-	public function createIcon($iconType, $attributes = array(), $iconSettings = array())
284
-	{
285
-		// Check for empty icons
286
-		if (!$iconType) {
287
-			return false;
288
-		}
289
-
290
-		// Create tag
291
-		$tag  = Arr::get($iconSettings, 'tag', $this->iconTag);
292
-		$icon = Element::create($tag, null, $attributes);
293
-
294
-		// White icons ignore user overrides to use legacy Bootstrap styling
295
-		if (Str::contains($iconType, 'white')) {
296
-			$iconType = str_replace('white', '', $iconType);
297
-			$iconType = trim($iconType, '-');
298
-			$icon->addClass('icon-white');
299
-			$set    = null;
300
-			$prefix = 'icon';
301
-		} else {
302
-			$set    = Arr::get($iconSettings, 'set', $this->iconSet);
303
-			$prefix = Arr::get($iconSettings, 'prefix', $this->iconPrefix);
304
-		}
305
-		$icon->addClass("$set $prefix-$iconType");
306
-
307
-		return $icon;
308
-	}
309
-
310
-	////////////////////////////////////////////////////////////////////
311
-	//////////////////////////// WRAP BLOCKS ///////////////////////////
312
-	////////////////////////////////////////////////////////////////////
313
-
314
-	/**
315
-	 * Wrap an item to be prepended or appended to the current field
316
-	 *
317
-	 * @param  string $item
318
-	 *
319
-	 * @return string A wrapped item
320
-	 */
321
-	public function placeAround($item)
322
-	{
323
-		// Render object
324
-		if (is_object($item) and method_exists($item, '__toString')) {
325
-			$item = $item->__toString();
326
-		}
327
-
328
-		// Return unwrapped if button
329
-		if (strpos($item, '<button') !== false) {
330
-			return $item;
331
-		}
332
-
333
-		return Element::create('span', $item)->addClass('add-on');
334
-	}
335
-
336
-	/**
337
-	 * Wrap a field with prepended and appended items
338
-	 *
339
-	 * @param  Field $field
340
-	 * @param  array $prepend
341
-	 * @param  array $append
342
-	 *
343
-	 * @return string A field concatented with prepended and/or appended items
344
-	 */
345
-	public function prependAppend($field, $prepend, $append)
346
-	{
347
-		$class = array();
348
-		if ($prepend) {
349
-			$class[] = 'input-prepend';
350
-		}
351
-		if ($append) {
352
-			$class[] = 'input-append';
353
-		}
354
-
355
-		$return = '<div class="'.join(' ', $class).'">';
356
-		$return .= implode('', $prepend);
357
-		$return .= $field->render();
358
-		$return .= implode('', $append);
359
-		$return .= '</div>';
360
-
361
-		return $return;
362
-	}
363
-
364
-	/**
365
-	 * Wrap a field with potential additional tags
366
-	 *
367
-	 * @param  Field $field
368
-	 *
369
-	 * @return Element A wrapped field
370
-	 */
371
-	public function wrapField($field)
372
-	{
373
-		return Element::create('div', $field)->addClass('controls');
374
-	}
375
-
376
-	/**
377
-	 * Wrap actions block with potential additional tags
378
-	 *
379
-	 * @param  Actions $actions
380
-	 *
381
-	 * @return string A wrapped actions block
382
-	 */
383
-	public function wrapActions($actions)
384
-	{
385
-		return $actions;
386
-	}
17
+    /**
18
+     * Form types that trigger special styling for this Framework
19
+     *
20
+     * @var array
21
+     */
22
+    protected $availableTypes = array('horizontal', 'vertical', 'inline', 'search');
23
+
24
+    /**
25
+     * The button types available
26
+     *
27
+     * @var array
28
+     */
29
+    private $buttons = array(
30
+        'large',
31
+        'small',
32
+        'mini',
33
+        'block',
34
+        'danger',
35
+        'info',
36
+        'inverse',
37
+        'link',
38
+        'primary',
39
+        'success',
40
+        'warning',
41
+    );
42
+
43
+    /**
44
+     * The field sizes available
45
+     *
46
+     * @var array
47
+     */
48
+    private $fields = array(
49
+        'mini',
50
+        'small',
51
+        'medium',
52
+        'large',
53
+        'xlarge',
54
+        'xxlarge',
55
+        'span1',
56
+        'span2',
57
+        'span3',
58
+        'span4',
59
+        'span5',
60
+        'span6',
61
+        'span7',
62
+        'span8',
63
+        'span9',
64
+        'span10',
65
+        'span11',
66
+        'span12',
67
+    );
68
+
69
+    /**
70
+     * The field states available
71
+     *
72
+     * @var array
73
+     */
74
+    protected $states = array(
75
+        'success',
76
+        'warning',
77
+        'error',
78
+        'info',
79
+    );
80
+
81
+    /**
82
+     * Create a new TwitterBootstrap instance
83
+     *
84
+     * @param \Illuminate\Container\Container $app
85
+     */
86
+    public function __construct(Container $app)
87
+    {
88
+        $this->app = $app;
89
+        $this->setFrameworkDefaults();
90
+    }
91
+
92
+    ////////////////////////////////////////////////////////////////////
93
+    /////////////////////////// FILTER ARRAYS //////////////////////////
94
+    ////////////////////////////////////////////////////////////////////
95
+
96
+    /**
97
+     * Filter buttons classes
98
+     *
99
+     * @param  array $classes An array of classes
100
+     *
101
+     * @return string[] A filtered array
102
+     */
103
+    public function filterButtonClasses($classes)
104
+    {
105
+        // Filter classes
106
+        // $classes = array_intersect($classes, $this->buttons);
107
+
108
+        // Prepend button type
109
+        $classes   = $this->prependWith($classes, 'btn-');
110
+        $classes[] = 'btn';
111
+
112
+        return $classes;
113
+    }
114
+
115
+    /**
116
+     * Filter field classes
117
+     *
118
+     * @param  array $classes An array of classes
119
+     *
120
+     * @return array A filtered array
121
+     */
122
+    public function filterFieldClasses($classes)
123
+    {
124
+        // Filter classes
125
+        $classes = array_intersect($classes, $this->fields);
126
+
127
+        // Prepend field type
128
+        $classes = array_map(function ($class) {
129
+            return Str::startsWith($class, 'span') ? $class : 'input-'.$class;
130
+        }, $classes);
131
+
132
+        return $classes;
133
+    }
134
+
135
+    ////////////////////////////////////////////////////////////////////
136
+    ///////////////////////////// ADD CLASSES //////////////////////////
137
+    ////////////////////////////////////////////////////////////////////
138
+
139
+    /**
140
+     * Add classes to a field
141
+     *
142
+     * @param Field $field
143
+     * @param array $classes The possible classes to add
144
+     *
145
+     * @return Field
146
+     */
147
+    public function getFieldClasses(Field $field, $classes)
148
+    {
149
+        // Add inline class for checkables
150
+        if ($field->isCheckable() and in_array('inline', $classes)) {
151
+            $field->inline();
152
+        }
153
+
154
+        // Filter classes according to field type
155
+        if ($field->isButton()) {
156
+            $classes = $this->filterButtonClasses($classes);
157
+        } else {
158
+            $classes = $this->filterFieldClasses($classes);
159
+        }
160
+
161
+        return $this->addClassesToField($field, $classes);
162
+    }
163
+
164
+    /**
165
+     * Add group classes
166
+     *
167
+     * @return string A list of group classes
168
+     */
169
+    public function getGroupClasses()
170
+    {
171
+        return 'control-group';
172
+    }
173
+
174
+    /**
175
+     * Add label classes
176
+     *
177
+     * @return string An array of attributes with the label class
178
+     */
179
+    public function getLabelClasses()
180
+    {
181
+        return 'control-label';
182
+    }
183
+
184
+    /**
185
+     * Add uneditable field classes
186
+     *
187
+     * @return string An array of attributes with the uneditable class
188
+     */
189
+    public function getUneditableClasses()
190
+    {
191
+        return 'uneditable-input';
192
+    }
193
+
194
+    public function getPlainTextClasses()
195
+    {
196
+        return null;
197
+    }
198
+
199
+    /**
200
+     * Add form class
201
+     *
202
+     * @param  string $type The type of form to add
203
+     *
204
+     * @return string|null
205
+     */
206
+    public function getFormClasses($type)
207
+    {
208
+        return $type ? 'form-'.$type : null;
209
+    }
210
+
211
+    /**
212
+     * Add actions block class
213
+     *
214
+     * @return string
215
+     */
216
+    public function getActionClasses()
217
+    {
218
+        return 'form-actions';
219
+    }
220
+
221
+    ////////////////////////////////////////////////////////////////////
222
+    //////////////////////////// RENDER BLOCKS /////////////////////////
223
+    ////////////////////////////////////////////////////////////////////
224
+
225
+    /**
226
+     * Render an help text
227
+     *
228
+     * @param string $text
229
+     * @param array  $attributes
230
+     *
231
+     * @return Element
232
+     */
233
+    public function createHelp($text, $attributes = array())
234
+    {
235
+        return Element::create('span', $text, $attributes)->addClass('help-inline');
236
+    }
237
+
238
+    /**
239
+     * Render a block help text
240
+     *
241
+     * @param string $text
242
+     * @param array  $attributes
243
+     *
244
+     * @return Element
245
+     */
246
+    public function createBlockHelp($text, $attributes = array())
247
+    {
248
+        return Element::create('p', $text, $attributes)->addClass('help-block');
249
+    }
250
+
251
+    /**
252
+     * Render a disabled field
253
+     *
254
+     * @param Field $field
255
+     *
256
+     * @return Element
257
+     */
258
+    public function createDisabledField(Field $field)
259
+    {
260
+        return Element::create('span', $field->getValue(), $field->getAttributes());
261
+    }
262
+
263
+    /**
264
+     * Render a plain text field
265
+     * Which fallback to a disabled field
266
+     *
267
+     * @param Field $field
268
+     *
269
+     * @return Element
270
+     */
271
+    public function createPlainTextField(Field $field)
272
+    {
273
+        return $this->createDisabledField($field);
274
+    }
275
+
276
+    /**
277
+     * Render an icon
278
+     *
279
+     * @param array $attributes Its general attributes
280
+     *
281
+     * @return string
282
+     */
283
+    public function createIcon($iconType, $attributes = array(), $iconSettings = array())
284
+    {
285
+        // Check for empty icons
286
+        if (!$iconType) {
287
+            return false;
288
+        }
289
+
290
+        // Create tag
291
+        $tag  = Arr::get($iconSettings, 'tag', $this->iconTag);
292
+        $icon = Element::create($tag, null, $attributes);
293
+
294
+        // White icons ignore user overrides to use legacy Bootstrap styling
295
+        if (Str::contains($iconType, 'white')) {
296
+            $iconType = str_replace('white', '', $iconType);
297
+            $iconType = trim($iconType, '-');
298
+            $icon->addClass('icon-white');
299
+            $set    = null;
300
+            $prefix = 'icon';
301
+        } else {
302
+            $set    = Arr::get($iconSettings, 'set', $this->iconSet);
303
+            $prefix = Arr::get($iconSettings, 'prefix', $this->iconPrefix);
304
+        }
305
+        $icon->addClass("$set $prefix-$iconType");
306
+
307
+        return $icon;
308
+    }
309
+
310
+    ////////////////////////////////////////////////////////////////////
311
+    //////////////////////////// WRAP BLOCKS ///////////////////////////
312
+    ////////////////////////////////////////////////////////////////////
313
+
314
+    /**
315
+     * Wrap an item to be prepended or appended to the current field
316
+     *
317
+     * @param  string $item
318
+     *
319
+     * @return string A wrapped item
320
+     */
321
+    public function placeAround($item)
322
+    {
323
+        // Render object
324
+        if (is_object($item) and method_exists($item, '__toString')) {
325
+            $item = $item->__toString();
326
+        }
327
+
328
+        // Return unwrapped if button
329
+        if (strpos($item, '<button') !== false) {
330
+            return $item;
331
+        }
332
+
333
+        return Element::create('span', $item)->addClass('add-on');
334
+    }
335
+
336
+    /**
337
+     * Wrap a field with prepended and appended items
338
+     *
339
+     * @param  Field $field
340
+     * @param  array $prepend
341
+     * @param  array $append
342
+     *
343
+     * @return string A field concatented with prepended and/or appended items
344
+     */
345
+    public function prependAppend($field, $prepend, $append)
346
+    {
347
+        $class = array();
348
+        if ($prepend) {
349
+            $class[] = 'input-prepend';
350
+        }
351
+        if ($append) {
352
+            $class[] = 'input-append';
353
+        }
354
+
355
+        $return = '<div class="'.join(' ', $class).'">';
356
+        $return .= implode('', $prepend);
357
+        $return .= $field->render();
358
+        $return .= implode('', $append);
359
+        $return .= '</div>';
360
+
361
+        return $return;
362
+    }
363
+
364
+    /**
365
+     * Wrap a field with potential additional tags
366
+     *
367
+     * @param  Field $field
368
+     *
369
+     * @return Element A wrapped field
370
+     */
371
+    public function wrapField($field)
372
+    {
373
+        return Element::create('div', $field)->addClass('controls');
374
+    }
375
+
376
+    /**
377
+     * Wrap actions block with potential additional tags
378
+     *
379
+     * @param  Actions $actions
380
+     *
381
+     * @return string A wrapped actions block
382
+     */
383
+    public function wrapActions($actions)
384
+    {
385
+        return $actions;
386
+    }
387 387
 }
Please login to merge, or discard this patch.
src/Former/Framework/Nude.php 1 patch
Indentation   +178 added lines, -178 removed lines patch added patch discarded remove patch
@@ -14,182 +14,182 @@
 block discarded – undo
14 14
 class Nude extends Framework implements FrameworkInterface
15 15
 {
16 16
 
17
-	/**
18
-	 * The field states available
19
-	 *
20
-	 * @var array
21
-	 */
22
-	protected $states = array(
23
-		'error',
24
-	);
25
-
26
-	/**
27
-	 * Create a new Nude instance
28
-	 *
29
-	 * @param Container $app
30
-	 */
31
-	public function __construct(Container $app)
32
-	{
33
-		$this->app = $app;
34
-		$this->setFrameworkDefaults();
35
-	}
36
-
37
-	////////////////////////////////////////////////////////////////////
38
-	/////////////////////////// FILTER ARRAYS //////////////////////////
39
-	////////////////////////////////////////////////////////////////////
40
-
41
-	public function filterButtonClasses($classes)
42
-	{
43
-		return $classes;
44
-	}
45
-
46
-	public function filterFieldClasses($classes)
47
-	{
48
-		return $classes;
49
-	}
50
-
51
-	////////////////////////////////////////////////////////////////////
52
-	///////////////////////////// ADD CLASSES //////////////////////////
53
-	////////////////////////////////////////////////////////////////////
54
-
55
-	public function getFieldClasses(Field $field, $classes = array())
56
-	{
57
-		$classes = $this->filterFieldClasses($classes);
58
-
59
-		// If we found any class, add them
60
-		if ($classes) {
61
-			$field->class(implode(' ', $classes));
62
-		}
63
-
64
-		return $field;
65
-	}
66
-
67
-	public function getGroupClasses()
68
-	{
69
-		return null;
70
-	}
71
-
72
-	public function getLabelClasses()
73
-	{
74
-		return null;
75
-	}
76
-
77
-	public function getUneditableClasses()
78
-	{
79
-		return null;
80
-	}
81
-
82
-	public function getPlainTextClasses()
83
-	{
84
-		return null;
85
-	}
86
-
87
-	public function getFormClasses($type)
88
-	{
89
-		return null;
90
-	}
91
-
92
-	public function getActionClasses()
93
-	{
94
-		return null;
95
-	}
96
-
97
-	////////////////////////////////////////////////////////////////////
98
-	//////////////////////////// RENDER BLOCKS /////////////////////////
99
-	////////////////////////////////////////////////////////////////////
100
-
101
-	/**
102
-	 * Create an help text
103
-	 */
104
-	public function createHelp($text, $attributes = array())
105
-	{
106
-		return Element::create('span', $text, $attributes)->addClass('help');
107
-	}
108
-
109
-	/**
110
-	 * Render a disabled field
111
-	 *
112
-	 * @param Field $field
113
-	 *
114
-	 * @return Input
115
-	 */
116
-	public function createDisabledField(Field $field)
117
-	{
118
-		$field->disabled();
119
-
120
-		return Input::create('text', $field->getName(), $field->getValue(), $field->getAttributes());
121
-	}
122
-
123
-	/**
124
-	 * Render a plain text field
125
-	 * Which fallback to a disabled field
126
-	 *
127
-	 * @param Field $field
128
-	 *
129
-	 * @return Element
130
-	 */
131
-	public function createPlainTextField(Field $field)
132
-	{
133
-		return $this->createDisabledField($field);
134
-	}
135
-
136
-	////////////////////////////////////////////////////////////////////
137
-	//////////////////////////// WRAP BLOCKS ///////////////////////////
138
-	////////////////////////////////////////////////////////////////////
139
-
140
-	/**
141
-	 * Wrap an item to be prepended or appended to the current field
142
-	 *
143
-	 * @param  string $item
144
-	 *
145
-	 * @return Element A wrapped item
146
-	 */
147
-	public function placeAround($item)
148
-	{
149
-		return Element::create('span', $item);
150
-	}
151
-
152
-	/**
153
-	 * Wrap a field with prepended and appended items
154
-	 *
155
-	 * @param  Field $field
156
-	 * @param  array $prepend
157
-	 * @param  array $append
158
-	 *
159
-	 * @return string A field concatented with prepended and/or appended items
160
-	 */
161
-	public function prependAppend($field, $prepend, $append)
162
-	{
163
-		$return = '<div>';
164
-		$return .= implode('', $prepend);
165
-		$return .= $field->render();
166
-		$return .= implode('', $append);
167
-		$return .= '</div>';
168
-
169
-		return $return;
170
-	}
171
-
172
-	/**
173
-	 * Wraps all field contents with potential additional tags.
174
-	 *
175
-	 * @param  Field $field
176
-	 *
177
-	 * @return Field A wrapped field
178
-	 */
179
-	public function wrapField($field)
180
-	{
181
-		return $field;
182
-	}
183
-
184
-	/**
185
-	 * Wrap actions block with potential additional tags
186
-	 *
187
-	 * @param  Actions $actions
188
-	 *
189
-	 * @return string A wrapped actions block
190
-	 */
191
-	public function wrapActions($actions)
192
-	{
193
-		return $actions;
194
-	}
17
+    /**
18
+     * The field states available
19
+     *
20
+     * @var array
21
+     */
22
+    protected $states = array(
23
+        'error',
24
+    );
25
+
26
+    /**
27
+     * Create a new Nude instance
28
+     *
29
+     * @param Container $app
30
+     */
31
+    public function __construct(Container $app)
32
+    {
33
+        $this->app = $app;
34
+        $this->setFrameworkDefaults();
35
+    }
36
+
37
+    ////////////////////////////////////////////////////////////////////
38
+    /////////////////////////// FILTER ARRAYS //////////////////////////
39
+    ////////////////////////////////////////////////////////////////////
40
+
41
+    public function filterButtonClasses($classes)
42
+    {
43
+        return $classes;
44
+    }
45
+
46
+    public function filterFieldClasses($classes)
47
+    {
48
+        return $classes;
49
+    }
50
+
51
+    ////////////////////////////////////////////////////////////////////
52
+    ///////////////////////////// ADD CLASSES //////////////////////////
53
+    ////////////////////////////////////////////////////////////////////
54
+
55
+    public function getFieldClasses(Field $field, $classes = array())
56
+    {
57
+        $classes = $this->filterFieldClasses($classes);
58
+
59
+        // If we found any class, add them
60
+        if ($classes) {
61
+            $field->class(implode(' ', $classes));
62
+        }
63
+
64
+        return $field;
65
+    }
66
+
67
+    public function getGroupClasses()
68
+    {
69
+        return null;
70
+    }
71
+
72
+    public function getLabelClasses()
73
+    {
74
+        return null;
75
+    }
76
+
77
+    public function getUneditableClasses()
78
+    {
79
+        return null;
80
+    }
81
+
82
+    public function getPlainTextClasses()
83
+    {
84
+        return null;
85
+    }
86
+
87
+    public function getFormClasses($type)
88
+    {
89
+        return null;
90
+    }
91
+
92
+    public function getActionClasses()
93
+    {
94
+        return null;
95
+    }
96
+
97
+    ////////////////////////////////////////////////////////////////////
98
+    //////////////////////////// RENDER BLOCKS /////////////////////////
99
+    ////////////////////////////////////////////////////////////////////
100
+
101
+    /**
102
+     * Create an help text
103
+     */
104
+    public function createHelp($text, $attributes = array())
105
+    {
106
+        return Element::create('span', $text, $attributes)->addClass('help');
107
+    }
108
+
109
+    /**
110
+     * Render a disabled field
111
+     *
112
+     * @param Field $field
113
+     *
114
+     * @return Input
115
+     */
116
+    public function createDisabledField(Field $field)
117
+    {
118
+        $field->disabled();
119
+
120
+        return Input::create('text', $field->getName(), $field->getValue(), $field->getAttributes());
121
+    }
122
+
123
+    /**
124
+     * Render a plain text field
125
+     * Which fallback to a disabled field
126
+     *
127
+     * @param Field $field
128
+     *
129
+     * @return Element
130
+     */
131
+    public function createPlainTextField(Field $field)
132
+    {
133
+        return $this->createDisabledField($field);
134
+    }
135
+
136
+    ////////////////////////////////////////////////////////////////////
137
+    //////////////////////////// WRAP BLOCKS ///////////////////////////
138
+    ////////////////////////////////////////////////////////////////////
139
+
140
+    /**
141
+     * Wrap an item to be prepended or appended to the current field
142
+     *
143
+     * @param  string $item
144
+     *
145
+     * @return Element A wrapped item
146
+     */
147
+    public function placeAround($item)
148
+    {
149
+        return Element::create('span', $item);
150
+    }
151
+
152
+    /**
153
+     * Wrap a field with prepended and appended items
154
+     *
155
+     * @param  Field $field
156
+     * @param  array $prepend
157
+     * @param  array $append
158
+     *
159
+     * @return string A field concatented with prepended and/or appended items
160
+     */
161
+    public function prependAppend($field, $prepend, $append)
162
+    {
163
+        $return = '<div>';
164
+        $return .= implode('', $prepend);
165
+        $return .= $field->render();
166
+        $return .= implode('', $append);
167
+        $return .= '</div>';
168
+
169
+        return $return;
170
+    }
171
+
172
+    /**
173
+     * Wraps all field contents with potential additional tags.
174
+     *
175
+     * @param  Field $field
176
+     *
177
+     * @return Field A wrapped field
178
+     */
179
+    public function wrapField($field)
180
+    {
181
+        return $field;
182
+    }
183
+
184
+    /**
185
+     * Wrap actions block with potential additional tags
186
+     *
187
+     * @param  Actions $actions
188
+     *
189
+     * @return string A wrapped actions block
190
+     */
191
+    public function wrapActions($actions)
192
+    {
193
+        return $actions;
194
+    }
195 195
 }
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-plaintext';
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 .= implode('', $prepend);
442
-		$return .= $field->render();
443
-		$return .= implode('', $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-plaintext';
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 .= implode('', $prepend);
442
+        $return .= $field->render();
443
+        $return .= implode('', $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.