Completed
Push — master ( dca322...47e653 )
by Julito
08:54
created

HTML_QuickForm_group   F

Complexity

Total Complexity 91

Size/Duplication

Total Lines 551
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 195
dl 0
loc 551
rs 2
c 0
b 0
f 0
wmc 91

How to fix   Complexity   

Complex Class

Complex classes like HTML_QuickForm_group often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use HTML_QuickForm_group, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4
/**
5
 * HTML class for a form element group
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: This source file is subject to version 3.01 of the PHP license
10
 * that is available through the world-wide-web at the following URI:
11
 * http://www.php.net/license/3_01.txt If you did not receive a copy of
12
 * the PHP License and are unable to obtain it through the web, please
13
 * send a note to [email protected] so we can mail you a copy immediately.
14
 *
15
 * @category    HTML
16
 * @package     HTML_QuickForm
17
 * @author      Adam Daniel <[email protected]>
18
 * @author      Bertrand Mansion <[email protected]>
19
 * @author      Alexey Borzov <[email protected]>
20
 * @copyright   2001-2009 The PHP Group
21
 * @license     http://www.php.net/license/3_01.txt PHP License 3.01
22
 * @version     CVS: $Id: group.php,v 1.40 2009/04/04 21:34:03 avb Exp $
23
 * @link        http://pear.php.net/package/HTML_QuickForm
24
 */
25
26
/**
27
 * HTML class for a form element group
28
 *
29
 * @category    HTML
30
 * @package     HTML_QuickForm
31
 * @author      Adam Daniel <[email protected]>
32
 * @author      Bertrand Mansion <[email protected]>
33
 * @author      Alexey Borzov <[email protected]>
34
 * @version     Release: 3.2.11
35
 * @since       1.0
36
 */
37
class HTML_QuickForm_group extends HTML_QuickForm_element
38
{
39
    /**
40
     * Name of the element
41
     * @var       string
42
     * @since     1.0
43
     * @access    private
44
     */
45
    private $_name = '';
46
47
    /**
48
     * Array of grouped elements
49
     * @var       array
50
     * @since     1.0
51
     * @access    private
52
     */
53
    private $_elements = array();
54
55
    /**
56
     * String to separate elements
57
     * @var       mixed
58
     * @since     2.5
59
     * @access    public
60
     */
61
    public $_separator = null;
62
63
    /**
64
     * Required elements in this group
65
     * @var       array
66
     * @since     2.5
67
     * @access    private
68
     */
69
    private $_required = array();
70
71
   /**
72
    * Whether to change elements' names to $groupName[$elementName] or leave them as is
73
    * @var      bool
74
    * @since    3.0
75
    * @access   private
76
    */
77
    private $_appendName = true;
78
79
    /**
80
     * Class constructor
81
     *
82
     * @param     string    $elementName    (optional)Group name
83
     * @param     array     $elementLabel   (optional)Group label
84
     * @param     array     $elements       (optional)Group elements
85
     * @param     mixed     $separator      (optional)Use a string for one separator,
86
     *                                      use an array to alternate the separators.
87
     * @param     bool      $appendName     (optional)whether to change elements' names to
88
     *                                      the form $groupName[$elementName] or leave
89
     *                                      them as is.
90
     * @since     1.0
91
     * @access    public
92
     * @return    void
93
     */
94
    public function __construct(
95
        $elementName = null,
96
        $elementLabel = null,
97
        $elements = null,
98
        $separator = null,
99
        $appendName = true
100
    ) {
101
        parent::__construct($elementName, $elementLabel);
102
        $this->_type = 'group';
103
        if (isset($elements) && is_array($elements)) {
104
            $this->setElements($elements);
105
        }
106
        if (isset($separator)) {
107
            $this->_separator = $separator;
108
        } else {
109
            $this->_separator = '';
110
        }
111
        if (isset($appendName)) {
112
            $this->_appendName = $appendName;
113
        }
114
    }
115
116
    /**
117
     * Sets the group name
118
     *
119
     * @param     string    $name   Group name
120
     * @since     1.0
121
     * @access    public
122
     * @return    void
123
     */
124
    function setName($name)
125
    {
126
        $this->_name = $name;
127
    }
128
129
    /**
130
     * Returns the group name
131
     *
132
     * @since     1.0
133
     * @access    public
134
     * @return    string
135
     */
136
    function getName()
137
    {
138
        return $this->_name;
139
    }
140
141
    /**
142
     * Sets values for group's elements
143
     *
144
     * @param     mixed    Values for group's elements
145
     * @since     1.0
146
     * @access    public
147
     * @return    void
148
     */
149
    function setValue($value)
150
    {
151
        $this->_createElementsIfNotExist();
152
        foreach (array_keys($this->_elements) as $key) {
153
            if (!$this->_appendName) {
154
                $v = $this->_elements[$key]->_findValue($value);
155
                if (null !== $v) {
156
                    $this->_elements[$key]->onQuickFormEvent('setGroupValue', $v, $this);
157
                }
158
159
            } else {
160
                $elementName = $this->_elements[$key]->getName();
161
                $index       = strlen($elementName) ? $elementName : $key;
162
                if (is_array($value)) {
163
                    if (isset($value[$index])) {
164
                        $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value[$index], $this);
165
                    }
166
                } elseif (isset($value)) {
167
                    $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value, $this);
168
                }
169
            }
170
        }
