Passed
Push — preprodparkur ( 0a56be...fd5dc5 )
by Julito
20:13 queued 07:57
created

deleteValuesByHandlerAndFieldAndValue()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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

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

514
                /** @scrutinizer ignore-call */ 
515
                $field_values = self::getAllValuesByItemAndFieldAndValue(
Loading history...
515
                    $params['item_id'],
516
                    $params['field_id'],
517
                    $value
518
                );
519
            } else {
520
                $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

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