Completed
Push — master ( c341b0...5d80e7 )
by Julito
09:18
created

ExtraField   F

Complexity

Total Complexity 404

Size/Duplication

Total Lines 3473
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1829
c 0
b 0
f 0
dl 0
loc 3473
rs 0.8
wmc 404

51 Methods

Rating   Name   Duplication   Size   Complexity  
A getAllSkillPerTag() 0 22 2
F set_extra_fields_in_form() 0 801 125
A display() 0 22 1
A save() 0 17 3
A getAllUserPerTag() 0 15 1
A getFieldInfoByFieldId() 0 23 3
A get_count() 0 9 1
B getAllGrid() 0 35 8
A get_all_extra_field_by_type() 0 16 2
A getJqgridColumnNames() 0 12 1
A getLocalizationInput() 0 33 1
C get_where_clause() 0 28 12
A setupBreadcrumb() 0 10 3
C get_handler_extra_data() 0 80 16
B extra_field_double_select_convert_array_to_string() 0 26 7
B addElements() 0 80 11
A extraFieldSelectWithTextConvertArrayToString() 0 17 3
B addDoubleSelectElement() 0 87 9
D addSelectElement() 0 139 18
C getRules() 0 105 10
A getOptionsFromTripleSelect() 0 4 1
A clean_parameters() 0 16 4
A get_handler_field_info_by_tags() 0 27 3
A searchOptionsFromTags() 0 37 3
C return_form() 0 144 8
A tripleSelectConvertStringToArray() 0 31 6
A getValidExtraFieldTypes() 0 26 2
A get_extra_fields_by_handler() 0 40 5
D parseConditions() 0 148 20
C getExtraFieldRules() 0 83 17
A getExtraFieldType() 0 3 1
A delete() 0 17 3
C addTripleSelectElement() 0 136 10
A get() 0 9 2
D __construct() 0 73 18
A update() 0 13 3
A get_all() 0 34 4
A translateDisplayName() 0 5 2
A getLocalizationJavascript() 0 145 1
B addSelectWithTextFieldElement() 0 61 6
A getJqgridActionLinks() 0 25 1
A tripleSelectConvertArrayToString() 0 20 3
A get_handler_field_info_by_field_variable() 0 30 4
A extra_field_double_select_convert_array_to_ordered_array() 0 14 4
A get_field_types() 0 3 1
A get_max_field_order() 0 15 2
D getDataAndFormattedValues() 0 118 23
A tripleSelectConvertArrayToOrderedArray() 0 15 3
A get_field_type_by_id() 0 8 2
A extra_field_double_select_convert_string_to_array() 0 19 4
A getJqgridColumnModel() 0 69 1

How to fix   Complexity   

Complex Class

Complex classes like ExtraField often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ExtraField, and based on these observations, apply Extract Interface, too.

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

937
            /** @scrutinizer ignore-call */ 
938
            $max_order = self::get_max_field_order();
Loading history...
938
            $params['field_order'] = $max_order;
939
        } else {
940
            $params['field_order'] = (int) $params['field_order'];
941
        }
942
943
        return $params;
944
    }
945
946
    /**
947
     * @param array $params
948
     * @param bool  $show_query
949
     *
950
     * @return int|bool
951
     */
952
    public function save($params, $show_query = false)
