Passed
Push — master ( f437d8...92f70a )
by Julito
10:14
created

ExtraField::addElements()   B

Complexity

Conditions 11
Paths 17

Size

Total Lines 80
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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

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

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

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