Passed
Push — 1.11.x ( b99403...e54d88 )
by Julito
11:24
created

ExtraField::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

944
        /** @scrutinizer ignore-call */ 
945
        $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
Loading history...
945
        $params = $this->clean_parameters($params);
946
        $params['extra_field_type'] = $this->extraFieldType;
947
948
        if ($fieldInfo) {
949
            return $fieldInfo['id'];
950
        } else {
951
            $id = parent::save($params, $show_query);
952
            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...
953
                $fieldOption = new ExtraFieldOption($this->type);
954
                $params['field_id'] = $id;
955
                $fieldOption->save($params);
956
            }
957
958
            return $id;
959
        }
960
    }
961
962
    /**
963
     * {@inheritdoc}
964
     */
965
    public function update($params, $showQuery = false)
966
    {
967
        $params = $this->clean_parameters($params);
968
        if (isset($params['id'])) {
969
            $fieldOption = new ExtraFieldOption($this->type);
970
            $params['field_id'] = $params['id'];
971
            if (empty($params['field_type'])) {
972
                $params['field_type'] = $this->type;
973
            }
974
            $fieldOption->save($params, $showQuery);
975
        }
976
977
        return parent::update($params, $showQuery);
978
    }
979
980
    /**
981
     * @param $id
982
     *
983
     * @return bool
984
     */
985
    public function delete($id)
986
    {
987
        $em = Database::getManager();
988
        $items = $em->getRepository('ChamiloCoreBundle:ExtraFieldSavedSearch')->findBy(['field' => $id]);
989
        if ($items) {
990
            foreach ($items as $item) {
991
                $em->remove($item);
992
            }
993
            $em->flush();
994
        }
995
        $field_option = new ExtraFieldOption($this->type);
996
        $field_option->delete_all_options_by_field_id($id);
997
998
        $session_field_values = new ExtraFieldValue($this->type);
999
        $session_field_values->delete_all_values_by_field_id($id);
1000
1001
        return parent::delete($id);
1002
    }
1003
1004
    /**
1005
     * Add an element that matches the given extra field to the given $form object.
1006
     *
1007
     * @param FormValidator $form                The form these fields are to be attached to
1008
     * @param array         $extraData
1009
     * @param bool          $adminPermissions    Whether the display is considered without edition limits (true) or not (false)
1010
     * @param array         $extra
1011
     * @param int           $itemId              The item (course, user, session, etc) this extra_field is attached to
1012
     * @param array         $exclude             Extra fields to be skipped, by textual ID
1013
     * @param bool          $useTagAsSelect      Whether to show tag fields as select drop-down or not
1014
     * @param array         $showOnlyTheseFields Limit the extra fields shown to just the list given here
1015
     * @param array         $orderFields         An array containing the names of the fields shown, in the right order
1016
     *
1017
     * @throws Exception
1018
     *
1019
     * @return array If relevant, returns a one-element array with JS code to be added to the page HTML headers
1020
     */
