Passed
Push — 1.11.x ( 07272c...878ec5 )
by Julito
09:25 queued 12s
created

ExtraField::addElements()   B

Complexity

Conditions 10
Paths 13

Size

Total Lines 78
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 43
c 0
b 0
f 0
nc 13
nop 17
dl 0
loc 78
rs 7.6666

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
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
                    $extra_field_info = $extra_field_obj->get($extra['id']);
2354
                    $extra['extra_field_info'] = $extra_field_info;
2355
2356
                    if (isset($extra_field_info['field_type']) &&
2357
                        in_array(
2358
                            $extra_field_info['field_type'],
2359
                            [
2360
                                self::FIELD_TYPE_SELECT,
2361
                                self::FIELD_TYPE_SELECT,
2362
                                self::FIELD_TYPE_DOUBLE_SELECT,
2363
                            ]
2364
                        )
2365
                    ) {
2366
                        $inject_extra_fields .= " fvo$counter.display_text as {$extra['field']}, ";
2367
                    } elseif ($extra_field_info['field_type'] == self::FIELD_TYPE_TAG) {
2368
                        $inject_extra_fields .= " tag$counter.tag as {$extra['field']}, ";
2369
                    } else {
2370
                        $inject_extra_fields .= " fv$counter.value as {$extra['field']}, ";
2371
                    }
2372
2373
                    if (isset($extra_fields_info[$extra['id']])) {
2374
                        $info = $extra_fields_info[$extra['id']];
2375
                    } else {
2376
                        $info = $this->get($extra['id']);
2377
                        $extra_fields_info[$extra['id']] = $info;
2378
                    }
2379
                    if (isset($info['field_type']) && self::FIELD_TYPE_DOUBLE_SELECT == $info['field_type']) {
2380
                        $double_fields[$info['id']] = $info;
2381
                    }
2382
                    $counter++;
2383
                }
2384
            }
2385
        }
2386
2387
        $options_by_double = [];
2388
        foreach ($double_fields as $double) {
2389
            $my_options = $extraFieldOption->get_field_options_by_field($double['id'], true);
2390
            $options_by_double['extra_'.$double['variable']] = $my_options;
2391
        }
2392
2393
        $field_value_to_join = [];
2394
        //filter can be all/any = and/or
2395
        $inject_joins = null;
2396
        $inject_where = null;
2397
        $where = null;
2398
2399
        if (!empty($options['where'])) {
2400
            if (!empty($options['extra'])) {
2401
                // Removing double 1=1
2402
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
2403
                // Always OR
2404
                $counter = 1;
2405
                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...
2406
                    $extra_field_info = $extra_info['extra_field_info'];
2407
                    $inject_joins .= " INNER JOIN $this->table_field_values fv$counter
2408
                                       ON ($alias.".$this->primaryKey." = fv$counter.".$this->handler_id.') ';
2409
                    // Add options
2410
                    if (isset($extra_field_info['field_type']) &&
2411
                        in_array(
2412
                            $extra_field_info['field_type'],
2413
                            [
2414
                                self::FIELD_TYPE_SELECT,
2415
                                self::FIELD_TYPE_SELECT,
2416
                                self::FIELD_TYPE_DOUBLE_SELECT,
2417
                            ]
2418
                        )
2419
                    ) {
2420
                        $options['where'] = str_replace(
2421
                            $extra_info['field'],
2422
                            'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fvo'.$counter.'.option_value',
2423
                            $options['where']
2424
                        );
2425
                        $inject_joins .= "
2426
                             INNER JOIN $this->table_field_options fvo$counter
2427
                             ON (
2428
                                fv$counter.field_id = fvo$counter.field_id AND
2429
                                fv$counter.value = fvo$counter.option_value
2430
                             )
2431
                            ";
2432
                    } else {
2433
                        if (isset($extra_field_info['field_type']) &&
2434
                            self::FIELD_TYPE_TAG == $extra_field_info['field_type']
2435
                        ) {
2436
                            $options['where'] = str_replace(
2437
                                $extra_info['field'],
2438
                                'tag'.$counter.'.tag ',
2439
                                $options['where']
2440
                            );
2441
2442
                            $inject_joins .= "
2443
                                INNER JOIN $this->table_field_rel_tag tag_rel$counter
2444
                                ON (
2445
                                    tag_rel$counter.field_id = ".$extra_info['id']." AND
2446
                                    tag_rel$counter.item_id = $alias.".$this->primaryKey."
2447
                                )
2448
                                INNER JOIN $this->table_field_tag tag$counter
2449
                                ON (tag$counter.id = tag_rel$counter.tag_id)
2450
                            ";
2451
                        } else {
2452
                            // text, textarea, etc
2453
                            $options['where'] = str_replace(
2454
                                $extra_info['field'],
2455
                                'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fv'.$counter.'.value',
2456
                                $options['where']
2457
                            );
2458
                        }
2459
                    }
2460
2461
                    $field_value_to_join[] = " fv$counter.$this->handler_id ";
2462
                    $counter++;
2463
                }
2464
                if (!empty($field_value_to_join)) {
2465
                    //$inject_where .= " AND $alias.id = ".implode(' = ', $field_value_to_join);
2466
                }
2467
            }
2468
            $where .= ' AND '.$options['where'];
2469
        }