171
    }
172
173
    /**
174
     * Returns the value of the group
175
     *
176
     * @since     1.0
177
     * @access    public
178
     * @return    mixed
179
     */
180
    function getValue()
181
    {
182
        $value = null;
183
        foreach (array_keys($this->_elements) as $key) {
184
            $element =& $this->_elements[$key];
185
            switch ($element->getType()) {
186
                case 'radio':
187
                    $v = $element->getChecked()? $element->getValue(): null;
188
                    break;
189
                case 'checkbox':
190
                    $v = $element->getChecked()? true: null;
191
                    break;
192
                default:
193
                    $v = $element->getValue();
194
            }
195
            if (null !== $v) {
196
                $elementName = $element->getName();
197
                if (is_null($elementName)) {
198
                    $value = $v;
199
                } else {
200
                    if (!is_array($value)) {
201
                        $value = is_null($value)? array(): array($value);
202
                    }
203
                    if ('' === $elementName) {
204
                        $value[] = $v;
205
                    } else {
206
                        $value[$elementName] = $v;
207
                    }
208
                }
209
            }
210
        }
211
        return $value;
212
    }
213
214
    /**
215
     * Sets the grouped elements
216
     *
217
     * @param     array     $elements   Array of elements
218
     * @since     1.1
219
     * @access    public
220
     * @return    void
221
     */
222
    function setElements($elements)
223
    {
224
        $this->_elements = array_values($elements);
225
        if ($this->_flagFrozen) {
226
            $this->freeze();
227
        }
228
    }
229
230
    /**
231
     * Gets the grouped elements
232
     *
233
     * @since     2.4
234
     * @access    public
235
     * @return    array
236
     */
237
    function &getElements()
238
    {
239
        $this->_createElementsIfNotExist();
240
        return $this->_elements;
241
    }
242
243
    /**
244
     * Gets the group type based on its elements
245
     * Will return 'mixed' if elements contained in the group
246
     * are of different types.
247
     *
248
     * @access    public
249
     * @return    string    group elements type
250
     */
251
    function getGroupType()
252
    {
253
        $this->_createElementsIfNotExist();
254
        $prevType = '';
255
        foreach (array_keys($this->_elements) as $key) {
256
            $type = $this->_elements[$key]->getType();
257
            if ($type != $prevType && $prevType != '') {
258
                return 'mixed';
259
            }
260
            $prevType = $type;
261
        }
262
        return $type;
263
    }
264
265
    /**
266
     * Returns Html for the group
267
     *
268
     * @since       1.0
269
     * @access      public
270
     * @return      string
271
     */
272
    public function toHtml()
273
    {
274
        $renderer = new HTML_QuickForm_Renderer_Default();
275
        $renderer->setElementTemplate('{element}');
276
        $this->accept($renderer);
277
278
        return $renderer->toHtml();
279
    }
280
281
    /**
282
     * Returns the element name inside the group such as found in the html form
283
     *
284
     * @param     mixed     $index  Element name or element index in the group
285
     * @since     3.0
286
     * @access    public
287
     * @return    mixed     string with element name, false if not found
288
     */
289
    function getElementName($index)
