Passed
Push — 1.10.x ( 23173d...b65d66 )
by
unknown
59:50 queued 10:49
created

FormValidator   D

Complexity

Total Complexity 118

Size/Duplication

Total Lines 1438
Duplicated Lines 15.09 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 4
Bugs 1 Features 3
Metric Value
wmc 118
c 4
b 1
f 3
lcom 1
cbo 6
dl 217
loc 1438
rs 4.4102

54 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 81 13
A getFormTemplate() 0 9 1
B getDefaultElementTemplate() 0 27 1
A getLayout() 0 4 1
A setLayout() 0 4 1
A addText() 0 8 2
A addDateRangePicker() 10 10 2
A addDatePicker() 0 4 1
A addDateTimePicker() 0 4 1
A addHidden() 0 4 1
A addTextarea() 0 4 1
B addButton() 0 34 2
A addButtonSave() 0 13 1
A addButtonCancel() 0 13 1
A addButtonCreate() 0 13 1
A addButtonUpdate() 0 13 1
A addButtonDelete() 0 13 1
A addButtonSend() 0 13 1
A addButtonSearch() 0 8 2
A addButtonNext() 0 4 1
A addButtonImport() 0 13 1
A addButtonExport() 0 13 1
A addButtonFilter() 0 13 1
B addButtonReset() 0 32 2
A addButtonUpload() 0 13 1
A addButtonDownload() 0 13 1
A addButtonPreview() 13 13 1
A addButtonCopy() 13 13 1
A addCheckBox() 0 4 1
A addCheckBoxGroup() 10 10 2
A addRadio() 9 9 2
A addSelect() 0 4 1
B addSelectFromCollection() 0 25 5
A addLabel() 0 4 1
A addHeader() 0 4 1
A addFile() 0 4 1
A addHtml() 0 4 1
C addHtmlEditor() 0 23 7
A addButtonAdvancedSettings() 0 6 2
A add_progress_bar() 0 10 2
A add_multiple_required_rule() 0 5 1
A display() 0 4 1
B returnForm() 0 30 6
A return_form() 0 4 1
F create() 0 51 20
A getDefaultRenderer() 0 6 2
A addUrl() 10 10 2
B addTextLettersOnly() 37 37 2
B addTextAlphanumeric() 37 37 2
B addTextLettersAndSpaces() 37 37 2
B addTextAlphanumericAndSpaces() 37 37 2
B addMultipleUpload() 0 29 1
B addMultipleUploadJavascript() 0 117 1
B add_real_progress_bar() 0 53 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FormValidator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FormValidator, and based on these observations, apply Extract Interface, too.

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
     * @return string
126
     */
127
    public function getDefaultElementTemplate()
128
    {
129
        return '
130
            <div class="form-group {error_class}">
131
                <label {label-for} class="col-sm-2 control-label" >
132
                    <!-- BEGIN required --><span class="form_required">*</span><!-- END required -->
133
                    {label}
134
                </label>
135
                <div class="col-sm-8">
136
                    {icon}
137
                    {element}
138
139
                    <!-- BEGIN label_2 -->
140
                        <p class="help-block">{label_2}</p>
141
                    <!-- END label_2 -->
142
143
                    <!-- BEGIN error -->
144
                        <span class="help-inline">{error}</span>
145
                    <!-- END error -->
146
                </div>
147
                <div class="col-sm-2">
148
                    <!-- BEGIN label_3 -->
149
                        {label_3}
150
                    <!-- END label_3 -->
151
                </div>
152
            </div>';
153
    }
154
155
    /**
156
     * @return string
157
     */
158
    public function getLayout()
159
    {
160
        return $this->layout;
161
    }
162
163
    /**
164
     * @param string $layout
165
     */
166
    public function setLayout($layout)
167
    {
168
        $this->layout = $layout;
169
    }
170
171
    /**
172
     * Adds a text field to the form.
173
     * A trim-filter is attached to the field.
174
     * @param string $label					The label for the form-element
175
     * @param string $name					The element name
176
     * @param bool   $required	(optional)	Is the form-element required (default=true)
177
     * @param array  $attributes (optional)	List of attributes for the form-element
178
     */
179
    public function addText($name, $label, $required = true, $attributes = array())
180
    {
181
        $this->addElement('text', $name, $label, $attributes);
182
        $this->applyFilter($name, 'trim');
183
        if ($required) {
184
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
185
        }
186
    }
187
188
    /**
189
     * The "date_range_picker" element creates 2 hidden fields
190
     * "elementName" + "_start"  and "elementName" + "_end"
191
     * For example if the name is "range", you will have 2 new fields
192
     * when executing $form->getSubmitValues()
193
     * "range_start" and "range_end"
194
     *
195
     * @param string $name
196
     * @param string $label
197
     * @param bool   $required
198
     * @param array  $attributes
199
     */
200 View Code Duplication
    public function addDateRangePicker($name, $label, $required = true, $attributes = array())
201
    {
202
        $this->addElement('date_range_picker', $name, $label, $attributes);
203
        $this->addElement('hidden', $name.'_start');
204
        $this->addElement('hidden', $name.'_end');
205
206
        if ($required) {
207
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
208
        }
209
    }
210
211
    /**
212
     * @param string $name
213
     * @param string $label
214
     * @param array $attributes
215
     *
216
     * @return mixed
217
     */
218
    public function addDatePicker($name, $label, $attributes = [])
219
    {
220
        return $this->addElement('DatePicker', $name, $label, $attributes);
221
    }
222
223
    /**
224
     * @param string $name
225
     * @param string $label
226
     * @param array $attributes
227
     *
228
     * @return mixed
229
     */
230
    public function addDateTimePicker($name, $label, $attributes = [])
231
    {
232
        return $this->addElement('DateTimePicker', $name, $label, $attributes);
233
    }
