Przeglądaj źródła

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

José Loguercio 8 lat temu
rodzic
commit
d1503a94ec

+ 4 - 1
.htaccess

@@ -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]

+ 5 - 5
main/badge/assign.php

@@ -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 = [];

+ 5 - 1
main/badge/issued.php

@@ -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 = [

+ 277 - 0
main/badge/issued_all.php

@@ -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();

+ 2 - 2
main/template/default/skill/issued.tpl

@@ -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>

+ 142 - 0
main/template/default/skill/issued_all.tpl

@@ -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 %}

+ 1 - 1
main/template/default/social/skills_block.tpl

@@ -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>

+ 12 - 2
src/Chamilo/CoreBundle/Entity/SkillRelUser.php

@@ -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()}";
     }
 
     /**