Passed
Push — 1.11.x ( 4520bd...6e8500 )
by Julito
10:51
created

FormValidator::addButton()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 19
c 1
b 0
f 0
nc 2
nop 8
dl 0
loc 32
rs 9.6333

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
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * Class FormValidator
7
 * create/manipulate/validate user input.
8
 */
9
class FormValidator extends HTML_QuickForm
10
{
11
    const LAYOUT_HORIZONTAL = 'horizontal';
12
    const LAYOUT_INLINE = 'inline';
13
    const LAYOUT_BOX = 'box';
14
    const LAYOUT_BOX_NO_LABEL = 'box-no-label';
15
    const LAYOUT_GRID = 'grid';
16
17
    public $with_progress_bar = false;
18
    private $layout;
19
20
    /**
21
     * Constructor.
22
     *
23
     * @param string $name        Name of the form
24
     * @param string $method      (optional) Method ('post' (default) or 'get')
25
     * @param string $action      (optional) Action (default is $PHP_SELF)
26
     * @param string $target      (optional) Form's target defaults to '_self'
27
     * @param mixed  $attributes  (optional) Extra attributes for <form> tag
28
     * @param string $layout
29
     * @param bool   $trackSubmit (optional) Whether to track if the form was
30
     *                            submitted by adding a special hidden field (default = true)
31
     */
32
    public function __construct(
33
        $name,
34
        $method = 'post',
35
        $action = '',
36
        $target = '',
37
        $attributes = [],
38
        $layout = self::LAYOUT_HORIZONTAL,
39
        $trackSubmit = true
40
    ) {
41
        // Default form class.
42
        if (is_array($attributes) && !isset($attributes['class']) || empty($attributes)) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (is_array($attributes) &...) || empty($attributes), Probably Intended Meaning: is_array($attributes) &&... || empty($attributes))
Loading history...
43
            $attributes['class'] = 'form-horizontal';
44
        }
45
46
        if (isset($attributes['class']) && strpos($attributes['class'], 'form-search') !== false) {
47
            $layout = 'inline';
48
        }
49
50
        $this->setLayout($layout);
51
52
        // Form template
53
        $formTemplate = $this->getFormTemplate();
54
55
        switch ($layout) {
56
            case self::LAYOUT_HORIZONTAL:
57
                $attributes['class'] = 'form-horizontal';
58
                break;
59
            case self::LAYOUT_INLINE:
60
                $attributes['class'] = 'form-inline';
61
                break;
62
            case self::LAYOUT_BOX:
63
                $attributes['class'] = 'form-inline-box';
64
                break;
65
            case self::LAYOUT_GRID:
66
                $attributes['class'] = 'form-grid';
67
                $formTemplate = $this->getGridFormTemplate();
68
                break;
69
        }
70
71
        parent::__construct($name, $method, $action, $target, $attributes, $trackSubmit);
72
73
        // Modify the default templates
74
        $renderer = &$this->defaultRenderer();
75
76
        $renderer->setFormTemplate($formTemplate);
77
78
        // Element template
79
        if (isset($attributes['class']) && $attributes['class'] == 'form-inline') {
80
            $elementTemplate = ' {label}  {element} ';
81
            $renderer->setElementTemplate($elementTemplate);
82
        } elseif (isset($attributes['class']) && $attributes['class'] == 'form-search') {
83
            $elementTemplate = ' {label}  {element} ';
84
            $renderer->setElementTemplate($elementTemplate);
85
        } else {
86
            $renderer->setElementTemplate($this->getDefaultElementTemplate());
87
88
            // Display a gray div in the buttons
89
            $templateSimple = '<div class="form-actions">{label} {element}</div>';
90
            $renderer->setElementTemplate($templateSimple, 'submit_in_actions');
91
92
            //Display a gray div in the buttons + makes the button available when scrolling
93
            $templateBottom = '<div class="form-actions bottom_actions bg-form">{label} {element}</div>';
94
            $renderer->setElementTemplate($templateBottom, 'submit_fixed_in_bottom');
95
            $renderer->setElementTemplate($templateSimple, 'buttons_in_action');
96
97
            $templateSimpleRight = '<div class="form-actions"> <div class="pull-right">{label} {element}</div></div>';
98
            $renderer->setElementTemplate($templateSimpleRight, 'buttons_in_action_right');
99
        }
100
101
        //Set Header template
102
        $renderer->setHeaderTemplate('<legend>{header}</legend>');
103
104
        //Set required field template
105
        $this->setRequiredNote(
106
            '<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>'
107
        );
108
109
        $noteTemplate = <<<EOT
110
	<div class="form-group">
111
		<div class="col-sm-offset-2 col-sm-10">{requiredNote}</div>
112
	</div>
113
EOT;
114
        $renderer->setRequiredNoteTemplate($noteTemplate);
115
    }
116
117
    /**
118
     * @return string
119
     */
120
    public function getFormTemplate()
121
    {
122
        return '<form{attributes}>
123
        <fieldset>
124
            {content}
125
        </fieldset>
126
        {hidden}
127
        </form>';
128
    }
129
130
    /**
131
     * @return string
132
     */
133
    public function getGridFormTemplate()
134
    {
135
        return '
136
        <style>
137
138
        </style>
139
        <form{attributes}>
140
            <div class="form_list">
141
                {content}
142
            </div>
143
        {hidden}
144
        </form>';
145
    }
146
147
    /**
148
     * @todo this function should be added in the element class
149
     *
150
     * @return string
151
     */
152
    public function getDefaultElementTemplate()
153
    {
154
        return '
155
            <div class="form-group {error_class}">
156
                <label {label-for} class="col-sm-2 control-label {extra_label_class}" >
157
                    <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
158
                    {label}
159
                </label>
160
                <div class="col-sm-8">
161
                    {icon}
162
                    {element}
163
                    <!-- BEGIN label_2 -->
164
                        <p class="help-block">{label_2}</p>
165
                    <!-- END label_2 -->
166
167
                    <!-- BEGIN error -->
168
                        <span class="help-inline help-block">{error}</span>
169
                    <!-- END error -->
170
                </div>
171
                <div class="col-sm-2">
172
                    <!-- BEGIN label_3 -->
173
                        {label_3}
174
                    <!-- END label_3 -->
175
                </div>
176
            </div>';
177
    }
178
179
    /**
180
     * @return string
181
     */
182
    public function getLayout()
183
    {
184
        return $this->layout;
185
    }
186
187
    /**
188
     * @param string $layout
189
     */
190
    public function setLayout($layout)
191
    {
192
        $this->layout = $layout;
193
    }
194
195
    /**
196
     * Adds a text field to the form.
197
     * A trim-filter is attached to the field.
198
     *
199
     * @param string|array $label      The label for the form-element
200
     * @param string       $name       The element name
201
     * @param bool         $required   (optional)    Is the form-element required (default=true)
202
     * @param array        $attributes (optional)    List of attributes for the form-element
203
     *
204
     * @return HTML_QuickForm_text
205
     */
206
    public function addText($name, $label, $required = true, $attributes = [], $createElement = false)
207
    {
208
        if ($createElement) {
209
            $element = $this->createElement('text', $name, $label, $attributes);
210
        } else {
211
            $element = $this->addElement('text', $name, $label, $attributes);
212
        }
213
214
        $this->applyFilter($name, 'trim');
215
        if ($required) {
216
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
217
        }
218
219
        return $element;
220
    }
221
222
    /**
223
     * Add hidden course params.
224
     */
225
    public function addCourseHiddenParams()
226
    {
227
        $this->addHidden('cidReq', api_get_course_id());
228
        $this->addHidden('id_session', api_get_session_id());
229
    }
