Completed
Push — master ( 8b2aa0...562606 )
by Julito
09:06
created

FormValidator::addButton()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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

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