Skills: Update legacy code to use the Asset entity.

pull/3959/head
Julio Montoya 4 years ago
parent b2055521e9
commit c6fd81c9cd
  1. 90
      public/main/admin/skill_badge_create.php
  2. 3
      public/main/admin/skill_list.php
  3. 31
      public/main/inc/lib/SkillModel.php
  4. 30
      public/main/template/default/skill/badge_create.html.twig
  5. 75
      public/main/template/default/skill/badge_list.html.twig
  6. 12
      public/main/template/default/skill/list.html.twig
  7. 28
      public/main/template/default/skill/skill_wheel.html.twig
  8. 2
      public/main/template/default/skill/skill_wheel.js.html.twig
  9. 2
      src/CoreBundle/EventListener/AssetListener.php
  10. 6
      src/CoreBundle/Framework/Container.php
  11. 2
      src/CoreBundle/Repository/ExtraFieldValuesRepository.php

@ -2,11 +2,16 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Asset;
use Chamilo\CoreBundle\Framework\Container;
/**
* Show information about Mozilla OpenBadges.
*
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @author Julio Montoya
*/
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
@ -17,10 +22,10 @@ SkillModel::isAllowed();
$this_section = SECTION_PLATFORM_ADMIN;
$skillId = (int) ($_GET['id'] ?? 0);
$objSkill = new SkillModel();
$skill = $objSkill->get($skillId);
$skillRepo = Container::getSkillRepository();
$skill = $skillRepo->find($skillId);
$htmlHeadXtra[] = '<link href="'.api_get_path(WEB_LIBRARY_JS_PATH).'badge-studio/media/css/core.css" rel="stylesheet">';
$htmlHeadXtra[] = '<link href="'.api_get_path(WEB_LIBRARY_JS_PATH).'badge-studio/media/css/core.css" rel="stylesheet">';
// Add badge studio paths
$badgeStudio = [
@ -32,66 +37,36 @@ $badgeStudio = [
];
if ('POST' === $_SERVER['REQUEST_METHOD']) {
$params = [
'id' => $skillId,
];
throw new Exception('implement skill badge');
if ((isset($_FILES['image']) && 0 == $_FILES['image']['error']) ||
!empty($_POST['badge_studio_image'])
(isset($_POST['badge_studio_image']) && !empty($_POST['badge_studio_image']))
) {
/*
$dirPermissions = api_get_permissions_for_new_directories();
$fileName = sha1($skill['name']);
$badgePath = api_get_path(SYS_UPLOAD_PATH).'badges/';
$existsBadgesDirectory = is_dir($badgePath);
if (!$existsBadgesDirectory) {
//$existsBadgesDirectory = api_create_protected_dir('badges', api_get_path(SYS_UPLOAD_PATH));
$assetRepo = Container::getAssetRepository();
$skillRepo->deleteAsset($skill);
$title = sprintf("%s.png", $skill->getName());
$asset = (new Asset())
->setCategory(Asset::SKILL)
->setTitle($title)
;
if (isset($_POST['badge_studio_image']) && !empty($_POST['badge_studio_image'])) {
$badgeImage = base64_decode(
preg_replace('#^data:image/\w+;base64,#i', '', $_POST['badge_studio_image'])
);
$asset = $assetRepo->createFromString($asset, 'image/png', $badgeImage);
}
if ($existsBadgesDirectory) {
if (!empty($skill['icon'])) {
$iconFileAbsolutePath = $badgePath.$skill['icon'];
if (Security::check_abs_path($iconFileAbsolutePath, $badgePath)) {
unlink($badgePath.$skill['icon']);
}
}
$skillImagePath = sprintf("%s%s.png", $badgePath, $fileName);
if (!empty($_POST['badge_studio_image'])) {
$badgeImage = base64_decode(
preg_replace('#^data:image/\w+;base64,#i', '', $_POST['badge_studio_image'])
);
file_put_contents($skillImagePath, $badgeImage);
$skillImage = new Image($skillImagePath);
} else {
$skillImage = new Image($_FILES['image']['tmp_name']);
}
$skillImage->send_image($skillImagePath, -1, 'png');
$skillThumbPath = sprintf("%s%s-small.png", $badgePath, $fileName);
$skillImageThumb = new Image($skillImagePath);
$skillImageThumb->resize(ICON_SIZE_BIG);
$skillImageThumb->send_image($skillThumbPath);
$params['icon'] = sprintf("%s.png", $fileName);
} else {
Display::addFlash(
Display::return_message(
get_lang('The uploaded file could not be saved (perhaps a permission problem?)')
),
'warning'
);
}*/
if (isset($_FILES['image'])) {
$asset = $assetRepo->createFromRequest($asset, $_FILES['image']);
}
$skill->setAsset($asset);
$skillRepo->update($skill);
Display::addFlash(Display::return_message(get_lang('Update successful')));
}
Display::addFlash(Display::return_message(get_lang('Update successful')));
$objSkill->update($params);
header('Location: '.api_get_path(WEB_CODE_PATH).'admin/skill_list.php');
exit;
api_location(api_get_path(WEB_CODE_PATH).'admin/skill_list.php');
}
$interbreadcrumb[] = [
@ -100,6 +75,7 @@ $interbreadcrumb[] = [
];
$interbreadcrumb[] = ['url' => 'skill_list.php', 'name' => get_lang('Manage skills')];
$objSkill = new SkillModel();
$toolbar = $objSkill->getToolBar();
$tpl = new Template(get_lang('Create badge'));

@ -158,10 +158,9 @@ switch ($action) {
}
}
/* View */
$skill = new SkillModel();
$skillList = $skill->getAllSkills();
$extraFieldSearchTagId = isset($_REQUEST['tag_id']) ? $_REQUEST['tag_id'] : 0;
$extraFieldSearchTagId = $_REQUEST['tag_id'] ?? 0;
if ($extraFieldSearchTagId) {
$skills = [];

@ -13,6 +13,7 @@ use Chamilo\CoreBundle\Entity\SkillRelItemRelUser;
use Chamilo\CoreBundle\Entity\SkillRelSkill;
use Chamilo\CoreBundle\Entity\SkillRelUser;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CourseBundle\Entity\CAttendance;
use Chamilo\CourseBundle\Entity\CForumThread;
use Chamilo\CourseBundle\Entity\CLink;
@ -80,7 +81,7 @@ class SkillModel extends Model
// @todo fix badges icons
//$path = api_get_path(WEB_UPLOAD_PATH).'badges/';
$path = '';
if (!empty($result['icon'])) {
/*if (!empty($result['icon'])) {
$iconSmall = sprintf(
'%s-small.png',
sha1($result['name'])
@ -98,15 +99,15 @@ class SkillModel extends Model
$iconMini = Display::returnIconPath('badges-default.png', ICON_SIZE_MEDIUM);
$iconSmall = Display::returnIconPath('badges-default.png', ICON_SIZE_BIG);
$iconBig = Display::returnIconPath('badges-default.png', ICON_SIZE_HUGE);
}
}*/
$result['icon_mini'] = $iconMini;
/*$result['icon_mini'] = $iconMini;
$result['icon_small'] = $iconSmall;
$result['icon_big'] = $iconBig;
$result['img_mini'] = Display::img($iconBig, $result['name'], ['width' => ICON_SIZE_MEDIUM]);
$result['img_big'] = Display::img($iconBig, $result['name']);
$result['img_small'] = Display::img($iconSmall, $result['name']);
$result['img_small'] = Display::img($iconSmall, $result['name']);*/
$result['name'] = self::translateName($result['name']);
$result['short_code'] = self::translateCode($result['short_code']);
@ -297,6 +298,9 @@ class SkillModel extends Model
}
}
$skillRepo = Container::getSkillRepository();
$assetRepo = Container::getAssetRepository();
$sql = "SELECT
s.id,
s.name,
@ -313,21 +317,22 @@ class SkillModel extends Model
$result = Database::query($sql);
$skills = [];
//$webPath = api_get_path(WEB_UPLOAD_PATH);
if (Database::num_rows($result)) {
while ($row = Database::fetch_array($result, 'ASSOC')) {
$skillInfo = self::get($row['id']);
$skillId = $row['id'];
$skill = $skillRepo->find($skillId);
$row['img_mini'] = $skillInfo['img_mini'];
$row['img_big'] = $skillInfo['img_big'];
$row['img_small'] = $skillInfo['img_small'];
$row['asset'] = '';
if ($skill->getAsset()) {
$row['asset'] = $assetRepo->getAssetUrl($skill->getAsset());
}
$row['name'] = self::translateName($row['name']);
$row['short_code'] = self::translateCode($row['short_code']);
$row['name'] = self::translateName($skill->getName());
$row['short_code'] = self::translateCode($skill->getShortCode());
$skillRelSkill = new SkillRelSkillModel();
$parents = $skillRelSkill->getSkillParents($row['id']);
$parents = $skillRelSkill->getSkillParents($skillId);
$row['level'] = count($parents) - 1;
$row['gradebooks'] = $this->getGradebooksBySkill($row['id']);
$row['gradebooks'] = $this->getGradebooksBySkill($skillId);
$skills[$row['id']] = $row;
}
}

@ -37,6 +37,7 @@
});
})();
</script>
<div class="grid grid-cols-2 gap-4">
<div class="col-md-9">
<form action="{{ current_url }}" class="form-horizontal" method="post" enctype="multipart/form-data">
@ -52,7 +53,7 @@
type="file" name="image" id="image" class="help-badges-img" accept="image/*">
</div>
</div>
<div class="form-group collapse" id="badge-studio-frame">
<div class="form-group collapse" id="badge-studio-frame" style="display: none">
<label class="col-sm-2 control-label" for="criteria"></label>
<div class="col-sm-10">
<h1 class="title">Badge Studio</h1>
@ -61,7 +62,8 @@
<div class="row">
<div class="col-md-4">
<h3 class="label"><label for="studio-mask">{{ "Templates" | trans }}</label></h3>
<select name="template" class="form-control" id="studio-template" data-path="{{ badge_studio.templates }}">
<select name="template" class="form-control" id="studio-template"
data-path="{{ badge_studio.templates }}">
<option value="template-1">{{ "Template" | trans }} 1</option>
<option value="template-2">{{ "Template" | trans }} 2</option>
<option value="template-3">{{ "Template" | trans }} 3</option>
@ -684,15 +686,15 @@
<div class="col-md-3">
<div class="openbadges-img" id="badge-container">
<img id="badge-preview"
class="img-fluid" alt="{{ 'Badge preview' | trans }}" src="{{ skill.icon_big }}">
class="img-fluid" alt="{{ 'Badge preview' | trans }}" src="{{ skill.asset }}">
</div>
<div class="create-openbadges">
<button id="btn-open-designer"
class="help-badges btn btn-primary btn-large btn-block"
data-toggle="tooltip" data-placement="bottom"
title="{{ 'Design a new badge, download it from the design tool and upload it on the platform.' | trans }}"
type="button"
class="help-badges btn btn-primary btn-large btn-block"
data-toggle="tooltip" data-placement="bottom"
title="{{ 'Design a new badge, download it from the design tool and upload it on the platform.' | trans }}"
type="button"
>
<em class="fas fa-pencil-alt"></em> {{ 'Design a new badge' | trans }}
</button>
@ -703,16 +705,20 @@
data-toggle="collapse" data-target="#badge-studio-frame" aria-expanded="false"
aria-controls="badge-studio-frame"
title="{{ 'Use the Badge Studio to create your own badge from within your platform' | trans }}"
type="button">
type="button"
>
<em class="fa fa-cogs"></em> {{ 'Design with Badge Studio' | trans }}
</button>
</div>
</div>
</div>
{{ badge_studio.script_js }}
<script>
$(function() {
$('#btn-open-badge-studio').click(function () {
$('#badge-studio-frame').toggle();
});
$('#set-custom-badge').click(function () {
var data = $('#raster').attr('src');
$('#badge_studio_image').val(data);
@ -726,3 +732,7 @@
});
})
</script>
{% autoescape false %}
{{ badge_studio.script_js }}
{% endautoescape %}