230
231
    /**
232
     * The "date_range_picker" element creates 2 hidden fields
233
     * "elementName" + "_start"  and "elementName" + "_end"
234
     * For example if the name is "range", you will have 2 new fields
235
     * when executing $form->getSubmitValues()
236
     * "range_start" and "range_end".
237
     *
238
     * @param string $name
239
     * @param string $label
240
     * @param bool   $required
241
     * @param array  $attributes
242
     */
243
    public function addDateRangePicker($name, $label, $required = true, $attributes = [])
244
    {
245
        $this->addElement('date_range_picker', $name, $label, $attributes);
246
        $this->addElement('hidden', $name.'_start');
247
        $this->addElement('hidden', $name.'_end');
248
249
        if ($required) {
250
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
251
        }
252
    }
253
254
    /**
255
     * @param string $name
256
     * @param string $label
257
     * @param array  $attributes
258
     *
259
     * @return DatePicker
260
     */
261
    public function addDatePicker($name, $label, $attributes = [])
262
    {
263
        return $this->addElement('DatePicker', $name, $label, $attributes);
264
    }
265
266
    /**
267
     * @param string $name
268
     * @param string $label
269
     * @param array  $attributes
270
     *
271
     * @return mixed
272
     */
273
    public function addSelectLanguage($name, $label, $options = [], $attributes = [])
274
    {
275
        return $this->addElement('SelectLanguage', $name, $label, $options, $attributes);
276
    }
277
278
    /**
279
     * @param string $name
280
     * @param string $label
281
     * @param array  $options
282
     * @param array  $attributes
283
     *
284
     * @throws Exception
285
     *
286
     * @return HTML_QuickForm_element
287
     */
288
    public function addSelectAjax($name, $label, $options = [], $attributes = [])
289
    {
290
        if (!isset($attributes['url'])) {
291
            throw new \Exception('select_ajax needs an URL');
292
        }
293
294
        return $this->addElement(
295
            'select_ajax',
296
            $name,
297
            $label,
298
            $options,
299
            $attributes
300
        );
301
    }
302
303
    /**
304
     * @param string       $name
305
     * @param string|array $label
306
     * @param array        $attributes
307
     *
308
     * @return DateTimePicker
309
     */
310
    public function addDateTimePicker($name, $label, $attributes = [])
311
    {
312
        return $this->addElement('DateTimePicker', $name, $label, $attributes);
313
    }
314
315
    /**
316
     * @param string       $name
317
     * @param string|array $label
318
     * @param array        $attributes
319
     *
320
     * @return DateTimeRangePicker
321
     */
322
    public function addDateTimeRangePicker($name, $label, $attributes = [])
323
    {
324
        return $this->addElement('DateTimeRangePicker', $name, $label, $attributes);
325
    }
326
327
    /**
328
     * @param string $name
329
     * @param string $value
330
     * @param array  $attributes
331
     */
332
    public function addHidden($name, $value, $attributes = [])
333
    {
334
        $this->addElement('hidden', $name, $value, $attributes);
335
    }
336
337
    /**
338
     * @param string       $name
339
     * @param string|array $label
340
     * @param array        $attributes
341
     * @param bool         $required
342
     *
343
     * @return HTML_QuickForm_textarea
344
     */
345
    public function addTextarea($name, $label, $attributes = [], $required = false)
346
    {
347
        $element = $this->addElement('textarea', $name, $label, $attributes);
348
349
        if ($required) {
350
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
351
        }
352
353
        return $element;
354
    }
355
356
    /**
357
     * @param string $name
358
     * @param string $label
359
     * @param string $icon          font-awesome
360
     * @param string $style         default|primary|success|info|warning|danger|link
361
     * @param string $size          large|default|small|extra-small
362
     * @param string $class         Example plus is transformed to icon fa fa-plus
363
     * @param array  $attributes
364
     * @param bool   $createElement
365
     *
366
     * @return HTML_QuickForm_button
367
     */
368
    public function addButton(
369
        $name,
370
        $label,
371
        $icon = 'check',
372
        $style = 'default',
373
        $size = 'default',
374
        $class = null,
375
        $attributes = [],
376
        $createElement = false
377
    ) {
378
        if ($createElement) {
379
            return $this->createElement(
380
                'button',
381
                $name,
382
                $label,
383
                $icon,
384
                $style,
385
                $size,
386
                $class,
387
                $attributes
388
            );
389
        }
390
391
        return $this->addElement(
392
            'button',
393
            $name,
394
            $label,
395
            $icon,
396
            $style,
397
            $size,
398
            $class,
399
            $attributes
400
        );
401
    }
402
403
    /**
404
     * Returns a button with the primary color and a check mark.
405
     *
406
     * @param string $label         Text appearing on the button
407
     * @param string $name          Element name (for form treatment purposes)
408
     * @param bool   $createElement Whether to use the create or add method
409
     *
410
     * @return HTML_QuickForm_button
411
     */
412
    public function addButtonSave($label, $name = 'submit', $createElement = false)
413
    {
414
        return $this->addButton(
415
            $name,
416
            $label,
417
            'check',
418
            'primary',
419
            null,
420
            null,
421
            [],
422
            $createElement
423
        );
424
    }
425
426
    /**
427
     * Returns a cancel button.
428
     *
429
     * @param string $label         Text appearing on the button
430
     * @param string $name          Element name (for form treatment purposes)
431
     * @param bool   $createElement Whether to use the create or add method
432
     *
433
     * @return HTML_QuickForm_button
434
     */
435
    public function addButtonCancel($label, $name = 'submit', $createElement = false)
436
    {
437
        return $this->addButton(
438
            $name,
439
            $label,
440
            'times',
441
            'danger',
442
            null,
443
            null,
444
            [],
445
            $createElement
446
        );
447
    }
448
449
    /**
450
     * Returns a button with the primary color and a "plus" icon.
451
     *
452
     * @param string $label         Text appearing on the button
453
     * @param string $name          Element name (for form treatment purposes)
454
     * @param bool   $createElement Whether to use the create or add method
455
     * @param array  $attributes    Additional attributes
456
     *
457
     * @return HTML_QuickForm_button
458
     */
459
    public function addButtonCreate($label, $name = 'submit', $createElement = false, $attributes = [])
460
    {
461
        return $this->addButton(
462
            $name,
463
            $label,
464
            'plus',
465
            'primary',
466
            null,
467
            null,
468
            $attributes,
469
            $createElement
470
        );
471
    }
472
473
    /**
474
     * Returns a button with the primary color and a pencil icon.
475
     *
476
     * @param string $label         Text appearing on the button
477
     * @param string $name          Element name (for form treatment purposes)
478
     * @param bool   $createElement Whether to use the create or add method
479
     *
480
     * @return HTML_QuickForm_button
481
     */
482
    public function addButtonUpdate($label, $name = 'submit', $createElement = false)
483
    {
484
        return $this->addButton(
485
            $name,
486
            $label,
487
            'pencil',
488
            'primary',
489
            null,
490
            null,
491
            [],
492
            $createElement
493
        );
494
    }
495
496
    /**
497
     * Returns a button with the danger color and a trash icon.
498
     *
499
     * @param string $label         Text appearing on the button
500
     * @param string $name          Element name (for form treatment purposes)
501
     * @param bool   $createElement Whether to use the create or add method
502
     *
503
     * @return HTML_QuickForm_button
504
     */
505
    public function addButtonDelete($label, $name = 'submit', $createElement = false)
506
    {
507
        return $this->addButton(
508
            $name,
509
            $label,
510
            'trash',
511
            'danger',
512
            null,
513
            null,
514
            [],
515
            $createElement
516
        );
517
    }
