Completed
Push — master ( 162b1e...50d94b )
by Julito
11:02
created

get_field_option_by_field_and_option()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 2
dl 0
loc 20
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\ExtraFieldOptions;
5
6
/**
7
 * Class ExtraFieldOption
8
 * Handles the extra fields for various objects (users, sessions, courses).
9
 */
10
class ExtraFieldOption extends Model
11
{
12
    public $columns = [
13
        'id',
14
        'field_id',
15
        'option_value',
16
        'display_text',
17
        'option_order',
18
        'priority',
19
        'priority_message',
20
        'tms',
21
    ];
22
23
    public $extraField;
24
    public $fieldId;
25
26
    /**
27
     * Gets the table for the type of object for which we are using an extra field.
28
     *
29
     * @param string $type Type of object (course, user or session)
30
     */
31
    public function __construct($type)
32
    {
33
        parent::__construct();
34
        $this->type = $type;
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
35
        $extraField = new ExtraField($this->type);
36
        $this->extraField = $extraField;
37
        $this->table = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
38
        $this->tableExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
0 ignored issues
show
Bug Best Practice introduced by
The property tableExtraField does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
39
    }
40
41
    /**
42
     * @return ExtraField
43
     */
44
    public function getExtraField()
45
    {
46
        return $this->extraField;
47
    }
48
49
    /**
50
     * Gets the number of options already available in the table for this item type.
51
     *
52
     * @return int Number of options available
53
     * @assert () >= 0
54
     */
55
    /*public function get_count()
56
    {
57
        $row = Database::select('count(*) as count', $this->table, array(), 'first');
58
59
        return $row['count'];
60
    }*/
61
62
    /**
63
     * Gets the number of options available for this field.
64
     *
65
     * @param int $fieldId
66
     *
67
     * @return int Number of options
68
     * @assert ('') === false
69
     * @assert (-1) == 0
70
     * @assert (0) == 0
71
     */
72
    public function get_count_by_field_id($fieldId)
73
    {
74
        if (empty($fieldId)) {
75
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
76
        }
77
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
78
        $fieldId = intval($fieldId);
79
80
        $sql = "SELECT count(*) as count
81
                FROM $this->table o 
82
                INNER JOIN $this->tableExtraField e
83
                ON o.field_id = e.id
84
                WHERE
85
                    o.field_id = $fieldId AND
86
                    e.extra_field_type = $extraFieldType ";
87
        $result = Database::query($sql);
88
        $result = Database::fetch_array($result);
89
90
        return $result['count'];
91
    }
92
93
    /**
94
     * Returns a list of options for a specific field, separated by ";".
95
     *
96
     * @param int    $field_id
97
     * @param bool   $add_id_in_array Indicates whether we want the results to be given with their id
98
     * @param string $ordered_by      Order by clause (without the "order by") to be added to the SQL query
99
     *
100
     * @return string List of options separated by ;
101
     * @assert (-1, false, null) == ''
102
     */
103
    public function getFieldOptionsToString($field_id, $add_id_in_array = false, $ordered_by = null)
104
    {
105
        $options = self::get_field_options_by_field($field_id, $add_id_in_array, $ordered_by);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldOption::get_field_options_by_field() 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

105
        /** @scrutinizer ignore-call */ 
106
        $options = self::get_field_options_by_field($field_id, $add_id_in_array, $ordered_by);
Loading history...
Bug introduced by
It seems like $ordered_by can also be of type string; however, parameter $ordered_by of ExtraFieldOption::get_field_options_by_field() does only seem to accept null, 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

105
        $options = self::get_field_options_by_field($field_id, $add_id_in_array, /** @scrutinizer ignore-type */ $ordered_by);
Loading history...
106
        $new_options = [];
107
        if (!empty($options)) {
108
            foreach ($options as $option) {
109
                $new_options[] = $option['option_value'].':'.$option['display_text'];
110
            }
111
            $string = implode(';', $new_options);
112
113
            return $string;
114
        }
115
116
        return '';
117
    }
118
119
    /**
120
     * Delete all the options of a specific field.
121
     *
122
     * @param int $field_id
123
     *
124
     * @assert (-1) === false
125
     */
126
    public function delete_all_options_by_field_id($field_id)
127
    {
128
        $field_id = intval($field_id);
129
        $sql = "DELETE FROM {$this->table} WHERE field_id = $field_id";
130
        $r = Database::query($sql);
131
132
        return $r;
133
    }
134
135
    /**
136
     * @param array $params
137
     * @param bool  $showQuery
138
     *
139
     * @return int|bool
140
     */
141
    public function saveOptions($params, $showQuery = false)
142
    {
143
        $optionInfo = $this->get_field_option_by_field_and_option(
144
            $params['field_id'],
145
            $params['option_value']
146
        );
147
148
        if ($optionInfo == false) {
149
            $optionValue = api_replace_dangerous_char($params['option_value']);
150
            $order = $this->get_max_order($params['field_id']);
151
            $newParams = [
152
                'field_id' => $params['field_id'],
153
                'value' => trim($optionValue),
154
                'display_text' => trim($params['display_text']),
155
                'option_order' => $order,
156
            ];
157
158
            return parent::save($newParams, $showQuery);
159
        }
160
161
        return false;
162
    }
163
164
    /**
165
     * Saves an option into the corresponding *_field_options table.
166
     *
167
     * @param array $params    Parameters to be considered for the insertion
168
     * @param bool  $showQuery Whether to show the query (sent to the parent save() method)
169
     *
170
     * @return bool True on success, false on error
171
     * @assert (array('field_id'=>0), false) === false
172
     * @assert (array('field_id'=>1), false) === true
173
     */
174
    public function save($params, $showQuery = false)
175
    {
176
        $field_id = intval($params['field_id']);
177
178
        if (empty($field_id)) {
179
            return false;
180
        }
181
182
        $parseOptions = in_array(
183
            $params['field_type'],
184
            [
185
                ExtraField::FIELD_TYPE_RADIO,
186
                ExtraField::FIELD_TYPE_SELECT,
187
                ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
188
                ExtraField::FIELD_TYPE_DOUBLE_SELECT,
189
                ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD,
190
                ExtraField::FIELD_TYPE_TRIPLE_SELECT,
191
            ]
192
        );
193
194
        if (empty($params['field_options']) || !$parseOptions) {
195
            return true;
196
        }
197
198
        switch ($params['field_type']) {
199
            case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
200
                //$params['field_options'] = France:Paris;Bretagne;Marseilles;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura;
201
            case ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
202
                //$params['field_options'] = Option 1|Option 2|Option 3
203
                $options_parsed = ExtraField::extra_field_double_select_convert_string_to_array(
204
                    $params['field_options']
205
                );
206
207
                if (empty($options_parsed)) {
208
                    break;
209
                }
210
211
                foreach ($options_parsed as $key => $option) {
212
                    $new_params = [
213
                        'field_id' => $field_id,
214
                        'option_value' => 0,
215
                        'display_text' => $option['label'],
216
                        'option_order' => 0,
217
                    ];
218
                    // Looking if option already exists:
219
                    $option_info = self::get_field_option_by_field_id_and_option_display_text(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldOption::get_fi...d_option_display_text() 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

219
                    /** @scrutinizer ignore-call */ 
220
                    $option_info = self::get_field_option_by_field_id_and_option_display_text(
Loading history...
220
                        $field_id,
221
                        $option['label']
222
                    );
223
224
                    if (empty($option_info)) {
225
                        $sub_id = parent::save($new_params, $showQuery);
226
                    } else {
227
                        $sub_id = $option_info['id'];
228
                        $new_params['id'] = $sub_id;
229
                        parent::update($new_params, $showQuery);
230
                    }
231
232
                    if ($params['field_type'] == ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD) {
233
                        continue;
234
                    }
235
236
                    foreach ($option['options'] as $sub_option) {
237
                        if (empty($sub_option)) {
238
                            continue;
239
                        }
240
241
                        $new_params = [
242
                            'field_id' => $field_id,
243
                            'option_value' => $sub_id,
244
                            'display_text' => $sub_option,
245
                            'option_order' => 0,
246
                        ];
247
                        $option_info = self::getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldOption::getFie...layTextAndOptionValue() 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

247
                        /** @scrutinizer ignore-call */ 
248
                        $option_info = self::getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
Loading history...
248
                            $field_id,
249
                            $sub_option,
250
                            $sub_id
251
                        );
252
253
                        if (empty($option_info)) {
254
                            parent::save($new_params, $showQuery);
255
256
                            continue;
257
                        }
258
259
                        $new_params['id'] = $option_info['id'];
260
                        parent::update($new_params, $showQuery);
261
                    }
262
                }
263
                break;
264
            case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
265
                //Format: Option1\Option11:Option111;Option112\Option12:Option121|Option2\Option21:Option211
266
                $options = ExtraField::tripleSelectConvertStringToArray($params['field_options']);
267
268
                if (!$options) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
269
                    break;
270
                }
271
272
                foreach ($options as $level1) {
273
                    $level1Params = [
274
                        'field_id' => $field_id,
275
                        'option_value' => 0,
276
                        'display_text' => $level1['label'],
277
                        'option_order' => 0,
278
                    ];
279
                    $optionInfo = self::get_field_option_by_field_id_and_option_display_text(
280
                        $field_id,
281
                        $level1['label']
282
                    );
283
284
                    if (empty($optionInfo)) {
285
                        $level1Id = parent::save($level1Params);
286
                    } else {
287
                        $level1Id = $optionInfo['id'];
288
                        $level1Params['id'] = $level1Id;
289
                        parent::update($level1Params);
290
                    }
291
292
                    foreach ($level1['options'] as $level2) {
293
                        $level2Params = [
294
                            'field_id' => $field_id,
295
                            'option_value' => $level1Id,
296
                            'display_text' => $level2['label'],
297
                            'display_order' => 0,
298
                        ];
299
                        $optionInfo = self::getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
300
                            $field_id,
301
                            $level2['label'],
302
                            $level1Id
303
                        );
304
305
                        if (empty($optionInfo)) {
306
                            $level2Id = parent::save($level2Params);
307
                        } else {
308
                            $level2Id = $optionInfo['id'];
309
                            $level2Params['id'] = $level2Id;
310
                            parent::update($level2Params);
311
                        }
312
313
                        foreach ($level2['options'] as $level3) {
314
                            foreach ($level3 as $item) {
315
                                $level3Params = [
316
                                    'field_id' => $field_id,
317
                                    'option_value' => $level2Id,
318
                                    'display_text' => $item,
319
                                    'display_order' => 0,
320
                                ];
321
                                $optionInfo = self::getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
322
                                    $field_id,
323
                                    $item,
324
                                    $level2Id
325
                                );
326
327
                                if (empty($optionInfo)) {
328
                                    parent::save($level3Params);
329
                                } else {
330
                                    $level3Params['id'] = $optionInfo['id'];
331
                                    parent::update($level3Params);
332
                                }
333
                            }
334
                        }
335
                    }
336
                }