953
    {
954
        $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraField::get_handler_...nfo_by_field_variable() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

954
        /** @scrutinizer ignore-call */ 
955
        $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
Loading history...
955
        $params = $this->clean_parameters($params);
956
        $params['extra_field_type'] = $this->extraFieldType;
957
958
        if ($fieldInfo) {
959
            return $fieldInfo['id'];
960
        } else {
961
            $id = parent::save($params, $show_query);
962
            if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1291
                        $jquery_ready_content .= self::/** @scrutinizer ignore-call */ addDoubleSelectElement(
Loading history...
1292
                            $form,
1293
                            $field_details,
1294
                            $extraData,
1295
                            $freezeElement
1296
                        );
1297
                        break;
1298
                    case self::FIELD_TYPE_DIVIDER:
1299
                        $form->addHtml('
1300
                            <div class="form-group ">
1301
                                <div class="col-sm-12">
1302
                                    <div class="panel-separator">
1303
                                       <h4 id="'.$field_details['variable'].'" class="form-separator">'
1304
                                            .$field_details['display_text'].'
1305
                                       </h4>
1306
                                    </div>
1307
                                </div>
1308
                            </div>    
1309
                        ');
1310
                        break;
1311
                    case self::FIELD_TYPE_TAG:
1312
                        $variable = $field_details['variable'];
1313
                        $field_id = $field_details['id'];
1314
                        $separateValue = 0;
1315
                        if (isset($separateExtraMultipleSelect[$field_details['variable']])) {
1316
                            $separateValue = $separateExtraMultipleSelect[$field_details['variable']];
1317
                        }
1318
1319
                        $selectedOptions = [];
1320
1321
                        if ($separateValue > 0) {
1322
                            $em = Database::getManager();
1323
                            $fieldTags = $em
1324
                                ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1325
                                ->findBy(
1326
                                    [
1327
                                        'fieldId' => $field_id,
1328
                                        'itemId' => $itemId,
1329
                                    ]
1330
                                );
1331
                            // ofaj
1332
1333
                            for ($i = 0; $i < $separateValue; $i++) {
1334
                                $tagsSelect = $form->addElement(
1335
                                    'select',
1336
                                    'extra_'.$field_details['variable'].'['.$i.']',
1337
                                    $customLabelsExtraMultipleSelect[$field_details['variable']][$i], //$field_details['display_text'],
1338
                                    null,
1339
                                    ['id' => 'extra_'.$field_details['variable'].'_'.$i]
1340
                                );
1341
1342
                                if ($addEmptyOptionSelects) {
1343
                                    $tagsSelect->addOption(
1344
                                        '',
1345
                                        ''
1346
                                    );
1347
                                }
1348
1349
                                foreach ($fieldTags as $fieldTag) {
1350
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1351
1352
                                    if (empty($tag)) {
1353
                                        continue;
1354
                                    }
1355
1356
                                    $tagsSelect->addOption(
1357
                                        $tag->getTag(),
1358
                                        $tag->getTag()
1359
                                    );
1360
                                }
1361
                            }
1362
                        } else {
1363
                            $tagsSelect = $form->addSelect(
1364
                                "extra_{$field_details['variable']}",
1365
                                $field_details['display_text'],
1366
                                [],
1367
                                ['style' => 'width: 100%;']
1368
                            );
1369
1370
                            if ($useTagAsSelect === false) {
1371
                                $tagsSelect->setAttribute('class', null);
1372
                            }
1373
1374
                            $tagsSelect->setAttribute(
1375
                                'id',
1376
                                "extra_{$field_details['variable']}"
1377
                            );
1378
                            $tagsSelect->setMultiple(true);
1379
1380
                            $selectedOptions = [];
1381
                            if ($this->type === 'user') {
1382
                                // The magic should be here
1383
                                $user_tags = UserManager::get_user_tags(
1384
                                    $itemId,
1385
                                    $field_details['id']
1386
                                );
1387
1388
                                if (is_array($user_tags) && count($user_tags) > 0) {
1389
                                    foreach ($user_tags as $tag) {
1390
                                        if (empty($tag['tag'])) {
1391
                                            continue;
1392
                                        }
1393
                                        $tagsSelect->addOption(
1394
                                            $tag['tag'],
1395
                                            $tag['tag'],
1396
                                            [
1397
                                                'selected' => 'selected',
1398
                                                'class' => 'selected',
1399
                                            ]
1400
                                        );
1401
                                        $selectedOptions[] = $tag['tag'];
1402
                                    }
1403
                                }
1404
                                $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
1405
                            } else {
1406
                                $em = Database::getManager();
1407
                                $fieldTags = $em->getRepository(
1408
                                    'ChamiloCoreBundle:ExtraFieldRelTag'
1409
                                )
1410
                                ->findBy(
1411
                                    [
1412
                                        'fieldId' => $field_id,
1413
                                        'itemId' => $itemId,
1414
                                    ]
1415
                                );
1416
1417
                                /** @var ExtraFieldRelTag $fieldTag */
1418
                                foreach ($fieldTags as $fieldTag) {
1419
                                    /** @var Tag $tag */
1420
                                    $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1421
1422
                                    if (empty($tag)) {
1423
                                        continue;
1424
                                    }
1425
                                    $tagsSelect->addOption(
1426
                                        $tag->getTag(),
1427
                                        $tag->getTag()
1428
                                    );
1429
                                    $selectedOptions[] = $tag->getTag();
1430
                                }
1431
1432
                                if (!empty($extraData) && isset($extraData['extra_'.$field_details['variable']])) {
1433
                                    $data = $extraData['extra_'.$field_details['variable']];
1434
                                    if (!empty($data)) {
1435
                                        foreach ($data as $option) {
1436
                                            $tagsSelect->addOption(
1437
                                                $option,
1438
                                                $option
1439
                                            );
1440
                                        }
1441
                                    }
1442
                                }
1443
1444
                                if ($useTagAsSelect) {
1445
                                    $fieldTags = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1446
                                        ->findBy(
1447
                                            [
1448
                                                'fieldId' => $field_id,
1449
                                            ]
1450
                                        );
1451
                                    $tagsAdded = [];
1452
                                    foreach ($fieldTags as $fieldTag) {
1453
                                        $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
1454
1455
                                        if (empty($tag)) {
1456
                                            continue;
1457
                                        }
1458
1459
                                        $tagText = $tag->getTag();
1460
1461
                                        if (in_array($tagText, $tagsAdded)) {
1462
                                            continue;
1463
                                        }
1464
1465
                                        $tagsSelect->addOption(
1466
                                            $tag->getTag(),
1467
                                            $tag->getTag(),
1468
                                            []
1469
                                        );
1470
1471
                                        $tagsAdded[] = $tagText;
1472
                                    }
1473
                                }
1474
                                $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php';
1475
                            }
1476
1477
                            $form->setDefaults(
1478
                                [
1479
                                    'extra_'.$field_details['variable'] => $selectedOptions,
1480
                                ]
1481
                            );
1482
1483
                            if ($useTagAsSelect == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1484
                                $jquery_ready_content .= "
1485
                                $('#extra_$variable').select2({
1486
                                    ajax: {
1487
                                        url: '$url?a=search_tags&field_id=$field_id&type={$this->type}',
1488
                                        processResults: function (data) {
1489
                                            return {
1490
                                                results: data.items
1491
                                            }
1492
                                        }
1493
                                    },
1494
                                    cache: false,
1495
                                    tags: true,
1496
                                    tokenSeparators: [','],
1497
                                    placeholder: '".get_lang('StartToType')."'
1498
                                });
1499
                            ";
1500
                            }
1501
                        }
1502
1503
                        break;
1504
                    case self::FIELD_TYPE_TIMEZONE:
1505
                        $form->addElement(
1506
                            'select',
1507
                            'extra_'.$field_details['variable'],
1508
                            $field_details['display_text'],
1509
                            api_get_timezones(),
1510
                            ''
1511
                        );
1512
                        if ($freezeElement) {
1513
                            $form->freeze('extra_'.$field_details['variable']);
1514
                        }
1515
                        break;
1516
                    case self::FIELD_TYPE_SOCIAL_PROFILE:
1517
                        // get the social network's favicon
1518
                        $extra_data_variable = isset($extraData['extra_'.$field_details['variable']])
1519
                            ? $extraData['extra_'.$field_details['variable']]
1520
                            : null;
1521
                        $field_default_value = isset($field_details['field_default_value'])
1522
                            ? $field_details['field_default_value']
1523
                            : null;
1524
                        $icon_path = UserManager::get_favicon_from_url(
1525
                            $extra_data_variable,
1526
                            $field_default_value
1527
                        );
1528
                        // special hack for hi5
1529
                        $leftpad = '1.7';
1530
                        $top = '0.4';
1531
                        $domain = parse_url($icon_path, PHP_URL_HOST);
1532
                        if ($domain == 'www.hi5.com' or $domain == 'hi5.com') {
1533
                            $leftpad = '3';
1534
                            $top = '0';
1535
                        }
1536
                        // print the input field
1537
                        $form->addElement(
1538
                            'text',
1539
                            'extra_'.$field_details['variable'],
1540
                            $field_details['display_text'],
1541
                            [
1542
                                'size' => 60,
1543
                                'size' => implode(
1544
                                    '; ',
1545
                                    [
1546
                                        "background-image: url('$icon_path')",
1547
                                        'background-repeat: no-repeat',
1548
                                        "background-position: 0.4em {$top}em",
1549
                                        "padding-left: {$leftpad}em",
1550
                                    ]
1551
                                ),
1552
                            ]
1553
                        );
1554
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1555
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1556
                        if ($freezeElement) {
1557
                            $form->freeze('extra_'.$field_details['variable']);
1558
                        }
1559
                        break;
1560
                    case self::FIELD_TYPE_MOBILE_PHONE_NUMBER:
1561
                        $form->addElement(
1562
                            'text',
1563
                            'extra_'.$field_details['variable'],
1564
                            $field_details['display_text']." (".get_lang('CountryDialCode').")",
1565
                            ['size' => 40, 'placeholder' => '(xx)xxxxxxxxx']
1566
                        );
1567
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1568
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1569
                        $form->applyFilter('extra_'.$field_details['variable'], 'mobile_phone_number_filter');
1570
                        $form->addRule(
1571
                            'extra_'.$field_details['variable'],
1572
                            get_lang('MobilePhoneNumberWrong'),
1573
                            'mobile_phone_number'
1574
                        );
1575
                        if ($freezeElement) {
1576
                            $form->freeze('extra_'.$field_details['variable']);
1577
                        }
1578
                        break;
1579
                    case self::FIELD_TYPE_INTEGER:
1580
                        $form->addElement(
1581
                            'number',
1582
                            'extra_'.$field_details['variable'],
1583
                            $field_details['display_text'],
1584
                            ['class' => 'span1', 'step' => 1]
1585
                        );
1586
1587
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1588
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1589
                        $form->applyFilter('extra_'.$field_details['variable'], 'intval');
1590
1591
                        if ($freezeElement) {
1592
                            $form->freeze('extra_'.$field_details['variable']);
1593
                        }
1594
                        break;
1595
                    case self::FIELD_TYPE_FILE_IMAGE:
1596
                        $fieldVariable = "extra_{$field_details['variable']}";
1597
                        $fieldTexts = [
1598
                            $field_details['display_text'],
1599
                        ];
1600
1601
                        if (is_array($extraData) && array_key_exists($fieldVariable, $extraData)) {
1602
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1603
                                $fieldTexts[] = Display::img(
1604
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1605
                                    $field_details['display_text'],
1606
                                    ['width' => '300']
1607
                                );
1608
                            }
1609
                        }
1610
1611
                        if ($fieldTexts[0] === 'Image') {
1612
                            $fieldTexts[0] = get_lang($fieldTexts[0]);
1613
                        }
1614
1615
                        $form->addFile(
1616
                            $fieldVariable,
1617
                            $fieldTexts,
1618
                            ['accept' => 'image/*', 'id' => 'extra_image', 'crop_image' => 'true']
1619
                        );
1620
1621
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1622
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1623
1624
                        $allowedPictureTypes = ['jpg', 'jpeg', 'png', 'gif'];
1625
                        $form->addRule(
1626
                            'extra_'.$field_details['variable'],
1627
                            get_lang('OnlyImagesAllowed').' ('.implode(',', $allowedPictureTypes).')',
1628
                            'filetype',
1629
                            $allowedPictureTypes
1630
                        );
1631
1632
                        if ($freezeElement) {
1633
                            $form->freeze('extra_'.$field_details['variable']);
1634
                        }
1635
                        break;
1636
                    case self::FIELD_TYPE_FLOAT:
1637
                        $form->addElement(
1638
                            'number',
1639
                            'extra_'.$field_details['variable'],
1640
                            $field_details['display_text'],
1641
                            ['class' => 'span1', 'step' => '0.01']
1642
                        );
1643
1644
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1645
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1646
                        $form->applyFilter('extra_'.$field_details['variable'], 'floatval');
1647
1648
                        if ($freezeElement) {
1649
                            $form->freeze('extra_'.$field_details['variable']);
1650
                        }
1651
                        break;
1652
                    case self::FIELD_TYPE_FILE:
1653
                        $fieldVariable = "extra_{$field_details['variable']}";
1654
                        $fieldTexts = [
1655
                            $field_details['display_text'],
1656
                        ];
1657
1658
                        if (is_array($extraData) &&
1659
                            array_key_exists($fieldVariable, $extraData)
1660
                        ) {
1661
                            if (file_exists(api_get_path(SYS_UPLOAD_PATH).$extraData[$fieldVariable])) {
1662
                                $linkToDelete = '';
1663
                                $divItemId = $field_details['variable'];
1664
                                if (api_is_platform_admin()) {
1665
                                    $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?type='.$this->type;
1666
                                    $url .= '&a=delete_file&field_id='.$field_details['id'].'&item_id='.$itemId;
1667
1668
                                    $deleteId = $field_details['variable'].'_delete';
1669
                                    $form->addHtml("
1670
                                        <script>
1671
                                            $(function() {                                     
1672
                                                $('#".$deleteId."').on('click', function() {
1673
                                                    $.ajax({			
1674
                                                        type: 'GET',
1675
                                                        url: '".$url."',			
1676
                                                        success: function(result) {		    
1677
                                                            if (result == 1) {
1678
                                                                $('#".$divItemId."').html('".get_lang('Deleted')."');
1679
                                                            }			    
1680
                                                        }
1681
                                                    });
1682
                                                });
1683
                                            });
1684
                                        </script>
1685
                                    ");
1686
1687
                                    $linkToDelete = '&nbsp;'.Display::url(
1688
                                        Display::return_icon('delete.png', get_lang('Delete')),
1689
                                        'javascript:void(0)',
1690
                                        ['id' => $deleteId]
1691
                                    );
1692
                                }
1693
                                $fieldTexts[] = '<div id="'.$divItemId.'">'.Display::url(
1694
                                    basename($extraData[$fieldVariable]),
1695
                                    api_get_path(WEB_UPLOAD_PATH).$extraData[$fieldVariable],
1696
                                    [
1697
                                        'title' => $field_details['display_text'],
1698
                                        'target' => '_blank',
1699
                                    ]
1700
                                ).$linkToDelete.'</div>';
1701
                            }
1702
                        }
1703
1704
                        $form->addElement(
1705
                            'file',
1706
                            $fieldVariable,
1707
                            $fieldTexts,
1708
                            []
1709
                        );
1710
1711
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1712
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');
1713
1714
                        if ($freezeElement) {
1715
                            $form->freeze('extra_'.$field_details['variable']);
1716
                        }
1717
                        break;
1718
                    case self::FIELD_TYPE_VIDEO_URL:
1719
                        $form->addUrl(
1720
                            "extra_{$field_details['variable']}",
1721
                            $field_details['display_text'],
1722
                            false,
1723
                            ['placeholder' => 'https://']
1724
                        );
1725
                        if ($freezeElement) {
1726
                            $form->freeze('extra_'.$field_details['variable']);
1727
                        }
1728
                        break;
1729
                    case self::FIELD_TYPE_LETTERS_ONLY:
1730
                        $form->addTextLettersOnly(
1731
                            "extra_{$field_details['variable']}",
1732
                            $field_details['display_text']
1733
                        );
1734
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1735
1736
                        if ($freezeElement) {
1737
                            $form->freeze('extra_'.$field_details['variable']);
1738
                        }
1739
                        break;
1740
                    case self::FIELD_TYPE_ALPHANUMERIC:
1741
                        $form->addTextAlphanumeric(
1742
                            "extra_{$field_details['variable']}",
1743
                            $field_details['display_text']
1744
                        );
1745
                        $form->applyFilter(
1746
                            'extra_'.$field_details['variable'],
1747
                            'stripslashes'
1748
                        );
1749
                        if ($freezeElement) {
1750
                            $form->freeze('extra_'.$field_details['variable']);
1751
                        }
1752
                        break;
1753
                    case self::FIELD_TYPE_LETTERS_SPACE:
1754
                        $form->addTextLettersAndSpaces(
1755
                            "extra_{$field_details['variable']}",
1756
                            $field_details['display_text']
1757
                        );
1758
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1759
1760
                        if ($freezeElement) {
1761
                            $form->freeze('extra_'.$field_details['variable']);
1762
                        }
1763
                        break;
1764
                    case self::FIELD_TYPE_ALPHANUMERIC_SPACE:
1765
                        $form->addTextAlphanumericAndSpaces(
1766
                            "extra_{$field_details['variable']}",
1767
                            $field_details['display_text']
1768
                        );
1769
                        $form->applyFilter(
1770
                            'extra_'.$field_details['variable'],
1771
                            'stripslashes'
1772
                        );
1773
                        if ($freezeElement) {
1774
                            $form->freeze('extra_'.$field_details['variable']);
1775
                        }
1776
                        break;
1777
                    case self::FIELD_TYPE_GEOLOCALIZATION_COORDINATES:
1778
                    case self::FIELD_TYPE_GEOLOCALIZATION:
1779
                        $dataValue = isset($extraData['extra_'.$field_details['variable']])
1780
                            ? $extraData['extra_'.$field_details['variable']]
1781
                            : '';
1782
1783
                        $form->addGeoLocationMapField(
1784
                            'extra_'.$field_details['variable'],
1785
                            $field_details['display_text'],
1786
                            $dataValue,
1787
                            $hideGeoLocalizationDetails
1788
                        );
1789
1790
                        /*$form->addElement(
1791
                            'text',
1792
                            'extra_'.$field_details['variable'],
1793
                            $field_details['display_text'],
1794
                            ['id' => 'extra_'.$field_details['variable']]
1795
                        );
1796
                        $form->addHidden(
1797
                            'extra_'.$field_details['variable'].'_coordinates',
1798
                            '',
1799
                            ['id' => 'extra_'.$field_details['variable'].'_coordinates']
1800
                        );
1801
1802
                        $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
1803
                        $form->applyFilter('extra_'.$field_details['variable'], 'trim');*/
1804
1805
                        if ($freezeElement) {
1806
                            $form->freeze('extra_'.$field_details['variable']);
1807
                        }
1808
                        break;
1809
                    case self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
1810
                        $jquery_ready_content .= $this->addSelectWithTextFieldElement(
1811
                            $form,
1812
                            $field_details,
1813
                            $freezeElement
1814
                        );
1815
                        break;
1816
                    case self::FIELD_TYPE_TRIPLE_SELECT:
1817
                        $jquery_ready_content .= $this->addTripleSelectElement(
1818
                            $form,
1819
                            $field_details,
1820
                            is_array($extraData) ? $extraData : [],
1821
                            $freezeElement
1822
                        );
1823
                        break;
1824
                }
1825
            }
1826
        }