1021
    public function set_extra_fields_in_form(
1022
        $form,
1023
        $extraData,
1024
        $adminPermissions = false,
1025
        $extra = [],
1026
        $itemId = null,
1027
        $exclude = [],
1028
        $useTagAsSelect = false,
1029
        $showOnlyTheseFields = [],
1030
        $orderFields = [],
1031
        $orderDependingDefaults = false,
1032
        $separateExtraMultipleSelect = [],
1033
        $customLabelsExtraMultipleSelect = [],
1034
        $addEmptyOptionSelects = false,
1035
        $introductionTextList = [],
1036
        $hideGeoLocalizationDetails = false,
1037
        $help = false
1038
    ) {
1039
        $jquery_ready_content = null;
1040
        if (!empty($extra)) {
1041
            $newOrder = [];
1042
            if (!empty($orderFields)) {
1043
                foreach ($orderFields as $order) {
1044
                    foreach ($extra as $field_details) {
1045
                        if ($order == $field_details['variable']) {
1046
                            $newOrder[] = $field_details;
1047
                        }
1048
                    }
1049
                }
1050
                $extra = $newOrder;
1051
            }
1052
1053
            foreach ($extra as $field_details) {
1054
                if (!empty($showOnlyTheseFields)) {
1055
                    if (!in_array($field_details['variable'], $showOnlyTheseFields)) {
1056
                        continue;
1057
                    }
1058
                }
1059
1060
                // Getting default value id if is set
1061
                $defaultValueId = null;
1062
                if (isset($field_details['options']) && !empty($field_details['options'])) {
1063
                    $valueToFind = null;
1064
                    if (isset($field_details['field_default_value'])) {
1065
                        $valueToFind = $field_details['field_default_value'];
1066
                    }
1067
                    // If a value is found we override the default value
1068
                    if (isset($extraData['extra_'.$field_details['variable']])) {
1069
                        $valueToFind = $extraData['extra_'.$field_details['variable']];
1070
                    }
1071
1072
                    foreach ($field_details['options'] as $option) {
1073
                        if ($option['option_value'] == $valueToFind) {
1074
                            $defaultValueId = $option['id'];
1075
                        }
1076
                    }
1077
                }
1078
1079
                if (!$adminPermissions) {
1080
                    if (0 == $field_details['visible_to_self']) {
1081
                        continue;
1082
                    }
1083
1084
                    if (in_array($field_details['variable'], $exclude)) {
1085
                        continue;
1086
                    }
1087
                }
1088
1089
                if (!empty($introductionTextList) &&
1090
                    in_array($field_details['variable'], array_keys($introductionTextList))
1091
                ) {
1092
                    $form->addHtml($introductionTextList[$field_details['variable']]);
1093
                }
1094
1095
                $freezeElement = false;
1096
                if (!$adminPermissions) {
1097
                    $freezeElement = 0 == $field_details['visible_to_self'] || 0 == $field_details['changeable'];
1098
                }
1099
1100
                $translatedDisplayText = get_lang($field_details['display_text'], true);
1101
                $translatedDisplayHelpText = '';
1102
                if ($help) {
1103
                    $translatedDisplayHelpText .= get_lang($field_details['display_text'].'Help');
1104
                }
1105
                if (!empty($translatedDisplayText)) {
1106
                    if (!empty($translatedDisplayHelpText)) {
1107
                        // In this case, exceptionally, display_text is an array
1108
                        // which is then treated by display_form()
1109
                        $field_details['display_text'] = [$translatedDisplayText, $translatedDisplayHelpText];
1110
                    } else {
1111
                        // We have an helper text, use it
1112
                        $field_details['display_text'] = $translatedDisplayText;
1113
                    }
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 (1 == $field_details['default_value']) {
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
                        if ($separateValue > 0) {
1311
                            $em = Database::getManager();
1312
                            $fieldTags = $em
1313
                                ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1314
                                ->findBy(
1315
                                    [
1316
                                        'fieldId' => $field_id,
1317
                                        'itemId' => $itemId,
1318
                                    ]
1319
                                );
1320
                            // ofaj
1321
1322
                            for ($i = 0; $i < $separateValue; $i++) {
1323
                                $tagsSelect = $form->addElement(
1324
                                    'select',
1325
                                    'extra_'.$field_details['variable'].'['.$i.']',
1326
                                    $customLabelsExtraMultipleSelect[$field_details['variable']][$i], //$field_details['display_text'],
1327
                                    null,
1328
                                    ['id' => 'extra_'.$field_details['variable'].'_'.$i]
1329
                                );
1330
1331
                                if ($addEmptyOptionSelects) {
1332
                                    $tagsSelect->addOption(
1333
                                        '',
1334
                                        ''
1335
                                    );
1336
                                }
1337
1338
                                foreach ($fieldTags as $fieldTag) {
1339
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1340
1341
                                    if (empty($tag)) {
1342
                                        continue;
1343
                                    }
1344
1345
                                    $tagsSelect->addOption(
1346
                                        $tag->getTag(),
1347
                                        $tag->getTag()
1348
                                    );
1349
                                }
1350
                            }
1351
                        } else {
1352
                            $tagsSelect = $form->addSelect(
1353
                                "extra_{$field_details['variable']}",
1354
                                $field_details['display_text'],
1355
                                [],
1356
                                ['style' => 'width: 100%;']
1357
                            );
1358
1359
                            if (false === $useTagAsSelect) {
1360
                                $tagsSelect->setAttribute('class', null);
1361
                            }
1362
1363
                            $tagsSelect->setAttribute(
1364
                                'id',
1365
                                "extra_{$field_details['variable']}"
1366
                            );
1367
                            $tagsSelect->setMultiple(true);
1368
1369
                            $selectedOptions = [];
1370
                            if ('user' === $this->type) {
1371
                                // The magic should be here
1372
                                $user_tags = UserManager::get_user_tags(
1373
                                    $itemId,
1374
                                    $field_details['id']
1375
                                );
1376
1377
                                if (is_array($user_tags) && count($user_tags) > 0) {
1378
                                    foreach ($user_tags as $tag) {
1379
                                        if (empty($tag['tag'])) {
1380
                                            continue;
1381
                                        }
1382
                                        $tagsSelect->addOption(
1383
                                            $tag['tag'],
1384
                                            $tag['tag'],
1385
                                            [
1386
                                                'selected' => 'selected',
1387
                                                'class' => 'selected',
1388
                                            ]
1389
                                        );
1390
                                        $selectedOptions[] = $tag['tag'];
1391
                                    }
1392
                                }
1393
                                $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
1394
                            } else {
1395
                                $em = Database::getManager();
1396
                                $fieldTags = $em->getRepository(
1397
                                    'ChamiloCoreBundle:ExtraFieldRelTag'
1398
                                )
1399
                                ->findBy(
1400
                                    [
1401
                                        'fieldId' => $field_id,
1402
                                        'itemId' => $itemId,
1403
                                    ]
1404
                                );
1405
1406
                                /** @var ExtraFieldRelTag $fieldTag */
1407
                                foreach ($fieldTags as $fieldTag) {
1408
                                    /** @var Tag $tag */
1409
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1410
1411
                                    if (empty($tag)) {
1412
                                        continue;
1413
                                    }
1414
                                    $tagsSelect->addOption(
1415
                                        $tag->getTag(),
1416
                                        $tag->getTag()
1417
                                    );
1418
                                    $selectedOptions[] = $tag->getTag();
1419
                                }
1420
1421
                                if (!empty($extraData) && isset($extraData['extra_'.$field_details['variable']])) {
1422
                                    $data = $extraData['extra_'.$field_details['variable']];
1423
                                    if (!empty($data)) {
1424
                                        foreach ($data as $option) {
1425
                                            $tagsSelect->addOption(
1426
                                                $option,
1427
                                                $option
1428
                                            );
1429
                                        }
1430
                                    }
1431
                                }
1432
1433
                                if ($useTagAsSelect) {
1434
                                    $fieldTags = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1435
                                        ->findBy(
1436
                                            [
1437
                                                'fieldId' => $field_id,
1438
                                            ]
1439
                                        );
1440
                                    $tagsAdded = [];
1441
                                    foreach ($fieldTags as $fieldTag) {
1442
                                        $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1443
1444
                                        if (empty($tag)) {
1445
                                            continue;
1446
                                        }
1447
1448
                                        $tagText = $tag->getTag();
1449
1450
                                        if (in_array($tagText, $tagsAdded)) {
1451
                                            continue;
1452
                                        }
1453
1454
                                        $tagsSelect->addOption(
1455
                                            $tag->getTag(),
1456
                                            $tag->getTag(),
1457
                                            []
1458
                                        );
1459
1460
                                        $tagsAdded[] = $tagText;
1461
                                    }
1462
                                }
1463
                                $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php';
1464
                            }
1465
1466
                            $form->setDefaults(
1467
                                [
1468
                                    'extra_'.$field_details['variable'] => $selectedOptions,
1469
                                ]
1470
                            );
1471
1472
                            if (false == $useTagAsSelect) {
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...
1473
                                $jquery_ready_content .= "
1474
                                $('#extra_$variable').select2({
1475
                                    ajax: {
1476
                                        url: '$url?a=search_tags&field_id=$field_id&type={$this->type}',
1477
                                        processResults: function (data) {
1478
                                            return {
1479
                                                results: data.items
1480
                                            }
1481
                                        }
1482
                                    },
1483
                                    cache: false,
1484
                                    tags: true,
1485
                                    tokenSeparators: [','],
1486
                                    placeholder: '".get_lang('StartToType')."'
1487
                                });
1488
                            ";
1489
                            }
1490
                        }
1491
1492
                        break;
1493
                    case self::FIELD_TYPE_TIMEZONE:
1494
                        $form->addElement(
1495
                            'select',
1496
                            'extra_'.$field_details['variable'],
1497
                            $field_details['display_text'],
1498
                            api_get_timezones(),
1499
                            ''
1500
                        );
1501
                        if ($freezeElement) {
1502
                            $form->freeze('extra_'.$field_details['variable']);
1503
                        }
1504
                        break;
1505
                    case self::FIELD_TYPE_SOCIAL_PROFILE:
1506
                        // get the social network's favicon
1507
                        $extra_data_variable = isset($extraData['extra_'.$field_details['variable']])
1508
                            ? $extraData['extra_'.$field_details['variable']]
1509
                            : null;
1510
                        $field_default_value = isset($field_details['field_default_value'])
1511
                            ? $field_details['field_default_value']
1512
                            : null;
1513
                        $icon_path = UserManager::get_favicon_from_url(
1514
                            $extra_data_variable,
1515
                            $field_default_value
1516
                        );
1517
                        // special hack for hi5
1518
                        $leftpad = '1.7';
1519
                        $top = '0.4';
1520
                        $domain = parse_url($icon_path, PHP_URL_HOST);
1521
                        if ('www.hi5.com' === $domain || 'hi5.com' === $domain) {
1522
                            $leftpad = '3';
1523
                            $top = '0';
1524
                        }
1525
                        // print the input field
1526
                        $form->addElement(
1527
                            'text',
1528
                            'extra_'.$field_details['variable'],
1529
                            $field_details['display_text'],
1530
                            [
1531
                                'size' => 60,
1532
                                'size' => implode(
1533
                                    '; ',
1534
                                    [
1535
                                        "background-image: url('$icon_path')",
1536
                                        'background-repeat: no-repeat',
1537
                                        "background-position: 0.4em {$top}em",
1538
                                        "padding-left: {$leftpad}em",
1539
                                    ]
1540
                                ),
1541
                            ]
1542
                        );
1543
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1544
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1545
                        if ($freezeElement) {
1546
                            $form->freeze('extra_'.$field_details['variable']);
1547
                        }
1548
                        break;
1549
                    case self::FIELD_TYPE_MOBILE_PHONE_NUMBER:
1550
                        $form->addElement(
1551
                            'text',
1552
                            'extra_'.$field_details['variable'],
1553
                            $field_details['display_text'].' ('.get_lang('CountryDialCode').')',
1554
                            ['size' => 40, 'placeholder' => '(xx)xxxxxxxxx']
1555
                        );
1556
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1557
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1558
                        $form->applyFilter('extra_'.$field_details['variable'], 'mobile_phone_number_filter');
1559
                        $form->addRule(
1560
                            'extra_'.$field_details['variable'],
1561
                            get_lang('MobilePhoneNumberWrong'),
1562
                            'mobile_phone_number'
1563
                        );
1564
                        if ($freezeElement) {
1565
                            $form->freeze('extra_'.$field_details['variable']);
1566
                        }
1567
                        break;
1568
                    case self::FIELD_TYPE_INTEGER:
1569
                        $form->addElement(
1570
                            'number',
1571
                            'extra_'.$field_details['variable'],
1572
                            $field_details['display_text'],
1573
                            ['class' => 'span1', 'step' => 1]
1574
                        );
1575
1576
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1577
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1578
                        $form->applyFilter('extra_'.$field_details['variable'], 'intval');
1579
1580
                        if ($freezeElement) {
1581
                            $form->freeze('extra_'.$field_details['variable']);
1582
                        }
1583
                        break;
1584
                    case self::FIELD_TYPE_FILE_IMAGE:
1585
                        $fieldVariable = "extra_{$field_details['variable']}";
1586
                        $fieldTexts = [
1587
                            $field_details['display_text'],
1588
                        ];
1589
1590
                        if (is_array($extraData) && array_key_exists($fieldVariable, $extraData)) {
1591
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1592
                                $fieldTexts[] = Display::img(
1593
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1594
                                    $field_details['display_text'],
1595
                                    ['width' => '300']
1596
                                );
1597
                            }
1598
                        }
1599
1600
                        if ('Image' === $fieldTexts[0]) {
1601
                            $fieldTexts[0] = get_lang($fieldTexts[0]);
1602
                        }
1603
1604
                        $form->addFile(
1605
                            $fieldVariable,
1606
                            $fieldTexts,
1607
                            ['accept' => 'image/*', 'id' => 'extra_image', 'crop_image' => 'true']
1608
                        );
1609
1610
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1611
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1612
1613
                        $allowedPictureTypes = ['jpg', 'jpeg', 'png', 'gif'];
1614
                        $form->addRule(
1615
                            'extra_'.$field_details['variable'],
1616
                            get_lang('OnlyImagesAllowed').' ('.implode(',', $allowedPictureTypes).')',
1617
                            'filetype',
1618
                            $allowedPictureTypes
1619
                        );
1620
1621
                        if ($freezeElement) {
1622
                            $form->freeze('extra_'.$field_details['variable']);
1623
                        }
1624
                        break;
1625
                    case self::FIELD_TYPE_FLOAT:
1626
                        $form->addElement(
1627
                            'number',
1628
                            'extra_'.$field_details['variable'],
1629
                            $field_details['display_text'],
1630
                            ['class' => 'span1', 'step' => '0.01']
1631
                        );
1632
1633
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1634
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1635
                        $form->applyFilter('extra_'.$field_details['variable'], 'floatval');
1636
1637
                        if ($freezeElement) {
1638
                            $form->freeze('extra_'.$field_details['variable']);
1639
                        }
1640
                        break;
1641
                    case self::FIELD_TYPE_FILE:
1642
                        $fieldVariable = "extra_{$field_details['variable']}";
1643
                        $fieldTexts = [
1644
                            $field_details['display_text'],
1645
                        ];
1646
1647
                        if (is_array($extraData) &&
1648
                            array_key_exists($fieldVariable, $extraData)
1649
                        ) {
1650
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1651
                                $linkToDelete = '';
1652
                                $divItemId = $field_details['variable'];
1653
                                if (api_is_platform_admin()) {
1654
                                    $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?type='.$this->type;
1655
                                    $url .= '&a=delete_file&field_id='.$field_details['id'].'&item_id='.$itemId;
1656
1657
                                    $deleteId = $field_details['variable'].'_delete';
1658
                                    $form->addHtml("
1659
                                        <script>
1660
                                            $(function() {
1661
                                                $('#".$deleteId."').on('click', function() {
1662
                                                    $.ajax({
1663
                                                        type: 'GET',
1664
                                                        url: '".$url."',
1665
                                                        success: function(result) {
1666
                                                            if (result == 1) {
1667
                                                                $('#".$divItemId."').html('".get_lang('Deleted')."');
1668
                                                            }
1669
                                                        }
1670
                                                    });
1671
                                                });
1672
                                            });
1673
                                        </script>
1674
                                    ");
1675
1676
                                    $linkToDelete = '&nbsp;'.Display::url(
1677
                                        Display::return_icon('delete.png', get_lang('Delete')),
1678
                                        'javascript:void(0)',
1679
                                        ['id' => $deleteId]
1680
                                    );
1681
                                }
1682
                                $fieldTexts[] = '<div id="'.$divItemId.'">'.Display::url(
1683
                                    basename($extraData[$fieldVariable]),
1684
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1685
                                    [
1686
                                        'title' => $field_details['display_text'],
1687
                                        'target' => '_blank',
1688
                                    ]
1689
                                ).$linkToDelete.'</div>';
1690
                            }
1691
                        }
1692
1693
                        $form->addElement(
1694
                            'file',
1695
                            $fieldVariable,
1696
                            $fieldTexts,
1697
                            []
1698
                        );
1699
1700
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1701
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1702
1703
                        if ($freezeElement) {
1704
                            $form->freeze('extra_'.$field_details['variable']);
1705
                        }
1706
                        break;
1707
                    case self::FIELD_TYPE_VIDEO_URL:
1708
                        $form->addUrl(
1709
                            "extra_{$field_details['variable']}",
1710
                            $field_details['display_text'],
1711
                            false,
1712
                            ['placeholder' => 'https://']
1713
                        );
1714
                        if ($freezeElement) {
1715
                            $form->freeze('extra_'.$field_details['variable']);
1716
                        }
1717
                        break;
1718
                    case self::FIELD_TYPE_LETTERS_ONLY:
1719
                        $form->addTextLettersOnly(
1720
                            "extra_{$field_details['variable']}",
1721
                            $field_details['display_text']
1722
                        );
1723
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1724
1725
                        if ($freezeElement) {
1726
                            $form->freeze('extra_'.$field_details['variable']);
1727
                        }
1728
                        break;
1729
                    case self::FIELD_TYPE_ALPHANUMERIC:
1730
                        $form->addTextAlphanumeric(
1731
                            "extra_{$field_details['variable']}",
1732
                            $field_details['display_text']
1733
                        );
1734
                        $form->applyFilter(
1735
                            'extra_'.$field_details['variable'],
1736
                            'stripslashes'
1737
                        );
1738
                        if ($freezeElement) {
1739
                            $form->freeze('extra_'.$field_details['variable']);
1740
                        }
1741
                        break;
1742
                    case self::FIELD_TYPE_LETTERS_SPACE:
1743
                        $form->addTextLettersAndSpaces(
1744
                            "extra_{$field_details['variable']}",
1745
                            $field_details['display_text']
1746
                        );
1747
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1748
1749
                        if ($freezeElement) {
1750
                            $form->freeze('extra_'.$field_details['variable']);
1751
                        }
1752
                        break;
1753
                    case self::FIELD_TYPE_ALPHANUMERIC_SPACE:
1754
                        $form->addTextAlphanumericAndSpaces(
1755
                            "extra_{$field_details['variable']}",
1756
                            $field_details['display_text']
1757
                        );
1758
                        $form->applyFilter(
1759
                            'extra_'.$field_details['variable'],
1760
                            'stripslashes'
1761
                        );
1762
                        if ($freezeElement) {
1763
                            $form->freeze('extra_'.$field_details['variable']);
1764
                        }
1765
                        break;
1766
                    case self::FIELD_TYPE_GEOLOCALIZATION_COORDINATES:
1767
                    case self::FIELD_TYPE_GEOLOCALIZATION:
1768
                        $dataValue = isset($extraData['extra_'.$field_details['variable']])
1769
                            ? $extraData['extra_'.$field_details['variable']]
1770
                            : '';
1771
1772
                        $form->addGeoLocationMapField(
1773
                            'extra_'.$field_details['variable'],
1774
                            $field_details['display_text'],
1775
                            $dataValue,
1776
                            $hideGeoLocalizationDetails
1777
                        );
1778
1779
                        /*$form->addElement(
1780
                            'text',
1781
                            'extra_'.$field_details['variable'],
1782
                            $field_details['display_text'],
1783
                            ['id' => 'extra_'.$field_details['variable']]
1784
                        );
1785
                        $form->addHidden(
1786
                            'extra_'.$field_details['variable'].'_coordinates',
1787
                            '',
1788
                            ['id' => 'extra_'.$field_details['variable'].'_coordinates']
1789
                        );
1790
1791
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1792
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');*/
1793
1794
                        if ($freezeElement) {
1795
                            $form->freeze('extra_'.$field_details['variable']);
1796
                        }
1797
                        break;
1798
                    case self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
1799
                        $jquery_ready_content .= $this->addSelectWithTextFieldElement(
1800
                            $form,
1801
                            $field_details,
1802
                            $freezeElement
1803
                        );
1804
                        break;
1805
                    case self::FIELD_TYPE_TRIPLE_SELECT:
1806
                        $jquery_ready_content .= $this->addTripleSelectElement(
1807
                            $form,
1808
                            $field_details,
1809
                            is_array($extraData) ? $extraData : [],
1810
                            $freezeElement
1811
                        );
1812
                        break;
1813
                }
1814
            }
1815
        }
1816
1817
        $return = [];
1818
        $return['jquery_ready_content'] = $jquery_ready_content;
1819
1820
        return $return;
1821
    }