234
235
    /**
236
     * @param string $name
237
     * @param string $value
238
     */
239
    public function addHidden($name, $value)
240
    {
241
        $this->addElement('hidden', $name, $value);
242
    }
243
244
    /**
245
     * @param string $name
246
     * @param string $label
247
     * @param array  $attributes
248
     *
249
     * @return HTML_QuickForm_textarea
250
     */
251
    public function addTextarea($name, $label, $attributes = array())
252
    {
253
        return $this->addElement('textarea', $name, $label, $attributes);
254
    }
255
256
    /**
257
     * @param string $name
258
     * @param string $label
259
     * @param string $icon font-awesome
260
     * @param string $style default|primary|success|info|warning|danger|link
261
     * @param string $size large|default|small|extra-small
262
     * @param string $class Example plus is transformed to icon fa fa-plus
263
     * @param array  $attributes
264
     *
265
     * @return HTML_QuickForm_button
266
     */
267
    public function addButton(
268
        $name,
269
        $label,
270
        $icon = 'check',
271
        $style = 'default',
272
        $size = 'default',
273
        $class = null,
274
        $attributes = array(),
275
        $createElement = false
276
    ) {
277
        if ($createElement) {
278
            return $this->createElement(
279
                'button',
280
                $name,
281
                $label,
282
                $icon,
283
                $style,
284
                $size,
285
                $class,
286
                $attributes
287
            );
288
        }
289
290
        return $this->addElement(
291
            'button',
292
            $name,
293
            $label,
294
            $icon,
295
            $style,
296
            $size,
297
            $class,
298
            $attributes
299
        );
300
    }
301
302
    /**
303
     * Returns a button with the primary color and a check mark
304
     * @param string $label Text appearing on the button
305
     * @param string $name Element name (for form treatment purposes)
306
     * @param bool $createElement Whether to use the create or add method
307
     *
308
     * @return HTML_QuickForm_button
309
     */
310
    public function addButtonSave($label, $name = 'submit', $createElement = false)
311
    {
312
        return $this->addButton(
313
            $name,
314
            $label,
315
            'check',
316
            'primary',
317
            null,
318
            null,
319
            array(),
320
            $createElement
321
        );
322
    }
323
324
    /**
325
     * Returns a cancel button
326
     * @param string $label Text appearing on the button
327
     * @param string $name Element name (for form treatment purposes)
328
     * @param bool $createElement Whether to use the create or add method
329
     *
330
     * @return HTML_QuickForm_button
331
     */
332
    public function addButtonCancel($label, $name = 'submit', $createElement = false)
333
    {
334
        return $this->addButton(
335
            $name,
336
            $label,
337
            'times',
338
            'danger',
339
            null,
340
            null,
341
            array(),
342
            $createElement
343
        );
344
    }
345
346
    /**
347
     * Returns a button with the primary color and a "plus" icon
348
     * @param string $label Text appearing on the button
349
     * @param string $name Element name (for form treatment purposes)
350
     * @param bool $createElement Whether to use the create or add method
351
     * @param array $attributes Additional attributes
352
     *
353
     * @return HTML_QuickForm_button
354
     */
355
    public function addButtonCreate($label, $name = 'submit', $createElement = false, $attributes = array())
356
    {
357
        return $this->addButton(
358
            $name,
359
            $label,
360
            'plus',
361
            'primary',
362
            null,
363
            null,
364
            $attributes,
365
            $createElement
366
        );
367
    }
368
369
    /**
370
     * Returns a button with the primary color and a pencil icon
371
     * @param string $label Text appearing on the button
372
     * @param string $name Element name (for form treatment purposes)
373
     * @param bool $createElement Whether to use the create or add method
374
     * @return HTML_QuickForm_button
375
     */
376
    public function addButtonUpdate($label, $name = 'submit', $createElement = false)
377
    {
378
        return $this->addButton(
379
            $name,
380
            $label,
381
            'pencil',
382
            'primary',
383
            null,
384
            null,
385
            array(),
386
            $createElement
387
        );
388
    }
389
390
    /**
391
     * Returns a button with the danger color and a trash icon
392
     * @param string $label Text appearing on the button
393
     * @param string $name Element name (for form treatment purposes)
394
     * @param bool $createElement Whether to use the create or add method
395
     *
396
     * @return HTML_QuickForm_button
397
     */
398
    public function addButtonDelete($label, $name = 'submit', $createElement = false)
399
    {
400
        return $this->addButton(
401
            $name,
402
            $label,
403
            'trash',
404
            'danger',
405
            null,
406
            null,
407
            array(),
408
            $createElement
409
        );
410
    }
411
412
    /**
413
     * Returns a button with the primary color and a paper-plane icon
414
     * @param string $label Text appearing on the button
415
     * @param string $name Element name (for form treatment purposes)
416
     * @param bool $createElement Whether to use the create or add method
417
     *
418
     * @return HTML_QuickForm_button
419
     */
420
    public function addButtonSend($label, $name = 'submit', $createElement = false, $attributes = array())
421
    {
422
        return $this->addButton(
423
            $name,
424
            $label,
425
            'paper-plane',
426
            'primary',
427
            null,
428
            null,
429
            $attributes,
430
            $createElement
431
        );
432
    }
433
434
    /**
435
     * Returns a button with the default (grey?) color and a magnifier icon
436
     * @param string $label Text appearing on the button
437
     * @param string $name Element name (for form treatment purposes)
438
     *
439
     * @return HTML_QuickForm_button
440
     */
441
    public function addButtonSearch($label = null, $name = 'submit')
442
    {
443
        if (empty($label)) {
444
            $label = get_lang('Search');
445
        }
446
447
        return $this->addButton($name, $label, 'search', 'default');
448
    }