1827
1828
        $return = [];
1829
        $return['jquery_ready_content'] = $jquery_ready_content;
1830
1831
        return $return;
1832
    }
1833
1834
    /**
1835
     * @param $breadcrumb
1836
     * @param $action
1837
     */
1838
    public function setupBreadcrumb(&$breadcrumb, $action)
1839
    {
1840
        if ($action == 'add') {
1841
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
1842
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Add')];
1843
        } elseif ($action == 'edit') {
1844
            $breadcrumb[] = ['url' => $this->pageUrl, 'name' => $this->pageName];
1845
            $breadcrumb[] = ['url' => '#', 'name' => get_lang('Edit')];
1846
        } else {
1847
            $breadcrumb[] = ['url' => '#', 'name' => $this->pageName];
1848
        }
1849
    }
1850
1851
    /**
1852
     * Displays the title + grid.
1853
     */
1854
    public function display()
1855
    {
1856
        // action links
1857
        echo '<div class="actions">';
1858
        echo '<a href="../admin/index.php">';
1859
        echo Display::return_icon(
1860
            'back.png',
1861
            get_lang('BackTo').' '.get_lang('PlatformAdmin'),
1862
            '',
1863
            ICON_SIZE_MEDIUM
1864
        );
1865
        echo '</a>';
1866
        echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'">';
1867
        echo Display::return_icon(
1868
            'add_user_fields.png',
1869
            get_lang('Add'),
1870
            '',
1871
            ICON_SIZE_MEDIUM
1872
        );
1873
        echo '</a>';
1874
        echo '</div>';
1875
        echo Display::grid_html($this->type.'_fields');
1876
    }
