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

ExtraField::addSelectElement()   D

Complexity

Conditions 18
Paths 128

Size

Total Lines 141
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
eloc 55
c 0
b 0
f 0
nc 128
nop 4
dl 0
loc 141
rs 4.6333

How to fix   Long Method    Complexity   

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:

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