Completed
Push — master ( c341b0...5d80e7 )
by Julito
09:18
created

ExtraField::set_extra_fields_in_form()   F

Complexity

Conditions 125
Paths 3

Size

Total Lines 801
Code Lines 500

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 125
eloc 500
nc 3
nop 16
dl 0
loc 801
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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

559
            /** @scrutinizer ignore-type */ $extraData,
Loading history...
560
            $adminPermissions,
561
            $extraFields,
562
            $itemId,
563
            $exclude,
564
            $useTagAsSelect,
565
            $showOnlyTheseFields,
566
            $orderFields,
567
            $orderDependingDefaults,
568
            $separateExtraMultipleSelect,
569
            $customLabelsExtraMultipleSelect,
570
            $addEmptyOptionSelects,
571
            $introductionTextList,
572
            $hideGeoLocalizationDetails,
573
            $help
574
        );
575
576
        if (!empty($requiredFields)) {
577
            /** @var HTML_QuickForm_input $element */
578
            foreach ($form->getElements() as $element) {
579
                $name = str_replace('extra_', '', $element->getName());
580
                if (in_array($name, $requiredFields)) {
581
                    $form->setRequired($element);
582
                }
583
            }
584
        }
585
586
        return $extra;
587
    }
588
589
    /**
590
     * Return an array of all the extra fields available for this item.
591
     *
592
     * @param int $itemId (session_id, question_id, course id)
593
     *
594
     * @return array
595
     */
596
    public function get_handler_extra_data($itemId)
597
    {
598
        if (empty($itemId)) {
599
            return [];
600
        }
601
602
        $extra_data = [];
603
        $fields = $this->get_all();
604
        $field_values = new ExtraFieldValue($this->type);
605
606
        if (!empty($fields) > 0) {
607
            foreach ($fields as $field) {
608
                $field_value = $field_values->get_values_by_handler_and_field_id(
609
                    $itemId,
610
                    $field['id']
611
                );
612
613
                if ($field['field_type'] == self::FIELD_TYPE_TAG) {
614
                    $tags = UserManager::get_user_tags_to_string(
615
                        $itemId,
616
                        $field['id'],
617
                        false
618
                    );
619
                    $extra_data['extra_'.$field['variable']] = $tags;
620
621
                    continue;
622
                }
623
624
                if ($field_value) {
625
                    $variable = $field['variable'];
626
                    $field_value = $field_value['value'];
627
                    switch ($field['field_type']) {
628
                        case self::FIELD_TYPE_TAG:
629
                            $tags = UserManager::get_user_tags_to_string(
630
                                $itemId,
631
                                $field['id'],
632
                                false
633
                            );
634
635
                            $extra_data['extra_'.$field['variable']] = $tags;
636
                            break;
637
                        case self::FIELD_TYPE_DOUBLE_SELECT:
638
                        case self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
639
                            $selected_options = explode('::', $field_value);
640
                            $firstOption = isset($selected_options[0]) ? $selected_options[0] : '';
641
                            $secondOption = isset($selected_options[1]) ? $selected_options[1] : '';
642
                            $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $firstOption;
643
                            $extra_data['extra_'.$field['variable']]['extra_'.$field['variable'].'_second'] = $secondOption;
644
645
                            break;
646
                        case self::FIELD_TYPE_SELECT_MULTIPLE:
647
                            $field_value = explode(';', $field_value);
648
                            $extra_data['extra_'.$field['variable']] = $field_value;
649
                            break;
650
                        case self::FIELD_TYPE_RADIO:
651
                            $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $field_value;
652
                            break;
653
                        case self::FIELD_TYPE_TRIPLE_SELECT:
654
                            list($level1, $level2, $level3) = explode(';', $field_value);
655
656
                            $extra_data["extra_$variable"]["extra_$variable"] = $level1;
657
                            $extra_data["extra_$variable"]["extra_{$variable}_second"] = $level2;
658
                            $extra_data["extra_$variable"]["extra_{$variable}_third"] = $level3;
659
                            break;
660
                        default:
661
                            $extra_data['extra_'.$field['variable']] = $field_value;
662
                            break;
663
                    }
664
                } else {
665
                    // Set default values
666
                    if (isset($field['field_default_value']) &&
667
                        !empty($field['field_default_value'])
668
                    ) {
669
                        $extra_data['extra_'.$field['variable']] = $field['field_default_value'];
670
                    }
671
                }
672
            }
673
        }
674
675
        return $extra_data;
676
    }
677
678
    /**
679
     * @param string $field_type
680
     *
681
     * @return array
682
     */
683
    public function get_all_extra_field_by_type($field_type)
684
    {
685
        // all the information of the field
686
        $sql = "SELECT * FROM {$this->table}
687
                WHERE
688
                    field_type = '".Database::escape_string($field_type)."' AND
689
                    extra_field_type = $this->extraFieldType
690
                ";
691
        $result = Database::query($sql);
692
693
        $return = [];
694
        while ($row = Database::fetch_array($result)) {
695
            $return[] = $row['id'];
696
        }
697
698
        return $return;
699
    }
700
701
    /**
702
     * @return array
703
     */
704
    public function get_field_types()
705
    {
706
        return $this->get_extra_fields_by_handler($this->type);
707
    }
708
709
    /**
710
     * @param int $id
711
     */
712
    public function get_field_type_by_id($id)
713
    {
714
        $types = $this->get_field_types();
715
        if (isset($types[$id])) {
716
            return $types[$id];
717
        }
718
719
        return null;
720
    }
721
722
    /**
723
     * Converts a string like this:
724
     * France:Paris;Bretagne;Marseille;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura;
725
     * into
726
     * array(
727
     *   'France' =>
728
     *      array('Paris', 'Bretagne', 'Marseille'),
729
     *   'Belgique' =>
730
     *      array('Namur', 'Liège')
731
     * ), etc.
732
     *
733
     * @param string $string
734
     *
735
     * @return array
736
     */
737
    public static function extra_field_double_select_convert_string_to_array($string)
738
    {
739
        $options = explode('|', $string);
740
        $options_parsed = [];
741
        $id = 0;
742
743
        if (!empty($options)) {
744
            foreach ($options as $sub_options) {
745
                $options = explode(':', $sub_options);
746
                $sub_sub_options = isset($options[1]) ? explode(';', $options[1]) : [];
747
                $options_parsed[$id] = [
748
                    'label' => $options[0],
749
                    'options' => $sub_sub_options,
750
                ];
751
                $id++;
752
            }
753
        }
754
755
        return $options_parsed;
756
    }
757
758
    /**
759
     * @param $string
760
     *
761
     * @return array
762
     */
763
    public static function tripleSelectConvertStringToArray($string)
764
    {
765
        $options = [];
766
767
        foreach (explode('|', $string) as $i => $item0) {
768
            $level1 = explode('\\', $item0);
769
770
            foreach ($level1 as $j => $item1) {
771
                if (0 === $j) {
772
                    $options[] = ['label' => $item1, 'options' => []];
773
774
                    continue;
775
                }
776
777
                foreach (explode(':', $item1) as $k => $item2) {
778
                    if (0 === $k) {
779
                        $options[$i]['options'][] = ['label' => $item2, 'options' => []];
780
781
                        continue;
782
                    }
783
784
                    $options[$i]['options'][$j - 1]['options'][] = explode(';', $item2);
785
                }
786
            }
787
        }
788
789
        array_walk_recursive($options, function (&$item) {
790
            $item = trim($item);
791
        });
792
793
        return $options;
794
    }
795
796
    /**
797
     * @param array $options
798
     *
799
     * @return array
800
     */
801
    public static function extra_field_double_select_convert_array_to_ordered_array($options)
802
    {
803
        $options_parsed = [];
804
        if (!empty($options)) {
805
            foreach ($options as $option) {
806
                if ($option['option_value'] == 0) {
807
                    $options_parsed[$option['id']][] = $option;
808
                } else {
809
                    $options_parsed[$option['option_value']][] = $option;
810
                }
811
            }
812
        }
813
814
        return $options_parsed;
815
    }
816
817
    /**
818
     * @param array $options
819
     *
820
     * @return array
821
     */
822
    public static function tripleSelectConvertArrayToOrderedArray(array $options)
823
    {
824
        $level1 = self::getOptionsFromTripleSelect($options, 0);
825
        $level2 = [];
826
        $level3 = [];
827
828
        foreach ($level1 as $item1) {
829
            $level2 += self::getOptionsFromTripleSelect($options, $item1['id']);
830
        }
831
832
        foreach ($level2 as $item2) {
833
            $level3 += self::getOptionsFromTripleSelect($options, $item2['id']);
834
        }
835
836
        return ['level1' => $level1, 'level2' => $level2, 'level3' => $level3];
837
    }
838
839
    /**
840
     * @param array $options the result of the get_field_options_by_field() array
841
     *
842
     * @return string
843
     */
844
    public static function extra_field_double_select_convert_array_to_string($options)
845
    {
846
        $string = null;
847
        $options_parsed = self::extra_field_double_select_convert_array_to_ordered_array($options);
848
849
        if (!empty($options_parsed)) {
850
            foreach ($options_parsed as $option) {
851
                foreach ($option as $key => $item) {
852
                    $string .= $item['display_text'];
853
                    if ($key == 0) {
854
                        $string .= ':';
855
                    } else {
856
                        if (isset($option[$key + 1])) {
857
                            $string .= ';';
858
                        }
859
                    }
860
                }
861
                $string .= '|';
862
            }
863
        }
864
865
        if (!empty($string)) {
866
            $string = substr($string, 0, strlen($string) - 1);
867
        }
868
869
        return $string;
870
    }
871
872
    /**
873
     * @param array $options The result of the get_field_options_by_field() array
874
     *
875
     * @return string
876
     */
877
    public static function extraFieldSelectWithTextConvertArrayToString(array $options)
878
    {
879
        $string = '';
880
        $parsedOptions = self::extra_field_double_select_convert_array_to_ordered_array($options);
881
882
        if (empty($parsedOptions)) {
883
            return '';
884
        }
885
886
        foreach ($parsedOptions as $options) {
887
            $option = current($options);
888
889
            $string .= $option['display_text'];
890
            $string .= '|';
891
        }
892
893
        return rtrim($string, '|');
894
    }
895
896
    /**
897
     * @param array $options
898
     *
899
     * @return string
900
     */
901
    public static function tripleSelectConvertArrayToString(array $options)
902
    {
903
        $string = '';
904
        $parsedOptions = self::tripleSelectConvertArrayToOrderedArray($options);
905
906
        foreach ($parsedOptions['level1'] as $item1) {
907
            $string .= $item1['display_text'];
908
            $level2 = self::getOptionsFromTripleSelect($parsedOptions['level2'], $item1['id']);
909
910
            foreach ($level2 as $item2) {
911
                $string .= '\\'.$item2['display_text'].':';
912
                $level3 = self::getOptionsFromTripleSelect($parsedOptions['level3'], $item2['id']);
913
914
                $string .= implode(';', array_column($level3, 'display_text'));
915
            }
916
917
            $string .= '|';
918
        }
919
920
        return trim($string, '\\|;');
921
    }
922
923
    /**
924
     * @param array $params
925
     *
926
     * @return array
927
     */
928
    public function clean_parameters($params)
929
    {
930
        if (!isset($params['variable']) || empty($params['variable'])) {
931
            $params['variable'] = $params['display_text'];
932
        }
933
934
        $params['variable'] = trim(strtolower(str_replace(" ", "_", $params['variable'])));
935
936
        if (!isset($params['field_order'])) {
937
            $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

937
            /** @scrutinizer ignore-call */ 
938
            $max_order = self::get_max_field_order();
Loading history...
938
            $params['field_order'] = $max_order;
939
        } else {
940
            $params['field_order'] = (int) $params['field_order'];
941
        }
942
943
        return $params;
944
    }
945
946
    /**
947
     * @param array $params
948
     * @param bool  $show_query
949
     *
950
     * @return int|bool
951
     */
952
    public function save($params, $show_query = false)
953
    {
954
        $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

954
        /** @scrutinizer ignore-call */ 
955
        $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
Loading history...
955
        $params = $this->clean_parameters($params);
956
        $params['extra_field_type'] = $this->extraFieldType;
957
958
        if ($fieldInfo) {
959
            return $fieldInfo['id'];
960
        } else {
961
            $id = parent::save($params, $show_query);
962
            if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
963
                $fieldOption = new ExtraFieldOption($this->type);
964
                $params['field_id'] = $id;
965
                $fieldOption->save($params);
966
            }
967
968
            return $id;
969
        }
970
    }
971
972
    /**
973
     * {@inheritdoc}
974
     */
975
    public function update($params, $showQuery = false)
976
    {
977
        $params = $this->clean_parameters($params);
978
        if (isset($params['id'])) {
979
            $fieldOption = new ExtraFieldOption($this->type);
980
            $params['field_id'] = $params['id'];
981
            if (empty($params['field_type'])) {
982
                $params['field_type'] = $this->type;
983
            }
984
            $fieldOption->save($params, $showQuery);
985
        }
986
987
        return parent::update($params, $showQuery);
988
    }
