Completed
Push — master ( 27e209...a08afa )
by Julito
186:04 queued 150:53
created

ExtraField::tripleSelectConvertStringToArray()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 32
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 15
nc 4
nop 1
dl 0
loc 32
rs 8.439
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField;
5
use Chamilo\CoreBundle\Entity\ExtraFieldRelTag;
6
use Chamilo\CoreBundle\Entity\Tag;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Tag. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
8
/**
9
 * Class ExtraField
10
 */
11
class ExtraField extends Model
12
{
13
    public $columns = [
14
        'id',
15
        'field_type',
16
        'variable',
17
        'display_text',
18
        'default_value',
19
        'field_order',
20
        'visible_to_self',
21
        'visible_to_others',
22
        'changeable',
23
        'filter',
24
        'extra_field_type',
25
        //Enable this when field_loggeable is introduced as a table field (2.0)
26
        //'field_loggeable',
27
        'created_at'
28
    ];
29
30
    public $ops = [
31
        'eq' => '=', //equal
32
        'ne' => '<>', //not equal
33
        'lt' => '<', //less than
34
        'le' => '<=', //less than or equal
35
        'gt' => '>', //greater than
36
        'ge' => '>=', //greater than or equal
37
        'bw' => 'LIKE', //begins with
38
        'bn' => 'NOT LIKE', //doesn't begin with
39
        'in' => 'LIKE', //is in
40
        'ni' => 'NOT LIKE', //is not in
41
        'ew' => 'LIKE', //ends with
42
        'en' => 'NOT LIKE', //doesn't end with
43
        'cn' => 'LIKE', //contains
44
        'nc' => 'NOT LIKE'  //doesn't contain
45
    ];
46
47
    const FIELD_TYPE_TEXT = 1;
48
    const FIELD_TYPE_TEXTAREA = 2;
49
    const FIELD_TYPE_RADIO = 3;
50
    const FIELD_TYPE_SELECT = 4;
51
    const FIELD_TYPE_SELECT_MULTIPLE = 5;
52
    const FIELD_TYPE_DATE = 6;
53
    const FIELD_TYPE_DATETIME = 7;
54
    const FIELD_TYPE_DOUBLE_SELECT = 8;
55
    const FIELD_TYPE_DIVIDER = 9;
56
    const FIELD_TYPE_TAG = 10;
57
    const FIELD_TYPE_TIMEZONE = 11;
58
    const FIELD_TYPE_SOCIAL_PROFILE = 12;
59
    const FIELD_TYPE_CHECKBOX = 13;
60
    const FIELD_TYPE_MOBILE_PHONE_NUMBER = 14;
61
    const FIELD_TYPE_INTEGER = 15;
62
    const FIELD_TYPE_FILE_IMAGE = 16;
63
    const FIELD_TYPE_FLOAT = 17;
64
    const FIELD_TYPE_FILE = 18;
65
    const FIELD_TYPE_VIDEO_URL = 19;
66
    const FIELD_TYPE_LETTERS_ONLY = 20;
67
    const FIELD_TYPE_ALPHANUMERIC = 21;
68
    const FIELD_TYPE_LETTERS_SPACE = 22;
69
    const FIELD_TYPE_ALPHANUMERIC_SPACE = 23;
70
    const FIELD_TYPE_GEOLOCALIZATION = 24;
71
    const FIELD_TYPE_GEOLOCALIZATION_COORDINATES = 25;
72
    const FIELD_TYPE_SELECT_WITH_TEXT_FIELD = 26;
73
    const FIELD_TYPE_TRIPLE_SELECT = 27;
74
75
    public $type = 'user';
76
    public $pageName;
77
    public $pageUrl;
78
    public $extraFieldType = 0;
79
80
    public $table_field_options;
81
    public $table_field_values;
82
    public $table_field_tag;
83
    public $table_field_rel_tag;
84
85
    public $handler_id;
86
    public $primaryKey;
87
88
    /**
89
     * @param string $type
90
     */
91
    public function __construct($type)
92
    {
93
        parent::__construct();
94
95
        $this->type = $type;
96
        $this->table = Database::get_main_table(TABLE_EXTRA_FIELD);
97
        $this->table_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
98
        $this->table_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
99
        $this->table_field_tag = Database::get_main_table(TABLE_MAIN_TAG);
100
        $this->table_field_rel_tag = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
101
102
        $this->handler_id = 'item_id';
103
104
        switch ($this->type) {
105
            case 'calendar_event':
106
                $this->extraFieldType = EntityExtraField::CALENDAR_FIELD_TYPE;
107
                break;
108
            case 'course':
109
                $this->extraFieldType = EntityExtraField::COURSE_FIELD_TYPE;
110
                $this->primaryKey = 'id';
111
                break;
112
            case 'user':
113
                $this->extraFieldType = EntityExtraField::USER_FIELD_TYPE;
114
                $this->primaryKey = 'id';
115
                break;
116
            case 'session':
117
                $this->extraFieldType = EntityExtraField::SESSION_FIELD_TYPE;
118
                $this->primaryKey = 'id';
119
                break;
120
            case 'question':
121
                $this->extraFieldType = EntityExtraField::QUESTION_FIELD_TYPE;
122
                break;
123
            case 'lp':
124
                $this->extraFieldType = EntityExtraField::LP_FIELD_TYPE;
125
                break;
126
            case 'lp_item':
127
                $this->extraFieldType = EntityExtraField::LP_ITEM_FIELD_TYPE;
128
                break;
129
            case 'skill':
130
                $this->extraFieldType = EntityExtraField::SKILL_FIELD_TYPE;
131
                break;
132
            case 'work':
133
                $this->extraFieldType = EntityExtraField::WORK_FIELD_TYPE;
134
                break;
135
            case 'career':
136
                $this->extraFieldType = EntityExtraField::CAREER_FIELD_TYPE;
137
                break;
138
            case 'user_certificate':
139
                $this->extraFieldType = EntityExtraField::USER_CERTIFICATE;
140
                break;
141
            case 'survey':
142
                $this->extraFieldType = EntityExtraField::SURVEY_FIELD_TYPE;
143
                break;
144
        }
145
146
        $this->pageUrl = 'extra_fields.php?type='.$this->type;
147
        // Example QuestionFields
148
        $this->pageName = get_lang(ucwords($this->type).'Fields');
149
    }
150
151
    /**
152
     * @return int
153
     */
154
    public function getExtraFieldType()
155
    {
156
        return (int) $this->extraFieldType;
157
    }
158
159
    /**
160
     * @return array
161
     */
162
    public static function getValidExtraFieldTypes()
163
    {
164
        return [
165
            'user',
166
            'course',
167
            'session',
168
            'question',
169
            'lp',
170
            'calendar_event',
171
            'lp_item',
172
            'skill',
173
            'work',
174
            'career',
175
            'user_certificate',
176
            'survey'
177
        ];
178
    }
179
180
    /**
181
     * @return int
182
     */
183
    public function get_count()
184
    {
185
        $em = Database::getManager();
186
        $query = $em->getRepository('ChamiloCoreBundle:ExtraField')->createQueryBuilder('e');
187
        $query->select('count(e.id)');
188
        $query->where('e.extraFieldType = :type');
189
        $query->setParameter('type', $this->getExtraFieldType());
190
191
        return $query->getQuery()->getSingleScalarResult();
192
    }
193
194
    /**
195
     * @param string $sidx
196
     * @param string $sord
197
     * @param int $start
198
     * @param int $limit
199
     *
200
     * @return array
201
     */
202
    public function getAllGrid($sidx, $sord, $start, $limit)
203
    {
204
        switch ($sidx) {
205
            case 'field_order':
206
                $sidx = 'e.fieldOrder';
207
                break;
208
            case 'variable':
209
                $sidx = 'e.variable';
210
                break;
211
            case 'display_text':
212
                $sidx = 'e.displayText';
213
                break;
214
            case 'changeable':
215
                $sidx = 'e.changeable';
216
                break;
217
            case 'visible_to_self':
218
                $sidx = 'e.visibleToSelf';
219
                break;
220
            case 'visible_to_others':
221
                $sidx = 'e.visibleToOthers';
222
                break;
223
            case 'filter':
224
                $sidx = 'e.filter';
225
                break;
226
        }
227
        $em = Database::getManager();
228
        $query = $em->getRepository('ChamiloCoreBundle:ExtraField')->createQueryBuilder('e');
229
        $query->select('e')
230
            ->where('e.extraFieldType = :type')
231
            ->setParameter('type', $this->getExtraFieldType())
232
            ->orderBy($sidx, $sord)
233
            ->setFirstResult($start)
234
            ->setMaxResults($limit);
235
236
        return $query->getQuery()->getArrayResult();
237
    }
238
239
    /**
240
     * @param array $conditions
241
     * @param null $order_field_options_by
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $order_field_options_by is correct as it would always require null to be passed?
Loading history...
242
     *
243
     * @return array
244
     */
245
    public function get_all($conditions = [], $order_field_options_by = null)
246
    {
247
        $conditions = Database::parse_conditions(['where' => $conditions]);
248
249
        if (empty($conditions)) {
250
            $conditions .= " WHERE extra_field_type = ".$this->extraFieldType;
251
        } else {
252
            $conditions .= " AND extra_field_type = ".$this->extraFieldType;
253
        }
254
255
        $sql = "SELECT * FROM $this->table
256
                $conditions
257
                ORDER BY field_order ASC
258
        ";
259
260
        $result = Database::query($sql);
261
        $extraFields = Database::store_result($result, 'ASSOC');
262
263
        $option = new ExtraFieldOption($this->type);
264
        if (!empty($extraFields)) {
265
            foreach ($extraFields as &$extraField) {
266
                $extraField['display_text'] = self::translateDisplayName(
267
                    $extraField['variable'],
268
                    $extraField['display_text']
269
                );
270
                $extraField['options'] = $option->get_field_options_by_field(
271
                    $extraField['id'],
272
                    false,
273
                    $order_field_options_by
274
                );
275
            }
276
        }
277
278
        return $extraFields;
279
    }
280
281
    /**
282
     * @param string $variable
283
     *
284
     * @return array|bool
285
     */
286
    public function get_handler_field_info_by_field_variable($variable)
287
    {
288
        $variable = Database::escape_string($variable);
289
        $sql = "SELECT * FROM {$this->table}
290
                WHERE
291
                    variable = '$variable' AND
292
                    extra_field_type = $this->extraFieldType";
293
        $result = Database::query($sql);
294
        if (Database::num_rows($result)) {
295
            $row = Database::fetch_array($result, 'ASSOC');
296
            $row['display_text'] = self::translateDisplayName(
297
                $row['variable'],
298
                $row['display_text']
299
            );
300
301
            // All the options of the field
302
            $sql = "SELECT * FROM $this->table_field_options
303
                    WHERE field_id='".intval($row['id'])."'
304
                    ORDER BY option_order ASC";
305
            $result = Database::query($sql);
306
            while ($option = Database::fetch_array($result)) {
307
                $row['options'][$option['id']] = $option;
308
            }
309
310
            return $row;
311
        } else {
312
            return false;
313
        }
314
    }
315
316
    /**
317
     * Get all the field info for tags
318
     * @param string $variable
319
     *
320
     * @return array|bool
321
     */
322
    public function get_handler_field_info_by_tags($variable)
323
    {
324
        $variable = Database::escape_string($variable);
325
        $sql = "SELECT * FROM {$this->table}
326
                WHERE
327
                    variable = '$variable' AND
328
                    extra_field_type = $this->extraFieldType";
329
        $result = Database::query($sql);
330
        if (Database::num_rows($result)) {
331
            $row = Database::fetch_array($result, 'ASSOC');
332
            $row['display_text'] = self::translateDisplayName(
333
                $row['variable'],
334
                $row['display_text']
335
            );
336
337
            // All the tags of the field
338
            $sql = "SELECT * FROM $this->table_field_tag
339
                    WHERE field_id='".intval($row['id'])."'
340
                    ORDER BY id ASC";
341
            $result = Database::query($sql);
342
            while ($option = Database::fetch_array($result, 'ASSOC')) {
343
                $row['options'][$option['id']] = $option;
344
            }
345
346
            return $row;
347
        } else {
348
            return false;
349
        }
350
    }
351
352
    /**
353
     * @param int $fieldId
354
     *
355
     * @return array|bool
356
     */
357
    public function getFieldInfoByFieldId($fieldId)
358
    {
359
        $fieldId = intval($fieldId);
360
        $sql = "SELECT * FROM {$this->table}
361
                WHERE
362
                    id = '$fieldId' AND
363
                    extra_field_type = $this->extraFieldType";
364
        $result = Database::query($sql);
365
        if (Database::num_rows($result)) {
366
            $row = Database::fetch_array($result, 'ASSOC');
367
368
            // All the options of the field
369
            $sql = "SELECT * FROM $this->table_field_options
370
                    WHERE field_id='".$fieldId."'
371
                    ORDER BY option_order ASC";
372
            $result = Database::query($sql);
373
            while ($option = Database::fetch_array($result)) {
374
                $row['options'][$option['id']] = $option;
375
            }
376
377
            return $row;
378
        } else {
379
            return false;
380
        }
381
    }
382
383
    /**
384
     * @return int
385
     */
386
    public function get_max_field_order()
387
    {
388
        $sql = "SELECT MAX(field_order)
389
                FROM {$this->table}
390
                WHERE
391
                    extra_field_type = '.$this->extraFieldType.'";
392
        $res = Database::query($sql);
393
394
        $order = 0;
395
        if (Database::num_rows($res) > 0) {
396
            $row = Database::fetch_row($res);
397
            $order = $row[0] + 1;
398
        }
399
400
        return $order;
401
    }
402
403
    /**
404
     * @param string $handler
405
     *
406
     * @return array
407
     */
408
    public static function get_extra_fields_by_handler($handler)
409
    {
410
        $types = [];
411
        $types[self::FIELD_TYPE_TEXT] = get_lang('FieldTypeText');
412
        $types[self::FIELD_TYPE_TEXTAREA] = get_lang('FieldTypeTextarea');
413
        $types[self::FIELD_TYPE_RADIO] = get_lang('FieldTypeRadio');
414
        $types[self::FIELD_TYPE_SELECT] = get_lang('FieldTypeSelect');
415
        $types[self::FIELD_TYPE_SELECT_MULTIPLE] = get_lang('FieldTypeSelectMultiple');
416
        $types[self::FIELD_TYPE_DATE] = get_lang('FieldTypeDate');
417
        $types[self::FIELD_TYPE_DATETIME] = get_lang('FieldTypeDatetime');
418
        $types[self::FIELD_TYPE_DOUBLE_SELECT] = get_lang('FieldTypeDoubleSelect');
419
        $types[self::FIELD_TYPE_DIVIDER] = get_lang('FieldTypeDivider');
420
        $types[self::FIELD_TYPE_TAG] = get_lang('FieldTypeTag');
421
        $types[self::FIELD_TYPE_TIMEZONE] = get_lang('FieldTypeTimezone');
422
        $types[self::FIELD_TYPE_SOCIAL_PROFILE] = get_lang('FieldTypeSocialProfile');
423
        $types[self::FIELD_TYPE_MOBILE_PHONE_NUMBER] = get_lang('FieldTypeMobilePhoneNumber');
424
        $types[self::FIELD_TYPE_CHECKBOX] = get_lang('FieldTypeCheckbox');
425
        $types[self::FIELD_TYPE_INTEGER] = get_lang('FieldTypeInteger');
426
        $types[self::FIELD_TYPE_FILE_IMAGE] = get_lang('FieldTypeFileImage');
427
        $types[self::FIELD_TYPE_FLOAT] = get_lang('FieldTypeFloat');
428
        $types[self::FIELD_TYPE_FILE] = get_lang('FieldTypeFile');
429
        $types[self::FIELD_TYPE_VIDEO_URL] = get_lang('FieldTypeVideoUrl');
430
        $types[self::FIELD_TYPE_LETTERS_ONLY] = get_lang('FieldTypeOnlyLetters');
431
        $types[self::FIELD_TYPE_ALPHANUMERIC] = get_lang('FieldTypeAlphanumeric');
432
        $types[self::FIELD_TYPE_LETTERS_SPACE] = get_lang(
433
            'FieldTypeLettersSpaces'
434
        );
435
        $types[self::FIELD_TYPE_ALPHANUMERIC_SPACE] = get_lang(
436
            'FieldTypeAlphanumericSpaces'
437
        );
438
        $types[self::FIELD_TYPE_GEOLOCALIZATION] = get_lang(
439
            'Geolocalization'
440
        );
441
        $types[self::FIELD_TYPE_GEOLOCALIZATION_COORDINATES] = get_lang(
442
            'GeolocalizationCoordinates'
443
        );
444
        $types[self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD] = get_lang('FieldTypeSelectWithTextField');
445
        $types[self::FIELD_TYPE_TRIPLE_SELECT] = get_lang('FieldTypeTripleSelect');
446
447
        switch ($handler) {
448
            case 'course':
449
            case 'session':
450
            case 'user':
451
            case 'skill':
452
                break;
453
        }
454
455
        return $types;
456
    }
457
458
    /**
459
     * Add elements to a form
460
     *
461
     * @param FormValidator $form
462
     * @param int $itemId
463
     * @param array $exclude variables of extra field to exclude
464
     * @param bool $filter
465
     * @param bool $useTagAsSelect
466
     * @param array $showOnlyTheseFields
467
     * @param array $orderFields
468
     * @param bool $adminPermissions
469
     *
470
     * @return array|bool
471
     */
472
    public function addElements(
473
        $form,
474
        $itemId = 0,
475
        $exclude = [],
476
        $filter = false,
477
        $useTagAsSelect = false,
478
        $showOnlyTheseFields = [],
479
        $orderFields = [],
480
        $adminPermissions = false
481
    ) {
482
        if (empty($form)) {
483
            return false;
484
        }
485
486
        $itemId = (int) $itemId;
487
        $form->addHidden('item_id', $itemId);
488
        $extraData = false;
489
        if (!empty($itemId)) {
490
            $extraData = self::get_handler_extra_data($itemId);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_handler_extra_data() is not static, but was called statically. ( Ignorable by Annotation )

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

490
            /** @scrutinizer ignore-call */ 
491
            $extraData = self::get_handler_extra_data($itemId);
Loading history...
491
492
            if ($form) {
493
                if (!empty($showOnlyTheseFields)) {
494
                    $setData = [];
495
                    foreach ($showOnlyTheseFields as $variable) {
496
                        $extraName = 'extra_'.$variable;
497
                        if (in_array($extraName, array_keys($extraData))) {
498
                            $setData[$extraName] = $extraData[$extraName];
499
                        }
500
                    }
501
                    $form->setDefaults($setData);
502
                } else {
503
                    $form->setDefaults($extraData);
504
                }
505
            }
506
        }
507
508
        $conditions = [];
509
        if ($filter) {
510
            $conditions = ['filter = ?' => 1];
511
        }
512
513
        $extraFields = $this->get_all($conditions, 'option_order');
514
        $extra = $this->set_extra_fields_in_form(
515
            $form,
516
            $extraData,
0 ignored issues
show
Bug introduced by
It seems like $extraData can also be of type false; however, parameter $extraData of ExtraField::set_extra_fields_in_form() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

516
            /** @scrutinizer ignore-type */ $extraData,
Loading history...
517
            $adminPermissions,
518
            $extraFields,
519
            $itemId,
520
            $exclude,
521
            $useTagAsSelect,
522
            $showOnlyTheseFields,
523
            $orderFields
524
        );
525
526
        return $extra;
527
    }
528
529
    /**
530
     * @param int $itemId (session_id, question_id, course id)
531
     *
532
     * @return array
533
     */
534
    public function get_handler_extra_data($itemId)
535
    {
536
        if (empty($itemId)) {
537
            return [];
538
        }
539
540
        $extra_data = [];
541
        $fields = self::get_all();
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_all() is not static, but was called statically. ( Ignorable by Annotation )

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

541
        /** @scrutinizer ignore-call */ 
542
        $fields = self::get_all();
Loading history...
542
        $field_values = new ExtraFieldValue($this->type);
543
544
        if (!empty($fields) > 0) {
545
            foreach ($fields as $field) {
546
                $field_value = $field_values->get_values_by_handler_and_field_id(
547
                    $itemId,
548
                    $field['id']
549
                );
550
551
                if ($field['field_type'] == self::FIELD_TYPE_TAG) {
552
                    $tags = UserManager::get_user_tags_to_string(
553
                        $itemId,
554
                        $field['id'],
555
                        false
556
                    );
557
                    $extra_data['extra_'.$field['variable']] = $tags;
558
559
                    continue;
560
                }
561
562
                if ($field_value) {
563
                    $variable = $field['variable'];
564
                    $field_value = $field_value['value'];
565
                    switch ($field['field_type']) {
566
                        case self::FIELD_TYPE_TAG:
567
                            $tags = UserManager::get_user_tags_to_string(
568
                                $itemId,
569
                                $field['id'],
570
                                false
571
                            );
572
573
                            $extra_data['extra_'.$field['variable']] = $tags;
574
                            break;
575
                        case self::FIELD_TYPE_DOUBLE_SELECT:
576
                        case self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
577
                            $selected_options = explode(
578
                                '::',
579
                                $field_value
580
                            );
581
                            $firstOption = isset($selected_options[0]) ? $selected_options[0] : '';
582
                            $secondOption = isset($selected_options[1]) ? $selected_options[1] : '';
583
                            $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $firstOption;
584
                            $extra_data['extra_'.$field['variable']]['extra_'.$field['variable'].'_second'] = $secondOption;
585
586
                            break;
587
                        case self::FIELD_TYPE_SELECT_MULTIPLE:
588
                            $field_value = explode(';', $field_value);
589
                            $extra_data['extra_'.$field['variable']] = $field_value;
590
                            break;
591
                        case self::FIELD_TYPE_RADIO:
592
                            $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $field_value;
593
                            break;
594
                        case self::FIELD_TYPE_TRIPLE_SELECT:
595
                            list($level1, $level2, $level3) = explode(';', $field_value);
596
597
                            $extra_data["extra_$variable"]["extra_$variable"] = $level1;
598
                            $extra_data["extra_$variable"]["extra_{$variable}_second"] = $level2;
599
                            $extra_data["extra_$variable"]["extra_{$variable}_third"] = $level3;
600
                            break;
601
                        default:
602
                            $extra_data['extra_'.$field['variable']] = $field_value;
603
                            break;
604
                    }
605
                } else {
606
                    // Set default values
607
                    if (isset($field['field_default_value']) &&
608
                        !empty($field['field_default_value'])
609
                    ) {
610
                        $extra_data['extra_'.$field['variable']] = $field['field_default_value'];
611
                    }
612
                }
613
            }
614
        }
615
616
        return $extra_data;
617
    }
618
619
    /**
620
     * @param string $field_type
621
     *
622
     * @return array
623
     */
624
    public function get_all_extra_field_by_type($field_type)
625
    {
626
        // all the information of the field
627
        $sql = "SELECT * FROM {$this->table}
628
                WHERE
629
                    field_type = '".Database::escape_string($field_type)."' AND
630
                    extra_field_type = $this->extraFieldType
631
                ";
632
        $result = Database::query($sql);
633
634
        $return = [];
635
        while ($row = Database::fetch_array($result)) {
636
            $return[] = $row['id'];
637
        }
638
639
        return $return;
640
    }
641
642
    /**
643
     * @return array
644
     */
645
    public function get_field_types()
646
    {
647
        return self::get_extra_fields_by_handler($this->type);
648
    }
649
650
    /**
651
     * @param int $id
652
     *
653
     * @return null
654
     */
655
    public function get_field_type_by_id($id)
656
    {
657
        $types = self::get_field_types();
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_field_types() is not static, but was called statically. ( Ignorable by Annotation )

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

657
        /** @scrutinizer ignore-call */ 
658
        $types = self::get_field_types();
Loading history...
658
        if (isset($types[$id])) {
659
            return $types[$id];
660
        }
661
662
        return null;
663
    }
664
665
    /**
666
     * Converts a string like this:
667
     * France:Paris;Bretagne;Marseille;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura;
668
     * into
669
     * array(
670
     *   'France' =>
671
     *      array('Paris', 'Bretagne', 'Marseille'),
672
     *   'Belgique' =>
673
     *      array('Namur', 'Liège')
674
     * ), etc
675
     * @param string $string
676
     *
677
     * @return array
678
     */
679
    public static function extra_field_double_select_convert_string_to_array($string)
680
    {
681
        $options = explode('|', $string);
682
        $options_parsed = [];
683
        $id = 0;
684
685
        if (!empty($options)) {
686
            foreach ($options as $sub_options) {
687
                $options = explode(':', $sub_options);
688
                $sub_sub_options = isset($options[1]) ? explode(';', $options[1]) : [];
689
                $options_parsed[$id] = [
690
                    'label' => $options[0],
691
                    'options' => $sub_sub_options,
692
                ];
693
                $id++;
694
            }
695
        }
696
697
        return $options_parsed;
698
    }
699
700
    /**
701
     * @param $string
702
     * @return array
703
     */
704
    public static function tripleSelectConvertStringToArray($string)
705
    {
706
        $options = [];
707
708
        foreach (explode('|', $string) as $i => $item0) {
709
            $level1 = explode('\\', $item0);
710
711
            foreach ($level1 as $j => $item1) {
712
                if (0 === $j) {
713
                    $options[] = ['label' => $item1, 'options' => []];
714
715
                    continue;
716
                }
717
718
719
                foreach (explode(':', $item1) as $k => $item2) {
720
                    if (0 === $k) {
721
                        $options[$i]['options'][] = ['label' => $item2, 'options' => []];
722
723
                        continue;
724
                    }
725
726
                    $options[$i]['options'][$j - 1]['options'][] = explode(';', $item2);
727
                }
728
            }
729
        }
730
731
        array_walk_recursive($options, function (&$item) {
732
            $item = trim($item);
733
        });
734
735
        return $options;
736
    }
737
738
    /**
739
     * @param array $options
740
     *
741
     * @return array
742
     */
743
    public static function extra_field_double_select_convert_array_to_ordered_array($options)
744
    {
745
        $options_parsed = [];
746
        if (!empty($options)) {
747
            foreach ($options as $option) {
748
                if ($option['option_value'] == 0) {
749
                    $options_parsed[$option['id']][] = $option;
750
                } else {
751
                    $options_parsed[$option['option_value']][] = $option;
752
                }
753
            }
754
        }
755
756
        return $options_parsed;
757
    }
758
759
    /**
760
     * @param array $options
761
     * @param int $parentId
762
     * @return array
763
     */
764
    private static function getOptionsFromTripleSelect(array $options, $parentId)
765
    {
766
        return array_filter($options, function ($option) use ($parentId) {
767
            return $option['option_value'] == $parentId;
768
        });
769
    }
770
771
    /**
772
     * @param array $options
773
     * @return array
774
     */
775
    public static function tripleSelectConvertArrayToOrderedArray(array $options)
776
    {
777
        $level1 = self::getOptionsFromTripleSelect($options, 0);
778
        $level2 = [];
779
        $level3 = [];
780
781
        foreach ($level1 as $item1) {
782
            $level2 += self::getOptionsFromTripleSelect($options, $item1['id']);
783
        }
784
785
        foreach ($level2 as $item2) {
786
            $level3 += self::getOptionsFromTripleSelect($options, $item2['id']);
787
        }
788
789
        return ['level1' => $level1, 'level2' => $level2, 'level3' => $level3];
790
    }
791
792
    /**
793
     * @param array $options the result of the get_field_options_by_field() array
794
     *
795
     * @return string
796
     */
797
    public static function extra_field_double_select_convert_array_to_string($options)
798
    {
799
        $string = null;
800
        $options_parsed = self::extra_field_double_select_convert_array_to_ordered_array($options);
801
802
        if (!empty($options_parsed)) {
803
            foreach ($options_parsed as $option) {
804
                foreach ($option as $key => $item) {
805
                    $string .= $item['display_text'];
806
                    if ($key == 0) {
807
                        $string .= ':';
808
                    } else {
809
                        if (isset($option[$key + 1])) {
810
                            $string .= ';';
811
                        }
812
                    }
813
                }
814
                $string .= '|';
815
            }
816
        }
817
818
        if (!empty($string)) {
819
            $string = substr($string, 0, strlen($string) - 1);
820
        }
821
822
        return $string;
823
    }
824
825
    /**
826
     * @param array $options The result of the get_field_options_by_field() array
827
     * @return string
828
     */
829
    public static function extrafieldSelectWithTextConvertArrayToString(array $options)
830
    {
831
        $string = '';
832
        $parsedOptions = self::extra_field_double_select_convert_array_to_ordered_array($options);
833
834
        if (empty($parsedOptions)) {
835
            return '';
836
        }
837
838
        foreach ($parsedOptions as $options) {
839
            $option = current($options);
840
841
            $string .= $option['display_text'];
842
            $string .= '|';
843
        }
844
845
        return rtrim($string, '|');
846
    }
847
848
    /**
849
     * @param array $options
850
     * @return string
851
     */
852
    public static function tripleSelectConvertArrayToString(array $options)
853
    {
854
        $string = '';
855
        $parsedOptions = self::tripleSelectConvertArrayToOrderedArray($options);
856
857
        foreach ($parsedOptions['level1'] as $item1) {
858
            $string .= $item1['display_text'];
859
            $level2 = self::getOptionsFromTripleSelect($parsedOptions['level2'], $item1['id']);
860
861
            foreach ($level2 as $item2) {
862
                $string .= '\\'.$item2['display_text'].':';
863
                $level3 = self::getOptionsFromTripleSelect($parsedOptions['level3'], $item2['id']);
864
865
                $string .= implode(';', array_column($level3, 'display_text'));
866
            }
867
868
            $string .= '|';
869
        }
870
871
        return trim($string, '\\|;');
872
    }
873
874
    /**
875
     * @param array $params
876
     *
877
     * @return array
878
     */
879
    public function clean_parameters($params)
880
    {
881
        if (!isset($params['variable']) || empty($params['variable'])) {
882
            $params['variable'] = $params['display_text'];
883
        }
884
885
        $params['variable'] = trim(strtolower(str_replace(" ", "_", $params['variable'])));
886
887
        if (!isset($params['field_order'])) {
888
            $max_order = self::get_max_field_order();
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_max_field_order() is not static, but was called statically. ( Ignorable by Annotation )

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

888
            /** @scrutinizer ignore-call */ 
889
            $max_order = self::get_max_field_order();
Loading history...
889
            $params['field_order'] = $max_order;
890
        } else {
891
            $params['field_order'] = (int) $params['field_order'];
892
        }
893
894
        return $params;
895
    }
896
897
    /**
898
     * @param array $params
899
     * @param bool $show_query
900
     *
901
     * @return int
902
     */
903
    public function save($params, $show_query = false)
904
    {
905
        $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_handler_...nfo_by_field_variable() is not static, but was called statically. ( Ignorable by Annotation )

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

905
        /** @scrutinizer ignore-call */ 
906
        $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
Loading history...
906
        $params = self::clean_parameters($params);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::clean_parameters() is not static, but was called statically. ( Ignorable by Annotation )

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

906
        /** @scrutinizer ignore-call */ 
907
        $params = self::clean_parameters($params);
Loading history...
907
        $params['extra_field_type'] = $this->extraFieldType;
908
909
        if ($fieldInfo) {
910
            return $fieldInfo['id'];
911
        } else {
912
            $id = parent::save($params, $show_query);
913
            if ($id) {
914
                $session_field_option = new ExtraFieldOption($this->type);
915
                $params['field_id'] = $id;
916
                $session_field_option->save($params);
917
            }
918
919
            return $id;
920
        }
921
    }
922
923
    /**
924
     * @inheritdoc
925
     */
926
    public function update($params, $showQuery = false)
927
    {
928
        $params = self::clean_parameters($params);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::clean_parameters() is not static, but was called statically. ( Ignorable by Annotation )

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

928
        /** @scrutinizer ignore-call */ 
929
        $params = self::clean_parameters($params);
Loading history...
929
        if (isset($params['id'])) {
930
            $field_option = new ExtraFieldOption($this->type);
931
            $params['field_id'] = $params['id'];
932
            if (empty($params['field_type'])) {
933
                $params['field_type'] = $this->type;
934
            }
935
            $field_option->save($params, $showQuery);
936
        }
937
938
        parent::update($params, $showQuery);
939
    }
940
941
    /**
942
     * @param $id
943
     *
944
     * @return bool|void
945
     */
946
    public function delete($id)
947
    {
948
        $em = Database::getManager();
949
        $items = $em->getRepository('ChamiloCoreBundle:ExtraFieldSavedSearch')->findBy(['field' => $id]);
950
        if ($items) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
951
            foreach ($items as $item) {
952
                $em->remove($item);
953
            }
954
            $em->flush();
955
        }
956
        $field_option = new ExtraFieldOption($this->type);
957
        $field_option->delete_all_options_by_field_id($id);
958
959
        $session_field_values = new ExtraFieldValue($this->type);
960
        $session_field_values->delete_all_values_by_field_id($id);
961
962
        parent::delete($id);
963
    }
