Completed
Pull Request — 1.11.x (#1661)
by José
27:18
created

FormValidator::addButton()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 28
nc 2
nop 8
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class FormValidator
6
 * create/manipulate/validate user input.
7
 */
8
class FormValidator extends HTML_QuickForm
9
{
10
    const LAYOUT_HORIZONTAL = 'horizontal';
11
    const LAYOUT_INLINE = 'inline';
12
    const LAYOUT_BOX = 'box';
13
    const LAYOUT_BOX_NO_LABEL = 'box-no-label';
14
15
    public $with_progress_bar = false;
16
    private $layout;
17
18
    /**
19
     * Constructor
20
     * @param string $name					Name of the form
21
     * @param string $method (optional			Method ('post' (default) or 'get')
22
     * @param string $action (optional			Action (default is $PHP_SELF)
23
     * @param string $target (optional			Form's target defaults to '_self'
24
     * @param mixed $attributes (optional)		Extra attributes for <form> tag
25
     * @param string $layout
26
     * @param bool $trackSubmit (optional)		Whether to track if the form was
27
     * submitted by adding a special hidden field (default = true)
28
     */
29
    public function __construct(
30
        $name,
31
        $method = 'post',
32
        $action = '',
33
        $target = '',
34
        $attributes = array(),
35
        $layout = self::LAYOUT_HORIZONTAL,
36
        $trackSubmit = true
37
    ) {
38
        // Default form class.
39
        if (is_array($attributes) && !isset($attributes['class']) || empty($attributes)) {
40
            $attributes['class'] = 'form-horizontal';
41
        }
42
43
        if (isset($attributes['class']) && strpos($attributes['class'], 'form-search') !== false) {
44
            $layout = 'inline';
45
        }
46
47
        $this->setLayout($layout);
48
49
        switch ($layout) {
50
            case self::LAYOUT_HORIZONTAL:
51
                $attributes['class'] = 'form-horizontal';
52
                break;
53
            case self::LAYOUT_INLINE:
54
            case self::LAYOUT_BOX:
55
                $attributes['class'] = 'form-inline';
56
                break;
57
        }
58
59
        parent::__construct($name, $method, $action, $target, $attributes, $trackSubmit);
60
61
        // Modify the default templates
62
        $renderer = & $this->defaultRenderer();
63
64
        // Form template
65
        $formTemplate = $this->getFormTemplate();
66
        $renderer->setFormTemplate($formTemplate);
67
68
        // Element template
69
        if (isset($attributes['class']) && $attributes['class'] == 'form-inline') {
70
            $elementTemplate = ' {label}  {element} ';
71
            $renderer->setElementTemplate($elementTemplate);
72
        } elseif (isset($attributes['class']) && $attributes['class'] == 'form-search') {
73
            $elementTemplate = ' {label}  {element} ';
74
            $renderer->setElementTemplate($elementTemplate);
75
        } else {
76
            $renderer->setElementTemplate($this->getDefaultElementTemplate());
77
78
            // Display a gray div in the buttons
79
            $templateSimple = '<div class="form-actions">{label} {element}</div>';
80
            $renderer->setElementTemplate($templateSimple, 'submit_in_actions');
81
82
            //Display a gray div in the buttons + makes the button available when scrolling
83
            $templateBottom = '<div class="form-actions bottom_actions bg-form">{label} {element}</div>';
84
            $renderer->setElementTemplate($templateBottom, 'submit_fixed_in_bottom');
85
86
            //When you want to group buttons use something like this
87
            /* $group = array();
88
              $group[] = $form->createElement('button', 'mark_all', get_lang('MarkAll'));
89
              $group[] = $form->createElement('button', 'unmark_all', get_lang('UnmarkAll'));
90
              $form->addGroup($group, 'buttons_in_action');
91
             */
92
            $renderer->setElementTemplate($templateSimple, 'buttons_in_action');
93
94
            $templateSimpleRight = '<div class="form-actions"> <div class="pull-right">{label} {element}</div></div>';
95
            $renderer->setElementTemplate($templateSimpleRight, 'buttons_in_action_right');
96
        }
97
98
        //Set Header template
99
        $renderer->setHeaderTemplate('<legend>{header}</legend>');
100
101
        //Set required field template
102
        $this->setRequiredNote('<span class="form_required">*</span> <small>' . get_lang('ThisFieldIsRequired') . '</small>');
103
        $noteTemplate = <<<EOT
104
	<div class="form-group">
105
		<div class="col-sm-offset-2 col-sm-10">{requiredNote}</div>
106
	</div>
107
EOT;
108
        $renderer->setRequiredNoteTemplate($noteTemplate);
109
    }
110
111
    /**
112
     * @return string
113
     */
114
    public function getFormTemplate()
115
    {
116
        return '<form{attributes}>
117
        <fieldset>
118
            {content}
119
        </fieldset>
120
        {hidden}
121
        </form>';
122
    }
123
124
    /**
125
     * @return string
126
     */
127
    public function getDefaultElementTemplate()
128
    {
129
        return '
130
            <div class="form-group {error_class}">
131
                <label {label-for} class="col-sm-2 control-label {extra_label_class}" >
132
                    <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
133
                    {label}
134
                </label>
135
                <div class="col-sm-8">
136
                    {icon}
137
                    {element}
138
139
                    <!-- BEGIN label_2 -->
140
                        <p class="help-block">{label_2}</p>
141
                    <!-- END label_2 -->
142
143
                    <!-- BEGIN error -->
144
                        <span class="help-inline">{error}</span>
145
                    <!-- END error -->
146
                </div>
147
                <div class="col-sm-2">
148
                    <!-- BEGIN label_3 -->
149
                        {label_3}
150
                    <!-- END label_3 -->
151
                </div>
152
            </div>';
153
    }
154
155
    /**
156
     * @return string
157
     */
158
    public function getLayout()
159
    {
160
        return $this->layout;
161
    }
162
163
    /**
164
     * @param string $layout
165
     */
166
    public function setLayout($layout)
167
    {
168
        $this->layout = $layout;
169
    }
170
171
    /**
172
     * Adds a text field to the form.
173
     * A trim-filter is attached to the field.
174
     * @param string $label					The label for the form-element
175
     * @param string $name					The element name
176
     * @param bool   $required	(optional)	Is the form-element required (default=true)
177
     * @param array  $attributes (optional)	List of attributes for the form-element
178
     */
179
    public function addText($name, $label, $required = true, $attributes = array())
180
    {
181
        $this->addElement('text', $name, $label, $attributes);
182
        $this->applyFilter($name, 'trim');
183
        if ($required) {
184
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
185
        }
186
    }
187
188
    /**
189
     * The "date_range_picker" element creates 2 hidden fields
190
     * "elementName" + "_start"  and "elementName" + "_end"
191
     * For example if the name is "range", you will have 2 new fields
192
     * when executing $form->getSubmitValues()
193
     * "range_start" and "range_end"
194
     *
195
     * @param string $name
196
     * @param string $label
197
     * @param bool   $required
198
     * @param array  $attributes
199
     */
200 View Code Duplication
    public function addDateRangePicker($name, $label, $required = true, $attributes = array())
201
    {
202
        $this->addElement('date_range_picker', $name, $label, $attributes);
203
        $this->addElement('hidden', $name.'_start');
204
        $this->addElement('hidden', $name.'_end');
205
206
        if ($required) {
207
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
208
        }
209
    }
210
211
    /**
212
     * @param string $name
213
     * @param string $label
214
     * @param array $attributes
215
     *
216
     * @return mixed
217
     */
218
    public function addDatePicker($name, $label, $attributes = [])
219
    {
220
        return $this->addElement('DatePicker', $name, $label, $attributes);
221
    }
222
223
    /**
224
     * @param string $name
225
     * @param string $label
226
     * @param array $attributes
227
     *
228
     * @return mixed
229
     */
230
    public function addSelectLanguage($name, $label, $options = [], $attributes = [])
231
    {
232
        return $this->addElement('SelectLanguage', $name, $label, $options, $attributes);
233
    }
234
235
    /**
236
     * @param $name
237
     * @param $label
238
     * @param array $options
239
     * @param array $attributes
240
     * @throws
241
     */
242
    public function addSelectAjax($name, $label, $options = [], $attributes = [])
243
    {
244
        if (!isset($attributes['url'])) {
245
            throw new \Exception('select_ajax needs an URL');
246
        }
247
        $this->addElement(
248
            'select_ajax',
249
            $name,
250
            $label,
251
            $options,
252
            $attributes
253
        );
254
    }
255
256
    /**
257
     * @param string $name
258
     * @param string $label
259
     * @param array $attributes
260
     *
261
     * @return mixed
262
     */
263
    public function addDateTimePicker($name, $label, $attributes = [])
264
    {
265
        return $this->addElement('DateTimePicker', $name, $label, $attributes);
266
    }
267
268
    /**
269
     * @param string $name
270
     * @param string $value
271
     */
272
    public function addHidden($name, $value)
273
    {
274
        $this->addElement('hidden', $name, $value);
275
    }
276
277
    /**
278
     * @param string $name
279
     * @param string $label
280
     * @param array  $attributes
281
     *
282
     * @return HTML_QuickForm_textarea
283
     */
284
    public function addTextarea($name, $label, $attributes = array())
285
    {
286
        return $this->addElement('textarea', $name, $label, $attributes);
287
    }
288
289
    /**
290
     * @param string $name
291
     * @param string $label
292
     * @param string $icon font-awesome
293
     * @param string $style default|primary|success|info|warning|danger|link
294
     * @param string $size large|default|small|extra-small
295
     * @param string $class Example plus is transformed to icon fa fa-plus
296
     * @param array  $attributes
297
     *
298
     * @return HTML_QuickForm_button
299
     */
300
    public function addButton(
301
        $name,
302
        $label,
303
        $icon = 'check',
304
        $style = 'default',
305
        $size = 'default',
306
        $class = null,
307
        $attributes = array(),
308
        $createElement = false
309
    ) {
310
        if ($createElement) {
311
            return $this->createElement(
312
                'button',
313
                $name,
314
                $label,
315
                $icon,
316
                $style,
317
                $size,
318
                $class,
319
                $attributes
320
            );
321
        }
322
323
        return $this->addElement(
324
            'button',
325
            $name,
326
            $label,
327
            $icon,
328
            $style,
329
            $size,
330
            $class,
331
            $attributes
332
        );
333
    }
334
335
    /**
336
     * Returns a button with the primary color and a check mark
337
     * @param string $label Text appearing on the button
338
     * @param string $name Element name (for form treatment purposes)
339
     * @param bool $createElement Whether to use the create or add method
340
     *
341
     * @return HTML_QuickForm_button
342
     */
343
    public function addButtonSave($label, $name = 'submit', $createElement = false)
344
    {
345
        return $this->addButton(
346
            $name,
347
            $label,
348
            'check',
349
            'primary',
350
            null,
351
            null,
352
            array(),
353
            $createElement
354
        );
355
    }
356
357
    /**
358
     * Returns a cancel button
359
     * @param string $label Text appearing on the button
360
     * @param string $name Element name (for form treatment purposes)
361
     * @param bool $createElement Whether to use the create or add method
362
     *
363
     * @return HTML_QuickForm_button
364
     */
365
    public function addButtonCancel($label, $name = 'submit', $createElement = false)
366
    {
367
        return $this->addButton(
368
            $name,
369
            $label,
370
            'times',
371
            'danger',
372
            null,
373
            null,
374
            array(),
375
            $createElement
376
        );
377
    }
378
379
    /**
380
     * Returns a button with the primary color and a "plus" icon
381
     * @param string $label Text appearing on the button
382
     * @param string $name Element name (for form treatment purposes)
383
     * @param bool $createElement Whether to use the create or add method
384
     * @param array $attributes Additional attributes
385
     *
386
     * @return HTML_QuickForm_button
387
     */
388
    public function addButtonCreate($label, $name = 'submit', $createElement = false, $attributes = array())
389
    {
390
        return $this->addButton(
391
            $name,
392
            $label,
393
            'plus',
394
            'primary',
395
            null,
396
            null,
397
            $attributes,
398
            $createElement
399
        );
400
    }
401
402
    /**
403
     * Returns a button with the primary color and a pencil icon
404
     * @param string $label Text appearing on the button
405
     * @param string $name Element name (for form treatment purposes)
406
     * @param bool $createElement Whether to use the create or add method
407
     * @return HTML_QuickForm_button
408
     */
409
    public function addButtonUpdate($label, $name = 'submit', $createElement = false)
410
    {
411
        return $this->addButton(
412
            $name,
413
            $label,
414
            'pencil',
415
            'primary',
416
            null,
417
            null,
418
            array(),
419
            $createElement
420
        );
421
    }
422
423
    /**
424
     * Returns a button with the danger color and a trash icon
425
     * @param string $label Text appearing on the button
426
     * @param string $name Element name (for form treatment purposes)
427
     * @param bool $createElement Whether to use the create or add method
428
     *
429
     * @return HTML_QuickForm_button
430
     */
431
    public function addButtonDelete($label, $name = 'submit', $createElement = false)
432
    {
433
        return $this->addButton(
434
            $name,
435
            $label,
436
            'trash',
437
            'danger',
438
            null,
439
            null,
440
            array(),
441
            $createElement
442
        );
443
    }
444
445
    /**
446
     * Returns a button with the primary color and a paper-plane icon
447
     * @param string $label Text appearing on the button
448
     * @param string $name Element name (for form treatment purposes)
449
     * @param bool $createElement Whether to use the create or add method
450
     *
451
     * @return HTML_QuickForm_button
452
     */
453
    public function addButtonSend($label, $name = 'submit', $createElement = false, $attributes = array())
454
    {
455
        return $this->addButton(
456
            $name,
457
            $label,
458
            'paper-plane',
459
            'primary',
460
            null,
461
            null,
462
            $attributes,
463
            $createElement
464
        );
465
    }
466
467
    /**
468
     * Returns a button with the default (grey?) color and a magnifier icon
469
     * @param string $label Text appearing on the button
470
     * @param string $name Element name (for form treatment purposes)
471
     *
472
     * @return HTML_QuickForm_button
473
     */
474
    public function addButtonSearch($label = null, $name = 'submit')
475
    {
476
        if (empty($label)) {
477
            $label = get_lang('Search');
478
        }
479
480
        return $this->addButton($name, $label, 'search', 'default');
481
    }
482
483
    /**
484
     * Returns a button with the primary color and a right-pointing arrow icon
485
     * @param string $label Text appearing on the button
486
     * @param string $name Element name (for form treatment purposes)
487
     * @param array $attributes Additional attributes
488
     * @return HTML_QuickForm_button
489
     */
490
    public function addButtonNext($label, $name = 'submit', $attributes = array())
491
    {
492
        return $this->addButton($name, $label, 'arrow-right', 'primary', null, null, $attributes);
493
    }
494
495
    /**
496
     * Returns a button with the primary color and a check mark icon
497
     * @param string $label Text appearing on the button
498
     * @param string $name Element name (for form treatment purposes)
499
     * @param bool $createElement Whether to use the create or add method
500
     * @return HTML_QuickForm_button
501
     */
502
    public function addButtonImport($label, $name = 'submit', $createElement = false)
503
    {
504
        return $this->addButton(
505
            $name,
506
            $label,
507
            'check',
508
            'primary',
509
            null,
510
            null,
511
            array(),
512
            $createElement
513
        );
514
    }
515
516
    /**
517
     * Returns a button with the primary color and a check-mark icon
518
     * @param string $label Text appearing on the button
519
     * @param string $name Element name (for form treatment purposes)
520
     * @param bool $createElement Whether to use the create or add method
521
     * @return HTML_QuickForm_button
522
     */
523
    public function addButtonExport($label, $name = 'submit', $createElement = false)
524
    {
525
        return $this->addButton(
526
            $name,
527
            $label,
528
            'check',
529
            'primary',
530
            null,
531
            null,
532
            array(),
533
            $createElement
534
        );
535
    }
536
537
    /**
538
     * Shortcut to filter button
539
     * @param string $label Text appearing on the button
540
     * @param string $name Element name (for form treatment purposes)
541
     * @param bool $createElement Whether to use the create or add method
542
     * @return HTML_QuickForm_button
543
     */
544
    public function addButtonFilter($label, $name = 'submit', $createElement = false)
545
    {
546
        return $this->addButton(
547
            $name,
548
            $label,
549
            'filter',
550
            'primary',
551
            null,
552
            null,
553
            array(),
554
            $createElement
555
        );
556
    }
557
558
    /**
559
     * Shortcut to reset button
560
     * @param string $label Text appearing on the button
561
     * @param string $name Element name (for form treatment purposes)
562
     * @param bool $createElement Whether to use the create or add method
563
     * @return HTML_QuickForm_button
564
     */
565
    public function addButtonReset($label, $name = 'reset', $createElement = false)
566
    {
567
        $icon = 'eraser';
568
        $style = 'default';
569
        $size = 'default';
570
        $class = null;
571
        $attributes = array();
572
573
        if ($createElement) {
574
            return $this->createElement(
575
                'reset',
576
                $name,
577
                $label,
578
                $icon,
579
                $style,
580
                $size,
581
                $class,
582
                $attributes
583
            );
584
        }
585
586
        return $this->addElement(
587
            'reset',
588
            $name,
589
            $label,
590
            $icon,
591
            $style,
592
            $size,
593
            $class,
594
            $attributes
595
        );
596
    }
597
598
    /**
599
     * Returns a button with the primary color and an upload icon
600
     * @param string $label Text appearing on the button
601
     * @param string $name Element name (for form treatment purposes)
602
     * @param bool $createElement Whether to use the create or add method
603
     *
604
     * @return HTML_QuickForm_button
605
     */
606
    public function addButtonUpload($label, $name = 'submit', $createElement = false)
607
    {
608
        return $this->addButton(
609
            $name,
610
            $label,
611
            'upload',
612
            'primary',
613
            null,
614
            null,
615
            array(),
616
            $createElement
617
        );
618
    }
619
620
    /**
621
     * Returns a button with the primary color and a download icon
622
     * @param string $label Text appearing on the button
623
     * @param string $name Element name (for form treatment purposes)
624
     * @param bool $createElement Whether to use the create or add method
625
     *
626
     * @return HTML_QuickForm_button
627
     */
628
    public function addButtonDownload($label, $name = 'submit', $createElement = false)
629
    {
630
        return $this->addButton(
631
            $name,
632
            $label,
633
            'download',
634
            'primary',
635
            null,
636
            null,
637
            array(),
638
            $createElement
639
        );
640
    }
641
642
    /**
643
     * Returns a button with the primary color and a magnifier icon
644
     * @param string $label Text appearing on the button
645
     * @param string $name Element name (for form treatment purposes)
646
     * @param bool $createElement Whether to use the create or add method
647
     *
648
     * @return HTML_QuickForm_button
649
     */
650 View Code Duplication
    public function addButtonPreview($label, $name = 'submit', $createElement = false)
651
    {
652
        return $this->addButton(
653
            $name,
654
            $label,
655
            'search',
656
            'primary',
657
            null,
658
            null,
659
            array(),
660
            $createElement
661
        );
662
    }
663
664
    /**
665
     * Returns a button with the primary color and a copy (double sheet) icon
666
     * @param string $label Text appearing on the button
667
     * @param string $name Element name (for form treatment purposes)
668
     * @param bool $createElement Whether to use the create or add method
669
     *
670
     * @return HTML_QuickForm_button
671
     */
672 View Code Duplication
    public function addButtonCopy($label, $name = 'submit', $createElement = false)
673
    {
674
        return $this->addButton(
675
            $name,
676
            $label,
677
            'copy',
678
            'primary',
679
            null,
680
            null,
681
            array(),
682
            $createElement
683
        );
684
    }
685
686
    /**
687
     * @param string $name
688
     * @param string $label
689
     * @param string $text
690
     * @param array  $attributes
691
     *
692
     * @return HTML_QuickForm_checkbox
693
     */
694
    public function addCheckBox($name, $label, $text = '', $attributes = array())
695
    {
696
        return $this->addElement('checkbox', $name, $label, $text, $attributes);
697
    }
698
699
    /**
700
     * @param string $name
701
     * @param string $label
702
     * @param array  $options
703
     * @param array  $attributes
704
     *
705
     * @return HTML_QuickForm_group
706
     */
707 View Code Duplication
    public function addCheckBoxGroup($name, $label, $options = array(), $attributes = array())
708
    {
709
        $group = array();
710
        foreach ($options as $value => $text) {
711
            $attributes['value'] = $value;
712
            $group[] = $this->createElement('checkbox', $value, null, $text, $attributes);
713
        }
714
715
        return $this->addGroup($group, $name, $label);
716
    }
717
718
    /**
719
     * @param string $name
720
     * @param string $label
721
     * @param array  $options
722
     * @param array  $attributes
723
     *
724
     * @return HTML_QuickForm_radio
725
     */
726 View Code Duplication
    public function addRadio($name, $label, $options = array(), $attributes = array())
727
    {
728
        $group = array();
729
        foreach ($options as $key => $value) {
730
            $group[] = $this->createElement('radio', null, null, $value, $key, $attributes);
731
        }
732
733
        return $this->addGroup($group, $name, $label);
734
    }
735
736
    /**
737
     * @param string $name
738
     * @param string $label
739
     * @param array  $options
740
     * @param array  $attributes
741
     *
742
     * @return HTML_QuickForm_select
743
     */
744
    public function addSelect($name, $label, $options = array(), $attributes = array())
745
    {
746
        return $this->addElement('select', $name, $label, $options, $attributes);
747
    }
748
749
    /**
750
     * @param $name
751
     * @param $label
752
     * @param $collection
753
     * @param array $attributes
754
     * @param bool $addNoneOption
755
     * @param string $textCallable set a function getStringValue() by default __toString()
756
     *
757
     * @return HTML_QuickForm_element
758
     */
759
    public function addSelectFromCollection(
760
        $name,
761
        $label,
762
        $collection,
763
        $attributes = array(),
764
        $addNoneOption = false,
765
        $textCallable = ''
766
    ) {
767
        $options = [];
768
769
        if ($addNoneOption) {
770
            $options[0] = get_lang('None');
771
        }
772
773
        if (!empty($collection)) {
774
            foreach ($collection as $item) {
775
                $text = $item;
776
                if (!empty($textCallable)) {
777
                    $text = $item->$textCallable();
778
                }
779
                $options[$item->getId()] = $text;
780
            }
781
        }
782
        return $this->addElement('select', $name, $label, $options, $attributes);
783
    }
784
785
    /**
786
     * @param string $label
787
     * @param string $text
788
     *
789
     * @return HTML_QuickForm_label
790
     */
791
    public function addLabel($label, $text)
792
    {
793
        return $this->addElement('label', $label, $text);
794
    }
795
796
    /**
797
     * @param string $text
798
     */
799
    public function addHeader($text)
800
    {
801
        $this->addElement('header', $text);
802
    }
803
804
    /**
805
     * @param string $name
806
     * @param string $label
807
     * @param array  $attributes
808
     * @throws Exception if the file doesn't have an id
809
     */
810
    public function addFile($name, $label, $attributes = array())
811
    {
812
        $element = $this->addElement('file', $name, $label, $attributes);
813
        if (isset($attributes['crop_image'])) {
814
            $id = $element->getAttribute('id');
815
            if (empty($id)) {
816
                throw new Exception('If you use the crop functionality the element must have an id');
817
            }
818
            $this->addHtml('
819
                <div class="form-group">
820
                <label for="cropImage" id="'.$id.'_label_crop_image" class="col-sm-2 control-label"></label>
821
                <div class="col-sm-8">
822
                <div id="'.$id.'_crop_image" class="cropCanvas">
823
                <img id="'.$id.'_preview_image">
824
                </div>
825
                <div>
826
                <button class="btn btn-primary hidden" name="cropButton" id="'.$id.'_crop_button" >
827
                    <em class="fa fa-crop"></em> '.
828
                    get_lang('CropYourPicture').'
829
                </button>
830
                </div>
831
                </div>
832
                </div>'
833
            );
834
            $this->addHidden($id.'_crop_result', '');
835
            $this->addHidden($id.'_crop_image_base_64', '');
836
        }
837
    }
838
839
    /**
840
     * @param string $snippet
841
     */
842
    public function addHtml($snippet)
843
    {
844
        $this->addElement('html', $snippet);
845
    }
846
847
    /**
848
     * Adds a HTML-editor to the form
849
     * @param string $name
850
     * @param string $label The label for the form-element
851
     * @param bool   $required (optional) Is the form-element required (default=true)
852
     * @param bool   $fullPage (optional) When it is true, the editor loads completed html code for a full page.
853
     * @param array  $config (optional) Configuration settings for the online editor.
854
     * @param bool   $style
855
     */
856
    public function addHtmlEditor($name, $label, $required = true, $fullPage = false, $config = array(), $style = false)
857
    {
858
        $config['rows'] = isset($config['rows']) ? $config['rows'] : 15;
859
        $config['cols'] = isset($config['cols']) ? $config['cols'] : 80;
860
        $this->addElement('html_editor', $name, $label, $config, $style);
861
        $this->applyFilter($name, 'trim');
862
        if ($required) {
863
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
864
        }
865
866
        /** @var HtmlEditor $element */
867
        $element = $this->getElement($name);
868
869
        if ($style) {
870
            $config['style'] = true;
871
        }
872
        if ($fullPage) {
873
            $config['fullPage'] = true;
874
        }
875
876
        if ($element->editor) {
877
            $element->editor->processConfig($config);
878
        }
879
    }
880
881
    /**
882
     * Adds a Google Maps Geolocalization field to the form
883
     *
884
     * @param $name
885
     * @param $label
886
     */
887
    public function addGeoLocationMapField($name, $label)
888
    {
889
        $gMapsPlugin = GoogleMapsPlugin::create();
890
        $geolocalization = $gMapsPlugin->get('enable_api') === 'true';
891
892
        if ($geolocalization) {
893
            $gmapsApiKey = $gMapsPlugin->get('api_key');
894
            $this->addHtml('<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?key='. $gmapsApiKey . '" ></script>');
895
        }
896
        $this->addElement(
897
            'text',
898
            $name,
899
            $label,
900
            ['id' => $name]
901
        );
902
        $this->applyFilter($name, 'stripslashes');
903
        $this->applyFilter($name, 'trim');
904
        $this->addHtml('
905
                            <div class="form-group">
906
                                <label for="geolocalization_'.$name.'" class="col-sm-2 control-label"></label>
907
                                <div class="col-sm-8">
908
                                    <button class="null btn btn-default " id="geolocalization_'.$name.'" name="geolocalization_'.$name.'" type="submit"><em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'</button>
909
                                    <button class="null btn btn-default " id="myLocation_'.$name.'" name="myLocation_'.$name.'" type="submit"><em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'</button>
910
                                </div>
911
                            </div>
912
                        ');
913
914
        $this->addHtml('
915
                            <div class="form-group">
916
                                <label for="map_'.$name.'" class="col-sm-2 control-label">
917
                                    '.$label.' - '.get_lang('Map').'
918
                                </label>
919
                                <div class="col-sm-8">
920
                                    <div name="map_'.$name.'" id="map_'.$name.'" style="width:100%; height:300px;">
921
                                    </div>
922
                                </div>
923
                            </div>
924
                        ');
925
926
        $this->addHtml(
927
            '<script>
928
                $(document).ready(function() {
929
930
                    if (typeof google === "object") {
931
932
                        var address = $("#' . $name . '").val();
933
                        initializeGeo'.$name.'(address, false);
934
935
                        $("#geolocalization_'.$name.'").on("click", function() {
936
                            var address = $("#'.$name.'").val();
937
                            initializeGeo'.$name.'(address, false);
938
                            return false;
939
                        });
940
941
                        $("#myLocation_'.$name.'").on("click", function() {
942
                            myLocation'.$name.'();
943
                            return false;
944
                        });
945
946
                        $("#'.$name.'").keypress(function (event) {
947
                            if (event.which == 13) {
948
                                $("#geolocalization_'.$name.'").click();
949
                                return false;
950
                            }
951
                        });
952
953
                    } else {
954
                        $("#map_'.$name.'").html("<div class=\"alert alert-info\">' . get_lang('YouNeedToActivateTheGoogleMapsPluginInAdminPlatformToSeeTheMap') . '</div>");
955
                    }
956
957
                });
958
959
                function myLocation'.$name.'() {
960
                    if (navigator.geolocation) {
961
                        var geoPosition = function(position) {
962
                            var lat = position.coords.latitude;
963
                            var lng = position.coords.longitude;
964
                            var latLng = new google.maps.LatLng(lat, lng);
965
                            initializeGeo'.$name.'(false, latLng)
966
                        };
967
968
                        var geoError = function(error) {
969
                            alert("Geocode ' . get_lang('Error') . ': " + error);
970
                        };
971
972
                        var geoOptions = {
973
                            enableHighAccuracy: true
974
                        };
975
976
                        navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
977
                    }
978
                }
979
980
                function initializeGeo'.$name.'(address, latLng) {
981
                    var geocoder = new google.maps.Geocoder();
982
                    var latlng = new google.maps.LatLng(-34.397, 150.644);
983
                    var myOptions = {
984
                        zoom: 15,
985
                        center: latlng,
986
                        mapTypeControl: true,
987
                        mapTypeControlOptions: {
988
                            style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
989
                        },
990
                        navigationControl: true,
991
                        mapTypeId: google.maps.MapTypeId.ROADMAP
992
                    };
993
994
                    map_'.$name.' = new google.maps.Map(document.getElementById("map_'.$name.'"), myOptions);
995
996
                    var parameter = address ? { "address": address } : latLng ? { "latLng": latLng } : false;
997
998
                    if (geocoder && parameter) {
999
                        geocoder.geocode(parameter, function(results, status) {
1000
                            if (status == google.maps.GeocoderStatus.OK) {
1001
                                if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
1002
                                    map_'.$name.'.setCenter(results[0].geometry.location);
1003
                                    if (!address) {
1004
                                        $("#'.$name.'").val(results[0].formatted_address);
1005
                                    }
1006
                                    var infowindow = new google.maps.InfoWindow({
1007
                                        content: "<b>" + $("#'.$name.'").val() + "</b>",
1008
                                        size: new google.maps.Size(150, 50)
1009
                                    });
1010
1011
                                    var marker = new google.maps.Marker({
1012
                                        position: results[0].geometry.location,
1013
                                        map: map_'.$name.',
1014
                                        title: $("#'.$name.'").val()
1015
                                    });
1016
                                    google.maps.event.addListener(marker, "click", function() {
1017
                                        infowindow.open(map_'.$name.', marker);
1018
                                    });
1019
                                } else {
1020
                                    alert("' . get_lang("NotFound") . '");
1021
                                }
1022
1023
                            } else {
1024
                                alert("Geocode ' . get_lang('Error') . ': ' . get_lang("AddressField") . ' ' . get_lang("NotFound") . '");
1025
                            }
1026
                        });
1027
                    }
1028
                }
1029
            </script>
1030
        ');
1031
1032
    }
1033
1034
    /**
1035
     * @param string $name
1036
     * @param string $label
1037
     *
1038
     * @return mixed
1039
     */
1040
    public function addButtonAdvancedSettings($name, $label = '')
1041
    {
1042
        $label = !empty($label) ? $label : get_lang('AdvancedParameters');
1043
1044
        return $this->addElement('advanced_settings', $name, $label);
1045
    }
1046
1047
    /**
1048
     * Adds a progress loading image to the form.
1049
     *
1050
     */
1051
    public function addProgress($delay = 2, $label = '')
1052
    {
1053
        if (empty($label)) {
1054
            $label = get_lang('PleaseStandBy');
1055
        }
1056
        $this->with_progress_bar = true;
1057
        $id = $this->getAttribute('id');
1058
1059
        $this->updateAttributes("onsubmit=\"javascript: addProgress('" . $id . "')\"");
1060
        $this->addHtml('<script language="javascript" src="' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/upload.js" type="text/javascript"></script>');
1061
    }
1062
1063
    /**
1064
     * This function has been created for avoiding changes directly within QuickForm class.
1065
     * When we use it, the element is threated as 'required' to be dealt during validation.
1066
     * @param array $element The array of elements
0 ignored issues
show
Documentation introduced by
There is no parameter named $element. Did you maybe mean $elements?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1067
     * @param string $message The message displayed
1068
     */
1069
    public function add_multiple_required_rule($elements, $message)
1070
    {
1071
        $this->_required[] = $elements[0];
1072
        $this->addRule($elements, $message, 'multiple_required');
1073
    }
1074
1075
    /**
1076
     * Displays the form.
1077
     * If an element in the form didn't validate, an error message is showed
1078
     * asking the user to complete the form.
1079
     */
1080
    public function display()
1081
    {
1082
        echo $this->returnForm();
1083
    }
1084
1085
    /**
1086
     * Returns the HTML code of the form.
1087
     * @return string $return_value HTML code of the form
1088
     */
1089
    public function returnForm()
1090
    {
1091
        $returnValue = '';
1092
1093
        /** @var HTML_QuickForm_element $element */
1094
        foreach ($this->_elements as $element) {
1095
            $elementError = parent::getElementError($element->getName());
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getElementError() instead of returnForm()). Are you sure this is correct? If so, you might want to change this to $this->getElementError().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1096
            if (!is_null($elementError)) {
1097
                $returnValue .= Display::return_message($elementError, 'warning').'<br />';
1098
                break;
1099
            }
1100
        }
1101
1102
        $returnValue .= parent::toHtml();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (toHtml() instead of returnForm()). Are you sure this is correct? If so, you might want to change this to $this->toHtml().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1103
        // Add div-element which is to hold the progress bar
1104
        $id = $this->getAttribute('id');
1105
        if (isset($this->with_progress_bar) && $this->with_progress_bar) {
1106
            $icon = Display::return_icon('progress_bar.gif');
1107
1108
            // @todo improve UI
1109
            $returnValue .= '<br />
1110
1111
            <div id="loading_div_'.$id.'" class="loading_div" style="display:none;margin-left:40%; margin-top:10px; height:50px;">
1112
                '.$icon.'
1113
            </div>
1114
            ';
1115
        }
1116
1117
        return $returnValue;
1118
    }
1119
1120
    /**
1121
     * Returns the HTML code of the form.
1122
     * If an element in the form didn't validate, an error message is showed
1123
     * asking the user to complete the form.
1124
     *
1125
     * @return string $return_value HTML code of the form
1126
     *
1127
     * @author Patrick Cool <[email protected]>, Ghent University, august 2006
1128
     * @author Julio Montoya
1129
     * @deprecated use returnForm()
1130
     */
1131
    public function return_form()
1132
    {
1133
        return $this->returnForm();
1134
    }
1135
1136
    /**
1137
     * Create a form validator based on an array of form data:
1138
     *
1139
     *         array(
1140
     *             'name' => 'zombie_report_parameters',    //optional
1141
     *             'method' => 'GET',                       //optional
1142
     *             'items' => array(
1143
     *                 array(
1144
     *                     'name' => 'ceiling',
1145
     *                     'label' => 'Ceiling',            //optional
1146
     *                     'type' => 'date',
1147
     *                     'default' => date()              //optional
1148
     *                 ),
1149
     *                 array(
1150
     *                     'name' => 'active_only',
1151
     *                     'label' => 'ActiveOnly',
1152
     *                     'type' => 'checkbox',
1153
     *                     'default' => true
1154
     *                 ),
1155
     *                 array(
1156
     *                     'name' => 'submit_button',
1157
     *                     'type' => 'style_submit_button',
1158
     *                     'value' => get_lang('Search'),
1159
     *                     'attributes' => array('class' => 'search')
1160
     *                 )
1161
     *             )
1162
     *         );
1163
     *
1164
     * @param array $form_data
1165
     * @deprecated use normal FormValidator construct
1166
     *
1167
     * @return FormValidator
1168
     */
1169
    public static function create($form_data)
1170
    {
1171
        if (empty($form_data)) {
1172
            return null;
1173
        }
1174
        $form_name = isset($form_data['name']) ? $form_data['name'] : 'form';
1175
        $form_method = isset($form_data['method']) ? $form_data['method'] : 'POST';
1176
        $form_action = isset($form_data['action']) ? $form_data['action'] : '';
1177
        $form_target = isset($form_data['target']) ? $form_data['target'] : '';
1178
        $form_attributes = isset($form_data['attributes']) ? $form_data['attributes'] : null;
1179
        $form_track_submit = isset($form_data['track_submit']) ? $form_data['track_submit'] : true;
1180
        $reset = null;
1181
        $result = new FormValidator($form_name, $form_method, $form_action, $form_target, $form_attributes, $form_track_submit);
1182
1183
        $defaults = array();
1184
        foreach ($form_data['items'] as $item) {
1185
            $name = $item['name'];
1186
            $type = isset($item['type']) ? $item['type'] : 'text';
1187
            $label = isset($item['label']) ? $item['label'] : '';
1188
            if ($type == 'wysiwyg') {
1189
                $element = $result->addHtmlEditor($name, $label);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $element is correct as $result->addHtmlEditor($name, $label) (which targets FormValidator::addHtmlEditor()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1190
            } else {
1191
                $element = $result->addElement($type, $name, $label);
1192
            }
1193
            if (isset($item['attributes'])) {
1194
                $attributes = $item['attributes'];
1195
                $element->setAttributes($attributes);
1196
            }
1197
            if (isset($item['value'])) {
1198
                $value = $item['value'];
1199
                $element->setValue($value);
1200
            }
1201
            if (isset($item['default'])) {
1202
                $defaults[$name] = $item['default'];
1203
            }
1204
            if (isset($item['rules'])) {
1205
                $rules = $item['rules'];
1206
                foreach ($rules as $rule) {
1207
                    $message = $rule['message'];
1208
                    $type = $rule['type'];
1209
                    $format = isset($rule['format']) ? $rule['format'] : null;
1210
                    $validation = isset($rule['validation']) ? $rule['validation'] : 'server';
1211
                    $force = isset($rule['force']) ? $rule['force'] : false;
1212
                    $result->addRule($name, $message, $type, $format, $validation, $reset, $force);
1213
                }
1214
            }
1215
        }
1216
        $result->setDefaults($defaults);
1217
1218
        return $result;
1219
    }
1220
1221
    /**
1222
     * @return HTML_QuickForm_Renderer_Default
1223
     */
1224
    public static function getDefaultRenderer()
1225
    {
1226
        return
1227
            isset($GLOBALS['_HTML_QuickForm_default_renderer']) ?
1228
                $GLOBALS['_HTML_QuickForm_default_renderer'] : null;
1229
    }
1230
1231
    /**
1232
     * Adds a input of type url to the form.
1233
     * @param type $name The label for the form-element
1234
     * @param type $label The element name
1235
     * @param type $required Optional. Is the form-element required (default=true)
1236
     * @param type $attributes Optional. List of attributes for the form-element
1237
     */
1238 View Code Duplication
    public function addUrl($name, $label, $required = true, $attributes = array())
1239
    {
1240
        $this->addElement('url', $name, $label, $attributes);
1241
        $this->applyFilter($name, 'trim');
1242
        $this->addRule($name, get_lang('InsertAValidUrl'), 'url');
1243
1244
        if ($required) {
1245
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1246
        }
1247
    }
1248
1249
    /**
1250
     * Adds a text field for letters to the form.
1251
     * A trim-filter is attached to the field.
1252
     * @param string $name The element name
1253
     * @param string $label The label for the form-element
1254
     * @param bool $required Optional. Is the form-element required (default=true)
1255
     * @param array $attributes Optional. List of attributes for the form-element
1256
     */
1257 View Code Duplication
    public function addTextLettersOnly(
1258
        $name,
1259
        $label,
1260
        $required = false,
1261
        $attributes = []
1262
    ) {
1263
        $attributes = array_merge(
1264
            $attributes,
1265
            [
1266
                'pattern' => '[a-zA-ZñÑ]+',
1267
                'title' => get_lang('OnlyLetters')
1268
            ]
1269
        );
1270
1271
        $this->addElement(
1272
            'text',
1273
            $name,
1274
            [
1275
                $label,
1276
                get_lang('OnlyLetters')
1277
            ],
1278
            $attributes
1279
        );
1280
1281
        $this->applyFilter($name, 'trim');
1282
1283
        if ($required) {
1284
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1285
        }
1286
1287
        $this->addRule(
1288
            $name,
1289
            get_lang('OnlyLetters'),
1290
            'regex',
1291
            '/^[a-zA-ZñÑ]+$/'
1292
        );
1293
    }
1294
1295
    /**
1296
     * Adds a text field for alphanumeric characters to the form.
1297
     * A trim-filter is attached to the field.
1298
     * @param string $name The element name
1299
     * @param string $label The label for the form-element
1300
     * @param bool $required Optional. Is the form-element required (default=true)
1301
     * @param array $attributes Optional. List of attributes for the form-element
1302
     */
1303 View Code Duplication
    public function addTextAlphanumeric(
1304
        $name,
1305
        $label,
1306
        $required = false,
1307
        $attributes = []
1308
    ) {
1309
        $attributes = array_merge(
1310
            $attributes,
1311
            [
1312
                'pattern' => '[a-zA-Z0-9ñÑ]+',
1313
                'title' => get_lang('OnlyLettersAndNumbers')
1314
            ]
1315
        );
1316
1317
        $this->addElement(
1318
            'text',
1319
            $name,
1320
            [
1321
                $label,
1322
                get_lang('OnlyLettersAndNumbers')
1323
            ],
1324
            $attributes
1325
        );
1326
1327
        $this->applyFilter($name, 'trim');
1328
1329
        if ($required) {
1330
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1331
        }
1332
1333
        $this->addRule(
1334
            $name,
1335
            get_lang('OnlyLettersAndNumbers'),
1336
            'regex',
1337
            '/^[a-zA-Z0-9ÑÑ]+$/'
1338
        );
1339
    }
1340
1341
    /**
1342
     * @param $name
1343
     * @param $label
1344
     * @param bool $required
1345
     * @param array $attributes
1346
     * @param bool $allowNegative
1347
     * @param null $minValue
1348
     * @param null $maxValue
1349
     */
1350
    public function addFloat(
1351
        $name,
1352
        $label,
1353
        $required = false,
1354
        $attributes = [],
1355
        $allowNegative = false,
1356
        $minValue = null,
1357
        $maxValue = null
1358
    ) {
1359
        $this->addElement(
1360
            'FloatNumber',
1361
            $name,
1362
            $label,
1363
            $attributes
1364
        );
1365
1366
        $this->applyFilter($name, 'trim');
1367
1368
        if ($required) {
1369
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1370
        }
1371
1372
        // Rule allows "," and "."
1373
        /*$this->addRule(
1374
            $name,
1375
            get_lang('OnlyNumbers'),
1376
            'regex',
1377
            '/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)|(^-?\d\d*\,\d*$)|(^-?\,\d\d*$)/'
1378
        );*/
1379
1380
        if ($allowNegative == false) {
1381
            $this->addRule(
1382
                $name,
1383
                get_lang('NegativeValue'),
1384
                'compare',
1385
                '>=',
1386
                'server',
1387
                false,
1388
                false,
1389
                0
1390
            );
1391
        }
1392
1393 View Code Duplication
        if (!is_null($minValue)) {
1394
            $this->addRule(
1395
                $name,
1396
                get_lang('UnderMin'),
1397
                'compare',
1398
                '>=',
1399
                'server',
1400
                false,
1401
                false,
1402
                $minValue
1403
            );
1404
        }
1405
1406 View Code Duplication
        if (!is_null($maxValue)) {
1407
            $this->addRule(
1408
                $name,
1409
                get_lang('OverMax'),
1410
                'compare',
1411
                '<=',
1412
                'server',
1413
                false,
1414
                false,
1415
                $maxValue
1416
            );
1417
        }
1418
    }
1419
1420
    /**
1421
     * Adds a text field for letters and spaces to the form.
1422
     * A trim-filter is attached to the field.
1423
     * @param string $name The element name
1424
     * @param string $label The label for the form-element
1425
     * @param bool $required Optional. Is the form-element required (default=true)
1426
     * @param array $attributes Optional. List of attributes for the form-element
1427
     */
1428 View Code Duplication
    public function addTextLettersAndSpaces(
1429
        $name,
1430
        $label,
1431
        $required = false,
1432
        $attributes = []
1433
    ) {
1434
        $attributes = array_merge(
1435
            $attributes,
1436
            [
1437
                'pattern' => '[a-zA-ZñÑ\s]+',
1438
                'title' => get_lang('OnlyLettersAndSpaces')
1439
            ]
1440
        );
1441
1442
        $this->addElement(
1443
            'text',
1444
            $name,
1445
            [
1446
                $label,
1447
                get_lang('OnlyLettersAndSpaces')
1448
            ],
1449
            $attributes
1450
        );
1451
1452
        $this->applyFilter($name, 'trim');
1453
1454
        if ($required) {
1455
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1456
        }
1457
1458
        $this->addRule(
1459
            $name,
1460
            get_lang('OnlyLettersAndSpaces'),
1461
            'regex',
1462
            '/^[a-zA-ZñÑ\s]+$/'
1463
        );
1464
    }
1465
1466
    /**
1467
     * Adds a text field for alphanumeric and spaces characters to the form.
1468
     * A trim-filter is attached to the field.
1469
     * @param string $name The element name
1470
     * @param string $label The label for the form-element
1471
     * @param bool $required Optional. Is the form-element required (default=true)
1472
     * @param array $attributes Optional. List of attributes for the form-element
1473
     */
1474 View Code Duplication
    public function addTextAlphanumericAndSpaces(
1475
        $name,
1476
        $label,
1477
        $required = false,
1478
        $attributes = []
1479
    ) {
1480
        $attributes = array_merge(
1481
            $attributes,
1482
            [
1483
                'pattern' => '[a-zA-Z0-9ñÑ\s]+',
1484
                'title' => get_lang('OnlyLettersAndNumbersAndSpaces')
1485
            ]
1486
        );
1487
1488
        $this->addElement(
1489
            'text',
1490
            $name,
1491
            [
1492
                $label,
1493
                get_lang('OnlyLettersAndNumbersAndSpaces')
1494
            ],
1495
            $attributes
1496
        );
1497
1498
        $this->applyFilter($name, 'trim');
1499
1500
        if ($required) {
1501
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1502
        }
1503
1504
        $this->addRule(
1505
            $name,
1506
            get_lang('OnlyLettersAndNumbersAndSpaces'),
1507
            'regex',
1508
            '/^[a-zA-Z0-9ñÑ\s]+$/'
1509
        );
1510
    }
1511
1512
    /**
1513
     * @param string $url
1514
     */
1515
    public function addMultipleUpload($url)
1516
    {
1517
        $inputName = 'input_file_upload';
1518
        $this->addMultipleUploadJavascript($url, $inputName);
1519
1520
        $this->addHtml('
1521
            <div class="description-upload">'.get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'</div>
1522
            <span class="btn btn-success fileinput-button">
1523
                <i class="glyphicon glyphicon-plus"></i>
1524
                <span>'.get_lang('AddFiles').'</span>
1525
                <!-- The file input field used as target for the file upload widget -->
1526
                <input id="'.$inputName.'" type="file" name="files[]" multiple>
1527
            </span>
1528
            <br />
1529
            <br />
1530
            <div id="dropzone">
1531
                <div class="button-load">
1532
                '.get_lang('UploadFiles').'
1533
                </div>
1534
            </div>
1535
1536
            <br />
1537
            <!-- The global progress bar -->
1538
            <div id="progress" class="progress">
1539
                <div class="progress-bar progress-bar-success"></div>
1540
            </div>
1541
            <div id="files" class="files"></div>
1542
        ');
1543
    }
1544
1545
    /**
1546
     *
1547
     * @param string $url page that will handle the upload
1548
     * @param string $inputName
1549
     */
1550
    private function addMultipleUploadJavascript($url, $inputName)
1551
    {
1552
        $icon = Display::return_icon('file_txt.gif');
1553
        $this->addHtml("
1554
        <script>
1555
        $(function () {
1556
            'use strict';
1557
            $('#".$this->getAttribute('id')."').submit(function() {
1558
                return false;
1559
            });
1560
1561
            $('#dropzone').on('click', function() {
1562
                $('#".$inputName."').click();
1563
            });
1564
1565
            var url = '".$url."';
1566
            var uploadButton = $('<button/>')
1567
                .addClass('btn btn-primary')
1568
                .prop('disabled', true)
1569
                .text('".addslashes(get_lang('Loading'))."')
1570
                .on('click', function () {
1571
                    var \$this = $(this),
1572
                    data = \$this.data();
1573
1574
                    \$this
1575
                        .off('click')
1576
                        .text('".addslashes(get_lang('Cancel'))."')
1577
                        .on('click', function () {
1578
                            \$this.remove();
1579
                            data.abort();
1580
                        });
1581
                    data.submit().always(function () {
1582
                        \$this.remove();
1583
                    });
1584
                });
1585
1586
            $('#".$inputName."').fileupload({
1587
                url: url,
1588
                dataType: 'json',
1589
                autoUpload: true,
1590
                // Enable image resizing, except for Android and Opera,
1591
                // which actually support image resizing, but fail to
1592
                // send Blob objects via XHR requests:
1593
                disableImageResize: /Android(?!.*Chrome)|Opera/.test(window.navigator.userAgent),
1594
                previewMaxWidth: 100,
1595
                previewMaxHeight: 100,
1596
                previewCrop: true,
1597
                dropzone: $('#dropzone')
1598
             }).on('fileuploadadd', function (e, data) {
1599
                data.context = $('<div class=\"row\" style=\"margin-bottom:35px\" />').appendTo('#files');
1600
                $.each(data.files, function (index, file) {
1601
                    var node = $('<div class=\"col-sm-5\">').text(file.name);                    
1602
                    node.appendTo(data.context);
1603
                }
1604
            );
1605
            
1606
            }).on('fileuploadprocessalways', function (e, data) {
1607
                var index = data.index,
1608
                    file = data.files[index],
1609
                    node = $(data.context.children()[index]);
1610
                if (file.preview) {
1611
                    data.context
1612
                        .prepend($('<div class=\"col-sm-2\">').html(file.preview))
1613
                    ;
1614
                } else {
1615
                    data.context
1616
                        .prepend($('<div class=\"col-sm-2\">').html('".$icon."'))
1617
                    ;
1618
                }
1619
                if (index + 1 === data.files.length) {
1620
                    data.context.find('button')
1621
                        .text('Upload')
1622
                        .prop('disabled', !!data.files.error);
1623
                }
1624
            }).on('fileuploadprogressall', function (e, data) {
1625
                var progress = parseInt(data.loaded / data.total * 100, 10);
1626
                $('#progress .progress-bar').css(
1627
                    'width',
1628
                    progress + '%'
1629
                );
1630
            }).on('fileuploaddone', function (e, data) {
1631
                $.each(data.result.files, function (index, file) {
1632
                    if (file.url) {
1633
                        var link = $('<a>')
1634
                            .attr('target', '_blank')
1635
                            .prop('href', file.url);
1636
                        $(data.context.children()[index]).parent().wrap(link);
1637
                        
1638
                        var successMessage = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-success\"/>').text('" . addslashes(get_lang('UplUploadSucceeded')) . "'));
1639
                        $(data.context.children()[index]).parent().append(successMessage);
1640
                    } else if (file.error) {
1641
                        var error = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-danger\"/>').text(file.error));
1642
                        $(data.context.children()[index]).parent().append(error);
1643
                    }
1644
                });
1645
            }).on('fileuploadfail', function (e, data) {
1646
                $.each(data.files, function (index) {
1647
                    var failedMessage = '" . addslashes(get_lang('UplUploadFailed')) . "';
1648
                    var error = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-danger\"/>').text(failedMessage));
1649
                    $(data.context.children()[index]).parent().append(error);
1650
                });
1651
            }).prop('disabled', !$.support.fileInput)
1652
                .parent().addClass($.support.fileInput ? undefined : 'disabled');
1653
1654
            $('.fileinput-button').hide();
1655
1656
        });
1657
        </script>");
1658
    }
1659
}
1660
1661
/**
1662
 * Cleans HTML text filter
1663
 * @param string $html			HTML to clean
1664
 * @param int $mode (optional)
1665
 * @return string				The cleaned HTML
1666
 */
1667
function html_filter($html, $mode = NO_HTML)
1668
{
1669
    $allowed_tags = HTML_QuickForm_Rule_HTML::get_allowed_tags($mode);
1670
    $cleaned_html = kses($html, $allowed_tags);
1671
    return $cleaned_html;
1672
}
1673
1674
function html_filter_teacher($html)
1675
{
1676
    return html_filter($html, TEACHER_HTML);
1677
}
1678
1679
function html_filter_student($html)
1680
{
1681
    return html_filter($html, STUDENT_HTML);
1682
}
1683
1684
function html_filter_teacher_fullpage($html)
1685
{
1686
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1687
}
1688
1689
function html_filter_student_fullpage($html)
1690
{
1691
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1692
}
1693
1694
/**
1695
 * Cleans mobile phone number text
1696
 * @param string $mobilePhoneNumber     Mobile phone number to clean
1697
 * @return string                       The cleaned mobile phone number
1698
 */
1699
function mobile_phone_number_filter($mobilePhoneNumber)
1700
{
1701
    $mobilePhoneNumber = str_replace(array('+', '(', ')'), '', $mobilePhoneNumber);
1702
1703
    return ltrim($mobilePhoneNumber, '0');
1704
}
1705