Passed
Push — master ( ad6b2a...ec8fd5 )
by Julito
28:29 queued 12s
created

FormValidator::addEmailTemplate()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 62
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 40
nc 5
nop 1
dl 0
loc 62
rs 8.9688
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

1901
    $cleaned_html = /** @scrutinizer ignore-call */ kses($html, $allowed_tags);
Loading history...
1902
1903
    return $cleaned_html;
1904
}
1905
1906
function html_filter_teacher($html)
1907
{
1908
    return html_filter($html, TEACHER_HTML);
1909
}
1910
1911
function html_filter_student($html)
1912
{
1913
    return html_filter($html, STUDENT_HTML);
1914
}
1915
1916
function html_filter_teacher_fullpage($html)
1917
{
1918
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1919
}
1920
1921
function html_filter_student_fullpage($html)
1922
{
1923
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1924
}
1925
1926
/**
1927
 * Cleans mobile phone number text.
1928
 *
1929
 * @param string $mobilePhoneNumber Mobile phone number to clean
1930
 *
1931
 * @return string The cleaned mobile phone number
1932
 */
1933
function mobile_phone_number_filter($mobilePhoneNumber)
1934
{
1935
    $mobilePhoneNumber = str_replace(['+', '(', ')'], '', $mobilePhoneNumber);
1936
1937
    return ltrim($mobilePhoneNumber, '0');
1938
}
1939