Passed
Push — master ( ccb5fd...57fe34 )
by Julito
13:03
created

FormValidator::addButtonImport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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

1821
    $cleaned_html = /** @scrutinizer ignore-call */ kses($html, $allowed_tags);
Loading history...
1822
1823
    return $cleaned_html;
1824
}
1825
1826
function html_filter_teacher($html)
1827
{
1828
    return html_filter($html, TEACHER_HTML);
1829
}
1830
1831
function html_filter_student($html)
1832
{
1833
    return html_filter($html, STUDENT_HTML);
1834
}
1835
1836
function html_filter_teacher_fullpage($html)
1837
{
1838
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1839
}
1840
1841
function html_filter_student_fullpage($html)
1842
{
1843
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1844
}
1845
1846
/**
1847
 * Cleans mobile phone number text.
1848
 *
1849
 * @param string $mobilePhoneNumber Mobile phone number to clean
1850
 *
1851
 * @return string The cleaned mobile phone number
1852
 */
1853
function mobile_phone_number_filter($mobilePhoneNumber)
1854
{
1855
    $mobilePhoneNumber = str_replace(['+', '(', ')'], '', $mobilePhoneNumber);
1856
1857
    return ltrim($mobilePhoneNumber, '0');
1858
}
1859