@ -1,45 +1,44 @@
<div class="col-md-12">
<ul class="nav nav-tabs">
<li>
<a href="{{ _p.web_main }}admin/skill_badge.php">{{ 'Home' | trans }}</a>
</li>
<li class="active">
<a href="{{ _p.web_main }}admin/skill_badge_list.php">{{ "CurrentBadges" | trans }}</a>
</li>
</ul>
<ul class="nav nav-tabs">
<li>
<a href="{{ _p.web_main }}admin/skill_badge.php">{{ 'Home' | trans }}</a>
</li>
<li class="active">
<a href="{{ _p.web_main }}admin/skill_badge_list.php">{{ "Current badges" | trans }}</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
<div class="openbadges-introduction">
<table class="table">
<thead>
<tr>
<th>{{ 'Badges' | trans }}</th>
<th>{{ 'Name' | trans }}</th>
<th>{{ 'Description' | trans }}</th>
<th>{{ 'Actions' | trans }}</th>
</tr>
</thead>
<tbody>
{% for skill in skills %}
<tr>
<td>
{{ skill.img_small }}
</td>
<td>
{{ skill.name }}
</td>
<td>{{ skill.description }}</td>
<td>
<a href="{{ _p.web_main }}admin/skill_badge_create.php?id={{ skill.id }}" class="btn btn-primary btn-sm" title="{{ "CreateBadge" | trans }}">
<em class="fa fa-shield fa-fw"></em>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th>{{ 'Badges' | trans }}</th>
<th>{{ 'Name' | trans }}</th>
<th>{{ 'Description' | trans }}</th>
<th>{{ 'Actions' | trans }}</th>
</tr>
</thead>
<tbody>
{% for skill in skills %}
<tr>
<td>
{{ skill.img_small }}
</td>
<td>
{{ skill.name }}
</td>
<td>{{ skill.description }}</td>
<td>
<a href="{{ _p.web_main }}admin/skill_badge_create.php?id={{ skill.id }}"
class="btn btn-primary btn-sm" title="{{ "Create badge" | trans }}">
<em class="fa fa-shield fa-fw"></em>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>

