Conflicts:
	main/inc/lib/database.lib.php
ofaj
Nicolas Ducoulombier 10 years ago
commit 416a0fdaea
  1. 5
      .htaccess
  2. 46
      app/Migrations/Schema/V111/Version20160405112100.php
  3. 1
      main/admin/index.php
  4. 93
      main/admin/skill.php
  5. 113
      main/admin/skill_level.php
  6. 122
      main/admin/skill_profile.php
  7. 9
      main/admin/user_list.php
  8. 183
      main/badge/assign.php
  9. 237
      main/badge/issued.php
  10. 277
      main/badge/issued_all.php
  11. 1
      main/inc/lib/database.lib.php
  12. 53
      main/inc/lib/skill.lib.php
  13. 30
      main/template/default/admin/skill.tpl
  14. 27
      main/template/default/admin/skill_level.tpl
  15. 42
      main/template/default/admin/skill_profile.tpl
  16. 177
      main/template/default/skill/issued.tpl
  17. 142
      main/template/default/skill/issued_all.tpl
  18. 2
      main/template/default/social/skills_block.tpl
  19. 5
      src/Chamilo/CoreBundle/Entity/Course.php
  20. 77
      src/Chamilo/CoreBundle/Entity/Skill.php
  21. 317
      src/Chamilo/CoreBundle/Entity/SkillRelUser.php
  22. 183
      src/Chamilo/CoreBundle/Entity/SkillRelUserComment.php
  23. 160
      src/Chamilo/SkillBundle/Entity/Level.php
  24. 133
      src/Chamilo/SkillBundle/Entity/Profile.php
  25. 53
      src/Chamilo/UserBundle/Entity/User.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 individual badge friendly URL
RewriteRule ^badge/(\d{1,}) main/badge/issued.php?issue=$1 [L]
# Issued badges friendly URL
RewriteRule ^badge/(\d{1,})/user/(\d{1,}) main/badge/issued.php?skill=$1&user=$2 [L]
RewriteRule ^skill/(\d{1,})/user/(\d{1,}) main/badge/issued_all.php?skill=$1&user=$2 [L]

@ -0,0 +1,46 @@
<?php
namespace Application\Migrations\Schema\V111;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
class Version20160405112100 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
$this->addSql(
'CREATE TABLE skill_level_profile (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'
);
$this->addSql(
'CREATE TABLE skill_level (id INT AUTO_INCREMENT NOT NULL, profile_id INT NOT NULL, name VARCHAR(255) NOT NULL, position INT, short_name VARCHAR(255), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'
);
$this->addSql(
'ALTER TABLE skill_rel_user ADD acquired_level INT, ADD argumentation TEXT, ADD argumentation_author_id INT, MODIFY course_id INT, MODIFY session_id INT'
);
$this->addSql(
'CREATE TABLE skill_rel_user_comment (id INT AUTO_INCREMENT NOT NULL, skill_rel_user_id INT NOT NULL, feedback_giver_id INT NOT NULL, feedback_text TEXT, feedback_value INT, feedback_datetime DATETIME, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'
);
$this->addSql(
'ALTER TABLE skill ADD profile_id INT'
);
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
$this->addSql(
'ALTER TABLE skill_rel_user DROP COLUMN acquired_level, DROP COLUMN argumentation, DROP COLUMN argumentation_author_id, MODIFY course_id INT NOT NULL, MODIFY session_id INT NOT NULL'
);
$this->addSql(
'ALTER TABLE skill DROP COLUMN profile_id'
);
$this->addSql('DROP TABLE skill_level');
$this->addSql('DROP TABLE skill_level_profile');
}
}