337
                break;
338
            default:
339
                $list = explode(';', $params['field_options']);
340
341
                foreach ($list as $option) {
342
                    $option_info = $this->get_field_option_by_field_and_option($field_id, $option);
343
344
                    // Use URLify only for new items
345
                    $optionValue = api_replace_dangerous_char($option);
346
                    $option = trim($option);
347
348
                    if ($option_info != false) {
349
                        continue;
350
                    }
351
352
                    $order = $this->get_max_order($field_id);
353
354
                    $new_params = [
355
                        'field_id' => $field_id,
356
                        'option_value' => trim($optionValue),
357
                        'display_text' => trim($option),
358
                        'option_order' => $order,
359
                    ];
360
                    parent::save($new_params, $showQuery);
361
                }
362
                break;
363
        }
364
365
        return true;
366
    }
367
368
    /**
369
     * Save one option item at a time.
370
     *
371
     * @param array $params          Parameters specific to the option
372
     * @param bool  $show_query      Whether to show the query (sent to parent save() method)
373
     * @param bool  $insert_repeated Whether to insert even if the option already exists
374
     *
375
     * @return bool True on success, false on failure
376
     * @assert (array('field_id'=>0),false) === false
377
     * @assert (array('field_id'=>0),false) === true
378
     */
379
    public function save_one_item($params, $show_query = false, $insert_repeated = true)