2470
2471
        $order = null;
2472
        if (!empty($options['order'])) {
2473
            $order = ' ORDER BY '.$options['order'];
2474
        }
2475
        $limit = null;
2476
        if (!empty($options['limit'])) {
2477
            $limit = ' LIMIT '.$options['limit'];
2478
        }
2479
2480
        return [
2481
            'order' => $order,
2482
            'limit' => $limit,
2483
            'where' => $where,
2484
            'inject_where' => $inject_where,
2485
            'inject_joins' => $inject_joins,
2486
            'field_value_to_join' => $field_value_to_join,
2487
            'inject_extra_fields' => $inject_extra_fields,
2488
        ];
2489
    }
2490
2491
    //@todo move this in the display_class or somewhere else
2492
2493
    /**
2494
     * @param $col
2495
     * @param $oper
2496
     * @param $val
2497
     *
2498
     * @return string
2499
     */
2500
    public function get_where_clause($col, $oper, $val)
2501
    {
2502
        if (empty($col)) {
2503
            return '';
2504
        }
2505
        if ('bw' === $oper || 'bn' === $oper) {
2506
            $val .= '%';
2507
        }
2508
        if ('ew' === $oper || 'en' === $oper) {
2509
            $val = '%'.$val;
2510
        }
2511
        if ('cn' === $oper || 'nc' === $oper || 'in' === $oper || 'ni' === $oper) {
2512
            if (is_array($val)) {
2513
                $result = '"%'.implode(';', $val).'%"';
2514
                foreach ($val as $item) {
2515
                    $item = trim($item);
2516
                    $result .= ' OR '.$col.' LIKE "%'.$item.'%"';
2517
                }
2518
                $val = $result;
2519
2520
                return " $col {$this->ops[$oper]} $val ";
2521
            } else {
2522
                if (is_string($val)) {
2523
                    $val = '%'.$val.'%';
2524
                } else {
2525
                    $val = '';
2526
                }
2527
            }
2528
        }
2529
        $val = \Database::escape_string($val);
2530
2531
        return " $col {$this->ops[$oper]} '$val' ";
2532
    }
2533
2534
    /**
2535
     * @param $filters
2536
     * @param string $stringToSearch
2537
     *
2538
     * @return array
2539
     */
2540
    public function getExtraFieldRules($filters, $stringToSearch = 'extra_')