@ -386,6 +386,7 @@ if (api_is_platform_admin()) {
$items[] = array('url' => 'skills_wheel.php', 'label' => get_lang('SkillsWheel'));
$items[] = array('url' => 'skills_import.php', 'label' => get_lang('SkillsImport'));
$items[] = array('url' => 'skill_list.php', 'label' => get_lang('ManageSkills'));
$items[] = array('url'=>'skill.php', 'label' => get_lang('ManageSkillsLevels'));
//$items[] = array('url'=>'skills_profile.php', 'label' => get_lang('SkillsProfile'));
$items[] = array(
'url' => api_get_path(WEB_CODE_PATH) . 'social/skills_ranking.php',

@ -0,0 +1,93 @@
<?php
/* For license terms, see /license.txt */
/**
* This script manages the skills, levels and profiles assignments.
*
* @package chamilo.skill
*/
$cidReset = true;
require_once '../inc/global.inc.php';
api_protect_admin_script();
$em = Database::getManager();
$profiles = $em->getRepository('ChamiloSkillBundle:Profile')->findAll();
$list = $em->getRepository('ChamiloCoreBundle:Skill')->findAll();
$listAction = api_get_self();
$action = '';
if (isset($_GET['action']) && in_array($_GET['action'], ['add', 'edit', 'delete'])) {
$action = $_GET['action'];
}
$id = isset($_GET['id']) ? $_GET['id'] : '';
$item = null;
if (!empty($id)) {
/** @var \Chamilo\CoreBundle\Entity\Skill $item */
$item = $em->getRepository('ChamiloCoreBundle:Skill')->find($id);
if (!$item) {
api_not_allowed();
}
}
$form = new FormValidator('Skill', 'GET', api_get_self().'?action='.$action.'&id='.$id);
$form->addSelectFromCollection('profile_id', get_lang('Profile'), $profiles, null, true);
$form->addHidden('action', $action);
$form->addHidden('id', $id);
$form->addButtonSave(get_lang('Update'));
if (!empty($item)) {
$profile = $item->getProfile();
if ($profile) {
$form->setDefaults(
[
'profile_id' => $item->getProfile()->getId(),
]
);
}
$form->addHeader($item->getName());
}
$formToDisplay = $form->returnForm();
$interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
$interbreadcrumb[] = array ('url' => api_get_self(), 'name' => get_lang('ManageSkillsLevels'));
$tpl = new Template($action);
switch ($action) {
case 'edit':
$tpl->assign('form', $formToDisplay);
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
if ($form->validate()) {
$values = $form->exportValues();
$profile = $em->getRepository('ChamiloSkillBundle:Profile')->find($values['profile_id']);
$item->setProfile($profile);
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
}
break;
case 'delete':
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
$em->remove($item);
$em->flush();
header('Location: '.$listAction);
exit;
break;
default:
break;
}
$tpl->assign('list', $list);
$contentTemplate = $tpl->fetch('default/admin/skill.tpl');
$tpl->assign('content', $contentTemplate);
$tpl->display_one_col_template();

@ -0,0 +1,113 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Add a skill Level
*
* @package chamilo.skill
*/
$cidReset = true;
require_once '../inc/global.inc.php';
api_protect_admin_script();
$em = Database::getManager();
$profiles = $em->getRepository('ChamiloSkillBundle:Profile')->findAll();
$list = $em->getRepository('ChamiloSkillBundle:Level')->findAll();
$listAction = api_get_self();
$action = '';
if (isset($_GET['action']) && in_array($_GET['action'], ['add', 'edit', 'delete', 'add_level'])) {
$action = $_GET['action'];
}
$id = isset($_GET['id']) ? $_GET['id'] : '';
$item = null;
if (!empty($id)) {
/** @var \Chamilo\SkillBundle\Entity\Level $item */
$item = $em->getRepository('ChamiloSkillBundle:Level')->find($id);
if (!$item) {
api_not_allowed();
}
}
$form = new FormValidator('Level', 'GET', api_get_self().'?action='.$action.'&id='.$id);
$form->addText('name', get_lang('Name'));
$form->addText('short_name', get_lang('ShortName'));
$form->addSelectFromCollection('profile_id', get_lang('Profile'), $profiles);
$form->addHidden('action', $action);
$form->addHidden('id', $id);
$form->addButtonSave(get_lang('Save'));
if (!empty($item)) {
$form->setDefaults([
'name' => $item->getName(),
'short_name' => $item->getShortName(),
'profile_id' => $item->getProfile()->getId(),
]);
}
$formToDisplay = $form->returnForm();
$interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
$interbreadcrumb[] = array ('url' => api_get_self(), 'name' => get_lang('SkillProfile'));
$tpl = new Template($action);
switch ($action) {
case 'add':
$tpl->assign('form', $formToDisplay);
if ($form->validate()) {
$values = $form->exportValues();
$item = new \Chamilo\SkillBundle\Entity\Level();
$item->setName($values['name']);
$item->setShortName($values['short_name']);
$profile = $em->getRepository('ChamiloSkillBundle:Profile')->find($values['profile_id']);
$item->setProfile($profile);
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
}
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
break;
case 'edit':
$tpl->assign('form', $formToDisplay);
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
if ($form->validate()) {
$values = $form->exportValues();
$item->setName($values['name']);
$item->setShortName($values['short_name']);
$profile = $em->getRepository('ChamiloSkillBundle:Profile')->find($values['profile_id']);
$item->setProfile($profile);
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
}
break;
case 'delete':
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
$em->remove($item);
$em->flush();
header('Location: '.$listAction);
exit;
break;
default:
$tpl->assign('actions', Display::url(get_lang('Add'), api_get_self().'?action=add'));
}
$tpl->assign('list', $list);
$contentTemplate = $tpl->fetch('default/admin/skill_level.tpl');
$tpl->assign('content', $contentTemplate);
$tpl->display_one_col_template();

@ -0,0 +1,122 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Add a skill Profile
*
* @package chamilo.skill
*/
$cidReset = true;
require_once '../inc/global.inc.php';
api_protect_admin_script();
$em = Database::getManager();
$list = $em->getRepository('ChamiloSkillBundle:Profile')->findAll();
$listAction = api_get_self();
$action = '';
if (isset($_GET['action']) && in_array($_GET['action'], ['add', 'edit', 'delete', 'move_up', 'move_down'])) {
$action = $_GET['action'];
}
$id = isset($_GET['id']) ? $_GET['id'] : '';
$item = null;
if (!empty($id)) {
$item = $em->getRepository('ChamiloSkillBundle:Profile')->find($id);
if (!$item) {
api_not_allowed();
}
}
$form = new FormValidator('Profile', 'GET', api_get_self().'?action='.$action.'&id='.$id);
$form->addText('name', get_lang('Name'));
$form->addHidden('action', $action);
$form->addHidden('id', $id);
$form->addButtonSave(get_lang('Save'));
if (!empty($item)) {
$form->setDefaults(['name' => $item->getName()]);
}
$formToDisplay = $form->returnForm();
$interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
$interbreadcrumb[] = array ('url' => 'skill.php', 'name' => get_lang('ManageSkillsLevels'));
$interbreadcrumb[] = array ('url' => api_get_self(), 'name' => get_lang('SkillProfile'));
$tpl = new Template($action);
switch ($action) {
case 'move_up':
/** @var \Chamilo\SkillBundle\Entity\Level $item */
$item = $em->getRepository('ChamiloSkillBundle:Level')->find($_GET['level_id']);
$position = $item->getPosition();
if (!empty($position)) {
$item->setPosition($position-1);
}
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
break;
case 'move_down':
/** @var \Chamilo\SkillBundle\Entity\Level $item */
$item = $em->getRepository('ChamiloSkillBundle:Level')->find($_GET['level_id']);
$position = $item->getPosition();
$item->setPosition($position+1);
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
break;
case 'add':
$tpl->assign('form', $formToDisplay);
if ($form->validate()) {
$values = $form->exportValues();
$item = new \Chamilo\SkillBundle\Entity\Profile();
$item->setName($values['name']);
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
}
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
break;
case 'edit':
$tpl->assign('form', $formToDisplay);
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
if ($form->validate()) {
$values = $form->exportValues();
$item->setName($values['name']);
$em->persist($item);
$em->flush();
header('Location: '.$listAction);
exit;
}
break;
case 'delete':
$tpl->assign('actions', Display::url(get_lang('List'), $listAction));
$em->remove($item);
$em->flush();
header('Location: '.$listAction);
exit;
break;
default:
$tpl->assign('actions', Display::url(get_lang('Add'), api_get_self().'?action=add'));
}
$tpl->assign('list', $list);
$contentTemplate = $tpl->fetch('default/admin/skill_profile.tpl');
$tpl->assign('content', $contentTemplate);
$tpl->display_one_col_template();

@ -530,6 +530,15 @@ function modify_filter($user_id, $url_params, $row) {
}
}
$allowAssignSkill = api_is_platform_admin(false, true);
if ($allowAssignSkill) {
$result .= Display::url(
Display::return_icon('skill-badges.png', get_lang('AssignSkill'), null, ICON_SIZE_SMALL),
api_get_path(WEB_CODE_PATH) . 'badge/assign.php?' . http_build_query(['user' => $user_id])
);
}
if ($is_admin) {
$result .= Display::return_icon('admin_star.png', get_lang('IsAdministrator'),array('width'=> ICON_SIZE_SMALL, 'heigth'=> ICON_SIZE_SMALL));
} else {

@ -0,0 +1,183 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Page for assign skills to a user
*
* @autor: Jose Loguercio <jose.loguercio@beeznest.com>
* @package chamilo.badge
*/
use \Chamilo\CoreBundle\Entity\Skill;
use \Chamilo\CoreBundle\Entity\SkillRelUser;
require_once '../inc/global.inc.php';
if (!api_is_platform_admin(false, true)) {
api_not_allowed(true);
}
if (!isset($_REQUEST['user'])) {
api_not_allowed(true);
}
$entityManager = Database::getManager();
$skillRepo = $entityManager->getRepository('ChamiloCoreBundle:Skill');
$skillRelSkill = $entityManager->getRepository('ChamiloCoreBundle:SkillRelSkill');
$skillLevelRepo = $entityManager->getRepository('ChamiloSkillBundle:Level');
$skillUserRepo = $entityManager->getRepository('ChamiloCoreBundle:SkillRelUser');
$user = $entityManager->find('ChamiloUserBundle:User', $_REQUEST['user']);
if (!$user) {
Display::addFlash(
Display::return_message(get_lang('NoUser'), 'error')
);
header('Location: ' . api_get_path(WEB_PATH));
exit;
}
$skills = $skillRepo->findBy([
'status' => Skill::STATUS_ENABLED
]);
$url = api_get_path(WEB_CODE_PATH)."badge/assign.php?user=".$_REQUEST['user']."&id=";
$htmlHeadXtra[] = ''
. '<script>'
. '$( document ).ready(function() {'
. '$("#skill").on("change", function() {'
. '$(location).attr("href", "'. $url .'"+$(this).val());'
. '});'
. '});'
. '</script>';
$skillsOptions = [];
$acquiredLevel = [];
$formDefaultValues = [];
foreach ($skills as $skill) {
$skillsOptions[$skill->getId()] = $skill->getName();
}
$skillId = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : key($skillsOptions);
$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 = isset($profile[0]) ? $profile[0] : false;
}
}
}
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];
}
}
$formDefaultValues = ['skill' => $skillId];
$form = new FormValidator('assign_skill');
$form->addText('user_name', get_lang('UserName'), false);
$form->addSelect('skill', get_lang('Skill'), $skillsOptions, ['id' => 'skill']);
$form->addHidden('user', $user->getId());
$form->addHidden('id', $skillId);
$form->addRule('skill', get_lang('ThisFieldIsRequired'), 'required');
$form->addSelect('acquired_level', get_lang('AcquiredLevel'), $acquiredLevel);
$form->addRule('acquired_level', get_lang('ThisFieldIsRequired'), 'required');
$form->addTextarea('argumentation', get_lang('Argumentation'), ['rows' => 6]);
$form->applyFilter('argumentation', 'trim');
$form->addButtonSave(get_lang('Save'));
$form->setDefaults($formDefaultValues);
if ($form->validate()) {
$values = $form->exportValues();
$skill = $skillRepo->find($values['skill']);
if (!$skill) {
Display::addFlash(
Display::return_message(get_lang('SkillNotFound'), 'error')
);
header('Location: ' . api_get_self() . '?' . http_build_query(['user' => $user->getId()]));
exit;
}
if ($user->hasSkill($skill)) {
Display::addFlash(
Display::return_message(
sprintf(get_lang('TheUserXHasAlreadyAchievedTheSkillY'), $user->getCompleteName(), $skill->getName()),
'warning'
)
);
header('Location: ' . api_get_self() . '?' . http_build_query(['user' => $user->getId()]));
exit;
}
$skillUser = new SkillRelUser();
$skillUser->setUser($user);
$skillUser->setSkill($skill);
$level = $skillLevelRepo->find(intval($values['acquired_level']));
$skillUser->setAcquiredLevel($level);
$skillUser->setArgumentation($values['argumentation']);
$skillUser->setArgumentationAuthorId(api_get_user_id());
$skillUser->setAcquiredSkillAt(new DateTime());
$skillUser->setAssignedBy(0);
$entityManager->persist($skillUser);
$entityManager->flush();
Display::addFlash(
Display::return_message(
sprintf(get_lang('SkillXAssignedToUserY'), $skill->getName(), $user->getCompleteName()),
'success'
)
);
header('Location: ' . api_get_path(WEB_PATH) . "badge/{$skillUser->getId()}");
exit;
}
$form->setDefaults(['user_name' => $user->getCompleteName()]);
$form->freeze(['user_name']);
//View
$template = new Template('');
$template->assign('header', get_lang('AssignSkill'));
$template->assign('content', $form->returnForm());
$template->display_one_col_template();