1822
1823
    /**
1824
     * @param $breadcrumb
1825
     * @param $action
1826
     */
1827
    public function setupBreadcrumb(&$breadcrumb, $action)
1828
    {
1829
        if ('add' === $action) {
1830
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
1831
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Add')];
1832
        } elseif ('edit' === $action) {
1833
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
1834
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Edit')];
1835
        } else {
1836
            $breadcrumb[] = ['url' => '#', 'name' => $this->pageName];
1837
        }
1838
    }
1839
1840
    /**
1841
     * Displays the title + grid.
1842
     */
1843
    public function display()
1844
    {
1845
        // action links
1846
        echo '<div class="actions">';
1847
        echo '<a href="../admin/index.php">';
1848
        echo Display::return_icon(
1849
            'back.png',
1850
            get_lang('BackTo').' '.get_lang('PlatformAdmin'),
1851
            '',
1852
            ICON_SIZE_MEDIUM
1853
        );
1854
        echo '</a>';
1855
        echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'">';
1856
        echo Display::return_icon(
1857
            'add_user_fields.png',
1858
            get_lang('Add'),
1859
            '',
1860
            ICON_SIZE_MEDIUM
1861
        );
1862
        echo '</a>';
1863
        echo '</div>';
1864
        echo Display::grid_html($this->type.'_fields');
1865
    }
