Issues (2160)

main/badge/issued.php (16 issues)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\SkillRelUser;
0 ignored issues
show
This use statement conflicts with another class in this namespace, SkillRelUser. 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 Chamilo\CoreBundle\Entity\SkillRelUserComment;
6
use SkillRelUser as SkillRelUserManager;
7
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...
8
9
/**
10
 * Show information about the issued badge.
11
 *
12
 * @author Angel Fernando Quiroz Campos <[email protected]>
13
 * @author José Loguercio Silva <[email protected]>
14
 */
15
require_once __DIR__.'/../inc/global.inc.php';
16
17
$httpRequest = HttpRequest::createFromGlobals();
18
19
$issue = $httpRequest->query->getInt(
20
    'issue',
21
    $httpRequest->request->getInt('issue')
22
);
23
24
if (empty($issue)) {
25
    api_not_allowed(true);
26
}
27
28
$entityManager = Database::getManager();
29
/** @var SkillRelUser $skillIssue */
30
$skillIssue = $entityManager->find('ChamiloCoreBundle:SkillRelUser', $issue);
31
32
if (!$skillIssue) {
0 ignored issues
show
$skillIssue is of type SkillRelUser, thus it always evaluated to true.
Loading history...
33
    Display::addFlash(
34
        Display::return_message(
35
            get_lang('SkillNotFound'),
36
            'warning'
37
        )
38
    );
39
    header('Location: '.api_get_path(WEB_PATH));
40
    exit;
41
}
42
43
$skillRepo = $entityManager->getRepository('ChamiloCoreBundle:Skill');
44
$skillLevelRepo = $entityManager->getRepository('ChamiloSkillBundle:Level');
45
46
$user = $skillIssue->getUser();
0 ignored issues
show
The method getUser() does not exist on SkillRelUser. Did you maybe mean getUserBySkills()? ( Ignorable by Annotation )

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

46
$user = $skillIssue->/** @scrutinizer ignore-call */ getUser();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
47
$skill = $skillIssue->getSkill();
0 ignored issues
show
The method getSkill() does not exist on SkillRelUser. Did you maybe mean getUserSkills()? ( Ignorable by Annotation )

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

47
$skill = $skillIssue->/** @scrutinizer ignore-call */ getSkill();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
48
49
if (!$user || !$skill) {
50
    Display::addFlash(
51
        Display::return_message(get_lang('NoResults'), 'warning')
52
    );
53
54
    header('Location: '.api_get_path(WEB_PATH));
55
    exit;
56
}
57
58
if (!Skill::isToolAvailable()) {
59
    api_not_allowed(true);
60
}
61
62
$showLevels = api_get_configuration_value('hide_skill_levels') === false;
63
64
$skillInfo = [
65
    'id' => $skill->getId(),
66
    'name' => $skill->getName(),
67
    'short_code' => $skill->getShortCode(),
68
    'description' => $skill->getDescription(),
69
    'criteria' => $skill->getCriteria(),
70
    'badge_image' => Skill::getWebIconPath($skill),
71
    'courses' => [],
72
];
73
74
$titleContent = sprintf(get_lang('IHaveObtainedSkillXOnY'), $skillInfo['name'], api_get_setting('siteName'));
75
76
// Open Graph Markup
77
$htmlHeadXtra[] = "
78
    <meta property='og:type' content='article' />
79
    <meta property='og:title' content='".$titleContent."' />
80
    <meta property='og:url' content='".api_get_path(WEB_PATH)."badge/".$issue."' />
81
    <meta property='og:description' content='".$skillInfo['description']."' />
82
    <meta property='og:image' content='".$skillInfo['badge_image']."' />
83
";
84
85
$currentUserId = api_get_user_id();
86
$currentUser = api_get_user_entity($currentUserId);
87
$allowExport = $currentUser ? $currentUser->getId() === $user->getId() : false;
0 ignored issues
show
$currentUser is of type Chamilo\UserBundle\Entity\User, thus it always evaluated to true.
Loading history...
88
89
$allowComment = $currentUser ? Skill::userCanAddFeedbackToUser($currentUser, $user) : false;
0 ignored issues
show
$currentUser is of type Chamilo\UserBundle\Entity\User, thus it always evaluated to true.
Loading history...
90
$skillIssueDate = api_get_local_time($skillIssue->getAcquiredSkillAt());
0 ignored issues
show
The method getAcquiredSkillAt() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

