Passed
Push — master ( ad6b2a...ec8fd5 )
by Julito
28:29 queued 12s
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
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