989
990
    /**
991
     * @param $id
992
     *
993
     * @return bool
994
     */
995
    public function delete($id)
996
    {
997
        $em = Database::getManager();
998
        $items = $em->getRepository('ChamiloCoreBundle:ExtraFieldSavedSearch')->findBy(['field' => $id]);
999
        if ($items) {
1000
            foreach ($items as $item) {
1001
                $em->remove($item);
1002
            }
1003
            $em->flush();
1004
        }
1005
        $field_option = new ExtraFieldOption($this->type);
1006
        $field_option->delete_all_options_by_field_id($id);
1007
1008
        $session_field_values = new ExtraFieldValue($this->type);
1009
        $session_field_values->delete_all_values_by_field_id($id);
1010
1011
        return parent::delete($id);
1012
    }
1013
1014
    /**
1015
     * Add an element that matches the given extra field to the given $form object.
1016
     *
1017
     * @param FormValidator $form                The form these fields are to be attached to
1018
     * @param array         $extraData
1019
     * @param bool          $adminPermissions    Whether the display is considered without edition limits (true) or not (false)
1020
     * @param array         $extra
1021
     * @param int           $itemId              The item (course, user, session, etc) this extra_field is attached to
1022
     * @param array         $exclude             Extra fields to be skipped, by textual ID
1023
     * @param bool          $useTagAsSelect      Whether to show tag fields as select drop-down or not
1024
     * @param array         $showOnlyTheseFields Limit the extra fields shown to just the list given here
1025
     * @param array         $orderFields         An array containing the names of the fields shown, in the right order
1026
     *
1027
     * @throws Exception
1028
     *
1029
     * @return array If relevant, returns a one-element array with JS code to be added to the page HTML headers
1030
     */