964
965
    /**
966
     * @param \FormValidator $form
967
     * @param array $fieldDetails
968
     * @param int $defaultValueId
969
     * @param bool $freezeElement
970
     */
971
    private function addSelectElement(FormValidator $form, array $fieldDetails, $defaultValueId, $freezeElement = false)
972
    {
973
        $get_lang_variables = false;
974
        if (in_array(
975
            $fieldDetails['variable'],
976
            ['mail_notify_message', 'mail_notify_invitation', 'mail_notify_group_message']
977
        )) {
978
            $get_lang_variables = true;
979
        }
980
981
        // Get extra field workflow
982
        $userInfo = api_get_user_info();
983
        $addOptions = [];
984
        $optionsExists = false;
985
        global $app;
986
        // Check if exist $app['orm.em'] object
987
        if (isset($app['orm.em']) && is_object($app['orm.em'])) {
988
            $optionsExists = $app['orm.em']
989
                ->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')
990
                ->findOneBy(['fieldId' => $fieldDetails['id']]);
991
        }
992
993
        if ($optionsExists) {
994
            if (isset($userInfo['status'])
995
                && !empty($userInfo['status'])
996
            ) {
997
                $fieldWorkFlow = $app['orm.em']
998
                    ->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')
999
                    ->findBy(
1000
                        [
1001
                            'fieldId' => $fieldDetails['id'],
1002
                            'relatedFieldOptionId' => $defaultValueId,
1003
                            'roleId' => $userInfo['status']
1004
                        ]
1005
                    );
1006
                foreach ($fieldWorkFlow as $item) {
1007
                    $addOptions[] = $item->getFieldOptionId();
1008
                }
1009
            }
1010
        }
1011
1012
        $options = [];
1013
        if (empty($defaultValueId)) {
1014
            $options[''] = get_lang('SelectAnOption');
1015
        }
1016
1017
        $optionList = [];
1018
        if (!empty($fieldDetails['options'])) {
1019
            foreach ($fieldDetails['options'] as $option_details) {
1020
                $optionList[$option_details['id']] = $option_details;
1021
                if ($get_lang_variables) {
1022
                    $options[$option_details['option_value']] = $option_details['display_text'];
1023
                } else {
1024
                    if ($optionsExists) {
1025
                        // Adding always the default value
1026
                        if ($option_details['id'] == $defaultValueId) {
1027
                            $options[$option_details['option_value']] = $option_details['display_text'];
1028
                        } else {
1029
                            if (isset($addOptions) && !empty($addOptions)) {
1030
                                // Parsing filters
1031
                                if (in_array($option_details['id'], $addOptions)) {
1032
                                    $options[$option_details['option_value']] = $option_details['display_text'];
1033
                                }
1034
                            }
1035
                        }
1036
                    } else {
1037
                        // Normal behaviour
1038
                        $options[$option_details['option_value']] = $option_details['display_text'];
1039
                    }
1040
                }
1041
            }
1042
1043
            if (isset($optionList[$defaultValueId])) {
1044
                if (isset($optionList[$defaultValueId]['option_value'])
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1045
                    && $optionList[$defaultValueId]['option_value'] == 'aprobada'
1046
                ) {
1047
                    // @todo function don't exists api_is_question_manager
1048
                    /*if (api_is_question_manager() == false) {
1049
                        $form->freeze();
1050
                    }*/
1051
                }
1052
            }
1053
1054
            // Setting priority message
1055
            if (isset($optionList[$defaultValueId])
1056
                && isset($optionList[$defaultValueId]['priority'])
1057
            ) {
1058
                if (!empty($optionList[$defaultValueId]['priority'])) {
1059
                    $priorityId = $optionList[$defaultValueId]['priority'];
1060
                    $option = new ExtraFieldOption($this->type);
1061
                    $messageType = $option->getPriorityMessageType($priorityId);
1062
                    $form->addElement(
1063
                        'label',
1064
                        null,
1065
                        Display::return_message(
1066
                            $optionList[$defaultValueId]['priority_message'],
1067
                            $messageType
1068
                        )
1069
                    );
1070
                }
1071
            }
1072
        }
1073
1074
        /** @var \HTML_QuickForm_select $slct */
1075
        $slct = $form->addElement(
1076
            'select',
1077
            'extra_'.$fieldDetails['variable'],
1078
            $fieldDetails['display_text'],
1079
            [],
1080
            ['id' => 'extra_'.$fieldDetails['variable']]
1081
        );
1082
1083
        foreach ($options as $value => $text) {
1084
            if (empty($value)) {
1085
                $slct->addOption($text, $value);
1086
                continue;
1087
            }
1088
1089
            $valueParts = explode('#', $text);
1090
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
1091
1092
            $slct->addOption(implode('', $valueParts), $value, ['data-value' => $dataValue]);
1093
        }
1094
1095
        /* Enable this when field_loggeable is introduced as a table field (2.0)
1096
        if ($optionsExists && $field_details['field_loggeable'] && !empty($defaultValueId)) {
1097
1098
            $form->addElement(
1099
                'textarea',
1100
                'extra_' . $field_details['variable'] . '_comment',
1101
                $field_details['display_text'] . ' ' . get_lang('Comment')
1102
            );
1103
1104
            $extraFieldValue = new ExtraFieldValue($this->type);
1105
            $repo = $app['orm.em']->getRepository($extraFieldValue->entityName);
1106
            $repoLog = $app['orm.em']->getRepository('Gedmo\Loggable\Entity\LogEntry');
1107
            $newEntity = $repo->findOneBy(
1108
                array(
1109
                    $this->handlerEntityId => $itemId,
1110
                    'fieldId' => $field_details['id']
1111
                )
1112
            );
1113
            // @todo move this in a function inside the class
1114
            if ($newEntity) {
1115
                $logs = $repoLog->getLogEntries($newEntity);
1116
                if (!empty($logs)) {
1117
                    $html = '<b>' . get_lang('LatestChanges') . '</b><br /><br />';
1118
1119
                    $table = new HTML_Table(array('class' => 'data_table'));
1120
                    $table->setHeaderContents(0, 0, get_lang('Value'));
1121
                    $table->setHeaderContents(0, 1, get_lang('Comment'));
1122
                    $table->setHeaderContents(0, 2, get_lang('ModifyDate'));
1123
                    $table->setHeaderContents(0, 3, get_lang('Username'));
1124
                    $row = 1;
1125
                    foreach ($logs as $log) {
1126
                        $column = 0;
1127
                        $data = $log->getData();
1128
                        $fieldValue = isset($data['fieldValue']) ? $data['fieldValue'] : null;
1129
                        $comment = isset($data['comment']) ? $data['comment'] : null;
1130
1131
                        $table->setCellContents($row, $column, $fieldValue);
1132
                        $column++;
1133
                        $table->setCellContents($row, $column, $comment);
1134
                        $column++;
1135
                        $table->setCellContents($row, $column, api_get_local_time($log->getLoggedAt()->format('Y-m-d H:i:s')));
1136
                        $column++;
1137
                        $table->setCellContents($row, $column, $log->getUsername());
1138
                        $row++;
1139
                    }
1140
                    $form->addElement('label', null, $html.$table->toHtml());
1141
                }
1142
            }
1143
        }
1144
        */
1145
1146
        if ($freezeElement) {
1147
            $form->freeze('extra_'.$fieldDetails['variable']);
1148
        }
1149
    }