518
519
    /**
520
     * Returns a move style button.
521
     *
522
     * @param string $label         Text appearing on the button
523
     * @param string $name          Element name (for form treatment purposes)
524
     * @param bool   $createElement Whether to use the create or add method
525
     *
526
     * @return HTML_QuickForm_button
527
     */
528
    public function addButtonMove($label, $name = 'submit', $createElement = false)
529
    {
530
        return $this->addButton(
531
            $name,
532
            $label,
533
            'arrow-circle-right',
534
            'primary',
535
            null,
536
            null,
537
            [],
538
            $createElement
539
        );
540
    }
541
542
    /**
543
     * Returns a button with the primary color and a paper-plane icon.
544
     *
545
     * @param string $label         Text appearing on the button
546
     * @param string $name          Element name (for form treatment purposes)
547
     * @param bool   $createElement Whether to use the create or add method
548
     * @param array  $attributes
549
     * @param string $size
550
     * @param string $class
551
     *
552
     * @return HTML_QuickForm_button
553
     */
554
    public function addButtonSend(
555
        $label,
556
        $name = 'submit',
557
        $createElement = false,
558
        $attributes = [],
559
        $size = 'default',
560
        $class = ''
561
    ) {
562
        return $this->addButton(
563
            $name,
564
            $label,
565
            'paper-plane',
566
            'primary',
567
            $size,
568
            $class,
569
            $attributes,
570
            $createElement
571
        );
572
    }
573
574
    /**
575
     * Returns a button with the default (grey?) color and a magnifier icon.
576
     *
577
     * @param string $label Text appearing on the button
578
     * @param string $name  Element name (for form treatment purposes)
579
     *
580
     * @return HTML_QuickForm_button
581
     */
582
    public function addButtonSearch($label = null, $name = 'submit')
583
    {
584
        if (empty($label)) {
585
            $label = get_lang('Search');
586
        }
587
588
        return $this->addButton($name, $label, 'search', 'default');
589
    }
590
591
    /**
592
     * Returns a button with the primary color and a right-pointing arrow icon.
593
     *
594
     * @param string $label      Text appearing on the button
595
     * @param string $name       Element name (for form treatment purposes)
596
     * @param array  $attributes Additional attributes
597
     *
598
     * @return HTML_QuickForm_button
599
     */
600
    public function addButtonNext($label, $name = 'submit', $attributes = [])
601
    {
602
        return $this->addButton(
603
            $name,
604
            $label,
605
            'arrow-right',
606
            'primary',
607
            null,
608
            null,
609
            $attributes
610
        );
611
    }
612
613
    /**
614
     * Returns a button with the primary color and a check mark icon.
615
     *
616
     * @param string $label         Text appearing on the button
617
     * @param string $name          Element name (for form treatment purposes)
618
     * @param bool   $createElement Whether to use the create or add method
619
     *
620
     * @return HTML_QuickForm_button
621
     */
622
    public function addButtonImport($label, $name = 'submit', $createElement = false)
623
    {
624
        return $this->addButton(
625
            $name,
626
            $label,
627
            'check',
628
            'primary',
629
            null,
630
            null,
631
            [],
632
            $createElement
633
        );
634
    }
635
636
    /**
637
     * Returns a button with the primary color and a check-mark icon.
638
     *
639
     * @param string $label         Text appearing on the button
640
     * @param string $name          Element name (for form treatment purposes)
641
     * @param bool   $createElement Whether to use the create or add method
642
     *
643
     * @return HTML_QuickForm_button
644
     */
645
    public function addButtonExport($label, $name = 'submit', $createElement = false)
646
    {
647
        return $this->addButton(
648
            $name,
649
            $label,
650
            'check',
651
            'primary',
652
            null,
653
            null,
654
            [],
655
            $createElement
656
        );
657
    }
658
659
    /**
660
     * Shortcut to filter button.
661
     *
662
     * @param string $label         Text appearing on the button
663
     * @param string $name          Element name (for form treatment purposes)
664
     * @param bool   $createElement Whether to use the create or add method
665
     *
666
     * @return HTML_QuickForm_button
667
     */
668
    public function addButtonFilter($label, $name = 'submit', $createElement = false)
669
    {
670
        return $this->addButton(
671
            $name,
672
            $label,
673
            'filter',
674
            'primary',
675
            null,
676
            null,
677
            [],
678
            $createElement
679
        );
680
    }
681
682
    /**
683
     * Shortcut to reset button.
684
     *
685
     * @param string $label         Text appearing on the button
686
     * @param string $name          Element name (for form treatment purposes)
687
     * @param bool   $createElement Whether to use the create or add method
688
     *
689
     * @return HTML_QuickForm_button
690
     */
691
    public function addButtonReset($label, $name = 'reset', $createElement = false)
692
    {
693
        $icon = 'eraser';
694
        $style = 'default';
695
        $size = 'default';
696
        $class = null;
697
        $attributes = [];
698
699
        if ($createElement) {
700
            return $this->createElement(
701
                'reset',
702
                $name,
703
                $label,
704
                $icon,
705
                $style,
706
                $size,
707
                $class,
708
                $attributes
709
            );
710
        }
711
712
        return $this->addElement(
713
            'reset',
714
            $name,
715
            $label,
716
            $icon,
717
            $style,
718
            $size,
719
            $class,
720
            $attributes
721
        );
722
    }
723
724
    /**
725
     * Returns a button with the primary color and an upload icon.
726
     *
727
     * @param string $label         Text appearing on the button
728
     * @param string $name          Element name (for form treatment purposes)
729
     * @param bool   $createElement Whether to use the create or add method
730
     *
731
     * @return HTML_QuickForm_button
732
     */
733
    public function addButtonUpload($label, $name = 'submit', $createElement = false)
734
    {
735
        return $this->addButton(
736
            $name,
737
            $label,
738
            'upload',
739
            'primary',
740
            null,
741
            null,
742
            [],
743
            $createElement
744
        );
745
    }
746
747
    /**
748
     * Returns a button with the primary color and a download icon.
749
     *
750
     * @param string $label         Text appearing on the button
751
     * @param string $name          Element name (for form treatment purposes)
752
     * @param bool   $createElement Whether to use the create or add method
753
     *
754
     * @return HTML_QuickForm_button
755
     */
756
    public function addButtonDownload($label, $name = 'submit', $createElement = false)
757
    {
758
        return $this->addButton(
759
            $name,
760
            $label,
761
            'download',
762
            'primary',
763
            null,
764
            null,
765
            [],
766
            $createElement
767
        );
768
    }
769
770
    /**
771
     * Returns a button with the primary color and a magnifier icon.
772
     *
773
     * @param string $label         Text appearing on the button
774
     * @param string $name          Element name (for form treatment purposes)
775
     * @param bool   $createElement Whether to use the create or add method
776
     *
777
     * @return HTML_QuickForm_button
778
     */
779
    public function addButtonPreview($label, $name = 'submit', $createElement = false)
780
    {
781
        return $this->addButton(
782
            $name,
783
            $label,
784
            'search',
785
            'primary',
786
            null,
787
            null,
788
            [],
789
            $createElement
790
        );
791
    }
792
793
    /**
794
     * Returns a button with the primary color and a copy (double sheet) icon.
795
     *
796
     * @param string $label         Text appearing on the button
797
     * @param string $name          Element name (for form treatment purposes)
798
     * @param bool   $createElement Whether to use the create or add method
799
     *
800
     * @return HTML_QuickForm_button
801
     */
802
    public function addButtonCopy($label, $name = 'submit', $createElement = false)