1031
    public function set_extra_fields_in_form(
1032
        $form,
1033
        $extraData,
1034
        $adminPermissions = false,
1035
        $extra = [],
1036
        $itemId = null,
1037
        $exclude = [],
1038
        $useTagAsSelect = false,
1039
        $showOnlyTheseFields = [],
1040
        $orderFields = [],
1041
        $orderDependingDefaults = false,
1042
        $separateExtraMultipleSelect = [],
1043
        $customLabelsExtraMultipleSelect = [],
1044
        $addEmptyOptionSelects = false,
1045
        $introductionTextList = [],
1046
        $hideGeoLocalizationDetails = false,
1047
        $help = false
1048
    ) {
1049
        $jquery_ready_content = null;
1050
        if (!empty($extra)) {
1051
            $newOrder = [];
1052
            if (!empty($orderFields)) {
1053
                foreach ($orderFields as $order) {
1054
                    foreach ($extra as $field_details) {
1055
                        if ($order == $field_details['variable']) {
1056
                            $newOrder[] = $field_details;
1057
                        }
1058
                    }
1059
                }
1060
                $extra = $newOrder;
1061
            }
1062
1063
            foreach ($extra as $field_details) {
1064
                if (!empty($showOnlyTheseFields)) {
1065
                    if (!in_array($field_details['variable'], $showOnlyTheseFields)) {
1066
                        continue;
1067
                    }
1068
                }
1069
1070
                // Getting default value id if is set
1071
                $defaultValueId = null;
1072
                if (isset($field_details['options']) && !empty($field_details['options'])) {
1073
                    $valueToFind = null;
1074
                    if (isset($field_details['field_default_value'])) {
1075
                        $valueToFind = $field_details['field_default_value'];
1076
                    }
1077
                    // If a value is found we override the default value
1078
                    if (isset($extraData['extra_'.$field_details['variable']])) {
1079
                        $valueToFind = $extraData['extra_'.$field_details['variable']];
1080
                    }
1081
1082
                    foreach ($field_details['options'] as $option) {
1083
                        if ($option['option_value'] == $valueToFind) {
1084
                            $defaultValueId = $option['id'];
1085
                        }
1086
                    }
1087
                }
1088
1089
                if (!$adminPermissions) {
1090
                    if ($field_details['visible_to_self'] == 0) {
1091
                        continue;
1092
                    }
1093
1094
                    if (in_array($field_details['variable'], $exclude)) {
1095
                        continue;
1096
                    }
1097
                }
1098
1099
                if (!empty($introductionTextList) &&
1100
                    in_array($field_details['variable'], array_keys($introductionTextList))
1101
                ) {
1102
                    $form->addHtml($introductionTextList[$field_details['variable']]);
1103
                }
1104
1105
                $freezeElement = false;
1106
                if (!$adminPermissions) {
1107
                    $freezeElement = $field_details['visible_to_self'] == 0 || $field_details['changeable'] == 0;
1108
                }
1109
1110
                $translatedDisplayText = get_lang($field_details['display_text'], true);
1111
                $translatedDisplayHelpText = '';
1112
                if ($help) {
1113
                    $translatedDisplayHelpText .= get_lang($field_details['display_text'].'Help');
1114
                }
1115
                if (!empty($translatedDisplayText)) {
1116
                    if (!empty($translatedDisplayHelpText)) {
1117
                        // In this case, exceptionally, display_text is an array
1118
                        // which is then treated by display_form()
1119
                        $field_details['display_text'] = [$translatedDisplayText, $translatedDisplayHelpText];
1120
                    } else {
1121
                        // We have an helper text, use it
1122
                        $field_details['display_text'] = $translatedDisplayText;
1123
                    }
1124
                }
1125
1126
                switch ($field_details['field_type']) {
1127
                    case self::FIELD_TYPE_TEXT:
1128
                        $form->addElement(
1129
                            'text',
1130
                            'extra_'.$field_details['variable'],
1131
                            $field_details['display_text'],
1132
                            [
1133
                                'id' => 'extra_'.$field_details['variable'],
1134
                            ]
1135
                        );
1136
                        $form->applyFilter(
1137
                            'extra_'.$field_details['variable'],
1138
                            'stripslashes'
1139
                        );
1140
                        $form->applyFilter(
1141
                            'extra_'.$field_details['variable'],
1142
                            'trim'
1143
                        );
1144
                        if ($freezeElement) {
1145
                            $form->freeze('extra_'.$field_details['variable']);
1146
                        }
1147
                        break;
1148
                    case self::FIELD_TYPE_TEXTAREA:
1149
                        $form->addHtmlEditor(
1150
                            'extra_'.$field_details['variable'],
1151
                            $field_details['display_text'],
1152
                            false,
1153
                            false,
1154
                            [
1155
                                'ToolbarSet' => 'Profile',
1156
                                'Width' => '100%',
1157
                                'Height' => '130',
1158
                                'id' => 'extra_'.$field_details['variable'],
1159
                            ]
1160
                        );
1161
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1162
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1163
                        if ($freezeElement) {
1164
                            $form->freeze('extra_'.$field_details['variable']);
1165
                        }
1166
                        break;
1167
                    case self::FIELD_TYPE_RADIO:
1168
                        $group = [];
1169
                        if (isset($field_details['options']) &&
1170
                            !empty($field_details['options'])
1171
                        ) {
1172
                            foreach ($field_details['options'] as $option_details) {
1173
                                $options[$option_details['option_value']] = $option_details['display_text'];
1174
                                $group[] = $form->createElement(
1175
                                    'radio',
1176
                                    'extra_'.$field_details['variable'],
1177
                                    $option_details['option_value'],
1178
                                    $option_details['display_text'].'<br />',
1179
                                    $option_details['option_value']
1180
                                );
1181
                            }
1182
                        }
1183
                        $form->addGroup(
1184
                            $group,
1185
                            'extra_'.$field_details['variable'],
1186
                            $field_details['display_text']
1187
                        );
1188
                        if ($freezeElement) {
1189
                            $form->freeze('extra_'.$field_details['variable']);
1190
                        }
1191
                        break;
1192
                    case self::FIELD_TYPE_CHECKBOX:
1193
                        $group = [];
1194
                        if (isset($field_details['options']) &&
1195
                            !empty($field_details['options'])
1196
                        ) {
1197
                            foreach ($field_details['options'] as $option_details) {
1198
                                $options[$option_details['option_value']] = $option_details['display_text'];
1199
                                $group[] = $form->createElement(
1200
                                    'checkbox',
1201
                                    'extra_'.$field_details['variable'],
1202
                                    $option_details['option_value'],
1203
                                    $option_details['display_text'].'<br />',
1204
                                    $option_details['option_value']
1205
                                );
1206
                            }
1207
                        } else {
1208
                            $fieldVariable = "extra_{$field_details['variable']}";
1209
                            $checkboxAttributes = [];
1210
                            if (is_array($extraData) &&
1211
                                array_key_exists($fieldVariable, $extraData)
1212
                            ) {
1213
                                if (!empty($extraData[$fieldVariable])) {
1214
                                    $checkboxAttributes['checked'] = 1;
1215
                                }
1216
                            }
1217
1218
                            if (empty($checkboxAttributes) &&
1219
                                isset($field_details['default_value']) && empty($extraData)) {
1220
                                if ($field_details['default_value'] == 1) {
1221
                                    $checkboxAttributes['checked'] = 1;
1222
                                }
1223
                            }
1224
1225
                            // We assume that is a switch on/off with 1 and 0 as values
1226
                            $group[] = $form->createElement(
1227
                                'checkbox',
1228
                                'extra_'.$field_details['variable'],
1229
                                null,
1230
                                //$field_details['display_text'].'<br />',
1231
                                get_lang('Yes'),
1232
                                $checkboxAttributes
1233
                            );
1234
                        }
1235
1236
                        $form->addGroup(
1237
                            $group,
1238
                            'extra_'.$field_details['variable'],
1239
                            $field_details['display_text']
1240
                        );
1241
                        if ($freezeElement) {
1242
                            $form->freeze('extra_'.$field_details['variable']);
1243
                        }
1244
                        break;
1245
                    case self::FIELD_TYPE_SELECT:
1246
                        $this->addSelectElement($form, $field_details, $defaultValueId, $freezeElement);
1247
                        break;
1248
                    case self::FIELD_TYPE_SELECT_MULTIPLE:
1249
                        $options = [];
1250
                        if (empty($defaultValueId)) {
1251
                            $options[''] = get_lang('SelectAnOption');
1252
                        }
1253
                        foreach ($field_details['options'] as $optionDetails) {
1254
                            $options[$optionDetails['option_value']] = $optionDetails['display_text'];
1255
                        }
1256
                        $form->addElement(
1257
                            'select',
1258
                            'extra_'.$field_details['variable'],
1259
                            $field_details['display_text'],
1260
                            $options,
1261
                            [
1262
                                'multiple' => 'multiple',
1263
                                'id' => 'extra_'.$field_details['variable'],
1264
                            ]
1265
                        );
1266
                        if ($freezeElement) {
1267
                            $form->freeze('extra_'.$field_details['variable']);
1268
                        }
1269
                        break;
1270
                    case self::FIELD_TYPE_DATE:
1271
                        $form->addDatePicker('extra_'.$field_details['variable'], $field_details['display_text']);
1272
                        if ($freezeElement) {
1273
                            $form->freeze('extra_'.$field_details['variable']);
1274
                        }
1275
                        break;
1276
                    case self::FIELD_TYPE_DATETIME:
1277
                        $form->addDateTimePicker(
1278
                            'extra_'.$field_details['variable'],
1279
                            $field_details['display_text']
1280
                        );
1281
1282
                        $defaults['extra_'.$field_details['variable']] = api_get_local_time();
1283
                        if (!isset($form->_defaultValues['extra_'.$field_details['variable']])) {
1284
                            $form->setDefaults($defaults);
1285
                        }
1286
                        if ($freezeElement) {
1287
                            $form->freeze('extra_'.$field_details['variable']);
1288
                        }
1289
                        break;
1290
                    case self::FIELD_TYPE_DOUBLE_SELECT:
1291
                        $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

1291
                        $jquery_ready_content .= self::/** @scrutinizer ignore-call */ addDoubleSelectElement(
Loading history...
1292
                            $form,
1293
                            $field_details,
1294
                            $extraData,
1295
                            $freezeElement
1296
                        );
1297
                        break;
1298
                    case self::FIELD_TYPE_DIVIDER:
1299
                        $form->addHtml('
1300
                            <div class="form-group ">
1301
                                <div class="col-sm-12">
1302
                                    <div class="panel-separator">
1303
                                       <h4 id="'.$field_details['variable'].'" class="form-separator">'
1304
                                            .$field_details['display_text'].'
1305
                                       </h4>
1306
                                    </div>
1307
                                </div>
1308
                            </div>    
1309
                        ');
1310
                        break;
1311
                    case self::FIELD_TYPE_TAG:
1312
                        $variable = $field_details['variable'];
1313
                        $field_id = $field_details['id'];
1314
                        $separateValue = 0;
1315
                        if (isset($separateExtraMultipleSelect[$field_details['variable']])) {
1316
                            $separateValue = $separateExtraMultipleSelect[$field_details['variable']];
1317
                        }
1318
1319
                        $selectedOptions = [];
1320
1321
                        if ($separateValue > 0) {
1322
                            $em = Database::getManager();
1323
                            $fieldTags = $em
1324
                                ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1325
                                ->findBy(
1326
                                    [
1327
                                        'fieldId' => $field_id,
1328
                                        'itemId' => $itemId,
1329
                                    ]
1330
                                );
1331
                            // ofaj
1332
1333
                            for ($i = 0; $i < $separateValue; $i++) {
1334
                                $tagsSelect = $form->addElement(
1335
                                    'select',
1336
                                    'extra_'.$field_details['variable'].'['.$i.']',
1337
                                    $customLabelsExtraMultipleSelect[$field_details['variable']][$i], //$field_details['display_text'],
1338
                                    null,
1339
                                    ['id' => 'extra_'.$field_details['variable'].'_'.$i]
1340
                                );
1341
1342
                                if ($addEmptyOptionSelects) {
1343
                                    $tagsSelect->addOption(
1344
                                        '',
1345
                                        ''
1346
                                    );
1347
                                }
1348
1349
                                foreach ($fieldTags as $fieldTag) {
1350
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1351
1352
                                    if (empty($tag)) {
1353
                                        continue;
1354
                                    }
1355
1356
                                    $tagsSelect->addOption(
1357
                                        $tag->getTag(),
1358
                                        $tag->getTag()
1359
                                    );
1360
                                }
1361
                            }
1362
                        } else {
1363
                            $tagsSelect = $form->addSelect(
1364
                                "extra_{$field_details['variable']}",
1365
                                $field_details['display_text'],
1366
                                [],
1367
                                ['style' => 'width: 100%;']
1368
                            );
1369
1370
                            if ($useTagAsSelect === false) {
1371
                                $tagsSelect->setAttribute('class', null);
1372
                            }
1373
1374
                            $tagsSelect->setAttribute(
1375
                                'id',
1376
                                "extra_{$field_details['variable']}"
1377
                            );
1378
                            $tagsSelect->setMultiple(true);
1379
1380
                            $selectedOptions = [];
1381
                            if ($this->type === 'user') {
1382
                                // The magic should be here
1383
                                $user_tags = UserManager::get_user_tags(
1384
                                    $itemId,
1385
                                    $field_details['id']
1386
                                );
1387
1388
                                if (is_array($user_tags) && count($user_tags) > 0) {
1389
                                    foreach ($user_tags as $tag) {
1390
                                        if (empty($tag['tag'])) {
1391
                                            continue;
1392
                                        }
1393
                                        $tagsSelect->addOption(
1394
                                            $tag['tag'],
1395
                                            $tag['tag'],
1396
                                            [
1397
                                                'selected' => 'selected',
1398
                                                'class' => 'selected',
1399
                                            ]
1400
                                        );
1401
                                        $selectedOptions[] = $tag['tag'];
1402
                                    }
1403
                                }
1404
                                $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
1405
                            } else {
1406
                                $em = Database::getManager();
1407
                                $fieldTags = $em->getRepository(
1408
                                    'ChamiloCoreBundle:ExtraFieldRelTag'
1409
                                )
1410
                                ->findBy(
1411
                                    [
1412
                                        'fieldId' => $field_id,
1413
                                        'itemId' => $itemId,
1414
                                    ]
1415
                                );
1416
1417
                                /** @var ExtraFieldRelTag $fieldTag */
1418
                                foreach ($fieldTags as $fieldTag) {
1419
                                    /** @var Tag $tag */
1420
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1421
1422
                                    if (empty($tag)) {
1423
                                        continue;
1424
                                    }
1425
                                    $tagsSelect->addOption(
1426
                                        $tag->getTag(),
1427
                                        $tag->getTag()
1428
                                    );
1429
                                    $selectedOptions[] = $tag->getTag();
1430
                                }
1431
1432
                                if (!empty($extraData) && isset($extraData['extra_'.$field_details['variable']])) {
1433
                                    $data = $extraData['extra_'.$field_details['variable']];
1434
                                    if (!empty($data)) {
1435
                                        foreach ($data as $option) {
1436
                                            $tagsSelect->addOption(
1437
                                                $option,
1438
                                                $option
1439
                                            );
1440
                                        }
1441
                                    }
1442
                                }
1443
1444
                                if ($useTagAsSelect) {
1445
                                    $fieldTags = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1446
                                        ->findBy(
1447
                                            [
1448
                                                'fieldId' => $field_id,
1449
                                            ]
1450
                                        );
1451
                                    $tagsAdded = [];
1452
                                    foreach ($fieldTags as $fieldTag) {
1453
                                        $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1454
1455
                                        if (empty($tag)) {
1456
                                            continue;
1457
                                        }
1458
1459
                                        $tagText = $tag->getTag();
1460
1461
                                        if (in_array($tagText, $tagsAdded)) {
1462
                                            continue;
1463
                                        }
1464
1465
                                        $tagsSelect->addOption(
1466
                                            $tag->getTag(),
1467
                                            $tag->getTag(),
1468
                                            []
1469
                                        );
1470
1471
                                        $tagsAdded[] = $tagText;
1472
                                    }
1473
                                }
1474
                                $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php';
1475
                            }
1476
1477
                            $form->setDefaults(
1478
                                [
1479
                                    'extra_'.$field_details['variable'] => $selectedOptions,
1480
                                ]
1481
                            );
1482
1483
                            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...
1484
                                $jquery_ready_content .= "
1485
                                $('#extra_$variable').select2({
1486
                                    ajax: {
1487
                                        url: '$url?a=search_tags&field_id=$field_id&type={$this->type}',
1488
                                        processResults: function (data) {
1489
                                            return {
1490
                                                results: data.items
1491
                                            }
1492
                                        }
1493
                                    },
1494
                                    cache: false,
1495
                                    tags: true,
1496
                                    tokenSeparators: [','],
1497
                                    placeholder: '".get_lang('StartToType')."'
1498
                                });
1499
                            ";
1500
                            }
1501
                        }
1502
1503
                        break;
1504
                    case self::FIELD_TYPE_TIMEZONE:
1505
                        $form->addElement(
1506
                            'select',
1507
                            'extra_'.$field_details['variable'],
1508
                            $field_details['display_text'],
1509
                            api_get_timezones(),
1510
                            ''
1511
                        );
1512
                        if ($freezeElement) {
1513
                            $form->freeze('extra_'.$field_details['variable']);
1514
                        }
1515
                        break;
1516
                    case self::FIELD_TYPE_SOCIAL_PROFILE:
1517
                        // get the social network's favicon
1518
                        $extra_data_variable = isset($extraData['extra_'.$field_details['variable']])
1519
                            ? $extraData['extra_'.$field_details['variable']]
1520
                            : null;
1521
                        $field_default_value = isset($field_details['field_default_value'])
1522
                            ? $field_details['field_default_value']
1523
                            : null;
1524
                        $icon_path = UserManager::get_favicon_from_url(
1525
                            $extra_data_variable,
1526
                            $field_default_value
1527
                        );
1528
                        // special hack for hi5
1529
                        $leftpad = '1.7';
1530
                        $top = '0.4';
1531
                        $domain = parse_url($icon_path, PHP_URL_HOST);
1532
                        if ($domain == 'www.hi5.com' or $domain == 'hi5.com') {
1533
                            $leftpad = '3';
1534
                            $top = '0';
1535
                        }
1536
                        // print the input field
1537
                        $form->addElement(
1538
                            'text',
1539
                            'extra_'.$field_details['variable'],
1540
                            $field_details['display_text'],
1541
                            [
1542
                                'size' => 60,
1543
                                'size' => implode(
1544
                                    '; ',
1545
                                    [
1546
                                        "background-image: url('$icon_path')",
1547
                                        'background-repeat: no-repeat',
1548
                                        "background-position: 0.4em {$top}em",
1549
                                        "padding-left: {$leftpad}em",
1550
                                    ]
1551
                                ),
1552
                            ]
1553
                        );
1554
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1555
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1556
                        if ($freezeElement) {
1557
                            $form->freeze('extra_'.$field_details['variable']);
1558
                        }
1559
                        break;
1560
                    case self::FIELD_TYPE_MOBILE_PHONE_NUMBER:
1561
                        $form->addElement(
1562
                            'text',
1563
                            'extra_'.$field_details['variable'],
1564
                            $field_details['display_text']." (".get_lang('CountryDialCode').")",
1565
                            ['size' => 40, 'placeholder' => '(xx)xxxxxxxxx']
1566
                        );
1567
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1568
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1569
                        $form->applyFilter('extra_'.$field_details['variable'], 'mobile_phone_number_filter');
1570
                        $form->addRule(
1571
                            'extra_'.$field_details['variable'],
1572
                            get_lang('MobilePhoneNumberWrong'),
1573
                            'mobile_phone_number'
1574
                        );
1575
                        if ($freezeElement) {
1576
                            $form->freeze('extra_'.$field_details['variable']);
1577
                        }
1578
                        break;
1579
                    case self::FIELD_TYPE_INTEGER:
1580
                        $form->addElement(
1581
                            'number',
1582
                            'extra_'.$field_details['variable'],
1583
                            $field_details['display_text'],
1584
                            ['class' => 'span1', 'step' => 1]
1585
                        );
1586
1587
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1588
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1589
                        $form->applyFilter('extra_'.$field_details['variable'], 'intval');
1590
1591
                        if ($freezeElement) {
1592
                            $form->freeze('extra_'.$field_details['variable']);
1593
                        }
1594
                        break;
1595
                    case self::FIELD_TYPE_FILE_IMAGE:
1596
                        $fieldVariable = "extra_{$field_details['variable']}";
1597
                        $fieldTexts = [
1598
                            $field_details['display_text'],
1599
                        ];
1600
1601
                        if (is_array($extraData) && array_key_exists($fieldVariable, $extraData)) {
1602
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1603
                                $fieldTexts[] = Display::img(
1604
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1605
                                    $field_details['display_text'],
1606
                                    ['width' => '300']
1607
                                );
1608
                            }
1609
                        }
1610
1611
                        if ($fieldTexts[0] === 'Image') {
1612
                            $fieldTexts[0] = get_lang($fieldTexts[0]);
1613
                        }
1614
1615
                        $form->addFile(
1616
                            $fieldVariable,
1617
                            $fieldTexts,
1618
                            ['accept' => 'image/*', 'id' => 'extra_image', 'crop_image' => 'true']
1619
                        );
1620
1621
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1622
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1623
1624
                        $allowedPictureTypes = ['jpg', 'jpeg', 'png', 'gif'];
1625
                        $form->addRule(
1626
                            'extra_'.$field_details['variable'],
1627
                            get_lang('OnlyImagesAllowed').' ('.implode(',', $allowedPictureTypes).')',
1628
                            'filetype',
1629
                            $allowedPictureTypes
1630
                        );
1631
1632
                        if ($freezeElement) {
1633
                            $form->freeze('extra_'.$field_details['variable']);
1634
                        }
1635
                        break;
1636
                    case self::FIELD_TYPE_FLOAT:
1637
                        $form->addElement(
1638
                            'number',
1639
                            'extra_'.$field_details['variable'],
1640
                            $field_details['display_text'],
1641
                            ['class' => 'span1', 'step' => '0.01']
1642
                        );
1643
1644
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1645
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1646
                        $form->applyFilter('extra_'.$field_details['variable'], 'floatval');
1647
1648
                        if ($freezeElement) {
1649
                            $form->freeze('extra_'.$field_details['variable']);
1650
                        }
1651
                        break;
1652
                    case self::FIELD_TYPE_FILE:
1653
                        $fieldVariable = "extra_{$field_details['variable']}";
1654
                        $fieldTexts = [
1655
                            $field_details['display_text'],
1656
                        ];
1657
1658
                        if (is_array($extraData) &&
1659
                            array_key_exists($fieldVariable, $extraData)
1660
                        ) {
1661
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1662
                                $linkToDelete = '';
1663
                                $divItemId = $field_details['variable'];
1664
                                if (api_is_platform_admin()) {
1665
                                    $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?type='.$this->type;
1666
                                    $url .= '&a=delete_file&field_id='.$field_details['id'].'&item_id='.$itemId;
1667
1668
                                    $deleteId = $field_details['variable'].'_delete';
1669
                                    $form->addHtml("
1670
                                        <script>
1671
                                            $(function() {                                     
1672
                                                $('#".$deleteId."').on('click', function() {
1673
                                                    $.ajax({			
1674
                                                        type: 'GET',
1675
                                                        url: '".$url."',			
1676
                                                        success: function(result) {		    
1677
                                                            if (result == 1) {
1678
                                                                $('#".$divItemId."').html('".get_lang('Deleted')."');
1679
                                                            }			    
1680
                                                        }
1681
                                                    });
1682
                                                });
1683
                                            });
1684
                                        </script>
1685
                                    ");
1686
1687
                                    $linkToDelete = '&nbsp;'.Display::url(
1688
                                        Display::return_icon('delete.png', get_lang('Delete')),
1689
                                        'javascript:void(0)',
1690
                                        ['id' => $deleteId]
1691
                                    );
1692
                                }
1693
                                $fieldTexts[] = '<div id="'.$divItemId.'">'.Display::url(
1694
                                    basename($extraData[$fieldVariable]),
1695
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1696
                                    [
1697
                                        'title' => $field_details['display_text'],
1698
                                        'target' => '_blank',
1699
                                    ]
1700
                                ).$linkToDelete.'</div>';
1701
                            }
1702
                        }
1703
1704
                        $form->addElement(
1705
                            'file',
1706
                            $fieldVariable,
1707
                            $fieldTexts,
1708
                            []
1709
                        );
1710
1711
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1712
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1713
1714
                        if ($freezeElement) {
1715
                            $form->freeze('extra_'.$field_details['variable']);
1716
                        }
1717
                        break;
1718
                    case self::FIELD_TYPE_VIDEO_URL:
1719
                        $form->addUrl(
1720
                            "extra_{$field_details['variable']}",
1721
                            $field_details['display_text'],
1722
                            false,
1723
                            ['placeholder' => 'https://']
1724
                        );
1725
                        if ($freezeElement) {
1726
                            $form->freeze('extra_'.$field_details['variable']);
1727
                        }
1728
                        break;
1729
                    case self::FIELD_TYPE_LETTERS_ONLY:
1730
                        $form->addTextLettersOnly(
1731
                            "extra_{$field_details['variable']}",
1732
                            $field_details['display_text']
1733
                        );
1734
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1735
1736
                        if ($freezeElement) {
1737
                            $form->freeze('extra_'.$field_details['variable']);
1738
                        }
1739
                        break;
1740
                    case self::FIELD_TYPE_ALPHANUMERIC:
1741
                        $form->addTextAlphanumeric(
1742
                            "extra_{$field_details['variable']}",
1743
                            $field_details['display_text']
1744
                        );
1745
                        $form->applyFilter(
1746
                            'extra_'.$field_details['variable'],
1747
                            'stripslashes'
1748
                        );
1749
                        if ($freezeElement) {
1750
                            $form->freeze('extra_'.$field_details['variable']);
1751
                        }
1752
                        break;
1753
                    case self::FIELD_TYPE_LETTERS_SPACE:
1754
                        $form->addTextLettersAndSpaces(
1755
                            "extra_{$field_details['variable']}",
1756
                            $field_details['display_text']
1757
                        );
1758
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1759
1760
                        if ($freezeElement) {
1761
                            $form->freeze('extra_'.$field_details['variable']);
1762
                        }
1763
                        break;
1764
                    case self::FIELD_TYPE_ALPHANUMERIC_SPACE:
1765
                        $form->addTextAlphanumericAndSpaces(
1766
                            "extra_{$field_details['variable']}",
1767
                            $field_details['display_text']
1768
                        );
1769
                        $form->applyFilter(
1770
                            'extra_'.$field_details['variable'],
1771
                            'stripslashes'
1772
                        );
1773
                        if ($freezeElement) {
1774
                            $form->freeze('extra_'.$field_details['variable']);
1775
                        }
1776
                        break;
1777
                    case self::FIELD_TYPE_GEOLOCALIZATION_COORDINATES:
1778
                    case self::FIELD_TYPE_GEOLOCALIZATION:
1779
                        $dataValue = isset($extraData['extra_'.$field_details['variable']])
1780
                            ? $extraData['extra_'.$field_details['variable']]
1781
                            : '';
1782
1783
                        $form->addGeoLocationMapField(
1784
                            'extra_'.$field_details['variable'],
1785
                            $field_details['display_text'],
1786
                            $dataValue,
1787
                            $hideGeoLocalizationDetails
1788
                        );
1789
1790
                        /*$form->addElement(
1791
                            'text',
1792
                            'extra_'.$field_details['variable'],
1793
                            $field_details['display_text'],
1794
                            ['id' => 'extra_'.$field_details['variable']]
1795
                        );
1796
                        $form->addHidden(
1797
                            'extra_'.$field_details['variable'].'_coordinates',
1798
                            '',
1799
                            ['id' => 'extra_'.$field_details['variable'].'_coordinates']
1800
                        );
1801
1802
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1803
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');*/
1804
1805
                        if ($freezeElement) {
1806
                            $form->freeze('extra_'.$field_details['variable']);
1807
                        }
1808
                        break;
1809
                    case self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
1810
                        $jquery_ready_content .= $this->addSelectWithTextFieldElement(
1811
                            $form,
1812
                            $field_details,
1813
                            $freezeElement
1814
                        );
1815
                        break;
1816
                    case self::FIELD_TYPE_TRIPLE_SELECT:
1817
                        $jquery_ready_content .= $this->addTripleSelectElement(
1818
                            $form,
1819
                            $field_details,
1820
                            is_array($extraData) ? $extraData : [],
1821
                            $freezeElement
1822
                        );
1823
                        break;
1824
                }
1825
            }
1826
        }