90
$skillIssueDate = api_get_local_time($skillIssue->/** @scrutinizer ignore-call */ getAcquiredSkillAt());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
91
$currentSkillLevel = get_lang('NoLevelAcquiredYet');
92
if ($skillIssue->getAcquiredLevel()) {
0 ignored issues
show
The method getAcquiredLevel() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

92
if ($skillIssue->/** @scrutinizer ignore-call */ getAcquiredLevel()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
    $currentSkillLevel = $skillLevelRepo->find(['id' => $skillIssue->getAcquiredLevel()])->getName();
94
}
95
96
$author = api_get_user_info($skillIssue->getArgumentationAuthorId());
0 ignored issues
show
The method getArgumentationAuthorId() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

96
$author = api_get_user_info($skillIssue->/** @scrutinizer ignore-call */ getArgumentationAuthorId());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
97
$tempDate = DateTime::createFromFormat('Y-m-d H:i:s', $skillIssueDate);
98
$linkedinOrganizationId = api_get_configuration_value('linkedin_organization_id');
99
if (($linkedinOrganizationId === false)) {
100
    $linkedinOrganizationId = null;
101
}
102
103
$skillIssueInfo = [
104
    'id' => $skillIssue->getId(),
0 ignored issues
show
The method getId() does not exist on SkillRelUser. Did you maybe mean get()? ( Ignorable by Annotation )

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

104
    'id' => $skillIssue->/** @scrutinizer ignore-call */ getId(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
105
    'datetime' => api_format_date($skillIssueDate, DATE_TIME_FORMAT_SHORT),
106
    'year' => $tempDate->format('Y'),
107
    'month' => $tempDate->format('m'),
108
    'linkedin_organization_id' => $linkedinOrganizationId,
109
    'acquired_level' => $currentSkillLevel,
110
    'argumentation_author_id' => $skillIssue->getArgumentationAuthorId(),
111
    'argumentation_author_name' => $author['complete_name'],
112
    'argumentation' => Security::remove_XSS($skillIssue->getArgumentation()),
0 ignored issues
show
The method getArgumentation() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

112
    'argumentation' => Security::remove_XSS($skillIssue->/** @scrutinizer ignore-call */ getArgumentation()),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
113
    'source_name' => $skillIssue->getSourceName(),
0 ignored issues
show
The method getSourceName() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

113
    'source_name' => $skillIssue->/** @scrutinizer ignore-call */ getSourceName(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
114
    'user_id' => $skillIssue->getUser()->getId(),
115
    'user_complete_name' => UserManager::formatUserFullName($skillIssue->getUser()),
116
    'skill_id' => $skillIssue->getSkill()->getId(),
117
    'skill_badge_image' => Skill::getWebIconPath($skillIssue->getSkill()),
118
    'skill_name' => $skillIssue->getSkill()->getName(),
119
    'skill_short_code' => $skillIssue->getSkill()->getShortCode(),
120
    'skill_description' => $skillIssue->getSkill()->getDescription(),
121
    'skill_criteria' => $skillIssue->getSkill()->getCriteria(),
122
    'badge_assertion' => SkillRelUserManager::getAssertionUrl($skillIssue),
123
    'comments' => [],
124
    'feedback_average' => $skillIssue->getAverage(),
0 ignored issues
show
The method getAverage() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

124
    'feedback_average' => $skillIssue->/** @scrutinizer ignore-call */ getAverage(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
125
];
126
127
$skillIssueComments = $skillIssue->getComments(true);
0 ignored issues
show
The method getComments() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

127
$skillIssueComments = $skillIssue->/** @scrutinizer ignore-call */ getComments(true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
128
129
$userId = $skillIssueInfo['user_id'];
130
$skillId = $skillIssueInfo['skill_id'];
131
132
/** @var SkillRelUserComment $comment */
133
foreach ($skillIssueComments as $comment) {
134
    $commentDate = api_get_local_time($comment->getFeedbackDateTime());
135
    $skillIssueInfo['comments'][] = [
136
        'text' => $comment->getFeedbackText(),
137
        'value' => $comment->getFeedbackValue(),
138
        'giver_complete_name' => UserManager::formatUserFullName($comment->getFeedbackGiver()),
139
        'datetime' => api_format_date($commentDate, DATE_TIME_FORMAT_SHORT),
140
    ];
141
}
142
143
$acquiredLevel = [];
144
$profile = $skillRepo->find($skillId)->getProfile();
145
146
if (!$profile) {
147
    $skillRelSkill = new SkillRelSkill();
148
    $parents = $skillRelSkill->getSkillParents($skillId);
149
150
    krsort($parents);
151
152
    foreach ($parents as $parent) {
153
        $skillParentId = $parent['skill_id'];
154
        $profile = $skillRepo->find($skillParentId)->getProfile();
155
156
        if ($profile) {
157
            break;
158
        }
159
160
        if (!$profile && $parent['parent_id'] == 0) {
161
            $profile = $skillLevelRepo->findAll();
162
            if ($profile) {
163
                $profile = $profile[0];
164
            }
165
        }
166
    }
167
}
168
169
if ($profile) {
170
    $profileId = $profile->getId();
171
    $levels = $skillLevelRepo->findBy([
172
        'profile' => $profileId,
173
    ]);
174
175
    $profileLevels = [];
176
    foreach ($levels as $level) {
177
        $profileLevels[$level->getPosition()][$level->getId()] = $level->getName();
178
    }
179
180
    ksort($profileLevels); // Sort the array by Position.
181
    foreach ($profileLevels as $profileLevel) {
182
        $profileId = key($profileLevel);
183
        $acquiredLevel[$profileId] = $profileLevel[$profileId];
184
    }
185
}
186
187
$allowToEdit = Skill::isAllowed($user->getId(), false);
188
189
if ($showLevels && $allowToEdit) {
190
    $formAcquiredLevel = new FormValidator('acquired_level');
191
    $formAcquiredLevel->addSelect('acquired_level', get_lang('AcquiredLevel'), $acquiredLevel);
192
    $formAcquiredLevel->addHidden('user', $skillIssue->getUser()->getId());
193
    $formAcquiredLevel->addHidden('issue', $skillIssue->getId());
194
    $formAcquiredLevel->addButtonSave(get_lang('Save'));
195
196
    if ($formAcquiredLevel->validate() && $allowComment) {
197
        $values = $formAcquiredLevel->exportValues();
198
        $level = $skillLevelRepo->find($values['acquired_level']);
199
        $skillIssue->setAcquiredLevel($level);
0 ignored issues
show
The method setAcquiredLevel() does not exist on SkillRelUser. ( Ignorable by Annotation )

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

199
        $skillIssue->/** @scrutinizer ignore-call */ 
200
                     setAcquiredLevel($level);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
200
201
        $entityManager->persist($skillIssue);
202
        $entityManager->flush();
203
        Display::addFlash(Display::return_message(get_lang('Saved')));
204
205
        header('Location: '.SkillRelUserManager::getIssueUrl($skillIssue));
206
        exit;
207
    }
208
}
209
210
$form = new FormValidator('comment');
211
$form->addTextarea('comment', get_lang('NewComment'), ['rows' => 4]);
212
$form->applyFilter('comment', 'trim');
213
$form->addRule('comment', get_lang('ThisFieldIsRequired'), 'required');
214
$form->addSelect(
215
    'value',
216
    [get_lang('Value'), get_lang('RateTheSkillInPractice')],
217
    ['-', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
218
);
219
$form->addHidden('user', $skillIssue->getUser()->getId());
220
$form->addHidden('issue', $skillIssue->getId());
221
$form->addButtonSend(get_lang('Send'));
222
223
if ($form->validate() && $allowComment && $allowToEdit) {
224
    $values = $form->exportValues();
225
    $skillUserComment = new SkillRelUserComment();
226
    $skillUserComment
227
        ->setFeedbackDateTime(new DateTime())
228
        ->setFeedbackGiver($currentUser)
229
        ->setFeedbackText($values['comment'])
230
        ->setFeedbackValue($values['value'] ? $values['value'] : null)
231
        ->setSkillRelUser($skillIssue)
232
    ;
233
234
    $entityManager->persist($skillUserComment);
235
    $entityManager->flush();
236
    Display::addFlash(Display::return_message(get_lang('Added')));
237
238
    header('Location: '.SkillRelUserManager::getIssueUrl($skillIssue));
239
    exit;
240
}
241
242
$badgeInfoError = '';
243
$personalBadge = '';
244
if ($allowExport) {
245
    $backpack = 'https://backpack.openbadges.org/';
246
    $configBackpack = api_get_setting('openbadges_backpack');
247
248
    if (0 !== strcmp($backpack, $configBackpack)) {
249
        $backpack = $configBackpack;
250
        if (substr($backpack, -1) !== '/') {
251
            $backpack .= '/';
252
        }
253
    }
254
255
    $htmlHeadXtra[] = '<script src="'.$backpack.'issuer.js"></script>';
256
    $objSkill = new Skill();
257
    $assertionUrl = $skillIssueInfo['badge_assertion'];
258
    $skills = $objSkill->get($skillId);
259
    $unbakedBadge = api_get_path(SYS_UPLOAD_PATH).'badges/'.$skills['icon'];
260
    if (!is_file($unbakedBadge)) {
261
        $unbakedBadge = api_get_path(SYS_CODE_PATH).'img/icons/128/badges-default.png';
262
    }
263
264
    $unbakedBadge = file_get_contents($unbakedBadge);
265
    $badgeInfoError = false;
266
    $personalBadge = '';
267
    $png = new PNGImageBaker($unbakedBadge);
268
269
    if ($png->checkChunks("tEXt", "openbadges")) {
270
        $bakedInfo = $png->addChunk("tEXt", "openbadges", $assertionUrl);
271
        $bakedBadge = UserManager::getUserPathById($userId, "system");
272
        $bakedBadge = $bakedBadge.'badges';
273
        if (!file_exists($bakedBadge)) {
274
            mkdir($bakedBadge, api_get_permissions_for_new_directories(), true);
275
        }
276
        $skillRelUserId = $skillIssueInfo['id'];
277
        if (!file_exists($bakedBadge."/badge_".$skillRelUserId)) {
278
            file_put_contents($bakedBadge."/badge_".$skillRelUserId.".png", $bakedInfo);
279
        }
280
281
        // Process to validate a baked badge
282
        $badgeContent = file_get_contents($bakedBadge."/badge_".$skillRelUserId.".png");
283
        $verifyBakedBadge = $png->extractBadgeInfo($badgeContent);
284
        if (!is_array($verifyBakedBadge)) {
285
            $badgeInfoError = true;
286
        }
287
288
        if (!$badgeInfoError) {
289
            $personalBadge = UserManager::getUserPathById($userId, 'web');
290
            $personalBadge = $personalBadge."badges/badge_".$skillRelUserId.".png";
291
        }
292
    }
293
}
294
295
$template = new Template(get_lang('IssuedBadgeInformation'));
296
$template->assign('issue_info', $skillIssueInfo);
297
$template->assign('allow_comment', $allowComment);
298
$template->assign('allow_export', $allowExport);
299
300
$commentForm = '';
301
if ($allowComment && $allowToEdit) {
302
    $commentForm = $form->returnForm();
303
}
304
$template->assign('comment_form', $commentForm);
305
306
$levelForm = '';
307
if ($showLevels && $allowToEdit) {
308
    $levelForm = $formAcquiredLevel->returnForm();
309
}
310
$template->assign('acquired_level_form', $levelForm);
311
$template->assign('badge_error', $badgeInfoError);
312
$template->assign('personal_badge', $personalBadge);
313
$template->assign('show_level', $showLevels);
314
$content = $template->fetch($template->get_template('skill/issued.tpl'));
315
$template->assign('header', get_lang('IssuedBadgeInformation'));
316
$template->assign('content', $content);
317
$template->display_one_col_template();
318