290
    {
291
        $this->_createElementsIfNotExist();
292
        $elementName = false;
293
        if (is_int($index) && isset($this->_elements[$index])) {
294
            $elementName = $this->_elements[$index]->getName();
295
            if (isset($elementName) && $elementName == '') {
296
                $elementName = $index;
297
            }
298
            if ($this->_appendName) {
299
                if (is_null($elementName)) {
300
                    $elementName = $this->getName();
301
                } else {
302
                    $elementName = $this->getName().'['.$elementName.']';
303
                }
304
            }
305
306
        } elseif (is_string($index)) {
307
            foreach (array_keys($this->_elements) as $key) {
308
                $elementName = $this->_elements[$key]->getName();
309
                if ($index == $elementName) {
310
                    if ($this->_appendName) {
311
                        $elementName = $this->getName().'['.$elementName.']';
312
                    }
313
                    break;
314
                } elseif ($this->_appendName && $this->getName().'['.$elementName.']' == $index) {
315
                    break;
316
                }
317
            }
318
        }
319
        return $elementName;
320
    }
321
322
    /**
323
     * Returns the value of field without HTML tags
324
     *
325
     * @since     1.3
326
     * @access    public
327
     * @return    string
328
     */
329
    function getFrozenHtml()
330
    {
331
        $flags = array();
332
        $this->_createElementsIfNotExist();
333
        foreach (array_keys($this->_elements) as $key) {
334
            if (false === ($flags[$key] = $this->_elements[$key]->isFrozen())) {
335
                $this->_elements[$key]->freeze();
336
            }
337
        }
338
        $html = $this->toHtml();
339
        foreach (array_keys($this->_elements) as $key) {
340
            if (!$flags[$key]) {
341
                $this->_elements[$key]->unfreeze();
342
            }
343
        }
344
        return $html;
345
    }
346
347
    /**
348
     * Called by HTML_QuickForm whenever form event is made on this element
349
     *
350
     * @param     string    $event  Name of event
351
     * @param     mixed     $arg    event arguments
352
     * @param     object    &$caller calling object
353
     * @since     1.0
354
     * @access    public
355
     * @return    void
356
     */
357
    public function onQuickFormEvent($event, $arg, &$caller)
358
    {
359
        switch ($event) {
360
            case 'updateValue':
361
                $this->_createElementsIfNotExist();
362
363
                foreach (array_keys($this->_elements) as $key) {
364
                    if ($this->_appendName) {
365
                        $elementName = $this->_elements[$key]->getName();
366
367
                        if (is_null($elementName)) {
368
                            $this->_elements[$key]->setName($this->getName());
369
                        } elseif ('' === $elementName) {
370
                            $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
371
                        } else {
372
                            $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
373
                        }
374
                    }
375
                    $this->_elements[$key]->onQuickFormEvent('updateValue', $arg, $caller);
376
                    if ($this->_appendName) {
377
                        $this->_elements[$key]->setName($elementName);
378
                    }
379
                }
380
                break;
381
            default:
382
                parent::onQuickFormEvent($event, $arg, $caller);
383
        }
384
385
        return true;
386
    }
387
388
   /**
389
    * Accepts a renderer
390
    *
391
    * @param HTML_QuickForm_Renderer    renderer object
392
    * @param bool                       Whether a group is required
393
    * @param string                     An error message associated with a group
394
    * @access public
395
    * @return void
396
    */
397
    public function accept(&$renderer, $required = false, $error = null)
398
    {
399
        $this->_createElementsIfNotExist();
400
        $renderer->startGroup($this, $required, $error);
401
        $name = $this->getName();
402
        foreach (array_keys($this->_elements) as $key) {
403
            $element =& $this->_elements[$key];
404
405
            if ($this->_appendName) {
406
                $elementName = $element->getName();
407
408
                if (isset($elementName)) {
409
                    $element->setName($name . '['. (strlen($elementName)? $elementName: $key) .']');
410
                } else {
411
                    $element->setName($name);
412
                }
413
            }
414
415
            $required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
416
            $element->accept($renderer, $required);
417
418
            // restore the element's name
419
            if ($this->_appendName) {
420
                $element->setName($elementName);
421
            }
422
        }
423
        $renderer->finishGroup($this);
424
    }
425
426
   /**
427
    * As usual, to get the group's value we access its elements and call
428
    * their exportValue() methods
429
    */
430
    function exportValue(&$submitValues, $assoc = false)