1150
1151
    /**
1152
     * @param \FormValidator $form
1153
     * @param array $fieldDetails
1154
     * @param array $extraData
1155
     * @param bool $freezeElement
1156
     * @return string JavaScript code
1157
     */
1158
    private function addDoubleSelectElement(FormValidator $form, $fieldDetails, $extraData, $freezeElement = false)
1159
    {
1160
        $firstSelectId = 'first_extra_'.$fieldDetails['variable'];
1161
        $secondSelectId = 'second_extra_'.$fieldDetails['variable'];
1162
1163
        $jqueryReadyContent = "
1164
            $('#$firstSelectId').on('change', function() {
1165
                var id = $(this).val();
1166
1167
                if (!id) {
1168
                    $('#$secondSelectId').empty().selectpicker('refresh');
1169
                    
1170
                    return;
1171
                }
1172
1173
                $.getJSON(_p.web_ajax + 'extra_field.ajax.php?1=1&a=get_second_select_options', {
1174
                    'type': '{$this->type}',
1175
                    'field_id': {$fieldDetails['id']},
1176
                    'option_value_id': id
1177
                })
1178
                    .done(function(data) {
1179
                        $('#$secondSelectId').empty();
1180
                        $.each(data, function(index, value) {
1181
                            $('#second_extra_{$fieldDetails['variable']}').append(
1182
                                $('<option>', {value: index, text: value})
1183
                            );
1184
                        });
1185
                        $('#$secondSelectId').selectpicker('refresh');
1186
                    });
1187
            });
1188
        ";
1189
1190
        $firstId = null;
1191
        if (!empty($extraData)) {
1192
            if (isset($extraData['extra_'.$fieldDetails['variable']])) {
1193
                $firstId = $extraData['extra_'.$fieldDetails['variable']]['extra_'.$fieldDetails['variable']];
1194
            }
1195
        }
1196
1197
        $options = self::extra_field_double_select_convert_array_to_ordered_array($fieldDetails['options']);
1198
        $values = ['' => get_lang('Select')];
1199
1200
        $second_values = [];
1201
        if (!empty($options)) {
1202
            foreach ($options as $option) {
1203
                foreach ($option as $sub_option) {
1204
                    if ($sub_option['option_value'] == '0') {
1205
                        $values[$sub_option['id']] = $sub_option['display_text'];
1206
1207
                        continue;
1208
                    }
1209
1210
                    if ($firstId === $sub_option['option_value']) {
1211
                        $second_values[$sub_option['id']] = $sub_option['display_text'];
1212
                    }
1213
                }
1214
            }
1215
        }
1216
        $form
1217
            ->defaultRenderer()
1218
            ->setGroupElementTemplate('<p>{element}</p>', 'extra_'.$fieldDetails['variable']);
1219
        $group = [];
1220
        $group[] = $form->createElement(
1221
            'select',
1222
            'extra_'.$fieldDetails['variable'],
1223
            null,
1224
            $values,
1225
            ['id' => $firstSelectId]
1226
        );
1227
        $group[] = $form->createElement(
1228
            'select',
1229
            'extra_'.$fieldDetails['variable'].'_second',
1230
            null,
1231
            $second_values,
1232
            ['id' => $secondSelectId]
1233
        );
1234
        $form->addGroup(
1235
            $group,
1236
            'extra_'.$fieldDetails['variable'],
1237
            $fieldDetails['display_text']
1238
        );
1239
1240
        if ($freezeElement) {
1241
            $form->freeze('extra_'.$fieldDetails['variable']);
1242
        }
1243
1244
        return $jqueryReadyContent;
1245
    }
1246
1247
    /**
1248
     * @param \FormValidator $form
1249
     * @param array $fieldDetails
1250
     * @param bool $freezeElement Optional
1251
     * @return string JavaScript code
1252
     */
1253
    private function addSelectWithTextFieldElement(
1254
        FormValidator $form,
1255
        array $fieldDetails,
1256
        $freezeElement = false
1257
    ) {
1258
        $firstSelectId = 'slct_extra_'.$fieldDetails['variable'];
1259
        $txtSelectId = 'txt_extra_'.$fieldDetails['variable'];
1260
1261
        $jqueryReadyContent = "
1262
            $('#$firstSelectId').on('change', function() {
1263
                var id = $(this).val();
1264
1265
                if (!id) {
1266
                    $('#$txtSelectId').val('');
1267
                }
1268
            });
1269
        ";
1270
1271
        $options = self::extra_field_double_select_convert_array_to_ordered_array($fieldDetails['options']);
1272
        $values = ['' => get_lang('Select')];
1273
1274
        if (!empty($options)) {
1275
            foreach ($options as $option) {
1276
                foreach ($option as $sub_option) {
1277
                    if ($sub_option['option_value'] != '0') {
1278
                        continue;
1279
                    }
1280
1281
                    $values[$sub_option['id']] = $sub_option['display_text'];
1282
                }
1283
            }
1284
        }
1285
1286
        $form
1287
            ->defaultRenderer()
1288
            ->setGroupElementTemplate('<p>{element}</p>', 'extra_'.$fieldDetails['variable']);
1289
        $group = [];
1290
        $group[] = $form->createElement(
1291
            'select',
1292
            'extra_'.$fieldDetails['variable'],
1293
            null,
1294
            $values,
1295
            ['id' => $firstSelectId]
1296
        );
1297
        $group[] = $form->createElement(
1298
            'text',
1299
            'extra_'.$fieldDetails['variable'].'_second',
1300
            null,
1301
            ['id' => $txtSelectId]
1302
        );
1303
        $form->addGroup(
1304
            $group,
1305
            'extra_'.$fieldDetails['variable'],
1306
            $fieldDetails['display_text']
1307
        );
1308
1309
        if ($freezeElement) {
1310
            $form->freeze('extra_'.$fieldDetails['variable']);
1311
        }
1312
1313
        return $jqueryReadyContent;
1314
    }
1315
1316
    /**
1317
     * @param \FormValidator $form
1318
     * @param array $fieldDetails
1319
     * @param array $extraData
1320
     * @param boolean $freezeElement
1321
     * @return string
1322
     */