1827
1828
        $return = [];
1829
        $return['jquery_ready_content'] = $jquery_ready_content;
1830
1831
        return $return;
1832
    }
1833
1834
    /**
1835
     * @param $breadcrumb
1836
     * @param $action
1837
     */
1838
    public function setupBreadcrumb(&$breadcrumb, $action)
1839
    {
1840
        if ($action == 'add') {
1841
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
1842
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Add')];
1843
        } elseif ($action == 'edit') {
1844
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
1845
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Edit')];
1846
        } else {
1847
            $breadcrumb[] = ['url' => '#', 'name' => $this->pageName];
1848
        }
1849
    }
1850
1851
    /**
1852
     * Displays the title + grid.
1853
     */
1854
    public function display()
1855
    {
1856
        // action links
1857
        echo '<div class="actions">';
1858
        echo '<a href="../admin/index.php">';
1859
        echo Display::return_icon(
1860
            'back.png',
1861
            get_lang('BackTo').' '.get_lang('PlatformAdmin'),
1862
            '',
1863
            ICON_SIZE_MEDIUM
1864
        );
1865
        echo '</a>';
1866
        echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'">';
1867
        echo Display::return_icon(
1868
            'add_user_fields.png',
1869
            get_lang('Add'),
1870
            '',
1871
            ICON_SIZE_MEDIUM
1872
        );
1873
        echo '</a>';
1874
        echo '</div>';
1875
        echo Display::grid_html($this->type.'_fields');
1876
    }
1877
1878
    /**
1879
     * @return array
1880
     */
1881
    public function getJqgridColumnNames()
1882
    {
1883
        return [
1884
            get_lang('Name'),
1885
            get_lang('FieldLabel'),
1886
            get_lang('Type'),
1887
            get_lang('FieldChangeability'),
1888
            get_lang('VisibleToSelf'),
1889
            get_lang('VisibleToOthers'),
1890
            get_lang('Filter'),
1891
            get_lang('FieldOrder'),
1892
            get_lang('Actions'),
1893
        ];
1894
    }
1895
1896
    /**
1897
     * @return array
1898
     */
1899
    public function getJqgridColumnModel()
1900
    {
1901
        return [
1902
            [
1903
                'name' => 'display_text',
1904
                'index' => 'display_text',
1905
                'width' => '140',
1906
                'align' => 'left',
1907
            ],
1908
            [
1909
                'name' => 'variable',
1910
                'index' => 'variable',
1911
                'width' => '90',
1912
                'align' => 'left',
1913
                'sortable' => 'true',
1914
            ],
1915
            [
1916
                'name' => 'field_type',
1917
                'index' => 'field_type',
1918
                'width' => '70',
1919
                'align' => 'left',
1920
                'sortable' => 'true',
1921
            ],
1922
            [
1923
                'name' => 'changeable',
1924
                'index' => 'changeable',
1925
                'width' => '35',
1926
                'align' => 'left',
1927
                'sortable' => 'true',
1928
                'formatter' => '',
1929
            ],
1930
            [
1931
                'name' => 'visible_to_self',
1932
                'index' => 'visible_to_self',
1933
                'width' => '45',
1934
                'align' => 'left',
1935
                'sortable' => 'true',
1936
                'formatter' => '',
1937
            ],
1938
            [
1939
                'name' => 'visible_to_others',
1940
                'index' => 'visible_to_others',
1941
                'width' => '35',
1942
                'align' => 'left',
1943
                'sortable' => 'true',
1944
                'formatter' => '',
1945
            ],
1946
            [
1947
                'name' => 'filter',
1948
                'index' => 'filter',
1949
                'width' => '30',
1950
                'align' => 'left',
1951
                'sortable' => 'true',
1952
                'formatter' => '',
1953
            ],
1954
            [
1955
                'name' => 'field_order',
1956
                'index' => 'field_order',
1957
                'width' => '25',
1958
                'align' => 'left',
1959
                'sortable' => 'true',
1960
            ],
1961
            [
1962
                'name' => 'actions',
1963
                'index' => 'actions',
1964
                'width' => '40',
1965
                'align' => 'left',
1966
                'formatter' => 'action_formatter',
1967
                'sortable' => 'false',
1968
            ],
1969
        ];
1970
    }
1971
1972
    /**
1973
     * @param string $url
1974
     * @param string $action
1975
     *
1976
     * @return FormValidator
1977
     */
1978
    public function return_form($url, $action)
1979
    {
1980
        $form = new FormValidator($this->type.'_field', 'post', $url);
1981
1982
        $form->addElement('hidden', 'type', $this->type);
1983
        $id = isset($_GET['id']) ? (int) $_GET['id'] : null;
1984
        $form->addElement('hidden', 'id', $id);
1985
1986
        // Setting the form elements
1987
        $header = get_lang('Add');
1988
        $defaults = [];
1989
1990
        if ($action === 'edit') {
1991
            $header = get_lang('Modify');
1992
            // Setting the defaults
1993
            $defaults = $this->get($id, false);
1994
        }
1995
1996
        $form->addElement('header', $header);
1997
1998
        if ($action === 'edit') {
1999
            $translateUrl = api_get_path(WEB_CODE_PATH).'extrafield/translate.php?'
2000
                .http_build_query(['extra_field' => $id]);
2001
            $translateButton = Display::toolbarButton(get_lang('TranslateThisTerm'), $translateUrl, 'language', 'link');
2002
2003
            $form->addText(
2004
                'display_text',
2005
                [get_lang('Name'), $translateButton]
2006
            );
2007
        } else {
2008
            $form->addElement('text', 'display_text', get_lang('Name'));
2009
        }
2010
2011
        $form->addHtmlEditor('description', get_lang('Description'), false);
2012
2013
        // Field type
2014
        $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

2014
        /** @scrutinizer ignore-call */ 
2015
        $types = self::get_field_types();
Loading history...
2015
2016
        $form->addElement(
2017
            'select',
2018
            'field_type',
2019
            get_lang('FieldType'),
2020
            $types,
2021
            ['id' => 'field_type']
2022
        );
2023
        $form->addElement('label', get_lang('Example'), '<div id="example">-</div>');
2024
        $form->addElement('text', 'variable', get_lang('FieldLabel'), ['class' => 'span5']);
2025
        $form->addElement(
2026
            'text',
2027
            'field_options',
2028
            get_lang('FieldPossibleValues'),
2029
            ['id' => 'field_options', 'class' => 'span6']
2030
        );
2031
2032
        $fieldWithOptions = [
2033
            self::FIELD_TYPE_RADIO,
2034
            self::FIELD_TYPE_SELECT_MULTIPLE,
2035
            self::FIELD_TYPE_SELECT,
2036
            self::FIELD_TYPE_TAG,
2037
            self::FIELD_TYPE_DOUBLE_SELECT,
2038
            self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD,
2039
            self::FIELD_TYPE_TRIPLE_SELECT,
2040
        ];
2041
2042
        if ($action == 'edit') {
2043
            if (in_array($defaults['field_type'], $fieldWithOptions)) {
2044
                $url = Display::url(
2045
                    get_lang('EditExtraFieldOptions'),
2046
                    'extra_field_options.php?type='.$this->type.'&field_id='.$id
2047
                );
2048
                $form->addElement('label', null, $url);
2049
2050
                if ($defaults['field_type'] == self::FIELD_TYPE_SELECT) {
2051
                    $urlWorkFlow = Display::url(
2052
                        get_lang('EditExtraFieldWorkFlow'),
2053
                        'extra_field_workflow.php?type='.$this->type.'&field_id='.$id
2054
                    );
2055
                    $form->addElement('label', null, $urlWorkFlow);
2056
                }
2057
2058
                $form->freeze('field_options');
2059
            }
2060
        }
2061
        $form->addElement(
2062
            'text',
2063
            'default_value',
2064
            get_lang('FieldDefaultValue'),
2065
            ['id' => 'default_value']
2066
        );
2067
2068
        $group = [];
2069
        $group[] = $form->createElement('radio', 'visible_to_self', null, get_lang('Yes'), 1);
2070
        $group[] = $form->createElement('radio', 'visible_to_self', null, get_lang('No'), 0);
2071
        $form->addGroup($group, '', get_lang('VisibleToSelf'), null, false);
2072
2073
        $group = [];
2074
        $group[] = $form->createElement('radio', 'visible_to_others', null, get_lang('Yes'), 1);
2075
        $group[] = $form->createElement('radio', 'visible_to_others', null, get_lang('No'), 0);
2076
        $form->addGroup($group, '', get_lang('VisibleToOthers'), null, false);
2077
2078
        $group = [];
2079
        $group[] = $form->createElement('radio', 'changeable', null, get_lang('Yes'), 1);
2080
        $group[] = $form->createElement('radio', 'changeable', null, get_lang('No'), 0);
2081
        $form->addGroup($group, '', get_lang('FieldChangeability'), null, false);
2082
2083
        $group = [];
2084
        $group[] = $form->createElement('radio', 'filter', null, get_lang('Yes'), 1);
2085
        $group[] = $form->createElement('radio', 'filter', null, get_lang('No'), 0);
2086
        $form->addGroup($group, '', get_lang('FieldFilter'), null, false);
2087
2088
        /* Enable this when field_loggeable is introduced as a table field (2.0)
2089
        $group   = array();
2090
        $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('Yes'), 1);
2091
        $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('No'), 0);
2092
        $form->addGroup($group, '', get_lang('FieldLoggeable'), '', false);
2093
        */
2094
2095
        $form->addElement('text', 'field_order', get_lang('FieldOrder'));
2096
2097
        if ($action == 'edit') {
2098
            $option = new ExtraFieldOption($this->type);
2099
            $defaults['field_options'] = $option->get_field_options_by_field_to_string($id);
2100
            $form->addButtonUpdate(get_lang('Modify'));
2101
        } else {
2102
            $defaults['visible_to_self'] = 0;
2103
            $defaults['visible_to_others'] = 0;
2104
            $defaults['changeable'] = 0;
2105
            $defaults['filter'] = 0;
2106
            $form->addButtonCreate(get_lang('Add'));
2107
        }
2108
2109
        /*if (!empty($defaults['created_at'])) {
2110
            $defaults['created_at'] = api_convert_and_format_date($defaults['created_at']);
2111
        }
2112
        if (!empty($defaults['updated_at'])) {
2113
            $defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']);
2114
        }*/
2115
        $form->setDefaults($defaults);
2116
2117
        // Setting the rules
2118
        $form->addRule('display_text', get_lang('ThisFieldIsRequired'), 'required');
2119
        $form->addRule('field_type', get_lang('ThisFieldIsRequired'), 'required');
2120
2121
        return $form;
2122
    }