449
450
    /**
451
     * Returns a button with the primary color and a right-pointing arrow icon
452
     * @param string $label Text appearing on the button
453
     * @param string $name Element name (for form treatment purposes)
454
     * @param array $attributes Additional attributes
455
     * @return HTML_QuickForm_button
456
     */
457
    public function addButtonNext($label, $name = 'submit', $attributes = array())
458
    {
459
        return $this->addButton($name, $label, 'arrow-right', 'primary', null, null, $attributes);
460
    }
461
462
    /**
463
     * Returns a button with the primary color and a check mark icon
464
     * @param string $label Text appearing on the button
465
     * @param string $name Element name (for form treatment purposes)
466
     * @param bool $createElement Whether to use the create or add method
467
     * @return HTML_QuickForm_button
468
     */
469
    public function addButtonImport($label, $name = 'submit', $createElement = false)
470
    {
471
        return $this->addButton(
472
            $name,
473
            $label,
474
            'check',
475
            'primary',
476
            null,
477
            null,
478
            array(),
479
            $createElement
480
        );
481
    }
482
483
    /**
484
     * Returns a button with the primary color and a check-mark icon
485
     * @param string $label Text appearing on the button
486
     * @param string $name Element name (for form treatment purposes)
487
     * @param bool $createElement Whether to use the create or add method
488
     * @return HTML_QuickForm_button
489
     */
490
    public function addButtonExport($label, $name = 'submit', $createElement = false)
491
    {
492
        return $this->addButton(
493
            $name,
494
            $label,
495
            'check',
496
            'primary',
497
            null,
498
            null,
499
            array(),
500
            $createElement
501
        );
502
    }
503
504
    /**
505
     * Shortcut to filter button
506
     * @param string $label Text appearing on the button
507
     * @param string $name Element name (for form treatment purposes)
508
     * @param bool $createElement Whether to use the create or add method
509
     * @return HTML_QuickForm_button
510
     */
511
    public function addButtonFilter($label, $name = 'submit', $createElement = false)
512
    {
513
        return $this->addButton(
514
            $name,
515
            $label,
516
            'filter',
517
            'primary',
518
            null,
519
            null,
520
            array(),
521
            $createElement
522
        );
523
    }
524
525
    /**
526
     * Shortcut to reset button
527
     * @param string $label Text appearing on the button
528
     * @param string $name Element name (for form treatment purposes)
529
     * @param bool $createElement Whether to use the create or add method
530
     * @return HTML_QuickForm_button
531
     */
532
    public function addButtonReset($label, $name = 'reset', $createElement = false)
533
    {
534
        $icon = 'eraser';
535
        $style = 'default';
536
        $size = 'default';
537
        $class = null;
538
        $attributes = array();
539
540
        if ($createElement) {
541
            return $this->createElement(
542
                'reset',
543
                $name,
544
                $label,
545
                $icon,
546
                $style,
547
                $size,
548
                $class,
549
                $attributes
550
            );
551
        }
552
553
        return $this->addElement(
554
            'reset',
555
            $name,
556
            $label,
557
            $icon,
558
            $style,
559
            $size,
560
            $class,
561
            $attributes
562
        );
563
    }
564
565
    /**
566
     * Returns a button with the primary color and an upload icon
567
     * @param string $label Text appearing on the button
568
     * @param string $name Element name (for form treatment purposes)
569
     * @param bool $createElement Whether to use the create or add method
570
     *
571
     * @return HTML_QuickForm_button
572
     */
573
    public function addButtonUpload($label, $name = 'submit', $createElement = false)
574
    {
575
        return $this->addButton(
576
            $name,
577
            $label,
578
            'upload',
579
            'primary',
580
            null,
581
            null,
582
            array(),
583
            $createElement
584
        );
585
    }
586
587
    /**
588
     * Returns a button with the primary color and a download icon
589
     * @param string $label Text appearing on the button
590
     * @param string $name Element name (for form treatment purposes)
591
     * @param bool $createElement Whether to use the create or add method
592
     *
593
     * @return HTML_QuickForm_button
594
     */
595
    public function addButtonDownload($label, $name = 'submit', $createElement = false)
596
    {
597
        return $this->addButton(
598
            $name,
599
            $label,
600
            'download',
601
            'primary',
602
            null,
603
            null,
604
            array(),
605
            $createElement
606
        );
607
    }
608
609
    /**
610
     * Returns a button with the primary color and a magnifier icon
611
     * @param string $label Text appearing on the button
612
     * @param string $name Element name (for form treatment purposes)
613
     * @param bool $createElement Whether to use the create or add method
614
     *
615
     * @return HTML_QuickForm_button
616
     */
617 View Code Duplication
    public function addButtonPreview($label, $name = 'submit', $createElement = false)
618
    {
619
        return $this->addButton(
620
            $name,
621
            $label,
622
            'search',
623
            'primary',
624
            null,
625
            null,
626
            array(),
627
            $createElement
628
        );
629
    }
630
631
    /**
632
     * Returns a button with the primary color and a copy (double sheet) icon
633
     * @param string $label Text appearing on the button
634
     * @param string $name Element name (for form treatment purposes)
635
     * @param bool $createElement Whether to use the create or add method
636
     *
637
     * @return HTML_QuickForm_button
638
     */
639 View Code Duplication
    public function addButtonCopy($label, $name = 'submit', $createElement = false)
640
    {
641
        return $this->addButton(
642
            $name,
643
            $label,
644
            'copy',
645
            'primary',
646
            null,
647
            null,
648
            array(),
649
            $createElement
650
        );
651
    }
652
653
    /**
654
     * @param string $name
655
     * @param string $label
656
     * @param string $text
657
     * @param array  $attributes
658
     *
659
     * @return HTML_QuickForm_checkbox
660
     */
661
    public function addCheckBox($name, $label, $text = '', $attributes = array())