@ -3,41 +3,39 @@
/**
* Show information about the issued badge
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @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;
$issue = isset($_REQUEST['issue']) ? intval($_REQUEST['issue']) : 0;
if (!isset($_GET['user'], $_GET['skill'])) {
if (!$issue) {
header('Location: ' . api_get_path(WEB_PATH));
exit;
}
$entityManager = Database::getManager();
$user = $entityManager->find('ChamiloUserBundle:User', $_GET['user']);
$skill = $entityManager->find('ChamiloCoreBundle:Skill', $_GET['skill']);
$skillIssue = $entityManager->find('ChamiloCoreBundle:SkillRelUser', $issue);
$skillRepo = $entityManager->getRepository('ChamiloCoreBundle:Skill');
$skillLevelRepo = $entityManager->getRepository('ChamiloSkillBundle:Level');
if (!$user || !$skill) {
if (!$skillIssue) {
Display::addFlash(
Display::return_message(get_lang('NoResults'), 'error')
Display::return_message(get_lang('TheUserXNotYetAchievedTheSkillX'), 'error')
);
header('Location: ' . api_get_path(WEB_PATH));
exit;
}
$skillUserRepo = $entityManager->getRepository('ChamiloCoreBundle:SkillRelUser');
$userSkills = $skillUserRepo->findBy([
'userId' => $user->getId(),
'skillId' => $skill->getId()
]);
$user = $skillIssue->getUser();
$skill = $skillIssue->getSkill();
if (!$userSkills) {
if (!$user || !$skill) {
Display::addFlash(
Display::return_message(get_lang('TheUserXNotYetAchievedTheSkillX'), 'error')
Display::return_message(get_lang('NoResults'), 'error')
);
header('Location: ' . api_get_path(WEB_PATH));
@ -59,50 +57,165 @@ $skillInfo = [
'courses' => []
];
// Open Graph Markup
$htmlHeadXtra[] = "
<meta property='og:type' content='article' />
<meta property='og:title' content='".sprintf(get_lang('IHaveObtainedSkillXOnY'), $skillInfo['name'], api_get_setting('siteName'))."' />
<meta property='og:url' content='".api_get_path(WEB_PATH)."badge/".$skillId."/user/".$userId."' />
<meta property='og:url' content='".api_get_path(WEB_PATH)."badge/".$issue."' />
<meta property='og:description' content='".$skillInfo['description']."' />
<meta property='og:image' content='".$skillInfo['badge_image']."' />
";
$badgeAssertions = [];
$currentUserId = api_get_user_id();
$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()
];
foreach ($userSkills as $userSkill) {
$sessionId = 0;
$course = $entityManager->find('ChamiloCoreBundle:Course', $userSkill->getCourseId());
$courseName = $course ? $course->getTitle() : '';
$skillIssueComments = $skillIssue->getComments(true);
if ($userSkill->getSessionId()) {
$session = $entityManager->find('ChamiloCoreBundle:Session', $userSkill->getSessionId());
$sessionId = $session->getId();
$courseName = "[{$session->getName()}] {$course->getTitle()}";
}
$userId = $skillIssueInfo['user_id'];
$skillId = $skillIssueInfo['skill_id'];
$userSkillDate = api_get_local_time($userSkill->getAcquiredSkillAt());
$skillInfo['courses'][] = [
'name' => $courseName,
'date_issued' => api_format_date($userSkillDate, DATE_TIME_FORMAT_LONG)
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();
$assertionUrl = api_get_path(WEB_CODE_PATH) . "badge/assertion.php?";
$assertionUrl .= http_build_query(array(
'user' => $user->getId(),
'skill' => $skill->getId(),
'course' => $userSkill->getCourseId(),
'session' => $userSkill->getSessionId()
));
if (!$profile) {
$badgeAssertions[] = $assertionUrl;
$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];
}
}
}
$allowExport = api_get_user_id() == $user->getId();
if ($profile) {
$profileId = $profile->getId();
if ($allowExport) {
$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');
$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->getIssueUrl());
exit;
}
$form = new FormValidator('comment');
$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->getIssueUrl());
exit;
}
$badgeInfoError = "";
$personalBadge = "";
if ($allowDownloadExport) {
$backpack = 'https://backpack.openbadges.org/';
$configBackpack = api_get_setting('openbadges_backpack');
@ -112,28 +225,27 @@ if ($allowExport) {
}
$htmlHeadXtra[] = '<script src="' . $backpack . 'issuer.js"></script>';
}
$badgeInfoError = false;
$personalBadge = "";
if ($skill->getIcon()) {
$unbakedBadge = file_get_contents(
api_get_path(SYS_UPLOAD_PATH) . "badges/" . $skill->getIcon()
);
$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") . 'badges';
$bakedBadge = UserManager::getUserPathById($userId, "system");
$bakedBadge = $bakedBadge.'badges';
if (!file_exists($bakedBadge)) {
mkdir($bakedBadge, api_get_permissions_for_new_directories(), true);
}
$skillRelUserId = $userSkills[0]->getId();
$skillRelUserId = $skillIssueInfo['id'];
if (!file_exists($bakedBadge . "/badge_" . $skillRelUserId)) {
file_put_contents($bakedBadge . "/badge_" . $skillRelUserId . ".png", $bakedInfo);
}
@ -141,7 +253,6 @@ if ($skill->getIcon()) {
//Process to validate a baked badge
$badgeContent = file_get_contents($bakedBadge . "/badge_" . $skillRelUserId . ".png");
$verifyBakedBadge = $png->extractBadgeInfo($badgeContent);
if (!is_array($verifyBakedBadge)) {
$badgeInfoError = true;
}
@ -153,17 +264,15 @@ if ($skill->getIcon()) {
}
}
$template = new Template('');
$template->assign('skill_info', $skillInfo);
$template->assign('user_info', $userInfo);
$template->assign('allow_export', $allowExport);
$template = new Template(get_lang('IssuedBadgeInformation'));
$template->assign('issue_info', $skillIssueInfo);
$template->assign('allow_comment', $allowComment);
$template->assign('allow_download_export', $allowDownloadExport);
$template->assign('comment_form', $form->returnForm());
$template->assign('acquired_level_form', $formAcquiredLevel->returnForm());
$template->assign('badge_error', $badgeInfoError);
$template->assign('personal_badge', $personalBadge);
if ($allowExport) {
$template->assign('assertions', $badgeAssertions);
}
$content = $template->fetch(
$template->get_template('skill/issued.tpl')
);

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

@ -141,6 +141,7 @@ class Database
'ChamiloCoreBundle' => 'Chamilo\CoreBundle\Entity',
'ChamiloCourseBundle' => 'Chamilo\CourseBundle\Entity',
'ChamiloFaqBundle' => 'Chamilo\FaqBundle\Entity'
'ChamiloSkillBundle' => 'Chamilo\SkillBundle\Entity'
)
);

@ -891,7 +891,7 @@ class Skill extends Model
public function get_user_skills($user_id, $get_skill_data = false)
{
$user_id = intval($user_id);
$sql = 'SELECT DISTINCT s.id, s.name, s.icon
$sql = 'SELECT DISTINCT s.id, s.name, s.icon, u.id as issue
FROM '.$this->table_skill_rel_user.' u
INNER JOIN '.$this->table.' s
ON u.skill_id = s.id
@ -1448,4 +1448,55 @@ class Skill extends Model
return Database::store_result($result, 'ASSOC');
}
/**
* Check if the $fromUser can comment the $toUser skill issue
* @param Chamilo\UserBundle\Entity\User $fromUser
* @param Chamilo\UserBundle\Entity\User $toUser
* @return boolean
*/
public static function userCanAddFeedbackToUser($fromUser, $toUser)
{
if (api_is_platform_admin()) {
return true;
}
$entityManager = Database::getManager();
$userRepo = $entityManager->getRepository('ChamiloUserBundle:User');
$fromUserStatus = $fromUser->getStatus();
switch ($fromUserStatus) {
case SESSIONADMIN:
if (api_get_setting('allow_session_admins_to_manage_all_sessions') === 'true') {
if ($toUser->getCreatorId() === $fromUser->getId()) {
return true;
}
}
$sessionAdmins = $userRepo->getSessionAdmins($toUser);
foreach ($sessionAdmins as $sessionAdmin) {
if ($sessionAdmin->getId() !== $fromUser->getId()) {
continue;
}
return true;
}
break;
case STUDENT_BOSS:
$studentBosses = $userRepo->getStudentBosses($toUser);
foreach ($studentBosses as $studentBoss) {
if ($studentBoss->getId() !== $fromUser->getId()) {
continue;
}
return true;
}
case DRH:
return UserManager::is_user_followed_by_drh($toUser->getId(), $fromUser->getId());
}
return false;
}
}

