Issues (2160)

main/badge/assign.php (3 issues)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\Skill;
0 ignored issues
show
This use statement conflicts with another class in this namespace, Skill. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
5
use Skill as SkillManager;
6
use Symfony\Component\HttpFoundation\Request as HttpRequest;
0 ignored issues
show
This use statement conflicts with another class in this namespace, HttpRequest. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
8
/**
9
 * Page for assign skills to a user.
10
 *
11
 * @author: Jose Loguercio <[email protected]>
12
 */
13
require_once __DIR__.'/../inc/global.inc.php';
14
15
$httpRequest = HttpRequest::createFromGlobals();
16
17
$userId = $httpRequest->query->getInt(
18
    'user',
19
    $httpRequest->request->getInt('user')
20
);
21
22
if (empty($userId)) {
23
    api_not_allowed(true);
24
}
25
26
SkillManager::isAllowed($userId);
27
28
$user = api_get_user_entity($userId);
29
30
if (!$user) {
0 ignored issues
show
$user is of type Chamilo\UserBundle\Entity\User, thus it always evaluated to true.
Loading history...
31
    api_not_allowed(true);
32
}
33
34
$entityManager = Database::getManager();
35
$skillManager = new SkillManager();
36
$skillRepo = $entityManager->getRepository('ChamiloCoreBundle:Skill');
37
$skillRelSkill = $entityManager->getRepository('ChamiloCoreBundle:SkillRelSkill');
38
$skillLevelRepo = $entityManager->getRepository('ChamiloSkillBundle:Level');
39
$skillUserRepo = $entityManager->getRepository('ChamiloCoreBundle:SkillRelUser');
40
41
$skillLevels = api_get_configuration_value('skill_levels_names');
42
43
$skillsOptions = ['' => get_lang('Select')];
44
$acquiredLevel = ['' => get_lang('None')];
45
$formDefaultValues = [];
46
47
if (empty($skillLevels)) {
48
    $skills = $skillRepo->findBy([
49
        'status' => Skill::STATUS_ENABLED,
50
    ]);
51
    /** @var Skill $skill */
52
    foreach ($skills as $skill) {
53
        $skillsOptions[$skill->getId()] = $skill->getName();
54
    }
55
} else {
56
    // Get only root elements
57
    $skills = $skillManager->getChildren(1);
58
    foreach ($skills as $skill) {
59
        $skillsOptions[$skill['data']['id']] = $skill['data']['name'];
60
    }
61
}
62
$skillIdFromGet = $httpRequest->query->getInt(
63
    'id',
64
    $httpRequest->request->getInt('id')
65
);
66
$currentValue = $httpRequest->query->getInt(
67
    'current_value',
68
    $httpRequest->request->getInt('current_value')
69
);
70
$currentLevel = $httpRequest->query->get(
71
    'current',
72
    $httpRequest->request->get('current', '')
73
);
74
$currentLevel = (int) str_replace('sub_skill_id_', '', $currentLevel);
75
76
$subSkillList = $httpRequest->query->get(
77
    'sub_skill_list',
78
    $httpRequest->request->get('sub_skill_list', '')
79
);
80
$subSkillList = explode(',', $subSkillList);
81
$subSkillList = array_unique($subSkillList);
82
83
if (!empty($subSkillList)) {
84
    // Compare asked skill with current level
85
    $correctLevel = false;
86
    if (isset($subSkillList[$currentLevel]) && $subSkillList[$currentLevel] == $currentValue) {
87
        $correctLevel = true;
88
    }
89
90
    // Level is wrong probably user change the level. Fix the subSkillList array
91
    if (!$correctLevel) {
92
        $newSubSkillList = [];
93
        $counter = 0;
94
        foreach ($subSkillList as $subSkillId) {
95
            if ($counter == $currentLevel) {
96
                $subSkillId = $currentValue;
97
            }
98
            $newSubSkillList[$counter] = $subSkillId;
99
            if ($counter == $currentLevel) {
100
                break;
101
            }
102
            $counter++;
103
        }
104
        $subSkillList = $newSubSkillList;
105
    }
106
}
107
108
if (!empty($currentLevel)) {
109
    $level = $currentLevel + 1;
110
    if ($level < count($subSkillList)) {
111
        $remove = count($subSkillList) - $currentLevel;
112
        $newSubSkillList = array_slice($subSkillList, 0, count($subSkillList) - $level);
113
        $subSkillList = $newSubSkillList;
114
    }
115
}
116
117
$skillId = $httpRequest->query->getInt(
118
    'id',
119
    $httpRequest->request->getInt('id', key($skillsOptions))
120
);
121
$skill = $skillRepo->find($skillId);
122
$profile = false;
123
if ($skill) {
124
    $profile = $skill->getProfile();
125
}
126
127
if (!empty($subSkillList)) {
128
    $skillFromLastSkill = $skillRepo->find(end($subSkillList));
129
    if ($skillFromLastSkill) {
130
        $profile = $skillFromLastSkill->getProfile();
131
    }
132
}
133
134
if (!$profile) {
135
    $skillRelSkill = new SkillRelSkill();
136
    $parents = $skillRelSkill->getSkillParents($skillId);
137
    krsort($parents);
138
    foreach ($parents as $parent) {
139
        $skillParentId = $parent['skill_id'];
140
        $profile = $skillRepo->find($skillParentId)->getProfile();
141
142
        if ($profile) {
143
            break;
144
        }
145
146
        if (!$profile && $parent['parent_id'] == 0) {
147
            $profile = $skillLevelRepo->findAll();
148
            $profile = isset($profile[0]) ? $profile[0] : false;
149
        }
150
    }
151
}
152
153
if ($profile) {
154
    $profileId = $profile->getId();
155
    $levels = $skillLevelRepo->findBy([
156
        'profile' => $profileId,
157
    ]);
158
    $profileLevels = [];
159
    foreach ($levels as $level) {
160
        $profileLevels[$level->getPosition()][$level->getId()] = $level->getName();
161
    }
162
163
    ksort($profileLevels); // Sort the array by Position.
164
165
    foreach ($profileLevels as $profileLevel) {
166
        $profileId = key($profileLevel);
167
        $acquiredLevel[$profileId] = $profileLevel[$profileId];
168
    }
169
}
170
171
$formDefaultValues = ['skill' => $skillId];
172
$newSubSkillList = [];
173
$disableList = [];
174
175
$currentUrl = api_get_self().'?user='.$userId.'&current='.$currentLevel;
176
177
$form = new FormValidator('assign_skill', 'POST', $currentUrl);
178
$form->addHeader(get_lang('AssignSkill'));
179
$form->addText('user_name', get_lang('UserName'), false);
180
181
$levelName = get_lang('Skill');
182
if (!empty($skillLevels)) {
183
    if (isset($skillLevels['levels'][1])) {
184
        $levelName = get_lang($skillLevels['levels'][1]);
185
    }
186
}
187
188
$form->addSelect('skill', $levelName, $skillsOptions, ['id' => 'skill']);
189
190
if (!empty($skillIdFromGet)) {
191
    if (empty($subSkillList)) {
192
        $subSkillList[] = $skillIdFromGet;
193
    }
194
    $oldSkill = $skillRepo->find($skillIdFromGet);
195
    $counter = 0;
196
    foreach ($subSkillList as $subSkillId) {
197
        $children = $skillManager->getChildren($subSkillId);
198
199
        if (isset($subSkillList[$counter - 1])) {
200
            $oldSkill = $skillRepo->find($subSkillList[$counter]);
201
        }
202
        $skillsOptions = [];
203
        if ($oldSkill) {
204
            $skillsOptions = [$oldSkill->getId() => ' -- '.$oldSkill->getName()];
205
        }
206
207
        if ($counter < count($subSkillList) - 1) {
208
            $disableList[] = 'sub_skill_id_'.($counter + 1);
209
        }
210
211
        foreach ($children as $child) {
212
            $skillsOptions[$child['id']] = $child['data']['name'];
213
        }
214
215
        $levelName = get_lang('SubSkill');
216
        if (!empty($skillLevels)) {
217
            if (isset($skillLevels['levels'][$counter + 2])) {
218
                $levelName = get_lang($skillLevels['levels'][$counter + 2]);
219
            }
220
        }
221
222
        $form->addSelect(
223
            'sub_skill_id_'.($counter + 1),
224
            $levelName,
225
            $skillsOptions,
226
            [
227
                'id' => 'sub_skill_id_'.($counter + 1),
228
                'class' => 'sub_skill',
229
            ]
230
        );
231
232
        if (isset($subSkillList[$counter + 1])) {
233
            $nextSkill = $skillRepo->find($subSkillList[$counter + 1]);
234
            if ($nextSkill) {
235
                $formDefaultValues['sub_skill_id_'.($counter + 1)] = $nextSkill->getId();
236
            }
237
        }
238
        $newSubSkillList[] = $subSkillId;
239
        $counter++;
240
    }
241
    $subSkillList = $newSubSkillList;
242
}
243
244
$subSkillListToString = implode(',', $subSkillList);
245
246
$currentUrl = api_get_self().'?user='.$userId.'&current='.$currentLevel.'&sub_skill_list='.$subSkillListToString;
247
248
$form->addHidden('sub_skill_list', $subSkillListToString);
249
$form->addHidden('user', $user->getId());
250
$form->addHidden('id', $skillId);
251
$form->addRule('skill', get_lang('ThisFieldIsRequired'), 'required');
252
253
$showLevels = api_get_configuration_value('hide_skill_levels') === false;
254
255
if ($showLevels) {
256
    $form->addSelect('acquired_level', get_lang('AcquiredLevel'), $acquiredLevel);
257
    //$form->addRule('acquired_level', get_lang('ThisFieldIsRequired'), 'required');
258
}
259
260
$form->addTextarea('argumentation', get_lang('Argumentation'), ['rows' => 6], true);
261
$form->addRule(
262
    'argumentation',
263
    sprintf(get_lang('ThisTextShouldBeAtLeastXCharsLong'), 10),
264
    'mintext',
265
    10
266
);
267
$form->applyFilter('argumentation', 'trim');
268
$form->applyFilter('argumentation', 'html_filter');
269
$form->addButtonSave(get_lang('Save'));
270
$form->setDefaults($formDefaultValues);
271
272
if ($form->validate()) {
273
    $values = $form->exportValues();
274
    $skillToProcess = $values['id'];
275
    if (!empty($subSkillList)) {
276
        $counter = 1;
277
        foreach ($subSkillList as $subSkill) {
278
            if (isset($values["sub_skill_id_$counter"])) {
279
                $skillToProcess = $values["sub_skill_id_$counter"];
280
            }
281
            $counter++;
282
        }
283
    }
284
    $skill = $skillRepo->find($skillToProcess);
285
286
    if (!$skill) {
287
        Display::addFlash(
288
            Display::return_message(get_lang('SkillNotFound'), 'error')
289
        );
290
291
        header('Location: '.api_get_self().'?'.$currentUrl);
292
        exit;
293
    }
294
295
    if ($user->hasSkill($skill)) {
296
        Display::addFlash(
297
            Display::return_message(
298
                sprintf(
299
                    get_lang('TheUserXHasAlreadyAchievedTheSkillY'),
300
                    UserManager::formatUserFullName($user),
301
                    $skill->getName()
302
                ),
303
                'warning'
304
            )
305
        );
306
307
        header('Location: '.$currentUrl);
308
        exit;
309
    }
310
311
    $skillUser = $skillManager->addSkillToUserBadge(
312
        $user,
313
        $skill,
314
        $values['acquired_level'],
315
        $values['argumentation'],
316
        api_get_user_id()
317
    );
318
319
    // Send email depending of children_auto_threshold
320
    $skillRelSkill = new SkillRelSkill();
321
    $skillModel = new \Skill();
322
    $parents = $skillModel->getDirectParents($skillToProcess);
323
324
    $extraFieldValue = new ExtraFieldValue('skill');
325
    foreach ($parents as $parentInfo) {
326
        $parentId = $parentInfo['skill_id'];
327
        $parentData = $skillModel->get($parentId);
328
329
        $data = $extraFieldValue->get_values_by_handler_and_field_variable($parentId, 'children_auto_threshold');
330
        if (!empty($data) && !empty($data['value'])) {
331
            // Search X children
332
            $requiredSkills = $data['value'];
333
            $children = $skillRelSkill->getChildren($parentId);
334
            $counter = 0;
335
            foreach ($children as $child) {
336
                if ($skillModel->userHasSkill($userId, $child['id'])) {
337
                    $counter++;
338
                }
339
            }
340
341
            if ($counter >= $requiredSkills) {
342
                $bossList = UserManager::getStudentBossList($userId);
343
                if (!empty($bossList)) {
344
                    Display::addFlash(Display::return_message(get_lang('MessageSent')));
345
                    $url = api_get_path(WEB_CODE_PATH).'badge/assign.php?user='.$userId.'&id='.$parentId;
346
                    $link = Display::url($url, $url);
347
                    $subject = get_lang('StudentHadEnoughSkills');
348
                    $message = sprintf(
349
                        get_lang('StudentXHadEnoughSkillsToGetSkillXToAssignClickHereX'),
350
                        UserManager::formatUserFullName($user),
351
                        $parentData['name'],
352
                        $link
353
                    );
354
                    foreach ($bossList as $boss) {
355
                        MessageManager::send_message_simple(
356
                            $boss['boss_id'],
357
                            $subject,
358
                            $message
359
                        );
360
                    }
361
                }
362
                break;
363
            }
364
        }
365
    }
366
367
    Display::addFlash(
368
        Display::return_message(
369
            sprintf(
370
                get_lang('SkillXAssignedToUserY'),
371
                $skill->getName(),
372
                UserManager::formatUserFullName($user)
373
            ),
374
            'success'
375
        )
376
    );
377
378
    Display::addFlash(
379
        Display::return_message(
380
            sprintf(
381
                get_lang('ToAssignNewSkillToUserClickLinkX'),
382
                api_get_self().'?'.http_build_query(['user' => $user->getId()])
383
            ),
384
            'info',
385
            false
386
        )
387
    );
388
389
    header('Location: '.api_get_path(WEB_PATH)."badge/{$skillUser->getId()}");
390
    exit;
391
}
392
393
$form->setDefaults(['user_name' => UserManager::formatUserFullName($user, true)]);
394
$form->freeze(['user_name']);
395
396
if (api_is_drh()) {
397
    $interbreadcrumb[] = [
398
        'url' => api_get_path(WEB_CODE_PATH).'mySpace/index.php',
399
        "name" => get_lang('MySpace'),
400
    ];
401
    if ($user->getStatus() == COURSEMANAGER) {
402
        $interbreadcrumb[] = [
403
            "url" => api_get_path(WEB_CODE_PATH).'mySpace/teachers.php',
404
            'name' => get_lang('Teachers'),
405
        ];
406
    } else {
407
        $interbreadcrumb[] = [
408
            "url" => api_get_path(WEB_CODE_PATH).'mySpace/student.php',
409
            'name' => get_lang('MyStudents'),
410
        ];
411
    }
412
    $interbreadcrumb[] = [
413
        'url' => api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$userId,
414
        'name' => UserManager::formatUserFullName($user),
415
    ];
416
} else {
417
    $interbreadcrumb[] = [
418
        'url' => api_get_path(WEB_CODE_PATH).'admin/index.php',
419
        'name' => get_lang('PlatformAdmin'),
420
    ];
421
    $interbreadcrumb[] = [
422
        'url' => api_get_path(WEB_CODE_PATH).'admin/user_list.php',
423
        'name' => get_lang('UserList'),
424
    ];
425
    $interbreadcrumb[] = [
426
        'url' => api_get_path(WEB_CODE_PATH).'admin/user_information.php?user_id='.$userId,
427
        'name' => UserManager::formatUserFullName($user),
428
    ];
429
}
430
431
$url = api_get_path(WEB_CODE_PATH).'badge/assign.php?user='.$userId;
432
433
$disableSelect = '';
434
if ($disableList) {
435
    foreach ($disableList as $name) {
436
        //$disableSelect .= "$('#".$name."').prop('disabled', true);";
437
        //$disableSelect .= "$('#".$name."').selectpicker('refresh');";
438
    }
439
}
440
441
$htmlHeadXtra[] = '<script>
442
$(function() {
443
    $("#skill").on("change", function() {
444
        $(location).attr("href", "'.$url.'&id="+$(this).val());
445
    });
446
    $(".sub_skill").on("change", function() {
447
        $(location).attr("href", "'.$url.'&id='.$skillIdFromGet.'&current_value="+$(this).val()+"&current="+$(this).attr("id")+"&sub_skill_list='.$subSkillListToString.',"+$(this).val());
448
    });
449
    '.$disableSelect.'
450
});
451
</script>';
452
453
$template = new Template(get_lang('AddSkill'));
454
$template->assign('content', $form->returnForm());
455
$template->display_one_col_template();
456