662
    {
663
        return $this->addElement('checkbox', $name, $label, $text, $attributes);
664
    }
665
666
    /**
667
     * @param string $name
668
     * @param string $label
669
     * @param array  $options
670
     * @param array  $attributes
671
     *
672
     * @return HTML_QuickForm_group
673
     */
674 View Code Duplication
    public function addCheckBoxGroup($name, $label, $options = array(), $attributes = array())
675
    {
676
        $group = array();
677
        foreach ($options as $value => $text) {
678
            $attributes['value'] = $value;
679
            $group[] = $this->createElement('checkbox', $value, null, $text, $attributes);
680
        }
681
682
        return $this->addGroup($group, $name, $label);
683
    }
684
685
    /**
686
     * @param string $name
687
     * @param string $label
688
     * @param array  $options
689
     * @param array  $attributes
690
     *
691
     * @return HTML_QuickForm_radio
692
     */
693 View Code Duplication
    public function addRadio($name, $label, $options = array(), $attributes = array())
694
    {
695
        $group = array();
696
        foreach ($options as $key => $value) {
697
            $group[] = $this->createElement('radio', null, null, $value, $key, $attributes);
698
        }
699
700
        return $this->addGroup($group, $name, $label);
701
    }
702
703
    /**
704
     * @param string $name
705
     * @param string $label
706
     * @param array  $options
707
     * @param array  $attributes
708
     *
709
     * @return HTML_QuickForm_select
710
     */
711
    public function addSelect($name, $label, $options = array(), $attributes = array())
712
    {
713
        return $this->addElement('select', $name, $label, $options, $attributes);
714
    }
715
716
    /**
717
     * @param $name
718
     * @param $label
719
     * @param $collection
720
     * @param array $attributes
721
     * @param bool $addNoneOption
722
     * @param string $textCallable set a function getStringValue() by default __toString()
723
     *
724
     * @return HTML_QuickForm_element
725
     */
726
    public function addSelectFromCollection(
727
        $name,
728
        $label,
729
        $collection,
730
        $attributes = array(),
731
        $addNoneOption = false,
732
        $textCallable = ''
733
    ) {
734
        $options = [];
735
736
        if ($addNoneOption) {
737
            $options[0] = get_lang('None');
738
        }
739
740
        if (!empty($collection)) {
741
            foreach ($collection as $item) {
742
                $text = $item;
743
                if (!empty($textCallable)) {
744
                    $text = $item->$textCallable();
745
                }
746
                $options[$item->getId()] = $text;
747
            }
748
        }
749
        return $this->addElement('select', $name, $label, $options, $attributes);
750
    }
751
752
    /**
753
     * @param string $label
754
     * @param string $text
755
     *
756
     * @return HTML_QuickForm_label
757
     */
758
    public function addLabel($label, $text)
759
    {
760
        return $this->addElement('label', $label, $text);
761
    }
762
763
    /**
764
     * @param string $text
765
     */
766
    public function addHeader($text)
767
    {
768
        $this->addElement('header', $text);
769
    }
770
771
    /**
772
     * @param string $name
773
     * @param string $label
774
     * @param array  $attributes
775
     */
776
    public function addFile($name, $label, $attributes = array())
777
    {
778
        $this->addElement('file', $name, $label, $attributes);
779
    }
780
781
    /**
782
     * @param string $snippet
783
     */
784
    public function addHtml($snippet)
785
    {
786
        $this->addElement('html', $snippet);
787
    }
788
789
    /**
790
     * Adds a HTML-editor to the form
791
     * @param string $name
792
     * @param string $label The label for the form-element
793
     * @param bool   $required (optional) Is the form-element required (default=true)
794
     * @param bool   $fullPage (optional) When it is true, the editor loads completed html code for a full page.
795
     * @param array  $config (optional) Configuration settings for the online editor.
796
     * @param bool   $style
797
     */
798
    public function addHtmlEditor($name, $label, $required = true, $fullPage = false, $config = array(), $style = false)
799
    {
800
        $config['rows'] = isset($config['rows']) ? $config['rows'] : 15;
801
        $config['cols'] = isset($config['cols']) ? $config['cols'] : 80;
802
        $this->addElement('html_editor', $name, $label, $config, $style);
803
        $this->applyFilter($name, 'trim');
804
        if ($required) {
805
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
806
        }
807
808
        /** @var HtmlEditor $element */
809
        $element = $this->getElement($name);
810
        if ($style) {
811
            $config['style'] = true;
812
        }
813
        if ($fullPage) {
814
            $config['fullPage'] = true;
815
        }
816
817
        if ($element->editor) {
818
            $element->editor->processConfig($config);
819
        }
820
    }
821
822
    /**
823
     * @param string $name
824
     * @param string $label
825
     *
826
     * @return mixed
827
     */
828
    public function addButtonAdvancedSettings($name, $label = '')
829
    {
830
        $label = !empty($label) ? $label : get_lang('AdvancedParameters');
831
832
        return $this->addElement('advanced_settings', $name, $label);
833
    }
834
835
    /**
836
     * Adds a progress bar to the form.
837
     *
838
     * Once the user submits the form, a progress bar (animated gif) is
839
     * displayed. The progress bar will disappear once the page has been
840
     * reloaded.
841
     *
842
     * @param int $delay (optional)	 The number of seconds between the moment the user
843
     * @param string $label (optional)	Custom label to be shown
844
     *
845
     * submits the form and the start of the progress bar.
846
     * @deprecated ?
847
     */
848
    public function add_progress_bar($delay = 2, $label = '')