1323
    private function addTripleSelectElement(
1324
        FormValidator $form,
1325
        array $fieldDetails,
1326
        array $extraData,
1327
        $freezeElement
1328
    ) {
1329
        $variable = $fieldDetails['variable'];
1330
        $id = $fieldDetails['id'];
1331
        $slctFirstId = "first_extra$variable";
1332
        $slctSecondId = "second_extra$variable";
1333
        $slctThirdId = "third_extra$variable";
1334
        $langSelect = get_lang('Select');
1335
1336
        $js = "
1337
            (function () {
1338
                var slctFirst = $('#$slctFirstId'),
1339
                    slctSecond = $('#$slctSecondId'),
1340
                    slctThird = $('#$slctThirdId');
1341
                    
1342
                slctFirst.on('change', function () {
1343
                    slctSecond.empty().selectpicker('refresh');
1344
                    slctThird.empty().selectpicker('refresh');
1345
    
1346
                    var level = $(this).val();
1347
    
1348
                    if (!level) {
1349
                        return;
1350
                    }
1351
    
1352
                    $.getJSON(_p.web_ajax + 'extra_field.ajax.php', {
1353
                        'a': 'get_second_select_options',
1354
                        'type': '$this->type',
1355
                        'field_id': $id,
1356
                        'option_value_id': level
1357
                    })
1358
                        .done(function (data) {
1359
                            slctSecond.append(
1360
                                $('<option>', {value: '', text: '$langSelect'})
1361
                            );
1362
1363
                            $.each(data, function (index, value) {
1364
                                var valueParts = value.split('#'),
1365
                                    dataValue = valueParts.length > 1 ? valueParts.shift() : '';
1366
1367
                                slctSecond.append(
1368
                                    $('<option>', {value: index, text: valueParts.join(''), 'data-value': dataValue})
1369
                                );
1370
                            });
1371
    
1372
                            slctSecond.selectpicker('refresh');
1373
                        });
1374
                });
1375
                slctSecond.on('change', function () {
1376
                    slctThird.empty().selectpicker('refresh');
1377
    
1378
                    var level = $(this).val();
1379
                    
1380
                    if (!level) {
1381
                        return;
1382
                    }
1383
                    
1384
                    $.getJSON(_p.web_ajax + 'extra_field.ajax.php', {
1385
                        'a': 'get_second_select_options',
1386
                        'type': '$this->type',
1387
                        'field_id': $id,
1388
                        'option_value_id': level
1389
                    })
1390
                        .done(function (data) {
1391
                            slctThird.append(
1392
                                $('<option>', {value: '', text: '$langSelect'})
1393
                            );
1394
1395
                            $.each(data, function (index, value) {
1396
                                var valueParts = value.split('#'),
1397
                                    dataValue = valueParts.length > 1 ? valueParts.shift() : '';
1398
1399
                                slctThird.append(
1400
                                    $('<option>', {value: index, text: valueParts.join(''), 'data-value': dataValue})
1401
                                );
1402
                            });
1403
    
1404
                            slctThird.selectpicker('refresh');
1405
                        });
1406
                });
1407
            })();
1408
        ";
1409
1410
        $firstId = isset($extraData["extra_$variable"]["extra_$variable"])
1411
            ? $extraData["extra_$variable"]["extra_$variable"]
1412
            : '';
1413
        $secondId = isset($extraData["extra_$variable"]["extra_{$variable}_second"])
1414
            ? $extraData["extra_$variable"]["extra_{$variable}_second"]
1415
            : '';
1416
1417
        $options = self::tripleSelectConvertArrayToOrderedArray($fieldDetails['options']);
1418
        $values1 = ['' => $langSelect];
1419
        $values2 = ['' => $langSelect];
1420
        $values3 = ['' => $langSelect];
1421
        $level1 = self::getOptionsFromTripleSelect($options['level1'], 0);
1422
        $level2 = self::getOptionsFromTripleSelect($options['level2'], $firstId);
0 ignored issues
show
Bug introduced by
It seems like $firstId can also be of type string; however, parameter $parentId of ExtraField::getOptionsFromTripleSelect() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

1422
        $level2 = self::getOptionsFromTripleSelect($options['level2'], /** @scrutinizer ignore-type */ $firstId);
Loading history...
1423
        $level3 = self::getOptionsFromTripleSelect($options['level3'], $secondId);
1424
        /** @var \HTML_QuickForm_select $slctFirst */
1425
        $slctFirst = $form->createElement('select', "extra_$variable", null, $values1, ['id' => $slctFirstId]);
1426
        /** @var \HTML_QuickForm_select $slctFirst */
1427
        $slctSecond = $form->createElement('select', "extra_{$variable}_second", null, $values2, ['id' => $slctSecondId]);
1428
        /** @var \HTML_QuickForm_select $slctFirst */
1429
        $slctThird = $form->createElement('select', "extra_{$variable}_third", null, $values3, ['id' => $slctThirdId]);
1430
1431
        foreach ($level1 as $item1) {
1432
            $valueParts = explode('#', $item1['display_text']);
1433
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
1434
            $slctFirst->addOption(implode('', $valueParts), $item1['id'], ['data-value' => $dataValue]);
1435
        }
1436
1437
        foreach ($level2 as $item2) {
1438
            $valueParts = explode('#', $item2['display_text']);
1439
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
1440
            $slctSecond->addOption(implode('', $valueParts), $item2['id'], ['data-value' => $dataValue]);
0 ignored issues
show
Bug introduced by
The method addOption() does not exist on HTML_QuickForm_element. It seems like you code against a sub-type of HTML_QuickForm_element such as HTML_QuickForm_select. ( Ignorable by Annotation )

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

1440
            $slctSecond->/** @scrutinizer ignore-call */ 
1441
                         addOption(implode('', $valueParts), $item2['id'], ['data-value' => $dataValue]);
Loading history...
1441
        }
1442
1443
        foreach ($level3 as $item3) {
1444
            $valueParts = explode('#', $item3['display_text']);
1445
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
1446
            $slctThird->addOption(implode('', $valueParts), $item3['id'], ['data-value' => $dataValue]);
1447
        }
1448
1449
        $form
1450
            ->defaultRenderer()
1451
            ->setGroupElementTemplate('<p>{element}</p>', "extra_$variable");
1452
        $form->addGroup([$slctFirst, $slctSecond, $slctThird], "extra_$variable", $fieldDetails['display_text']);
1453
1454
        if ($freezeElement) {
1455
            $form->freeze('extra_'.$fieldDetails['variable']);
1456
        }
1457
1458
        return $js;
1459
    }
1460
1461
    /**
1462
     * Add an element that matches the given extra field to the given $form object
1463
     * @param FormValidator $form
1464
     * @param array $extraData
1465
     * @param bool $adminPermissions
1466
     * @param array $extra
1467
     * @param int $itemId
1468
     * @param array $exclude variables of extra field to exclude
1469
     * @param bool $useTagAsSelect
1470
     * @param array $showOnlyTheseFields
1471
     * @param array $orderFields
1472
     *
1473
     * @return array If relevant, returns a one-element array with JS code to be added to the page HTML headers
1474
     */