2123
2124
    /**
2125
     * @param $token
2126
     *
2127
     * @return string
2128
     */
2129
    public function getJqgridActionLinks($token)
2130
    {
2131
        //With this function we can add actions to the jgrid (edit, delete, etc)
2132
        $editIcon = Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL);
2133
        $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2134
        $confirmMessage = addslashes(
2135
            api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES)
2136
        );
2137
2138
        $editButton = <<<JAVASCRIPT
2139
            <a href="?action=edit&type={$this->type}&id=' + options.rowId + '" class="btn btn-link btn-xs">\
2140
                $editIcon\
2141
            </a>
2142
JAVASCRIPT;
2143
        $deleteButton = <<<JAVASCRIPT
2144
            <a \
2145
                    onclick="if (!confirm(\'$confirmMessage\')) {return false;}" \
2146
                href="?sec_token=$token&type={$this->type}&id=' + options.rowId + '&action=delete" \
2147
                class="btn btn-link btn-xs">\
2148
                $deleteIcon\
2149
            </a>
2150
JAVASCRIPT;
2151
2152
        return "function action_formatter(cellvalue, options, rowObject) {        
2153
            return '$editButton $deleteButton';
2154
        }";
2155
    }
2156
2157
    /**
2158
     * @param array $columns
2159
     * @param array $column_model
2160
     * @param array $extraFields
2161
     *
2162
     * @return array
2163
     */
2164
    public function getRules(&$columns, &$column_model, $extraFields = [], $checkExtraFieldExistence = false)
