Passed
Push — 1.11.x ( 2c28ff...45e776 )
by Julito
12:06
created

ExtraFieldValue::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField;
6
use Chamilo\CoreBundle\Entity\ExtraFieldRelTag;
7
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
8
use Chamilo\CoreBundle\Entity\Tag;
9
use ChamiloSession as Session;
10
11
/**
12
 * Class ExtraFieldValue
13
 * Declaration for the ExtraFieldValue class, managing the values in extra
14
 * fields for any data type.
15
 */
16
class ExtraFieldValue extends Model
17
{
18
    public $type = '';
19
    public $columns = [
20
        'id',
21
        'field_id',
22
        'value',
23
        'comment',
24
        'item_id',
25
        'created_at',
26
        'updated_at',
27
    ];
28
    /** @var ExtraField */
29
    public $extraField;
30
31
    /**
32
     * Formats the necessary elements for the given datatype.
33
     *
34
     * @param string $type The type of data to which this extra field
35
     *                     applies (user, course, session, ...)
36
     *
37
     * @assert (-1) === false
38
     */
39
    public function __construct($type)
40
    {
41
        parent::__construct();
42
        $this->type = $type;
43
        $extraField = new ExtraField($this->type);
44
        $this->extraField = $extraField;
45
        $this->table = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
46
        $this->table_handler_field = Database::get_main_table(TABLE_EXTRA_FIELD);
47
    }
48
49
    /**
50
     * @return ExtraField
51
     */
52
    public function getExtraField()
53
    {
54
        return $this->extraField;
55
    }
56
57
    /**
58
     * Gets the number of values stored in the table (all fields together)
59
     * for this type of resource.
60
     *
61
     * @return int Number of rows in the table
62
     * @assert () !== false
63
     */
64
    public function get_count()
65
    {
66
        $em = Database::getManager();
67
        $query = $em->getRepository('ChamiloCoreBundle:ExtraFieldValues')->createQueryBuilder('e');
68
        $query->select('count(e.id)');
69
        $query->where('e.extraFieldType = :type');
70
        $query->setParameter('type', $this->getExtraField()->getExtraFieldType());
71
72
        return $query->getQuery()->getSingleScalarResult();
73
    }
74
75
    /**
76
     * Save the extra fields values
77
     * In order to save this function needs a item_id (user id, course id, etc)
78
     * This function is used with $extraField->addElements().
79
     *
80
     * @param array $params              array for the insertion into the *_field_values table
81
     * @param bool  $onlySubmittedFields Only save parameters in the $param array
82
     * @param bool  $showQuery
83
     * @param array $saveOnlyThisFields
84
     * @param array $avoidFields         do not insert/modify this field
85
     * @param bool  $forceSave
86
     *
87
     * @return mixed false on empty params, void otherwise
88
     * @assert (array()) === false
89
     */
90
    public function saveFieldValues(
91
        $params,
92
        $onlySubmittedFields = false,
93
        $showQuery = false,
94
        $saveOnlyThisFields = [],
95
        $avoidFields = [],
96
        $forceSave = false
97
    ) {
98
        foreach ($params as $key => $value) {
99
            $found = strpos($key, '__persist__');
100
101
            if (false === $found) {
102
                continue;
103
            }
104
105
            $tempKey = str_replace('__persist__', '', $key);
106
            if (!isset($params[$tempKey])) {
107
                $params[$tempKey] = [];
108
            }
109
        }
110
111
        if (empty($params['item_id'])) {
112
            return false;
113
        }
114
115
        $type = $this->getExtraField()->getExtraFieldType();
116
117
        $extraField = new ExtraField($this->type);
118
        $extraFields = $extraField->get_all(null, 'option_order');
119
120
        // Parse params.
121
        foreach ($extraFields as $fieldDetails) {
122
            if ($forceSave === false) {
123
                // if the field is not visible to the user in the end, we need to apply special rules.
124
                if (1 != $fieldDetails['visible_to_self']) {
125
                    //only admins should be able to add those values
126
                    if (!api_is_platform_admin(true, true)) {
127
                        // although if not admin but sent through a CLI script, we should accept it as well
128
                        if (PHP_SAPI != 'cli') {
129
                            continue; //not a CLI script, so don't write the value to DB
130
                        }
131
                    }
132
                }
133
            }
134
135
            $field_variable = $fieldDetails['variable'];
136
137
            if ($onlySubmittedFields && !isset($params['extra_'.$field_variable])) {
138
                continue;
139
            }
140
141
            if (!empty($avoidFields)) {
142
                if (in_array($field_variable, $avoidFields)) {
143
                    continue;
144
                }
145
            }
146
147
            if (!empty($saveOnlyThisFields)) {
148
                if (!in_array($field_variable, $saveOnlyThisFields)) {
149
                    continue;
150
                }
151
            }
152
153
            $value = '';
154
            if (isset($params['extra_'.$field_variable])) {
155
                $value = $params['extra_'.$field_variable];
156
            }
157
            $extraFieldInfo = $this->getExtraField()->get_handler_field_info_by_field_variable($field_variable);
158
159
            if (!$extraFieldInfo) {
160
                continue;
161
            }
162
163
            // see  BT#17943
164
            $authors = false;
165
            if (
166
                $extraFieldInfo['variable'] == 'authors'
167
                || $extraFieldInfo['variable'] == 'authorlp'
168
                || $extraFieldInfo['variable'] == 'authorlpitem'
169
                || $extraFieldInfo['variable'] == 'price'
170
            ) {
171
                $authors = true;
172
            }
173
            if (!api_is_platform_admin() && $authors == true) {
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...
174
                continue;
175
            }
176
177
            $commentVariable = 'extra_'.$field_variable.'_comment';
178
            $comment = isset($params[$commentVariable]) ? $params[$commentVariable] : null;
179
            $dirPermissions = api_get_permissions_for_new_directories();
180
181
            switch ($extraFieldInfo['field_type']) {
182
                case ExtraField::FIELD_TYPE_GEOLOCALIZATION_COORDINATES:
183
                case ExtraField::FIELD_TYPE_GEOLOCALIZATION:
184
                    if (!empty($value)) {
185
                        if (isset($params['extra_'.$extraFieldInfo['variable'].'_coordinates'])) {
186
                            $value = $value.'::'.$params['extra_'.$extraFieldInfo['variable'].'_coordinates'];
187
                        }
188
                        $newParams = [
189
                            'item_id' => $params['item_id'],
190
                            'field_id' => $extraFieldInfo['id'],
191
                            'value' => $value,
192
                            'comment' => $comment,
193
                        ];
194
                        self::save($newParams, $showQuery);
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldValue::save() 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

194
                        self::/** @scrutinizer ignore-call */ 
195
                              save($newParams, $showQuery);
Loading history...
195
                    }
196
                    break;
197
                case ExtraField::FIELD_TYPE_TAG:
198
                    if (EntityExtraField::USER_FIELD_TYPE == $type) {
199
                        UserManager::delete_user_tags(
200
                            $params['item_id'],
201
                            $extraFieldInfo['id']
202
                        );
203
204
                        UserManager::process_tags(
205
                            $value,
206
                            $params['item_id'],
207
                            $extraFieldInfo['id']
208
                        );
209
                        break;
210
                    }
211
212
                    $em = Database::getManager();
213
214
                    $currentTags = $em
215
                        ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
216
                        ->findBy([
217
                            'fieldId' => $extraFieldInfo['id'],
218
                            'itemId' => $params['item_id'],
219
                        ]);
220
221
                    foreach ($currentTags as $extraFieldtag) {
222
                        $em->remove($extraFieldtag);
223
                    }
224
                    $em->flush();
225
                    $tagValues = is_array($value) ? $value : [$value];
226
                    $tags = [];
227
228
                    foreach ($tagValues as $tagValue) {
229
                        if (empty($tagValue)) {
230
                            continue;
231
                        }
232
233
                        $tagsResult = $em->getRepository('ChamiloCoreBundle:Tag')
234
                            ->findBy([
235
                                'tag' => $tagValue,
236
                                'fieldId' => $extraFieldInfo['id'],
237
                            ]);
238
239
                        if (empty($tagsResult)) {
240
                            $tag = new Tag();
241
                            $tag->setFieldId($extraFieldInfo['id']);
242
                            $tag->setTag($tagValue);
243
244
                            $tags[] = $tag;
245
                        } else {
246
                            $tags = array_merge($tags, $tagsResult);
247
                        }
248
                    }
249
250
                    foreach ($tags as $tag) {
251
                        $tagUses = $em
252
                            ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
253
                            ->findBy([
254
                                'tagId' => $tag->getId(),
255
                            ]);
256
257
                        $tag->setCount(count($tagUses) + 1);
258
                        $em->persist($tag);
259
                    }
260
261
                    $em->flush();
262
263
                    foreach ($tags as $tag) {
264
                        $fieldRelTag = new ExtraFieldRelTag();
265
                        $fieldRelTag->setFieldId($extraFieldInfo['id']);
266
                        $fieldRelTag->setItemId($params['item_id']);
267
                        $fieldRelTag->setTagId($tag->getId());
268
                        $em->persist($fieldRelTag);
269
                    }
270
271
                    $em->flush();
272
                    break;
273
                case ExtraField::FIELD_TYPE_FILE_IMAGE:
274
                    $fileDir = $fileDirStored = '';
275
                    switch ($this->type) {
276
                        case 'course':
277
                            $fileDir = api_get_path(SYS_UPLOAD_PATH)."courses/";
278
                            $fileDirStored = "courses/";
279
                            break;
280
                        case 'session':
281
                            $fileDir = api_get_path(SYS_UPLOAD_PATH)."sessions/";
282
                            $fileDirStored = "sessions/";
283
                            break;
284
                        case 'user':
285
                            $fileDir = UserManager::getUserPathById($params['item_id'], 'system');
286
                            $fileDirStored = UserManager::getUserPathById($params['item_id'], 'last');
287
                            break;
288
                        case 'work':
289
                            $fileDir = api_get_path(SYS_UPLOAD_PATH).'work/';
290
                            $fileDirStored = 'work/';
291
                            break;
292
                    }
293
294
                    $fileName = ExtraField::FIELD_TYPE_FILE_IMAGE."_{$params['item_id']}.png";
295
296
                    if (!file_exists($fileDir)) {
297
                        mkdir($fileDir, $dirPermissions, true);
298
                    }
299
300
                    if (!empty($value['tmp_name']) && isset($value['error']) && $value['error'] == 0) {
301
                        // Crop the image to adjust 16:9 ratio
302
                        if (isset($params['extra_'.$field_variable.'_crop_result'])) {
303
                            $crop = new Image($value['tmp_name']);
304
                            $crop->crop($params['extra_'.$field_variable.'_crop_result']);
305
                        }
306
307
                        $imageExtraField = new Image($value['tmp_name']);
308
                        $imageExtraField->resize(400);
309
                        $imageExtraField->send_image($fileDir.$fileName, -1, 'png');
310
                        $newParams = [
311
                            'item_id' => $params['item_id'],
312
                            'field_id' => $extraFieldInfo['id'],
313
                            'value' => $fileDirStored.$fileName,
314
                            'comment' => $comment,
315
                        ];
316
                        $this->save($newParams);
317
                    }
318
                    break;
319
                case ExtraField::FIELD_TYPE_FILE:
320
                    $fileDir = $fileDirStored = '';
321
                    switch ($this->type) {
322
                        case 'course':
323
                            $fileDir = api_get_path(SYS_UPLOAD_PATH).'courses/';
324
                            $fileDirStored = "courses/";
325
                            break;
326
                        case 'session':
327
                            $fileDir = api_get_path(SYS_UPLOAD_PATH).'sessions/';
328
                            $fileDirStored = "sessions/";
329
                            break;
330
                        case 'user':
331
                            $fileDir = UserManager::getUserPathById($params['item_id'], 'system');
332
                            $fileDirStored = UserManager::getUserPathById($params['item_id'], 'last');
333
                            break;
334
                        case 'work':
335
                            $fileDir = api_get_path(SYS_UPLOAD_PATH).'work/';
336
                            $fileDirStored = "work/";
337
                            break;
338
                        case 'scheduled_announcement':
339
                            $fileDir = api_get_path(SYS_UPLOAD_PATH).'scheduled_announcement/';
340
                            $fileDirStored = 'scheduled_announcement/';
341
                            break;
342
                    }
343
344
                    $cleanedName = api_replace_dangerous_char($value['name']);
345
                    $fileName = ExtraField::FIELD_TYPE_FILE."_{$params['item_id']}_$cleanedName";
346
                    if (!file_exists($fileDir)) {
347
                        mkdir($fileDir, $dirPermissions, true);
348
                    }
349
350
                    if (!empty($value['tmp_name']) && isset($value['error']) && $value['error'] == 0) {
351
                        $cleanedName = api_replace_dangerous_char($value['name']);
352
                        $fileName = ExtraField::FIELD_TYPE_FILE."_{$params['item_id']}_$cleanedName";
353
                        moveUploadedFile($value, $fileDir.$fileName);
354
355
                        $new_params = [
356
                            'item_id' => $params['item_id'],
357
                            'field_id' => $extraFieldInfo['id'],
358
                            'value' => $fileDirStored.$fileName,
359
                        ];
360
361
                        if ('session' !== $this->type && 'course' !== $this->type) {
362
                            $new_params['comment'] = $comment;
363
                        }
364
365
                        $this->save($new_params);
366
                    }
367
                    break;
368
                case ExtraField::FIELD_TYPE_CHECKBOX:
369
                    $fieldToSave = 0;
370
                    if (is_array($value)) {
371
                        if (isset($value['extra_'.$field_variable])) {
372
                            $fieldToSave = 1;
373
                        }
374
                    }
375
376
                    $newParams = [
377
                        'item_id' => $params['item_id'],
378
                        'field_id' => $extraFieldInfo['id'],
379
                        'value' => $fieldToSave,
380
                        'comment' => $comment,
381
                    ];
382
                    $this->save($newParams);
383
384
                    break;
385
                case ExtraField::FIELD_TYPE_DATE:
386
                    $d = DateTime::createFromFormat('Y-m-d', $value);
387
                    $valid = $d && $d->format('Y-m-d') === $value;
388
                    if ($valid) {
389
                        $newParams = [
390
                            'item_id' => $params['item_id'],
391
                            'field_id' => $extraFieldInfo['id'],
392
                            'value' => $value,
393
                            'comment' => $comment,
394
                        ];
395
                        $this->save($newParams, $showQuery);
396
                    }
397
                    break;
398
                case ExtraField::FIELD_TYPE_DATETIME:
399
                    $d = DateTime::createFromFormat('Y-m-d H:i', $value);
400
                    $valid = $d && $d->format('Y-m-d H:i') === $value;
401
                    if ($valid) {
402
                        $newParams = [
403
                            'item_id' => $params['item_id'],
404
                            'field_id' => $extraFieldInfo['id'],
405
                            'value' => $value,
406
                            'comment' => $comment,
407
                        ];
408
                        $this->save($newParams, $showQuery);
409
                    }
410
                    break;
411
                default:
412
                    $newParams = [
413
                        'item_id' => $params['item_id'],
414
                        'field_id' => $extraFieldInfo['id'],
415
                        'value' => $value,
416
                        'comment' => $comment,
417
                    ];
418
                    $this->save($newParams, $showQuery);
419
            }
420
        }
421
    }
422
423
    /**
424
     * Save values in the *_field_values table.
425
     *
426
     * @param array $params    Structured array with the values to save
427
     * @param bool  $showQuery Whether to show the insert query (passed to the parent save() method)
428
     *
429
     * @return mixed The result sent from the parent method
430
     * @assert (array()) === false
431
     */
432
    public function save($params, $showQuery = false)
433
    {
434
        $extra_field = $this->getExtraField();
435
436
        // Setting value to insert.
437
        $value = $params['value'];
438
        $value_to_insert = null;
439
440
        if (is_array($value)) {
441
            $value_to_insert = implode(';', $value);
442
        } else {
443
            $value_to_insert = $value;
444
        }
445
446
        $params['value'] = $value_to_insert;
447
448
        // If field id exists
449
        if (isset($params['field_id'])) {
450
            $extraFieldInfo = $extra_field->get($params['field_id']);
451
        } else {
452
            // Try the variable
453
            $extraFieldInfo = $extra_field->get_handler_field_info_by_field_variable(
454
                $params['variable']
455
            );
456
            if ($extraFieldInfo) {
457
                $params['field_id'] = $extraFieldInfo['id'];
458
            }
459
        }
460
461
        if ($extraFieldInfo) {
462
            switch ($extraFieldInfo['field_type']) {
463
                case ExtraField::FIELD_TYPE_RADIO:
464
                case ExtraField::FIELD_TYPE_SELECT:
465
                    break;
466
                case ExtraField::FIELD_TYPE_SELECT_MULTIPLE:
467
                    //$field_options = $session_field_option->get_field_options_by_field($params['field_id']);
468
                    //$params['field_value'] = split(';', $value_to_insert);
469
                    /*
470
                        if ($field_options) {
471
                            $check = false;
472
                            foreach ($field_options as $option) {
473
                                if (in_array($option['option_value'], $values)) {
474
                                    $check = true;
475
                                    break;
476
                                }
477
                           }
478
                           if (!$check) {
479
                               return false; //option value not found
480
                           }
481
                       } else {
482
                           return false; //enumerated type but no option found
483
                       }*/
484
                    break;
485
                case ExtraField::FIELD_TYPE_TEXT:
486
                case ExtraField::FIELD_TYPE_TEXTAREA:
487
                    break;
488
                case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
489
                case ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
490
                    if (is_array($value)) {
491
                        $value_to_insert = null;
492
                        if (isset($value['extra_'.$extraFieldInfo['variable']]) &&
493
                            isset($value['extra_'.$extraFieldInfo['variable'].'_second'])
494
                        ) {
495
                            $value_to_insert = $value['extra_'.$extraFieldInfo['variable']].'::'.$value['extra_'.$extraFieldInfo['variable'].'_second'];
496
                        }
497
                    }
498
                    break;
499
                default:
500
                    break;
501
            }
502
503
            if (ExtraField::FIELD_TYPE_TAG == $extraFieldInfo['field_type']) {
504
                $field_values = self::getAllValuesByItemAndFieldAndValue(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldValue::getAllV...yItemAndFieldAndValue() 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

504
                /** @scrutinizer ignore-call */ 
505
                $field_values = self::getAllValuesByItemAndFieldAndValue(
Loading history...
505
                    $params['item_id'],
506
                    $params['field_id'],
507
                    $value
508
                );
509
            } else {
510
                $field_values = self::get_values_by_handler_and_field_id(
0 ignored issues
show
Bug Best Practice introduced by
The method ExtraFieldValue::get_val..._handler_and_field_id() 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

510
                /** @scrutinizer ignore-call */ 
511
                $field_values = self::get_values_by_handler_and_field_id(
Loading history...
511
                    $params['item_id'],
512
                    $params['field_id']
513
                );
514
            }
515
516
            $params['value'] = $value_to_insert;
517
            //$params['author_id'] = api_get_user_id();
518
519
            // Insert
520
            if (empty($field_values)) {
521
                /* Enable this when field_loggeable is introduced as a table field (2.0)
522
                if ($extraFieldInfo['field_loggeable'] == 1) {
523
                */
524
                if (false) {
525
                    global $app;
526
                    switch ($this->type) {
527
                        case 'question':
528
                            $extraFieldValue = new ChamiloLMS\Entity\QuestionFieldValues();
529
                            $extraFieldValue->setUserId(api_get_user_id());
530
                            $extraFieldValue->setQuestionId($params[$this->handler_id]);
0 ignored issues
show
Bug Best Practice introduced by
The property handler_id does not exist on ExtraFieldValue. Did you maybe forget to declare it?
Loading history...
531
                            break;
532
                        case 'course':
533
                            $extraFieldValue = new ChamiloLMS\Entity\CourseFieldValues();
534
                            $extraFieldValue->setUserId(api_get_user_id());
535
                            $extraFieldValue->setQuestionId($params[$this->handler_id]);
536
                            break;
537
                        case 'user':
538
                            $extraFieldValue = new ChamiloLMS\Entity\UserFieldValues();
539
                            $extraFieldValue->setUserId($params[$this->handler_id]);
540
                            $extraFieldValue->setAuthorId(api_get_user_id());
541
                            break;
542
                        case 'session':
543
                            $extraFieldValue = new ChamiloLMS\Entity\SessionFieldValues();
544
                            $extraFieldValue->setUserId(api_get_user_id());
545
                            $extraFieldValue->setSessionId($params[$this->handler_id]);
546
                            break;
547
                    }
548
                    if (isset($extraFieldValue)) {
549
                        if (!empty($params['value'])) {
550
                            $extraFieldValue->setComment($params['comment']);
551
                            $extraFieldValue->setFieldValue($params['value']);
552
                            $extraFieldValue->setFieldId($params['field_id']);
553
                            $extraFieldValue->setTms(api_get_utc_datetime(null, false, true));
554
                            $app['orm.ems']['db_write']->persist($extraFieldValue);
555
                            $app['orm.ems']['db_write']->flush();
556
                        }
557
                    }
558
                } else {
559
                    if ($extraFieldInfo['field_type'] == ExtraField::FIELD_TYPE_TAG) {
560
                        $option = new ExtraFieldOption($this->type);
561
                        $optionExists = $option->get($params['value']);
562
                        if (empty($optionExists)) {
563
                            $optionParams = [
564
                                'field_id' => $params['field_id'],
565
                                'option_value' => $params['value'],
566
                            ];
567
                            $optionId = $option->saveOptions($optionParams);
568
                        } else {
569
                            $optionId = $optionExists['id'];
570
                        }
571
572
                        $params['value'] = $optionId;
573
                        if ($optionId) {
574
                            return parent::save($params, $showQuery);
575
                        }
576
                    } else {
577
                        return parent::save($params, $showQuery);
578
                    }
579
                }
580
            } else {
581
                // Update
582
                /* Enable this when field_loggeable is introduced as a table field (2.0)
583
                if ($extraFieldInfo['field_loggeable'] == 1) {
584
                */
585
                if (false) {
586
                    global $app;
587
                    switch ($this->type) {
588
                        case 'question':
589
                            $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\QuestionFieldValues')->find($field_values['id']);
590
                            $extraFieldValue->setUserId(api_get_user_id());
591
                            $extraFieldValue->setQuestionId($params[$this->handler_id]);
592
                            break;
593
                        case 'course':
594
                            $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\CourseFieldValues')->find($field_values['id']);
595
                            $extraFieldValue->setUserId(api_get_user_id());
596
                            $extraFieldValue->setCourseCode($params[$this->handler_id]);
597
                            break;
598
                        case 'user':
599
                            $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\UserFieldValues')->find($field_values['id']);
600
                            $extraFieldValue->setUserId(api_get_user_id());
601
                            $extraFieldValue->setAuthorId(api_get_user_id());
602
                            break;
603
                        case 'session':
604
                            $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\SessionFieldValues')->find($field_values['id']);
605
                            $extraFieldValue->setUserId(api_get_user_id());
606
                            $extraFieldValue->setSessionId($params[$this->handler_id]);
607
                            break;
608
                    }
609
610
                    if (isset($extraFieldValue)) {
611
                        if (!empty($params['value'])) {
612
                            /*
613
                             *  If the field value is similar to the previous value then the comment will be the same
614
                                in order to no save in the log an empty record
615
                            */
616
                            if ($extraFieldValue->getFieldValue() == $params['value']) {
617
                                if (empty($params['comment'])) {
618
                                    $params['comment'] = $extraFieldValue->getComment();
619
                                }
620
                            }
621
622
                            $extraFieldValue->setComment($params['comment']);
623
                            $extraFieldValue->setFieldValue($params['value']);
624
                            $extraFieldValue->setFieldId($params['field_id']);
625
                            $extraFieldValue->setTms(api_get_utc_datetime(null, false, true));
626
                            $app['orm.ems']['db_write']->persist($extraFieldValue);
627
                            $app['orm.ems']['db_write']->flush();
628
                        }
629
                    }
630
                } else {
631
                    $params['id'] = $field_values['id'];
632
633
                    return parent::update($params, $showQuery);
634
                }
635
            }
636
        }
637
    }
638
639
    /**
640
     * Returns the value of the given extra field on the given resource.
641
     *
642
     * @param int  $item_id   Item ID (It could be a session_id, course_id or user_id)
643
     * @param int  $field_id  Field ID (the ID from the *_field table)
644
     * @param bool $transform Whether to transform the result to a human readable strings
645
     *
646
     * @return mixed A structured array with the field_id and field_value, or false on error
647
     * @assert (-1,-1) === false
648
     */
649
    public function get_values_by_handler_and_field_id($item_id, $field_id, $transform = false)
650
    {
651
        $field_id = (int) $field_id;
652
        $item_id = Database::escape_string($item_id);
653
654
        $sql = "SELECT s.*, field_type FROM {$this->table} s
655
                INNER JOIN {$this->table_handler_field} sf ON (s.field_id = sf.id)
656
                WHERE
657
                    item_id = '$item_id' AND
658
                    field_id = '".$field_id."' AND
659
                    sf.extra_field_type = ".$this->getExtraField()->getExtraFieldType()."
660
                ORDER BY id";
661
        $result = Database::query($sql);
662
        if (Database::num_rows($result)) {
663
            $result = Database::fetch_array($result, 'ASSOC');
664
            if ($transform) {
665
                if (!empty($result['value'])) {
666
                    switch ($result['field_type']) {
667
                        case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
668
                            $field_option = new ExtraFieldOption($this->type);
669
                            $options = explode('::', $result['value']);
670
                            // only available for PHP 5.4  :( $result['field_value'] = $field_option->get($options[0])['id'].' -> ';
671
                            $result = $field_option->get($options[0]);
672
                            $result_second = $field_option->get($options[1]);
673
                            if (!empty($result)) {
674
                                $result['value'] = $result['display_text'].' -> ';
675
                                $result['value'] .= $result_second['display_text'];
676
                            }
677
                            break;
678
                        case ExtraField::FIELD_TYPE_SELECT:
679
                            $field_option = new ExtraFieldOption($this->type);
680
                            $extra_field_option_result = $field_option->get_field_option_by_field_and_option(
681
                                $result['field_id'],
682
                                $result['value']
683
                            );
684
685
                            if (isset($extra_field_option_result[0])) {
686
                                $result['value'] = $extra_field_option_result[0]['display_text'];
687
                            }
688
                            break;
689
                        case ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
690
                            $options = explode('::', $result['value']);
691
692
                            $field_option = new ExtraFieldOption($this->type);
693
                            $result = $field_option->get($options[0]);
694
695
                            if (!empty($result)) {
696
                                $result['value'] = $result['display_text']
697
                                    .'&rarr;'
698
                                    .$options[1];
699
                            }
700
                            break;
701
                        case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
702
                            $optionIds = explode(';', $result['value']);
703
                            $optionValues = [];
704
705
                            foreach ($optionIds as $optionId) {
706
                                $objEfOption = new ExtraFieldOption('user');
707
                                $optionInfo = $objEfOption->get($optionId);
708
709
                                $optionValues[] = $optionInfo['display_text'];
710
                            }
711
712
                            $result['value'] = implode(' / ', $optionValues);
713
                            break;
714
                    }
715
                }
716
            }
717
718
            return $result;
719
        }
720
721
        return false;
722
    }
723
724
    /**
725
     * @param string $tag
726
     * @param int    $field_id
727
     * @param int    $limit
728
     *
729
     * @return array
730
     */
731
    public function searchValuesByField($tag, $field_id, $limit = 10)
732
    {
733
        $field_id = (int) $field_id;
734
        $limit = (int) $limit;
735
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
736
737
        $tag = Database::escape_string($tag);
738
        $sql = "SELECT DISTINCT s.value, s.field_id
739
                FROM {$this->table} s
740
                INNER JOIN {$this->table_handler_field} sf
741
                ON (s.field_id = sf.id)
742
                WHERE
743
                    field_id = '".$field_id."' AND
744
                    value LIKE '%$tag%' AND
745
                    sf.extra_field_type = ".$extraFieldType."
746
                ORDER BY value
747
                LIMIT 0, $limit
748
                ";
749
        $result = Database::query($sql);
750
        $values = [];
751
        if (Database::num_rows($result)) {
752
            $values = Database::store_result($result, 'ASSOC');
753
        }
754
755
        return $values;
756
    }
757
758
    /**
759
     * Gets a structured array of the original item and its extra values, using
760
     * a specific original item and a field name (like "branch", or "birthdate").
761
     *
762
     * @param int    $item_id            Item ID from the original table
763
     * @param string $field_variable     The name of the field we are looking for
764
     * @param bool   $transform
765
     * @param bool   $filterByVisibility
766
     * @param int    $visibility
767
     *
768
     * @return mixed Array of results, or false on error or not found
769
     * @assert (-1,'') === false
770
     */
771
    public function get_values_by_handler_and_field_variable(
772
        $item_id,
773
        $field_variable,
774
        $transform = false,
775
        $filterByVisibility = false,
776
        $visibility = 0
777
    ) {
778
        $item_id = (int) $item_id;
779
        $field_variable = Database::escape_string($field_variable);
780
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
781
782
        $sql = "SELECT s.*, field_type
783
                FROM {$this->table} s
784
                INNER JOIN {$this->table_handler_field} sf
785
                ON (s.field_id = sf.id)
786
                WHERE
787
                    item_id = '$item_id'  AND
788
                    variable = '".$field_variable."' AND
789
                    sf.extra_field_type = $extraFieldType
790
                ";
791
        if ($filterByVisibility) {
792
            $visibility = (int) $visibility;
793
            $sql .= " AND visible_to_self = $visibility ";
794
        }
795
        $sql .= ' ORDER BY id';
796
797
        $result = Database::query($sql);
798
        if (Database::num_rows($result)) {
799
            $result = Database::fetch_array($result, 'ASSOC');
800
            if ($transform) {
801
                if ($result['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
802
                    if (!empty($result['value'])) {
803
                        $field_option = new ExtraFieldOption($this->type);
804
                        $options = explode('::', $result['value']);
805
                        $result = $field_option->get($options[0]);
806
                        $result_second = $field_option->get($options[1]);
807
                        if (!empty($result)) {
808
                            $result['value'] = $result['display_text'].' -> ';
809
                            $result['value'] .= $result_second['display_text'];
810
                        }
811
                    }
812
                }
813
                if ($result['field_type'] == ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD) {
814
                    if (!empty($result['value'])) {
815
                        $options = explode('::', $result['value']);
816
817
                        $field_option = new ExtraFieldOption($this->type);
818
                        $result = $field_option->get($options[0]);
819
820
                        if (!empty($result)) {
821
                            $result['value'] = $result['display_text']
822
                                .'&rarr;'
823
                                .$options[1];
824
                        }
825
                    }
826
                }
827
                if ($result['field_type'] == ExtraField::FIELD_TYPE_TRIPLE_SELECT) {
828
                    if (!empty($result['value'])) {
829
                        $optionIds = explode(';', $result['value']);
830
                        $optionValues = [];
831
832
                        foreach ($optionIds as $optionId) {
833
                            $objEfOption = new ExtraFieldOption('user');
834
                            $optionInfo = $objEfOption->get($optionId);
835
836
                            $optionValues[] = $optionInfo['display_text'];
837
                        }
838
839
                        $result['value'] = implode(' / ', $optionValues);
840
                    }
841
                }
842
            }
843
844
            return $result;
845
        }
846
847
        return false;
848
    }
849
850
    /**
851
     * Gets the ID from the item (course, session, etc) for which
852
     * the given field is defined with the given value.
853
     *
854
     * Example:
855
     * <code>
856
     * <?php
857
     * $extraFieldValueUser = new ExtraFieldValue('user');
858
     * $arrayExtraFieldValueUser =  $extraFieldValueUser->get_item_id_from_field_variable_and_field_value(
859
     * 'variable',
860
     * 1,
861
     * true,
862
     * false,
863
     * true);
864
     * echo "<pre>".var_export($arrayExtraFieldValueUser,true)."</pre>";
865
     * ?>
866
     * </code>
867
     *
868
     * @param string $variable  Field (type of data) we want to check
869
     * @param string $value     Data we are looking for in the given field
870
     * @param bool   $transform Whether to transform the result to a human readable strings
871
     * @param bool   $last      Whether to return the last element or simply the first one we get
872
     * @param bool   $useLike
873
     *
874
     * @return mixed Give the ID if found, or false on failure or not found
875
     * @assert (-1,-1) === false
876
     */
877
    public function get_item_id_from_field_variable_and_field_value(
878
        $variable,
879
        $value,
880
        $transform = false,
881
        $last = false,
882
        $all = false,
883
        $useLike = false
884
    ) {
885
        $value = Database::escape_string($value);
886
        $variable = Database::escape_string($variable);
887
888
        $valueCondition = " value  = '$value' AND ";
889
        if ($useLike) {
890
            $valueCondition = " value LIKE '%".$value."%' AND ";
891
        }
892
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
893
894
        $sql = "SELECT item_id FROM {$this->table} s
895
                INNER JOIN {$this->table_handler_field} sf
896
                ON (s.field_id = sf.id)
897
                WHERE
898
                    $valueCondition
899
                    variable = '".$variable."' AND
900
                    sf.extra_field_type = $extraFieldType
901
                ORDER BY item_id
902
                ";
903
904
        if ($last) {
905
            // If we want the last element instead of the first
906
            // This is useful in special cases where there might
907
            // (erroneously) be more than one row for an item
908
            $sql .= ' DESC';
909
        }
910
        $result = Database::query($sql);
911
        if ($result !== false && Database::num_rows($result)) {
912
            if ($all) {
913
                $result = Database::store_result($result, 'ASSOC');
914
            } else {
915
                $result = Database::fetch_array($result, 'ASSOC');
916
            }
917
918
            return $result;
919
        }
920
921
        return false;
922
    }
923
924
    /**
925
     * Get all the values stored for one specific field.
926
     *
927
     * @param int $fieldId
928
     *
929
     * @return array|bool
930
     */
931
    public function getValuesByFieldId($fieldId)
932
    {
933
        $fieldId = (int) $fieldId;
934
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
935
936
        $sql = "SELECT s.* FROM {$this->table} s
937
                INNER JOIN {$this->table_handler_field} sf
938
                ON (s.field_id = sf.id)
939
                WHERE
940
                    field_id = '".$fieldId."' AND
941
                    sf.extra_field_type = $extraFieldType
942
                ORDER BY s.value";
943
        $result = Database::query($sql);
944
945
        if (Database::num_rows($result)) {
946
            return Database::store_result($result, 'ASSOC');
947
        }
948
949
        return false;
950
    }
951
952
    /**
953
     * @param int $itemId
954
     * @param int $fieldId
955
     *
956
     * @return array
957
     */
958
    public function getAllValuesByItemAndField($itemId, $fieldId)
959
    {
960
        $fieldId = (int) $fieldId;
961
        $itemId = (int) $itemId;
962
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
963
964
        $sql = "SELECT s.* FROM {$this->table} s
965
                INNER JOIN {$this->table_handler_field} sf
966
                ON (s.field_id = sf.id)
967
                WHERE
968
                    field_id = $fieldId AND
969
                    item_id = $itemId AND
970
                    sf.extra_field_type = $extraFieldType
971
                ORDER BY s.value";
972
        $result = Database::query($sql);
973
974
        if (Database::num_rows($result)) {
975
            return Database::store_result($result, 'ASSOC');
976
        }
977
978
        return false;
979
    }
980
981
    /**
982
     * @param int $itemId
983
     *
984
     * @return array
985
     */
986
    public function getAllValuesByItem($itemId)
987
    {
988
        $itemId = (int) $itemId;
989
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
990
991
        $sql = "SELECT s.value, sf.variable, sf.field_type, sf.id, sf.display_text
992
                FROM {$this->table} s
993
                INNER JOIN {$this->table_handler_field} sf
994
                ON (s.field_id = sf.id)
995
                WHERE
996
                    item_id = '$itemId' AND
997
                    sf.extra_field_type = $extraFieldType
998
                ORDER BY s.value";
999
1000
        $result = Database::query($sql);
1001
        $idList = [];
1002
        if (Database::num_rows($result)) {
1003
            $result = Database::store_result($result, 'ASSOC');
1004
            $finalResult = [];
1005
            foreach ($result as $item) {
1006
                $finalResult[$item['id']] = $item;
1007
            }
1008
            $idList = array_column($result, 'id');
1009
        }
1010
1011
        $em = Database::getManager();
1012
1013
        $extraField = new ExtraField($this->type);
1014
        $allData = $extraField->get_all(['filter = ?' => 1]);
1015
        $allResults = [];
1016
        foreach ($allData as $field) {
1017
            if (in_array($field['id'], $idList)) {
1018
                $allResults[] = $finalResult[$field['id']];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $finalResult does not seem to be defined for all execution paths leading up to this point.
Loading history...
1019
            } else {
1020
                if ($field['field_type'] == ExtraField::FIELD_TYPE_TAG) {
1021
                    $tagResult = [];
1022
                    $tags = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
1023
                        ->findBy(
1024
                            [
1025
                                'fieldId' => $field['id'],
1026
                                'itemId' => $itemId,
1027
                            ]
1028
                        );
1029
                    if ($tags) {
1030
                        /** @var ExtraFieldRelTag $extraFieldTag */
1031
                        foreach ($tags as $extraFieldTag) {
1032
                            /** @var \Chamilo\CoreBundle\Entity\Tag $tag */
1033
                            $tag = $em->find('ChamiloCoreBundle:Tag', $extraFieldTag->getTagId());
1034
                            $tagResult[] = [
1035
                                'id' => $extraFieldTag->getTagId(),
1036
                                'value' => $tag->getTag(),
1037
                            ];
1038
                        }
1039
                    }
1040
                    $allResults[] = [
1041
                        'value' => $tagResult,
1042
                        'variable' => $field['variable'],
1043
                        'field_type' => $field['field_type'],
1044
                        'id' => $field['id'],
1045
                    ];
1046
                }
1047
            }
1048
        }
1049
1050
        return $allResults;
1051
    }
1052
1053
    /**
1054
     * @param int    $itemId
1055
     * @param int    $fieldId
1056
     * @param string $fieldValue
1057
     *
1058
     * @return array|bool
1059
     */
1060
    public function getAllValuesByItemAndFieldAndValue($itemId, $fieldId, $fieldValue)
1061
    {
1062
        $fieldId = (int) $fieldId;
1063
        $itemId = (int) $itemId;
1064
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
1065
1066
        $fieldValue = Database::escape_string($fieldValue);
1067
        $sql = "SELECT s.* FROM {$this->table} s
1068
                INNER JOIN {$this->table_handler_field} sf
1069
                ON (s.field_id = sf.id)
1070
                WHERE
1071
                    field_id = '$fieldId' AND
1072
                    item_id = '$itemId' AND
1073
                    value = '$fieldValue' AND
1074
                    sf.extra_field_type = $extraFieldType
1075
                ORDER BY value";
1076
1077
        $result = Database::query($sql);
1078
        if (Database::num_rows($result)) {
1079
            return Database::store_result($result, 'ASSOC');
1080
        }
1081
1082
        return false;
1083
    }
1084
1085
    /**
1086
     * Deletes all the values related to a specific field ID.
1087
     *
1088
     * @param int $field_id
1089
     *
1090
     * @assert ('a') == null
1091
     */
1092
    public function delete_all_values_by_field_id($field_id)
1093
    {
1094
        $field_id = (int) $field_id;
1095
        $sql = "DELETE FROM {$this->table}
1096
                WHERE
1097
                    field_id = $field_id ";
1098
        Database::query($sql);
1099
    }
1100
1101
    /**
1102
     * Deletes all values from an item.
1103
     *
1104
     * @param int $itemId (session id, course id, etc)
1105
     * @assert (-1,-1) == null
1106
     */
1107
    public function deleteValuesByItem($itemId)
1108
    {
1109
        $itemId = (int) $itemId;
1110
        $extraFieldType = $this->getExtraField()->getExtraFieldType();
1111
1112
        $sql = "DELETE FROM {$this->table}
1113
                WHERE
1114
                    item_id = '$itemId' AND
1115
                    field_id IN (
1116
                        SELECT id FROM {$this->table_handler_field}
1117
                        WHERE extra_field_type = ".$extraFieldType."
1118
                    )
1119
                ";
1120
        Database::query($sql);
1121
    }
1122
1123
    /**
1124
     * @param int $itemId
1125
     * @param int $fieldId
1126
     * @param int $fieldValue
1127
     *
1128
     * @return bool
1129
     */
1130
    public function deleteValuesByHandlerAndFieldAndValue($itemId, $fieldId, $fieldValue)
1131
    {
1132
        $itemId = (int) $itemId;
1133
        $fieldId = (int) $fieldId;
1134
1135
        $fieldData = $this->getExtraField()->get($fieldId);
1136
        if ($fieldData) {
1137
            $fieldValue = Database::escape_string($fieldValue);
1138
1139
            $sql = "DELETE FROM {$this->table}
1140
                WHERE
1141
                    item_id = '$itemId' AND
1142
                    field_id = '$fieldId' AND
1143
                    value = '$fieldValue'
1144
                ";
1145
            Database::query($sql);
1146
1147
            // Delete file from uploads
1148
            if ($fieldData['field_type'] == ExtraField::FIELD_TYPE_FILE) {
1149
                api_remove_uploaded_file($this->type, basename($fieldValue));
1150
            }
1151
1152
            return true;
1153
        }
1154
1155
        return false;
1156
    }
1157
1158
    /**
1159
     * Get all values for an item.
1160
     *
1161
     * @param int  $itemId          The item ID
1162
     * @param bool $visibleToSelf   Get the visible extra field only
1163
     * @param bool $visibleToOthers
1164
     *
1165
     * @return array
1166
     */
1167
    public function getAllValuesForAnItem($itemId, $visibleToSelf = null, $visibleToOthers = null)
1168
    {
1169
        $em = Database::getManager();
1170
        $qb = $em->createQueryBuilder();
1171
        $qb = $qb->select('fv')
1172
            ->from('ChamiloCoreBundle:ExtraFieldValues', 'fv')
1173
            ->join('fv.field', 'f')
1174
            ->where(
1175
                $qb->expr()->eq('fv.itemId', ':item')
1176
            )
1177
            ->andWhere(
1178
                $qb->expr()->eq('f.extraFieldType', ':extra_field_type')
1179
            );
1180
1181
        if (is_bool($visibleToSelf)) {
1182
            $qb
1183
                ->andWhere($qb->expr()->eq('f.visibleToSelf', ':visibleToSelf'))
1184
                ->setParameter('visibleToSelf', $visibleToSelf);
1185
        }
1186
1187
        if (is_bool($visibleToOthers)) {
1188
            $qb
1189
                ->andWhere($qb->expr()->eq('f.visibleToOthers', ':visibleToOthers'))
1190
                ->setParameter('visibleToOthers', $visibleToOthers);
1191
        }
1192
1193
        $fieldValues = $qb
1194
            ->setParameter('item', $itemId)
1195
            ->setParameter('extra_field_type', $this->getExtraField()->getExtraFieldType())
1196
            ->getQuery()
1197
            ->getResult();
1198
1199
        $fieldOptionsRepo = $em->getRepository('ChamiloCoreBundle:ExtraFieldOptions');
1200
1201
        $valueList = [];
1202
        /** @var ExtraFieldValues $fieldValue */
1203
        foreach ($fieldValues as $fieldValue) {
1204
            $item = ['value' => $fieldValue];
1205
            switch ($fieldValue->getField()->getFieldType()) {
1206
                case ExtraField::FIELD_TYPE_SELECT:
1207
                    $item['option'] = $fieldOptionsRepo->findOneBy([
1208
                        'field' => $fieldValue->getField(),
1209
                        'value' => $fieldValue->getValue(),
1210
                    ]);
1211
                    break;
1212
            }
1213
            $valueList[] = $item;
1214
        }
1215
1216
        return $valueList;
1217
    }
1218
1219
    public function copy($sourceId, $destinationId)
1220
    {
1221
        if (empty($sourceId) || empty($destinationId)) {
1222
            return false;
1223
        }
1224
1225
        $extraField = new ExtraField($this->type);
1226
        $allFields = $extraField->get_all();
1227
        $extraFieldValue = new ExtraFieldValue($this->type);
1228
        foreach ($allFields as $field) {
1229
            $variable = $field['variable'];
1230
            $sourceValues = $extraFieldValue->get_values_by_handler_and_field_variable($sourceId, $variable);
1231
            if (!empty($sourceValues) && isset($sourceValues['value']) && $sourceValues['value'] != '') {
1232
                $params = [
1233
                    'extra_'.$variable => $sourceValues['value'],
1234
                    'item_id' => $destinationId
1235
                ];
1236
                $extraFieldValue->saveFieldValues($params, true);
1237
            }
1238
        }
1239
1240
        return true;
1241
    }
1242
}
1243