1877
1878
    /**
1879
     * @return array
1880
     */
1881
    public function getJqgridColumnNames()
1882
    {
1883
        return [
1884
            get_lang('Name'),
1885
            get_lang('FieldLabel'),
1886
            get_lang('Type'),
1887
            get_lang('FieldChangeability'),
1888
            get_lang('VisibleToSelf'),
1889
            get_lang('VisibleToOthers'),
1890
            get_lang('Filter'),
1891
            get_lang('FieldOrder'),
1892
            get_lang('Actions'),
1893
        ];
1894
    }
1895
1896
    /**
1897
     * @return array
1898
     */
1899
    public function getJqgridColumnModel()
1900
    {
1901
        return [
1902
            [
1903
                'name' => 'display_text',
1904
                'index' => 'display_text',
1905
                'width' => '140',
1906
                'align' => 'left',
1907
            ],
1908
            [
1909
                'name' => 'variable',
1910
                'index' => 'variable',
1911
                'width' => '90',
1912
                'align' => 'left',
1913
                'sortable' => 'true',
1914
            ],
1915
            [
1916
                'name' => 'field_type',
1917
                'index' => 'field_type',
1918
                'width' => '70',
1919
                'align' => 'left',
1920
                'sortable' => 'true',
1921
            ],
1922
            [
1923
                'name' => 'changeable',
1924
                'index' => 'changeable',
1925
                'width' => '35',
1926
                'align' => 'left',
1927
                'sortable' => 'true',
1928
                'formatter' => '',
1929
            ],
1930
            [
1931
                'name' => 'visible_to_self',
1932
                'index' => 'visible_to_self',
1933
                'width' => '45',
1934
                'align' => 'left',
1935
                'sortable' => 'true',
1936
                'formatter' => '',
1937
            ],
1938
            [
1939
                'name' => 'visible_to_others',
1940
                'index' => 'visible_to_others',
1941
                'width' => '35',
1942
                'align' => 'left',
1943
                'sortable' => 'true',
1944
                'formatter' => '',
1945
            ],
1946
            [
1947
                'name' => 'filter',
1948
                'index' => 'filter',
1949
                'width' => '30',
1950
                'align' => 'left',
1951
                'sortable' => 'true',
1952
                'formatter' => '',
1953
            ],
1954
            [
1955
                'name' => 'field_order',
1956
                'index' => 'field_order',
1957
                'width' => '25',
1958
                'align' => 'left',
1959
                'sortable' => 'true',
1960
            ],
1961
            [
1962
                'name' => 'actions',
1963
                'index' => 'actions',
1964
                'width' => '40',
1965
                'align' => 'left',
1966
                'formatter' => 'action_formatter',
1967
                'sortable' => 'false',
1968
            ],
1969
        ];
1970
    }