2165
    {
2166
        $fields = $this->get_all(
2167
            [
2168
                'visible_to_self = ? AND filter = ?' => [1, 1],
2169
            ],
2170
            'display_text'
2171
        );
2172
        $extraFieldOption = new ExtraFieldOption($this->type);
2173
2174
        $rules = [];
2175
        if (!empty($fields)) {
2176
            foreach ($fields as $field) {
2177
                $search_options = [];
2178
                $type = 'text';
2179
                if (in_array($field['field_type'], [self::FIELD_TYPE_SELECT, self::FIELD_TYPE_DOUBLE_SELECT])) {
2180
                    $type = 'select';
2181
                    $search_options['sopt'] = ['eq', 'ne']; //equal not equal
2182
                } else {
2183
                    $search_options['sopt'] = ['cn', 'nc']; //contains not contains
2184
                }
2185
2186
                $search_options['searchhidden'] = 'true';
2187
                $search_options['defaultValue'] = isset($search_options['field_default_value'])
2188
                    ? $search_options['field_default_value']
2189
                    : null;
2190
2191
                if ($field['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
2192
                    // Add 2 selects
2193
                    $options = $extraFieldOption->get_field_options_by_field($field['id']);
2194
                    $options = self::extra_field_double_select_convert_array_to_ordered_array($options);
2195
2196
                    $first_options = [];
2197
                    if (!empty($options)) {
2198
                        foreach ($options as $option) {
2199
                            foreach ($option as $sub_option) {
2200
                                if ($sub_option['option_value'] == 0) {
2201
                                    $first_options[] = $sub_option['field_id'].'#'.$sub_option['id'].':'
2202
                                        .$sub_option['display_text'];
2203
                                }
2204
                            }
2205
                        }
2206
                    }
2207
2208
                    $search_options['value'] = implode(';', $first_options);
2209
                    $search_options['dataInit'] = 'fill_second_select';
2210
2211
                    // First
2212
                    $column_model[] = [
2213
                        'name' => 'extra_'.$field['variable'],
2214
                        'index' => 'extra_'.$field['variable'],
2215
                        'width' => '100',
2216
                        'hidden' => 'true',
2217
                        'search' => 'true',
2218
                        'stype' => 'select',
2219
                        'searchoptions' => $search_options,
2220
                    ];
2221
                    $columns[] = $field['display_text'].' (1)';
2222
                    $rules[] = [
2223
                        'field' => 'extra_'.$field['variable'],
2224
                        'op' => 'cn',
2225
                    ];
2226
2227
                    // Second
2228
                    $search_options['value'] = $field['id'].':';
2229
                    $search_options['dataInit'] = 'register_second_select';
2230
2231
                    $column_model[] = [
2232
                        'name' => 'extra_'.$field['variable'].'_second',
2233
                        'index' => 'extra_'.$field['variable'].'_second',
2234
                        'width' => '100',
2235
                        'hidden' => 'true',
2236
                        'search' => 'true',
2237
                        'stype' => 'select',
2238
                        'searchoptions' => $search_options,
2239
                    ];
2240
                    $columns[] = $field['display_text'].' (2)';
2241
                    $rules[] = ['field' => 'extra_'.$field['variable'].'_second', 'op' => 'cn'];
2242
                    continue;
2243
                } else {
2244
                    $search_options['value'] = $extraFieldOption->getFieldOptionsToString(
2245
                        $field['id'],
2246
                        false,
2247
                        'display_text'
2248
                    );
2249
                }
2250
                $column_model[] = [
2251
                    'name' => 'extra_'.$field['variable'],
2252
                    'index' => 'extra_'.$field['variable'],
2253
                    'width' => '100',
2254
                    'hidden' => 'true',
2255
                    'search' => 'true',
2256
                    'stype' => $type,
2257
                    'searchoptions' => $search_options,
2258
                ];
2259
                $columns[] = $field['display_text'];
2260
                $rules[] = [
2261
                    'field' => 'extra_'.$field['variable'],
2262
                    'op' => 'cn',
2263
                    'data' => '',
2264
                ];
2265
            }
2266
        }
2267
2268
        return $rules;
2269
    }
2270
2271
    /**
2272
     * @param array $options
2273
     *
2274
     * @return array
2275
     */
2276
    public function parseConditions($options)
2277
    {
2278
        $inject_extra_fields = null;
2279
        $extraFieldOption = new ExtraFieldOption($this->type);
2280
        $double_fields = [];
2281
2282
        if (isset($options['extra'])) {
2283
            $extra_fields = $options['extra'];
2284
            if (!empty($extra_fields)) {
2285
                $counter = 1;
2286
                foreach ($extra_fields as &$extra) {
2287
                    $extra_field_obj = new ExtraField($this->type);
2288
                    $extra_field_info = $extra_field_obj->get($extra['id']);
2289
                    $extra['extra_field_info'] = $extra_field_info;
2290
2291
                    if (isset($extra_field_info['field_type']) &&
2292
                        in_array(
2293
                            $extra_field_info['field_type'],
2294
                            [
2295
                                self::FIELD_TYPE_SELECT,
2296
                                self::FIELD_TYPE_SELECT,
2297
                                self::FIELD_TYPE_DOUBLE_SELECT,
2298
                            ]
2299
                        )
2300
                    ) {
2301
                        $inject_extra_fields .= " fvo$counter.display_text as {$extra['field']}, ";
2302
                    } else {
2303
                        $inject_extra_fields .= " fv$counter.value as {$extra['field']}, ";
2304
                    }
2305
2306
                    if (isset($extra_fields_info[$extra['id']])) {
2307
                        $info = $extra_fields_info[$extra['id']];
2308
                    } else {
2309
                        $info = $this->get($extra['id']);
2310
                        $extra_fields_info[$extra['id']] = $info;
2311
                    }
2312
                    if (isset($info['field_type']) && $info['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
2313
                        $double_fields[$info['id']] = $info;
2314
                    }
2315
                    $counter++;
2316
                }
2317
            }
2318
        }
2319
2320
        $options_by_double = [];
2321
        foreach ($double_fields as $double) {
2322
            $my_options = $extraFieldOption->get_field_options_by_field(
2323
                $double['id'],
2324
                true
2325
            );
2326
            $options_by_double['extra_'.$double['variable']] = $my_options;
2327
        }
2328
2329
        $field_value_to_join = [];
2330
        //filter can be all/any = and/or
2331
        $inject_joins = null;
2332
        $inject_where = null;
2333
        $where = null;
2334
2335
        if (!empty($options['where'])) {
2336
            if (!empty($options['extra'])) {
2337
                // Removing double 1=1
2338
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
2339
                // Always OR
2340
                $counter = 1;
2341
                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...
2342
                    $extra_field_info = $extra_info['extra_field_info'];
2343
                    $inject_joins .= " INNER JOIN $this->table_field_values fv$counter
2344
                                       ON (s.".$this->primaryKey." = fv$counter.".$this->handler_id.") ";
2345
                    // Add options
2346
                    if (isset($extra_field_info['field_type']) &&
2347
                        in_array(
2348
                            $extra_field_info['field_type'],
2349
                            [
2350
                                self::FIELD_TYPE_SELECT,
2351
                                self::FIELD_TYPE_SELECT,
2352
                                self::FIELD_TYPE_DOUBLE_SELECT,
2353
                            ]
2354
                        )
2355
                    ) {
2356
                        $options['where'] = str_replace(
2357
                            $extra_info['field'],
2358
                            'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fvo'.$counter.'.option_value',
2359
                            $options['where']
2360
                        );
2361
                        $inject_joins .= "
2362
                             INNER JOIN $this->table_field_options fvo$counter
2363
                             ON (
2364
                                fv$counter.field_id = fvo$counter.field_id AND
2365
                                fv$counter.value = fvo$counter.option_value
2366
                             )
2367
                            ";
2368
                    } else {
2369
                        if (isset($extra_field_info['field_type']) &&
2370
                            $extra_field_info['field_type'] == self::FIELD_TYPE_TAG
2371
                        ) {
2372
                            $options['where'] = str_replace(
2373
                                $extra_info['field'],
2374
                                'tag'.$counter.'.tag ',
2375
                                $options['where']
2376
                            );
2377
2378
                            $inject_joins .= "
2379
                                INNER JOIN $this->table_field_rel_tag tag_rel$counter
2380
                                ON (
2381
                                    tag_rel$counter.field_id = ".$extra_info['id']." AND 
2382
                                    tag_rel$counter.item_id = s.".$this->primaryKey."
2383
                                )
2384
                                INNER JOIN $this->table_field_tag tag$counter
2385
                                ON (tag$counter.id = tag_rel$counter.tag_id)
2386
                            ";
2387
                        } else {
2388
                            //text, textarea, etc
2389
                            $options['where'] = str_replace(
2390
                                $extra_info['field'],
2391
                                'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fv'.$counter.'.value',
2392
                                $options['where']
2393
                            );
2394
                        }
2395
                    }
2396
2397
                    $field_value_to_join[] = " fv$counter.$this->handler_id ";
2398
                    $counter++;
2399
                }
2400
                if (!empty($field_value_to_join)) {
2401
                    //$inject_where .= " AND s.id = ".implode(' = ', $field_value_to_join);
2402
                }
2403
            }
2404
            $where .= ' AND '.$options['where'];
2405
        }
2406
2407
        $order = null;
2408
        if (!empty($options['order'])) {
2409
            $order = " ORDER BY ".$options['order'];
2410
        }
2411
        $limit = null;
2412
        if (!empty($options['limit'])) {
2413
            $limit = " LIMIT ".$options['limit'];
2414
        }
2415
2416
        return [
2417
            'order' => $order,
2418
            'limit' => $limit,
2419
            'where' => $where,
2420
            'inject_where' => $inject_where,
2421
            'inject_joins' => $inject_joins,
2422
            'field_value_to_join' => $field_value_to_join,
2423
            'inject_extra_fields' => $inject_extra_fields,
2424
        ];
2425
    }
2426
2427
    //@todo move this in the display_class or somewhere else
2428
2429
    /**
2430
     * @param $col
2431
     * @param $oper
2432
     * @param $val
2433
     *
2434
     * @return string
2435
     */
2436
    public function get_where_clause($col, $oper, $val)
2437
    {
2438
        if (empty($col)) {
2439
            return '';
2440
        }
2441
        if ($oper == 'bw' || $oper == 'bn') {
2442
            $val .= '%';
2443
        }
2444
        if ($oper == 'ew' || $oper == 'en') {
2445
            $val = '%'.$val;
2446
        }
2447
        if ($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') {
2448
            if (is_array($val)) {
2449
                $result = '"%'.implode(';', $val).'%"';
2450
                foreach ($val as $item) {
2451
                    $item = trim($item);
2452
                    $result .= ' OR '.$col.' LIKE "%'.$item.'%"';
2453
                }
2454
                $val = $result;
2455
2456
                return " $col {$this->ops[$oper]} $val ";
2457
            } else {
2458
                $val = '%'.$val.'%';
2459
            }
2460
        }
2461
        $val = \Database::escape_string($val);
2462
2463
        return " $col {$this->ops[$oper]} '$val' ";
2464
    }
2465
2466
    /**
2467
     * @param $filters
2468
     * @param string $stringToSearch
2469
     *
2470
     * @return array
2471
     */
2472
    public function getExtraFieldRules($filters, $stringToSearch = 'extra_')
2473
    {
2474
        $extra_fields = [];
2475
2476
        // Getting double select if exists
2477
        $double_select = [];
2478
        foreach ($filters->rules as $rule) {
2479
            if (empty($rule)) {
2480
                continue;
2481
            }
2482
            if (strpos($rule->field, '_second') === false) {
2483
            } else {
2484
                $my_field = str_replace('_second', '', $rule->field);
2485
                $double_select[$my_field] = $rule->data;
2486
            }
2487
        }
2488
2489
        $condition_array = [];
2490
        foreach ($filters->rules as $rule) {
2491
            if (empty($rule)) {
2492
                continue;
2493
            }
2494
            if (strpos($rule->field, $stringToSearch) === false) {
2495
                // normal fields
2496
                $field = $rule->field;
2497
                if (isset($rule->data) && is_string($rule->data) && $rule->data != -1) {
2498
                    $condition_array[] = $this->get_where_clause($field, $rule->op, $rule->data);
2499
                }
2500
            } else {
2501
                // Extra fields
2502
                if (strpos($rule->field, '_second') === false) {
2503
                    //No _second
2504
                    $original_field = str_replace($stringToSearch, '', $rule->field);
2505
                    $field_option = $this->get_handler_field_info_by_field_variable($original_field);
2506
2507
                    if ($field_option['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
2508
                        if (isset($double_select[$rule->field])) {
2509
                            $data = explode('#', $rule->data);
2510
                            $rule->data = $data[1].'::'.$double_select[$rule->field];
2511
                        } else {
2512
                            // only was sent 1 select
2513
                            if (is_string($rule->data)) {
2514
                                $data = explode('#', $rule->data);
2515
                                $rule->data = $data[1];
2516
                            }
2517
                        }
2518
2519
                        if (!isset($rule->data)) {
2520
                            $condition_array[] = ' ('
2521
                                .$this->get_where_clause($rule->field, $rule->op, $rule->data)
2522
                                .') ';
2523
                            $extra_fields[] = ['field' => $rule->field, 'id' => $field_option['id']];
2524
                        }
2525
                    } else {
2526
                        if (isset($rule->data)) {
2527
                            if ($rule->data == -1) {
2528
                                continue;
2529
                            }
2530
                            $condition_array[] = ' ('
2531
                                .$this->get_where_clause($rule->field, $rule->op, $rule->data)
2532
                                .') ';
2533
                            $extra_fields[] = [
2534
                                'field' => $rule->field,
2535
                                'id' => $field_option['id'],
2536
                                'data' => $rule->data,
2537
                            ];
2538
                        }
2539
                    }
2540
                } else {
2541
                    $my_field = str_replace('_second', '', $rule->field);
2542
                    $original_field = str_replace($stringToSearch, '', $my_field);
2543
                    $field_option = $this->get_handler_field_info_by_field_variable($original_field);
2544
                    $extra_fields[] = [
2545
                        'field' => $rule->field,
2546
                        'id' => $field_option['id'],
2547
                    ];
2548
                }
2549
            }
2550
        }
2551
2552
        return [
2553
            'extra_fields' => $extra_fields,
2554
            'condition_array' => $condition_array,
2555
        ];
2556
    }
2557
2558
    /**
2559
     * Get the extra fields and their formatted values.
2560
     *
2561
     * @param int|string $itemId The item ID (It could be a session_id, course_id or user_id)
2562
     *
2563
     * @return array The extra fields data
2564
     */
2565
    public function getDataAndFormattedValues($itemId)
2566
    {
2567
        $valuesData = [];
2568
        $fields = $this->get_all();
2569
        $em = Database::getManager();
2570
2571
        foreach ($fields as $field) {
2572
            if ($field['visible_to_self'] != '1') {
2573
                continue;
2574
            }
2575
2576
            $fieldValue = new ExtraFieldValue($this->type);
2577
            $valueData = $fieldValue->get_values_by_handler_and_field_id(
2578
                $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

2578
                /** @scrutinizer ignore-type */ $itemId,
Loading history...
2579
                $field['id'],
2580
                true
2581
            );
2582
2583
            if ($field['field_type'] == ExtraField::FIELD_TYPE_TAG) {
2584
                $tags = $em
2585
                    ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
2586
                    ->findBy(
2587
                        [
2588
                            'fieldId' => $field['id'],
2589
                            'itemId' => $itemId,
2590
                        ]
2591
                    );
2592
                if ($tags) {
2593
                    /** @var \Chamilo\CoreBundle\Entity\ExtraFieldRelTag $tag */
2594
                    $data = [];
2595
                    foreach ($tags as $extraFieldTag) {
2596
                        /** @var \Chamilo\CoreBundle\Entity\Tag $tag */
2597
                        $tag = $em->find('ChamiloCoreBundle:Tag', $extraFieldTag->getTagId());
2598
                        /*$data[] = [
2599
                            'id' => $extraFieldTag->getTagId(),
2600
                            'value' => $tag->getTag()
2601
                        ];*/
2602
                        $data[] = $tag->getTag();
2603
                    }
2604
                    $valueData = implode(',', $data);
2605
                }
2606
            }
2607
2608
            if (!$valueData) {
2609
                continue;
2610
            }
2611
2612
            $displayedValue = get_lang('None');
2613
2614
            switch ($field['field_type']) {
2615
                case self::FIELD_TYPE_CHECKBOX:
2616
                    if ($valueData !== false && $valueData['value'] == '1') {
2617
                        $displayedValue = get_lang('Yes');
2618
                    } else {
2619
                        $displayedValue = get_lang('No');
2620
                    }
2621
                    break;
2622
                case self::FIELD_TYPE_DATE:
2623
                    if ($valueData !== false && !empty($valueData['value'])) {
2624
                        $displayedValue = api_format_date($valueData['value'], DATE_FORMAT_LONG_NO_DAY);
2625
                    }
2626
                    break;
2627
                case self::FIELD_TYPE_TAG:
2628
                    if (!empty($valueData)) {
2629
                        $displayedValue = $valueData;
2630
                    }
2631
                    break;
2632
                case self::FIELD_TYPE_FILE_IMAGE:
2633
                    if ($valueData === false || empty($valueData['value'])) {
2634
                        break;
2635
                    }
2636
2637
                    if (!file_exists(api_get_path(SYS_UPLOAD_PATH).$valueData['value'])) {
2638
                        break;
2639
                    }
2640
2641
                    $image = Display::img(
2642
                        api_get_path(WEB_UPLOAD_PATH).$valueData['value'],
2643
                        $field['display_text'],
2644
                        ['width' => '300']
2645
                    );
2646
2647
                    $displayedValue = Display::url(
2648
                        $image,
2649
                        api_get_path(WEB_UPLOAD_PATH).$valueData['value'],
2650
                        ['target' => '_blank']
2651
                    );
2652
                    break;
2653
                case self::FIELD_TYPE_FILE:
2654
                    if ($valueData === false || empty($valueData['value'])) {
2655
                        break;
2656
                    }
2657
2658
                    if (!file_exists(api_get_path(SYS_UPLOAD_PATH).$valueData['value'])) {
2659
                        break;
2660
                    }
2661
2662
                    $displayedValue = Display::url(
2663
                        get_lang('Download'),
2664
                        api_get_path(WEB_UPLOAD_PATH).$valueData['value'],
2665
                        [
2666
                            'title' => $field['display_text'],
2667
                            'target' => '_blank',
2668
                        ]
2669
                    );
2670
                    break;
2671
                default:
2672
                    $displayedValue = $valueData['value'];
2673
                    break;
2674
            }
2675
2676
            $valuesData[] = [
2677
                'text' => $field['display_text'],
2678
                'value' => $displayedValue,
2679
            ];
2680
        }
2681
2682
        return $valuesData;
2683
    }
2684
2685
    /**
2686
     * Gets an element.
2687
     *
2688
     * @param int  $id
2689
     * @param bool $translateDisplayText Optional
2690
     *
2691
     * @return array
2692
     */
2693
    public function get($id, $translateDisplayText = true)
2694
    {
2695
        $info = parent::get($id);
2696
2697
        if ($translateDisplayText) {
2698
            $info['display_text'] = self::translateDisplayName($info['variable'], $info['display_text']);
2699
        }
2700
2701
        return $info;
2702
    }
2703
2704
    /**
2705
     * Translate the display text for a extra field.
2706
     *
2707
     * @param string $variable
2708
     * @param string $defaultDisplayText
2709
     *
2710
     * @return string
2711
     */
2712
    public static function translateDisplayName($variable, $defaultDisplayText)
2713
    {
2714
        $camelCase = api_underscore_to_camel_case($variable);
2715
2716
        return isset($GLOBALS[$camelCase]) ? $GLOBALS[$camelCase] : $defaultDisplayText;
2717
    }
2718
2719
    /**
2720
     * @param int    $fieldId
2721
     * @param string $tag
2722
     *
2723
     * @return array
2724
     */
2725
    public function getAllUserPerTag($fieldId, $tag)
2726
    {
2727
        $tagRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
2728
        $tag = Database::escape_string($tag);
2729
        $fieldId = (int) $fieldId;
2730
2731
        $sql = "SELECT user_id 
2732
                FROM {$this->table_field_tag} f INNER JOIN $tagRelUserTable ft 
2733
                ON tag_id = f.id 
2734
                WHERE tag = '$tag' AND f.field_id = $fieldId;
2735
        ";
2736
2737
        $result = Database::query($sql);
2738
2739
        return Database::store_result($result, 'ASSOC');
2740
    }
2741
2742
    /**
2743
     * @param int $fieldId
2744
     * @param int $tagId
2745
     *
2746
     * @return array
2747
     */
2748
    public function getAllSkillPerTag($fieldId, $tagId)
2749
    {
2750
        $skillTable = Database::get_main_table(TABLE_MAIN_SKILL);
2751
        $tagRelExtraTable = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
2752
        $fieldId = intval($fieldId);
2753
        $tagId = intval($tagId);
2754
2755
        $sql = "SELECT s.id
2756
                FROM $skillTable s INNER JOIN $tagRelExtraTable t
2757
                ON t.item_id = s.id
2758
                WHERE tag_id = $tagId AND t.field_id = $fieldId;
2759
        ";
2760
2761
        $result = Database::query($sql);
2762
        $result = Database::store_result($result, 'ASSOC');
2763
2764
        $skillList = [];
2765
        foreach ($result as $index => $value) {
2766
            $skillList[$value['id']] = $value['id'];
2767
        }
2768
2769
        return $skillList;
2770
    }
2771
2772
    /**
2773
     * @param string $from
2774
     * @param string $search
2775
     * @param array  $options
2776
     *
2777
     * @return array
2778
     */
2779
    public function searchOptionsFromTags($from, $search, $options)
2780
    {
2781
        $extraFieldInfo = $this->get_handler_field_info_by_field_variable(
2782
            str_replace('extra_', '', $from)
2783
        );
2784
        $extraFieldInfoTag = $this->get_handler_field_info_by_field_variable(
2785
            str_replace('extra_', '', $search)
2786
        );
2787
2788
        if (empty($extraFieldInfo) || empty($extraFieldInfoTag)) {
2789
            return [];
2790
        }
2791
2792
        $id = $extraFieldInfo['id'];
2793
        $tagId = $extraFieldInfoTag['id'];
2794
2795
        $table = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
2796
        $tagRelExtraTable = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
2797
        $tagTable = Database::get_main_table(TABLE_MAIN_TAG);
2798
        $optionsTable = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
2799
2800
        $sql = "SELECT DISTINCT t.*, v.value, o.display_text
2801
                FROM $tagRelExtraTable te 
2802
                INNER JOIN $tagTable t
2803
                ON (t.id = te.tag_id AND te.field_id = t.field_id AND te.field_id = $tagId) 
2804
                INNER JOIN $table v
2805
                ON (te.item_id = v.item_id AND v.field_id = $id)
2806
                INNER JOIN $optionsTable o
2807
                ON (o.option_value = v.value)
2808
                WHERE v.value IN ('".implode("','", $options)."')                           
2809
                ORDER BY o.option_order, t.tag
2810
               ";
2811
2812
        $result = Database::query($sql);
2813
        $result = Database::store_result($result);
2814
2815
        return $result;
2816
    }
2817
2818
    /**
2819
     * @param string $variable
2820
     * @param string $dataValue
2821
     *
2822
     * @return string
2823
     */
2824
    public static function getLocalizationJavascript($variable, $dataValue)
2825
    {
2826
        $dataValue = addslashes($dataValue);
2827
        $html = "<script>
2828
            $(function() {
2829
                if (typeof google === 'object') {
2830
                    var address = '$dataValue';
2831
                    initializeGeo{$variable}(address, false);
2832
    
2833
                    $('#geolocalization_extra_{$variable}').on('click', function() {
2834
                        var address = $('#{$variable}').val();
2835
                        initializeGeo{$variable}(address, false);
2836
                        return false;
2837
                    });
2838
    
2839
                    $('#myLocation_extra_{$variable}').on('click', function() {
2840
                        myLocation{$variable}();
2841
                        return false;
2842
                    });
2843
    
2844
                    // When clicking enter
2845
                    $('#{$variable}').keypress(function(event) {                        
2846
                        if (event.which == 13) {                            
2847
                            $('#geolocalization_extra_{$variable}').click();
2848
                            return false;
2849
                        }
2850
                    });
2851
                    
2852
                    // On focus out update city
2853
                    $('#{$variable}').focusout(function() {                                                 
2854
                        $('#geolocalization_extra_{$variable}').click();
2855
                        return false;                        
2856
                    });
2857
                    
2858
                    return;
2859
                }
2860
    
2861
                $('#map_extra_{$variable}')
2862
                    .html('<div class=\"alert alert-info\">"
2863
                .addslashes(get_lang('YouNeedToActivateTheGoogleMapsPluginInAdminPlatformToSeeTheMap'))
2864
                ."</div>');
2865
            });
2866
    
2867
            function myLocation{$variable}() 
2868
            {                                                    
2869
                if (navigator.geolocation) {
2870
                    var geoPosition = function(position) {
2871
                        var lat = position.coords.latitude;
2872
                        var lng = position.coords.longitude;
2873
                        var latLng = new google.maps.LatLng(lat, lng);
2874
                        initializeGeo{$variable}(false, latLng);
2875
                    };
2876
    
2877
                    var geoError = function(error) {                        
2878
                        alert('Geocode ".get_lang('Error').": ' + error);
2879
                    };
2880
    
2881
                    var geoOptions = {
2882
                        enableHighAccuracy: true
2883
                    };
2884
                    navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
2885
                }
2886
            }
2887
    
2888
            function initializeGeo{$variable}(address, latLng)
2889
            {                
2890
                var geocoder = new google.maps.Geocoder();
2891
                var latlng = new google.maps.LatLng(-34.397, 150.644);
2892
                var myOptions = {
2893
                    zoom: 15,
2894
                    center: latlng,
2895
                    mapTypeControl: true,
2896
                    mapTypeControlOptions: {
2897
                        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
2898
                    },
2899
                    navigationControl: true,
2900
                    mapTypeId: google.maps.MapTypeId.ROADMAP
2901
                };
2902
    
2903
                map_{$variable} = new google.maps.Map(
2904
                    document.getElementById('map_extra_{$variable}'),
2905
                    myOptions
2906
                );
2907
    
2908
                var parameter = address ? {'address': address} : latLng ? {'latLng': latLng} : false;
2909
    
2910
                if (geocoder && parameter) {
2911
                    geocoder.geocode(parameter, function(results, status) {
2912
                        if (status == google.maps.GeocoderStatus.OK) {
2913
                            if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {                                
2914
                                map_{$variable}.setCenter(results[0].geometry.location);
2915
                                
2916
                                // get city and country                                
2917
                                var defaultAddress = results[0].formatted_address;
2918
                                var city = '';
2919
                                var country = '';
2920
                                
2921
                                for (var i=0; i<results[0].address_components.length; i++) {
2922
                                    if (results[0].address_components[i].types[0] == \"locality\") {
2923
                                        //this is the object you are looking for City
2924
                                        city = results[0].address_components[i];
2925
                                    }
2926
                                    /*if (results[j].address_components[i].types[0] == \"administrative_area_level_1\") {
2927
                                        //this is the object you are looking for State
2928
                                        region = results[0].address_components[i];
2929
                                    }*/
2930
                                    if (results[0].address_components[i].types[0] == \"country\") {
2931
                                        //this is the object you are looking for
2932
                                        country = results[0].address_components[i];
2933
                                    }
2934
                                }
2935
                        
2936
                                if (city && city.long_name && country && country.long_name) {
2937
                                    defaultAddress = city.long_name + ', ' + country.long_name;
2938
                                }
2939
                                $('#{$variable}').val(defaultAddress);                                
2940
                                $('#{$variable}_coordinates').val(
2941
                                    results[0].geometry.location.lat()+','+results[0].geometry.location.lng()
2942
                                );
2943
                                
2944
                                var infowindow = new google.maps.InfoWindow({
2945
                                    content: '<b>' + $('#extra_{$variable}').val() + '</b>',
2946
                                    size: new google.maps.Size(150, 50)
2947
                                });
2948
    
2949
                                var marker = new google.maps.Marker({
2950
                                    position: results[0].geometry.location,
2951
                                    map: map_{$variable},
2952
                                    title: $('#extra_{$variable}').val()
2953
                                });
2954
                                google.maps.event.addListener(marker, 'click', function() {
2955
                                    infowindow.open(map_{$variable}, marker);
2956
                                });
2957
                            } else {
2958
                                alert('".get_lang('NotFound')."');
2959
                            }
2960
                        } else {
2961
                            alert('Geocode ".get_lang('Error').": ".get_lang("AddressField")." ".get_lang('NotFound')."');
2962
                        }
2963
                    });
2964
                }
2965
            }
2966
            </script>";
2967
2968
        return $html;
2969
    }
2970
2971
    /**
2972
     * @param string $variable
2973
     * @param string $text
2974
     *
2975
     * @return string
2976
     */
2977
    public static function getLocalizationInput($variable, $text)
2978
    {
2979
        $html = '
2980
                <div class="form-group">
2981
                    <label for="geolocalization_extra_'.$variable.'"
2982
                        class="col-sm-2 control-label"></label>
2983
                    <div class="col-sm-8">
2984
                        <button class="btn btn-default"
2985
                            id="geolocalization_extra_'.$variable.'"
2986
                            name="geolocalization_extra_'.$variable.'"
2987
                            type="submit">
2988
                            <em class="fa fa-map-marker"></em> '.get_lang('SearchGeolocalization').'
2989
                        </button>
2990
                        <button class="btn btn-default" id="myLocation_extra_'.$variable.'"
2991
                            name="myLocation_extra_'.$variable.'"
2992
                            type="submit">
2993
                            <em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'
2994
                        </button>
2995
                    </div>
2996
                </div>                   
2997
                <div class="form-group">
2998
                    <label for="map_extra_'.$variable.'" class="col-sm-2 control-label">
2999
                        '.$text.' - '.get_lang('Map').'
3000
                    </label>
3001
                    <div class="col-sm-8">
3002
                        <div name="map_extra_'.$variable.'"
3003
                            id="map_extra_'.$variable.'" style="width:100%; height:300px;">
3004
                        </div>
3005
                    </div>
3006
                </div>
3007
            ';
3008
3009
        return $html;
3010
    }
3011
3012
    /**
3013
     * @param array $options
3014
     * @param int   $parentId
3015
     *
3016
     * @return array
3017
     */
3018
    private static function getOptionsFromTripleSelect(array $options, $parentId)
3019
    {
3020
        return array_filter($options, function ($option) use ($parentId) {
3021
            return $option['option_value'] == $parentId;
3022
        });
3023
    }
3024
3025
    /**
3026
     * @param \FormValidator $form
3027
     * @param array          $fieldDetails
3028
     * @param int            $defaultValueId
3029
     * @param bool           $freezeElement
3030
     */
3031
    private function addSelectElement(FormValidator $form, array $fieldDetails, $defaultValueId, $freezeElement = false)
3032
    {
3033
        $get_lang_variables = false;
3034
        if (in_array(
3035
            $fieldDetails['variable'],
3036
            ['mail_notify_message', 'mail_notify_invitation', 'mail_notify_group_message']
3037
        )) {
3038
            $get_lang_variables = true;
3039
        }
3040
3041
        // Get extra field workflow
3042
        $addOptions = [];
3043
        $optionsExists = false;
3044
        $options = [];
3045
3046
        $optionList = [];
3047
        if (!empty($fieldDetails['options'])) {
3048
            foreach ($fieldDetails['options'] as $option_details) {
3049
                $optionList[$option_details['id']] = $option_details;
3050
                if ($get_lang_variables) {
3051
                    $options[$option_details['option_value']] = $option_details['display_text'];
3052
                } else {
3053
                    if ($optionsExists) {
3054
                        // Adding always the default value
3055
                        if ($option_details['id'] == $defaultValueId) {
3056
                            $options[$option_details['option_value']] = $option_details['display_text'];
3057
                        } else {
3058
                            if (isset($addOptions) && !empty($addOptions)) {
3059
                                // Parsing filters
3060
                                if (in_array($option_details['id'], $addOptions)) {
3061
                                    $options[$option_details['option_value']] = $option_details['display_text'];
3062
                                }
3063
                            }
3064
                        }
3065
                    } else {
3066
                        // Normal behaviour
3067
                        $options[$option_details['option_value']] = $option_details['display_text'];
3068
                    }
3069
                }
3070
            }
3071
3072
            // Setting priority message
3073
            if (isset($optionList[$defaultValueId])
3074
                && isset($optionList[$defaultValueId]['priority'])
3075
            ) {
3076
                if (!empty($optionList[$defaultValueId]['priority'])) {
3077
                    $priorityId = $optionList[$defaultValueId]['priority'];
3078
                    $option = new ExtraFieldOption($this->type);
3079
                    $messageType = $option->getPriorityMessageType($priorityId);
3080
                    $form->addElement(
3081
                        'label',
3082
                        null,
3083
                        Display::return_message(
3084
                            $optionList[$defaultValueId]['priority_message'],
3085
                            $messageType
3086
                        )
3087
                    );
3088
                }
3089
            }
3090
        }
3091
3092
        /** @var \HTML_QuickForm_select $slct */
3093
        $slct = $form->addElement(
3094
            'select',
3095
            'extra_'.$fieldDetails['variable'],
3096
            $fieldDetails['display_text'],
3097
            [],
3098
            ['id' => 'extra_'.$fieldDetails['variable']]
3099
        );
3100
3101
        if (empty($defaultValueId)) {
3102
            $slct->addOption(get_lang('SelectAnOption'), '');
3103
        }
3104
3105
        foreach ($options as $value => $text) {
3106
            if (empty($value)) {
3107
                $slct->addOption($text, $value);
3108
                continue;
3109
            }
3110
3111
            $valueParts = explode('#', $text);
3112
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3113
3114
            $slct->addOption(implode('', $valueParts), $value, ['data-value' => $dataValue]);
3115
        }
3116
3117
        /* Enable this when field_loggeable is introduced as a table field (2.0)
3118
        if ($optionsExists && $field_details['field_loggeable'] && !empty($defaultValueId)) {
3119
3120
            $form->addElement(
3121
                'textarea',
3122
                'extra_' . $field_details['variable'] . '_comment',
3123
                $field_details['display_text'] . ' ' . get_lang('Comment')
3124
            );
3125
3126
            $extraFieldValue = new ExtraFieldValue($this->type);
3127
            $repo = $app['orm.em']->getRepository($extraFieldValue->entityName);
3128
            $repoLog = $app['orm.em']->getRepository('Gedmo\Loggable\Entity\LogEntry');
3129
            $newEntity = $repo->findOneBy(
3130
                array(
3131
                    $this->handlerEntityId => $itemId,
3132
                    'fieldId' => $field_details['id']
3133
                )
3134
            );
3135
            // @todo move this in a function inside the class
3136
            if ($newEntity) {
3137
                $logs = $repoLog->getLogEntries($newEntity);
3138
                if (!empty($logs)) {
3139
                    $html = '<b>' . get_lang('LatestChanges') . '</b><br /><br />';
3140
3141
                    $table = new HTML_Table(array('class' => 'data_table'));
3142
                    $table->setHeaderContents(0, 0, get_lang('Value'));
3143
                    $table->setHeaderContents(0, 1, get_lang('Comment'));
3144
                    $table->setHeaderContents(0, 2, get_lang('ModifyDate'));
3145
                    $table->setHeaderContents(0, 3, get_lang('Username'));
3146
                    $row = 1;
3147
                    foreach ($logs as $log) {
3148
                        $column = 0;
3149
                        $data = $log->getData();
3150
                        $fieldValue = isset($data['fieldValue']) ? $data['fieldValue'] : null;
3151
                        $comment = isset($data['comment']) ? $data['comment'] : null;
3152
3153
                        $table->setCellContents($row, $column, $fieldValue);
3154
                        $column++;
3155
                        $table->setCellContents($row, $column, $comment);
3156
                        $column++;
3157
                        $table->setCellContents($row, $column, api_get_local_time($log->getLoggedAt()->format('Y-m-d H:i:s')));
3158
                        $column++;
3159
                        $table->setCellContents($row, $column, $log->getUsername());
3160
                        $row++;
3161
                    }
3162
                    $form->addElement('label', null, $html.$table->toHtml());
3163
                }
3164
            }
3165
        }
3166
        */
3167
3168
        if ($freezeElement) {
3169
            $form->freeze('extra_'.$fieldDetails['variable']);
3170
        }
3171
    }
3172
3173
    /**
3174
     * @param \FormValidator $form
3175
     * @param array          $fieldDetails
3176
     * @param array          $extraData
3177
     * @param bool           $freezeElement
3178
     *
3179
     * @return string JavaScript code
3180
     */
3181
    private function addDoubleSelectElement(FormValidator $form, $fieldDetails, $extraData, $freezeElement = false)
3182
    {
3183
        $firstSelectId = 'first_extra_'.$fieldDetails['variable'];
3184
        $secondSelectId = 'second_extra_'.$fieldDetails['variable'];
3185
3186
        $jqueryReadyContent = "
3187
            $('#$firstSelectId').on('change', function() {
3188
                var id = $(this).val();
3189
3190
                if (!id) {
3191
                    $('#$secondSelectId').empty().selectpicker('refresh');
3192
                    
3193
                    return;
3194
                }
3195
3196
                $.getJSON(_p.web_ajax + 'extra_field.ajax.php?1=1&a=get_second_select_options', {
3197
                    'type': '{$this->type}',
3198
                    'field_id': {$fieldDetails['id']},
3199
                    'option_value_id': id
3200
                })
3201
                    .done(function(data) {
3202
                        $('#$secondSelectId').empty();
3203
                        $.each(data, function(index, value) {
3204
                            $('#second_extra_{$fieldDetails['variable']}').append(
3205
                                $('<option>', {value: index, text: value})
3206
                            );
3207
                        });
3208
                        $('#$secondSelectId').selectpicker('refresh');
3209
                    });
3210
            });
3211
        ";
3212
3213
        $firstId = null;
3214
        if (!empty($extraData)) {
3215
            if (isset($extraData['extra_'.$fieldDetails['variable']])) {
3216
                $firstId = $extraData['extra_'.$fieldDetails['variable']]['extra_'.$fieldDetails['variable']];
3217
            }
3218
        }
3219
3220
        $options = $this->extra_field_double_select_convert_array_to_ordered_array($fieldDetails['options']);
3221
        $values = ['' => get_lang('Select')];
3222
3223
        $second_values = [];
3224
        if (!empty($options)) {
3225
            foreach ($options as $option) {
3226
                foreach ($option as $sub_option) {
3227
                    if ($sub_option['option_value'] == '0') {
3228
                        $values[$sub_option['id']] = $sub_option['display_text'];
3229
3230
                        continue;
3231
                    }
3232
3233
                    if ($firstId === $sub_option['option_value']) {
3234
                        $second_values[$sub_option['id']] = $sub_option['display_text'];
3235
                    }
3236
                }
3237
            }
3238
        }
3239
        $form
3240
            ->defaultRenderer()
3241
            ->setGroupElementTemplate('<p>{element}</p>', 'extra_'.$fieldDetails['variable']);
3242
        $group = [];
3243
        $group[] = $form->createElement(
3244
            'select',
3245
            'extra_'.$fieldDetails['variable'],
3246
            null,
3247
            $values,
3248
            ['id' => $firstSelectId]
3249
        );
3250
        $group[] = $form->createElement(
3251
            'select',
3252
            'extra_'.$fieldDetails['variable'].'_second',
3253
            null,
3254
            $second_values,
3255
            ['id' => $secondSelectId]
3256
        );
3257
        $form->addGroup(
3258
            $group,
3259
            'extra_'.$fieldDetails['variable'],
3260
            $fieldDetails['display_text']
3261
        );
3262
3263
        if ($freezeElement) {
3264
            $form->freeze('extra_'.$fieldDetails['variable']);
3265
        }
3266
3267
        return $jqueryReadyContent;
3268
    }
3269
3270
    /**
3271
     * @param \FormValidator $form
3272
     * @param array          $fieldDetails
3273
     * @param bool           $freezeElement Optional
3274
     *
3275
     * @return string JavaScript code
3276
     */
3277
    private function addSelectWithTextFieldElement(
3278
        FormValidator $form,
3279
        array $fieldDetails,
3280
        $freezeElement = false
3281
    ) {
3282
        $firstSelectId = 'slct_extra_'.$fieldDetails['variable'];
3283
        $txtSelectId = 'txt_extra_'.$fieldDetails['variable'];
3284
3285
        $jqueryReadyContent = "
3286
            $('#$firstSelectId').on('change', function() {
3287
                var id = $(this).val();
3288
3289
                if (!id) {
3290
                    $('#$txtSelectId').val('');
3291
                }
3292
            });
3293
        ";
3294
3295
        $options = $this->extra_field_double_select_convert_array_to_ordered_array($fieldDetails['options']);
3296
        $values = ['' => get_lang('Select')];
3297
3298
        if (!empty($options)) {
3299
            foreach ($options as $option) {
3300
                foreach ($option as $sub_option) {
3301
                    if ($sub_option['option_value'] != '0') {
3302
                        continue;
3303
                    }
3304
3305
                    $values[$sub_option['id']] = $sub_option['display_text'];
3306
                }
3307
            }
3308
        }
3309
3310
        $form
3311
            ->defaultRenderer()
3312
            ->setGroupElementTemplate('<p>{element}</p>', 'extra_'.$fieldDetails['variable']);
3313
        $group = [];
3314
        $group[] = $form->createElement(
3315
            'select',
3316
            'extra_'.$fieldDetails['variable'],
3317
            null,
3318
            $values,
3319
            ['id' => $firstSelectId]
3320
        );
3321
        $group[] = $form->createElement(
3322
            'text',
3323
            'extra_'.$fieldDetails['variable'].'_second',
3324
            null,
3325
            ['id' => $txtSelectId]
3326
        );
3327
        $form->addGroup(
3328
            $group,
3329
            'extra_'.$fieldDetails['variable'],
3330
            $fieldDetails['display_text']
3331
        );
3332
3333
        if ($freezeElement) {
3334
            $form->freeze('extra_'.$fieldDetails['variable']);
3335
        }
3336
3337
        return $jqueryReadyContent;
3338
    }
3339
3340
    /**
3341
     * @param \FormValidator $form
3342
     * @param array          $fieldDetails
3343
     * @param array          $extraData
3344
     * @param bool           $freezeElement
3345
     *
3346
     * @return string
3347
     */
3348
    private function addTripleSelectElement(
3349
        FormValidator $form,
3350
        array $fieldDetails,
3351
        array $extraData,
3352
        $freezeElement
3353
    ) {
3354
        $variable = $fieldDetails['variable'];
3355
        $id = $fieldDetails['id'];
3356
        $slctFirstId = "first_extra$variable";
3357
        $slctSecondId = "second_extra$variable";
3358
        $slctThirdId = "third_extra$variable";
3359
        $langSelect = get_lang('Select');
3360
3361
        $js = "
3362
            (function () {
3363
                var slctFirst = $('#$slctFirstId'),
3364
                    slctSecond = $('#$slctSecondId'),
3365
                    slctThird = $('#$slctThirdId');
3366
                    
3367
                slctFirst.on('change', function () {
3368
                    slctSecond.empty().selectpicker('refresh');
3369
                    slctThird.empty().selectpicker('refresh');
3370
    
3371
                    var level = $(this).val();
3372
    
3373
                    if (!level) {
3374
                        return;
3375
                    }
3376
    
3377
                    $.getJSON(_p.web_ajax + 'extra_field.ajax.php', {
3378
                        'a': 'get_second_select_options',
3379
                        'type': '$this->type',
3380
                        'field_id': $id,
3381
                        'option_value_id': level
3382
                    })
3383
                        .done(function (data) {
3384
                            slctSecond.append(
3385
                                $('<option>', {value: '', text: '$langSelect'})
3386
                            );
3387
3388
                            $.each(data, function (index, value) {
3389
                                var valueParts = value.split('#'),
3390
                                    dataValue = valueParts.length > 1 ? valueParts.shift() : '';
3391
3392
                                slctSecond.append(
3393
                                    $('<option>', {value: index, text: valueParts.join(''), 'data-value': dataValue})
3394
                                );
3395
                            });
3396
    
3397
                            slctSecond.selectpicker('refresh');
3398
                        });
3399
                });
3400
                slctSecond.on('change', function () {
3401
                    slctThird.empty().selectpicker('refresh');
3402
    
3403
                    var level = $(this).val();
3404
                    
3405
                    if (!level) {
3406
                        return;
3407
                    }
3408
                    
3409
                    $.getJSON(_p.web_ajax + 'extra_field.ajax.php', {
3410
                        'a': 'get_second_select_options',
3411
                        'type': '$this->type',
3412
                        'field_id': $id,
3413
                        'option_value_id': level
3414
                    })
3415
                        .done(function (data) {
3416
                            slctThird.append(
3417
                                $('<option>', {value: '', text: '$langSelect'})
3418
                            );
3419
3420
                            $.each(data, function (index, value) {
3421
                                var valueParts = value.split('#'),
3422
                                    dataValue = valueParts.length > 1 ? valueParts.shift() : '';
3423
3424
                                slctThird.append(
3425
                                    $('<option>', {value: index, text: valueParts.join(''), 'data-value': dataValue})
3426
                                );
3427
                            });
3428
    
3429
                            slctThird.selectpicker('refresh');
3430
                        });
3431
                });
3432
            })();
3433
        ";
3434
3435
        $firstId = isset($extraData["extra_$variable"]["extra_$variable"])
3436
            ? $extraData["extra_$variable"]["extra_$variable"]
3437
            : '';
3438
        $secondId = isset($extraData["extra_$variable"]["extra_{$variable}_second"])
3439
            ? $extraData["extra_$variable"]["extra_{$variable}_second"]
3440
            : '';
3441
3442
        $options = $this->tripleSelectConvertArrayToOrderedArray($fieldDetails['options']);
3443
        $values1 = ['' => $langSelect];
3444
        $values2 = ['' => $langSelect];
3445
        $values3 = ['' => $langSelect];
3446
        $level1 = $this->getOptionsFromTripleSelect($options['level1'], 0);
3447
        $level2 = $this->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

3447
        $level2 = $this->getOptionsFromTripleSelect($options['level2'], /** @scrutinizer ignore-type */ $firstId);
Loading history...
3448
        $level3 = $this->getOptionsFromTripleSelect($options['level3'], $secondId);
3449
        /** @var \HTML_QuickForm_select $slctFirst */
3450
        $slctFirst = $form->createElement('select', "extra_$variable", null, $values1, ['id' => $slctFirstId]);
3451
        /** @var \HTML_QuickForm_select $slctFirst */
3452
        $slctSecond = $form->createElement('select', "extra_{$variable}_second", null, $values2, ['id' => $slctSecondId]);
3453
        /** @var \HTML_QuickForm_select $slctFirst */
3454
        $slctThird = $form->createElement('select', "extra_{$variable}_third", null, $values3, ['id' => $slctThirdId]);
3455
3456
        foreach ($level1 as $item1) {
3457
            $valueParts = explode('#', $item1['display_text']);
3458
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3459
            $slctFirst->addOption(implode('', $valueParts), $item1['id'], ['data-value' => $dataValue]);
3460
        }
3461
3462
        foreach ($level2 as $item2) {
3463
            $valueParts = explode('#', $item2['display_text']);
3464
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3465
            $slctSecond->addOption(implode('', $valueParts), $item2['id'], ['data-value' => $dataValue]);
3466
        }
3467
3468
        foreach ($level3 as $item3) {
3469
            $valueParts = explode('#', $item3['display_text']);
3470
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3471
            $slctThird->addOption(implode('', $valueParts), $item3['id'], ['data-value' => $dataValue]);
3472
        }
3473
3474
        $form
3475
            ->defaultRenderer()
3476
            ->setGroupElementTemplate('<p>{element}</p>', "extra_$variable");
3477
        $form->addGroup([$slctFirst, $slctSecond, $slctThird], "extra_$variable", $fieldDetails['display_text']);
3478
3479
        if ($freezeElement) {
3480
            $form->freeze('extra_'.$fieldDetails['variable']);
3481
        }
3482
3483
        return $js;
3484
    }
3485
}
3486