@ -1,16 +1,16 @@
{% autoescape false %}
{% if tags %}
<div class="row">
<div class="col-md-3" >
<div class="col-md-3">
<select id="tag-filter" class="chzn-select form-control">
<option value="0">{{ 'PleaseSelectAChoice' | trans }}</option>
<option value="0">{{ 'Please make a choice' | trans }}</option>
{% for tag in tags %}
<option value="{{ tag.id }}">{{ tag.tag }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<a id="filter-button" class="btn btn-default">{{ 'FilterByTags' | trans }}</a>
<a id="filter-button" class="btn btn-default">{{ 'Filter by tags' | trans }}</a>
</div>
</div>
<br />
@ -39,7 +39,9 @@
{% for skill in skills %}
<tr>
<td width="50">
{{ skill.img_small }}
{% if skill.asset %}
<img src="{{ skill.asset }}?w=50" />
{% endif %}
</td>
<td width="200">{{ skill.name }}</td>
<td class="text-center">{{ skill.short_code }}</td>
@ -70,7 +72,7 @@
{% else %}
<a
href="{{ url('legacy_main', { 'name' : 'admin/skill_list.php', 'id' : skill.id, 'action': 'disable' }) }}"
class="btn btn-danger btn-sm" title="{{ 'Disable' }}">
class="btn btn-sm" title="{{ 'Disable' }}">
<i class="fas fa-ban"></i>
</a>
{% endif %}

@ -1,3 +1,5 @@
{% import '@ChamiloCore/Macros/box.html.twig' as display %}
{% autoescape false %}
<script>
/* Skill search input in the left menu */
@ -12,7 +14,7 @@
async: false,
success: function (return_value) {
if (return_value == 0) {
alert("{{ 'SkillDoesNotExist'|trans }}");
alert("{{ 'There is no such skill'|trans }}");
//Deleting select option tag
//$("#skill_id option[value="+skill_id+"]").remove();
@ -62,11 +64,11 @@
<td>' + skill_name + '</td>\n\
<td class="text-right">\n\
<div class="btn-group btn-group-sm" data-toggle="buttons">\n\
<label class="btn btn-default ' + activeCondition + '" aria-label="{{ 'Select'|trans }}" title="{{ 'SelectToSearch'|trans }}">\n\
<label class="btn btn-default ' + activeCondition + '" aria-label="{{ 'Select'|trans }}" title="{{ 'Select to search'|trans }}">\n\
<input id="skill_to_select_id_' + skill_id + '" data-id="' + skill_id + '" name="' + skill_name + '" class="skill_to_select" type="checkbox" autocomplete="off" ' + checked_condition + '>\n\
<span class="' + iconClassCondition + '" aria-hidden="true"></span>\n\
</label>\n\
<button class="btn btn-default load_wheel" aria-label="{{ 'Search'|trans }}" title="{{ 'PlaceOnTheWheel'|trans }}" data-id="' + skill_id + '">\n\
<button class="btn btn-default load_wheel" aria-label="{{ 'Search'|trans }}" title="{{ 'Place on the wheel'|trans }}" data-id="' + skill_id + '">\n\
<span class="fa fa-crosshairs fa-fw" aria-hidden="true"></span>\n\
</button>\n\
</div>\n\
@ -377,7 +379,7 @@
}
},
cache: false,
placeholder: '{{ 'EnterTheSkillNameToSearch'|trans }}'
placeholder: '{{ 'Enter the skill name to search'|trans }}'
}).on('change', function () {
check_skills_sidebar();
});
@ -532,7 +534,8 @@
<div class="card">
<div class="card-header" role="tab" id="wheel-legend-heading">
<h4 class="card-title">
<a role="button" data-toggle="collapse" data-parent="#wheel-second-accordion" href="#wheel-legend-collapse" aria-expanded="true" aria-controls="wheel-legend-collapse">
<a role="button" data-toggle="collapse" data-parent="#wheel-second-accordion"
href="#wheel-legend-collapse" aria-expanded="true" aria-controls="wheel-legend-collapse">
{{ "Legend"|trans }}
</a>
</h4>
@ -556,8 +559,9 @@
<div class="card">
<div class="card-header" role="tab" id="wheel-display-heading">
<h4 class="card-title">
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#wheel-second-accordion" href="#wheel-display-collapse" aria-expanded="false" aria-controls="wheel-display-collapse">
{{ 'Display Options' | trans }}
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#wheel-second-accordion"
href="#wheel-display-collapse" aria-expanded="false" aria-controls="wheel-display-collapse">
{{ 'Display options' | trans }}
</a>
</h4>
</div>
@ -567,7 +571,7 @@
<ul class="list-unstyled" id="skill-change-background-options">
<li><a href="#" data-color="#FFFFFF">{{ 'White' | trans }}</a></li>
<li><a href="#" data-color="#000000">{{ 'Black' | trans }}</a></li>
<li><a href="#" data-color="#A9E2F3">{{ 'LightBlue' }}</a></li>
<li><a href="#" data-color="#A9E2F3">{{ 'Light blue' }}</a></li>
<li><a href="#" data-color="#848484">{{ 'Gray' | trans }}</a></li>
<li><a href="#" data-color="#F7F8E0">{{ 'Corn' | trans }}</a></li>
</ul>
@ -602,10 +606,10 @@
<em class="fa fa-edit"></em> {{ "Edit" | trans }}
</button>
<button id="form-button-create-child" class="btn btn-primary">
<em class="fa fa-plus"></em> {{ "CreateChildSkill" | trans }}
<em class="fa fa-plus"></em> {{ "Create child skill" | trans }}
</button>
<button id="form-button-add-to-profile" class="btn btn-primary">
<em class="fa fa-check"></em> {{ "AddSkillToProfileSearch" | trans }}
<em class="fa fa-check"></em> {{ "Add skill to profile search" | trans }}
</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">
<em class="fa fa-close"></em> {{ "Close" | trans }}
@ -622,7 +626,9 @@
<button type="button" class="close" data-dismiss="modal" aria-label="{{ "Close" | trans }}">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="form-save-profile-title">{{ "SkillProfile" | trans }}</h4>
<h4 class="modal-title" id="form-save-profile-title">
{{ "Skill profile" | trans }}
</h4>
</div>
<div class="modal-body">
{{ save_profile_form }}