1971
1972
    /**
1973
     * @param string $url
1974
     * @param string $action
1975
     *
1976
     * @return FormValidator
1977
     */
1978
    public function return_form($url, $action)
1979
    {
1980
        $form = new FormValidator($this->type.'_field', 'post', $url);
1981
1982
        $form->addElement('hidden', 'type', $this->type);
1983
        $id = isset($_GET['id']) ? (int) $_GET['id'] : null;
1984
        $form->addElement('hidden', 'id', $id);
1985
1986
        // Setting the form elements
1987
        $header = get_lang('Add');
1988
        $defaults = [];
1989
1990
        if ($action === 'edit') {
1991
            $header = get_lang('Modify');
1992
            // Setting the defaults
1993
            $defaults = $this->get($id, false);
1994
        }
1995
1996
        $form->addElement('header', $header);
1997
1998
        if ($action === 'edit') {
1999
            $translateUrl = api_get_path(WEB_CODE_PATH).'extrafield/translate.php?'
2000
                .http_build_query(['extra_field' => $id]);
2001
            $translateButton = Display::toolbarButton(get_lang('TranslateThisTerm'), $translateUrl, 'language', 'link');
2002
2003
            $form->addText(
2004
                'display_text',
2005
                [get_lang('Name'), $translateButton]
2006
            );
2007
        } else {
2008
            $form->addElement('text', 'display_text', get_lang('Name'));
2009
        }
2010
2011
        $form->addHtmlEditor('description', get_lang('Description'), false);
2012
2013
        // Field type
2014
        $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

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

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

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