380
    {
381
        $field_id = intval($params['field_id']);
382
        if (empty($field_id)) {
383
            return false;
384
        }
385
386
        if (isset($params['option_value'])) {
387
            $params['option_value'] = trim($params['option_value']);
388
        }
389
390
        if (isset($params['display_text'])) {
391
            $params['display_text'] = trim($params['display_text']);
392
        }
393
394
        if (empty($params['option_order'])) {
395
            $order = $this->get_max_order($field_id);
396
            $params['option_order'] = $order;
397
        }
398
        if ($insert_repeated) {
399
            parent::save($params, $show_query);
400
        } else {
401
            $check = $this->get_field_option_by_field_and_option(
402
                $field_id,
403
                $params['option_value']
404
            );
405
            if ($check == false) {
406
                parent::save($params, $show_query);
407
            }
408
        }
409
410
        return true;
411
    }
412
413
    /**
414
     * Get the complete row of a specific option of a specific field.
415
     *
416
     * @param int    $field_id
417
     * @param string $option_value Value of the option
418
     *
419
     * @return mixed The row on success or false on failure
420
     * @assert (0,'') === false
421
     */
422
    public function get_field_option_by_field_and_option($field_id, $option_value)
423
    {
424
        $field_id = intval($field_id);
425
        $option_value = Database::escape_string($option_value);
426
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
427
428
        $sql = "SELECT s.* FROM {$this->table} s
429
                INNER JOIN {$this->tableExtraField} sf
430
                ON (s.field_id = sf.id)
431
                WHERE
432
                    field_id = $field_id AND
433
                    option_value = '".$option_value."' AND
434
                    sf.extra_field_type = $extraFieldType
435
                ";
436
        $result = Database::query($sql);
437
        if (Database::num_rows($result) > 0) {
438
            return Database::store_result($result, 'ASSOC');
439
        }
440
441
        return false;
442
    }