803
    {
804
        return $this->addButton(
805
            $name,
806
            $label,
807
            'copy',
808
            'primary',
809
            null,
810
            null,
811
            [],
812
            $createElement
813
        );
814
    }
815
816
    /**
817
     * @param string $name
818
     * @param string $label
819
     * @param string $text
820
     * @param array  $attributes
821
     *
822
     * @return HTML_QuickForm_checkbox
823
     */
824
    public function addCheckBox($name, $label, $text = '', $attributes = [])
825
    {
826
        return $this->addElement('checkbox', $name, $label, $text, $attributes);
827
    }
828
829
    /**
830
     * @param string $name
831
     * @param string $label
832
     * @param array  $options
833
     * @param array  $attributes
834
     *
835
     * @return HTML_QuickForm_group
836
     */
837
    public function addCheckBoxGroup($name, $label, $options = [], $attributes = [])
838
    {
839
        $group = [];
840
        foreach ($options as $value => $text) {
841
            $attributes['value'] = $value;
842
            $group[] = $this->createElement(
843
                'checkbox',
844
                $value,
845
                null,
846
                $text,
847
                $attributes
848
            );
849
        }
850
851
        return $this->addGroup($group, $name, $label);
852
    }
853
854
    /**
855
     * @param string $name
856
     * @param string $label
857
     * @param array  $options
858
     * @param array  $attributes
859
     *
860
     * @return HTML_QuickForm_group
861
     */
862
    public function addRadio($name, $label, $options = [], $attributes = [])
863
    {
864
        $group = [];
865
        $counter = 1;
866
        foreach ($options as $key => $value) {
867
            $attributes['data-order'] = $counter;
868
            $group[] = $this->createElement('radio', null, null, $value, $key, $attributes);
869
            $counter++;
870
        }
871
872
        return $this->addGroup($group, $name, $label);
873
    }
874
875
    /**
876
     * @param string $name
877
     * @param mixed  $label      String, or array if form element with a comment
878
     * @param array  $options
879
     * @param array  $attributes
880
     *
881
     * @return HTML_QuickForm_select
882
     */
883
    public function addSelect($name, $label, $options = [], $attributes = [])
884
    {
885
        return $this->addElement('select', $name, $label, $options, $attributes);
886
    }
887
888
    /**
889
     * @param $name
890
     * @param $label
891
     * @param $collection
892
     * @param array  $attributes
893
     * @param bool   $addNoneOption
894
     * @param string $textCallable  set a function getStringValue() by default __toString()
895
     *
896
     * @return HTML_QuickForm_element
897
     */
898
    public function addSelectFromCollection(
899
        $name,
900
        $label,
901
        $collection,
902
        $attributes = [],
903
        $addNoneOption = false,
904
        $textCallable = ''
905
    ) {
906
        $options = [];
907
908
        if ($addNoneOption) {
909
            $options[0] = get_lang('None');
910
        }
911
912
        if (!empty($collection)) {
913
            foreach ($collection as $item) {
914
                $text = $item;
915
                if (!empty($textCallable)) {
916
                    $text = $item->$textCallable();
917
                }
918
                $options[$item->getId()] = $text;
919
            }
920
        }
921
922
        return $this->addElement('select', $name, $label, $options, $attributes);
923
    }
924
925
    /**
926
     * @param string $label
927
     * @param string $text
928
     * @param bool   $createElement
929
     *
930
     * @return HTML_QuickForm_Element
931
     */
932
    public function addLabel($label, $text, $createElement = false)
933
    {
934
        if ($createElement) {
935
            return $this->createElement(
936
                'label',
937
                $label,
938
                $text
939
            );
940
        }
941
942
        return $this->addElement('label', $label, $text);
943
    }
944
945
    /**
946
     * @param string $text
947
     */
948
    public function addHeader($text)
949
    {
950
        if (!empty($text)) {
951
            $this->addElement('header', $text);
952
        }
953
    }
954
955
    /**
956
     * @param string $name
957
     * @param string $label
958
     * @param array  $attributes
959
     *
960
     * @throws Exception if the file doesn't have an id
961
     *
962
     * @return HTML_QuickForm_file
963
     */
964
    public function addFile($name, $label, $attributes = [])
965
    {
966
        $element = $this->addElement('file', $name, $label, $attributes);
967
        if (isset($attributes['crop_image'])) {
968
            $id = $element->getAttribute('id');
969
            if (empty($id)) {
970
                throw new Exception('If you use the crop functionality the element must have an id');
971
            }
972
            $this->addHtml(
973
                '
974
                <div class="form-group" id="'.$id.'-form-group" style="display: none;">
975
                    <div class="col-sm-offset-2 col-sm-8">
976
                        <div id="'.$id.'_crop_image" class="cropCanvas thumbnail">
977
                            <img id="'.$id.'_preview_image">
978
                        </div>
979
                        <button class="btn btn-primary" type="button" name="cropButton" id="'.$id.'_crop_button">
980
                            <em class="fa fa-crop"></em> '.get_lang('CropYourPicture').'
981
                        </button>
982
                    </div>
983
                </div>'
984
            );
985
            $this->addHidden($id.'_crop_result', '');
986
            $this->addHidden($id.'_crop_image_base_64', '');
987
        }
988
989
        return $element;
990
    }
991
992
    /**
993
     * @param string $snippet
994
     */
995
    public function addHtml($snippet)
996
    {
997
        if (empty($snippet)) {
998
            return false;
999
        }
1000
        $this->addElement('html', $snippet);
1001
1002
        return true;
1003
    }
1004
1005
    /**
1006
     * Draws a panel of options see the course_info/infocours.php page.
1007
     *
1008
     * @param string $name      internal name
1009
     * @param string $title     visible title
1010
     * @param array  $groupList list of group or elements
1011
     */
1012
    public function addPanelOption($name, $title, $groupList)
