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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

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