Passed
Push — 1.11.x ( 457e1c...c45650 )
by Julito
09:33
created

FormValidator::addDateRangePicker()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

1879
    $cleaned_html = /** @scrutinizer ignore-call */ kses($html, $allowed_tags);
Loading history...
1880
1881
    return $cleaned_html;
1882
}
1883
1884
function html_filter_teacher($html)
1885
{
1886
    return html_filter($html, TEACHER_HTML);
1887
}
1888
1889
function html_filter_student($html)
1890
{
1891
    return html_filter($html, STUDENT_HTML);
1892
}
1893
1894
function html_filter_teacher_fullpage($html)
1895
{
1896
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1897
}
1898
1899
function html_filter_student_fullpage($html)
1900
{
1901
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1902
}
1903
1904
/**
1905
 * Cleans mobile phone number text.
1906
 *
1907
 * @param string $mobilePhoneNumber Mobile phone number to clean
1908
 *
1909
 * @return string The cleaned mobile phone number
1910
 */
1911
function mobile_phone_number_filter($mobilePhoneNumber)
1912
{
1913
    $mobilePhoneNumber = str_replace(['+', '(', ')'], '', $mobilePhoneNumber);
1914
1915
    return ltrim($mobilePhoneNumber, '0');
1916
}
1917