1866
1867
    /**
1868
     * @return array
1869
     */
1870
    public function getJqgridColumnNames()
1871
    {
1872
        return [
1873
            get_lang('Name'),
1874
            get_lang('FieldLabel'),
1875
            get_lang('Type'),
1876
            get_lang('FieldChangeability'),
1877
            get_lang('VisibleToSelf'),
1878
            get_lang('VisibleToOthers'),
1879
            get_lang('Filter'),
1880
            get_lang('FieldOrder'),
1881
            get_lang('Actions'),
1882
        ];
1883
    }
1884
1885
    /**
1886
     * @return array
1887
     */
1888
    public function getJqgridColumnModel()
1889
    {
1890
        return [
1891
            [
1892
                'name' => 'display_text',
1893
                'index' => 'display_text',
1894
                'width' => '140',
1895
                'align' => 'left',
1896
            ],
1897
            [
1898
                'name' => 'variable',
1899
                'index' => 'variable',
1900
                'width' => '90',
1901
                'align' => 'left',
1902
                'sortable' => 'true',
1903
            ],
1904
            [
1905
                'name' => 'field_type',
1906
                'index' => 'field_type',
1907
                'width' => '70',
1908
                'align' => 'left',
1909
                'sortable' => 'true',
1910
            ],
1911
            [
1912
                'name' => 'changeable',
1913
                'index' => 'changeable',
1914
                'width' => '35',
1915
                'align' => 'left',
1916
                'sortable' => 'true',
1917
            ],
1918
            [
1919
                'name' => 'visible_to_self',
1920
                'index' => 'visible_to_self',
1921
                'width' => '45',
1922
                'align' => 'left',
1923
                'sortable' => 'true',
1924
            ],
1925
            [
1926
                'name' => 'visible_to_others',
1927
                'index' => 'visible_to_others',
1928
                'width' => '35',
1929
                'align' => 'left',
1930
                'sortable' => 'true',
1931
            ],
1932
            [
1933
                'name' => 'filter',
1934
                'index' => 'filter',
1935
                'width' => '30',
1936
                'align' => 'left',
1937
                'sortable' => 'true',
1938
            ],
1939
            [
1940
                'name' => 'field_order',
1941
                'index' => 'field_order',
1942
                'width' => '25',
1943
                'align' => 'left',
1944
                'sortable' => 'true',
1945
            ],
1946
            [
1947
                'name' => 'actions',
1948
                'index' => 'actions',
1949
                'width' => '40',
1950
                'align' => 'left',
1951
                'formatter' => 'action_formatter',
1952
                'sortable' => 'false',
1953
            ],
1954
        ];
1955
    }
