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

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