Added new "All Issued" page for Same skills badges obtained by a user - Ref BT#10651

ofaj
José Loguercio 9 years ago
parent e2a2145dad
commit d1503a94ec
  1. 5
      .htaccess
  2. 10
      main/badge/assign.php
  3. 6
      main/badge/issued.php
  4. 277
      main/badge/issued_all.php
  5. 4
      main/template/default/skill/issued.tpl
  6. 142
      main/template/default/skill/issued_all.tpl
  7. 2
      main/template/default/social/skills_block.tpl
  8. 14
      src/Chamilo/CoreBundle/Entity/SkillRelUser.php

@ -38,5 +38,8 @@ RewriteRule ^courses/([^/]+)/course-pic.png$ app/courses/$1/course-pic.png [QSA,
# About session
RewriteRule ^session/(\d{1,})/about/?$ main/session/about.php?session_id=$1 [L]
# Issued badges friendly URL
# Issued individual badge friendly URL
RewriteRule ^badge/(\d{1,}) main/badge/issued.php?issue=$1 [L]
# Issued badges friendly URL
RewriteRule ^skill/(\d{1,})/user/(\d{1,}) main/badge/issued_all.php?skill=$1&user=$2 [L]

@ -46,11 +46,11 @@ $url = api_get_path(WEB_CODE_PATH)."badge/assign.php?user=".$_REQUEST['user']."&
$htmlHeadXtra[] = ''
. '<script>'
. '$( document ).ready(function() {'
. '$("#skill").on("change", function() {'
. '$(location).attr("href", "'. $url .'"+$(this).val());'
. '});'
. '});'
. '$( document ).ready(function() {'
. '$("#skill").on("change", function() {'
. '$(location).attr("href", "'. $url .'"+$(this).val());'
. '});'
. '});'
. '</script>';
$skillsOptions = [];

@ -71,7 +71,11 @@ $currentUser = $entityManager->find('ChamiloUserBundle:User', $currentUserId);
$allowDownloadExport = $currentUser ? $currentUser->getId() === $user->getId() : false;
$allowComment = $currentUser ? Skill::userCanAddFeedbackToUser($currentUser, $user) : false;
$skillIssueDate = api_get_local_time($skillIssue->getAcquiredSkillAt());
$currentSkillLevel = $skillLevelRepo->find(['id' => $skillIssue->getAcquiredLevel()])->getName();
$currentSkillLevel = get_lang('NoLevelAcquiredYet');
if ($skillIssue->getAcquiredLevel()) {
$currentSkillLevel = $skillLevelRepo->find(['id' => $skillIssue->getAcquiredLevel()])->getName();
}
$argumentationAuthor = api_get_user_info($skillIssue->getArgumentationAuthorId());
$skillIssueInfo = [

@ -0,0 +1,277 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Show information about all issued badges with same skill by user
*
* @author José Loguercio Silva <jose.loguercio@beeznest.com>
* @package chamilo.badge
*/
require_once '../inc/global.inc.php';
require_once '../inc/lib/baker.lib.php';
$userId = isset($_GET['user']) ? intval($_GET['user']) : 0;
$skillId = isset($_GET['skill']) ? intval($_GET['skill']) : 0;
if (!$userId || !$skillId) {
header('Location: ' . api_get_path(WEB_PATH));
exit;
}
$entityManager = Database::getManager();
$user = $entityManager->find('ChamiloUserBundle:User', $userId);
$skill = $entityManager->find('ChamiloCoreBundle:Skill', $skillId);
$skillRepo = $entityManager->getRepository('ChamiloCoreBundle:Skill');
$skillUserRepo = $entityManager->getRepository('ChamiloCoreBundle:SkillRelUser');
$skillLevelRepo = $entityManager->getRepository('ChamiloSkillBundle:Level');
$currentUserId = api_get_user_id();
if (!$user || !$skill) {
Display::addFlash(
Display::return_message(get_lang('NoResults'), 'error')
);
header('Location: ' . api_get_path(WEB_PATH));
exit;
}
$userSkills = $skillUserRepo->findBy([
'userId' => $user->getId(),
'skillId' => $skill->getId()
]);
$userInfo = [
'id' => $user->getId(),
'complete_name' => $user->getCompleteName()
];
$skillInfo = [
'id' => $skill->getId(),
'name' => $skill->getName(),
'short_code' => $skill->getShortCode(),
'description' => $skill->getDescription(),
'criteria' => $skill->getCriteria(),
'badge_image' => $skill->getWebIconPath(),
'courses' => []
];
$allUserBadges = [];
foreach ($userSkills as $index => $skillIssue) {
$currentUser = $entityManager->find('ChamiloUserBundle:User', $currentUserId);
$allowDownloadExport = $currentUser ? $currentUser->getId() === $user->getId() : false;
$allowComment = $currentUser ? Skill::userCanAddFeedbackToUser($currentUser, $user) : false;
$skillIssueDate = api_get_local_time($skillIssue->getAcquiredSkillAt());
$currentSkillLevel = get_lang('NoLevelAcquiredYet');
if ($skillIssue->getAcquiredLevel()) {
$currentSkillLevel = $skillLevelRepo->find(['id' => $skillIssue->getAcquiredLevel()])->getName();
}
$argumentationAuthor = api_get_user_info($skillIssue->getArgumentationAuthorId());
$skillIssueInfo = [
'id' => $skillIssue->getId(),
'datetime' => api_format_date($skillIssueDate, DATE_TIME_FORMAT_SHORT),
'acquired_level' => $currentSkillLevel,
'argumentation_author_id' => $skillIssue->getArgumentationAuthorId(),
'argumentation_author_name' => api_get_person_name($argumentationAuthor['firstname'], $argumentationAuthor['lastname']),
'argumentation' => $skillIssue->getArgumentation(),
'source_name' => $skillIssue->getSourceName(),
'user_id' => $skillIssue->getUser()->getId(),
'user_complete_name' => $skillIssue->getUser()->getCompleteName(),
'skill_id' => $skillIssue->getSkill()->getId(),
'skill_badge_image' => $skillIssue->getSkill()->getWebIconPath(),
'skill_name' => $skillIssue->getSkill()->getName(),
'skill_short_code' => $skillIssue->getSkill()->getShortCode(),
'skill_description' => $skillIssue->getSkill()->getDescription(),
'skill_criteria' => $skillIssue->getSkill()->getCriteria(),
'badge_assertion' => $skillIssue->getAssertionUrl(),
'comments' => [],
'feedback_average' => $skillIssue->getAverage()
];
$skillIssueComments = $skillIssue->getComments(true);
$userId = $skillIssueInfo['user_id'];
$skillId = $skillIssueInfo['skill_id'];
foreach ($skillIssueComments as $comment) {
$commentDate = api_get_local_time($comment->getFeedbackDateTime());
$skillIssueInfo['comments'][] = [
'text' => $comment->getFeedbackText(),
'value' => $comment->getFeedbackValue(),
'giver_complete_name' => $comment->getFeedbackGiver()->getCompleteName(),
'datetime' => api_format_date($commentDate, DATE_TIME_FORMAT_SHORT)
];
}
$acquiredLevel = [];
$profile = $skillRepo->find($skillId)->getProfile();
if (!$profile) {
$skillRelSkill = new SkillRelSkill();
$parents = $skillRelSkill->get_skill_parents($skillId);
krsort($parents);
foreach ($parents as $parent) {
$skillParentId = $parent['skill_id'];
$profile = $skillRepo->find($skillParentId)->getProfile();
if ($profile) {
break;
}
if (!$profile && $parent['parent_id'] == 0) {
$profile = $skillLevelRepo->findAll();
$profile = $profile[0];
}
}
}
if ($profile) {
$profileId = $profile->getId();
$levels = $skillLevelRepo->findBy([
'profile' => $profileId
]);
foreach ($levels as $level) {
$profileLevels[$level->getPosition()][$level->getId()] = $level->getName();
}
ksort($profileLevels); // Sort the array by Position.
foreach ($profileLevels as $profileLevel) {
$profileId = key($profileLevel);
$acquiredLevel[$profileId] = $profileLevel[$profileId];
}
}
$formAcquiredLevel = new FormValidator('acquired_level'.$skillIssue->getId(), 'post', $skillIssue->getIssueUrlAll());
$formAcquiredLevel->addSelect('acquired_level', get_lang('AcquiredLevel'), $acquiredLevel);
$formAcquiredLevel->addHidden('user', $skillIssue->getUser()->getId());
$formAcquiredLevel->addHidden('issue', $skillIssue->getId());
$formAcquiredLevel->addButtonSend(get_lang('Save'));
if ($formAcquiredLevel->validate() && $allowComment) {
$values = $formAcquiredLevel->exportValues();
$level = $skillLevelRepo->find(intval($values['acquired_level']));
$skillIssue->setAcquiredLevel($level);
$entityManager->persist($skillIssue);
$entityManager->flush();
header("Location: " . $skillIssue->getIssueUrlAll());
exit;
}
$form = new FormValidator('comment'.$skillIssue->getId(), 'post', $skillIssue->getIssueUrlAll());
$form->addTextarea('comment', get_lang('NewComment'), ['rows' => 4]);
$form->applyFilter('comment', 'trim');
$form->addRule('comment', get_lang('ThisFieldIsRequired'), 'required');
$form->addSelect(
'value',
[get_lang('Value'), get_lang('RateTheSkillInPractice')],
['-', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
);
$form->addHidden('user', $skillIssue->getUser()->getId());
$form->addHidden('issue', $skillIssue->getId());
$form->addButtonSend(get_lang('Send'));
if ($form->validate() && $allowComment) {
$values = $form->exportValues();
$skillUserComment = new Chamilo\CoreBundle\Entity\SkillRelUserComment();
$skillUserComment
->setFeedbackDateTime(new DateTime)
->setFeedbackGiver($currentUser)
->setFeedbackText($values['comment'])
->setFeedbackValue($values['value'] ? $values['value'] : null)
->setSkillRelUser($skillIssue);
$entityManager->persist($skillUserComment);
$entityManager->flush();
header("Location: " . $skillIssue->getIssueUrlAll());
exit;
}
$badgeInfoError = "";
$personalBadge = "";
if ($allowDownloadExport) {
$backpack = 'https://backpack.openbadges.org/';
$configBackpack = api_get_setting('openbadges_backpack');
if (strcmp($backpack, $configBackpack) !== 0) {
$backpack = $configBackpack;
}
$htmlHeadXtra[] = '<script src="' . $backpack . 'issuer.js"></script>';
$objSkill = new Skill();
$assertionUrl = $skillIssueInfo['badge_assertion'];
$skills = $objSkill->get($skillId);
$unbakedBadge = api_get_path(SYS_UPLOAD_PATH) . "badges/".$skills['icon'];
if (!is_file($unbakedBadge)) {
$unbakedBadge = api_get_path(WEB_CODE_PATH).'img/icons/128/badges-default.png';
}
$unbakedBadge = file_get_contents($unbakedBadge);
$badgeInfoError = false;
$personalBadge = "";
$png = new PNGImageBaker($unbakedBadge);
if ($png->checkChunks("tEXt", "openbadges")) {
$bakedInfo = $png->addChunk("tEXt", "openbadges", $assertionUrl);
$bakedBadge = UserManager::getUserPathById($userId, "system");
$bakedBadge = $bakedBadge.'badges';
if (!file_exists($bakedBadge)) {
mkdir($bakedBadge, api_get_permissions_for_new_directories(), true);
}
$skillRelUserId = $skillIssueInfo['id'];
if (!file_exists($bakedBadge . "/badge_" . $skillRelUserId)) {
file_put_contents($bakedBadge . "/badge_" . $skillRelUserId . ".png", $bakedInfo);
}
//Process to validate a baked badge
$badgeContent = file_get_contents($bakedBadge . "/badge_" . $skillRelUserId . ".png");
$verifyBakedBadge = $png->extractBadgeInfo($badgeContent);
if (!is_array($verifyBakedBadge)) {
$badgeInfoError = true;
}
if (!$badgeInfoError) {
$personalBadge = UserManager::getUserPathById($userId, "web");
$personalBadge = $personalBadge."badges/badge_" . $skillRelUserId . ".png";
}
}
}
$allUserBadges[$index]['issue_info'] = $skillIssueInfo;
$allUserBadges[$index]['allow_comment'] = $allowComment;
$allUserBadges[$index]['allow_download_export'] = $allowDownloadExport;
$allUserBadges[$index]['comment_form'] = $form->returnForm();
$allUserBadges[$index]['acquired_level_form'] = $formAcquiredLevel->returnForm();
$allUserBadges[$index]['badge_error'] = $badgeInfoError;
$allUserBadges[$index]['personal_badge'] = $personalBadge;
}
$template = new Template(get_lang('IssuedBadgeInformation'));
$template->assign('user_badges', $allUserBadges);
$content = $template->fetch(
$template->get_template('skill/issued_all.tpl')
);
$template->assign('header', get_lang('IssuedBadgeInformation'));
$template->assign('content', $content);
$template->display_one_col_template();

@ -39,10 +39,10 @@
</p>
<div class='col-md-12 text-center'>
<h5><b> {{ 'ShareWithYourFriends' | get_lang }} </b></h5>
<a href='http://www.facebook.com/sharer.php?u={{ _p.web }}badge/{{ skill_info.id }}/user/{{ user_info.id }}' target='_new'>
<a href='http://www.facebook.com/sharer.php?u={{ _p.web }}badge/{{ issue_info.id }}' target='_new'>
<em class='fa fa-facebook-square fa-3x text-info' aria-hidden='true'></em>
</a>
<a href='https://twitter.com/home?status={{ 'IHaveObtainedSkillXOnY' | get_lang |format(skill_info.name, _s.site_name)}} - {{ _p.web }}badge/{{ skill_info.id }}/user/{{ user_info.id }}' target='_new'>
<a href='https://twitter.com/home?status={{ 'IHaveObtainedSkillXOnY' | get_lang |format(skill_info.name, _s.site_name)}} - {{ _p.web }}badge/{{ issue_info.id }}' target='_new'>
<em class='fa fa-twitter-square fa-3x text-light' aria-hidden='true'></em>
</a>
</div>

@ -0,0 +1,142 @@
{% for badge in user_badges %}
<div class="row issued">
<div class="col-md-5">
<div class="thumbnail">
<figure class="text-center">
<img class="img-responsive center-block" src="{{ badge.issue_info.skill_badge_image }}" alt="{{ badge.issue_info.skill_name }}">
<figcaption>
<p class="lead">{{ badge.issue_info.skill_name }}</p>
{% if badge.issue_info.skill_short_code %}
<p>{{ badge.issue_info.skill_short_code }}</p>
{% endif %}
</figcaption>
</figure>
<div class="caption">
{% if badge.issue_info.skill_description %}
<p>{{ badge.issue_info.skill_description }}</p>
{% endif %}
{% if badge.issue_info.skill_criteria %}
<h3>{{ 'CriteriaToEarnTheBadge'|get_lang }}</h3>
<p>{{ badge.issue_info.skill_criteria }}</p>
{% endif %}
</div>
</div>
{% if badge.allow_download_export %}
{% if badge.badge_error %}
<hr>
<div class="alert alert-danger"> {{ 'BakedBadgeProblem'|get_lang }}</div>
{% else %}
<p class="text-center">
<a href="{{ badge.personal_badge }}" class="btn btn-primary" target="_new" download="badge">
<em class="fa fa-download fa-fw"></em> {{ 'DownloadBadge'|get_lang }}
</a>
</p>
{% endif %}
<hr>
<p class="text-center">
<a href="#" class="btn btn-success" id="badge-export-button-{{ badge.issue_info.id }}">
<em class="fa fa-external-link-square fa-fw"></em> {{ 'ExportBadge'|get_lang }}
</a>
</p>
<div class='col-md-12 text-center'>
<h5><b> {{ 'ShareWithYourFriends' | get_lang }} </b></h5>
<a href='http://www.facebook.com/sharer.php?u={{ _p.web }}badge/{{ badge.issue_info.id }}' target='_new'>
<em class='fa fa-facebook-square fa-3x text-info' aria-hidden='true'></em>
</a>
<a href='https://twitter.com/home?status={{ 'IHaveObtainedSkillXOnY' | get_lang |format(skill_info.name, _s.site_name)}} - {{ _p.web }}badge/{{ badge.issue_info.id }}' target='_new'>
<em class='fa fa-twitter-square fa-3x text-light' aria-hidden='true'></em>
</a>
</div>
{% endif %}
</div>
<div class="col-md-7">
<h3>{{ 'RecipientDetails'|get_lang }}</h3>
<p class="lead">{{ badge.issue_info.user_complete_name }}</p>
<h4>{{ 'SkillAcquiredAt'|get_lang }}</h4>
<ul class="fa-ul">
<li>
{% if badge.issue_info.source_name %}
<em class="fa-li fa fa-clock-o fa-fw"></em> {{ 'TimeXThroughCourseY'|get_lang|format(badge.issue_info.datetime, badge.issue_info.source_name) }}
{% else %}
<em class="fa-li fa fa-clock-o fa-fw"></em> {{ badge.issue_info.datetime }}
{% endif %}
{% if badge.issue_info.argumentation %}
{% if badge.issue_info.argumentation %}
<b><p style="font-style: italic;">{{ 'UserXIndicated'|get_lang|format(badge.issue_info.argumentation_author_name) }} </p></b>
{% endif %}
<p>{{ badge.issue_info.argumentation }}</p>
{% endif %}
</li>
</ul>
<h4>{{ 'AcquiredLevel'|get_lang }}</h4>
<ul class="fa-ul">
<li>
<em class="fa-li fa fa-check-circle-o fa-fw"></em> {{ badge.issue_info.acquired_level }}
</li>
</ul>
{% if badge.allow_comment %}
<hr>
<div class="panel panel-info">
<div class="panel-heading">
<em class="fa fa-check-circle-o fa-fw" aria-hidden="true"></em> {{ 'ChangeAcquiredLevel'|get_lang }}
</div>
<div class="panel-body">
{{ badge.acquired_level_form }}
</div>
</div>
<hr>
<div class="panel panel-info">
<div class="panel-heading">
<em class="fa fa-comment-o fa-fw" aria-hidden="true"></em> {{ 'XComments'|get_lang|format(badge.issue_info.comments|length) }}
/
<em class="fa fa-thumbs-o-up fa-fw" aria-hidden="true"></em> {{ 'AverageRatingX'|get_lang|format(badge.issue_info.feedback_average) }}
</div>
<div class="panel-body">
{{ badge.comment_form }}
<hr>
{% for comment in badge.issue_info.comments %}
<article class="media">
<div class="media-body">
<h4 class="media-heading">{{ comment.giver_complete_name }}</h4>
<p><small>{{ comment.datetime }}</small></p>
<p>{{ comment.text }}</p>
</div>
<div class="media-right text-right">
<div style="width: 80px;">
{% if comment.value %}
<em class="fa fa-certificate fa-fw" aria-label="{{ 'AverageRating' }}"></em>
<span class="sr-only">{{ 'AverageRating' }}</span> {{ comment.value }}
{% endif %}
</div>
</div>
</article>
{% else %}
<p>{{ 'WithoutComment'|get_lang }}</p>
{% endfor %}
</div>
</div>
{% else %}
<hr>
<p class="lead">
<em class="fa fa-comment-o fa-fw" aria-hidden="true"></em> {{ 'XComments'|get_lang|format(badge.issue_info.comments|length) }}
/
<em class="fa fa-thumbs-o-up fa-fw" aria-hidden="true"></em> {{ 'AverageRatingX'|get_lang|format(badge.issue_info.feedback_average) }}
</p>
{% endif %}
</div>
</div>
{% if badge.allow_download_export %}
<script>
$(document).on('ready', function () {
$('#badge-export-button-{{ badge.issue_info.id }}').on('click', function (e) {
e.preventDefault();
OpenBadges.issue({{ badge.issue_info.badge_assertion|json_encode() }});
});
});
</script>
{% endif %}
<br />
<br />
{% endfor %}

@ -39,7 +39,7 @@
<ul class="list-unstyled list-badges">
{% for skill in skills %}
<li class="thumbnail">
<a href="{{ _p.web }}badge/{{ skill.issue }}" target="_blank">
<a href="{{ _p.web }}skill/{{ skill.id }}/user/{{ user_id }}" target="_blank">
<img title="{{ skill.name }}" class="img-responsive" src="{{ skill.icon ? skill.web_icon_thumb_path : 'badges-default.png'|icon(64) }}" width="64" height="64" alt="{{ skill.name }}">
<div class="caption">
<p class="text-center">{{ skill.name }}</p>

@ -437,7 +437,8 @@ class SkillRelUser
{
$source = '';
if ($this->session) {
if ($this->session && $this->session->getId() != 0) {
$source .= "[{$this->session->getName()}] ";
}
@ -454,7 +455,16 @@ class SkillRelUser
*/
public function getIssueUrl()
{
return api_get_path(WEB_PATH) . "badge/issue/{$this->id}/user/{$this->user->getId()}/";
return api_get_path(WEB_PATH) . "badge/{$this->id}";
}
/**
* Get the URL for the All issues page
* @return string
*/
public function getIssueUrlAll()
{
return api_get_path(WEB_PATH) . "skill/{$this->skill->getId()}/user/{$this->user->getId()}";
}
/**

Loading…
Cancel
Save