@ -457,7 +457,7 @@ function load_nodes(load_skill_id, main_depth, extra_parent_id) {
/* Add a small label to help the user */
div.append("p")
.attr("id", "intro")
.text("{{ "ClickToZoom"|trans }}");
.text("{{ "Click to zoom"|trans }}");
/* Generate the partition layout */
var partition = d3.layout.partition()

@ -28,7 +28,7 @@ class AssetListener
$folder = $mapping->getFile($asset)->getFilename();
// Deletes scorm folder: example: assets/scorm/myABC .
if (Asset::SCORM === $asset->getCategory() && !empty($folder)) {
if (!empty($folder) && Asset::SCORM === $asset->getCategory()) {
$folder = Asset::SCORM.'/'.$folder;
$this->assetRepository->getFileSystem()->deleteDirectory($folder);
}

@ -23,6 +23,7 @@ use Chamilo\CoreBundle\Repository\PromotionRepository;
use Chamilo\CoreBundle\Repository\SequenceRepository;
use Chamilo\CoreBundle\Repository\SequenceResourceRepository;
use Chamilo\CoreBundle\Repository\SessionRepository;
use Chamilo\CoreBundle\Repository\SkillRepository;
use Chamilo\CoreBundle\Repository\SysAnnouncementRepository;
use Chamilo\CoreBundle\Serializer\UserToJsonNormalizer;
use Chamilo\CoreBundle\Settings\SettingsManager;
@ -493,6 +494,11 @@ class Container
return self::$container->get(SessionRepository::class);
}
public static function getSkillRepository(): SkillRepository
{
return self::$container->get(SkillRepository::class);
}
public static function getSurveyRepository(): CSurveyRepository
{
return self::$container->get(CSurveyRepository::class);

@ -12,8 +12,6 @@ use Doctrine\ORM\Query\Expr\Join;
use Doctrine\Persistence\ManagerRegistry;
/**
* ExtraFieldValuesRepository class.
*
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
*/
class ExtraFieldValuesRepository extends ServiceEntityRepository

Loading…
Cancel
Save