@ -0,0 +1,30 @@
<h3>{{ 'Skills' | get_lang }}</h3>
<ul>
<li>
<a href="{{ _p.web_main }}{{ 'admin/skill_profile.php' }}">
{{ 'AddProfile' | get_lang }}
</a>
</li>
<li>
<a href="{{ _p.web_main }}{{ 'admin/skill_level.php' }}">
{{ 'AddLevel' | get_lang }}
</a>
</li>
</ul>
{{ form }}
{% for item in list %}
<h4>{{ item.name }} ({{ item.shortCode }})
<a href="{{ _p.web_main }}admin/skill.php?action=edit&id={{ item.id }}">
<img src="{{ 'edit.png'|icon(22) }}">
</a>
</h4>
{{ item.profile }}
{% endfor %}

@ -0,0 +1,27 @@
{{ form }}
<table class="data_table">
<tr>
<th>{{ 'Name' | get_lang }}</th>
<th>{{ 'ShortName' | get_lang }}</th>
<th>{{ 'Profile' | get_lang }}</th>
<th>{{ 'Actions' | get_lang }}</th>
</tr>
{% for item in list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.shortName }}</td>
<td> {{ item.profile }}</td>
<td>
<a href="{{ _p.web_main }}admin/skill_level.php?action=edit&id={{ item.id }}">
<img src="{{ 'edit.png'|icon(22) }}">
</a>
<a href="{{ _p.web_main }}admin/skill_level.php?action=delete&id={{ item.id }}">
<img src="{{ 'delete.png'|icon(22) }}">
</a>
</td>
</tr>
{% endfor %}
</table>