443
444
    /**
445
     * Get the complete row of a specific option's display text of a specific field.
446
     *
447
     * @param int    $field_id
448
     * @param string $option_display_text Display value of the option
449
     *
450
     * @return mixed The row on success or false on failure
451
     * @assert (0, '') === false
452
     */
453
    public function get_field_option_by_field_id_and_option_display_text($field_id, $option_display_text)
454
    {
455
        $field_id = intval($field_id);
456
        $option_display_text = Database::escape_string($option_display_text);
457
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
458
459
        $sql = "SELECT s.* FROM {$this->table} s
460
                INNER JOIN {$this->tableExtraField} sf
461
                ON (s.field_id = sf.id)
462
                WHERE
463
                    field_id = $field_id AND
464
                    s.display_text = '".$option_display_text."' AND
465
                    sf.extra_field_type = $extraFieldType
466
                ";
467
        $result = Database::query($sql);
468
        if (Database::num_rows($result) > 0) {
469
            return Database::fetch_array($result, 'ASSOC');
470
        }
471
472
        return false;
473
    }
474
475
    /**
476
     * Get the complete row of a specific option's display text of a specific field.
477
     *
478
     * @param int    $field_id
479
     * @param string $option_display_text Display value of the option
480
     * @param string $option_value        Value of the option
481
     *
482
     * @return mixed The row on success or false on failure
483
     * @assert (0, '', '') === false
484
     */