1013
    {
1014
        $this->addHtml('<div class="panel panel-default">');
1015
        $this->addHtml(
1016
            '
1017
            <div class="panel-heading" role="tab" id="heading-'.$name.'-settings">
1018
                <h4 class="panel-title">
1019
                    <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
1020
                       href="#collapse-'.$name.'-settings" aria-expanded="false" aria-controls="collapse-'.$name.'-settings">
1021
        '
1022
        );
1023
        $this->addHtml($title);
1024
        $this->addHtml('</a></h4></div>');
1025
        $this->addHtml('<div id="collapse-'.$name.'-settings" class="panel-collapse collapse" role="tabpanel"
1026
             aria-labelledby="heading-'.$name.'-settings">
1027
            <div class="panel-body">
1028
        ');
1029
1030
        foreach ($groupList as $groupName => $group) {
1031
            // Add group array
1032
            if (!empty($groupName) && is_array($group)) {
1033
                $this->addGroup($group, '', $groupName);
1034
            }
1035
            // Add element
1036
            if ($group instanceof HTML_QuickForm_element) {
1037
                $this->addElement($group);
1038
            }
1039
        }
1040
1041
        $this->addHtml('</div></div>');
1042
        $this->addHtml('</div>');
1043
    }
1044
1045
    /**
1046
     * Adds a HTML-editor to the form.
1047
     *
1048
     * @param string       $name
1049
     * @param string|array $label    The label for the form-element
1050
     * @param bool         $required (optional) Is the form-element required (default=true)
1051
     * @param bool         $fullPage (optional) When it is true, the editor loads completed html code for a full page
1052
     * @param array        $config   (optional) Configuration settings for the online editor
1053
     */
1054
    public function addHtmlEditor(
1055
        $name,
1056
        $label,
1057
        $required = true,
1058
        $fullPage = false,
1059
        $config = []
1060
    ) {
1061
        $attributes = [];
1062
        $attributes['rows'] = isset($config['rows']) ? $config['rows'] : 15;
1063
        $attributes['cols'] = isset($config['cols']) ? $config['cols'] : 80;
1064
        $attributes['cols-size'] = isset($config['cols-size']) ? $config['cols-size'] : [];
1065
        $attributes['class'] = isset($config['class']) ? $config['class'] : [];
1066
        $attributes['id'] = isset($config['id']) ? $config['id'] : '';
1067
1068
        if (empty($attributes['id'])) {
1069
            $attributes['id'] = $name;
1070
        }
1071
1072
        $this->addElement('html_editor', $name, $label, $attributes, $config);
1073
        $this->applyFilter($name, 'trim');
1074
        if ($required) {
1075
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1076
        }
1077
1078
        /** @var HtmlEditor $element */
1079
        $element = $this->getElement($name);
1080
        $config['style'] = isset($config['style']) ? $config['style'] : false;
1081
        if ($fullPage) {
1082
            $config['fullPage'] = true;
1083
            // Adds editor_content.css in ckEditor
1084
            $config['style'] = true;
1085
        }
1086
1087
        if ($element->editor) {
1088
            $element->editor->processConfig($config);
1089
        }
1090
    }
1091
1092
    /**
1093
     * Adds a Google Maps Geolocalization field to the form.
1094
     *
1095
     * @param      $name
1096
     * @param      $label
1097
     * @param bool $hideGeoLocalizationDetails
1098
     */
1099
    public function addGeoLocationMapField($name, $label, $dataValue, $hideGeoLocalizationDetails = false)
1100
    {
1101
        $gMapsPlugin = GoogleMapsPlugin::create();
1102
        $geolocalization = $gMapsPlugin->get('enable_api') === 'true';
1103
1104
        if ($geolocalization && $gMapsPlugin->javascriptIncluded === false) {
1105
            $gmapsApiKey = $gMapsPlugin->get('api_key');
1106
            $url = '//maps.googleapis.com/maps/api/js?key='.$gmapsApiKey;
1107
            $this->addHtml('<script type="text/javascript" src="'.$url.'" ></script>');
1108
            $gMapsPlugin->javascriptIncluded = true;
1109
        }
1110
1111
        $this->addElement(
1112
            'text',
1113
            $name,
1114
            $label,
1115
            ['id' => $name]
1116
        );
1117
1118
        $this->addHidden(
1119
            $name.'_coordinates',
1120
            '',
1121
            ['id' => $name.'_coordinates']
1122
        );
1123
1124
        $this->applyFilter($name, 'stripslashes');
1125
        $this->applyFilter($name, 'trim');
1126
1127
        $this->addHtml(Extrafield::getLocalizationJavascript($name, $dataValue));
1128
1129
        if ($hideGeoLocalizationDetails) {
1130
            $this->addHtml('<div style="display:none">');
1131
        }
1132
1133
        $this->addHtml(
1134
            Extrafield::getLocalizationInput($name, $label)
1135
        );
1136
1137
        if ($hideGeoLocalizationDetails) {
1138
            $this->addHtml('</div>');
1139
        }
1140
    }
1141
1142
    /**
1143
     * @param string $name
1144
     * @param string $label
1145
     *
1146
     * @return mixed
1147
     */
1148
    public function addButtonAdvancedSettings($name, $label = '')
1149
    {
1150
        $label = !empty($label) ? $label : get_lang('AdvancedParameters');
1151
1152
        return $this->addElement('advanced_settings', $name, $label);
1153
    }
1154
1155
    /**
1156
     * Adds a progress loading image to the form.
1157
     */
1158
    public function addProgress($delay = 2, $label = '')
1159
    {
1160
        if (empty($label)) {
1161
            $label = get_lang('PleaseStandBy');
1162
        }
1163
        $this->with_progress_bar = true;
1164
        $id = $this->getAttribute('id');
1165
1166
        $this->updateAttributes("onsubmit=\"javascript: addProgress('".$id."')\"");
1167
        $this->addHtml('<script language="javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/upload.js" type="text/javascript"></script>');
1168
    }
1169
1170
    /**
1171
     * This function has been created for avoiding changes directly within QuickForm class.
1172
     * When we use it, the element is threated as 'required' to be dealt during validation.
1173
     *
1174
     * @param array  $elements The array of elements
1175
     * @param string $message  The message displayed
1176
     */
1177
    public function add_multiple_required_rule($elements, $message)
1178
    {
1179
        $this->_required[] = $elements[0];
1180
        $this->addRule($elements, $message, 'multiple_required');
1181
    }
1182
1183
    /**
1184
     * Displays the form.
1185
     * If an element in the form didn't validate, an error message is showed
1186
     * asking the user to complete the form.
1187
     */
1188
    public function display()
1189
    {
1190
        echo $this->returnForm();
1191
    }
1192
1193
    /**
1194
     * Returns the HTML code of the form.
1195
     *
1196
     * @return string $return_value HTML code of the form
1197
     */
1198
    public function returnForm()
1199
    {
1200
        $returnValue = '';
1201
1202
        /** @var HTML_QuickForm_element $element */
1203
        foreach ($this->_elements as &$element) {
1204
            $element->setLayout($this->getLayout());
1205
            $elementError = parent::getElementError($element->getName());
1206
            if (!is_null($elementError)) {
1207
                $returnValue .= Display::return_message($elementError, 'warning').'<br />';
1208
                break;
1209
            }
1210
        }
1211
1212
        $returnValue .= parent::toHtml();
1213
        // Add div-element which is to hold the progress bar
1214
        $id = $this->getAttribute('id');
1215
        if (isset($this->with_progress_bar) && $this->with_progress_bar) {
1216
            // @todo improve UI
1217
            $returnValue .= '<br />
1218
            <div id="loading_div_'.$id.'" class="loading_div" style="display:none;margin-left:40%; margin-top:10px; height:50px;">
1219
                <div class="wobblebar-loader"></div>
1220
            </div>
1221
            ';
1222
        }
1223
1224
        return $returnValue;
1225
    }
1226
1227
    /**
1228
     * Returns the HTML code of the form.
1229
     * If an element in the form didn't validate, an error message is showed
1230
     * asking the user to complete the form.
1231
     *
1232
     * @return string $return_value HTML code of the form
1233
     *
1234
     * @author Patrick Cool <[email protected]>, Ghent University, august 2006
1235
     * @author Julio Montoya
1236
     *
1237
     * @deprecated use returnForm()
1238
     */
1239
    public function return_form()
1240
    {
1241
        return $this->returnForm();
1242
    }
1243
1244
    /**
1245
     * @return HTML_QuickForm_Renderer_Default
1246
     */
1247
    public static function getDefaultRenderer()
1248
    {
1249
        return
1250
            isset($GLOBALS['_HTML_QuickForm_default_renderer']) ?
1251
                $GLOBALS['_HTML_QuickForm_default_renderer'] : null;
1252
    }
1253
1254
    /**
1255
     * Adds a input of type url to the form.
1256
     *
1257
     * @param string $name       The label for the form-element
1258
     * @param string $label      The element name
1259
     * @param bool   $required   Optional. Is the form-element required (default=true)
1260
     * @param array  $attributes Optional. List of attributes for the form-element
1261
     */
1262
    public function addUrl($name, $label, $required = true, $attributes = [])
1263
    {
1264
        $this->addElement('url', $name, $label, $attributes);
1265
        $this->applyFilter($name, 'trim');
1266
        $this->addRule($name, get_lang('InsertAValidUrl'), 'url');
1267
1268
        if ($required) {
1269
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1270
        }
1271
    }
1272
1273
    /**
1274
     * Adds a text field for letters to the form.
1275
     * A trim-filter is attached to the field.
1276
     *
1277
     * @param string $name       The element name
1278
     * @param string $label      The label for the form-element
1279
     * @param bool   $required   Optional. Is the form-element required (default=true)
1280
     * @param array  $attributes Optional. List of attributes for the form-element
1281
     */
1282
    public function addTextLettersOnly(
1283
        $name,
1284
        $label,
1285
        $required = false,
1286
        $attributes = []
1287
    ) {
1288
        $attributes = array_merge(
1289
            $attributes,
1290
            [
1291
                'pattern' => '[a-zA-ZñÑ]+',
1292
                'title' => get_lang('OnlyLetters'),
1293
            ]
1294
        );
1295
1296
        $this->addElement(
1297
            'text',
1298
            $name,
1299
            [
1300
                $label,
1301
                get_lang('OnlyLetters'),
1302
            ],
1303
            $attributes
1304
        );
1305
1306
        $this->applyFilter($name, 'trim');
1307
1308
        if ($required) {
1309
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1310
        }
1311
1312
        $this->addRule(
1313
            $name,
1314
            get_lang('OnlyLetters'),
1315
            'regex',
1316
            '/^[a-zA-ZñÑ]+$/'
1317
        );
1318
    }
1319
1320
    /**
1321
     * @param string $name
1322
     * @param string $label
1323
     * @param array  $attributes
1324
     * @param bool   $required
1325
     *
1326
     * @return HTML_QuickForm_element
1327
     */
1328
    public function addNumeric($name, $label, $attributes = [], $required = false)
1329
    {
1330
        $element = $this->addElement('Number', $name, $label, $attributes);
1331
1332
        if ($required) {
1333
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1334
        }
1335
1336
        return $element;
1337
    }
1338
1339
    /**
1340
     * Adds a text field for alphanumeric characters to the form.
1341
     * A trim-filter is attached to the field.
1342
     *
1343
     * @param string $name       The element name
1344
     * @param string $label      The label for the form-element
1345
     * @param bool   $required   Optional. Is the form-element required (default=true)
1346
     * @param array  $attributes Optional. List of attributes for the form-element
1347
     */
1348
    public function addTextAlphanumeric(
1349
        $name,
1350
        $label,
1351
        $required = false,
1352
        $attributes = []
1353
    ) {
1354
        $attributes = array_merge(
1355
            $attributes,
1356
            [
1357
                'pattern' => '[a-zA-Z0-9ñÑ]+',
1358
                'title' => get_lang('OnlyLettersAndNumbers'),
1359
            ]
1360
        );
1361
1362
        $this->addElement(
1363
            'text',
1364
            $name,
1365
            [
1366
                $label,
1367
                get_lang('OnlyLettersAndNumbers'),
1368
            ],
1369
            $attributes
1370
        );
1371
1372
        $this->applyFilter($name, 'trim');
1373
1374
        if ($required) {
1375
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1376
        }
1377
1378
        $this->addRule(
1379
            $name,
1380
            get_lang('OnlyLettersAndNumbers'),
1381
            'regex',
1382
            '/^[a-zA-Z0-9ÑÑ]+$/'
1383
        );
1384
    }
1385
1386
    /**
1387
     * @param string $name
1388
     * @param $label
1389
     * @param bool  $required
1390
     * @param array $attributes
1391
     * @param bool  $allowNegative
1392
     * @param int   $minValue
1393
     * @param null  $maxValue
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $maxValue is correct as it would always require null to be passed?
Loading history...
1394
     */
1395
    public function addFloat(
1396
        $name,
1397
        $label,
1398
        $required = false,
1399
        $attributes = [],
1400
        $allowNegative = false,
1401
        $minValue = null,
1402
        $maxValue = null
1403
    ) {
1404
        $this->addElement(
1405
            'FloatNumber',
1406
            $name,
1407
            $label,
1408
            $attributes
1409
        );
1410
1411
        $this->applyFilter($name, 'trim');
1412
1413
        if ($required) {
1414
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1415
        }
1416
1417
        // Rule allows "," and "."
1418
        /*$this->addRule(
1419
            $name,
1420
            get_lang('OnlyNumbers'),
1421
            'regex',
1422
            '/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)|(^-?\d\d*\,\d*$)|(^-?\,\d\d*$)/'
1423
        );*/
1424
1425
        if ($allowNegative == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1426
            $this->addRule(
1427
                $name,
1428
                get_lang('NegativeValue'),
1429
                'compare',
1430
                '>=',
1431
                'server',
1432
                false,
1433
                false,
1434
                0
1435
            );
1436
        }
1437
1438
        if (!is_null($minValue)) {
1439
            $this->addRule(
1440
                $name,
1441
                get_lang('UnderMin'),
1442
                'compare',
1443
                '>=',
1444
                'server',
1445
                false,
1446
                false,
1447
                $minValue
1448
            );
1449
        }
1450
1451
        if (!is_null($maxValue)) {
1452
            $this->addRule(
1453
                $name,
1454
                get_lang('OverMax'),
1455
                'compare',
1456
                '<=',
1457
                'server',
1458
                false,
1459
                false,
1460
                $maxValue
1461
            );
1462
        }
1463
    }
1464
1465
    /**
1466
     * Adds a text field for letters and spaces to the form.
1467
     * A trim-filter is attached to the field.
1468
     *
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
    public function addTextLettersAndSpaces(
1475
        $name,
1476
        $label,
1477
        $required = false,
1478
        $attributes = []
1479
    ) {
1480
        $attributes = array_merge(
1481
            $attributes,
1482
            [
1483
                'pattern' => '[a-zA-ZñÑ\s]+',
1484
                'title' => get_lang('OnlyLettersAndSpaces'),
1485
            ]
1486
        );
1487
1488
        $this->addElement(
1489
            'text',
1490
            $name,
1491
            [
1492
                $label,
1493
                get_lang('OnlyLettersAndSpaces'),
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('OnlyLettersAndSpaces'),
1507
            'regex',
1508
            '/^[a-zA-ZñÑ\s]+$/'
1509
        );
1510
    }
1511
1512
    /**
1513
     * Adds a text field for alphanumeric and spaces characters to the form.
1514
     * A trim-filter is attached to the field.
1515
     *
1516
     * @param string $name       The element name
1517
     * @param string $label      The label for the form-element
1518
     * @param bool   $required   Optional. Is the form-element required (default=true)
1519
     * @param array  $attributes Optional. List of attributes for the form-element
1520
     */
1521
    public function addTextAlphanumericAndSpaces(
1522
        $name,
1523
        $label,
1524
        $required = false,
1525
        $attributes = []
1526
    ) {
1527
        $attributes = array_merge(
1528
            $attributes,
1529
            [
1530
                'pattern' => '[a-zA-Z0-9ñÑ\s]+',
1531
                'title' => get_lang('OnlyLettersAndNumbersAndSpaces'),
1532
            ]
1533
        );
1534
1535
        $this->addElement(
1536
            'text',
1537
            $name,
1538
            [
1539
                $label,
1540
                get_lang('OnlyLettersAndNumbersAndSpaces'),
1541
            ],
1542
            $attributes
1543
        );
1544
1545
        $this->applyFilter($name, 'trim');
1546
1547
        if ($required) {
1548
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1549
        }
1550
1551
        $this->addRule(
1552
            $name,
1553
            get_lang('OnlyLettersAndNumbersAndSpaces'),
1554
            'regex',
1555
            '/^[a-zA-Z0-9ñÑ\s]+$/'
1556
        );
1557
    }
1558
1559
    /**
1560
     * @param string $url
1561
     * @param string $urlToRedirect after upload redirect to this page
1562
     */
1563
    public function addMultipleUpload($url, $urlToRedirect = '')
1564
    {
1565
        $inputName = 'input_file_upload';
1566
        $this->addMultipleUploadJavascript($url, $inputName, $urlToRedirect);
1567
1568
        $this->addHtml('
1569
            <div class="description-upload">
1570
            '.get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'
1571
            </div>
1572
            <span class="btn btn-success fileinput-button">
1573
                <i class="glyphicon glyphicon-plus"></i>
1574
                <span>'.get_lang('AddFiles').'</span>
1575
                <!-- The file input field used as target for the file upload widget -->
1576
                <input id="'.$inputName.'" type="file" name="files[]" multiple>
1577
            </span>
1578
            <div id="dropzone">
1579
                <div class="button-load">
1580
                '.get_lang('UploadFiles').'
1581
                </div>
1582
            </div>
1583
            <br />
1584
            <!-- The global progress bar -->
1585
            <div id="progress" class="progress">
1586
                <div class="progress-bar progress-bar-success"></div>
1587
            </div>
1588
            <div id="files" class="files"></div>
1589
        ');
1590
    }
1591
1592
    /**
1593
     * @param string $elementName
1594
     * @param string $groupName   if element is inside a group
1595
     *
1596
     * @throws Exception
1597
     */
1598
    public function addPasswordRule($elementName, $groupName = '')
1599
    {
1600
        // Constant defined in old config/profile.conf.php
1601
        if (CHECK_PASS_EASY_TO_FIND === true) {
0 ignored issues
show
Bug introduced by
The constant CHECK_PASS_EASY_TO_FIND was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1602
            $message = get_lang('PassTooEasy').': '.api_generate_password();
1603
1604
            if (!empty($groupName)) {
1605
                $groupObj = $this->getElement($groupName);
1606
1607
                if ($groupObj instanceof HTML_QuickForm_group) {
1608
                    $elementName = $groupObj->getElementName($elementName);
1609
1610
                    if ($elementName === false) {
1611
                        throw new Exception("The $groupName doesn't have the element $elementName");
1612
                    }
1613
1614
                    $this->_rules[$elementName][] = [
1615
                        'type' => 'callback',
1616
                        'format' => 'api_check_password',
1617
                        'message' => $message,
1618
                        'validation' => '',
1619
                        'reset' => false,
1620
                        'group' => $groupName,
1621
                    ];
1622
                }
1623
            } else {
1624
                $this->addRule(
1625
                    $elementName,
1626
                    $message,
1627
                    'callback',
1628
                    'api_check_password'
1629
                );
1630
            }
1631
        }
1632
    }
1633
1634
    /**
1635
     * Add an element with user ID and avatar to the form.
1636
     * It needs a Chamilo\UserBundle\Entity\User as value. The exported value is the Chamilo\UserBundle\Entity\User ID.
1637
     *
1638
     * @see \UserAvatar
1639
     *
1640
     * @param string $name
1641
     * @param string $label
1642
     * @param string $imageSize Optional. Small, medium or large image
1643
     * @param string $subtitle  Optional. The subtitle for the field
1644
     *
1645
     * @return \UserAvatar
1646
     */
1647
    public function addUserAvatar($name, $label, $imageSize = 'small', $subtitle = '')
1648
    {
1649
        return $this->addElement('UserAvatar', $name, $label, ['image_size' => $imageSize, 'sub_title' => $subtitle]);
1650
    }
1651
1652
    public function addCaptcha()
1653
    {
1654
        $ajax = api_get_path(WEB_AJAX_PATH).'form.ajax.php?a=get_captcha';
1655
        $options = [
1656
            'width' => 220,
1657
            'height' => 90,
1658
            'callback' => $ajax.'&var='.basename(__FILE__, '.php'),
1659
            'sessionVar' => basename(__FILE__, '.php'),
1660
            'imageOptions' => [
1661
                'font_size' => 20,
1662
                'font_path' => api_get_path(SYS_FONTS_PATH).'opensans/',
1663
                'font_file' => 'OpenSans-Regular.ttf',
1664
                //'output' => 'gif'
1665
            ],
1666
        ];
1667
1668
        $captcha_question = $this->addElement(
1669
            'CAPTCHA_Image',
1670
            'captcha_question',
1671
            '',
1672
            $options
1673
        );
1674
        $this->addElement('static', null, null, get_lang('ClickOnTheImageForANewOne'));
1675
1676
        $this->addElement(
1677
            'text',
1678
            'captcha',
1679
            get_lang('EnterTheLettersYouSee'),
1680
            ['size' => 40]
1681
        );
1682
        $this->addRule(
1683
            'captcha',
1684
            get_lang('EnterTheCharactersYouReadInTheImage'),
1685
            'required',
1686
            null,
1687
            'client'
1688
        );
1689
        $this->addRule(
1690
            'captcha',
1691
            get_lang('TheTextYouEnteredDoesNotMatchThePicture'),
1692
            'CAPTCHA',
1693
            $captcha_question
1694
        );
1695
    }
1696
1697
    /**
1698
     * @param array $typeList
1699
     */
1700
    public function addEmailTemplate($typeList)
1701
    {
1702
        $mailManager = new MailTemplateManager();
1703
        foreach ($typeList as $type) {
1704
            $list = $mailManager->get_all(
1705
                ['where' => ['type = ? AND url_id = ?' => [$type, api_get_current_access_url_id()]]]
1706
            );
1707
1708
            $options = [get_lang('Select')];
1709
            $name = $type;
1710
            $defaultId = '';
1711
            foreach ($list as $item) {
1712
                $options[$item['id']] = $item['name'];
1713
                $name = $item['name'];
1714
                if (empty($defaultId)) {
1715
                    $defaultId = $item['default_template'] == 1 ? $item['id'] : '';
1716
                }
1717
            }
1718
1719
            $url = api_get_path(WEB_AJAX_PATH).'mail.ajax.php?a=select_option';
1720
            $typeNoDots = 'email_template_option_'.str_replace('.tpl', '', $type);
1721
            $this->addSelect(
1722
                'email_template_option['.$type.']',
1723
                $name,
1724
                $options,
1725
                ['id' => $typeNoDots]
1726
            );
1727
1728
            $templateNoDots = 'email_template_'.str_replace('.tpl', '', $type);
1729
            $templateNoDotsBlock = 'email_template_block_'.str_replace('.tpl', '', $type);
1730
            $this->addHtml('<div id="'.$templateNoDotsBlock.'" style="display:none">');
1731
            $this->addTextarea(
1732
                $templateNoDots,
1733
                get_lang('Preview'),
1734
                ['disabled' => 'disabled ', 'id' => $templateNoDots, 'rows' => '5']
1735
            );
1736
            $this->addHtml('</div>');
1737
1738
            $this->addHtml("<script>
1739
            $(function() {
1740
                var defaultValue = '$defaultId';
1741
                $('#$typeNoDots').val(defaultValue);
1742
                $('#$typeNoDots').selectpicker('render');
1743
                if (defaultValue != '') {
1744
                    var selected = $('#$typeNoDots option:selected').val();
1745
                    $.ajax({
1746
                        url: '$url' + '&id=' + selected+ '&template_name=$type',
1747
                        success: function (data) {
1748
                            $('#$templateNoDots').html(data);
1749
                            $('#$templateNoDotsBlock').show();
1750
                            return;
1751
                        },
1752
                    });
1753
                }
1754
1755
                $('#$typeNoDots').on('change', function(){
1756
                    var selected = $('#$typeNoDots option:selected').val();
1757
                    $.ajax({
1758
                        url: '$url' + '&id=' + selected,
1759
                        success: function (data) {
1760
                            $('#$templateNoDots').html(data);
1761
                            $('#$templateNoDotsBlock').show();
1762
                            return;
1763
                        },
1764
                    });
1765
                });
1766
            });
1767
            </script>");
1768
        }
1769
    }
1770
1771
    /**
1772
     * @param string $url           page that will handle the upload
1773
     * @param string $inputName
1774
     * @param string $urlToRedirect
1775
     */
1776
    private function addMultipleUploadJavascript($url, $inputName, $urlToRedirect = '')
1777
    {
1778
        $redirectCondition = '';
1779
        if (!empty($urlToRedirect)) {
1780
            $redirectCondition = "window.location.replace('$urlToRedirect'); ";
1781
        }
1782
        $icon = Display::return_icon('file_txt.gif');
1783
        $this->addHtml("
1784
        <script>
1785
        $(function () {
1786
            'use strict';
1787
            $('#".$this->getAttribute('id')."').submit(function() {
1788
                return false;
1789
            });
1790
1791
            $('#dropzone').on('click', function() {
1792
                $('#".$inputName."').click();
1793
            });
1794
1795
            var url = '".$url."';
1796
            var uploadButton = $('<button/>')
1797
                .addClass('btn btn-primary')
1798
                .prop('disabled', true)
1799
                .text('".addslashes(get_lang('Loading'))."')
1800
                .on('click', function () {
1801
                    var \$this = $(this),
1802
                    data = \$this.data();
1803
                    \$this
1804
                        .off('click')
1805
                        .text('".addslashes(get_lang('Cancel'))."')
1806
                        .on('click', function () {
1807
                            \$this.remove();
1808
                            data.abort();
1809
                        });
1810
                    data.submit().always(function () {
1811
                        \$this.remove();
1812
                    });
1813
                });
1814
1815
            $('#".$inputName."').fileupload({
1816
                url: url,
1817
                dataType: 'json',
1818
                // Enable image resizing, except for Android and Opera,
1819
                // which actually support image resizing, but fail to
1820
                // send Blob objects via XHR requests:
1821
                disableImageResize: /Android(?!.*Chrome)|Opera/.test(window.navigator.userAgent),
1822
                previewMaxWidth: 300,
1823
                previewMaxHeight: 169,
1824
                previewCrop: true,
1825
                dropzone: $('#dropzone'),
1826
            }).on('fileuploadadd', function (e, data) {
1827
                data.context = $('<div class=\"row\" />').appendTo('#files');
1828
                $.each(data.files, function (index, file) {
1829
                    var node = $('<div class=\"col-sm-5 file_name\">').text(file.name);
1830
                    node.appendTo(data.context);
1831
                });
1832
            }).on('fileuploadprocessalways', function (e, data) {
1833
                var index = data.index,
1834
                    file = data.files[index],
1835
                    node = $(data.context.children()[index]);
1836
                if (file.preview) {
1837
                    data.context.prepend($('<div class=\"col-sm-4\">').html(file.preview));
1838
                } else {
1839
                    data.context.prepend($('<div class=\"col-sm-4\">').html('".$icon."'));
1840
                }
1841
                if (index + 1 === data.files.length) {
1842
                    data.context.find('button')
1843
                        .text('Upload')
1844
                        .prop('disabled', !!data.files.error);
1845
                }
1846
            }).on('fileuploadprogressall', function (e, data) {
1847
                var progress = parseInt(data.loaded / data.total * 100, 10);
1848
                $('#progress .progress-bar').css(
1849
                    'width',
1850
                    progress + '%'
1851
                );
1852
            }).on('fileuploaddone', function (e, data) {
1853
                $.each(data.result.files, function (index, file) {
1854
                    if (file.error) {
1855
                        var link = $('<div>')
1856
                            .attr({class : 'panel-image'})                            ;
1857
                        $(data.context.children()[index]).parent().wrap(link);
1858
                        // Update file name with new one from Chamilo
1859
                        $(data.context.children()[index]).parent().find('.file_name').html(file.name);
1860
                        var message = $('<div class=\"col-sm-3\">').html(
1861
                            $('<span class=\"message-image-danger\"/>').text(file.error)
1862
                        );
1863
                        $(data.context.children()[index]).parent().append(message);
1864
1865
                        return;
1866
                    }
1867
                    if (file.url) {
1868
                        var link = $('<a>')
1869
                            .attr({target: '_blank', class : 'panel-image'})
1870
                            .prop('href', file.url);
1871
                        $(data.context.children()[index]).parent().wrap(link);
1872
                    }
1873
                    // Update file name with new one from Chamilo
1874
                    $(data.context.children()[index]).parent().find('.file_name').html(file.name);
1875
                    var message = $('<div class=\"col-sm-3\">').html(
1876
                        $('<span class=\"message-image-success\"/>').text('".addslashes(get_lang('UplUploadSucceeded'))."')
1877
                    );
1878
                    $(data.context.children()[index]).parent().append(message);
1879
                });
1880
                $('#dropzone').removeClass('hover');
1881
                ".$redirectCondition."
1882
            }).on('fileuploadfail', function (e, data) {
1883
                $.each(data.files, function (index) {
1884
                    var failedMessage = '".addslashes(get_lang('UplUploadFailed'))."';
1885
                    var error = $('<div class=\"col-sm-3\">').html(
1886
                        $('<span class=\"alert alert-danger\"/>').text(failedMessage)
1887
                    );
1888
                    $(data.context.children()[index]).parent().append(error);
1889
                });
1890
                $('#dropzone').removeClass('hover');
1891
            }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled');
1892
1893
            $('#dropzone').on('dragover', function (e) {
1894
                // dragleave callback implementation
1895
                $('#dropzone').addClass('hover');
1896
            });
1897
1898
            $('#dropzone').on('dragleave', function (e) {
1899
                $('#dropzone').removeClass('hover');
1900
            });
1901
            $('.fileinput-button').hide();
1902
        });
1903
        </script>");
1904
    }
1905
}
1906
1907
/**
1908
 * Cleans HTML text filter.
1909
 *
1910
 * @param string $html HTML to clean
1911
 * @param int    $mode (optional)
1912
 *
1913
 * @return string The cleaned HTML
1914
 */
1915
function html_filter($html, $mode = NO_HTML)
1916
{
1917
    $allowed_tags = HTML_QuickForm_Rule_HTML::get_allowed_tags($mode);
1918
    $cleaned_html = kses($html, $allowed_tags);
0 ignored issues
show
Bug introduced by
The function kses was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1918
    $cleaned_html = /** @scrutinizer ignore-call */ kses($html, $allowed_tags);
Loading history...
1919
1920
    return $cleaned_html;
1921
}
1922
1923
function html_filter_teacher($html)
1924
{
1925
    return html_filter($html, TEACHER_HTML);
1926
}
1927
1928
function html_filter_student($html)
1929
{
1930
    return html_filter($html, STUDENT_HTML);
1931
}
1932
1933
function html_filter_teacher_fullpage($html)
1934
{
1935
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1936
}
1937
1938
function html_filter_student_fullpage($html)
1939
{
1940
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1941
}
1942
1943
/**
1944
 * Cleans mobile phone number text.
1945
 *
1946
 * @param string $mobilePhoneNumber Mobile phone number to clean
1947
 *
1948
 * @return string The cleaned mobile phone number
1949
 */
1950
function mobile_phone_number_filter($mobilePhoneNumber)
1951
{
1952
    $mobilePhoneNumber = str_replace(['+', '(', ')'], '', $mobilePhoneNumber);
1953
1954
    return ltrim($mobilePhoneNumber, '0');
1955
}
1956