Passed
Pull Request — 1.11.x (#4352)
by Angel Fernando Quiroz
09:11
created

FormValidator::addButton()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 19
nc 2
nop 8
dl 0
loc 32
rs 9.6333
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
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\UserBundle\Entity\User;
6
7
/**
8
 * Class FormValidator
9
 * create/manipulate/validate user input.
10
 */
11
class FormValidator extends HTML_QuickForm
12
{
13
    public const LAYOUT_HORIZONTAL = 'horizontal';
14
    public const LAYOUT_INLINE = 'inline';
15
    public const LAYOUT_BOX = 'box';
16
    public const LAYOUT_BOX_NO_LABEL = 'box-no-label';
17
    public const LAYOUT_GRID = 'grid';
18
19
    public $with_progress_bar = false;
20
    private $layout;
21
22
    /**
23
     * Constructor.
24
     *
25
     * @param string $name        Name of the form
26
     * @param string $method      (optional) Method ('post' (default) or 'get')
27
     * @param string $action      (optional) Action (default is $PHP_SELF)
28
     * @param string $target      (optional) Form's target defaults to '_self'
29
     * @param mixed  $attributes  (optional) Extra attributes for <form> tag
30
     * @param string $layout
31
     * @param bool   $trackSubmit (optional) Whether to track if the form was
32
     *                            submitted by adding a special hidden field (default = true)
33
     */
34
    public function __construct(
35
        $name,
36
        $method = 'post',
37
        $action = '',
38
        $target = '',
39
        $attributes = [],
40
        $layout = self::LAYOUT_HORIZONTAL,
41
        $trackSubmit = true
42
    ) {
43
        // Default form class.
44
        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...
45
            $attributes['class'] = 'form-horizontal';
46
        }
47
48
        if (isset($attributes['class']) && strpos($attributes['class'], 'form-search') !== false) {
49
            $layout = 'inline';
50
        }
51
52
        $this->setLayout($layout);
53
54
        // Form template
55
        $formTemplate = $this->getFormTemplate();
56
57
        switch ($layout) {
58
            case self::LAYOUT_HORIZONTAL:
59
                $attributes['class'] = 'form-horizontal';
60
                break;
61
            case self::LAYOUT_INLINE:
62
                $attributes['class'] = 'form-inline';
63
                break;
64
            case self::LAYOUT_BOX:
65
                $attributes['class'] = 'form-inline-box';
66
                break;
67
            case self::LAYOUT_GRID:
68
                $attributes['class'] = 'form-grid';
69
                $formTemplate = $this->getGridFormTemplate();
70
                break;
71
        }
72
73
        parent::__construct($name, $method, $action, $target, $attributes, $trackSubmit);
74
75
        // Modify the default templates
76
        $renderer = &$this->defaultRenderer();
77
78
        $renderer->setFormTemplate($formTemplate);
79
80
        // Element template
81
        if (isset($attributes['class']) && $attributes['class'] == 'form-inline') {
82
            $elementTemplate = ' {label}  {element} ';
83
            $renderer->setElementTemplate($elementTemplate);
84
        } elseif (isset($attributes['class']) && $attributes['class'] == 'form-search') {
85
            $elementTemplate = ' {label}  {element} ';
86
            $renderer->setElementTemplate($elementTemplate);
87
        } else {
88
            $renderer->setElementTemplate($this->getDefaultElementTemplate());
89
90
            // Display a gray div in the buttons
91
            $templateSimple = '<div class="form-actions">{label} {element}</div>';
92
            $renderer->setElementTemplate($templateSimple, 'submit_in_actions');
93
94
            //Display a gray div in the buttons + makes the button available when scrolling
95
            $templateBottom = '<div class="form-actions bottom_actions bg-form">{label} {element}</div>';
96
            $renderer->setElementTemplate($templateBottom, 'submit_fixed_in_bottom');
97
            $renderer->setElementTemplate($templateSimple, 'buttons_in_action');
98
99
            $templateSimpleRight = '<div class="form-actions"> <div class="pull-right">{label} {element}</div></div>';
100
            $renderer->setElementTemplate($templateSimpleRight, 'buttons_in_action_right');
101
        }
102
103
        //Set Header template
104
        $renderer->setHeaderTemplate('<legend>{header}</legend>');
105
106
        //Set required field template
107
        $this->setRequiredNote(
108
            '<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>'
109
        );
110
111
        $noteTemplate = <<<EOT
112
	<div class="form-group">
113
		<div class="col-sm-offset-2 col-sm-10">{requiredNote}</div>
114
	</div>
115
EOT;
116
        $renderer->setRequiredNoteTemplate($noteTemplate);
117
    }
118
119
    /**
120
     * @return string
121
     */
122
    public function getFormTemplate()
123
    {
124
        return '<form{attributes}>
125
        <fieldset>
126
            {content}
127
        </fieldset>
128
        {hidden}
129
        </form>';
130
    }
131
132
    /**
133
     * @return string
134
     */
135
    public function getGridFormTemplate()
136
    {
137
        return '
138
        <style>
139
140
        </style>
141
        <form{attributes}>
142
            <div class="form_list">
143
                {content}
144
            </div>
145
        {hidden}
146
        </form>';
147
    }
148
149
    /**
150
     * @todo this function should be added in the element class
151
     *
152
     * @return string
153
     */
154
    public function getDefaultElementTemplate()
155
    {
156
        return '
157
            <div class="form-group {error_class}">
158
                <label {label-for} class="col-sm-2 control-label {extra_label_class}" >
159
                    <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
160
                    {label}
161
                </label>
162
                <div class="col-sm-8">
163
                    {icon}
164
                    {element}
165
                    <!-- BEGIN label_2 -->
166
                        <p class="help-block">{label_2}</p>
167
                    <!-- END label_2 -->
168
169
                    <!-- BEGIN error -->
170
                        <span class="help-inline help-block">{error}</span>
171
                    <!-- END error -->
172
                </div>
173
                <div class="col-sm-2">
174
                    <!-- BEGIN label_3 -->
175
                        {label_3}
176
                    <!-- END label_3 -->
177
                </div>
178
            </div>';
179
    }
180
181
    /**
182
     * @return string
183
     */
184
    public function getLayout()
185
    {
186
        return $this->layout;
187
    }
188
189
    /**
190
     * @param string $layout
191
     */
192
    public function setLayout($layout)
193
    {
194
        $this->layout = $layout;
195
    }
196
197
    /**
198
     * Adds a text field to the form.
199
     * A trim-filter is attached to the field.
200
     *
201
     * @param string|array $label      The label for the form-element
202
     * @param string       $name       The element name
203
     * @param bool         $required   (optional)    Is the form-element required (default=true)
204
     * @param array        $attributes (optional)    List of attributes for the form-element
205
     *
206
     * @return HTML_QuickForm_text
207
     */
208
    public function addText($name, $label, $required = true, $attributes = [], $createElement = false)
209
    {
210
        if ($createElement) {
211
            $element = $this->createElement('text', $name, $label, $attributes);
212
        } else {
213
            $element = $this->addElement('text', $name, $label, $attributes);
214
        }
215
216
        $this->applyFilter($name, 'trim');
217
        if ($required) {
218
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
219
        }
220
221
        return $element;
222
    }
223
224
    /**
225
     * Add hidden course params.
226
     */
227
    public function addCourseHiddenParams()
228
    {
229
        $this->addHidden('cidReq', api_get_course_id());
230
        $this->addHidden('id_session', api_get_session_id());
231
    }
232
233
    /**
234
     * The "date_range_picker" element creates 2 hidden fields
235
     * "elementName" + "_start"  and "elementName" + "_end"
236
     * For example if the name is "range", you will have 2 new fields
237
     * when executing $form->getSubmitValues()
238
     * "range_start" and "range_end".
239
     *
240
     * @param string $name
241
     * @param string $label
242
     * @param bool   $required
243
     * @param array  $attributes
244
     */
245
    public function addDateRangePicker($name, $label, $required = true, $attributes = [])
246
    {
247
        $this->addElement('date_range_picker', $name, $label, $attributes);
248
        $this->addElement('hidden', $name.'_start');
249
        $this->addElement('hidden', $name.'_end');
250
251
        if ($required) {
252
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
253
        }
254
    }
255
256
    /**
257
     * @param string $name
258
     * @param string $label
259
     * @param array  $attributes
260
     *
261
     * @return DatePicker
262
     */
263
    public function addDatePicker($name, $label, $attributes = [])
264
    {
265
        return $this->addElement('DatePicker', $name, $label, $attributes);
266
    }
267
268
    /**
269
     * @param string $name
270
     * @param string $label
271
     * @param array  $attributes
272
     *
273
     * @return mixed
274
     */
275
    public function addSelectLanguage($name, $label, $options = [], $attributes = [])
276
    {
277
        return $this->addElement('SelectLanguage', $name, $label, $options, $attributes);
278
    }
279
280
    /**
281
     * @param string $name
282
     * @param string $label
283
     * @param array  $options
284
     * @param array  $attributes
285
     *
286
     * @throws Exception
287
     *
288
     * @return HTML_QuickForm_element
289
     */
290
    public function addSelectAjax($name, $label, $options = [], $attributes = [])
291
    {
292
        if (!isset($attributes['url'])) {
293
            throw new \Exception('select_ajax needs an URL');
294
        }
295
296
        return $this->addElement(
297
            'select_ajax',
298
            $name,
299
            $label,
300
            $options,
301
            $attributes
302
        );
303
    }
304
305
    /**
306
     * @param string       $name
307
     * @param string|array $label
308
     * @param array        $attributes
309
     *
310
     * @return DateTimePicker
311
     */
312
    public function addDateTimePicker($name, $label, $attributes = [])
313
    {
314
        return $this->addElement('DateTimePicker', $name, $label, $attributes);
315
    }
316
317
    /**
318
     * @param string       $name
319
     * @param string|array $label
320
     * @param array        $attributes
321
     *
322
     * @return DateTimeRangePicker
323
     */
324
    public function addDateTimeRangePicker($name, $label, $attributes = [])
325
    {
326
        return $this->addElement('DateTimeRangePicker', $name, $label, $attributes);
327
    }
328
329
    /**
330
     * @param string $name
331
     * @param string $value
332
     * @param array  $attributes
333
     */
334
    public function addHidden($name, $value, $attributes = [])
335
    {
336
        $this->addElement('hidden', $name, $value, $attributes);
337
    }
338
339
    /**
340
     * @param string       $name
341
     * @param string|array $label
342
     * @param array        $attributes
343
     * @param bool         $required
344
     *
345
     * @return HTML_QuickForm_textarea
346
     */
347
    public function addTextarea($name, $label, $attributes = [], $required = false)
348
    {
349
        $element = $this->addElement('textarea', $name, $label, $attributes);
350
351
        if ($required) {
352
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
353
        }
354
355
        return $element;
356
    }
357
358
    /**
359
     * @param string $name
360
     * @param string $label
361
     * @param string $icon          font-awesome
362
     * @param string $style         default|primary|success|info|warning|danger|link
363
     * @param string $size          large|default|small|extra-small
364
     * @param string $class         Example plus is transformed to icon fa fa-plus
365
     * @param array  $attributes
366
     * @param bool   $createElement
367
     *
368
     * @return HTML_QuickForm_button
369
     */
370
    public function addButton(
371
        $name,
372
        $label,
373
        $icon = 'check',
374
        $style = 'default',
375
        $size = 'default',
376
        $class = null,
377
        $attributes = [],
378
        $createElement = false
379
    ) {
380
        if ($createElement) {
381
            return $this->createElement(
382
                'button',
383
                $name,
384
                $label,
385
                $icon,
386
                $style,
387
                $size,
388
                $class,
389
                $attributes
390
            );
391
        }
392
393
        return $this->addElement(
394
            'button',
395
            $name,
396
            $label,
397
            $icon,
398
            $style,
399
            $size,
400
            $class,
401
            $attributes
402
        );
403
    }
404
405
    /**
406
     * Returns a button with the primary color and a check mark.
407
     *
408
     * @param string $label         Text appearing on the button
409
     * @param string $name          Element name (for form treatment purposes)
410
     * @param bool   $createElement Whether to use the create or add method
411
     *
412
     * @return HTML_QuickForm_button
413
     */
414
    public function addButtonSave($label, $name = 'submit', $createElement = false)
415
    {
416
        return $this->addButton(
417
            $name,
418
            $label,
419
            'check',
420
            'primary',
421
            null,
422
            null,
423
            [],
424
            $createElement
425
        );
426
    }
427
428
    /**
429
     * Returns a cancel button.
430
     *
431
     * @param string $label         Text appearing on the button
432
     * @param string $name          Element name (for form treatment purposes)
433
     * @param bool   $createElement Whether to use the create or add method
434
     *
435
     * @return HTML_QuickForm_button
436
     */
437
    public function addButtonCancel($label, $name = 'submit', $createElement = false)
438
    {
439
        return $this->addButton(
440
            $name,
441
            $label,
442
            'times',
443
            'danger',
444
            null,
445
            null,
446
            [],
447
            $createElement
448
        );
449
    }
450
451
    /**
452
     * Returns a button with the primary color and a "plus" icon.
453
     *
454
     * @param string $label         Text appearing on the button
455
     * @param string $name          Element name (for form treatment purposes)
456
     * @param bool   $createElement Whether to use the create or add method
457
     * @param array  $attributes    Additional attributes
458
     *
459
     * @return HTML_QuickForm_button
460
     */
461
    public function addButtonCreate($label, $name = 'submit', $createElement = false, $attributes = [])
462
    {
463
        return $this->addButton(
464
            $name,
465
            $label,
466
            'plus',
467
            'primary',
468
            null,
469
            null,
470
            $attributes,
471
            $createElement
472
        );
473
    }
474
475
    /**
476
     * Returns a button with the primary color and a pencil icon.
477
     *
478
     * @param string $label         Text appearing on the button
479
     * @param string $name          Element name (for form treatment purposes)
480
     * @param bool   $createElement Whether to use the create or add method
481
     *
482
     * @return HTML_QuickForm_button
483
     */
484
    public function addButtonUpdate($label, $name = 'submit', $createElement = false)
485
    {
486
        return $this->addButton(
487
            $name,
488
            $label,
489
            'pencil',
490
            'primary',
491
            null,
492
            null,
493
            [],
494
            $createElement
495
        );
496
    }
497
498
    /**
499
     * Returns a button with the danger color and a trash icon.
500
     *
501
     * @param string $label         Text appearing on the button
502
     * @param string $name          Element name (for form treatment purposes)
503
     * @param bool   $createElement Whether to use the create or add method
504
     *
505
     * @return HTML_QuickForm_button
506
     */
507
    public function addButtonDelete($label, $name = 'submit', $createElement = false)
508
    {
509
        return $this->addButton(
510
            $name,
511
            $label,
512
            'trash',
513
            'danger',
514
            null,
515
            null,
516
            [],
517
            $createElement
518
        );
519
    }
520
521
    /**
522
     * Returns a move style button.
523
     *
524
     * @param string $label         Text appearing on the button
525
     * @param string $name          Element name (for form treatment purposes)
526
     * @param bool   $createElement Whether to use the create or add method
527
     *
528
     * @return HTML_QuickForm_button
529
     */
530
    public function addButtonMove($label, $name = 'submit', $createElement = false)
531
    {
532
        return $this->addButton(
533
            $name,
534
            $label,
535
            'arrow-circle-right',
536
            'primary',
537
            null,
538
            null,
539
            [],
540
            $createElement
541
        );
542
    }
543
544
    /**
545
     * Returns a button with the primary color and a paper-plane icon.
546
     *
547
     * @param string $label         Text appearing on the button
548
     * @param string $name          Element name (for form treatment purposes)
549
     * @param bool   $createElement Whether to use the create or add method
550
     * @param array  $attributes
551
     * @param string $size
552
     * @param string $class
553
     *
554
     * @return HTML_QuickForm_button
555
     */
556
    public function addButtonSend(
557
        $label,
558
        $name = 'submit',
559
        $createElement = false,
560
        $attributes = [],
561
        $size = 'default',
562
        $class = ''
563
    ) {
564
        return $this->addButton(
565
            $name,
566
            $label,
567
            'paper-plane',
568
            'primary',
569
            $size,
570
            $class,
571
            $attributes,
572
            $createElement
573
        );
574
    }
575
576
    /**
577
     * Returns a button with the default (grey?) color and a magnifier icon.
578
     *
579
     * @param string $label Text appearing on the button
580
     * @param string $name  Element name (for form treatment purposes)
581
     *
582
     * @return HTML_QuickForm_button
583
     */
584
    public function addButtonSearch($label = null, $name = 'submit')
585
    {
586
        if (empty($label)) {
587
            $label = get_lang('Search');
588
        }
589
590
        return $this->addButton($name, $label, 'search', 'default');
591
    }
592
593
    /**
594
     * Returns a button with the primary color and a right-pointing arrow icon.
595
     *
596
     * @param string $label      Text appearing on the button
597
     * @param string $name       Element name (for form treatment purposes)
598
     * @param array  $attributes Additional attributes
599
     *
600
     * @return HTML_QuickForm_button
601
     */
602
    public function addButtonNext($label, $name = 'submit', $attributes = [])
603
    {
604
        return $this->addButton(
605
            $name,
606
            $label,
607
            'arrow-right',
608
            'primary',
609
            null,
610
            null,
611
            $attributes
612
        );
613
    }
614
615
    /**
616
     * Returns a button with the primary color and a check mark icon.
617
     *
618
     * @param string $label         Text appearing on the button
619
     * @param string $name          Element name (for form treatment purposes)
620
     * @param bool   $createElement Whether to use the create or add method
621
     *
622
     * @return HTML_QuickForm_button
623
     */
624
    public function addButtonImport($label, $name = 'submit', $createElement = false)
625
    {
626
        return $this->addButton(
627
            $name,
628
            $label,
629
            'check',
630
            'primary',
631
            null,
632
            null,
633
            [],
634
            $createElement
635
        );
636
    }
637
638
    /**
639
     * Returns a button with the primary color and a check-mark icon.
640
     *
641
     * @param string $label         Text appearing on the button
642
     * @param string $name          Element name (for form treatment purposes)
643
     * @param bool   $createElement Whether to use the create or add method
644
     *
645
     * @return HTML_QuickForm_button
646
     */
647
    public function addButtonExport($label, $name = 'submit', $createElement = false)
648
    {
649
        return $this->addButton(
650
            $name,
651
            $label,
652
            'check',
653
            'primary',
654
            null,
655
            null,
656
            [],
657
            $createElement
658
        );
659
    }
660
661
    /**
662
     * Shortcut to filter button.
663
     *
664
     * @param string $label         Text appearing on the button
665
     * @param string $name          Element name (for form treatment purposes)
666
     * @param bool   $createElement Whether to use the create or add method
667
     *
668
     * @return HTML_QuickForm_button
669
     */
670
    public function addButtonFilter($label, $name = 'submit', $createElement = false)
671
    {
672
        return $this->addButton(
673
            $name,
674
            $label,
675
            'filter',
676
            'primary',
677
            null,
678
            null,
679
            [],
680
            $createElement
681
        );
682
    }
683
684
    /**
685
     * Shortcut to reset button.
686
     *
687
     * @param string $label         Text appearing on the button
688
     * @param string $name          Element name (for form treatment purposes)
689
     * @param bool   $createElement Whether to use the create or add method
690
     *
691
     * @return HTML_QuickForm_button
692
     */
693
    public function addButtonReset($label, $name = 'reset', $createElement = false)
694
    {
695
        $icon = 'eraser';
696
        $style = 'default';
697
        $size = 'default';
698
        $class = null;
699
        $attributes = [];
700
701
        if ($createElement) {
702
            return $this->createElement(
703
                'reset',
704
                $name,
705
                $label,
706
                $icon,
707
                $style,
708
                $size,
709
                $class,
710
                $attributes
711
            );
712
        }
713
714
        return $this->addElement(
715
            'reset',
716
            $name,
717
            $label,
718
            $icon,
719
            $style,
720
            $size,
721
            $class,
722
            $attributes
723
        );
724
    }
725
726
    /**
727
     * Returns a button with the primary color and an upload icon.
728
     *
729
     * @param string $label         Text appearing on the button
730
     * @param string $name          Element name (for form treatment purposes)
731
     * @param bool   $createElement Whether to use the create or add method
732
     *
733
     * @return HTML_QuickForm_button
734
     */
735
    public function addButtonUpload($label, $name = 'submit', $createElement = false)
736
    {
737
        return $this->addButton(
738
            $name,
739
            $label,
740
            'upload',
741
            'primary',
742
            null,
743
            null,
744
            [],
745
            $createElement
746
        );
747
    }
748
749
    /**
750
     * Returns a button with the primary color and a download icon.
751
     *
752
     * @param string $label         Text appearing on the button
753
     * @param string $name          Element name (for form treatment purposes)
754
     * @param bool   $createElement Whether to use the create or add method
755
     *
756
     * @return HTML_QuickForm_button
757
     */
758
    public function addButtonDownload($label, $name = 'submit', $createElement = false)
759
    {
760
        return $this->addButton(
761
            $name,
762
            $label,
763
            'download',
764
            'primary',
765
            null,
766
            null,
767
            [],
768
            $createElement
769
        );
770
    }
771
772
    /**
773
     * Returns a button with the primary color and a magnifier icon.
774
     *
775
     * @param string $label         Text appearing on the button
776
     * @param string $name          Element name (for form treatment purposes)
777
     * @param bool   $createElement Whether to use the create or add method
778
     *
779
     * @return HTML_QuickForm_button
780
     */
781
    public function addButtonPreview($label, $name = 'submit', $createElement = false)
782
    {
783
        return $this->addButton(
784
            $name,
785
            $label,
786
            'search',
787
            'primary',
788
            null,
789
            null,
790
            [],
791
            $createElement
792
        );
793
    }
794
795
    /**
796
     * Returns a button with the primary color and a copy (double sheet) icon.
797
     *
798
     * @param string $label         Text appearing on the button
799
     * @param string $name          Element name (for form treatment purposes)
800
     * @param bool   $createElement Whether to use the create or add method
801
     *
802
     * @return HTML_QuickForm_button
803
     */
804
    public function addButtonCopy($label, $name = 'submit', $createElement = false)
805
    {
806
        return $this->addButton(
807
            $name,
808
            $label,
809
            'copy',
810
            'primary',
811
            null,
812
            null,
813
            [],
814
            $createElement
815
        );
816
    }
817
818
    /**
819
     * @param string $name
820
     * @param string $label
821
     * @param string $text
822
     * @param array  $attributes
823
     *
824
     * @return HTML_QuickForm_checkbox
825
     */
826
    public function addCheckBox($name, $label, $text = '', $attributes = [])
827
    {
828
        return $this->addElement('checkbox', $name, $label, $text, $attributes);
829
    }
830
831
    /**
832
     * @param string $name
833
     * @param string $label
834
     * @param array  $options
835
     * @param array  $attributes
836
     *
837
     * @return HTML_QuickForm_group
838
     */
839
    public function addCheckBoxGroup($name, $label, $options = [], $attributes = [])
840
    {
841
        $group = [];
842
        foreach ($options as $value => $text) {
843
            $attributes['value'] = $value;
844
            $group[] = $this->createElement(
845
                'checkbox',
846
                $value,
847
                null,
848
                $text,
849
                $attributes
850
            );
851
        }
852
853
        return $this->addGroup($group, $name, $label);
854
    }
855
856
    /**
857
     * @param string $name
858
     * @param string $label
859
     * @param array  $options
860
     * @param array  $attributes
861
     *
862
     * @return HTML_QuickForm_group
863
     */
864
    public function addRadio($name, $label, $options = [], $attributes = [])
865
    {
866
        $group = [];
867
        $counter = 1;
868
        foreach ($options as $key => $value) {
869
            $attributes['data-order'] = $counter;
870
            $group[] = $this->createElement('radio', null, null, $value, $key, $attributes);
871
            $counter++;
872
        }
873
874
        return $this->addGroup($group, $name, $label);
875
    }
876
877
    /**
878
     * @param string $name
879
     * @param mixed  $label      String, or array if form element with a comment
880
     * @param array  $options
881
     * @param array  $attributes
882
     *
883
     * @return HTML_QuickForm_select
884
     */
885
    public function addSelect($name, $label, $options = [], $attributes = [])
886
    {
887
        return $this->addElement('select', $name, $label, $options, $attributes);
888
    }
889
890
    /**
891
     * @param $name
892
     * @param $label
893
     * @param $collection
894
     * @param array  $attributes
895
     * @param bool   $addNoneOption
896
     * @param string $textCallable  set a function getStringValue() by default __toString()
897
     *
898
     * @return HTML_QuickForm_element
899
     */
900
    public function addSelectFromCollection(
901
        $name,
902
        $label,
903
        $collection,
904
        $attributes = [],
905
        $addNoneOption = false,
906
        $textCallable = ''
907
    ) {
908
        $options = [];
909
910
        if ($addNoneOption) {
911
            $options[0] = get_lang('None');
912
        }
913
914
        if (!empty($collection)) {
915
            foreach ($collection as $item) {
916
                $text = $item;
917
                if (!empty($textCallable)) {
918
                    $text = $item->$textCallable();
919
                }
920
                $options[$item->getId()] = $text;
921
            }
922
        }
923
924
        return $this->addElement('select', $name, $label, $options, $attributes);
925
    }
926
927
    /**
928
     * @param string $label
929
     * @param string $text
930
     * @param bool   $createElement
931
     *
932
     * @return HTML_QuickForm_Element
933
     */
934
    public function addLabel($label, $text, $createElement = false)
935
    {
936
        if ($createElement) {
937
            return $this->createElement(
938
                'label',
939
                $label,
940
                $text
941
            );
942
        }
943
944
        return $this->addElement('label', $label, $text);
945
    }
946
947
    /**
948
     * @param string $text
949
     */
950
    public function addHeader($text)
951
    {
952
        if (!empty($text)) {
953
            $this->addElement('header', $text);
954
        }
955
    }
956
957
    /**
958
     * @param string $name
959
     * @param string $label
960
     * @param array  $attributes
961
     *
962
     * @throws Exception if the file doesn't have an id
963
     *
964
     * @return HTML_QuickForm_file
965
     */
966
    public function addFile($name, $label, $attributes = [])
967
    {
968
        $element = $this->addElement('file', $name, $label, $attributes);
969
        if (isset($attributes['crop_image'])) {
970
            $id = $element->getAttribute('id');
971
            if (empty($id)) {
972
                throw new Exception('If you use the crop functionality the element must have an id');
973
            }
974
            $this->addHtml(
975
                '
976
                <div class="form-group" id="'.$id.'-form-group" style="display: none;">
977
                    <div class="col-sm-offset-2 col-sm-8">
978
                        <div id="'.$id.'_crop_image" class="cropCanvas thumbnail">
979
                            <img id="'.$id.'_preview_image">
980
                        </div>
981
                        <button class="btn btn-primary" type="button" name="cropButton" id="'.$id.'_crop_button">
982
                            <em class="fa fa-crop"></em> '.get_lang('CropYourPicture').'
983
                        </button>
984
                    </div>
985
                </div>'
986
            );
987
            $this->addHidden($id.'_crop_result', '');
988
            $this->addHidden($id.'_crop_image_base_64', '');
989
        }
990
991
        return $element;
992
    }
993
994
    /**
995
     * @param string $snippet
996
     */
997
    public function addHtml($snippet)
998
    {
999
        if (empty($snippet)) {
1000
            return false;
1001
        }
1002
        $this->addElement('html', $snippet);
1003
1004
        return true;
1005
    }
1006
1007
    /**
1008
     * Draws a panel of options see the course_info/infocours.php page.
1009
     *
1010
     * @param string $name      internal name
1011
     * @param string $title     visible title
1012
     * @param array  $groupList list of group or elements
1013
     */
1014
    public function addPanelOption($name, $title, $groupList)
1015
    {
1016
        $this->addHtml('<div class="panel panel-default">');
1017
        $this->addHtml(
1018
            '
1019
            <div class="panel-heading" role="tab" id="heading-'.$name.'-settings">
1020
                <h4 class="panel-title">
1021
                    <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
1022
                       href="#collapse-'.$name.'-settings" aria-expanded="false" aria-controls="collapse-'.$name.'-settings">
1023
        '
1024
        );
1025
        $this->addHtml($title);
1026
        $this->addHtml('</a></h4></div>');
1027
        $this->addHtml('<div id="collapse-'.$name.'-settings" class="panel-collapse collapse" role="tabpanel"
1028
             aria-labelledby="heading-'.$name.'-settings">
1029
            <div class="panel-body">
1030
        ');
1031
1032
        foreach ($groupList as $groupName => $group) {
1033
            // Add group array
1034
            if (!empty($groupName) && is_array($group)) {
1035
                $this->addGroup($group, '', $groupName);
1036
            }
1037
            // Add element
1038
            if ($group instanceof HTML_QuickForm_element) {
1039
                $this->addElement($group);
1040
            }
1041
        }
1042
1043
        $this->addHtml('</div></div>');
1044
        $this->addHtml('</div>');
1045
    }
1046
1047
    /**
1048
     * Adds a HTML-editor to the form.
1049
     *
1050
     * @param string       $name
1051
     * @param string|array $label    The label for the form-element
1052
     * @param bool         $required (optional) Is the form-element required (default=true)
1053
     * @param bool         $fullPage (optional) When it is true, the editor loads completed html code for a full page
1054
     * @param array        $config   (optional) Configuration settings for the online editor
1055
     */
1056
    public function addHtmlEditor(
1057
        $name,
1058
        $label,
1059
        $required = true,
1060
        $fullPage = false,
1061
        $config = []
1062
    ) {
1063
        $attributes = [];
1064
        $attributes['rows'] = isset($config['rows']) ? $config['rows'] : 15;
1065
        $attributes['cols'] = isset($config['cols']) ? $config['cols'] : 80;
1066
        $attributes['cols-size'] = isset($config['cols-size']) ? $config['cols-size'] : [];
1067
        $attributes['class'] = isset($config['class']) ? $config['class'] : [];
1068
        $attributes['id'] = isset($config['id']) ? $config['id'] : '';
1069
1070
        if (empty($attributes['id'])) {
1071
            $attributes['id'] = $name;
1072
        }
1073
1074
        $this->addElement('html_editor', $name, $label, $attributes, $config);
1075
        $this->applyFilter($name, 'trim');
1076
        if ($required) {
1077
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1078
        }
1079
1080
        /** @var HtmlEditor $element */
1081
        $element = $this->getElement($name);
1082
        $config['style'] = isset($config['style']) ? $config['style'] : false;
1083
        if ($fullPage) {
1084
            $config['fullPage'] = true;
1085
            // Adds editor_content.css in ckEditor
1086
            $config['style'] = true;
1087
        }
1088
1089
        if ($element->editor) {
1090
            $element->editor->processConfig($config);
1091
        }
1092
    }
1093
1094
    /**
1095
     * Adds a Google Maps Geolocalization field to the form.
1096
     *
1097
     * @param      $name
1098
     * @param      $label
1099
     * @param bool $hideGeoLocalizationDetails
1100
     */
1101
    public function addGeoLocationMapField($name, $label, $dataValue, $hideGeoLocalizationDetails = false)
1102
    {
1103
        $gMapsPlugin = GoogleMapsPlugin::create();
1104
        $geolocalization = $gMapsPlugin->get('enable_api') === 'true';
1105
1106
        if ($geolocalization && $gMapsPlugin->javascriptIncluded === false) {
1107
            $gmapsApiKey = $gMapsPlugin->get('api_key');
1108
            $url = '//maps.googleapis.com/maps/api/js?key='.$gmapsApiKey;
1109
            $this->addHtml('<script type="text/javascript" src="'.$url.'" ></script>');
1110
            $gMapsPlugin->javascriptIncluded = true;
1111
        }
1112
1113
        $this->addElement(
1114
            'text',
1115
            $name,
1116
            $label,
1117
            ['id' => $name]
1118
        );
1119
1120
        $this->addHidden(
1121
            $name.'_coordinates',
1122
            '',
1123
            ['id' => $name.'_coordinates']
1124
        );
1125
1126
        $this->applyFilter($name, 'stripslashes');
1127
        $this->applyFilter($name, 'trim');
1128
1129
        $this->addHtml(Extrafield::getLocalizationJavascript($name, $dataValue));
1130
1131
        if ($hideGeoLocalizationDetails) {
1132
            $this->addHtml('<div style="display:none">');
1133
        }
1134
1135
        $this->addHtml(
1136
            Extrafield::getLocalizationInput($name, $label)
1137
        );
1138
1139
        if ($hideGeoLocalizationDetails) {
1140
            $this->addHtml('</div>');
1141
        }
1142
    }
1143
1144
    /**
1145
     * @param string $name
1146
     * @param string $label
1147
     *
1148
     * @return mixed
1149
     */
1150
    public function addButtonAdvancedSettings($name, $label = '')
1151
    {
1152
        $label = !empty($label) ? $label : get_lang('AdvancedParameters');
1153
1154
        return $this->addElement('advanced_settings', $name, $label);
1155
    }
1156
1157
    /**
1158
     * Adds a progress loading image to the form.
1159
     */
1160
    public function addProgress($delay = 2, $label = '')
1161
    {
1162
        if (empty($label)) {
1163
            $label = get_lang('PleaseStandBy');
1164
        }
1165
        $this->with_progress_bar = true;
1166
        $id = $this->getAttribute('id');
1167
1168
        $this->updateAttributes("onsubmit=\"javascript: addProgress('".$id."')\"");
1169
        $this->addHtml('<script language="javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/upload.js" type="text/javascript"></script>');
1170
    }
1171
1172
    /**
1173
     * This function has been created for avoiding changes directly within QuickForm class.
1174
     * When we use it, the element is threated as 'required' to be dealt during validation.
1175
     *
1176
     * @param array  $elements The array of elements
1177
     * @param string $message  The message displayed
1178
     */
1179
    public function add_multiple_required_rule($elements, $message)
1180
    {
1181
        $this->_required[] = $elements[0];
1182
        $this->addRule($elements, $message, 'multiple_required');
1183
    }
1184
1185
    /**
1186
     * Displays the form.
1187
     * If an element in the form didn't validate, an error message is showed
1188
     * asking the user to complete the form.
1189
     */
1190
    public function display()
1191
    {
1192
        echo $this->returnForm();
1193
    }
1194
1195
    /**
1196
     * Returns the HTML code of the form.
1197
     *
1198
     * @return string $return_value HTML code of the form
1199
     */
1200
    public function returnForm()
1201
    {
1202
        $returnValue = '';
1203
1204
        /** @var HTML_QuickForm_element $element */
1205
        foreach ($this->_elements as &$element) {
1206
            $element->setLayout($this->getLayout());
1207
            $elementError = parent::getElementError($element->getName());
1208
            if (!is_null($elementError)) {
1209
                $returnValue .= Display::return_message($elementError, 'warning').'<br />';
1210
                break;
1211
            }
1212
        }
1213
1214
        $returnValue .= parent::toHtml();
1215
        // Add div-element which is to hold the progress bar
1216
        $id = $this->getAttribute('id');
1217
        if (isset($this->with_progress_bar) && $this->with_progress_bar) {
1218
            // @todo improve UI
1219
            $returnValue .= '<br />
1220
            <div id="loading_div_'.$id.'" class="loading_div" style="display:none;margin-left:40%; margin-top:10px; height:50px;">
1221
                <div class="wobblebar-loader"></div>
1222
            </div>
1223
            ';
1224
        }
1225
1226
        return $returnValue;
1227
    }
1228
1229
    /**
1230
     * Returns the HTML code of the form.
1231
     * If an element in the form didn't validate, an error message is showed
1232
     * asking the user to complete the form.
1233
     *
1234
     * @return string $return_value HTML code of the form
1235
     *
1236
     * @author Patrick Cool <[email protected]>, Ghent University, august 2006
1237
     * @author Julio Montoya
1238
     *
1239
     * @deprecated use returnForm()
1240
     */
1241
    public function return_form()
1242
    {
1243
        return $this->returnForm();
1244
    }
1245
1246
    /**
1247
     * @return HTML_QuickForm_Renderer_Default
1248
     */
1249
    public static function getDefaultRenderer()
1250
    {
1251
        return
1252
            isset($GLOBALS['_HTML_QuickForm_default_renderer']) ?
1253
                $GLOBALS['_HTML_QuickForm_default_renderer'] : null;
1254
    }
1255
1256
    /**
1257
     * Adds a input of type url to the form.
1258
     *
1259
     * @param string $name       The label for the form-element
1260
     * @param string $label      The element name
1261
     * @param bool   $required   Optional. Is the form-element required (default=true)
1262
     * @param array  $attributes Optional. List of attributes for the form-element
1263
     */
1264
    public function addUrl($name, $label, $required = true, $attributes = [])
1265
    {
1266
        $this->addElement('url', $name, $label, $attributes);
1267
        $this->applyFilter($name, 'trim');
1268
        $this->addRule($name, get_lang('InsertAValidUrl'), 'url');
1269
1270
        if ($required) {
1271
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1272
        }
1273
    }
1274
1275
    /**
1276
     * Adds a text field for letters to the form.
1277
     * A trim-filter is attached to the field.
1278
     *
1279
     * @param string $name       The element name
1280
     * @param string $label      The label for the form-element
1281
     * @param bool   $required   Optional. Is the form-element required (default=true)
1282
     * @param array  $attributes Optional. List of attributes for the form-element
1283
     */
1284
    public function addTextLettersOnly(
1285
        $name,
1286
        $label,
1287
        $required = false,
1288
        $attributes = []
1289
    ) {
1290
        $attributes = array_merge(
1291
            $attributes,
1292
            [
1293
                'pattern' => '[a-zA-ZñÑ]+',
1294
                'title' => get_lang('OnlyLetters'),
1295
            ]
1296
        );
1297
1298
        $this->addElement(
1299
            'text',
1300
            $name,
1301
            [
1302
                $label,
1303
                get_lang('OnlyLetters'),
1304
            ],
1305
            $attributes
1306
        );
1307
1308
        $this->applyFilter($name, 'trim');
1309
1310
        if ($required) {
1311
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1312
        }
1313
1314
        $this->addRule(
1315
            $name,
1316
            get_lang('OnlyLetters'),
1317
            'regex',
1318
            '/^[a-zA-ZñÑ]+$/'
1319
        );
1320
    }
1321
1322
    /**
1323
     * @param string $name
1324
     * @param string $label
1325
     * @param array  $attributes
1326
     * @param bool   $required
1327
     *
1328
     * @return HTML_QuickForm_element
1329
     */
1330
    public function addNumeric($name, $label, $attributes = [], $required = false)
1331
    {
1332
        $element = $this->addElement('Number', $name, $label, $attributes);
1333
1334
        if ($required) {
1335
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1336
        }
1337
1338
        return $element;
1339
    }
1340
1341
    /**
1342
     * Adds a text field for alphanumeric characters to the form.
1343
     * A trim-filter is attached to the field.
1344
     *
1345
     * @param string $name       The element name
1346
     * @param string $label      The label for the form-element
1347
     * @param bool   $required   Optional. Is the form-element required (default=true)
1348
     * @param array  $attributes Optional. List of attributes for the form-element
1349
     */
1350
    public function addTextAlphanumeric(
1351
        $name,
1352
        $label,
1353
        $required = false,
1354
        $attributes = []
1355
    ) {
1356
        $attributes = array_merge(
1357
            $attributes,
1358
            [
1359
                'pattern' => '[a-zA-Z0-9ñÑ]+',
1360
                'title' => get_lang('OnlyLettersAndNumbers'),
1361
            ]
1362
        );
1363
1364
        $this->addElement(
1365
            'text',
1366
            $name,
1367
            [
1368
                $label,
1369
                get_lang('OnlyLettersAndNumbers'),
1370
            ],
1371
            $attributes
1372
        );
1373
1374
        $this->applyFilter($name, 'trim');
1375
1376
        if ($required) {
1377
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1378
        }
1379
1380
        $this->addRule(
1381
            $name,
1382
            get_lang('OnlyLettersAndNumbers'),
1383
            'regex',
1384
            '/^[a-zA-Z0-9ÑÑ]+$/'
1385
        );
1386
    }
1387
1388
    /**
1389
     * @param string $name
1390
     * @param $label
1391
     * @param bool  $required
1392
     * @param array $attributes
1393
     * @param bool  $allowNegative
1394
     * @param int   $minValue
1395
     * @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...
1396
     */
1397
    public function addFloat(
1398
        $name,
1399
        $label,
1400
        $required = false,
1401
        $attributes = [],
1402
        $allowNegative = false,
1403
        $minValue = null,
1404
        $maxValue = null
1405
    ) {
1406
        $this->addElement(
1407
            'FloatNumber',
1408
            $name,
1409
            $label,
1410
            $attributes
1411
        );
1412
1413
        $this->applyFilter($name, 'trim');
1414
1415
        if ($required) {
1416
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1417
        }
1418
1419
        // Rule allows "," and "."
1420
        /*$this->addRule(
1421
            $name,
1422
            get_lang('OnlyNumbers'),
1423
            'regex',
1424
            '/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)|(^-?\d\d*\,\d*$)|(^-?\,\d\d*$)/'
1425
        );*/
1426
1427
        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...
1428
            $this->addRule(
1429
                $name,
1430
                get_lang('NegativeValue'),
1431
                'compare',
1432
                '>=',
1433
                'server',
1434
                false,
1435
                false,
1436
                0
1437
            );
1438
        }
1439
1440
        if (!is_null($minValue)) {
1441
            $this->addRule(
1442
                $name,
1443
                get_lang('UnderMin'),
1444
                'compare',
1445
                '>=',
1446
                'server',
1447
                false,
1448
                false,
1449
                $minValue
1450
            );
1451
        }
1452
1453
        if (!is_null($maxValue)) {
1454
            $this->addRule(
1455
                $name,
1456
                get_lang('OverMax'),
1457
                'compare',
1458
                '<=',
1459
                'server',
1460
                false,
1461
                false,
1462
                $maxValue
1463
            );
1464
        }
1465
    }
1466
1467
    /**
1468
     * Adds a text field for letters and spaces to the form.
1469
     * A trim-filter is attached to the field.
1470
     *
1471
     * @param string $name       The element name
1472
     * @param string $label      The label for the form-element
1473
     * @param bool   $required   Optional. Is the form-element required (default=true)
1474
     * @param array  $attributes Optional. List of attributes for the form-element
1475
     */
1476
    public function addTextLettersAndSpaces(
1477
        $name,
1478
        $label,
1479
        $required = false,
1480
        $attributes = []
1481
    ) {
1482
        $attributes = array_merge(
1483
            $attributes,
1484
            [
1485
                'pattern' => '[a-zA-ZñÑ\s]+',
1486
                'title' => get_lang('OnlyLettersAndSpaces'),
1487
            ]
1488
        );
1489
1490
        $this->addElement(
1491
            'text',
1492
            $name,
1493
            [
1494
                $label,
1495
                get_lang('OnlyLettersAndSpaces'),
1496
            ],
1497
            $attributes
1498
        );
1499
1500
        $this->applyFilter($name, 'trim');
1501
1502
        if ($required) {
1503
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1504
        }
1505
1506
        $this->addRule(
1507
            $name,
1508
            get_lang('OnlyLettersAndSpaces'),
1509
            'regex',
1510
            '/^[a-zA-ZñÑ\s]+$/'
1511
        );
1512
    }
1513
1514
    /**
1515
     * Adds a text field for alphanumeric and spaces characters to the form.
1516
     * A trim-filter is attached to the field.
1517
     *
1518
     * @param string $name       The element name
1519
     * @param string $label      The label for the form-element
1520
     * @param bool   $required   Optional. Is the form-element required (default=true)
1521
     * @param array  $attributes Optional. List of attributes for the form-element
1522
     */
1523
    public function addTextAlphanumericAndSpaces(
1524
        $name,
1525
        $label,
1526
        $required = false,
1527
        $attributes = []
1528
    ) {
1529
        $attributes = array_merge(
1530
            $attributes,
1531
            [
1532
                'pattern' => '[a-zA-Z0-9ñÑ\s]+',
1533
                'title' => get_lang('OnlyLettersAndNumbersAndSpaces'),
1534
            ]
1535
        );
1536
1537
        $this->addElement(
1538
            'text',
1539
            $name,
1540
            [
1541
                $label,
1542
                get_lang('OnlyLettersAndNumbersAndSpaces'),
1543
            ],
1544
            $attributes
1545
        );
1546
1547
        $this->applyFilter($name, 'trim');
1548
1549
        if ($required) {
1550
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1551
        }
1552
1553
        $this->addRule(
1554
            $name,
1555
            get_lang('OnlyLettersAndNumbersAndSpaces'),
1556
            'regex',
1557
            '/^[a-zA-Z0-9ñÑ\s]+$/'
1558
        );
1559
    }
1560
1561
    /**
1562
     * @param string $url
1563
     * @param string $urlToRedirect after upload redirect to this page
1564
     */
1565
    public function addMultipleUpload($url, $urlToRedirect = '')
1566
    {
1567
        $inputName = 'input_file_upload';
1568
        $this->addMultipleUploadJavascript($url, $inputName, $urlToRedirect);
1569
1570
        $this->addHtml('
1571
            <div class="description-upload">
1572
            '.get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'
1573
            </div>
1574
            <span class="btn btn-success fileinput-button">
1575
                <i class="glyphicon glyphicon-plus"></i>
1576
                <span>'.get_lang('AddFiles').'</span>
1577
                <!-- The file input field used as target for the file upload widget -->
1578
                <input id="'.$inputName.'" type="file" name="files[]" multiple>
1579
            </span>
1580
            <div id="dropzone">
1581
                <div class="button-load">
1582
                '.get_lang('UploadFiles').'
1583
                </div>
1584
            </div>
1585
            <br />
1586
            <!-- The global progress bar -->
1587
            <div id="progress" class="progress">
1588
                <div class="progress-bar progress-bar-success"></div>
1589
            </div>
1590
            <div id="files" class="files"></div>
1591
        ');
1592
    }
1593
1594
    /**
1595
     * @throws Exception
1596
     */
1597
    public function addNoSamePasswordRule(string $elementName, User $user)
1598
    {
1599
        $passwordRequirements = api_get_configuration_value('password_requirements');
1600
1601
        if (!empty($passwordRequirements) && $passwordRequirements['force_different_password']) {
1602
            $this->addRule(
1603
                $elementName,
1604
                get_lang('NewPasswordCannotBeSameAsCurrent'),
1605
                'no_same_current_password',
1606
                $user
1607
            );
1608
        }
1609
    }
1610
1611
    /**
1612
     * @param string $elementName
1613
     * @param string $groupName   if element is inside a group
1614
     *
1615
     * @throws Exception
1616
     */
1617
    public function addPasswordRule($elementName, $groupName = '')
1618
    {
1619
        // Constant defined in old config/profile.conf.php
1620
        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...
1621
            $message = get_lang('PassTooEasy').': '.api_generate_password();
1622
1623
            if (!empty($groupName)) {
1624
                $groupObj = $this->getElement($groupName);
1625
1626
                if ($groupObj instanceof HTML_QuickForm_group) {
1627
                    $elementName = $groupObj->getElementName($elementName);
1628
1629
                    if ($elementName === false) {
1630
                        throw new Exception("The $groupName doesn't have the element $elementName");
1631
                    }
1632
1633
                    $this->_rules[$elementName][] = [
1634
                        'type' => 'callback',
1635
                        'format' => 'api_check_password',
1636
                        'message' => $message,
1637
                        'validation' => '',
1638
                        'reset' => false,
1639
                        'group' => $groupName,
1640
                    ];
1641
                }
1642
            } else {
1643
                $this->addRule(
1644
                    $elementName,
1645
                    $message,
1646
                    'callback',
1647
                    'api_check_password'
1648
                );
1649
            }
1650
1651
            if (!$this->isSubmitted()) {
1652
                $element = $this->getElement($elementName);
1653
                $label = $element->getLabel();
1654
                $element->setLabel([
1655
                    $label,
1656
                    Security::getPasswordRequirementsToString(),
1657
                ]);
1658
            }
1659
        }
1660
    }
1661
1662
    /**
1663
     * Add an element with user ID and avatar to the form.
1664
     * It needs a Chamilo\UserBundle\Entity\User as value. The exported value is the Chamilo\UserBundle\Entity\User ID.
1665
     *
1666
     * @see \UserAvatar
1667
     *
1668
     * @param string $name
1669
     * @param string $label
1670
     * @param string $imageSize Optional. Small, medium or large image
1671
     * @param string $subtitle  Optional. The subtitle for the field
1672
     *
1673
     * @return \UserAvatar
1674
     */
1675
    public function addUserAvatar($name, $label, $imageSize = 'small', $subtitle = '')
1676
    {
1677
        return $this->addElement('UserAvatar', $name, $label, ['image_size' => $imageSize, 'sub_title' => $subtitle]);
1678
    }
1679
1680
    public function addCaptcha()
1681
    {
1682
        $ajax = api_get_path(WEB_AJAX_PATH).'form.ajax.php?a=get_captcha';
1683
        $options = [
1684
            'width' => 220,
1685
            'height' => 90,
1686
            'callback' => $ajax.'&var='.basename(__FILE__, '.php'),
1687
            'sessionVar' => basename(__FILE__, '.php'),
1688
            'imageOptions' => [
1689
                'font_size' => 20,
1690
                'font_path' => api_get_path(SYS_FONTS_PATH).'opensans/',
1691
                'font_file' => 'OpenSans-Regular.ttf',
1692
                //'output' => 'gif'
1693
            ],
1694
        ];
1695
1696
        $captcha_question = $this->addElement(
1697
            'CAPTCHA_Image',
1698
            'captcha_question',
1699
            '',
1700
            $options
1701
        );
1702
        $this->addElement('static', null, null, get_lang('ClickOnTheImageForANewOne'));
1703
1704
        $this->addElement(
1705
            'text',
1706
            'captcha',
1707
            get_lang('EnterTheLettersYouSee'),
1708
            ['size' => 40]
1709
        );
1710
        $this->addRule(
1711
            'captcha',
1712
            get_lang('EnterTheCharactersYouReadInTheImage'),
1713
            'required',
1714
            null,
1715
            'client'
1716
        );
1717
        $this->addRule(
1718
            'captcha',
1719
            get_lang('TheTextYouEnteredDoesNotMatchThePicture'),
1720
            'CAPTCHA',
1721
            $captcha_question
1722
        );
1723
    }
1724
1725
    /**
1726
     * @param array $typeList
1727
     */
1728
    public function addEmailTemplate($typeList)
1729
    {
1730
        $mailManager = new MailTemplateManager();
1731
        foreach ($typeList as $type) {
1732
            $list = $mailManager->get_all(
1733
                ['where' => ['type = ? AND url_id = ?' => [$type, api_get_current_access_url_id()]]]
1734
            );
1735
1736
            $options = [get_lang('Select')];
1737
            $name = $type;
1738
            $defaultId = '';
1739
            foreach ($list as $item) {
1740
                $options[$item['id']] = $item['name'];
1741
                $name = $item['name'];
1742
                if (empty($defaultId)) {
1743
                    $defaultId = $item['default_template'] == 1 ? $item['id'] : '';
1744
                }
1745
            }
1746
1747
            $url = api_get_path(WEB_AJAX_PATH).'mail.ajax.php?a=select_option';
1748
            $typeNoDots = 'email_template_option_'.str_replace('.tpl', '', $type);
1749
            $this->addSelect(
1750
                'email_template_option['.$type.']',
1751
                $name,
1752
                $options,
1753
                ['id' => $typeNoDots]
1754
            );
1755
1756
            $templateNoDots = 'email_template_'.str_replace('.tpl', '', $type);
1757
            $templateNoDotsBlock = 'email_template_block_'.str_replace('.tpl', '', $type);
1758
            $this->addHtml('<div id="'.$templateNoDotsBlock.'" style="display:none">');
1759
            $this->addTextarea(
1760
                $templateNoDots,
1761
                get_lang('Preview'),
1762
                ['disabled' => 'disabled ', 'id' => $templateNoDots, 'rows' => '5']
1763
            );
1764
            $this->addHtml('</div>');
1765
1766
            $this->addHtml("<script>
1767
            $(function() {
1768
                var defaultValue = '$defaultId';
1769
                $('#$typeNoDots').val(defaultValue);
1770
                $('#$typeNoDots').selectpicker('render');
1771
                if (defaultValue != '') {
1772
                    var selected = $('#$typeNoDots option:selected').val();
1773
                    $.ajax({
1774
                        url: '$url' + '&id=' + selected+ '&template_name=$type',
1775
                        success: function (data) {
1776
                            $('#$templateNoDots').html(data);
1777
                            $('#$templateNoDotsBlock').show();
1778
                            return;
1779
                        },
1780
                    });
1781
                }
1782
1783
                $('#$typeNoDots').on('change', function(){
1784
                    var selected = $('#$typeNoDots option:selected').val();
1785
                    $.ajax({
1786
                        url: '$url' + '&id=' + selected,
1787
                        success: function (data) {
1788
                            $('#$templateNoDots').html(data);
1789
                            $('#$templateNoDotsBlock').show();
1790
                            return;
1791
                        },
1792
                    });
1793
                });
1794
            });
1795
            </script>");
1796
        }
1797
    }
1798
1799
    /**
1800
     * @param string $url           page that will handle the upload
1801
     * @param string $inputName
1802
     * @param string $urlToRedirect
1803
     */
1804
    private function addMultipleUploadJavascript($url, $inputName, $urlToRedirect = '')
1805
    {
1806
        $redirectCondition = '';
1807
        if (!empty($urlToRedirect)) {
1808
            $redirectCondition = "window.location.replace('$urlToRedirect'); ";
1809
        }
1810
        $icon = Display::return_icon('file_txt.gif');
1811
        $this->addHtml("
1812
        <script>
1813
        $(function () {
1814
            'use strict';
1815
            $('#".$this->getAttribute('id')."').submit(function() {
1816
                return false;
1817
            });
1818
1819
            $('#dropzone').on('click', function() {
1820
                $('#".$inputName."').click();
1821
            });
1822
1823
            var url = '".$url."';
1824
            var uploadButton = $('<button/>')
1825
                .addClass('btn btn-primary')
1826
                .prop('disabled', true)
1827
                .text('".addslashes(get_lang('Loading'))."')
1828
                .on('click', function () {
1829
                    var \$this = $(this),
1830
                    data = \$this.data();
1831
                    \$this
1832
                        .off('click')
1833
                        .text('".addslashes(get_lang('Cancel'))."')
1834
                        .on('click', function () {
1835
                            \$this.remove();
1836
                            data.abort();
1837
                        });
1838
                    data.submit().always(function () {
1839
                        \$this.remove();
1840
                    });
1841
                });
1842
1843
            var counter = 0,
1844
                total = 0;
1845
            $('#".$inputName."').fileupload({
1846
                url: url,
1847
                dataType: 'json',
1848
                // Enable image resizing, except for Android and Opera,
1849
                // which actually support image resizing, but fail to
1850
                // send Blob objects via XHR requests:
1851
                disableImageResize: /Android(?!.*Chrome)|Opera/.test(window.navigator.userAgent),
1852
                previewMaxWidth: 300,
1853
                previewMaxHeight: 169,
1854
                previewCrop: true,
1855
                dropzone: $('#dropzone'),
1856
                maxChunkSize: 10000000, // 10 MB
1857
                sequentialUploads: true,
1858
            }).on('fileuploadchunksend', function (e, data) {
1859
                console.log('fileuploadchunkbeforesend');
1860
                console.log(data);
1861
                data.url = url + '&chunkAction=send';
1862
            }).on('fileuploadchunkdone', function (e, data) {
1863
                console.log('fileuploadchunkdone');
1864
                console.log(data);
1865
                if (data.uploadedBytes >= data.total) {
1866
                    data.url = url + '&chunkAction=done';
1867
                    data.submit();
1868
                }
1869
            }).on('fileuploadchunkfail', function (e, data) {
1870
                console.log('fileuploadchunkfail');
1871
                console.log(data);
1872
1873
            }).on('fileuploadadd', function (e, data) {
1874
                data.context = $('<div class=\"row\" />').appendTo('#files');
1875
                $.each(data.files, function (index, file) {
1876
                    var node = $('<div class=\"col-sm-5 file_name\">').text(file.name);
1877
                    node.appendTo(data.context);
1878
                    var iconLoading = $('<div class=\"col-sm-3\">').html(
1879
                        $('<span id=\"image-loading'+index+'\"/>').html('".Display::return_icon('loading1.gif', get_lang('Uploading'), [], ICON_SIZE_MEDIUM)."')
1880
                    );
1881
                    $(data.context.children()[index]).parent().append(iconLoading);
1882
                    total++;
1883
                });
1884
            }).on('fileuploadprocessalways', function (e, data) {
1885
                var index = data.index,
1886
                    file = data.files[index],
1887
                    node = $(data.context.children()[index]);
1888
                if (file.preview) {
1889
                    data.context.prepend($('<div class=\"col-sm-4\">').html(file.preview));
1890
                } else {
1891
                    data.context.prepend($('<div class=\"col-sm-4\">').html('".$icon."'));
1892
                }
1893
                if (index + 1 === data.files.length) {
1894
                    data.context.find('button')
1895
                        .text('Upload')
1896
                        .prop('disabled', !!data.files.error);
1897
                }
1898
            }).on('fileuploadprogressall', function (e, data) {
1899
                var progress = parseInt(data.loaded / data.total * 100, 10) - 2;
1900
                $('#progress .progress-bar').css(
1901
                    'width',
1902
                    progress + '%'
1903
                );
1904
                $('#progress .progress-bar').text(progress + '%');
1905
            }).on('fileuploaddone', function (e, data) {
1906
                $.each(data.result.files, function (index, file) {
1907
                    if (file.error) {
1908
                        var link = $('<div>')
1909
                            .attr({class : 'panel-image'})                            ;
1910
                        $(data.context.children()[index]).parent().wrap(link);
1911
                        // Update file name with new one from Chamilo
1912
                        $(data.context.children()[index]).parent().find('.file_name').html(file.name);
1913
                        var message = $('<div class=\"col-sm-3\">').html(
1914
                            $('<span class=\"message-image-danger\"/>').text(file.error)
1915
                        );
1916
                        $(data.context.children()[index]).parent().append(message);
1917
1918
                        return;
1919
                    }
1920
                    if (file.url) {
1921
                        var link = $('<a>')
1922
                            .attr({target: '_blank', class : 'panel-image'})
1923
                            .prop('href', file.url);
1924
                        $(data.context.children()[index]).parent().wrap(link);
1925
                    }
1926
                    // Update file name with new one from Chamilo
1927
                    $(data.context.children()[index]).parent().find('.file_name').html(file.name);
1928
                    $('#image-loading'+index).remove();
1929
                    var message = $('<div class=\"col-sm-3\">').html(
1930
                        $('<span class=\"message-image-success\"/>').text('".addslashes(get_lang('UplUploadSucceeded'))."')
1931
                    );
1932
                    $(data.context.children()[index]).parent().append(message);
1933
                    counter++;
1934
                });
1935
                if (counter == total) {
1936
                    $('#progress .progress-bar').css('width', '100%');
1937
                    $('#progress .progress-bar').text('100%');
1938
                }
1939
                $('#dropzone').removeClass('hover');
1940
                ".$redirectCondition."
1941
            }).on('fileuploadfail', function (e, data) {
1942
                $.each(data.files, function (index) {
1943
                    var failedMessage = '".addslashes(get_lang('UplUploadFailed'))."';
1944
                    var error = $('<div class=\"col-sm-3\">').html(
1945
                        $('<span class=\"alert alert-danger\"/>').text(failedMessage)
1946
                    );
1947
                    $(data.context.children()[index]).parent().append(error);
1948
                });
1949
                $('#dropzone').removeClass('hover');
1950
            }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled');
1951
1952
            $('#dropzone').on('dragover', function (e) {
1953
                // dragleave callback implementation
1954
                $('#dropzone').addClass('hover');
1955
            });
1956
1957
            $('#dropzone').on('dragleave', function (e) {
1958
                $('#dropzone').removeClass('hover');
1959
            });
1960
            $('.fileinput-button').hide();
1961
        });
1962
        </script>");
1963
    }
1964
}
1965
1966
/**
1967
 * Cleans HTML text filter.
1968
 *
1969
 * @param string $html HTML to clean
1970
 * @param int    $mode (optional)
1971
 *
1972
 * @return string The cleaned HTML
1973
 */
1974
function html_filter($html, $mode = NO_HTML)
1975
{
1976
    $allowed_tags = HTML_QuickForm_Rule_HTML::get_allowed_tags($mode);
1977
    $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

1977
    $cleaned_html = /** @scrutinizer ignore-call */ kses($html, $allowed_tags);
Loading history...
1978
1979
    return $cleaned_html;
1980
}
1981
1982
function html_filter_teacher($html)
1983
{
1984
    return html_filter($html, TEACHER_HTML);
1985
}
1986
1987
function html_filter_student($html)
1988
{
1989
    return html_filter($html, STUDENT_HTML);
1990
}
1991
1992
function html_filter_teacher_fullpage($html)
1993
{
1994
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1995
}
1996
1997
function html_filter_student_fullpage($html)
1998
{
1999
    return html_filter($html, STUDENT_HTML_FULLPAGE);
2000
}
2001
2002
/**
2003
 * Cleans mobile phone number text.
2004
 *
2005
 * @param string $mobilePhoneNumber Mobile phone number to clean
2006
 *
2007
 * @return string The cleaned mobile phone number
2008
 */
2009
function mobile_phone_number_filter($mobilePhoneNumber)
2010
{
2011
    $mobilePhoneNumber = str_replace(['+', '(', ')'], '', $mobilePhoneNumber);
2012
2013
    return ltrim($mobilePhoneNumber, '0');
2014
}
2015