Passed
Push — master ( 271415...ff556a )
by Julito
09:26
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
            ],
1929
            [
1930
                'name' => 'visible_to_self',
1931
                'index' => 'visible_to_self',
1932
                'width' => '45',
1933
                'align' => 'left',
1934
                'sortable' => 'true',
1935
            ],
1936
            [
1937
                'name' => 'visible_to_others',
1938
                'index' => 'visible_to_others',
1939
                'width' => '35',
1940
                'align' => 'left',
1941
                'sortable' => 'true',
1942
            ],
1943
            [
1944
                'name' => 'filter',
1945
                'index' => 'filter',
1946
                'width' => '30',
1947
                'align' => 'left',
1948
                'sortable' => 'true',
1949
            ],
1950
            [
1951
                'name' => 'field_order',
1952
                'index' => 'field_order',
1953
                'width' => '25',
1954
                'align' => 'left',
1955
                'sortable' => 'true',
1956
            ],
1957
            [
1958
                'name' => 'actions',
1959
                'index' => 'actions',
1960
                'width' => '40',
1961
                'align' => 'left',
1962
                'formatter' => 'action_formatter',
1963
                'sortable' => 'false',
1964
            ],
1965
        ];
1966
    }
1967
1968
    /**
1969
     * @param string $url
1970
     * @param string $action
1971
     *
1972
     * @return FormValidator
1973
     */
1974
    public function return_form($url, $action)
1975
    {
1976
        $form = new FormValidator($this->type.'_field', 'post', $url);
1977
1978
        $form->addElement('hidden', 'type', $this->type);
1979
        $id = isset($_GET['id']) ? (int) $_GET['id'] : null;
1980
        $form->addElement('hidden', 'id', $id);
1981
1982
        // Setting the form elements
1983
        $header = get_lang('Add');
1984
        $defaults = [];
1985
1986
        if ($action === 'edit') {
1987
            $header = get_lang('Modify');
1988
            // Setting the defaults
1989
            $defaults = $this->get($id, false);
1990
        }
1991
1992
        $form->addElement('header', $header);
1993
1994
        if ($action === 'edit') {
1995
            $translateUrl = api_get_path(WEB_CODE_PATH).'extrafield/translate.php?'
1996
                .http_build_query(['extra_field' => $id]);
1997
            $translateButton = Display::toolbarButton(get_lang('TranslateThisTerm'), $translateUrl, 'language', 'link');
1998
1999
            $form->addText(
2000
                'display_text',
2001
                [get_lang('Name'), $translateButton]
2002
            );
2003
        } else {
2004
            $form->addElement('text', 'display_text', get_lang('Name'));
2005
        }
2006
2007
        $form->addHtmlEditor('description', get_lang('Description'), false);
2008
2009
        // Field type
2010
        $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

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

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

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