485
    public function getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
486
        $field_id,
487
        $option_display_text,
488
        $option_value
489
    ) {
490
        $field_id = intval($field_id);
491
        $option_display_text = Database::escape_string($option_display_text);
492
        $option_value = Database::escape_string($option_value);
493
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
494
495
        $sql = "SELECT s.* FROM {$this->table} s
496
                INNER JOIN {$this->tableExtraField} sf
497
                ON (s.field_id = sf.id)
498
                WHERE
499
                    field_id = $field_id AND
500
                    sf.display_text = '".$option_display_text."' AND
501
                    option_value = '$option_value' AND
502
                    sf.extra_field_type = ".$extraFieldType."
503
                ";
504
        $result = Database::query($sql);
505
        if (Database::num_rows($result) > 0) {
506
            return Database::fetch_array($result, 'ASSOC');
507
        }
508
509
        return false;
510
    }
511
512
    /**
513
     * Gets an array of options for a specific field.
514
     *
515
     * @param int  $field_id        The field ID
516
     * @param bool $add_id_in_array Whether to add the row ID in the result
517
     * @param null $ordered_by      Extra ordering query bit
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $ordered_by is correct as it would always require null to be passed?
Loading history...
518
     *
519
     * @return array The options if they exists. Otherwise return false
520
     */
521
    public function get_field_options_by_field($field_id, $add_id_in_array = false, $ordered_by = null)
522
    {
523
        $field_id = intval($field_id);
524
525
        $orderBy = null;
526
        switch ($ordered_by) {
527
            case 'id':
528
                $orderBy = ['id' => 'ASC'];
529
                break;
530
            case 'field_id':
531
                $orderBy = ['fieldId' => 'ASC'];
532
                break;
533
            case 'option_value':
534
                $orderBy = ['optionValue' => 'ASC'];
535
                break;
536
            case 'display_text':
537
                $orderBy = ['displayText' => 'ASC'];
538
                break;
539
            case 'priority':
540
                $orderBy = ['priority' => 'ASC'];
541
                break;
542
            case 'priority_message':
543
                $orderBy = ['priorityMessage' => 'ASC'];
544
                break;
545
            case 'option_order':
546
                $orderBy = ['optionOrder' => 'ASC'];
547
                break;
548
        }
549
550
        $result = Database::getManager()
551
            ->getRepository('ChamiloCoreBundle:ExtraFieldOptions')
552
            ->findBy(['field' => $field_id], $orderBy);
553
554
        if (!$result) {
555
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
556
        }
557
558
        $options = [];
559
        /** @var ExtraFieldOptions $row */
560
        foreach ($result as $row) {
561
            $option = [
562
                'id' => $row->getId(),
563
                'field_id' => $row->getField()->getId(),
564
                'option_value' => $row->getValue(),
565
                'display_text' => self::translateDisplayName($row->getDisplayText()),
566
                'priority' => $row->getPriority(),
567
                'priority_message' => $row->getPriorityMessage(),
568
                'option_order' => $row->getOptionOrder(),
569
            ];
570
571
            if ($add_id_in_array) {
572
                $options[$row->getId()] = $option;
573
                continue;
574
            }
575
            $options[] = $option;
576
        }
577
578
        return $options;
579
    }
580
581
    /**
582
     * Get options for a specific field as array or in JSON format suited for the double-select format.
583
     *
584
     * @param int  $option_value_id Option value ID
585
     * @param bool $to_json         Return format (whether it should be formatted to JSON or not)
586
     *
587
     * @return mixed Row/JSON on success
588
     */
589
    public function get_second_select_field_options_by_field($option_value_id, $to_json = false)