849
    {
850
        if (empty($label)) {
851
            $label = get_lang('PleaseStandBy');
852
        }
853
        $this->with_progress_bar = true;
854
        $this->updateAttributes("onsubmit=\"javascript: myUpload.start('dynamic_div','".Display::returnIconPath('progress_bar.gif')."','" . $label . "','" . $this->getAttribute('id') . "')\"");
855
        $this->addElement('html', '<script language="javascript" src="' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/upload.js" type="text/javascript"></script>');
856
        $this->addElement('html', '<script type="text/javascript">var myUpload = new upload(' . (abs(intval($delay)) * 1000) . ');</script>');
857
    }
858
859
    /**
860
     * Uses new functions (php 5.2) for displaying real upload progress.
861
     * @param string $upload_id							The value of the field UPLOAD_IDENTIFIER, the second parameter (XXX) of the $form->addElement('file', XXX) sentence
862
     * @param string $element_after						The first element of the form (to place at first UPLOAD_IDENTIFIER)
863
     * @param int $delay (optional)						The frequency of the xajax call
864
     * @param bool $wait_after_upload (optional)
865
     */
866
    public function add_real_progress_bar($upload_id, $element_after, $delay = 2, $wait_after_upload = false)
867
    {
868
        if (!function_exists('uploadprogress_get_info')) {
869
            $this->add_progress_bar($delay);
0 ignored issues
show
Deprecated Code introduced by
The method FormValidator::add_progress_bar() has been deprecated with message: ?

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
870
            return;
871
        }
872
873
        $xajax_upload = new xajax(api_get_path(WEB_LIBRARY_PATH) . 'upload.xajax.php');
874
875
        $xajax_upload->registerFunction('updateProgress');
876
        // IMPORTANT : must be the first element of the form
877
        $el = $this->insertElementBefore(FormValidator::createElement('html', '<input type="hidden" name="UPLOAD_IDENTIFIER" value="' . $upload_id . '" />'), $element_after);
878
879
        $this->addElement('html', '<br />');
880
881
        // Add div-element where the progress bar is to be displayed
882
        $this->addElement(
883
            'html',
884
            '<div id="dynamic_div_container" style="display:none">
885
                <div id="dynamic_div_label">' . get_lang('UploadFile') . '</div>
886
                <div id="dynamic_div_frame" style="width:214px; height:12px; border:1px solid grey; background-image:url(' . Display::returnIconPath('real_upload_frame.gif').');">
887
                    <div id="dynamic_div_filled" style="width:0%;height:100%;background-image:url(' . Display::returnIconPath('real_upload_step.gif').');background-repeat:repeat-x;background-position:center;"></div>
888
                </div>
889
            </div>'
890
        );
891
892
        if ($wait_after_upload) {
893
            $this->addElement('html', '
894
			<div id="dynamic_div_waiter_container" style="display:none">
895
				<div id="dynamic_div_waiter_label">
896
					' . get_lang('SlideshowConversion') . '
897
				</div>
898
				<div id="dynamic_div_waiter_frame">
899
					'.Display::return_icon('real_upload_frame.gif').'
900
				</div>
901
			</div>
902
		');
903
        }
904
905
        // Get the xajax code
906
        $this->addElement('html', $xajax_upload->getJavascript(api_get_path(WEB_LIBRARY_PATH) . 'xajax'));
907
908
        // Get the upload code
909
        $this->addElement('html', '<script language="javascript" src="' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/upload.js" type="text/javascript"></script>');
910
        $this->addElement('html', '<script type="text/javascript">var myUpload = new upload(' . (abs(intval($delay)) * 1000) . ');</script>');
911
912
        if (!$wait_after_upload) {
913
            $wait_after_upload = 0;
914
        }
915
916
        // Add the upload event
917
        $this->updateAttributes("onsubmit=\"javascript: myUpload.startRealUpload('dynamic_div','" . $upload_id . "','" . $this->getAttribute('id') . "'," . $wait_after_upload . ")\"");
918
    }
919
920
    /**
921
     * This function has been created for avoiding changes directly within QuickForm class.
922
     * When we use it, the element is threated as 'required' to be dealt during validation.
923
     * @param array $element					The array of elements
0 ignored issues
show
Documentation introduced by
There is no parameter named $element. Did you maybe mean $elements?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
924
     * @param string $message					The message displayed
925
     */
926
    public function add_multiple_required_rule($elements, $message)
927
    {
928
        $this->_required[] = $elements[0];
929
        $this->addRule($elements, $message, 'multiple_required');
930
    }
931
932
    /**
933
     * Displays the form.
934
     * If an element in the form didn't validate, an error message is showed
935
     * asking the user to complete the form.
936
     */
937
    public function display()
938
    {
939
        echo $this->returnForm();
940
    }
941
942
    /**
943
     * Returns the HTML code of the form.
944
     * @return string $return_value HTML code of the form
945
     */
946
    public function returnForm()
947
    {
948
        $error = false;
949
        /** @var HTML_QuickForm_element $element */
950
        foreach ($this->_elements as $element) {
951
            if (!is_null(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...
952
                $error = true;
953
                break;
954
            }
955
        }
956
957
        $returnValue = '';
958
        $js = null;
959
960
        if ($error) {
961
            $returnValue = Display::return_message(
962
                get_lang('FormHasErrorsPleaseComplete'),
963
                'warning'
964
            );
965
        }
966
967
        $returnValue .= $js;
968
        $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...
969
        // Add div-element which is to hold the progress bar
970
        if (isset($this->with_progress_bar) && $this->with_progress_bar) {
971
            $returnValue .= '<div id="dynamic_div" style="display:block; margin-left:40%; margin-top:10px; height:50px;"></div>';
972
        }
973
974
        return $returnValue;
975
    }
976
977
    /**
978
     * Returns the HTML code of the form.
979
     * If an element in the form didn't validate, an error message is showed
980
     * asking the user to complete the form.
981
     *
982
     * @return string $return_value HTML code of the form
983
     *
984
     * @author Patrick Cool <[email protected]>, Ghent University, august 2006
985
     * @author Julio Montoya
986
     * @deprecated use returnForm()
987
     */
988
    public function return_form()
989
    {
990
        return $this->returnForm();
991
    }
992
993
    /**
994
     * Create a form validator based on an array of form data:
995
     *
996
     *         array(
997
     *             'name' => 'zombie_report_parameters',    //optional
998
     *             'method' => 'GET',                       //optional
999
     *             'items' => array(
1000
     *                 array(
1001
     *                     'name' => 'ceiling',
1002
     *                     'label' => 'Ceiling',            //optional
1003
     *                     'type' => 'date',
1004
     *                     'default' => date()              //optional
1005
     *                 ),
1006
     *                 array(
1007
     *                     'name' => 'active_only',
1008
     *                     'label' => 'ActiveOnly',
1009
     *                     'type' => 'checkbox',
1010
     *                     'default' => true
1011
     *                 ),
1012
     *                 array(
1013
     *                     'name' => 'submit_button',
1014
     *                     'type' => 'style_submit_button',
1015
     *                     'value' => get_lang('Search'),
1016
     *                     'attributes' => array('class' => 'search')
1017
     *                 )
1018
     *             )
1019
     *         );
1020
     *
1021
     * @param array $form_data
1022
     * @deprecated use normal FormValidator construct
1023
     *
1024
     * @return FormValidator
1025
     */
1026
    public static function create($form_data)
1027
    {
1028
        if (empty($form_data)) {
1029
            return null;
1030
        }
1031
        $form_name = isset($form_data['name']) ? $form_data['name'] : 'form';
1032
        $form_method = isset($form_data['method']) ? $form_data['method'] : 'POST';
1033
        $form_action = isset($form_data['action']) ? $form_data['action'] : '';
1034
        $form_target = isset($form_data['target']) ? $form_data['target'] : '';
1035
        $form_attributes = isset($form_data['attributes']) ? $form_data['attributes'] : null;
1036
        $form_track_submit = isset($form_data['track_submit']) ? $form_data['track_submit'] : true;
1037
        $reset = null;
1038
        $result = new FormValidator($form_name, $form_method, $form_action, $form_target, $form_attributes, $form_track_submit);
1039
1040
        $defaults = array();
1041
        foreach ($form_data['items'] as $item) {
1042
            $name = $item['name'];
1043
            $type = isset($item['type']) ? $item['type'] : 'text';
1044
            $label = isset($item['label']) ? $item['label'] : '';
1045
            if ($type == 'wysiwyg') {
1046
                $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...
1047
            } else {
1048
                $element = $result->addElement($type, $name, $label);
1049
            }
1050
            if (isset($item['attributes'])) {
1051
                $attributes = $item['attributes'];
1052
                $element->setAttributes($attributes);
1053
            }
1054
            if (isset($item['value'])) {
1055
                $value = $item['value'];
1056
                $element->setValue($value);
1057
            }
1058
            if (isset($item['default'])) {
1059
                $defaults[$name] = $item['default'];
1060
            }
1061
            if (isset($item['rules'])) {
1062
                $rules = $item['rules'];
1063
                foreach ($rules as $rule) {
1064
                    $message = $rule['message'];
1065
                    $type = $rule['type'];
1066
                    $format = isset($rule['format']) ? $rule['format'] : null;
1067
                    $validation = isset($rule['validation']) ? $rule['validation'] : 'server';
1068
                    $force = isset($rule['force']) ? $rule['force'] : false;
1069
                    $result->addRule($name, $message, $type, $format, $validation, $reset, $force);
1070
                }
1071
            }
1072
        }
1073
        $result->setDefaults($defaults);
1074
1075
        return $result;
1076
    }
1077
1078
    /**
1079
     * @return HTML_QuickForm_Renderer_Default
1080
     */
1081
    public static function getDefaultRenderer()
1082
    {
1083
        return
1084
            isset($GLOBALS['_HTML_QuickForm_default_renderer']) ?
1085
                $GLOBALS['_HTML_QuickForm_default_renderer'] : null;
1086
    }
1087
1088
    /**
1089
     * Adds a input of type url to the form.
1090
     * @param type $name The label for the form-element
1091
     * @param type $label The element name
1092
     * @param type $required Optional. Is the form-element required (default=true)
1093
     * @param type $attributes Optional. List of attributes for the form-element
1094
     */
1095 View Code Duplication
    public function addUrl($name, $label, $required = true, $attributes = array())
1096
    {
1097
        $this->addElement('url', $name, $label, $attributes);
1098
        $this->applyFilter($name, 'trim');
1099
        $this->addRule($name, get_lang('InsertAValidUrl'), 'url');
1100
1101
        if ($required) {
1102
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1103
        }
1104
    }
1105
1106
    /**
1107
     * Adds a text field for letters to the form.
1108
     * A trim-filter is attached to the field.
1109
     * @param string $name The element name
1110
     * @param string $label The label for the form-element
1111
     * @param bool $required Optional. Is the form-element required (default=true)
1112
     * @param array $attributes Optional. List of attributes for the form-element
1113
     */
1114 View Code Duplication
    public function addTextLettersOnly(
1115
        $name,
1116
        $label,
1117
        $required = false,
1118
        $attributes = []
1119
    ) {
1120
        $attributes = array_merge(
1121
            $attributes,
1122
            [
1123
                'pattern' => '[a-zA-ZñÑ]+',
1124
                'title' => get_lang('OnlyLetters')
1125
            ]
1126
        );
1127
1128
        $this->addElement(
1129
            'text',
1130
            $name,
1131
            [
1132
                $label,
1133
                get_lang('OnlyLetters')
1134
            ],
1135
            $attributes
1136
        );
1137
1138
        $this->applyFilter($name, 'trim');
1139
1140
        if ($required) {
1141
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1142
        }
1143
1144
        $this->addRule(
1145
            $name,
1146
            get_lang('OnlyLetters'),
1147
            'regex',
1148
            '/^[a-zA-ZñÑ]+$/'
1149
        );
1150
    }
1151
1152
    /**
1153
     * Adds a text field for alphanumeric characters to the form.
1154
     * A trim-filter is attached to the field.
1155
     * @param string $name The element name
1156
     * @param string $label The label for the form-element
1157
     * @param bool $required Optional. Is the form-element required (default=true)
1158
     * @param array $attributes Optional. List of attributes for the form-element
1159
     */
1160 View Code Duplication
    public function addTextAlphanumeric(
1161
        $name,
1162
        $label,
1163
        $required = false,
1164
        $attributes = []
1165
    ) {
1166
        $attributes = array_merge(
1167
            $attributes,
1168
            [
1169
                'pattern' => '[a-zA-Z0-9ñÑ]+',
1170
                'title' => get_lang('OnlyLettersAndNumbers')
1171
            ]
1172
        );
1173
1174
        $this->addElement(
1175
            'text',
1176
            $name,
1177
            [
1178
                $label,
1179
                get_lang('OnlyLettersAndNumbers')
1180
            ],
1181
            $attributes
1182
        );
1183
1184
        $this->applyFilter($name, 'trim');
1185
1186
        if ($required) {
1187
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1188
        }
1189
1190
        $this->addRule(
1191
            $name,
1192
            get_lang('OnlyLettersAndNumbers'),
1193
            'regex',
1194
            '/^[a-zA-Z0-9ÑÑ]+$/'
1195
        );
1196
    }
1197
1198
    /**
1199
     * Adds a text field for letters and spaces to the form.
1200
     * A trim-filter is attached to the field.
1201
     * @param string $name The element name
1202
     * @param string $label The label for the form-element
1203
     * @param bool $required Optional. Is the form-element required (default=true)
1204
     * @param array $attributes Optional. List of attributes for the form-element
1205
     */
1206 View Code Duplication
    public function addTextLettersAndSpaces(
1207
        $name,
1208
        $label,
1209
        $required = false,
1210
        $attributes = []
1211
    ) {
1212
        $attributes = array_merge(
1213
            $attributes,
1214
            [
1215
                'pattern' => '[a-zA-ZñÑ\s]+',
1216
                'title' => get_lang('OnlyLettersAndSpaces')
1217
            ]
1218
        );
1219
1220
        $this->addElement(
1221
            'text',
1222
            $name,
1223
            [
1224
                $label,
1225
                get_lang('OnlyLettersAndSpaces')
1226
            ],
1227
            $attributes
1228
        );
1229
1230
        $this->applyFilter($name, 'trim');
1231
1232
        if ($required) {
1233
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1234
        }
1235
1236
        $this->addRule(
1237
            $name,
1238
            get_lang('OnlyLettersAndSpaces'),
1239
            'regex',
1240
            '/^[a-zA-ZñÑ\s]+$/'
1241
        );
1242
    }
1243
1244
    /**
1245
     * Adds a text field for alphanumeric and spaces characters to the form.
1246
     * A trim-filter is attached to the field.
1247
     * @param string $name The element name
1248
     * @param string $label The label for the form-element
1249
     * @param bool $required Optional. Is the form-element required (default=true)
1250
     * @param array $attributes Optional. List of attributes for the form-element
1251
     */
1252 View Code Duplication
    public function addTextAlphanumericAndSpaces(
1253
        $name,
1254
        $label,
1255
        $required = false,
1256
        $attributes = []
1257
    ) {
1258
        $attributes = array_merge(
1259
            $attributes,
1260
            [
1261
                'pattern' => '[a-zA-Z0-9ñÑ\s]+',
1262
                'title' => get_lang('OnlyLettersAndNumbersAndSpaces')
1263
            ]
1264
        );
1265
1266
        $this->addElement(
1267
            'text',
1268
            $name,
1269
            [
1270
                $label,
1271
                get_lang('OnlyLettersAndNumbersAndSpaces')
1272
            ],
1273
            $attributes
1274
        );
1275
1276
        $this->applyFilter($name, 'trim');
1277
1278
        if ($required) {
1279
            $this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
1280
        }
1281
1282
        $this->addRule(
1283
            $name,
1284
            get_lang('OnlyLettersAndNumbersAndSpaces'),
1285
            'regex',
1286
            '/^[a-zA-Z0-9ñÑ\s]+$/'
1287
        );
1288
    }
1289
1290
    /**
1291
     * @param string $url
1292
     */
1293
    public function addMultipleUpload($url)
1294
    {
1295
        $inputName = 'input_file_upload';
1296
        $this->addMultipleUploadJavascript($url, $inputName);
1297
1298
        $this->addHtml('
1299
            <div class="description-upload">'.get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'</div>
1300
            <span class="btn btn-success fileinput-button">
1301
                <i class="glyphicon glyphicon-plus"></i>
1302
                <span>'.get_lang('AddFiles').'</span>
1303
                <!-- The file input field used as target for the file upload widget -->
1304
                <input id="'.$inputName.'" type="file" name="files[]" multiple>
1305
            </span>
1306
            <br />
1307
            <br />
1308
            <div id="dropzone">
1309
                <div class="button-load">
1310
                '.get_lang('UploadFiles').'
1311
                </div>
1312
            </div>
1313
1314
            <br />
1315
            <!-- The global progress bar -->
1316
            <div id="progress" class="progress">
1317
                <div class="progress-bar progress-bar-success"></div>
1318
            </div>
1319
            <div id="files" class="files"></div>
1320
        ');
1321
    }
1322
1323
    /**
1324
     *
1325
     * @param string $url page that will handle the upload
1326
     * @param string $inputName
1327
     */
1328
    private function addMultipleUploadJavascript($url, $inputName)
1329
    {
1330
        $this->addHtml("
1331
        <script>
1332
        $(function () {
1333
            'use strict';
1334
1335
            $('#".$this->getAttribute('id')."').submit(function(){
1336
                return false;
1337
            });
1338
1339
            $('#dropzone').on('click', function() {
1340
                $('#".$inputName."').click();
1341
            });
1342
1343
            var url = '".$url."';
1344
            var uploadButton = $('<button/>')
1345
                .addClass('btn btn-primary')
1346
                .prop('disabled', true)
1347
                .text('".get_lang('Loading')."')
1348
                .on('click', function () {
1349
                    var \$this = $(this),
1350
                    data = \$this.data();
1351
1352
                    \$this
1353
                        .off('click')
1354
                        .text('".get_lang('Cancel')."')
1355
                        .on('click', function () {
1356
                            \$this.remove();
1357
                            data.abort();
1358
                        });
1359
                    data.submit().always(function () {
1360
                        \$this.remove();
1361
                    });
1362
                });
1363
1364
            $('#".$inputName."').fileupload({
1365
                url: url,
1366
                dataType: 'json',
1367
                autoUpload: true,
1368
                // Enable image resizing, except for Android and Opera,
1369
                // which actually support image resizing, but fail to
1370
                // send Blob objects via XHR requests:
1371
                disableImageResize: /Android(?!.*Chrome)|Opera/.test(window.navigator.userAgent),
1372
                previewMaxWidth: 100,
1373
                previewMaxHeight: 100,
1374
                previewCrop: true,
1375
                dropzone: $('#dropzone')
1376
             }).on('fileuploadadd', function (e, data) {
1377
                data.context = $('<div/>').appendTo('#files');
1378
                $.each(data.files, function (index, file) {
1379
                    var node = $('<p/>').append($('<span/>').text(file.name));
1380
                    /*if (!index) {
1381
                        node
1382
                            .append('<br>')
1383
                            .append(uploadButton.clone(true).data(data));
1384
                    }*/
1385
                    node.appendTo(data.context);
1386
                }
1387
            );
1388
            }).on('fileuploadprocessalways', function (e, data) {
1389
                var index = data.index,
1390
                    file = data.files[index],
1391
                    node = $(data.context.children()[index]);
1392
                if (file.preview) {
1393
                    node
1394
                        .prepend('<br>')
1395
                        .prepend(file.preview);
1396
                }
1397
                if (file.error) {
1398
                    node
1399
                        .append('<br>')
1400
                        .append($('<span class=\"text-danger\"/>').text(file.error));
1401
                }
1402
                if (index + 1 === data.files.length) {
1403
                    data.context.find('button')
1404
                        .text('Upload')
1405
                        .prop('disabled', !!data.files.error);
1406
                }
1407
            }).on('fileuploadprogressall', function (e, data) {
1408
                var progress = parseInt(data.loaded / data.total * 100, 10);
1409
                $('#progress .progress-bar').css(
1410
                    'width',
1411
                    progress + '%'
1412
                );
1413
            }).on('fileuploaddone', function (e, data) {
1414
1415
                $.each(data.result.files, function (index, file) {
1416
                    if (file.url) {
1417
                        var link = $('<a>')
1418
                            .attr('target', '_blank')
1419
                            .prop('href', file.url);
1420
1421
                        $(data.context.children()[index]).wrap(link);
1422
                    } else if (file.error) {
1423
                        var error = $('<span class=\"text-danger\"/>').text(file.error);
1424
                        $(data.context.children()[index])
1425
                            .append('<br>')
1426
                            .append(error);
1427
                    }
1428
                });
1429
            }).on('fileuploadfail', function (e, data) {
1430
                $.each(data.files, function (index) {
1431
                    var error = $('<span class=\"text-danger\"/>').text('".get_lang('Failed')."');
1432
                    $(data.context.children()[index])
1433
                        .append('<br>')
1434
                        .append(error);
1435
                });
1436
            }).prop('disabled', !$.support.fileInput)
1437
                .parent().addClass($.support.fileInput ? undefined : 'disabled');
1438
1439
            $('.fileinput-button').hide();
1440
1441
        });
1442
        </script>"
1443
        );
1444
    }
1445
}
1446
1447
/**
1448
 * Cleans HTML text filter
1449
 * @param string $html			HTML to clean
1450
 * @param int $mode (optional)
1451
 * @return string				The cleaned HTML
1452
 */
1453
function html_filter($html, $mode = NO_HTML)
1454
{
1455
    $allowed_tags = HTML_QuickForm_Rule_HTML::get_allowed_tags($mode);
1456
    $cleaned_html = kses($html, $allowed_tags);
1457
    return $cleaned_html;
1458
}
1459
1460
function html_filter_teacher($html)
1461
{
1462
    return html_filter($html, TEACHER_HTML);
1463
}
1464
1465
function html_filter_student($html)
1466
{
1467
    return html_filter($html, STUDENT_HTML);
1468
}
1469
1470
function html_filter_teacher_fullpage($html)
1471
{
1472
    return html_filter($html, TEACHER_HTML_FULLPAGE);
1473
}
1474
1475
function html_filter_student_fullpage($html)
1476
{
1477
    return html_filter($html, STUDENT_HTML_FULLPAGE);
1478
}
1479
1480
/**
1481
 * Cleans mobile phone number text
1482
 * @param string $mobilePhoneNumber     Mobile phone number to clean
1483
 * @return string                       The cleaned mobile phone number
1484
 */
1485
function mobile_phone_number_filter($mobilePhoneNumber)
1486
{
1487
    $mobilePhoneNumber = str_replace(array('+', '(', ')'), '', $mobilePhoneNumber);
1488
1489
    return ltrim($mobilePhoneNumber, '0');
1490
}
1491