@ -0,0 +1,42 @@
{{ form }}
{% for item in list %}
<h4>{{ item.name }}
{#<a href="{{ _p.web_main }}admin/skill_level.php?action=add_level&id={{ item.id }}">#}
{#<img src="{{ 'add.png'|icon(22) }}">#}
{#</a>#}
<a href="{{ _p.web_main }}admin/skill_profile.php?action=edit&id={{ item.id }}">
<img src="{{ 'edit.png'|icon(22) }}"> </a>
<a href="{{ _p.web_main }}admin/skill_profile.php?action=delete&id={{ item.id }}">
<img src="{{ 'delete.png'|icon(22) }}">
</a>
</h4>
<ul>
{% for level in item.levels %}
<li>
{{ level }}
{% if loop.first %}
<img src="{{ 'up_na.png'|icon(22) }}">
{% else %}
<a href="{{ _p.web_main }}admin/skill_profile.php?action=move_up&level_id={{ level.id }}&id={{ item.id }}">
<img src="{{ 'up.png'|icon(22) }}">
</a>
{% endif %}
{% if loop.last %}
<img src="{{ 'down_na.png'|icon(22) }}">
{% else %}
<a href="{{ _p.web_main }}admin/skill_profile.php?action=move_down&level_id={{ level.id }}&id={{ item.id }}">
<img src="{{ 'down.png'|icon(22) }}">
</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% endfor %}

@ -1,79 +1,138 @@
<div class="row issued">
<div class="col-md-4">
<figure class="thumbnail">
<img class="img-responsive" src="{{ skill_info.badge_image }}" alt="{{ skill_info.name }}">
<figcaption class="caption text-center">
<p class="name-badge text-center">{{ skill_info.name }}</p>
</figcaption>
</figure>
<div class="panel panel-default">
<div class="panel-heading">{{ 'SkillAcquiredAt'|get_lang }}</div>
<div class="panel-body">
{% for course in skill_info.courses %}
<p>
{% if course.name %}
<em class="fa fa-clock-o fa-fw"></em> {{ 'TimeXThroughCourseY'|get_lang|format(course.date_issued, course.name) }}
{% else %}
<em class="fa fa-clock-o fa-fw"></em> {{ course.date_issued }}
{% endif %}
</p>
{% endfor %}
</div>
<div class="col-md-5">
<div class="thumbnail">
<figure class="text-center">
<img class="img-responsive center-block" src="{{ issue_info.skill_badge_image }}" alt="{{ issue_info.skill_name }}">
<figcaption>
<p class="lead">{{ issue_info.skill_name }}</p>
{% if issue_info.skill_short_code %}
<p>{{ issue_info.skill_short_code }}</p>
{% endif %}
</figcaption>
</figure>
<div class="caption">
{% if issue_info.skill_description %}
<p>{{ issue_info.skill_description }}</p>
{% endif %}
{% if issue_info.skill_criteria %}
<h3>{{ 'CriteriaToEarnTheBadge'|get_lang }}</h3>
<p>{{ issue_info.skill_criteria }}</p>
{% endif %}
</div>
{% if badge_error %}
<div class="alert alert-danger"> {{ 'BakedBadgeProblem'|get_lang }}</div>
{% elseif personal_badge is not empty %}
<p class="text-center">
<a href="{{ personal_badge }}" class="btn btn-primary" target="_new" download="badge">
<em class="fa fa-download fa-fw"></em> {{ 'DownloadBadge'|get_lang }}
</a>
</p>
{% endif %}
{% if allow_export %}
</div>
{% if allow_download_export %}
{% if badge_error %}
<hr>
<div class="alert alert-danger"> {{ 'BakedBadgeProblem'|get_lang }}</div>
{% else %}
<p class="text-center">
<a href="{{ 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">
<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/{{ 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/{{ issue_info.id }}' target='_new'>
<em class='fa fa-twitter-square fa-3x text-light' aria-hidden='true'></em>
</a>
</div>
{% endif %}
<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'>
<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'>
<em class='fa fa-twitter-square fa-3x text-light' aria-hidden='true'></em>
</a>
</div>
</div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h4 class="title-badge">{{ 'RecipientDetails'|get_lang }}</h4>
<p class="lead">{{ user_info.complete_name }}</p>
<h4 class="title-badge">{{ 'BadgeDetails'|get_lang }}</h4>
<h4 class="title-badge">{{ 'Name'|get_lang }}</h4>
<p>{{ skill_info.name }}</p>
{% if skill_info.short_code %}
<h4 class="title-badge">{{ 'ShortCode'|get_lang }}</h4>
<p>{{ skill_info.short_code }}</p>
<div class="col-md-7">
<h3>{{ 'RecipientDetails'|get_lang }}</h3>
<p class="lead">{{ issue_info.user_complete_name }}</p>
<h4>{{ 'SkillAcquiredAt'|get_lang }}</h4>
<ul class="fa-ul">
<li>
{% if issue_info.source_name %}
<em class="fa-li fa fa-clock-o fa-fw"></em> {{ 'TimeXThroughCourseY'|get_lang|format(issue_info.datetime, issue_info.source_name) }}
{% else %}
<em class="fa-li fa fa-clock-o fa-fw"></em> {{ issue_info.datetime }}
{% endif %}
{% if issue_info.argumentation %}
{% if issue_info.argumentation %}
<b><p style="font-style: italic;">{{ 'UserXIndicated'|get_lang|format(issue_info.argumentation_author_name) }} </p></b>
{% endif %}
<p>{{ 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> {{ issue_info.acquired_level }}
</li>
</ul>
{% if 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">
{{ 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(issue_info.comments|length) }}
/
<em class="fa fa-thumbs-o-up fa-fw" aria-hidden="true"></em> {{ 'AverageRatingX'|get_lang|format(issue_info.feedback_average) }}
</div>
<div class="panel-body">
{{ comment_form }}
<hr>
{% for comment in 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(issue_info.comments|length) }}
/
<em class="fa fa-thumbs-o-up fa-fw" aria-hidden="true"></em> {{ 'AverageRatingX'|get_lang|format(issue_info.feedback_average) }}
</p>
{% endif %}
<h4 class="title-badge">{{ 'Description'|get_lang }}</h4>
<p>{{ skill_info.description }}</p>
<h4 class="title-badge">{{ 'CriteriaToEarnTheBadge'|get_lang }}</h4>
<p>{{ skill_info.criteria }}</p>
</div>
</div>
</div>
</div>
{% if allow_export %}
{% if allow_download_export %}
<script>
$(document).on('ready', function () {
$('#badge-export-button').on('click', function (e) {
e.preventDefault();
OpenBadges.issue({{ assertions|json_encode() }});
OpenBadges.issue({{ issue_info.badge_assertion|json_encode() }});
});
});
</script>
{% endif %}
{% endif %}

@ -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.id }}/user/{{ user_id }}" 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>

@ -276,6 +276,11 @@ class Course
**/
protected $currentSession;
/**
* @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\SkillRelUser", mappedBy="course", cascade={"persist"})
*/
protected $issuedSkills;
/**
* Constructor
*/

@ -1,5 +1,13 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Skill Entity
*
* @package chamilo.skill
*/
namespace Chamilo\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
@ -12,6 +20,9 @@ use Doctrine\ORM\Mapping as ORM;
*/
class Skill
{
const STATUS_DISABLED = 0;
const STATUS_ENABLED = 1;
/**
* @var string
*
@ -77,7 +88,24 @@ class Skill
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\SkillBundle\Entity\Profile", inversedBy="skills")
* @ORM\JoinColumn(name="profile_id", referencedColumnName="id")
**/
protected $profile;
/**
* @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\SkillRelUser", mappedBy="skill", cascade={"persist"})
*/
protected $issuedSkills;
/**
* @return string
*/
public function __toString()
{
return (string) $this->getName();
}
/**
* Set name
@ -195,16 +223,25 @@ class Skill
}
/**
* Get the icon URL
* Get the icon (badge image) URL
* @param boolean $getSmall Optional. Allow get the small image
* @return string
*/
public function getWebIconPath()
public function getWebIconPath($getSmall = false)
{
if ($this->getIcon()) {
return api_get_path(WEB_UPLOAD_PATH) . "badges/{$this->getIcon()}";
if ($getSmall) {
if (empty($this->icon)) {
return \Display::return_icon('badges-default.png', null, null, ICON_SIZE_BIG, null, true);
}
return api_get_path(WEB_UPLOAD_PATH) . 'badges/' . sha1($this->name) . '-small.png';
}
if (empty($this->icon)) {
return \Display::return_icon('badges-default.png', null, null, ICON_SIZE_HUGE, null, true);
}
return \Display::return_icon('badges-default.png', null, null, ICON_SIZE_HUGE, null, true);
return api_get_path(WEB_UPLOAD_PATH) . "badges/{$this->icon}";
}
/**
@ -281,4 +318,34 @@ class Skill
{
return $this->id;
}
/**
* @return Profile
*/
public function getProfile()
{
return $this->profile;
}
/**
* @param Profile $profile
*
* @return Skill
*/
public function setProfile($profile)
{
$this->profile = $profile;
return $this;
}
/**
* Get issuedSkills
* @return ArrayCollection
*/
public function getIssuedSkills()
{
return $this->issuedSkills;
}
}

@ -1,5 +1,13 @@
<?php
/* For licensing terms, see /license.txt */
/**
* SkillRelUser Entity
*
* @package chamilo.skill
*/
namespace Chamilo\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
@ -7,7 +15,14 @@ use Doctrine\ORM\Mapping as ORM;
/**
* SkillRelUser
*
* @ORM\Table(name="skill_rel_user", indexes={@ORM\Index(name="idx_select_cs", columns={"course_id", "session_id"})})
* @ORM\Table(
* name="skill_rel_user",
* indexes={
* @ORM\Index(name="idx_select_cs", columns={"course_id", "session_id"}),
* @ORM\Index(name="idx_select_s_c_u", columns={"session_id", "course_id", "user_id"}),
* @ORM\Index(name="idx_select_sk_u", columns={"skill_id", "user_id"})
* }
* )
* @ORM\Entity
*/
class SkillRelUser
@ -26,6 +41,17 @@ class SkillRelUser
*/
private $skillId;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User", inversedBy="achievedSkills", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Skill", inversedBy="issuedSkills", cascade={"persist"})
* @ORM\JoinColumn(name="skill_id", referencedColumnName="id", nullable=false)
*/
private $skill;
/**
* @var \DateTime
*
@ -54,6 +80,18 @@ class SkillRelUser
*/
private $sessionId;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="issuedSkills", cascade={"persist"})
* @ORM\JoinColumn(name="course_id", referencedColumnName="id")
*/
private $course;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session", inversedBy="issuedSkills", cascade={"persist"})
* @ORM\JoinColumn(name="session_id", referencedColumnName="id")
*/
private $session;
/**
* @var integer
*
@ -63,7 +101,37 @@ class SkillRelUser
*/
private $id;
/**
* @var Level
*
* @ORM\ManyToOne(targetEntity="Chamilo\SkillBundle\Entity\Level")
* @ORM\JoinColumn(name="acquired_level", referencedColumnName="id")
*/
private $acquiredLevel;
/**
* @var string
*
* @ORM\Column(name="argumentation", type="text")
*/
private $argumentation;
/**
* @var integer
*
* @ORM\Column(name="argumentation_author_id", type="integer")
*/
private $argumentationAuthorId;
/**
* @ORM\OneToMany(targetEntity="SkillRelUserComment", mappedBy="skillRelUser")
*/
protected $comments;
public function __construct()
{
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set userId
@ -111,6 +179,91 @@ class SkillRelUser
return $this->skillId;
}
/**
* Set user
* @param \Chamilo\UserBundle\Entity\User $user
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setUser(\Chamilo\UserBundle\Entity\User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
* @return \Chamilo\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set skill
* @param \Chamilo\CoreBundle\Entity\Skill $skill
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setSkill(Skill $skill)
{
$this->skill = $skill;
return $this;
}
/**
* Get skill
* @return \Chamilo\CoreBundle\Entity\Skill
*/
public function getSkill()
{
return $this->skill;
}
/**
* Set course
* @param \Chamilo\CoreBundle\Entity\Course $course
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setCourse(Course $course)
{
$this->course = $course;
return $this;
}
/**
* Get course
* @return \Chamilo\CoreBundle\Entity\Course
*/
public function getCourse()
{
return $this->course;
}
/**
* Set session
* @param \Chamilo\CoreBundle\Entity\Session $session
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setSession(Session $session)
{
$this->session = $session;
return $this;
}
/**
* Get session
* @return \Chamilo\CoreBundle\Entity\Session
*/
public function getSession()
{
return $this->session;
}
/**
* Set acquiredSkillAt
*
@ -212,4 +365,166 @@ class SkillRelUser
{
return $this->id;
}
/**
* Set acquiredLevel
* @param \Chamilo\SkillBundle\Entity\Level $acquiredLevel
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setAcquiredLevel($acquiredLevel)
{
$this->acquiredLevel = $acquiredLevel;
return $this;
}
/**
* Get acquiredLevel
* @return \Chamilo\SkillBundle\Entity\Level
*/
public function getAcquiredLevel()
{
return $this->acquiredLevel;
}
/**
* Set argumentationAuthorId
* @param integer $argumentationAuthorId
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setArgumentationAuthorId($argumentationAuthorId)
{
$this->argumentationAuthorId = $argumentationAuthorId;
return $this;
}
/**
* Get argumentationAuthorId
* @return integer
*/
public function getArgumentationAuthorId()
{
return $this->argumentationAuthorId;
}
/**
* Set argumentation
* @param string $argumentation
* @return \Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function setArgumentation($argumentation)
{
$this->argumentation = $argumentation;
return $this;
}
/**
* Get argumentation
* @return string
*/
public function getArgumentation()
{
return $this->argumentation;
}
/**
* Get the source which the skill was obtained
* @return string
*/
public function getSourceName()
{
$source = '';
if ($this->session && $this->session->getId() != 0) {
$source .= "[{$this->session->getName()}] ";
}
if ($this->course) {
$source .= $this->course->getTitle();
}
return $source;
}
/**
* Get the URL for the issue
* @return string
*/
public function getIssueUrl()
{
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()}";
}
/**
* Get the URL for the assertion
* @return string
*/
public function getAssertionUrl()
{
$url = api_get_path(WEB_CODE_PATH) . "badge/assertion.php?";
$url .= http_build_query(array(
'user' => $this->user->getId(),
'skill' => $this->skill->getId(),
'course' => $this->course ? $this->course->getId() : 0,
'session' => $this->session ? $this->session->getId() : 0
));
return $url;
}
/**
* Get comments
* @param boolean $sortDescByDateTime
* @return ArrayCollection
*/
public function getComments($sortDescByDateTime = false)
{
if ($sortDescByDateTime) {
$criteria = \Doctrine\Common\Collections\Criteria::create();
$criteria->orderBy([
'feedbackDateTime' => \Doctrine\Common\Collections\Criteria::DESC
]);
return $this->comments->matching($criteria);
}
return $this->comments;
}
/**
* Calculate the average value from the feedback comments
* @return type
*/
public function getAverage()
{
$sum = 0;
$average = 0;
$countValues = 0;
foreach ($this->comments as $comment) {
if (!$comment->getFeedbackValue()) {
continue;
}
$sum += $comment->getFeedbackValue();
$countValues++;
}
$average = $countValues > 0 ? $sum / $countValues : 0;
return number_format($average, 2);
}
}

@ -0,0 +1,183 @@
<?php
/* For licensing terms, see /license.txt */
/**
* SkillRelUserComment Entity
*
* @package chamilo.skill
*/
namespace Chamilo\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* SkillRelUserComment class
*
* @ORM\Table(
* name="skill_rel_user_comment",
* indexes={
* @ORM\Index(name="idx_select_su_giver", columns={"skill_rel_user_id", "feedback_giver_id"})
* }
* )
* @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Entity\Repository\SkillRelUserCommentRepository")
*/
class SkillRelUserComment
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\SkillRelUser", inversedBy="comments")
* @ORM\JoinColumn(name="skill_rel_user_id", referencedColumnName="id")
*/
private $skillRelUser;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User", inversedBy="commentedUserSkills")
* @ORM\JoinColumn(name="feedback_giver_id", referencedColumnName="id")
*/
private $feedbackGiver;
/**
* @var string
*
* @ORM\Column(name="feedback_text", type="text")
*/
private $feedbackText;
/**
* @var int
*
* @ORM\Column(name="feedback_value", type="integer", nullable=true, options={"default":1})
*/
private $feedbackValue;
/**
* @var \DateTime
*
* @ORM\Column(name="feedback_datetime", type="datetime")
*/
private $feedbackDateTime;
/**
* Get id
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Get skillRelUser
* @return Chamilo\CoreBundle\Entity\SkillRelUser
*/
public function getSkillRelUser()
{
return $this->skillRelUser;
}
/**
* Get feedbackGiver
* @return Chamilo\UserBundle\Entity\User
*/
public function getFeedbackGiver()
{
return $this->feedbackGiver;
}
/**
* Get feedbackText
* @return string
*/
public function getFeedbackText()
{
return $this->feedbackText;
}
/**
* Get feedbackValue
* @return int
*/
public function getFeedbackValue()
{
return $this->feedbackValue;
}
/**
* Get feedbackDateTime
* @return type
*/
public function getFeedbackDateTime()
{
return $this->feedbackDateTime;
}
/**
* Set skillRelUser
* @param \Chamilo\CoreBundle\Entity\SkillRelUser $skillRelUser
* @return \Chamilo\CoreBundle\Entity\SkillRelUserComment
*/
public function setSkillRelUser(SkillRelUser $skillRelUser)
{
$this->skillRelUser = $skillRelUser;
return $this;
}
/**
* Set feedbackGiver
* @param \Chamilo\UserBundle\Entity\User $feedbackGiver
* @return \Chamilo\CoreBundle\Entity\SkillRelUserComment
*/
public function setFeedbackGiver(\Chamilo\UserBundle\Entity\User $feedbackGiver)
{
$this->feedbackGiver = $feedbackGiver;
return $this;
}
/**
* Set feedbackText
* @param string $feedbackText
* @return \Chamilo\CoreBundle\Entity\SkillRelUserComment
*/
public function setFeedbackText($feedbackText)
{
$this->feedbackText = $feedbackText;
return $this;
}
/**
* Set feebackValue
* @param int $feedbackValue
* @return \Chamilo\CoreBundle\Entity\SkillRelUserComment
*/
public function setFeedbackValue($feedbackValue)
{
$this->feedbackValue = $feedbackValue;
return $this;
}
/**
* Set feedbackDateTime
* @param \DateTime $feedbackDateTime
* @return \Chamilo\CoreBundle\Entity\SkillRelUserComment
*/
public function setFeedbackDateTime(\DateTime $feedbackDateTime)
{
$this->feedbackDateTime = $feedbackDateTime;
return $this;
}
}