1956
1957
    /**
1958
     * @param string $url
1959
     * @param string $action
1960
     *
1961
     * @return FormValidator
1962
     */
1963
    public function return_form($url, $action)
1964
    {
1965
        $form = new FormValidator($this->type.'_field', 'post', $url);
1966
1967
        $form->addElement('hidden', 'type', $this->type);
1968
        $id = isset($_GET['id']) ? (int) $_GET['id'] : null;
1969
        $form->addElement('hidden', 'id', $id);
1970
1971
        // Setting the form elements
1972
        $header = get_lang('Add');
1973
        $defaults = [];
1974
1975
        if ('edit' === $action) {
1976
            $header = get_lang('Modify');
1977
            // Setting the defaults
1978
            $defaults = $this->get($id, false);
1979
        }
1980
1981
        $form->addElement('header', $header);
1982
1983
        if ('edit' === $action) {
1984
            $translateUrl = api_get_path(WEB_CODE_PATH).'extrafield/translate.php?'
1985
                .http_build_query(['extra_field' => $id]);
1986
            $translateButton = Display::toolbarButton(get_lang('TranslateThisTerm'), $translateUrl, 'language', 'link');
1987
1988
            $form->addText(
1989
                'display_text',
1990
                [get_lang('Name'), $translateButton]
1991
            );
1992
        } else {
1993
            $form->addElement('text', 'display_text', get_lang('Name'));
1994
        }
1995
1996
        // Field type
1997
        $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

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

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

3530
        $level2 = $this->getOptionsFromTripleSelect($options['level2'], /** @scrutinizer ignore-type */ $firstId);
Loading history...
3531
        $level3 = $this->getOptionsFromTripleSelect($options['level3'], $secondId);
3532
        /** @var \HTML_QuickForm_select $slctFirst */
3533
        $slctFirst = $form->createElement('select', "extra_$variable", null, $values1, ['id' => $slctFirstId]);
3534
        /** @var \HTML_QuickForm_select $slctFirst */
3535
        $slctSecond = $form->createElement('select', "extra_{$variable}_second", null, $values2, ['id' => $slctSecondId]);
3536
        /** @var \HTML_QuickForm_select $slctFirst */
3537
        $slctThird = $form->createElement('select', "extra_{$variable}_third", null, $values3, ['id' => $slctThirdId]);
3538
3539
        foreach ($level1 as $item1) {
3540
            $valueParts = explode('#', $item1['display_text']);
3541
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3542
            $slctFirst->addOption(implode('', $valueParts), $item1['id'], ['data-value' => $dataValue]);
3543
        }
3544
3545
        foreach ($level2 as $item2) {
3546
            $valueParts = explode('#', $item2['display_text']);
3547
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3548
            $slctSecond->addOption(implode('', $valueParts), $item2['id'], ['data-value' => $dataValue]);
3549
        }
3550
3551
        foreach ($level3 as $item3) {
3552
            $valueParts = explode('#', $item3['display_text']);
3553
            $dataValue = count($valueParts) > 1 ? array_shift($valueParts) : '';
3554
            $slctThird->addOption(implode('', $valueParts), $item3['id'], ['data-value' => $dataValue]);
3555
        }
3556
3557
        $form
3558
            ->defaultRenderer()
3559
            ->setGroupElementTemplate('<p>{element}</p>', "extra_$variable");
3560
        $form->addGroup([$slctFirst, $slctSecond, $slctThird], "extra_$variable", $fieldDetails['display_text']);
3561
3562
        if ($freezeElement) {
3563
            $form->freeze('extra_'.$fieldDetails['variable']);
3564
        }
3565
3566
        return $js;
3567
    }
3568
}
3569