Test Setup Failed
Push — master ( ec638a...cb9435 )
by Julito
51:10
created

FormValidator::addHtmlEditor()   F

Complexity

Conditions 9
Paths 256

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 23
nc 256
nop 6
dl 0
loc 34
rs 3
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class FormValidator
6
 * create/manipulate/validate user input.
7
 */
8
class FormValidator extends HTML_QuickForm
9
{
10
    const LAYOUT_HORIZONTAL = 'horizontal';
11
    const LAYOUT_INLINE = 'inline';
12
    const LAYOUT_BOX = 'box';
13
    const LAYOUT_BOX_NO_LABEL = 'box-no-label';
14
15
    public $with_progress_bar = false;
16
    private $layout;
17
18
    /**
19
     * Constructor
20
     * @param string $name Name of the form
21
     * @param string $method (optional) Method ('post' (default) or 'get')
22
     * @param string $action (optional) Action (default is $PHP_SELF)
23
     * @param string $target (optional) Form's target defaults to '_self'
24
     * @param mixed $attributes (optional) Extra attributes for <form> tag
25
     * @param string $layout
26
     * @param bool $trackSubmit (optional) Whether to track if the form was
27
     * submitted by adding a special hidden field (default = true)
28
     */
29
    public function __construct(
30
        $name,
31
        $method = 'post',
32
        $action = '',
33
        $target = '',
34
        $attributes = array(),
35
        $layout = self::LAYOUT_HORIZONTAL,
36
        $trackSubmit = true
37
    ) {
38
        // Default form class.
39
        if (is_array($attributes) && !isset($attributes['class']) || empty($attributes)) {
40
            $attributes['class'] = 'form-horizontal';
41
        }
42
43
        if (isset($attributes['class']) && strpos($attributes['class'], 'form-search') !== false) {
44
            $layout = 'inline';
45
        }
46
47
        $this->setLayout($layout);
48
49
        switch ($layout) {
50
            case self::LAYOUT_HORIZONTAL:
51
                $attributes['class'] = 'form-horizontal';
52
                break;
53
            case self::LAYOUT_INLINE:
54
            case self::LAYOUT_BOX:
55
                $attributes['class'] = 'form-inline';
56
                break;
57
        }
58
59
        parent::__construct($name, $method, $action, $target, $attributes, $trackSubmit);
60
61
        // Modify the default templates
62
        $renderer = & $this->defaultRenderer();
63
64
        // Form template
65
        $formTemplate = $this->getFormTemplate();
66
        $renderer->setFormTemplate($formTemplate);
67
68
        // Element template
69
        if (isset($attributes['class']) && $attributes['class'] == 'form-inline') {
70
            $elementTemplate = ' {label}  {element} ';
71
            $renderer->setElementTemplate($elementTemplate);
72
        } elseif (isset($attributes['class']) && $attributes['class'] == 'form-search') {
73
            $elementTemplate = ' {label}  {element} ';
74
            $renderer->setElementTemplate($elementTemplate);
75
        } else {
76
            $renderer->setElementTemplate($this->getDefaultElementTemplate());
77
78
            // Display a gray div in the buttons
79
            $templateSimple = '<div class="form-actions">{label} {element}</div>';
80
            $renderer->setElementTemplate($templateSimple, 'submit_in_actions');
81
82
            //Display a gray div in the buttons + makes the button available when scrolling
83
            $templateBottom = '<div class="form-actions bottom_actions bg-form">{label} {element}</div>';
84
            $renderer->setElementTemplate($templateBottom, 'submit_fixed_in_bottom');
85
86
            //When you want to group buttons use something like this
87
            /* $group = array();
88
              $group[] = $form->createElement('button', 'mark_all', get_lang('MarkAll'));
89
              $group[] = $form->createElement('button', 'unmark_all', get_lang('UnmarkAll'));
90
              $form->addGroup($group, 'buttons_in_action');
91
             */
92
            $renderer->setElementTemplate($templateSimple, 'buttons_in_action');
93
94
            $templateSimpleRight = '<div class="form-actions"> <div class="pull-right">{label} {element}</div></div>';
95
            $renderer->setElementTemplate($templateSimpleRight, 'buttons_in_action_right');
96
        }
97
98
        //Set Header template
99
        $renderer->setHeaderTemplate('<legend>{header}</legend>');
100
101
        //Set required field template
102
        $this->setRequiredNote('<span class="form_required">*</span> <small>' . get_lang('ThisFieldIsRequired') . '</small>');
103
        $noteTemplate = <<<EOT
104
	<div class="form-group">
105
		<div class="col-sm-offset-2 col-sm-10">{requiredNote}</div>
106
	</div>
107
EOT;
108
        $renderer->setRequiredNoteTemplate($noteTemplate);
109
    }
110
111
    /**
112
     * @return string
113
     */
114
    public function getFormTemplate()
115
    {
116
        return '<form{attributes}>
117
        <fieldset>
118
            {content}
119
        </fieldset>
120
        {hidden}
121
        </form>';
122
    }
123
124
    /**
125
     * @todo this function should be added in the element class
126
     * @return string
127
     */
128
    public function getDefaultElementTemplate()
129
    {
130
        return '
131
            <div class="form-group {error_class}">
132
                <label {label-for} class="col-sm-2 control-label {extra_label_class}" >
133
                    <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
134
                    {label}
135
                </label>
136
                <div class="col-sm-8">
137
                    {icon}
138
                    {element}
139
140
                    <!-- BEGIN label_2 -->
141
                        <p class="help-block">{label_2}</p>
142
                    <!-- END label_2 -->
143
144
                    <!-- BEGIN error -->
145
                        <span class="help-inline">{error}</span>
146
                    <!-- END error -->
147
                </div>
148
                <div class="col-sm-2">
149
                    <!-- BEGIN label_3 -->
150
                        {label_3}
151
                    <!-- END label_3 -->
152
                </div>
153
            </div>';
154
    }
155
156
    /**
157
     * @return string
158
     */
159
    public function getLayout()
160
    {
161
        return $this->layout;
162
    }
163
164
    /**
165
     * @param string $layout
166
     */
167
    public function setLayout($layout)
168
    {
169
        $this->layout = $layout;
170
    }
171
172
    /**
173
     * Adds a text field to the form.
174
     * A trim-filter is attached to the field.
175
     * @param string $label					The label for the form-element
176
     * @param string $name					The element name
177
     * @param bool   $required	(optional)	Is the form-element required (default=true)
178
     * @param array  $attributes (optional)	List of attributes for the form-element
179
     * @return HTML_QuickForm_text
180
     */
181
    public function addText($name, $label, $required = true, $attributes = array())
182
    {
183
        $element = $this->addElement('text', $name, $label, $attributes);
184
        $this->applyFilter($name, 'trim');
185
        if ($required) {
186
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
187
        }
188
189
        return $element;
190
    }
191
192
    /**
193
     * The "date_range_picker" element creates 2 hidden fields
194
     * "elementName" + "_start"  and "elementName" + "_end"
195
     * For example if the name is "range", you will have 2 new fields
196
     * when executing $form->getSubmitValues()
197
     * "range_start" and "range_end"
198
     *
199
     * @param string $name
200
     * @param string $label
201
     * @param bool   $required
202
     * @param array  $attributes
203
     */
204 View Code Duplication
    public function addDateRangePicker($name, $label, $required = true, $attributes = array())
205
    {
206
        $this->addElement('date_range_picker', $name, $label, $attributes);
207
        $this->addElement('hidden', $name.'_start');
208
        $this->addElement('hidden', $name.'_end');
209
210
        if ($required) {
211
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
212
        }
213
    }
214
215
    /**
216
     * @param string $name
217
     * @param string $label
218
     * @param array $attributes
219
     *
220
     * @return mixed
221
     */
222
    public function addDatePicker($name, $label, $attributes = [])
223
    {
224
        return $this->addElement('DatePicker', $name, $label, $attributes);
225
    }
226
227
    /**
228
     * @param string $name
229
     * @param string $label
230
     * @param array $attributes
231
     *
232
     * @return mixed
233
     */
234
    public function addSelectLanguage($name, $label, $options = [], $attributes = [])
235
    {
236
        return $this->addElement('SelectLanguage', $name, $label, $options, $attributes);
237
    }
238
239
    /**
240
     * @param string $name
241
     * @param string $label
242
     * @param array $options
243
     * @param array $attributes
244
     * @throws
245
     */
246
    public function addSelectAjax($name, $label, $options = [], $attributes = [])
247
    {
248
        if (!isset($attributes['url'])) {
249
            throw new \Exception('select_ajax needs an URL');
250
        }
251
        $this->addElement(
252
            'select_ajax',
253
            $name,
254
            $label,
255
            $options,
256
            $attributes
257
        );
258
    }
259
260
    /**
261
     * @param string $name
262
     * @param string $label
263
     * @param array $attributes
264
     *
265
     * @return mixed
266
     */
267
    public function addDateTimePicker($name, $label, $attributes = [])
268
    {
269
        return $this->addElement('DateTimePicker', $name, $label, $attributes);
270
    }
271
272
    /**
273
     * @param string $name
274
     * @param string $value
275
     */
276
    public function addHidden($name, $value)
277
    {
278
        $this->addElement('hidden', $name, $value);
279
    }
280
281
    /**
282
     * @param string $name
283
     * @param string $label
284
     * @param array  $attributes
285
     *
286
     * @return HTML_QuickForm_textarea
287
     */
288
    public function addTextarea($name, $label, $attributes = array())
289
    {
290
        return $this->addElement('textarea', $name, $label, $attributes);
291
    }
292
293
    /**
294
     * @param string $name
295
     * @param string $label
296
     * @param string $icon font-awesome
297
     * @param string $style default|primary|success|info|warning|danger|link
298
     * @param string $size large|default|small|extra-small
299
     * @param string $class Example plus is transformed to icon fa fa-plus
300
     * @param array  $attributes
301
     *
302
     * @return HTML_QuickForm_button
303
     */
304
    public function addButton(
305
        $name,
306
        $label,
307
        $icon = 'check',
308
        $style = 'default',
309
        $size = 'default',
310
        $class = null,
311
        $attributes = array(),
312
        $createElement = false
313
    ) {
314
        if ($createElement) {
315
            return $this->createElement(
316
                'button',
317
                $name,
318
                $label,
319
                $icon,
320
                $style,
321
                $size,
322
                $class,
323
                $attributes
324
            );
325
        }
326
327
        return $this->addElement(
328
            'button',
329
            $name,
330
            $label,
331
            $icon,
332
            $style,
333
            $size,
334
            $class,
335
            $attributes
336
        );
337
    }
338
339
    /**
340
     * Returns a button with the primary color and a check mark
341
     * @param string $label Text appearing on the button
342
     * @param string $name Element name (for form treatment purposes)
343
     * @param bool $createElement Whether to use the create or add method
344
     *
345
     * @return HTML_QuickForm_button
346
     */
347
    public function addButtonSave($label, $name = 'submit', $createElement = false)
348
    {
349
        return $this->addButton(
350
            $name,
351
            $label,
352
            'check',
353
            'primary',
354
            null,
355
            null,
356
            array(),
357
            $createElement
358
        );
359
    }
360
361
    /**
362
     * Returns a cancel button
363
     * @param string $label Text appearing on the button
364
     * @param string $name Element name (for form treatment purposes)
365
     * @param bool $createElement Whether to use the create or add method
366
     *
367
     * @return HTML_QuickForm_button
368
     */
369
    public function addButtonCancel($label, $name = 'submit', $createElement = false)
370
    {
371
        return $this->addButton(
372
            $name,
373
            $label,
374
            'times',
375
            'danger',
376
            null,
377
            null,
378
            array(),
379
            $createElement
380
        );
381
    }
382
383
    /**
384
     * Returns a button with the primary color and a "plus" icon
385
     * @param string $label Text appearing on the button
386
     * @param string $name Element name (for form treatment purposes)
387
     * @param bool $createElement Whether to use the create or add method
388
     * @param array $attributes Additional attributes
389
     *
390
     * @return HTML_QuickForm_button
391
     */
392
    public function addButtonCreate($label, $name = 'submit', $createElement = false, $attributes = array())
393
    {
394
        return $this->addButton(
395
            $name,
396
            $label,
397
            'plus',
398
            'primary',
399
            null,
400
            null,
401
            $attributes,
402
            $createElement
403
        );
404
    }
405
406
    /**
407
     * Returns a button with the primary color and a pencil icon
408
     * @param string $label Text appearing on the button
409
     * @param string $name Element name (for form treatment purposes)
410
     * @param bool $createElement Whether to use the create or add method
411
     * @return HTML_QuickForm_button
412
     */
413
    public function addButtonUpdate($label, $name = 'submit', $createElement = false)
414
    {
415
        return $this->addButton(
416
            $name,
417
            $label,
418
            'pencil',
419
            'primary',
420
            null,
421
            null,
422
            array(),
423
            $createElement
424
        );
425
    }
426
427
    /**
428
     * Returns a button with the danger color and a trash icon
429
     * @param string $label Text appearing on the button
430
     * @param string $name Element name (for form treatment purposes)
431
     * @param bool $createElement Whether to use the create or add method
432
     *
433
     * @return HTML_QuickForm_button
434
     */
435
    public function addButtonDelete($label, $name = 'submit', $createElement = false)
436
    {
437
        return $this->addButton(
438
            $name,
439
            $label,
440
            'trash',
441
            'danger',
442
            null,
443
            null,
444
            array(),
445
            $createElement
446
        );
447
    }
448
449
    /**
450
     * Returns a move style button
451
     * @param string $label Text appearing on the button
452
     * @param string $name Element name (for form treatment purposes)
453
     * @param bool $createElement Whether to use the create or add method
454
     *
455
     * @return HTML_QuickForm_button
456
     */
457
    public function addButtonMove($label, $name = 'submit', $createElement = false)
458
    {
459
        return $this->addButton(
460
            $name,
461
            $label,
462
            'arrow-circle-right',
463
            'primary',
464
            null,
465
            null,
466
            array(),
467
            $createElement
468
        );
469
    }
470
471
472
    /**
473
     * Returns a button with the primary color and a paper-plane icon
474
     * @param string $label Text appearing on the button
475
     * @param string $name Element name (for form treatment purposes)
476
     * @param bool $createElement Whether to use the create or add method
477
     *
478
     * @return HTML_QuickForm_button
479
     */
480
    public function addButtonSend($label, $name = 'submit', $createElement = false, $attributes = array())
481
    {
482
        return $this->addButton(
483
            $name,
484
            $label,
485
            'paper-plane',
486
            'primary',
487
            null,
488
            null,
489
            $attributes,
490
            $createElement
491
        );
492
    }
493
494
    /**
495
     * Returns a button with the default (grey?) color and a magnifier icon
496
     * @param string $label Text appearing on the button
497
     * @param string $name Element name (for form treatment purposes)
498
     *
499
     * @return HTML_QuickForm_button
500
     */
501
    public function addButtonSearch($label = null, $name = 'submit')
502
    {
503
        if (empty($label)) {
504
            $label = get_lang('Search');
505
        }
506
507
        return $this->addButton($name, $label, 'search', 'default');
508
    }
509
510
    /**
511
     * Returns a button with the primary color and a right-pointing arrow icon
512
     * @param string $label Text appearing on the button
513
     * @param string $name Element name (for form treatment purposes)
514
     * @param array $attributes Additional attributes
515
     * @return HTML_QuickForm_button
516
     */
517
    public function addButtonNext($label, $name = 'submit', $attributes = array())
518
    {
519
        return $this->addButton(
520
            $name,
521
            $label,
522
            'arrow-right',
523
            'primary',
524
            null,
525
            null,
526
            $attributes
527
        );
528
    }
529
530
    /**
531
     * Returns a button with the primary color and a check mark icon
532
     * @param string $label Text appearing on the button
533
     * @param string $name Element name (for form treatment purposes)
534
     * @param bool $createElement Whether to use the create or add method
535
     * @return HTML_QuickForm_button
536
     */
537
    public function addButtonImport($label, $name = 'submit', $createElement = false)
538
    {
539
        return $this->addButton(
540
            $name,
541
            $label,
542
            'check',
543
            'primary',
544
            null,
545
            null,
546
            array(),
547
            $createElement
548
        );
549
    }
550
551
    /**
552
     * Returns a button with the primary color and a check-mark icon
553
     * @param string $label Text appearing on the button
554
     * @param string $name Element name (for form treatment purposes)
555
     * @param bool $createElement Whether to use the create or add method
556
     * @return HTML_QuickForm_button
557
     */
558
    public function addButtonExport($label, $name = 'submit', $createElement = false)
559
    {
560
        return $this->addButton(
561
            $name,
562
            $label,
563
            'check',
564
            'primary',
565
            null,
566
            null,
567
            array(),
568
            $createElement
569
        );
570
    }
571
572
    /**
573
     * Shortcut to filter button
574
     * @param string $label Text appearing on the button
575
     * @param string $name Element name (for form treatment purposes)
576
     * @param bool $createElement Whether to use the create or add method
577
     * @return HTML_QuickForm_button
578
     */
579
    public function addButtonFilter($label, $name = 'submit', $createElement = false)
580
    {
581
        return $this->addButton(
582
            $name,
583
            $label,
584
            'filter',
585
            'primary',
586
            null,
587
            null,
588
            array(),
589
            $createElement
590
        );
591
    }
592
593
    /**
594
     * Shortcut to reset button
595
     * @param string $label Text appearing on the button
596
     * @param string $name Element name (for form treatment purposes)
597
     * @param bool $createElement Whether to use the create or add method
598
     * @return HTML_QuickForm_button
599
     */
600
    public function addButtonReset($label, $name = 'reset', $createElement = false)
601
    {
602
        $icon = 'eraser';
603
        $style = 'default';
604
        $size = 'default';
605
        $class = null;
606
        $attributes = array();
607
608
        if ($createElement) {
609
            return $this->createElement(
610
                'reset',
611
                $name,
612
                $label,
613
                $icon,
614
                $style,
615
                $size,
616
                $class,
617
                $attributes
618
            );
619
        }
620
621
        return $this->addElement(
622
            'reset',
623
            $name,
624
            $label,
625
            $icon,
626
            $style,
627
            $size,
628
            $class,
629
            $attributes
630
        );
631
    }
632
633
    /**
634
     * Returns a button with the primary color and an upload icon
635
     * @param string $label Text appearing on the button
636
     * @param string $name Element name (for form treatment purposes)
637
     * @param bool $createElement Whether to use the create or add method
638
     *
639
     * @return HTML_QuickForm_button
640
     */
641
    public function addButtonUpload($label, $name = 'submit', $createElement = false)
642
    {
643
        return $this->addButton(
644
            $name,
645
            $label,
646
            'upload',
647
            'primary',
648
            null,
649
            null,
650
            array(),
651
            $createElement
652
        );
653
    }
654
655
    /**
656
     * Returns a button with the primary color and a download icon
657
     * @param string $label Text appearing on the button
658
     * @param string $name Element name (for form treatment purposes)
659
     * @param bool $createElement Whether to use the create or add method
660
     *
661
     * @return HTML_QuickForm_button
662
     */
663
    public function addButtonDownload($label, $name = 'submit', $createElement = false)
664
    {
665
        return $this->addButton(
666
            $name,
667
            $label,
668
            'download',
669
            'primary',
670
            null,
671
            null,
672
            array(),
673
            $createElement
674
        );
675
    }
676
677
    /**
678
     * Returns a button with the primary color and a magnifier icon
679
     * @param string $label Text appearing on the button
680
     * @param string $name Element name (for form treatment purposes)
681
     * @param bool $createElement Whether to use the create or add method
682
     *
683
     * @return HTML_QuickForm_button
684
     */
685 View Code Duplication
    public function addButtonPreview($label, $name = 'submit', $createElement = false)
686
    {
687
        return $this->addButton(
688
            $name,
689
            $label,
690
            'search',
691
            'primary',
692
            null,
693
            null,
694
            array(),
695
            $createElement
696
        );
697
    }
698
699
    /**
700
     * Returns a button with the primary color and a copy (double sheet) icon
701
     * @param string $label Text appearing on the button
702
     * @param string $name Element name (for form treatment purposes)
703
     * @param bool $createElement Whether to use the create or add method
704
     *
705
     * @return HTML_QuickForm_button
706
     */
707 View Code Duplication
    public function addButtonCopy($label, $name = 'submit', $createElement = false)
708
    {
709
        return $this->addButton(
710
            $name,
711
            $label,
712
            'copy',
713
            'primary',
714
            null,
715
            null,
716
            array(),
717
            $createElement
718
        );
719
    }
720
721
    /**
722
     * @param string $name
723
     * @param string $label
724
     * @param string $text
725
     * @param array  $attributes
726
     *
727
     * @return HTML_QuickForm_checkbox
728
     */
729
    public function addCheckBox($name, $label, $text = '', $attributes = array())
730
    {
731
        return $this->addElement('checkbox', $name, $label, $text, $attributes);
732
    }
733
734
    /**
735
     * @param string $name
736
     * @param string $label
737
     * @param array  $options
738
     * @param array  $attributes
739
     *
740
     * @return HTML_QuickForm_group
741
     */
742 View Code Duplication
    public function addCheckBoxGroup($name, $label, $options = array(), $attributes = array())
743
    {
744
        $group = array();
745
        foreach ($options as $value => $text) {
746
            $attributes['value'] = $value;
747
            $group[] = $this->createElement(
748
                'checkbox',
749
                $value,
750
                null,
751
                $text,
752
                $attributes
753
            );
754
        }
755
756
        return $this->addGroup($group, $name, $label);
757
    }
758
759
    /**
760
     * @param string $name
761
     * @param string $label
762
     * @param array  $options
763
     * @param array  $attributes
764
     *
765
     * @return HTML_QuickForm_radio
766
     */
767 View Code Duplication
    public function addRadio($name, $label, $options = array(), $attributes = array())
768
    {
769
        $group = array();
770
        foreach ($options as $key => $value) {
771
            $group[] = $this->createElement('radio', null, null, $value, $key, $attributes);
772
        }
773
774
        return $this->addGroup($group, $name, $label);
775
    }
776
777
    /**
778
     * @param string $name
779
     * @param string $label
780
     * @param array  $options
781
     * @param array  $attributes
782
     *
783
     * @return HTML_QuickForm_select
784
     */
785
    public function addSelect($name, $label, $options = array(), $attributes = array())
786
    {
787
        return $this->addElement('select', $name, $label, $options, $attributes);
788
    }
789
790
    /**
791
     * @param $name
792
     * @param $label
793
     * @param $collection
794
     * @param array $attributes
795
     * @param bool $addNoneOption
796
     * @param string $textCallable set a function getStringValue() by default __toString()
797
     *
798
     * @return HTML_QuickForm_element
799
     */
800
    public function addSelectFromCollection(
801
        $name,
802
        $label,
803
        $collection,
804
        $attributes = array(),
805
        $addNoneOption = false,
806
        $textCallable = ''
807
    ) {
808
        $options = [];
809
810
        if ($addNoneOption) {
811
            $options[0] = get_lang('None');
812
        }
813
814
        if (!empty($collection)) {
815
            foreach ($collection as $item) {
816
                $text = $item;
817
                if (!empty($textCallable)) {
818
                    $text = $item->$textCallable();
819
                }
820
                $options[$item->getId()] = $text;
821
            }
822
        }
823
        return $this->addElement('select', $name, $label, $options, $attributes);
824
    }
825
826
    /**
827
     * @param string $label
828
     * @param string $text
829
     *
830
     * @return HTML_QuickForm_label
831
     */
832
    public function addLabel($label, $text)
833
    {
834
        return $this->addElement('label', $label, $text);
835
    }
836
837
    /**
838
     * @param string $text
839
     */
840
    public function addHeader($text)
841
    {
842
        $this->addElement('header', $text);
843
    }
844
845
    /**
846
     * @param string $name
847
     * @param string $label
848
     * @param array  $attributes
849
     * @throws Exception if the file doesn't have an id
850
     */
851
    public function addFile($name, $label, $attributes = array())
852
    {
853
        $element = $this->addElement('file', $name, $label, $attributes);
854
        if (isset($attributes['crop_image'])) {
855
            $id = $element->getAttribute('id');
856
            if (empty($id)) {
857
                throw new Exception('If you use the crop functionality the element must have an id');
858
            }
859
            $this->addHtml('
860
                <div class="form-group">
861
                <label for="cropImage" id="'.$id.'_label_crop_image" class="col-sm-2 control-label"></label>
862
                <div class="col-sm-8">
863
                <div id="'.$id.'_crop_image" class="cropCanvas">
864
                <img id="'.$id.'_preview_image">
865
                </div>
866
                <div>
867
                <button class="btn btn-primary hidden" name="cropButton" id="'.$id.'_crop_button" >
868
                    <em class="fa fa-crop"></em> '.
869
                    get_lang('CropYourPicture').'
870
                </button>
871
                </div>
872
                </div>
873
                </div>'
874
            );
875
            $this->addHidden($id.'_crop_result', '');
876
            $this->addHidden($id.'_crop_image_base_64', '');
877
        }
878
    }
879
880
    /**
881
     * @param string $snippet
882
     */
883
    public function addHtml($snippet)
884
    {
885
        $this->addElement('html', $snippet);
886
    }
887
888
    /**
889
     * Adds a HTML-editor to the form
890
     * @param string $name
891
     * @param string $label The label for the form-element
892
     * @param bool   $required (optional) Is the form-element required (default=true)
893
     * @param bool   $fullPage (optional) When it is true, the editor loads completed html code for a full page.
894
     * @param array  $config (optional) Configuration settings for the online editor.
895
     * @param bool   $style
896
     */
897
    public function addHtmlEditor(
898
        $name,
899
        $label,
900
        $required = true,
901
        $fullPage = false,
902
        $config = [],
903
        $style = false
904
    ) {
905
        $attributes = [];
906
        $attributes['rows'] = isset($config['rows']) ? $config['rows'] : 15;
907
        $attributes['cols'] = isset($config['cols']) ? $config['cols'] : 80;
908
        $attributes['cols-size'] = isset($config['cols-size']) ? $config['cols-size'] : [];
909
        $attributes['class'] = isset($config['class']) ? $config['class'] : [];
910
911
        $this->addElement('html_editor', $name, $label, $attributes, $config);
912
        $this->applyFilter($name, 'trim');
913
        if ($required) {
914
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
915
        }
916
917
        /** @var HtmlEditor $element */
918
        $element = $this->getElement($name);
919
920
        if ($style) {
921
            $config['style'] = true;
922
        }
923
        if ($fullPage) {
924
            $config['fullPage'] = true;
925
        }
926
927
        if ($element->editor) {
928
            $element->editor->processConfig($config);
929
        }
930
    }
931
932
    /**
933
     * Adds a Google Maps Geolocalization field to the form
934
     *
935
     * @param $name
936
     * @param $label
937
     */
938
    public function addGeoLocationMapField($name, $label)
939
    {
940
        $gMapsPlugin = GoogleMapsPlugin::create();
941
        $geolocalization = $gMapsPlugin->get('enable_api') === 'true';
942
943
        if ($geolocalization) {
944
            $gmapsApiKey = $gMapsPlugin->get('api_key');
945
            $this->addHtml('<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?key='. $gmapsApiKey . '" ></script>');
946
        }
947
        $this->addElement(
948
            'text',
949
            $name,
950
            $label,
951
            ['id' => $name]
952
        );
953
        $this->applyFilter($name, 'stripslashes');
954
        $this->applyFilter($name, 'trim');
955
        $this->addHtml('
956
                            <div class="form-group">
957
                                <label for="geolocalization_'.$name.'" class="col-sm-2 control-label"></label>
958
                                <div class="col-sm-8">
959
                                    <button class="null btn btn-default " id="geolocalization_'.$name.'" name="geolocalization_'.$name.'" type="submit"><em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'</button>
960
                                    <button class="null btn btn-default " id="myLocation_'.$name.'" name="myLocation_'.$name.'" type="submit"><em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'</button>
961
                                </div>
962
                            </div>
963
                        ');
964
965
        $this->addHtml('
966
                            <div class="form-group">
967
                                <label for="map_'.$name.'" class="col-sm-2 control-label">
968
                                    '.$label.' - '.get_lang('Map').'
969
                                </label>
970
                                <div class="col-sm-8">
971
                                    <div name="map_'.$name.'" id="map_'.$name.'" style="width:100%; height:300px;">
972
                                    </div>
973
                                </div>
974
                            </div>
975
                        ');
976
977
        $this->addHtml(
978
            '<script>
979
                $(document).ready(function() {
980
981
                    if (typeof google === "object") {
982
983
                        var address = $("#' . $name . '").val();
984
                        initializeGeo'.$name.'(address, false);
985
986
                        $("#geolocalization_'.$name.'").on("click", function() {
987
                            var address = $("#'.$name.'").val();
988
                            initializeGeo'.$name.'(address, false);
989
                            return false;
990
                        });
991
992
                        $("#myLocation_'.$name.'").on("click", function() {
993
                            myLocation'.$name.'();
994
                            return false;
995
                        });
996
997
                        $("#'.$name.'").keypress(function (event) {
998
                            if (event.which == 13) {
999
                                $("#geolocalization_'.$name.'").click();
1000
                                return false;
1001
                            }
1002
                        });
1003
1004
                    } else {
1005
                        $("#map_'.$name.'").html("<div class=\"alert alert-info\">' . get_lang('YouNeedToActivateTheGoogleMapsPluginInAdminPlatformToSeeTheMap') . '</div>");
1006
                    }
1007
1008
                });
1009
1010
                function myLocation'.$name.'() {
1011
                    if (navigator.geolocation) {
1012
                        var geoPosition = function(position) {
1013
                            var lat = position.coords.latitude;
1014
                            var lng = position.coords.longitude;
1015
                            var latLng = new google.maps.LatLng(lat, lng);
1016
                            initializeGeo'.$name.'(false, latLng)
1017
                        };
1018
1019
                        var geoError = function(error) {
1020
                            alert("Geocode ' . get_lang('Error') . ': " + error);
1021
                        };
1022
1023
                        var geoOptions = {
1024
                            enableHighAccuracy: true
1025
                        };
1026
1027
                        navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
1028
                    }
1029
                }
1030
1031
                function initializeGeo'.$name.'(address, latLng) {
1032
                    var geocoder = new google.maps.Geocoder();
1033
                    var latlng = new google.maps.LatLng(-34.397, 150.644);
1034
                    var myOptions = {
1035
                        zoom: 15,
1036
                        center: latlng,
1037
                        mapTypeControl: true,
1038
                        mapTypeControlOptions: {
1039
                            style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
1040
                        },
1041
                        navigationControl: true,
1042
                        mapTypeId: google.maps.MapTypeId.ROADMAP
1043
                    };
1044
1045
                    map_'.$name.' = new google.maps.Map(document.getElementById("map_'.$name.'"), myOptions);
1046
1047
                    var parameter = address ? { "address": address } : latLng ? { "latLng": latLng } : false;
1048
1049
                    if (geocoder && parameter) {
1050
                        geocoder.geocode(parameter, function(results, status) {
1051
                            if (status == google.maps.GeocoderStatus.OK) {
1052
                                if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
1053
                                    map_'.$name.'.setCenter(results[0].geometry.location);
1054
                                    if (!address) {
1055
                                        $("#'.$name.'").val(results[0].formatted_address);
1056
                                    }
1057
                                    var infowindow = new google.maps.InfoWindow({
1058
                                        content: "<b>" + $("#'.$name.'").val() + "</b>",
1059
                                        size: new google.maps.Size(150, 50)
1060
                                    });
1061
1062
                                    var marker = new google.maps.Marker({
1063
                                        position: results[0].geometry.location,
1064
                                        map: map_'.$name.',
1065
                                        title: $("#'.$name.'").val()
1066
                                    });
1067
                                    google.maps.event.addListener(marker, "click", function() {
1068
                                        infowindow.open(map_'.$name.', marker);
1069
                                    });
1070
                                } else {
1071
                                    alert("' . get_lang("NotFound") . '");
1072
                                }
1073
1074
                            } else {
1075
                                alert("Geocode ' . get_lang('Error') . ': ' . get_lang("AddressField") . ' ' . get_lang("NotFound") . '");
1076
                            }
1077
                        });
1078
                    }
1079
                }
1080
            </script>
1081
        ');
1082
1083
    }
1084
1085
    /**
1086
     * @param string $name
1087
     * @param string $label
1088
     *
1089
     * @return mixed
1090
     */
1091
    public function addButtonAdvancedSettings($name, $label = '')
1092
    {
1093
        $label = !empty($label) ? $label : get_lang('AdvancedParameters');
1094
1095
        return $this->addElement('advanced_settings', $name, $label);
1096
    }
1097
1098
    /**
1099
     * Adds a progress loading image to the form.
1100
     *
1101
     */
1102
    public function addProgress($delay = 2, $label = '')
1103
    {
1104
        if (empty($label)) {
1105
            $label = get_lang('PleaseStandBy');
1106
        }
1107
        $this->with_progress_bar = true;
1108
        $id = $this->getAttribute('id');
1109
1110
        $this->updateAttributes("onsubmit=\"javascript: addProgress('" . $id . "')\"");
1111
        $this->addHtml(api_get_js('js/upload.js'));
1112
    }
1113
1114
    /**
1115
     * This function has been created for avoiding changes directly within QuickForm class.
1116
     * When we use it, the element is threated as 'required' to be dealt during validation.
1117
     * @param array $elements The array of elements
1118
     * @param string $message The message displayed
1119
     */
1120
    public function add_multiple_required_rule($elements, $message)
1121
    {
1122
        $this->_required[] = $elements[0];
1123
        $this->addRule($elements, $message, 'multiple_required');
1124
    }
1125
1126
    /**
1127
     * Displays the form.
1128
     * If an element in the form didn't validate, an error message is showed
1129
     * asking the user to complete the form.
1130
     */
1131
    public function display()
1132
    {
1133
        echo $this->returnForm();
1134
    }
1135
1136
    /**
1137
     * Returns the HTML code of the form.
1138
     * @return string $return_value HTML code of the form
1139
     */
1140
    public function returnForm()
1141
    {
1142
        $returnValue = '';
1143
1144
        /** @var HTML_QuickForm_element $element */
1145
        foreach ($this->_elements as $element) {
1146
            $elementError = parent::getElementError($element->getName());
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getElementError() instead of returnForm()). Are you sure this is correct? If so, you might want to change this to $this->getElementError().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1147
            if (!is_null($elementError)) {
1148
                $returnValue .= Display::return_message($elementError, 'warning').'<br />';
1149
                break;
1150
            }
1151
        }
1152
1153
        $returnValue .= parent::toHtml();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (toHtml() instead of returnForm()). Are you sure this is correct? If so, you might want to change this to $this->toHtml().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1154
        // Add div-element which is to hold the progress bar
1155
        $id = $this->getAttribute('id');
1156
        if (isset($this->with_progress_bar) && $this->with_progress_bar) {
1157
            $icon = Display::return_icon('progress_bar.gif');
1158
1159
            // @todo improve UI
1160
            $returnValue .= '<br />
1161
1162
            <div id="loading_div_'.$id.'" class="loading_div" style="display:none;margin-left:40%; margin-top:10px; height:50px;">
1163
                '.$icon.'
1164
            </div>
1165
            ';
1166
        }
1167
1168
        return $returnValue;
1169
    }
1170
1171
    /**
1172
     * Returns the HTML code of the form.
1173
     * If an element in the form didn't validate, an error message is showed
1174
     * asking the user to complete the form.
1175
     *
1176
     * @return string $return_value HTML code of the form
1177
     *
1178
     * @author Patrick Cool <[email protected]>, Ghent University, august 2006
1179
     * @author Julio Montoya
1180
     * @deprecated use returnForm()
1181
     */
1182
    public function return_form()
1183
    {
1184
        return $this->returnForm();
1185
    }
1186
1187
    /**
1188
     * Create a form validator based on an array of form data:
1189
     *
1190
     *         array(
1191
     *             'name' => 'zombie_report_parameters',    //optional
1192
     *             'method' => 'GET',                       //optional
1193
     *             'items' => array(
1194
     *                 array(
1195
     *                     'name' => 'ceiling',
1196
     *                     'label' => 'Ceiling',            //optional
1197
     *                     'type' => 'date',
1198
     *                     'default' => date()              //optional
1199
     *                 ),
1200
     *                 array(
1201
     *                     'name' => 'active_only',
1202
     *                     'label' => 'ActiveOnly',
1203
     *                     'type' => 'checkbox',
1204
     *                     'default' => true
1205
     *                 ),
1206
     *                 array(
1207
     *                     'name' => 'submit_button',
1208
     *                     'type' => 'style_submit_button',
1209
     *                     'value' => get_lang('Search'),
1210
     *                     'attributes' => array('class' => 'search')
1211
     *                 )
1212
     *             )
1213
     *         );
1214
     *
1215
     * @param array $form_data
1216
     * @deprecated use normal FormValidator construct
1217
     *
1218
     * @return FormValidator
1219
     */
1220
    public static function create($form_data)
1221
    {
1222
        if (empty($form_data)) {
1223
            return null;
1224
        }
1225
        $form_name = isset($form_data['name']) ? $form_data['name'] : 'form';
1226
        $form_method = isset($form_data['method']) ? $form_data['method'] : 'POST';
1227
        $form_action = isset($form_data['action']) ? $form_data['action'] : '';
1228
        $form_target = isset($form_data['target']) ? $form_data['target'] : '';
1229
        $form_attributes = isset($form_data['attributes']) ? $form_data['attributes'] : null;
1230
        $form_track_submit = isset($form_data['track_submit']) ? $form_data['track_submit'] : true;
1231
        $reset = null;
1232
        $result = new FormValidator($form_name, $form_method, $form_action, $form_target, $form_attributes, $form_track_submit);
1233
1234
        $defaults = array();
1235
        foreach ($form_data['items'] as $item) {
1236
            $name = $item['name'];
1237
            $type = isset($item['type']) ? $item['type'] : 'text';
1238
            $label = isset($item['label']) ? $item['label'] : '';
1239
            if ($type == 'wysiwyg') {
1240
                $element = $result->addHtmlEditor($name, $label);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $element is correct as $result->addHtmlEditor($name, $label) (which targets FormValidator::addHtmlEditor()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1241
            } else {
1242
                $element = $result->addElement($type, $name, $label);
1243
            }
1244
            if (isset($item['attributes'])) {
1245
                $attributes = $item['attributes'];
1246
                $element->setAttributes($attributes);
1247
            }
1248
            if (isset($item['value'])) {
1249
                $value = $item['value'];
1250
                $element->setValue($value);
1251
            }
1252
            if (isset($item['default'])) {
1253
                $defaults[$name] = $item['default'];
1254
            }
1255
            if (isset($item['rules'])) {
1256
                $rules = $item['rules'];
1257
                foreach ($rules as $rule) {
1258
                    $message = $rule['message'];
1259
                    $type = $rule['type'];
1260
                    $format = isset($rule['format']) ? $rule['format'] : null;
1261
                    $validation = isset($rule['validation']) ? $rule['validation'] : 'server';
1262
                    $force = isset($rule['force']) ? $rule['force'] : false;
1263
                    $result->addRule($name, $message, $type, $format, $validation, $reset, $force);
1264
                }
1265
            }
1266
        }
1267
        $result->setDefaults($defaults);
1268
1269
        return $result;
1270
    }
1271
1272
    /**
1273
     * @return HTML_QuickForm_Renderer_Default
1274
     */
1275
    public static function getDefaultRenderer()
1276
    {
1277
        return
1278
            isset($GLOBALS['_HTML_QuickForm_default_renderer']) ?
1279
                $GLOBALS['_HTML_QuickForm_default_renderer'] : null;
1280
    }
1281
1282
    /**
1283
     * Adds a input of type url to the form.
1284
     * @param string $name The label for the form-element
1285
     * @param string $label The element name
1286
     * @param bool $required Optional. Is the form-element required (default=true)
1287
     * @param array $attributes Optional. List of attributes for the form-element
1288
     */
1289 View Code Duplication
    public function addUrl($name, $label, $required = true, $attributes = array())
1290
    {
1291
        $this->addElement('url', $name, $label, $attributes);
1292
        $this->applyFilter($name, 'trim');
1293
        $this->addRule($name, get_lang('InsertAValidUrl'), 'url');
1294
1295
        if ($required) {
1296
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1297
        }
1298
    }
1299
1300
    /**
1301
     * Adds a text field for letters to the form.
1302
     * A trim-filter is attached to the field.
1303
     * @param string $name The element name
1304
     * @param string $label The label for the form-element
1305
     * @param bool $required Optional. Is the form-element required (default=true)
1306
     * @param array $attributes Optional. List of attributes for the form-element
1307
     */
1308 View Code Duplication
    public function addTextLettersOnly(
1309
        $name,
1310
        $label,
1311
        $required = false,
1312
        $attributes = []
1313
    ) {
1314
        $attributes = array_merge(
1315
            $attributes,
1316
            [
1317
                'pattern' => '[a-zA-ZñÑ]+',
1318
                'title' => get_lang('OnlyLetters')
1319
            ]
1320
        );
1321
1322
        $this->addElement(
1323
            'text',
1324
            $name,
1325
            [
1326
                $label,
1327
                get_lang('OnlyLetters')
1328
            ],
1329
            $attributes
1330
        );
1331
1332
        $this->applyFilter($name, 'trim');
1333
1334
        if ($required) {
1335
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1336
        }
1337
1338
        $this->addRule(
1339
            $name,
1340
            get_lang('OnlyLetters'),
1341
            'regex',
1342
            '/^[a-zA-ZñÑ]+$/'
1343
        );
1344
    }
1345
1346
    /**
1347
     * Adds a text field for alphanumeric characters to the form.
1348
     * A trim-filter is attached to the field.
1349
     * @param string $name The element name
1350
     * @param string $label The label for the form-element
1351
     * @param bool $required Optional. Is the form-element required (default=true)
1352
     * @param array $attributes Optional. List of attributes for the form-element
1353
     */
1354 View Code Duplication
    public function addTextAlphanumeric(
1355
        $name,
1356
        $label,
1357
        $required = false,
1358
        $attributes = []
1359
    ) {
1360
        $attributes = array_merge(
1361
            $attributes,
1362
            [
1363
                'pattern' => '[a-zA-Z0-9ñÑ]+',
1364
                'title' => get_lang('OnlyLettersAndNumbers')
1365
            ]
1366
        );
1367
1368
        $this->addElement(
1369
            'text',
1370
            $name,
1371
            [
1372
                $label,
1373
                get_lang('OnlyLettersAndNumbers')
1374
            ],
1375
            $attributes
1376
        );
1377
1378
        $this->applyFilter($name, 'trim');
1379
1380
        if ($required) {
1381
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1382
        }
1383
1384
        $this->addRule(
1385
            $name,
1386
            get_lang('OnlyLettersAndNumbers'),
1387
            'regex',
1388
            '/^[a-zA-Z0-9ÑÑ]+$/'
1389
        );
1390
    }
1391
1392
    /**
1393
     * @param string $name
1394
     * @param $label
1395
     * @param bool $required
1396
     * @param array $attributes
1397
     * @param bool $allowNegative
1398
     * @param integer $minValue
1399
     * @param null $maxValue
1400
     */
1401
    public function addFloat(
1402
        $name,
1403
        $label,
1404
        $required = false,
1405
        $attributes = [],
1406
        $allowNegative = false,
1407
        $minValue = null,
1408
        $maxValue = null
1409
    ) {
1410
        $this->addElement(
1411
            'FloatNumber',
1412
            $name,
1413
            $label,
1414
            $attributes
1415
        );
1416
1417
        $this->applyFilter($name, 'trim');
1418
1419
        if ($required) {
1420
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1421
        }
1422
1423
        // Rule allows "," and "."
1424
        /*$this->addRule(
1425
            $name,
1426
            get_lang('OnlyNumbers'),
1427
            'regex',
1428
            '/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)|(^-?\d\d*\,\d*$)|(^-?\,\d\d*$)/'
1429
        );*/
1430
1431
        if ($allowNegative == false) {
1432
            $this->addRule(
1433
                $name,
1434
                get_lang('NegativeValue'),
1435
                'compare',
1436
                '>=',
1437
                'server',
1438
                false,
1439
                false,
1440
                0
1441
            );
1442
        }
1443
1444 View Code Duplication
        if (!is_null($minValue)) {
1445
            $this->addRule(
1446
                $name,
1447
                get_lang('UnderMin'),
1448
                'compare',
1449
                '>=',
1450
                'server',
1451
                false,
1452
                false,
1453
                $minValue
1454
            );
1455
        }
1456
1457 View Code Duplication
        if (!is_null($maxValue)) {
1458
            $this->addRule(
1459
                $name,
1460
                get_lang('OverMax'),
1461
                'compare',
1462
                '<=',
1463
                'server',
1464
                false,
1465
                false,
1466
                $maxValue
1467
            );
1468
        }
1469
    }
1470
1471
    /**
1472
     * Adds a text field for letters and spaces to the form.
1473
     * A trim-filter is attached to the field.
1474
     * @param string $name The element name
1475
     * @param string $label The label for the form-element
1476
     * @param bool $required Optional. Is the form-element required (default=true)
1477
     * @param array $attributes Optional. List of attributes for the form-element
1478
     */
1479 View Code Duplication
    public function addTextLettersAndSpaces(
1480
        $name,
1481
        $label,
1482
        $required = false,
1483
        $attributes = []
1484
    ) {
1485
        $attributes = array_merge(
1486
            $attributes,
1487
            [
1488
                'pattern' => '[a-zA-ZñÑ\s]+',
1489
                'title' => get_lang('OnlyLettersAndSpaces')
1490
            ]
1491
        );
1492
1493
        $this->addElement(
1494
            'text',
1495
            $name,
1496
            [
1497
                $label,
1498
                get_lang('OnlyLettersAndSpaces')
1499
            ],
1500
            $attributes
1501
        );
1502
1503
        $this->applyFilter($name, 'trim');
1504
1505
        if ($required) {
1506
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1507
        }
1508
1509
        $this->addRule(
1510
            $name,
1511
            get_lang('OnlyLettersAndSpaces'),
1512
            'regex',
1513
            '/^[a-zA-ZñÑ\s]+$/'
1514
        );
1515
    }
1516
1517
    /**
1518
     * Adds a text field for alphanumeric and spaces characters to the form.
1519
     * A trim-filter is attached to the field.
1520
     * @param string $name The element name
1521
     * @param string $label The label for the form-element
1522
     * @param bool $required Optional. Is the form-element required (default=true)
1523
     * @param array $attributes Optional. List of attributes for the form-element
1524
     */
1525 View Code Duplication
    public function addTextAlphanumericAndSpaces(
1526
        $name,
1527
        $label,
1528
        $required = false,
1529
        $attributes = []
1530
    ) {
1531
        $attributes = array_merge(
1532
            $attributes,
1533
            [
1534
                'pattern' => '[a-zA-Z0-9ñÑ\s]+',
1535
                'title' => get_lang('OnlyLettersAndNumbersAndSpaces')
1536
            ]
1537
        );
1538
1539
        $this->addElement(
1540
            'text',
1541
            $name,
1542
            [
1543
                $label,
1544
                get_lang('OnlyLettersAndNumbersAndSpaces')
1545
            ],
1546
            $attributes
1547
        );
1548
1549
        $this->applyFilter($name, 'trim');
1550
1551
        if ($required) {
1552
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1553
        }
1554
1555
        $this->addRule(
1556
            $name,
1557
            get_lang('OnlyLettersAndNumbersAndSpaces'),
1558
            'regex',
1559
            '/^[a-zA-Z0-9ñÑ\s]+$/'
1560
        );
1561
    }
1562
1563
    /**
1564
     * @param string $url
1565
     */
1566
    public function addMultipleUpload($url)
1567
    {
1568
        $inputName = 'input_file_upload';
1569
        $this->addMultipleUploadJavascript($url, $inputName);
1570
1571
        $this->addHtml('
1572
            <div class="description-upload">
1573
            '.get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'
1574
            </div>
1575
            <span class="btn btn-success fileinput-button">
1576
                <i class="glyphicon glyphicon-plus"></i>
1577
                <span>'.get_lang('AddFiles').'</span>
1578
                <!-- The file input field used as target for the file upload widget -->
1579
                <input id="'.$inputName.'" type="file" name="files[]" multiple>
1580
            </span>
1581
            <div id="dropzone">
1582
                <div class="button-load">
1583
                '.get_lang('UploadFiles').'
1584
                </div>
1585
            </div>
1586
            <br />
1587
            <!-- The global progress bar -->
1588
            <div id="progress" class="progress">
1589
                <div class="progress-bar progress-bar-success"></div>
1590
            </div>
1591
            <div id="files" class="files"></div>
1592
        ');
1593
    }
1594
1595
    /**
1596
     *
1597
     * @param string $url page that will handle the upload
1598
     * @param string $inputName
1599
     */
1600
    private function addMultipleUploadJavascript($url, $inputName)
1601
    {
1602
        $icon = Display::return_icon('file_txt.gif');
1603
        $this->addHtml("
1604
        <script>
1605
        $(function () {
1606
            'use strict';
1607
            $('#".$this->getAttribute('id')."').submit(function() {
1608
                return false;
1609
            });
1610
1611
            $('#dropzone').on('click', function() {
1612
                $('#".$inputName."').click();
1613
            });
1614
1615
            var url = '".$url."';
1616
            var uploadButton = $('<button/>')
1617
                .addClass('btn btn-primary')
1618
                .prop('disabled', true)
1619
                .text('".addslashes(get_lang('Loading'))."')
1620
                .on('click', function () {
1621
                    var \$this = $(this),
1622
                    data = \$this.data();
1623
1624
                    \$this
1625
                        .off('click')
1626
                        .text('".addslashes(get_lang('Cancel'))."')
1627
                        .on('click', function () {
1628
                            \$this.remove();
1629
                            data.abort();
1630
                        });
1631
                    data.submit().always(function () {
1632
                        \$this.remove();
1633
                    });
1634
                });               
1635
                
1636
            $('#".$inputName."').fileupload({
1637
                url: url,
1638
                dataType: 'json',
1639
                // Enable image resizing, except for Android and Opera,
1640
                // which actually support image resizing, but fail to
1641
                // send Blob objects via XHR requests:
1642
                disableImageResize: /Android(?!.*Chrome)|Opera/.test(window.navigator.userAgent),
1643
                previewMaxWidth: 100,
1644
                previewMaxHeight: 100,
1645
                previewCrop: true,
1646
                dropzone: $('#dropzone'),                                
1647
            }).on('fileuploadadd', function (e, data) {
1648
                data.context = $('<div class=\"row\" style=\"margin-bottom:35px\" />').appendTo('#files');
1649
                $.each(data.files, function (index, file) {
1650
                    var node = $('<div class=\"col-sm-5\">').text(file.name);                    
1651
                    node.appendTo(data.context);
1652
                });
1653
            }).on('fileuploadprocessalways', function (e, data) {
1654
                var index = data.index,
1655
                    file = data.files[index],
1656
                    node = $(data.context.children()[index]);
1657
                if (file.preview) {
1658
                    data.context
1659
                        .prepend($('<div class=\"col-sm-2\">').html(file.preview))
1660
                    ;
1661
                } else {
1662
                    data.context
1663
                        .prepend($('<div class=\"col-sm-2\">').html('".$icon."'))
1664
                    ;
1665
                }
1666
                if (index + 1 === data.files.length) {
1667
                    data.context.find('button')
1668
                        .text('Upload')
1669
                        .prop('disabled', !!data.files.error);
1670
                }
1671
            }).on('fileuploadprogressall', function (e, data) {
1672
                var progress = parseInt(data.loaded / data.total * 100, 10);
1673
                $('#progress .progress-bar').css(
1674
                    'width',
1675
                    progress + '%'
1676
                );
1677
            }).on('fileuploaddone', function (e, data) {
1678
                $.each(data.result.files, function (index, file) {
1679
                    if (file.url) {
1680
                        var link = $('<a>')
1681
                            .attr('target', '_blank')
1682
                            .prop('href', file.url);
1683
                        $(data.context.children()[index]).parent().wrap(link);                        
1684
                        var successMessage = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-success\"/>').text('" . addslashes(get_lang('UplUploadSucceeded')) . "'));
1685
                        $(data.context.children()[index]).parent().append(successMessage);
1686
                    } else if (file.error) {
1687
                        var error = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-danger\"/>').text(file.error));
1688
                        $(data.context.children()[index]).parent().append(error);
1689
                    }
1690
                });
1691
                $('#dropzone').removeClass('hover');
1692
            }).on('fileuploadfail', function (e, data) {
1693
                $.each(data.files, function (index) {
1694
                    var failedMessage = '" . addslashes(get_lang('UplUploadFailed')) . "';
1695
                    var error = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-danger\"/>').text(failedMessage));
1696
                    $(data.context.children()[index]).parent().append(error);
1697
                });
1698
                $('#dropzone').removeClass('hover');
1699
            }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled');            
1700
            
1701
            $('#dropzone').on('dragover', function (e) {
1702
                // dragleave callback implementation                
1703
                $('#dropzone').addClass('hover');
1704
            });
1705
            
1706
            $('#dropzone').on('dragleave', function (e) {                
1707
                $('#dropzone').removeClass('hover');
1708
            });
1709
            $('.fileinput-button').hide();
1710
        });
1711
        </script>");
1712
    }
1713
1714
    /**
1715
     * @param string $elementName
1716
     * @param string $groupName if element is inside a group
1717
     * @throws Exception
1718
     */
1719
    public function addPasswordRule($elementName, $groupName = '')
1720
    {
1721
        // Constant defined in old config/profile.conf.php
1722
        if (CHECK_PASS_EASY_TO_FIND === true) {
1723
            $message = get_lang('PassTooEasy').': '.api_generate_password();
1724
1725
            if (!empty($groupName)) {
1726
                $groupObj = $this->getElement($groupName);
1727
1728
                if ($groupObj instanceof HTML_QuickForm_group) {
0 ignored issues
show
Bug introduced by
The class HTML_QuickForm_group does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
1729
                    $elementName = $groupObj->getElementName($elementName);
1730
1731
                    if ($elementName === false) {
1732
                        throw new Exception("The $groupName doesn't have the element $elementName");
1733
                    }
1734
1735
                    $this->_rules[$elementName][] = array(
1736
                        'type' => 'callback',
1737
                        'format' => 'api_check_password',
1738
                        'message' => $message,
1739
                        'validation' => '',
1740
                        'reset' => false,
1741
                        'group' => $groupName
1742
                    );
1743
                }
1744
            } else {
1745
                $this->addRule(
1746
                    $elementName,
1747
                    $message,
1748
                    'callback',
1749
                    'api_check_password'
1750
                );
1751
            }
1752
        }
1753
    }
1754
}
1755
1756
/**
1757
 * Cleans HTML text filter
1758
 * @param string $html			HTML to clean
1759
 * @param int $mode (optional)
1760
 * @return string				The cleaned HTML
1761
 */
1762
function html_filter($html, $mode = NO_HTML)
1763
{
1764
    $allowed_tags = HTML_QuickForm_Rule_HTML::get_allowed_tags($mode);
1765
    //@todo check kses support in Chamilo 2.0
1766
    //$cleaned_html = kses($html, $allowed_tags);
1767
    return $html;
1768
}
1769
1770
function html_filter_teacher($html)
1771
{
1772
    return html_filter($html, TEACHER_HTML);
1773
}
1774
1775
function html_filter_student($html)
1776
{
1777
    return html_filter($html, STUDENT_HTML);
1778
}
1779
1780
function html_filter_teacher_fullpage($html)
1781
{
1782
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1783
}
1784
1785
function html_filter_student_fullpage($html)
1786
{
1787
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1788
}
1789
1790
/**
1791
 * Cleans mobile phone number text
1792
 * @param string $mobilePhoneNumber     Mobile phone number to clean
1793
 * @return string                       The cleaned mobile phone number
1794
 */
1795
function mobile_phone_number_filter($mobilePhoneNumber)
1796
{
1797
    $mobilePhoneNumber = str_replace(array('+', '(', ')'), '', $mobilePhoneNumber);
1798
1799
    return ltrim($mobilePhoneNumber, '0');
1800
}
1801