@ -0,0 +1,160 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\SkillBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
/**
* Level
*
* @ORM\Table(
* name="skill_level",
* )
* @ORM\Entity
*/
class Level
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
/**
* @Gedmo\SortablePosition
* @ORM\Column(name="position", type="integer")
*/
protected $position;
/**
* @var string
*
* @ORM\Column(name="short_name", type="string", length=255, nullable=false)
*/
protected $shortName;
/**
*
* @Gedmo\SortableGroup
* @ORM\ManyToOne(targetEntity="Chamilo\SkillBundle\Entity\Profile", inversedBy="level")
* @ORM\JoinColumn(name="profile_id", referencedColumnName="id")
**/
protected $profile;
/**
* @return string
*/
public function __toString()
{
return (string) $this->getName();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
* @return Level
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return Level
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return mixed
*/
public function getPosition()
{
return $this->position;
}
/**
* @param mixed $position
* @return Level
*/
public function setPosition($position)
{
$this->position = $position;
return $this;
}
/**
* @return mixed
*/
public function getShortName()
{
return $this->shortName;
}
/**
* @param mixed $shortName
* @return Level
*/
public function setShortName($shortName)
{
$this->shortName = $shortName;
return $this;
}
/**
* @return Profile
*/
public function getProfile()
{
return $this->profile;
}
/**
* @param mixed $profile
* @return Level
*/
public function setProfile($profile)
{
$this->profile = $profile;
return $this;
}
}