1475
    public function set_extra_fields_in_form(
1476
        $form,
1477
        $extraData,
1478
        $adminPermissions = false,
1479
        $extra = [],
1480
        $itemId = null,
1481
        $exclude = [],
1482
        $useTagAsSelect = false,
1483
        $showOnlyTheseFields = [],
1484
        $orderFields = []
1485
    ) {
1486
        $jquery_ready_content = null;
1487
        if (!empty($extra)) {
1488
            $newOrder = [];
1489
            if (!empty($orderFields)) {
1490
                foreach ($orderFields as $order) {
1491
                    foreach ($extra as $field_details) {
1492
                        if ($order == $field_details['variable']) {
1493
                            $newOrder[] = $field_details;
1494
                        }
1495
                    }
1496
                }
1497
                $extra = $newOrder;
1498
            }
1499
1500
            foreach ($extra as $field_details) {
1501
                if (!empty($showOnlyTheseFields)) {
1502
                    if (!in_array($field_details['variable'], $showOnlyTheseFields)) {
1503
                        continue;
1504
                    }
1505
                }
1506
1507
                // Getting default value id if is set
1508
                $defaultValueId = null;
1509
                if (isset($field_details['options']) && !empty($field_details['options'])) {
1510
                    $valueToFind = null;
1511
                    if (isset($field_details['field_default_value'])) {
1512
                        $valueToFind = $field_details['field_default_value'];
1513
                    }
1514
                    // If a value is found we override the default value
1515
                    if (isset($extraData['extra_'.$field_details['variable']])) {
1516
                        $valueToFind = $extraData['extra_'.$field_details['variable']];
1517
                    }
1518
1519
                    foreach ($field_details['options'] as $option) {
1520
                        if ($option['option_value'] == $valueToFind) {
1521
                            $defaultValueId = $option['id'];
1522
                        }
1523
                    }
1524
                }
1525
1526
                if (!$adminPermissions) {
1527
                    if ($field_details['visible_to_self'] == 0) {
1528
                        continue;
1529
                    }
1530
1531
                    if (in_array($field_details['variable'], $exclude)) {
1532
                        continue;
1533
                    }
1534
                }
1535
1536
                $freezeElement = false;
1537
                if (!$adminPermissions) {
1538
                    $freezeElement = $field_details['visible_to_self'] == 0 || $field_details['changeable'] == 0;
1539
                }
1540
1541
                switch ($field_details['field_type']) {
1542
                    case self::FIELD_TYPE_TEXT:
1543
                        $form->addElement(
1544
                            'text',
1545
                            'extra_'.$field_details['variable'],
1546
                            $field_details['display_text'],
1547
                            [
1548
                                'id' => 'extra_'.$field_details['variable']
1549
                            ]
1550
                        );
1551
                        $form->applyFilter(
1552
                            'extra_'.$field_details['variable'],
1553
                            'stripslashes'
1554
                        );
1555
                        $form->applyFilter(
1556
                            'extra_'.$field_details['variable'],
1557
                            'trim'
1558
                        );
1559
                        if ($freezeElement) {
1560
                            $form->freeze('extra_'.$field_details['variable']);
1561
                        }
1562
                        break;
1563
                    case self::FIELD_TYPE_TEXTAREA:
1564
                        $form->addHtmlEditor(
1565
                            'extra_'.$field_details['variable'],
1566
                            $field_details['display_text'],
1567
                            false,
1568
                            false,
1569
                            [
1570
                                'ToolbarSet' => 'Profile',
1571
                                'Width' => '100%',
1572
                                'Height' => '130',
1573
                                'id' => 'extra_'.$field_details['variable']
1574
                            ]
1575
                        );
1576
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1577
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1578
                        if ($freezeElement) {
1579
                            $form->freeze('extra_'.$field_details['variable']);
1580
                        }
1581
                        break;
1582
                    case self::FIELD_TYPE_RADIO:
1583
                        $group = [];
1584
                        if (isset($field_details['options']) &&
1585
                            !empty($field_details['options'])
1586
                        ) {
1587
                            foreach ($field_details['options'] as $option_details) {
1588
                                $options[$option_details['option_value']] = $option_details['display_text'];
1589
                                $group[] = $form->createElement(
1590
                                    'radio',
1591
                                    'extra_'.$field_details['variable'],
1592
                                    $option_details['option_value'],
1593
                                    $option_details['display_text'].'<br />',
1594
                                    $option_details['option_value']
1595
                                );
1596
                            }
1597
                        }
1598
                        $form->addGroup(
1599
                            $group,
1600
                            'extra_'.$field_details['variable'],
1601
                            $field_details['display_text']
1602
                        );
1603
                        if ($freezeElement) {
1604
                            $form->freeze('extra_'.$field_details['variable']);
1605
                        }
1606
                        break;
1607
                    case self::FIELD_TYPE_CHECKBOX:
1608
                        $group = [];
1609
                        if (isset($field_details['options']) &&
1610
                            !empty($field_details['options'])
1611
                        ) {
1612
                            foreach ($field_details['options'] as $option_details) {
1613
                                $options[$option_details['option_value']] = $option_details['display_text'];
1614
                                $group[] = $form->createElement(
1615
                                    'checkbox',
1616
                                    'extra_'.$field_details['variable'],
1617
                                    $option_details['option_value'],
1618
                                    $option_details['display_text'].'<br />',
1619
                                    $option_details['option_value']
1620
                                );
1621
                            }
1622
                        } else {
1623
                            $fieldVariable = "extra_{$field_details['variable']}";
1624
                            $checkboxAttributes = [];
1625
                            if (is_array($extraData) &&
1626
                                array_key_exists($fieldVariable, $extraData)
1627
                            ) {
1628
                                if (!empty($extraData[$fieldVariable])) {
1629
                                    $checkboxAttributes['checked'] = 1;
1630
                                }
1631
                            }
1632
1633
                            // We assume that is a switch on/off with 1 and 0 as values
1634
                            $group[] = $form->createElement(
1635
                                'checkbox',
1636
                                'extra_'.$field_details['variable'],
1637
                                null,
1638
                                //$field_details['display_text'].'<br />',
1639
                                get_lang('Yes'),
1640
                                $checkboxAttributes
1641
                            );
1642
                        }
1643
1644
                        $form->addGroup(
1645
                            $group,
1646
                            'extra_'.$field_details['variable'],
1647
                            $field_details['display_text']
1648
                        );
1649
                        if ($freezeElement) {
1650
                            $form->freeze('extra_'.$field_details['variable']);
1651
                        }
1652
                        break;
1653
                    case self::FIELD_TYPE_SELECT:
1654
                        self::addSelectElement($form, $field_details, $defaultValueId, $freezeElement);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::addSelectElement() is not static, but was called statically. ( Ignorable by Annotation )

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

1654
                        self::/** @scrutinizer ignore-call */ 
1655
                              addSelectElement($form, $field_details, $defaultValueId, $freezeElement);
Loading history...
1655
                        break;
1656
                    case self::FIELD_TYPE_SELECT_MULTIPLE:
1657
                        $options = [];
1658
                        foreach ($field_details['options'] as $option_id => $option_details) {
1659
                            $options[$option_details['option_value']] = $option_details['display_text'];
1660
                        }
1661
                        $form->addElement(
1662
                            'select',
1663
                            'extra_'.$field_details['variable'],
1664
                            $field_details['display_text'],
1665
                            $options,
1666
                            [
1667
                                'multiple' => 'multiple',
1668
                                'id' => 'extra_'.$field_details['variable']
1669
                            ]
1670
                        );
1671
                        if ($freezeElement) {
1672
                            $form->freeze('extra_'.$field_details['variable']);
1673
                        }
1674
                        break;
1675
                    case self::FIELD_TYPE_DATE:
1676
                        $form->addDatePicker('extra_'.$field_details['variable'], $field_details['display_text']);
1677
                        if ($freezeElement) {
1678
                            $form->freeze('extra_'.$field_details['variable']);
1679
                        }
1680
                        break;
1681
                    case self::FIELD_TYPE_DATETIME:
1682
                        $form->addDateTimePicker(
1683
                            'extra_'.$field_details['variable'],
1684
                            $field_details['display_text']
1685
                        );
1686
1687
                        $defaults['extra_'.$field_details['variable']] = api_get_local_time();
1688
                        if (!isset($form->_defaultValues['extra_'.$field_details['variable']])) {
1689
                            $form->setDefaults($defaults);
1690
                        }
1691
                        if ($freezeElement) {
1692
                            $form->freeze('extra_'.$field_details['variable']);
1693
                        }
1694
                        break;
1695
                    case self::FIELD_TYPE_DOUBLE_SELECT:
1696
                        $jquery_ready_content .= self::addDoubleSelectElement(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::addDoubleSelectElement() is not static, but was called statically. ( Ignorable by Annotation )

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

1696
                        $jquery_ready_content .= self::/** @scrutinizer ignore-call */ addDoubleSelectElement(
Loading history...
1697
                            $form,
1698
                            $field_details,
1699
                            $extraData,
1700
                            $freezeElement
1701
                        );
1702
                        break;
1703
                    case self::FIELD_TYPE_DIVIDER:
1704
                        $form->addHtml('
1705
                            <div class="form-group ">
1706
                                <div class="col-sm-12">
1707
                                    <div class="panel-separator">
1708
                                       <h4 id="'.$field_details['variable'].'" class="form-separator">'
1709
                                            .$field_details['display_text'].'
1710
                                       </h4>
1711
                                    </div>
1712
                                </div>
1713
                            </div>    
1714
                        ');
1715
                        break;
1716
                    case self::FIELD_TYPE_TAG:
1717
                        $variable = $field_details['variable'];
1718
                        $field_id = $field_details['id'];
1719
1720
                        $tagsSelect = $form->addSelect(
1721
                            "extra_{$field_details['variable']}",
1722
                            $field_details['display_text'],
1723
                            [],
1724
                            ['style' => 'width: 100%;']
1725
                        );
1726
1727
                        if ($useTagAsSelect == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1728
                            $tagsSelect->setAttribute('class', null);
1729
                        }
1730
1731
                        $tagsSelect->setAttribute('id', "extra_{$field_details['variable']}");
1732
                        $tagsSelect->setMultiple(true);
1733
1734
                        $selectedOptions = [];
1735
                        if ($this->type === 'user') {
1736
                            // The magic should be here
1737
                            $user_tags = UserManager::get_user_tags($itemId, $field_details['id']);
1738
1739
                            if (is_array($user_tags) && count($user_tags) > 0) {
1740
                                foreach ($user_tags as $tag) {
1741
                                    if (empty($tag['tag'])) {
1742
                                        continue;
1743
                                    }
1744
                                    $tagsSelect->addOption(
1745
                                        $tag['tag'],
1746
                                        $tag['tag']
1747
                                    );
1748
                                    $selectedOptions[] = $tag['tag'];
1749
                                }
1750
                            }
1751
                            $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
1752
                        } else {
1753
                            $em = Database::getManager();
1754
                            $fieldTags = $em
1755
                                ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1756
                                ->findBy(
1757
                                    [
1758
                                        'fieldId' => $field_id,
1759
                                        'itemId' => $itemId,
1760
                                    ]
1761
                                );
1762
                            /** @var ExtraFieldRelTag $fieldTag */
1763
                            foreach ($fieldTags as $fieldTag) {
1764
                                /** @var Tag $tag */
1765
                                $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1766
1767
                                if (empty($tag)) {
1768
                                    continue;
1769
                                }
1770
                                $tagsSelect->addOption(
1771
                                    $tag->getTag(),
1772
                                    $tag->getTag()
1773
                                );
1774
                                $selectedOptions[] = $tag->getTag();
1775
                            }
1776
1777
                            if ($useTagAsSelect) {
1778
                                $fieldTags = $em
1779
                                    ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1780
                                    ->findBy([
1781
                                        'fieldId' => $field_id
1782
                                    ]);
1783
                                $tagsAdded = [];
1784
                                foreach ($fieldTags as $fieldTag) {
1785
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1786
1787
                                    if (empty($tag)) {
1788
                                        continue;
1789
                                    }
1790
1791
                                    $tagText = $tag->getTag();
1792
1793
                                    if (in_array($tagText, $tagsAdded)) {
1794
                                        continue;
1795
                                    }
1796
1797
                                    $tagsSelect->addOption(
1798
                                        $tag->getTag(),
1799
                                        $tag->getTag(),
1800
                                        []
1801
                                    );
1802
1803
                                    $tagsAdded[] = $tagText;
1804
                                }
1805
                            }
1806
                            $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php';
1807
                        }
1808
1809
                        $form->setDefaults(
1810
                            [
1811
                                'extra_'.$field_details['variable'] => $selectedOptions
1812
                            ]
1813
                        );
1814
1815
                        if ($useTagAsSelect == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1816
                            $jquery_ready_content .= "
1817
                                $('#extra_$variable').select2({
1818
                                    ajax: {
1819
                                        url: '$url?a=search_tags&field_id=$field_id&type={$this->type}',
1820
                                        processResults: function (data) {
1821
                                            return {
1822
                                                results: data.items
1823
                                            }
1824
                                        }
1825
                                    },
1826
                                    cache: false,
1827
                                    tags: true,
1828
                                    tokenSeparators: [','],
1829
                                    placeholder: '".get_lang('StartToType')."'
1830
                                });
1831
                            ";
1832
                        }
1833
                        break;
1834
                    case self::FIELD_TYPE_TIMEZONE:
1835
                        $form->addElement(
1836
                            'select',
1837
                            'extra_'.$field_details['variable'],
1838
                            $field_details['display_text'],
1839
                            api_get_timezones(),
1840
                            ''
1841
                        );
1842
                        if ($freezeElement) {
1843
                            $form->freeze('extra_'.$field_details['variable']);
1844
                        }
1845
                        break;
1846
                    case self::FIELD_TYPE_SOCIAL_PROFILE:
1847
                        // get the social network's favicon
1848
                        $extra_data_variable = isset($extraData['extra_'.$field_details['variable']])
1849
                            ? $extraData['extra_'.$field_details['variable']]
1850
                            : null;
1851
                        $field_default_value = isset($field_details['field_default_value'])
1852
                            ? $field_details['field_default_value']
1853
                            : null;
1854
                        $icon_path = UserManager::get_favicon_from_url(
1855
                            $extra_data_variable,
1856
                            $field_default_value
1857
                        );
1858
                        // special hack for hi5
1859
                        $leftpad = '1.7';
1860
                        $top = '0.4';
1861
                        $domain = parse_url($icon_path, PHP_URL_HOST);
1862
                        if ($domain == 'www.hi5.com' or $domain == 'hi5.com') {
1863
                            $leftpad = '3';
1864
                            $top = '0';
1865
                        }
1866
                        // print the input field
1867
                        $form->addElement(
1868
                            'text',
1869
                            'extra_'.$field_details['variable'],
1870
                            $field_details['display_text'],
1871
                            [
1872
                                'size' => 60,
1873
                                'size' => implode(
1874
                                    '; ',
1875
                                    [
1876
                                        "background-image: url('$icon_path')",
1877
                                        'background-repeat: no-repeat',
1878
                                        "background-position: 0.4em {$top}em",
1879
                                        "padding-left: {$leftpad}em"
1880
                                    ]
1881
                                )
1882
                            ]
1883
                        );
1884
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1885
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1886
                        if ($freezeElement) {
1887
                            $form->freeze('extra_'.$field_details['variable']);
1888
                        }
1889
                        break;
1890
                    case self::FIELD_TYPE_MOBILE_PHONE_NUMBER:
1891
                        $form->addElement(
1892
                            'text',
1893
                            'extra_'.$field_details['variable'],
1894
                            $field_details['display_text']." (".get_lang('CountryDialCode').")",
1895
                            ['size' => 40, 'placeholder' => '(xx)xxxxxxxxx']
1896
                        );
1897
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1898
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1899
                        $form->applyFilter('extra_'.$field_details['variable'], 'mobile_phone_number_filter');
1900
                        $form->addRule(
1901
                            'extra_'.$field_details['variable'],
1902
                            get_lang('MobilePhoneNumberWrong'),
1903
                            'mobile_phone_number'
1904
                        );
1905
                        if ($freezeElement) {
1906
                            $form->freeze('extra_'.$field_details['variable']);
1907
                        }
1908
                        break;
1909
                    case self::FIELD_TYPE_INTEGER:
1910
                        $form->addElement(
1911
                            'number',
1912
                            'extra_'.$field_details['variable'],
1913
                            $field_details['display_text'],
1914
                            ['class' => 'span1', 'step' => 1]
1915
                        );
1916
1917
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1918
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1919
                        $form->applyFilter('extra_'.$field_details['variable'], 'intval');
1920
1921
                        if ($freezeElement) {
1922
                            $form->freeze('extra_'.$field_details['variable']);
1923
                        }
1924
                        break;
1925
                    case self::FIELD_TYPE_FILE_IMAGE:
1926
                        $fieldVariable = "extra_{$field_details['variable']}";
1927
                        $fieldTexts = [
1928
                            $field_details['display_text']
1929
                        ];
1930
1931
                        if (is_array($extraData) && array_key_exists($fieldVariable, $extraData)) {
1932
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1933
                                $fieldTexts[] = Display::img(
1934
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1935
                                    $field_details['display_text'],
1936
                                    ['width' => '300']
1937
                                );
1938
                            }
1939
                        }
1940
1941
                        if ($fieldTexts[0] === 'Image') {
1942
                            $fieldTexts[0] = get_lang($fieldTexts[0]);
1943
                        }
1944
1945
                        $form->addFile(
1946
                            $fieldVariable,
1947
                            $fieldTexts,
1948
                            ['accept' => 'image/*', 'id' => 'extra_image', 'crop_image' => 'true']
1949
                        );
1950
1951
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1952
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1953
1954
                        $allowed_picture_types = ['jpg', 'jpeg', 'png', 'gif'];
1955
                        $form->addRule(
1956
                            'extra_'.$field_details['variable'],
1957
                            get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')',
1958
                            'filetype',
1959
                            $allowed_picture_types
1960
                        );
1961
1962
                        if ($freezeElement) {
1963
                            $form->freeze('extra_'.$field_details['variable']);
1964
                        }
1965
                        break;
1966
                    case self::FIELD_TYPE_FLOAT:
1967
                        $form->addElement(
1968
                            'number',
1969
                            'extra_'.$field_details['variable'],
1970
                            $field_details['display_text'],
1971
                            ['class' => 'span1', 'step' => '0.01']
1972
                        );
1973
1974
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1975
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1976
                        $form->applyFilter('extra_'.$field_details['variable'], 'floatval');
1977
1978
                        if ($freezeElement) {
1979
                            $form->freeze('extra_'.$field_details['variable']);
1980
                        }
1981
                        break;
1982
                    case self::FIELD_TYPE_FILE:
1983
                        $fieldVariable = "extra_{$field_details['variable']}";
1984
                        $fieldTexts = [
1985
                            $field_details['display_text']
1986
                        ];
1987
1988
                        if (is_array($extraData) &&
1989
                            array_key_exists($fieldVariable, $extraData)
1990
                        ) {
1991
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1992
                                $fieldTexts[] = Display::url(
1993
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1994
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1995
                                    [
1996
                                        'title' => $field_details['display_text'],
1997
                                        'target' => '_blank'
1998
                                    ]
1999
                                );
2000
                            }
2001
                        }
2002
2003
                        $form->addElement(
2004
                            'file',
2005
                            $fieldVariable,
2006
                            $fieldTexts,
2007
                            []
2008
                        );
2009
2010
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
2011
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
2012
2013
                        if ($freezeElement) {
2014
                            $form->freeze('extra_'.$field_details['variable']);
2015
                        }
2016
                        break;
2017
                    case self::FIELD_TYPE_VIDEO_URL:
2018
                        $form->addUrl(
2019
                            "extra_{$field_details['variable']}",
2020
                            $field_details['display_text'],
2021
                            false,
2022
                            ['placeholder' => 'https://']
2023
                        );
2024
                        if ($freezeElement) {
2025
                            $form->freeze('extra_'.$field_details['variable']);
2026
                        }
2027
                        break;
2028
                    case self::FIELD_TYPE_LETTERS_ONLY:
2029
                        $form->addTextLettersOnly(
2030
                            "extra_{$field_details['variable']}",
2031
                            $field_details['display_text']
2032
                        );
2033
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
2034
2035
                        if ($freezeElement) {
2036
                            $form->freeze('extra_'.$field_details['variable']);
2037
                        }
2038
                        break;
2039
                    case self::FIELD_TYPE_ALPHANUMERIC:
2040
                        $form->addTextAlphanumeric(
2041
                            "extra_{$field_details['variable']}",
2042
                            $field_details['display_text']
2043
                        );
2044
                        $form->applyFilter(
2045
                            'extra_'.$field_details['variable'],
2046
                            'stripslashes'
2047
                        );
2048
                        if ($freezeElement) {
2049
                            $form->freeze('extra_'.$field_details['variable']);
2050
                        }
2051
                        break;
2052
                    case self::FIELD_TYPE_LETTERS_SPACE:
2053
                        $form->addTextLettersAndSpaces(
2054
                            "extra_{$field_details['variable']}",
2055
                            $field_details['display_text']
2056
                        );
2057
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
2058
2059
                        if ($freezeElement) {
2060
                            $form->freeze('extra_'.$field_details['variable']);
2061
                        }
2062
                        break;
2063
                    case self::FIELD_TYPE_ALPHANUMERIC_SPACE:
2064
                        $form->addTextAlphanumericAndSpaces(
2065
                            "extra_{$field_details['variable']}",
2066
                            $field_details['display_text']
2067
                        );
2068
                        $form->applyFilter(
2069
                            'extra_'.$field_details['variable'],
2070
                            'stripslashes'
2071
                        );
2072
                        if ($freezeElement) {
2073
                            $form->freeze('extra_'.$field_details['variable']);
2074
                        }
2075
                        break;
2076
                    case self::FIELD_TYPE_GEOLOCALIZATION:
2077
                        $dataValue = isset($extraData['extra_'.$field_details['variable']])
2078
                            ? $extraData['extra_'.$field_details['variable']]
2079
                            : '';
2080
                        $form->addElement(
2081
                            'text',
2082
                            'extra_'.$field_details['variable'],
2083
                            $field_details['display_text'],
2084
                            ['id' => 'extra_'.$field_details['variable']]
2085
                        );
2086
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
2087
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
2088
                        if ($freezeElement) {
2089
                            $form->freeze('extra_'.$field_details['variable']);
2090
                        }
2091
2092
                        $form->addHtml("
2093
                            <script>
2094
                                $(document).ready(function() {
2095
                                    if (typeof google === 'object') {
2096
                                        var address = '$dataValue';
2097
                                        initializeGeo{$field_details['variable']}(address, false);
2098
    
2099
                                        $('#geolocalization_extra_{$field_details['variable']}').on('click', function() {
2100
                                            var address = $('#extra_{$field_details['variable']}').val();
2101
                                            initializeGeo{$field_details['variable']}(address, false);
2102
                                            return false;
2103
                                        });
2104
    
2105
                                        $('#myLocation_extra_{$field_details['variable']}').on('click', function() {
2106
                                            myLocation{$field_details['variable']}();
2107
                                            return false;
2108
                                        });
2109
    
2110
                                        $('#extra_{$field_details['variable']}').keypress(function(event) {
2111
                                            if (event.which == 13) {
2112
                                                $('#geolocalization_extra_{$field_details['variable']}').click();
2113
                                                return false;
2114
                                            }
2115
                                        });
2116
                                        
2117
                                        return;
2118
                                    }
2119
2120
                                    $('#map_extra_{$field_details['variable']}')
2121
                                        .html('<div class=\"alert alert-info\">"
2122
                                            .get_lang('YouNeedToActivateTheGoogleMapsPluginInAdminPlatformToSeeTheMap')
2123
                                            ."</div>');
2124
                                });
2125
2126
                                function myLocation{$field_details['variable']}() {
2127
                                    if (navigator.geolocation) {
2128
                                        var geoPosition = function(position) {
2129
                                            var lat = position.coords.latitude;
2130
                                            var lng = position.coords.longitude;
2131
                                            var latLng = new google.maps.LatLng(lat, lng);
2132
                                            initializeGeo{$field_details['variable']}(false, latLng)
2133
                                        };
2134
2135
                                        var geoError = function(error) {
2136
                                            console.log(error);
2137
                                            alert('Geocode ".get_lang('Error').": ' + error);
2138
                                        };
2139
2140
                                        var geoOptions = {
2141
                                            enableHighAccuracy: true
2142
                                        };
2143
2144
                                        navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
2145
                                    }
2146
                                }
2147
2148
                                function initializeGeo{$field_details['variable']}(address, latLng) {
2149
                                    var geocoder = new google.maps.Geocoder();
2150
                                    var latlng = new google.maps.LatLng(-34.397, 150.644);
2151
                                    var myOptions = {
2152
                                        zoom: 15,
2153
                                        center: latlng,
2154
                                        mapTypeControl: true,
2155
                                        mapTypeControlOptions: {
2156
                                            style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
2157
                                        },
2158
                                        navigationControl: true,
2159
                                        mapTypeId: google.maps.MapTypeId.ROADMAP
2160
                                    };
2161
2162
                                    map_{$field_details['variable']} = new google.maps.Map(
2163
                                        document.getElementById('map_extra_{$field_details['variable']}'),
2164
                                        myOptions
2165
                                    );
2166
2167
                                    var parameter = address ? {'address': address} : latLng ? {'latLng': latLng} : false;
2168
2169
                                    if (geocoder && parameter) {
2170
                                        geocoder.geocode(parameter, function(results, status) {
2171
                                            if (status == google.maps.GeocoderStatus.OK) {
2172
                                                if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
2173
                                                    map_{$field_details['variable']}.setCenter(results[0].geometry.location);
2174
                                                    if (!address) {
2175
                                                        $('#extra_{$field_details['variable']}').val(results[0].formatted_address);
2176
                                                    }
2177
                                                    var infowindow = new google.maps.InfoWindow({
2178
                                                        content: '<b>' + $('#extra_{$field_details['variable']}').val() + '</b>',
2179
                                                        size: new google.maps.Size(150, 50)
2180
                                                    });
2181
2182
                                                    var marker = new google.maps.Marker({
2183
                                                        position: results[0].geometry.location,
2184
                                                        map: map_{$field_details['variable']},
2185
                                                        title: $('#extra_{$field_details['variable']}').val()
2186
                                                    });
2187
                                                    google.maps.event.addListener(marker, 'click', function() {
2188
                                                        infowindow.open(map_{$field_details['variable']}, marker);
2189
                                                    });
2190
                                                } else {
2191
                                                    alert('".get_lang('NotFound')."');
2192
                                                }
2193
                                            } else {
2194
                                                alert('Geocode ".get_lang('Error').": ".get_lang("AddressField")
2195
                                                    ." ".get_lang('NotFound')."');
2196
                                            }
2197
                                        });
2198
                                    }
2199
                                }
2200
                            </script>
2201
                        ");
2202
                        $form->addHtml('
2203
                            <div class="form-group">
2204
                                <label for="geolocalization_extra_'.$field_details['variable'].'"
2205
                                    class="col-sm-2 control-label"></label>
2206
                                <div class="col-sm-8">
2207
                                    <button class="null btn btn-default"
2208
                                        id="geolocalization_extra_'.$field_details['variable'].'"
2209
                                        name="geolocalization_extra_'.$field_details['variable'].'"
2210
                                        type="submit">
2211
                                        <em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'
2212
                                    </button>
2213
                                    <button class="null btn btn-default" id="myLocation_extra_'.$field_details['variable'].'"
2214
                                        name="myLocation_extra_'.$field_details['variable'].'"
2215
                                        type="submit">
2216
                                        <em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'
2217
                                    </button>
2218
                                </div>
2219
                            </div>
2220
                        ');
2221
2222
                        $form->addHtml('
2223
                            <div class="form-group">
2224
                                <label for="map_extra_'.$field_details['variable'].'" class="col-sm-2 control-label">
2225
                                    '.$field_details['display_text'].' - '.get_lang('Map').'
2226
                                </label>
2227
                                <div class="col-sm-8">
2228
                                    <div name="map_extra_'.$field_details['variable'].'"
2229
                                        id="map_extra_'.$field_details['variable'].'" style="width:100%; height:300px;">
2230
                                    </div>
2231
                                </div>
2232
                            </div>
2233
                        ');
2234
                        break;
2235
                    case self::FIELD_TYPE_GEOLOCALIZATION_COORDINATES:
2236
                        $dataValue = isset($extraData['extra_'.$field_details['variable']])
2237
                            ? $extraData['extra_'.$field_details['variable']]
2238
                            : '';
2239
                        $form->addElement(
2240
                            'text',
2241
                            'extra_'.$field_details['variable'],
2242
                            $field_details['display_text'],
2243
                            ['id' => 'extra_'.$field_details['variable']]
2244
                        );
2245
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
2246
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
2247
                        if ($freezeElement) {
2248
                            $form->freeze('extra_'.$field_details['variable']);
2249
                        }
2250
                        $latLag = explode(",", $dataValue);
2251
2252
                        // if no value, set default coordinates value
2253
                        if (empty($dataValue)) {
2254
                            $lat = '-34.397';
2255
                            $lng = '150.644';
2256
                        } else {
2257
                            $lat = $latLag[0];
2258
                            $lng = $latLag[1];
2259
                        }
2260
2261
                        $form->addHtml("
2262
                            <script>
2263
                                $(document).ready(function() {
2264
                                    if (typeof google === 'object') {
2265
                                        var lat = '$lat';
2266
                                        var lng = '$lng';
2267
                                        var latLng = new google.maps.LatLng(lat, lng);
2268
                                        initializeGeo{$field_details['variable']}(false, latLng);
2269
2270
                                        $('#geolocalization_extra_{$field_details['variable']}').on('click', function() {
2271
                                            var latLng = $('#extra_{$field_details['variable']}').val().split(',');
2272
                                            var lat = latLng[0];
2273
                                            var lng = latLng[1];
2274
                                            var latLng = new google.maps.LatLng(lat, lng);
2275
                                            initializeGeo{$field_details['variable']}(false, latLng);
2276
                                            return false;
2277
                                        });
2278
2279
                                        $('#myLocation_extra_{$field_details['variable']}').on('click', function() {
2280
                                            myLocation{$field_details['variable']}();
2281
                                            return false;
2282
                                        });
2283
2284
                                        $('#extra_{$field_details['variable']}').keypress(function (event) {
2285
                                            if (event.which == 13) {
2286
                                                $('#geolocalization_extra_{$field_details['variable']}').click();
2287
                                                return false;
2288
                                            }
2289
                                        });
2290
2291
                                        return;
2292
                                    }
2293
2294
2295
                                    $('#map_extra_{$field_details['variable']}')
2296
                                        .html('<div class=\"alert alert-info\">"
2297
                                            .get_lang('YouNeedToActivateTheGoogleMapsPluginInAdminPlatformToSeeTheMap')
2298
                                            ."</div>');
2299
                                });
2300
2301
                                function myLocation{$field_details['variable']}() {
2302
                                    if (navigator.geolocation) {
2303
                                        var geoPosition = function(position) {
2304
                                            var lat = position.coords.latitude;
2305
                                            var lng = position.coords.longitude;
2306
                                            var latLng = new google.maps.LatLng(lat, lng);
2307
                                            initializeGeo{$field_details['variable']}(false, latLng)
2308
                                        };
2309
2310
                                        var geoError = function(error) {
2311
                                            alert('Geocode ".get_lang('Error').": ' + error);
2312
                                        };
2313
2314
                                        var geoOptions = {
2315
                                            enableHighAccuracy: true
2316
                                        };
2317
2318
                                        navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
2319
                                    }
2320
                                }
2321
2322
                                function initializeGeo{$field_details['variable']}(address, latLng) {
2323
                                    var geocoder = new google.maps.Geocoder();
2324
                                    var latlng = new google.maps.LatLng(-34.397, 150.644);
2325
                                    var myOptions = {
2326
                                        zoom: 15,
2327
                                        center: latlng,
2328
                                        mapTypeControl: true,
2329
                                        mapTypeControlOptions: {
2330
                                            style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
2331
                                        },
2332
                                        navigationControl: true,
2333
                                        mapTypeId: google.maps.MapTypeId.ROADMAP
2334
                                    };
2335
2336
                                    map_{$field_details['variable']} = new google.maps.Map(
2337
                                        document.getElementById('map_extra_{$field_details['variable']}'),
2338
                                        myOptions
2339
                                    );
2340
2341
                                    var parameter = address ? {'address': address} : latLng ? {'latLng': latLng} : false;
2342
2343
                                    if (geocoder && parameter) {
2344
                                        geocoder.geocode(parameter, function(results, status) {
2345
                                            if (status == google.maps.GeocoderStatus.OK) {
2346
                                                if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
2347
                                                    map_{$field_details['variable']}.setCenter(results[0].geometry.location);
2348
2349
                                                    $('#extra_{$field_details['variable']}')
2350
                                                        .val(results[0].geometry.location.lat() + ',' + results[0].geometry.location.lng());
2351
2352
                                                    var infowindow = new google.maps.InfoWindow({
2353
                                                        content: '<b>' + $('#extra_{$field_details['variable']}').val() + '</b>',
2354
                                                        size: new google.maps.Size(150, 50)
2355
                                                    });
2356
2357
                                                    var marker = new google.maps.Marker({
2358
                                                        position: results[0].geometry.location,
2359
                                                        map: map_{$field_details['variable']},
2360
                                                        title: $('#extra_{$field_details['variable']}').val()
2361
                                                    });
2362
                                                    google.maps.event.addListener(marker, 'click', function() {
2363
                                                        infowindow.open(map_{$field_details['variable']}, marker);
2364
                                                    });
2365
                                                } else {
2366
                                                    alert('".get_lang("NotFound")."');
2367
                                                }
2368
2369
                                            } else {
2370
                                                alert('Geocode ".get_lang('Error').": ' + status);
2371
                                            }
2372
                                        });
2373
                                    }
2374
                                }
2375
                            </script>
2376
                        ");
2377
                        $form->addHtml('
2378
                            <div class="form-group">
2379
                                <label for="geolocalization_extra_'.$field_details['variable'].'"
2380
                                    class="col-sm-2 control-label"></label>
2381
                                <div class="col-sm-8">
2382
                                    <button class="null btn btn-default "
2383
                                        id="geolocalization_extra_'.$field_details['variable'].'"
2384
                                        name="geolocalization_extra_'.$field_details['variable'].'"
2385
                                        type="submit">
2386
                                        <em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'
2387
                                    </button>
2388
                                    <button class="null btn btn-default"
2389
                                        id="myLocation_extra_'.$field_details['variable'].'"
2390
                                        name="myLocation_extra_'.$field_details['variable'].'" type="submit">
2391
                                        <em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'
2392
                                    </button>
2393
                                </div>
2394
                            </div>
2395
                        ');
2396
2397
                        $form->addHtml('
2398
                            <div class="form-group">
2399
                                <label for="map_extra_'.$field_details['variable'].'" class="col-sm-2 control-label">
2400
                                    '.$field_details['display_text'].' - '.get_lang('Map').'
2401
                                </label>
2402
                                <div class="col-sm-8">
2403
                                    <div name="map_extra_'.$field_details['variable'].'"
2404
                                        id="map_extra_'.$field_details['variable'].'"
2405
                                        style="width:100%; height:300px;">
2406
                                    </div>
2407
                                </div>
2408
                            </div>
2409
                        ');
2410
                        break;
2411
                    case self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
2412
                        $jquery_ready_content .= self::addSelectWithTextFieldElement(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::addSelectWithTextFieldElement() is not static, but was called statically. ( Ignorable by Annotation )

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

2412
                        $jquery_ready_content .= self::/** @scrutinizer ignore-call */ addSelectWithTextFieldElement(
Loading history...
2413
                            $form,
2414
                            $field_details,
2415
                            $freezeElement
2416
                        );
2417
                        break;
2418
                    case self::FIELD_TYPE_TRIPLE_SELECT:
2419
                        $jquery_ready_content .= self::addTripleSelectElement(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::addTripleSelectElement() is not static, but was called statically. ( Ignorable by Annotation )

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

2419
                        $jquery_ready_content .= self::/** @scrutinizer ignore-call */ addTripleSelectElement(
Loading history...
2420
                            $form,
2421
                            $field_details,
2422
                            is_array($extraData) ? $extraData : [],
2423
                            $freezeElement
2424
                        );
2425
                        break;
2426
                }
2427
            }
2428
        }
2429
2430
        $return = [];
2431
        $return['jquery_ready_content'] = $jquery_ready_content;
2432
2433
        return $return;
2434
    }
2435
2436
    /**
2437
     * @param $breadcrumb
2438
     * @param $action
2439
     */
2440
    public function setupBreadcrumb(&$breadcrumb, $action)
2441
    {
2442
        if ($action == 'add') {
2443
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
2444
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Add')];
2445
        } elseif ($action == 'edit') {
2446
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
2447
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Edit')];
2448
        } else {
2449
            $breadcrumb[] = ['url' => '#', 'name' => $this->pageName];
2450
        }
2451
    }
2452
2453
    /**
2454
     * Displays the title + grid
2455
     */
2456
    public function display()
2457
    {
2458
        // action links
2459
        echo '<div class="actions">';
2460
        echo '<a href="../admin/index.php">';
2461
        echo Display::return_icon(
2462
            'back.png',
2463
            get_lang('BackTo').' '.get_lang('PlatformAdmin'),
2464
            '',
2465
            ICON_SIZE_MEDIUM
2466
        );
2467
        echo '</a>';
2468
        echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'">';
2469
        echo Display::return_icon(
2470
            'add_user_fields.png',
2471
            get_lang('Add'),
2472
            '',
2473
            ICON_SIZE_MEDIUM
2474
        );
2475
        echo '</a>';
2476
        echo '</div>';
2477
        echo Display::grid_html($this->type.'_fields');
2478
    }
2479
2480
    /**
2481
     * @return array
2482
     */
2483
    public function getJqgridColumnNames()
2484
    {
2485
        return [
2486
            get_lang('Name'),
2487
            get_lang('FieldLabel'),
2488
            get_lang('Type'),
2489
            get_lang('FieldChangeability'),
2490
            get_lang('VisibleToSelf'),
2491
            get_lang('VisibleToOthers'),
2492
            get_lang('Filter'),
2493
            get_lang('FieldOrder'),
2494
            get_lang('Actions')
2495
        ];
2496
    }
2497
2498
    /**
2499
     * @return array
2500
     */
2501
    public function getJqgridColumnModel()
2502
    {
2503
        return [
2504
            [
2505
                'name' => 'display_text',
2506
                'index' => 'display_text',
2507
                'width' => '140',
2508
                'align' => 'left',
2509
            ],
2510
            [
2511
                'name' => 'variable',
2512
                'index' => 'variable',
2513
                'width' => '90',
2514
                'align' => 'left',
2515
                'sortable' => 'true',
2516
            ],
2517
            [
2518
                'name' => 'field_type',
2519
                'index' => 'field_type',
2520
                'width' => '70',
2521
                'align' => 'left',
2522
                'sortable' => 'true',
2523
            ],
2524
            [
2525
                'name' => 'changeable',
2526
                'index' => 'changeable',
2527
                'width' => '35',
2528
                'align' => 'left',
2529
                'sortable' => 'true',
2530
            ],
2531
            [
2532
                'name' => 'visible_to_self',
2533
                'index' => 'visible_to_self',
2534
                'width' => '45',
2535
                'align' => 'left',
2536
                'sortable' => 'true',
2537
            ],
2538
            [
2539
                'name' => 'visible_to_others',
2540
                'index' => 'visible_to_others',
2541
                'width' => '35',
2542
                'align' => 'left',
2543
                'sortable' => 'true',
2544
            ],
2545
            [
2546
                'name' => 'filter',
2547
                'index' => 'filter',
2548
                'width' => '30',
2549
                'align' => 'left',
2550
                'sortable' => 'true',
2551
            ],
2552
            [
2553
                'name' => 'field_order',
2554
                'index' => 'field_order',
2555
                'width' => '25',
2556
                'align' => 'left',
2557
                'sortable' => 'true',
2558
            ],
2559
            [
2560
                'name' => 'actions',
2561
                'index' => 'actions',
2562
                'width' => '40',
2563
                'align' => 'left',
2564
                'formatter' => 'action_formatter',
2565
                'sortable' => 'false',
2566
            ],
2567
        ];
2568
    }
2569
2570
    /**
2571
     * @param string $url
2572
     * @param string $action
2573
     * @return FormValidator
2574
     */
2575
    public function return_form($url, $action)
2576
    {
2577
        $form = new FormValidator($this->type.'_field', 'post', $url);
2578
2579
        $form->addElement('hidden', 'type', $this->type);
2580
        $id = isset($_GET['id']) ? intval($_GET['id']) : null;
2581
        $form->addElement('hidden', 'id', $id);
2582
2583
        // Setting the form elements
2584
        $header = get_lang('Add');
2585
        $defaults = [];
2586
2587
        if ($action == 'edit') {
2588
            $header = get_lang('Modify');
2589
            // Setting the defaults
2590
            $defaults = $this->get($id, false);
2591
        }
2592
2593
        $form->addElement('header', $header);
2594
2595
        if ($action == 'edit') {
2596
            $translateUrl = api_get_path(WEB_CODE_PATH).'extrafield/translate.php?'
2597
                .http_build_query(['extra_field' => $id]);
2598
            $translateButton = Display::toolbarButton(get_lang('TranslateThisTerm'), $translateUrl, 'language', 'link');
2599
2600
            $form->addText(
2601
                'display_text',
2602
                [get_lang('Name'), $translateButton]
2603
            );
2604
        } else {
2605
            $form->addElement('text', 'display_text', get_lang('Name'));
2606
        }
2607
2608
        // Field type
2609
        $types = self::get_field_types();
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_field_types() is not static, but was called statically. ( Ignorable by Annotation )

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

2609
        /** @scrutinizer ignore-call */ 
2610
        $types = self::get_field_types();
Loading history...
2610
2611
        $form->addElement(
2612
            'select',
2613
            'field_type',
2614
            get_lang('FieldType'),
2615
            $types,
2616
            ['id' => 'field_type']
2617
        );
2618
        $form->addElement('label', get_lang('Example'), '<div id="example">-</div>');
2619
        $form->addElement('text', 'variable', get_lang('FieldLabel'), ['class' => 'span5']);
2620
        $form->addElement(
2621
            'text',
2622
            'field_options',
2623
            get_lang('FieldPossibleValues'),
2624
            ['id' => 'field_options', 'class' => 'span6']
2625
        );
2626
2627
        $fieldWithOptions = [
2628
            self::FIELD_TYPE_RADIO,
2629
            self::FIELD_TYPE_SELECT_MULTIPLE,
2630
            self::FIELD_TYPE_SELECT,
2631
            self::FIELD_TYPE_TAG,
2632
            self::FIELD_TYPE_DOUBLE_SELECT,
2633
            self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD,
2634
            self::FIELD_TYPE_TRIPLE_SELECT
2635
        ];
2636
2637
        if ($action == 'edit') {
2638
            if (in_array($defaults['field_type'], $fieldWithOptions)) {
2639
                $url = Display::url(
2640
                    get_lang('EditExtraFieldOptions'),
2641
                    'extra_field_options.php?type='.$this->type.'&field_id='.$id
2642
                );
2643
                $form->addElement('label', null, $url);
2644
2645
                if ($defaults['field_type'] == self::FIELD_TYPE_SELECT) {
2646
                    $urlWorkFlow = Display::url(
2647
                        get_lang('EditExtraFieldWorkFlow'),
2648
                        'extra_field_workflow.php?type='.$this->type.'&field_id='.$id
2649
                    );
2650
                    $form->addElement('label', null, $urlWorkFlow);
2651
                }
2652
2653
                $form->freeze('field_options');
2654
            }
2655
        }
2656
        $form->addElement(
2657
            'text',
2658
            'default_value',
2659
            get_lang('FieldDefaultValue'),
2660
            ['id' => 'default_value']
2661
        );
2662
2663
        $group = [];
2664
        $group[] = $form->createElement('radio', 'visible_to_self', null, get_lang('Yes'), 1);
2665
        $group[] = $form->createElement('radio', 'visible_to_self', null, get_lang('No'), 0);
2666
        $form->addGroup($group, '', get_lang('VisibleToSelf'), null, false);
2667
2668
        $group = [];
2669
        $group[] = $form->createElement('radio', 'visible_to_others', null, get_lang('Yes'), 1);
2670
        $group[] = $form->createElement('radio', 'visible_to_others', null, get_lang('No'), 0);
2671
        $form->addGroup($group, '', get_lang('VisibleToOthers'), null, false);
2672
2673
        $group = [];
2674
        $group[] = $form->createElement('radio', 'changeable', null, get_lang('Yes'), 1);
2675
        $group[] = $form->createElement('radio', 'changeable', null, get_lang('No'), 0);
2676
        $form->addGroup($group, '', get_lang('FieldChangeability'), null, false);
2677
2678
        $group = [];
2679
        $group[] = $form->createElement('radio', 'filter', null, get_lang('Yes'), 1);
2680
        $group[] = $form->createElement('radio', 'filter', null, get_lang('No'), 0);
2681
        $form->addGroup($group, '', get_lang('FieldFilter'), null, false);
2682
2683
        /* Enable this when field_loggeable is introduced as a table field (2.0)
2684
        $group   = array();
2685
        $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('Yes'), 1);
2686
        $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('No'), 0);
2687
        $form->addGroup($group, '', get_lang('FieldLoggeable'), '', false);
2688
        */
2689
2690
        $form->addElement('text', 'field_order', get_lang('FieldOrder'));
2691
2692
        if ($action == 'edit') {
2693
            $option = new ExtraFieldOption($this->type);
2694
            $defaults['field_options'] = $option->get_field_options_by_field_to_string($id);
2695
            $form->addButtonUpdate(get_lang('Modify'));
2696
        } else {
2697
            $defaults['visible_to_self'] = 0;
2698
            $defaults['visible_to_others'] = 0;
2699
            $defaults['changeable'] = 0;
2700
            $defaults['filter'] = 0;
2701
            $form->addButtonCreate(get_lang('Add'));
2702
        }
2703
2704
        /*if (!empty($defaults['created_at'])) {
2705
            $defaults['created_at'] = api_convert_and_format_date($defaults['created_at']);
2706
        }
2707
        if (!empty($defaults['updated_at'])) {
2708
            $defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']);
2709
        }*/
2710
        $form->setDefaults($defaults);
2711
2712
        // Setting the rules
2713
        $form->addRule('display_text', get_lang('ThisFieldIsRequired'), 'required');
2714
        $form->addRule('field_type', get_lang('ThisFieldIsRequired'), 'required');
2715
2716
        return $form;
2717
    }
2718
2719
    /**
2720
     * @param $token
2721
     * @return string
2722
     */
2723
    public function getJqgridActionLinks($token)
2724
    {
2725
        //With this function we can add actions to the jgrid (edit, delete, etc)
2726
        $editIcon = Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL);
2727
        $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2728
        $confirmMessage = addslashes(
2729
            api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES)
2730
        );
2731
2732
        $editButton = <<<JAVASCRIPT
2733
            <a href="?action=edit&type={$this->type}&id=' + options.rowId + '" class="btn btn-link btn-xs">\
2734
                $editIcon\
2735
            </a>
2736
JAVASCRIPT;
2737
        $deleteButton = <<<JAVASCRIPT
2738
            <a \
2739
                onclick="if (!confirm(\'$confirmMessage\')) {return false;}" \
2740
                href="?sec_token=$token&type={$this->type}&id=' + options.rowId + '&action=delete" \
2741
                class="btn btn-link btn-xs">\
2742
                $deleteIcon\
2743
            </a>
2744
JAVASCRIPT;
2745
2746
        return "function action_formatter(cellvalue, options, rowObject) {        
2747
            return '$editButton $deleteButton';
2748
        }";
2749
    }
2750
2751
    /**
2752
     * @param array $columns
2753
     * @param array $column_model
2754
     * @param array $extraFields
2755
     * @return array
2756
     */
2757
    public function getRules(&$columns, &$column_model, $extraFields = [], $checkExtraFieldExistence = false)
2758
    {
2759
        $fields = $this->get_all(
2760
            [
2761
                'visible_to_self = ? AND filter = ?' => [1, 1]
2762
            ],
2763
            'display_text'
2764
        );
2765
        $extraFieldOption = new ExtraFieldOption($this->type);
2766
2767
        $rules = [];
2768
        if (!empty($fields)) {
2769
            foreach ($fields as $field) {
2770
                $search_options = [];
2771
                $type = 'text';
2772
                if (in_array($field['field_type'], [self::FIELD_TYPE_SELECT, self::FIELD_TYPE_DOUBLE_SELECT])) {
2773
                    $type = 'select';
2774
                    $search_options['sopt'] = ['eq', 'ne']; //equal not equal
2775
                } else {
2776
                    $search_options['sopt'] = ['cn', 'nc']; //contains not contains
2777
                }
2778
2779
                $search_options['searchhidden'] = 'true';
2780
                $search_options['defaultValue'] = isset($search_options['field_default_value'])
2781
                    ? $search_options['field_default_value']
2782
                    : null;
2783
2784
                if ($field['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
2785
                    //Add 2 selects
2786
                    $options = $extraFieldOption->get_field_options_by_field($field['id']);
2787
                    $options = self::extra_field_double_select_convert_array_to_ordered_array($options);
2788
                    $first_options = [];
2789
2790
                    if (!empty($options)) {
2791
                        foreach ($options as $option) {
2792
                            foreach ($option as $sub_option) {
2793
                                if ($sub_option['option_value'] == 0) {
2794
                                    $first_options[] = $sub_option['field_id'].'#'.$sub_option['id'].':'
2795
                                        .$sub_option['display_text'];
2796
                                }
2797
                            }
2798
                        }
2799
                    }
2800
2801
                    $search_options['value'] = implode(';', $first_options);
2802
                    $search_options['dataInit'] = 'fill_second_select';
2803
2804
                    // First
2805
                    $column_model[] = [
2806
                        'name' => 'extra_'.$field['variable'],
2807
                        'index' => 'extra_'.$field['variable'],
2808
                        'width' => '100',
2809
                        'hidden' => 'true',
2810
                        'search' => 'true',
2811
                        'stype' => 'select',
2812
                        'searchoptions' => $search_options,
2813
                    ];
2814
                    $columns[] = $field['display_text'].' (1)';
2815
                    $rules[] = [
2816
                        'field' => 'extra_'.$field['variable'],
2817
                        'op' => 'cn',
2818
                    ];
2819
2820
                    // Second
2821
                    $search_options['value'] = $field['id'].':';
2822
                    $search_options['dataInit'] = 'register_second_select';
2823
2824
                    $column_model[] = [
2825
                        'name' => 'extra_'.$field['variable'].'_second',
2826
                        'index' => 'extra_'.$field['variable'].'_second',
2827
                        'width' => '100',
2828
                        'hidden' => 'true',
2829
                        'search' => 'true',
2830
                        'stype' => 'select',
2831
                        'searchoptions' => $search_options,
2832
                    ];
2833
                    $columns[] = $field['display_text'].' (2)';
2834
                    $rules[] = ['field' => 'extra_'.$field['variable'].'_second', 'op' => 'cn'];
2835
                    continue;
2836
                } else {
2837
                    $search_options['value'] = $extraFieldOption->getFieldOptionsToString(
2838
                        $field['id'],
2839
                        false,
2840
                        'display_text'
2841
                    );
2842
                }
2843
                $column_model[] = [
2844
                    'name' => 'extra_'.$field['variable'],
2845
                    'index' => 'extra_'.$field['variable'],
2846
                    'width' => '100',
2847
                    'hidden' => 'true',
2848
                    'search' => 'true',
2849
                    'stype' => $type,
2850
                    'searchoptions' => $search_options,
2851
                ];
2852
                $columns[] = $field['display_text'];
2853
                $rules[] = [
2854
                    'field' => 'extra_'.$field['variable'],
2855
                    'op' => 'cn'
2856
                ];
2857
            }
2858
        }
2859
2860
        return $rules;
2861
    }
2862
2863
    /**
2864
     * @param array $options
2865
     * @return array
2866
     */
2867
    public function parseConditions($options)
2868
    {
2869
        $inject_extra_fields = null;
2870
        $extraFieldOption = new ExtraFieldOption($this->type);
2871
        $double_fields = [];
2872
2873
        if (isset($options['extra'])) {
2874
            $extra_fields = $options['extra'];
2875
            if (!empty($extra_fields)) {
2876
                $counter = 1;
2877
                foreach ($extra_fields as &$extra) {
2878
                    $extra_field_obj = new ExtraField($this->type);
2879
                    $extra_field_info = $extra_field_obj->get($extra['id']);
2880
                    $extra['extra_field_info'] = $extra_field_info;
2881
2882
                    if (isset($extra_field_info['field_type']) &&
2883
                        in_array(
2884
                            $extra_field_info['field_type'],
2885
                            [
2886
                                self::FIELD_TYPE_SELECT,
2887
                                self::FIELD_TYPE_SELECT,
2888
                                self::FIELD_TYPE_DOUBLE_SELECT
2889
                            ]
2890
                        )
2891
                    ) {
2892
                        $inject_extra_fields .= " fvo$counter.display_text as {$extra['field']}, ";
2893
                    } else {
2894
                        $inject_extra_fields .= " fv$counter.value as {$extra['field']}, ";
2895
                    }
2896
2897
                    if (isset($extra_fields_info[$extra['id']])) {
2898
                        $info = $extra_fields_info[$extra['id']];
2899
                    } else {
2900
                        $info = $this->get($extra['id']);
2901
                        $extra_fields_info[$extra['id']] = $info;
2902
                    }
2903
                    if (isset($info['field_type']) && $info['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
2904
                        $double_fields[$info['id']] = $info;
2905
                    }
2906
                    $counter++;
2907
                }
2908
            }
2909
        }
2910
2911
        $options_by_double = [];
2912
        foreach ($double_fields as $double) {
2913
            $my_options = $extraFieldOption->get_field_options_by_field(
2914
                $double['id'],
2915
                true
2916
            );
2917
            $options_by_double['extra_'.$double['variable']] = $my_options;
2918
        }
2919
2920
        $field_value_to_join = [];
2921
        //filter can be all/any = and/or
2922
        $inject_joins = null;
2923
        $inject_where = null;
2924
        $where = null;
2925
2926
        if (!empty($options['where'])) {
2927
            if (!empty($options['extra'])) {
2928
                // Removing double 1=1
2929
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
2930
                // Always OR
2931
                $counter = 1;
2932
                foreach ($extra_fields as $extra_info) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $extra_fields does not seem to be defined for all execution paths leading up to this point.
Loading history...
2933
                    $extra_field_info = $extra_info['extra_field_info'];
2934
                    $inject_joins .= " INNER JOIN $this->table_field_values fv$counter
2935
                                       ON (s.".$this->primaryKey." = fv$counter.".$this->handler_id.") ";
2936
                    // Add options
2937
                    if (isset($extra_field_info['field_type']) &&
2938
                        in_array(
2939
                            $extra_field_info['field_type'],
2940
                            [
2941
                                self::FIELD_TYPE_SELECT,
2942
                                self::FIELD_TYPE_SELECT,
2943
                                self::FIELD_TYPE_DOUBLE_SELECT
2944
                            ]
2945
                        )
2946
                    ) {
2947
                        $options['where'] = str_replace(
2948
                            $extra_info['field'],
2949
                            'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fvo'.$counter.'.option_value',
2950
                            $options['where']
2951
                        );
2952
                        $inject_joins .= "
2953
                             INNER JOIN $this->table_field_options fvo$counter
2954
                             ON (
2955
                                fv$counter.field_id = fvo$counter.field_id AND
2956
                                fv$counter.value = fvo$counter.option_value
2957
                             )
2958
                            ";
2959
                    } else {
2960
                        if (isset($extra_field_info['field_type']) &&
2961
                            $extra_field_info['field_type'] == self::FIELD_TYPE_TAG
2962
                        ) {
2963
                            $options['where'] = str_replace(
2964
                                $extra_info['field'],
2965
                                'tag'.$counter.'.tag ',
2966
                                $options['where']
2967
                            );
2968
2969
                            $inject_joins .= "
2970
                                INNER JOIN $this->table_field_rel_tag tag_rel$counter
2971
                                ON (
2972
                                    tag_rel$counter.field_id = ".$extra_info['id']." AND 
2973
                                    tag_rel$counter.item_id = s.".$this->primaryKey."
2974
                                )
2975
                                INNER JOIN $this->table_field_tag tag$counter
2976
                                ON (tag$counter.id = tag_rel$counter.tag_id)
2977
                            ";
2978
                        } else {
2979
                            //text, textarea, etc
2980
                            $options['where'] = str_replace(
2981
                                $extra_info['field'],
2982
                                'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fv'.$counter.'.value',
2983
                                $options['where']
2984
                            );
2985
                        }
2986
                    }
2987
2988
                    $field_value_to_join[] = " fv$counter.$this->handler_id ";
2989
                    $counter++;
2990
                }
2991
                if (!empty($field_value_to_join)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
2992
                    //$inject_where .= " AND s.id = ".implode(' = ', $field_value_to_join);
2993
                }
2994
            }
2995
            $where .= ' AND '.$options['where'];
2996
        }
2997
2998
        $order = null;
2999
        if (!empty($options['order'])) {
3000
            $order = " ORDER BY ".$options['order'];
3001
        }
3002
        $limit = null;
3003
        if (!empty($options['limit'])) {
3004
            $limit = " LIMIT ".$options['limit'];
3005
        }
3006
3007
        return [
3008
            'order' => $order,
3009
            'limit' => $limit,
3010
            'where' => $where,
3011
            'inject_where' => $inject_where,
3012
            'inject_joins' => $inject_joins,
3013
            'field_value_to_join' => $field_value_to_join,
3014
            'inject_extra_fields' => $inject_extra_fields,
3015
        ];
3016
    }
3017
3018
    //@todo move this in the display_class or somewhere else
3019
    /**
3020
     * @param $col
3021
     * @param $oper
3022
     * @param $val
3023
     * @return string
3024
     */
3025
    public function get_where_clause($col, $oper, $val)
3026
    {
3027
        if (empty($col)) {
3028
            return '';
3029
        }
3030
        if ($oper == 'bw' || $oper == 'bn') {
3031
            $val .= '%';
3032
        }
3033
        if ($oper == 'ew' || $oper == 'en') {
3034
            $val = '%'.$val;
3035
        }
3036
        if ($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') {
3037
            if (is_array($val)) {
3038
                $result = '"%'.implode(';', $val).'%"';
3039
                foreach ($val as $item) {
3040
                    $item = trim($item);
3041
                    $result .= ' OR '.$col.' LIKE "%'.$item.'%"';
3042
                }
3043
                $val = $result;
3044
3045
                return " $col {$this->ops[$oper]} $val ";
3046
            } else {
3047
                $val = '%'.$val.'%';
3048
            }
3049
        }
3050
        $val = \Database::escape_string($val);
3051
3052
        return " $col {$this->ops[$oper]} '$val' ";
3053
    }
3054
3055
    /**
3056
     * @param $filters
3057
     * @param string $stringToSearch
3058
     * @return array
3059
     */
3060
    public function getExtraFieldRules($filters, $stringToSearch = 'extra_')
3061
    {
3062
        $extra_fields = [];
3063
3064
        // Getting double select if exists
3065
        $double_select = [];
3066
        foreach ($filters->rules as $rule) {
3067
            if (empty($rule)) {
3068
                continue;
3069
            }
3070
            if (strpos($rule->field, '_second') === false) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
3071
            } else {
3072
                $my_field = str_replace('_second', '', $rule->field);
3073
                $double_select[$my_field] = $rule->data;
3074
            }
3075
        }
3076
3077
        $condition_array = [];
3078
        foreach ($filters->rules as $rule) {
3079
            if (empty($rule)) {
3080
                continue;
3081
            }
3082
            if (strpos($rule->field, $stringToSearch) === false) {
3083
                // normal fields
3084
                $field = $rule->field;
3085
                if (isset($rule->data) && is_string($rule->data) && $rule->data != -1) {
3086
                    $condition_array[] = $this->get_where_clause($field, $rule->op, $rule->data);
3087
                }
3088
            } else {
3089
                // Extra fields
3090
                if (strpos($rule->field, '_second') === false) {
3091
                    //No _second
3092
                    $original_field = str_replace($stringToSearch, '', $rule->field);
3093
                    $field_option = $this->get_handler_field_info_by_field_variable($original_field);
3094
3095
                    if ($field_option['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
3096
                        if (isset($double_select[$rule->field])) {
3097
                            $data = explode('#', $rule->data);
3098
                            $rule->data = $data[1].'::'.$double_select[$rule->field];
3099
                        } else {
3100
                            // only was sent 1 select
3101
                            if (is_string($rule->data)) {
3102
                                $data = explode('#', $rule->data);
3103
                                $rule->data = $data[1];
3104
                            }
3105
                        }
3106
3107
                        if (!isset($rule->data)) {
3108
                            $condition_array[] = ' ('
3109
                                .$this->get_where_clause($rule->field, $rule->op, $rule->data)
3110
                                .') ';
3111
                            $extra_fields[] = ['field' => $rule->field, 'id' => $field_option['id']];
3112
                        }
3113
                    } else {
3114
                        if (isset($rule->data)) {
3115
                            if ($rule->data == -1) {
3116
                                continue;
3117
                            }
3118
                            $condition_array[] = ' ('
3119
                                .$this->get_where_clause($rule->field, $rule->op, $rule->data)
3120
                                .') ';
3121
                            $extra_fields[] = [
3122
                                'field' => $rule->field,
3123
                                'id' => $field_option['id'],
3124
                                'data' => $rule->data
3125
                            ];
3126
                        }
3127
                    }
3128
                } else {
3129
                    $my_field = str_replace('_second', '', $rule->field);
3130
                    $original_field = str_replace($stringToSearch, '', $my_field);
3131
                    $field_option = $this->get_handler_field_info_by_field_variable($original_field);
3132
                    $extra_fields[] = [
3133
                        'field' => $rule->field,
3134
                        'id' => $field_option['id']
3135
                    ];
3136
                }
3137
            }
3138
        }
3139
3140
        return [
3141
            'extra_fields' => $extra_fields,
3142
            'condition_array' => $condition_array
3143
        ];
3144
    }
3145
3146
    /**
3147
     * Get the extra fields and their formatted values
3148
     * @param int|string $itemId The item ID (It could be a session_id, course_id or user_id)
3149
     * @return array The extra fields data
3150
     */
3151
    public function getDataAndFormattedValues($itemId)
3152
    {
3153
        $valuesData = [];
3154
        $fields = $this->get_all();
3155
        $em = Database::getManager();
3156
3157
        foreach ($fields as $field) {
3158
            if ($field['visible_to_self'] != '1') {
3159
                continue;
3160
            }
3161
3162
            $fieldValue = new ExtraFieldValue($this->type);
3163
            $valueData = $fieldValue->get_values_by_handler_and_field_id(
3164
                $itemId,
0 ignored issues
show
Bug introduced by
It seems like $itemId can also be of type string; however, parameter $item_id of ExtraFieldValue::get_val..._handler_and_field_id() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

3164
                /** @scrutinizer ignore-type */ $itemId,
Loading history...
3165
                $field['id'],
3166
                true
3167
            );
3168
3169
            if ($field['field_type'] == ExtraField::FIELD_TYPE_TAG) {
3170
                $tags = $em
3171
                    ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
3172
                    ->findBy(
3173
                        [
3174
                            'fieldId' => $field['id'],
3175
                            'itemId' => $itemId,
3176
                        ]
3177
                    );
3178
                if ($tags) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tags of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3179
                    /** @var \Chamilo\CoreBundle\Entity\ExtraFieldRelTag $tag */
3180
                    $data = [];
3181
                    foreach ($tags as $extraFieldTag) {
3182
                        /** @var \Chamilo\CoreBundle\Entity\Tag $tag */
3183
                        $tag = $em->find('ChamiloCoreBundle:Tag', $extraFieldTag->getTagId());
3184
                        /*$data[] = [
3185
                            'id' => $extraFieldTag->getTagId(),
3186
                            'value' => $tag->getTag()
3187
                        ];*/
3188
                        $data[] = $tag->getTag();
3189
                    }
3190
                    $valueData = implode(',', $data);
3191
                }
3192
            }
3193
3194
            if (!$valueData) {
3195
                continue;
3196
            }
3197
3198
            $displayedValue = get_lang('None');
3199
3200
            switch ($field['field_type']) {
3201
                case self::FIELD_TYPE_CHECKBOX:
3202
                    if ($valueData !== false && $valueData['value'] == '1') {
3203
                        $displayedValue = get_lang('Yes');
3204
                    } else {
3205
                        $displayedValue = get_lang('No');
3206
                    }
3207
                    break;
3208
                case self::FIELD_TYPE_DATE:
3209
                    if ($valueData !== false && !empty($valueData['value'])) {
3210
                        $displayedValue = api_format_date($valueData['value'], DATE_FORMAT_LONG_NO_DAY);
3211
                    }
3212
                    break;
3213
                case self::FIELD_TYPE_TAG:
3214
                    if (!empty($valueData)) {
3215
                        $displayedValue = $valueData;
3216
                    }
3217
                    break;
3218
                case self::FIELD_TYPE_FILE_IMAGE:
3219
                    if ($valueData === false || empty($valueData['value'])) {
3220
                        break;
3221
                    }
3222
3223
                    if (!file_exists(api_get_path(SYS_UPLOAD_PATH).$valueData['value'])) {
3224
                        break;
3225
                    }
3226
3227
                    $image = Display::img(
3228
                        api_get_path(WEB_UPLOAD_PATH).$valueData['value'],
3229
                        $field['display_text'],
3230
                        ['width' => '300']
3231
                    );
3232
3233
                    $displayedValue = Display::url(
3234
                        $image,
3235
                        api_get_path(WEB_UPLOAD_PATH).$valueData['value'],
3236
                        ['target' => '_blank']
3237
                    );
3238
                    break;
3239
                case self::FIELD_TYPE_FILE:
3240
                    if ($valueData === false || empty($valueData['value'])) {
3241
                        break;
3242
                    }
3243
3244
                    if (!file_exists(api_get_path(SYS_UPLOAD_PATH).$valueData['value'])) {
3245
                        break;
3246
                    }
3247
3248
                    $displayedValue = Display::url(
3249
                        get_lang('Download'),
3250
                        api_get_path(WEB_UPLOAD_PATH).$valueData['value'],
3251
                        [
3252
                            'title' => $field['display_text'],
3253
                            'target' => '_blank'
3254
                        ]
3255
                    );
3256
                    break;
3257
                default:
3258
                    $displayedValue = $valueData['value'];
3259
                    break;
3260
            }
3261
3262
            $valuesData[] = [
3263
                'text' => $field['display_text'],
3264
                'value' => $displayedValue
3265
            ];
3266
        }
3267
3268
        return $valuesData;
3269
    }
3270
3271
    /**
3272
     * Gets an element
3273
     * @param int $id
3274
     * @param bool $translateDisplayText Optional
3275
     * @return array
3276
     */
3277
    public function get($id, $translateDisplayText = true)
3278
    {
3279
        $info = parent::get($id);
3280
3281
        if ($translateDisplayText) {
3282
            $info['display_text'] = self::translateDisplayName($info['variable'], $info['display_text']);
3283
        }
3284
3285
        return $info;
3286
    }
3287
3288
    /**
3289
     * Translate the display text for a extra field
3290
     * @param string $variable
3291
     * @param string $defaultDisplayText
3292
     * @return string
3293
     */
3294
    public static function translateDisplayName($variable, $defaultDisplayText)
3295
    {
3296
        $camelCase = api_underscore_to_camel_case($variable);
3297
3298
        return isset($GLOBALS[$camelCase]) ? $GLOBALS[$camelCase] : $defaultDisplayText;
3299
    }
3300
3301
    /**
3302
     * @param int $fieldId
3303
     * @param string $tag
3304
     *
3305
     * @return array
3306
     */
3307
    public function getAllUserPerTag($fieldId, $tag)
3308
    {
3309
        $tagRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
3310
        $tag = Database::escape_string($tag);
3311
        $fieldId = (int) $fieldId;
3312
3313
        $sql = "SELECT user_id 
3314
                FROM {$this->table_field_tag} f INNER JOIN $tagRelUserTable ft 
3315
                ON tag_id = f.id 
3316
                WHERE tag = '$tag' AND f.field_id = $fieldId;
3317
        ";
3318
3319
        $result = Database::query($sql);
3320
3321
        return Database::store_result($result, 'ASSOC');
3322
    }
3323
3324
    /**
3325
     * @param int $fieldId
3326
     * @param int $tagId
3327
     *
3328
     * @return array
3329
     */
3330
    public function getAllSkillPerTag($fieldId, $tagId)
3331
    {
3332
        $skillTable = Database::get_main_table(TABLE_MAIN_SKILL);
3333
        $tagRelExtraTable = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
3334
        $fieldId = intval($fieldId);
3335
        $tagId = intval($tagId);
3336
3337
        $sql = "SELECT s.id
3338
                FROM $skillTable s INNER JOIN $tagRelExtraTable t
3339
                ON t.item_id = s.id
3340
                WHERE tag_id = $tagId AND t.field_id = $fieldId;
3341
        ";
3342
3343
        $result = Database::query($sql);
3344
        $result = Database::store_result($result, 'ASSOC');
3345
3346
        $skillList = [];
3347
        foreach ($result as $index => $value) {
3348
            $skillList[$value['id']] = $value['id'];
3349
        }
3350
3351
        return $skillList;
3352
    }
3353
3354
    /**
3355
     * @param string $from
3356
     * @param string $search
3357
     * @param array $options
3358
     *
3359
     * @return array
3360
     */
3361
    public function searchOptionsFromTags($from, $search, $options)
3362
    {
3363
        $extraFieldInfo = $this->get_handler_field_info_by_field_variable(
3364
            str_replace('extra_', '', $from)
3365
        );
3366
        $extraFieldInfoTag = $this->get_handler_field_info_by_field_variable(
3367
            str_replace('extra_', '', $search)
3368
        );
3369
3370
        if (empty($extraFieldInfo) || empty($extraFieldInfoTag)) {
3371
            return [];
3372
        }
3373
3374
        $id = $extraFieldInfo['id'];
3375
        $tagId = $extraFieldInfoTag['id'];
3376
3377
        $table = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
3378
        $tagRelExtraTable = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
3379
        $tagTable = Database::get_main_table(TABLE_MAIN_TAG);
3380
        $optionsTable = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
3381
3382
        $sql = "SELECT DISTINCT t.*, v.value, o.display_text
3383
                FROM $tagRelExtraTable te 
3384
                INNER JOIN $tagTable t
3385
                ON (t.id = te.tag_id AND te.field_id = t.field_id AND te.field_id = $tagId) 
3386
                INNER JOIN $table v
3387
                ON (te.item_id = v.item_id AND v.field_id = $id)
3388
                INNER JOIN $optionsTable o
3389
                ON (o.option_value = v.value)
3390
                WHERE v.value IN ('".implode("','", $options)."')                           
3391
                ORDER BY o.option_order, t.tag
3392
               ";
3393
3394
        $result = Database::query($sql);
3395
        $result = Database::store_result($result);
3396
        return $result;
3397
    }
3398
}
3399