590
    {
591
        $em = Database::getManager();
592
        $option = $em->find('ChamiloCoreBundle:ExtraFieldOptions', intval($option_value_id));
593
594
        if (!$option) {
595
            return !$to_json ? [] : '{}';
596
        }
597
598
        $subOptions = $em
599
            ->getRepository('ChamiloCoreBundle:ExtraFieldOptions')
600
            ->findSecondaryOptions($option);
601
602
        $optionsInfo = [];
603
        /** @var ExtraFieldOptions $subOption */
604
        foreach ($subOptions as $subOption) {
605
            $optionsInfo[] = [
606
                'id' => $subOption->getId(),
607
                'field_id' => $subOption->getField()->getId(),
608
                'option_value' => $subOption->getValue(),
609
                'display_text' => $subOption->getDisplayText(),
610
                'priority' => $subOption->getPriority(),
611
                'priority_message' => $subOption->getPriorityMessage(),
612
                'option_order' => $subOption->getOptionOrder(),
613
            ];
614
        }
615
616
        if (!$to_json) {
617
            return $optionsInfo;
618
        }
619
620
        $json = [];
621
622
        foreach ($optionsInfo as $optionInfo) {
623
            $json[$optionInfo['id']] = $optionInfo['display_text'];
624
        }
625
626
        return json_encode($json);
627
    }
628
629
    /**
630
     * Get options for a specific field as string split by ;.
631
     *
632
     * @param int    $field_id
633
     * @param string $ordered_by Extra query bit for reordering
634
     *
635
     * @return string HTML string of options
636
     * @assert (0, '') === null
637
     */
638
    public function get_field_options_by_field_to_string($field_id, $ordered_by = null)
639
    {
640
        $field = new ExtraField($this->type);
641
        $field_info = $field->get($field_id);
642
        $options = self::get_field_options_by_field($field_id, false, $ordered_by);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldOption::get_field_options_by_field() 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

642
        /** @scrutinizer ignore-call */ 
643
        $options = self::get_field_options_by_field($field_id, false, $ordered_by);
Loading history...
Bug introduced by
It seems like $ordered_by can also be of type string; however, parameter $ordered_by of ExtraFieldOption::get_field_options_by_field() does only seem to accept null, 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

642
        $options = self::get_field_options_by_field($field_id, false, /** @scrutinizer ignore-type */ $ordered_by);
Loading history...
643
        $elements = [];
644
        if (!empty($options)) {
645
            switch ($field_info['field_type']) {
646
                case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
647
                    $html = ExtraField::extra_field_double_select_convert_array_to_string($options);
648
                    break;
649
                case ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
650
                    $html = ExtraField::extraFieldSelectWithTextConvertArrayToString($options);
651
                    break;
652
                case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
653
                    $html = ExtraField::tripleSelectConvertArrayToString($options);
654
                    break;
655
                default:
656
                    foreach ($options as $option) {
657
                        $elements[] = $option['option_value'];
658
                    }
659
                    $html = implode(';', $elements);
660
                    break;
661
            }
662
663
            return $html;
664
        }
665
666
        return null;
667
    }
668
669
    /**
670
     * Get the maximum order value for a specific field.
671
     *
672
     * @param int $field_id
673
     *
674
     * @return int Current max ID + 1 (we start from 0)
675
     * @assert (0, '') === 1
676
     */
677
    public function get_max_order($field_id)
678
    {
679
        $field_id = intval($field_id);
680
        $sql = "SELECT MAX(option_order)
681
                FROM {$this->table}
682
                WHERE field_id = $field_id";
683
        $res = Database::query($sql);
684
        $max = 1;
685
        if (Database::num_rows($res) > 0) {
686
            $row = Database::fetch_array($res);
687
            $max = $row[0] + 1;
688
        }
689
690
        return $max;
691
    }
692
693
    /**
694
     * Display a form with the options for the field_id given in REQUEST.
695
     */
696
    public function display()