@ -0,0 +1,133 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Profile Entity
*
* @package chamilo.skill
*/
namespace Chamilo\SkillBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Profile
*
* @ORM\Table(
* name="skill_level_profile",
* )
* @ORM\Entity
*/
class Profile
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
/**
* @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\Skill", mappedBy="profile", cascade={"persist"})
**/
protected $skills;
/**
* @ORM\OneToMany(targetEntity="Chamilo\SkillBundle\Entity\Level", mappedBy="profile", cascade={"persist"})
* @ORM\OrderBy({"position" = "ASC"})
**/
protected $levels;
public function __toString()
{
return (string) $this->getName();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
* @return Profile
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return Profile
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return mixed
*/
public function getSkills()
{
return $this->skills;
}
/**
* @param mixed $skills
* @return Profile
*/
public function setSkills($skills)
{
$this->skills = $skills;
return $this;
}
/**
* @return mixed
*/
public function getLevels()
{
return $this->levels;
}
/**
* @param mixed $levels
* @return Profile
*/
public function setLevels($levels)
{
$this->levels = $levels;
return $this;
}
}

@ -1,6 +1,13 @@
<?php
/* For licensing terms, see /license.txt */
/**
* User Entity
*
* @package chamilo.User
*/
namespace Chamilo\UserBundle\Entity;
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
@ -440,6 +447,16 @@ class User implements UserInterface //implements ParticipantInterface, ThemeUser
**/
protected $sessionCourseSubscriptions;
/**
* @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\SkillRelUser", mappedBy="user", cascade={"persist"})
*/
protected $achievedSkills;
/**
* @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\SkillRelUserComment", mappedBy="feedbackGiver")
*/
protected $commentedUserSkills;
/**
* Constructor
*/
@ -750,6 +767,16 @@ class User implements UserInterface //implements ParticipantInterface, ThemeUser
});*/
}
/**
* Return Complete Name with the Username
*
* @return string
*/
public function getCompleteNameWithUsername()
{
return api_get_person_name($this->firstname, $this->lastname).' ('.$this->username.')';
}
/**
* @todo don't use api_get_person_name
* @return string
@ -2453,4 +2480,30 @@ class User implements UserInterface //implements ParticipantInterface, ThemeUser
$this->id
) = $data;
}
/**
* Get achievedSkills
* @return ArrayCollection
*/
public function getAchievedSkills()
{
return $this->achievedSkills;
}
/**
* Check if the user has the skill
* @param \Chamilo\CoreBundle\Entity\Skill $skill The skill
* @return boolean
*/
public function hasSkill(\Chamilo\CoreBundle\Entity\Skill $skill)
{
$achievedSkills = $this->getAchievedSkills();
foreach ($achievedSkills as $userSkill) {
if ($userSkill->getSkill()->getId() !== $skill->getId()) {
continue;
}
return true;
}
}
}

Loading…
Cancel
Save