431
    {
432
        $value = null;
433
        foreach (array_keys($this->_elements) as $key) {
434
            $elementName = $this->_elements[$key]->getName();
435
            if ($this->_appendName) {
436
                if (is_null($elementName)) {
437
                    $this->_elements[$key]->setName($this->getName());
438
                } elseif ('' === $elementName) {
439
                    $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
440
                } else {
441
                    $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
442
                }
443
            }
444
            $v = $this->_elements[$key]->exportValue($submitValues, $assoc);
445
            if ($this->_appendName) {
446
                $this->_elements[$key]->setName($elementName);
447
            }
448
            if (null !== $v) {
449
                // Make $value an array, we will use it like one
450
                if (null === $value) {
451
                    $value = array();
452
                }
453
                if ($assoc) {
454
                    // just like HTML_QuickForm::exportValues()
455
                    $value = HTML_QuickForm::arrayMerge($value, $v);
456
                } else {
457
                    // just like getValue(), but should work OK every time here
458
                    if (is_null($elementName)) {
459
                        $value = $v;
460
                    } elseif ('' === $elementName) {
461
                        $value[] = $v;
462
                    } else {
463
                        $value[$elementName] = $v;
464
                    }
465
                }
466
            }
467
        }
468
        // do not pass the value through _prepareValue, we took care of this already
469
        return $value;
470
    }
471
472
   /**
473
    * Creates the group's elements.
474
    *
475
    * This should be overriden by child classes that need to create their
476
    * elements. The method will be called automatically when needed, calling
477
    * it from the constructor is discouraged as the constructor is usually
478
    * called _twice_ on element creation, first time with _no_ parameters.
479
    *
480
    * @access private
481
    * @abstract
482
    */
483
    function _createElements()
484
    {
485
        // abstract
486
    }
487
488
   /**
489
    * A wrapper around _createElements()
490
    *
491
    * This method calls _createElements() if the group's _elements array
492
    * is empty. It also performs some updates, e.g. freezes the created
493
    * elements if the group is already frozen.
494
    *
495
    * @access private
496
    */
497
    function _createElementsIfNotExist()
498
    {
499
        if (empty($this->_elements)) {
500
            $this->_createElements();
501
            if ($this->_flagFrozen) {
502
                $this->freeze();
503
            }
504
        }
505
    }
506
507
    function freeze()
508
    {
509
        parent::freeze();
510
        foreach (array_keys($this->_elements) as $key) {
511
            $this->_elements[$key]->freezeSeeOnlySelected = $this->freezeSeeOnlySelected;
512
            $this->_elements[$key]->freeze();
513
        }
514
    }
515
516
    function unfreeze()
517
    {
518
        parent::unfreeze();
519
        foreach (array_keys($this->_elements) as $key) {
520
            $this->_elements[$key]->unfreeze();
521
        }
522
    }
523
524
    function setPersistantFreeze($persistant = false)
525
    {
526
        parent::setPersistantFreeze($persistant);
527
        foreach (array_keys($this->_elements) as $key) {
528
            $this->_elements[$key]->setPersistantFreeze($persistant);
529
        }
530
    }
531
532
    /**
533
     * @param string $layout
534
     *
535
     * @return string
536
     */
537
    public function getTemplate($layout)
538
    {
539
        $size = $this->calculateSize();
540
541
        switch ($layout) {
542
            case FormValidator::LAYOUT_INLINE:
543
                return '
544
                <div class="input-group">
545
                    <label {label-for} >
546
                        <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
547
                        {label}
548
                    </label>     
549
                </div>
550
                <div class="input-group {error_class}">                               
551
                    {element}
552
                </div>
553
                ';
554
                break;
555
            case FormValidator::LAYOUT_HORIZONTAL:
556
                return '
557
                <div class="form-group row {error_class}" id="'.$this->getName().'-group">
558
                    <label {label-for}  class="col-sm-'.$size[0].' col-form-label  {extra_label_class}" >
559
                        <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
560
                        {label}
561
                    </label>
562
                    <div class="col-sm-'.$size[1].'">
563
                        {icon}
564
                        {element}
565
566
                        <!-- BEGIN label_2 -->
567
                            <p class="help-block">{label_2}</p>
568
                        <!-- END label_2 -->
569
570
                        <!-- BEGIN error -->
571
                            <span class="help-inline help-block">{error}</span>
572
                        <!-- END error -->
573
                    </div>
574
                    <div class="col-sm-'.$size[2].'">
575
                        <!-- BEGIN label_3 -->
576
                            {label_3}
577
                        <!-- END label_3 -->
578
                    </div>
579
                </div>';
580
                break;
581
            case FormValidator::LAYOUT_BOX_NO_LABEL:
582
                return '
583
                        <div class="input-group">
584
                            {icon}
585
                            {element}
586
                        </div>';
587
                break;
588
        }
589
    }
590
}
591