2541
    {
2542
        $extra_fields = [];
2543
        $condition_array = [];
2544
2545
        // Getting double select if exists
2546
        $double_select = [];
2547
        if (is_object($filters)
2548
            && property_exists($filters, 'rules')
2549
            && is_array($filters->rules)
2550
            && !empty($filters->rules)
2551
        ) {
2552
            foreach ($filters->rules as $rule) {
2553
                if (empty($rule)) {
2554
                    continue;
2555
                }
2556
                if (false === strpos($rule->field, '_second')) {
2557
                } else {
2558
                    $my_field = str_replace('_second', '', $rule->field);
2559
                    $double_select[$my_field] = $rule->data;
2560
                }
2561
            }
2562
2563
            foreach ($filters->rules as $rule) {
2564
                if (empty($rule)) {
2565
                    continue;
2566
                }
2567
                if (false === strpos($rule->field, $stringToSearch)) {
2568
                    // normal fields
2569
                    $field = $rule->field;
2570
                    if (isset($rule->data) && is_string($rule->data) && -1 != $rule->data) {
2571
                        $condition_array[] = $this->get_where_clause($field, $rule->op, $rule->data);
2572
                    }
2573
                } else {
2574
                    // Extra fields
2575
                    if (false === strpos($rule->field, '_second')) {
2576
                        //No _second
2577
                        $original_field = str_replace($stringToSearch, '', $rule->field);
2578
                        $field_option = $this->get_handler_field_info_by_field_variable($original_field);
2579
2580
                        if (self::FIELD_TYPE_DOUBLE_SELECT == $field_option['field_type']) {
2581
                            if (isset($double_select[$rule->field])) {
2582
                                $data = explode('#', $rule->data);
2583
                                $rule->data = $data[1].'::'.$double_select[$rule->field];
2584
                            } else {
2585
                                // only was sent 1 select
2586
                                if (is_string($rule->data)) {
2587
                                    $data = explode('#', $rule->data);
2588
                                    $rule->data = $data[1];
2589
                                }
2590
                            }
2591
2592
                            if (!isset($rule->data)) {
2593
                                $condition_array[] = ' ('
2594
                                    .$this->get_where_clause($rule->field, $rule->op, $rule->data)
2595
                                    .') ';
2596
                                $extra_fields[] = ['field' => $rule->field, 'id' => $field_option['id']];
2597
                            }
2598
                        } else {
2599
                            if (isset($rule->data)) {
2600
                                if (isset($rule->data) && is_int($rule->data) && -1 == $rule->data) {
2601
                                    continue;
2602
                                }
2603
                                $condition_array[] = ' ('
2604
                                    .$this->get_where_clause($rule->field, $rule->op, $rule->data)
2605
                                    .') ';
2606
                                $extra_fields[] = [
2607
                                    'field' => $rule->field,
2608
                                    'id' => $field_option['id'],
2609
                                    'data' => $rule->data,
2610
                                ];
2611
                            }
2612
                        }
2613
                    } else {
2614
                        $my_field = str_replace('_second', '', $rule->field);
2615
                        $original_field = str_replace($stringToSearch, '', $my_field);
2616
                        $field_option = $this->get_handler_field_info_by_field_variable($original_field);
2617
                        $extra_fields[] = [
2618
                            'field' => $rule->field,
2619
                            'id' => $field_option['id'],
2620
                        ];
2621
                    }
2622
                }
2623
            }
2624
        }
2625
2626
        return [
2627
            'extra_fields' => $extra_fields,
2628
            'condition_array' => $condition_array,
2629
        ];
2630
    }
2631
2632
    /**
2633
     * Get the extra fields and their formatted values.
2634
     *
2635
     * @param int|string $itemId   The item ID (It could be a session_id, course_id or user_id)
2636
     * @param bool       $filter
2637
     * @param array      $onlyShow (list of extra fields variables to show)
2638
     *
2639
     * @return array The extra fields data
2640
     */
2641
    public function getDataAndFormattedValues($itemId, $filter = false, $onlyShow = [])
2642
    {
2643
        $valuesData = [];
2644
        $fields = $this->get_all();
2645
        $em = Database::getManager();
2646
2647
        $repoTag = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
2648
2649
        foreach ($fields as $field) {
2650
            if ('1' != $field['visible_to_self']) {
2651
                continue;
2652
            }
2653
2654
            if ($filter && $field['filter'] != 1) {
2655
                continue;
2656
            }
2657
2658
            if (!empty($onlyShow) && !in_array($field['variable'], $onlyShow)) {
2659
                continue;
2660
            }
2661
2662
            $valueAsArray = [];
2663
            $fieldValue = new ExtraFieldValue($this->type);
2664
            $valueData = $fieldValue->get_values_by_handler_and_field_id(
2665
                $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

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

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