697
    {
698
        // action links
699
        echo '<div class="actions">';
700
        $field_id = isset($_REQUEST['field_id']) ? intval($_REQUEST['field_id']) : null;
701
        echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'&field_id='.$field_id.'">'.
702
                Display::return_icon('add_user_fields.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
703
        echo '</div>';
704
        echo Display::grid_html('extra_field_options');
705
    }
706
707
    /**
708
     * @return array
709
     */
710
    public function getPriorityOptions()
711
    {
712
        return  [
713
            '' => get_lang('SelectAnOption'),
714
            1 => get_lang('Success'),
715
            2 => get_lang('Info'),
716
            3 => get_lang('Warning'),
717
            4 => get_lang('Error'),
718
        ];
719
    }
720
721
    /**
722
     * @param $priority
723
     *
724
     * @return string|null
725
     */
726
    public function getPriorityMessageType($priority)
727
    {
728
        switch ($priority) {
729
            case 1:
730
                return 'success';
731
            case 2:
732
                return 'info';
733
            case 3:
734
                return 'warning';
735
            case 4:
736
                return 'error';
737
        }
738
739
        return null;
740
    }
741
742
    /**
743
     * Returns an HTML form for the current field.
744
     *
745
     * @param string URL to send the form to (action=...)
746
     * @param string Type of action to offer through the form (edit, usually)
747
     *
748
     * @return FormValidator
749
     */
750
    public function return_form($url, $action)
751
    {
752
        $form_name = $this->type.'_field';
753
        $form = new FormValidator($form_name, 'post', $url);
754
        // Setting the form elements
755
        $header = get_lang('Add');
756
        if ($action == 'edit') {
757
            $header = get_lang('Modify');
758
        }
759
760
        $form->addElement('header', $header);
761
        $id = isset($_GET['id']) ? intval($_GET['id']) : '';
762
763
        $form->addElement('hidden', 'id', $id);
764
        $form->addElement('hidden', 'type', $this->type);
765
        $form->addElement('hidden', 'field_id', $this->fieldId);
766
767
        if ($action == 'edit') {
768
            $translateUrl = api_get_path(WEB_CODE_PATH).'extrafield/translate.php?'.http_build_query([
769
                'extra_field_option' => $id,
770
            ]);
771
            $translateButton = Display::toolbarButton(
772
                get_lang('TranslateThisTerm'),
773
                $translateUrl,
774
                'language',
775
                'link'
776
            );
777
778
            $form->addText(
779
                'display_text',
780
                [get_lang('Name'), $translateButton]
781
            );
782
        } else {
783
            $form->addElement('text', 'display_text', get_lang('Name'));
784
        }
785
786
        $form->addElement('text', 'option_value', get_lang('Value'));
787
        $form->addElement('text', 'option_order', get_lang('Order'));
788
        $form->addElement('select', 'priority', get_lang('Priority'), $this->getPriorityOptions());
789
        $form->addElement('textarea', 'priority_message', get_lang('PriorityOfMessage'));
790
791
        $defaults = [];
792
793
        if ($action == 'edit') {
794
            // Setting the defaults
795
            $defaults = $this->get($id, false);
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type string; however, parameter $id of ExtraFieldOption::get() 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

795
            $defaults = $this->get(/** @scrutinizer ignore-type */ $id, false);
Loading history...
796
            $form->freeze('option_value');
797
            $form->addButtonUpdate(get_lang('Modify'));
798
        } else {
799
            $form->addButtonCreate(get_lang('Add'));
800
        }
801
802
        $form->setDefaults($defaults);
803
804
        // Setting the rules
805
        $form->addRule('display_text', get_lang('ThisFieldIsRequired'), 'required');
806
        $form->addRule('option_value', get_lang('ThisFieldIsRequired'), 'required');
807
808
        return $form;
809
    }
810
811
    /**
812
     * @param string $tag
813
     * @param int    $field_id
814
     * @param int    $limit
815
     *
816
     * @return array
817
     */
818
    public function searchByField($tag, $field_id, $limit = 10)
819
    {
820
        $field_id = intval($field_id);
821
        $limit = intval($limit);
822
        $tag = Database::escape_string($tag);
823
        $sql = "SELECT DISTINCT id, option_display_text
824
                FROM {$this->table}
825
                WHERE
826
                    field_id = '".$field_id."' AND
827
                    option_value LIKE '%$tag%'
828
                ORDER BY option_value
829
                LIMIT 0, $limit
830
                ";
831
        $result = Database::query($sql);
832
        $values = [];
833
        if (Database::num_rows($result)) {
834
            $values = Database::store_result($result, 'ASSOC');
835
        }
836
837
        return $values;
838
    }
839
840
    /**
841
     * @param string $tag
842
     * @param int    $field_id
843
     * @param int    $limit
844
     *
845
     * @return string
846
     */
847
    public function getSearchOptionsByField($tag, $field_id, $limit = 10)
0 ignored issues
show
Unused Code introduced by
The parameter $limit is not used and could be removed. ( Ignorable by Annotation )

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

847
    public function getSearchOptionsByField($tag, $field_id, /** @scrutinizer ignore-unused */ $limit = 10)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
848
    {
849
        $result = $this->searchByField($tag, $field_id, $limit = 10);
850
        $values = [];
851
        $json = null;
852
        if (!empty($result)) {
853
            foreach ($result as $item) {
854
                $values[] = [
855
                    'value' => $item['id'],
856
                    'caption' => $item['option_display_text'],
857
                ];
858
            }
859
            $json = json_encode($values);
860
        }
861
862
        return $json;
863
    }
864
865
    /**
866
     * Gets an element.
867
     *
868
     * @param int  $id
869
     * @param bool $translateDisplayText Optional
870
     *
871
     * @return array
872
     */
873
    public function get($id, $translateDisplayText = true)
874
    {
875
        $info = parent::get($id);
876
877
        if ($translateDisplayText) {
878
            $info['display_text'] = self::translateDisplayName($info['display_text']);
879
        }
880
881
        return $info;
882
    }
883
884
    /**
885
     * Translate the display text for a extra field option.
886
     *
887
     * @param string $defaultDisplayText
888
     *
889
     * @return string
890
     */
891
    public static function translateDisplayName($defaultDisplayText)
892
    {
893
        $variableLanguage = self::getLanguageVariable($defaultDisplayText);
894
895
        return isset($GLOBALS[$variableLanguage]) ? $GLOBALS[$variableLanguage] : $defaultDisplayText;
896
    }
897
898
    /**
899
     * @param $defaultDisplayText
900
     *
901
     * @return mixed|string
902
     */
903
    public static function getLanguageVariable($defaultDisplayText)
904
    {
905
        $variableLanguage = api_replace_dangerous_char($defaultDisplayText);
906
        $variableLanguage = str_replace('-', '_', $variableLanguage);
907
        $variableLanguage = api_underscore_to_camel_case($variableLanguage);
908
909
        return $variableLanguage;
910
    }
911
912
    /**
913
     * @param null $options
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $options is correct as it would always require null to be passed?
Loading history...
914
     *
915
     * @return array
916
     */
917
    public function get_all($options = null)
918
    {
919
        $result = parent::get_all($options);
920
921
        foreach ($result as &$row) {
922
            $row['display_text'] = self::translateDisplayName($row['display_text']);
923
        }
924
925
        return $result;
926
    }
927
928
    /**
929
     * @param string $variable
930
     *
931
     * @return array|\Chamilo\CoreBundle\Entity\ExtraFieldOptions[]
932
     */
933
    public function getOptionsByFieldVariable($variable)
934
    {
935
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
936
937
        $dql = "SELECT o FROM ChamiloCoreBundle:ExtraFieldOptions o
938
            INNER JOIN ChamiloCoreBundle:ExtraField f WITH o.field = f.id
939
            WHERE f.variable = :variable AND f.extraFieldType = :extra_field_type
940
            ORDER BY o.value ASC";
941
942
        $result = Database::getManager()
943
            ->createQuery($dql)
944
            ->setParameters(['variable' => $variable, 'extra_field_type' => $extraFieldType])
945
            ->getResult();
946
947
        return $result;
948
    }
949
}
950