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