Adding first draft of the Skills management; adding skill.lib.php, gradebook.lib.php, adding DB changes (not functional yet) see #1791
parent
228775bfe8
commit
0226119323
@ -0,0 +1,472 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
/** |
||||
* @package chamilo.admin |
||||
*/ |
||||
|
||||
// Language files that need to be included. |
||||
$language_file = array('admin'); |
||||
|
||||
$cidReset = true; |
||||
require_once '../inc/global.inc.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'skill.lib.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'skill.visualizer.lib.php'; |
||||
$this_section = SECTION_PLATFORM_ADMIN; |
||||
|
||||
//api_protect_admin_script(); |
||||
|
||||
//Adds the JS needed to use the jqgrid |
||||
$htmlHeadXtra[] = api_get_jquery_ui_js(true); |
||||
$htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js'); |
||||
|
||||
Display::display_header(); |
||||
//Display::display_reduced_header(); |
||||
|
||||
$skill = new Skill(); |
||||
$skills = $skill->get_all(true); |
||||
$type = 'edit'; //edit |
||||
$skill_visualizer = new SkillVisualizer($skills, $type); |
||||
|
||||
$skill_visualizer->display_html(); |
||||
|
||||
$url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?1=1'; |
||||
//$url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?load_user_data=1'; |
||||
?> |
||||
|
||||
<script> |
||||
jsPlumb.bind("ready", function() { |
||||
$("#dialog-form").dialog({ |
||||
autoOpen: false, |
||||
modal : true, |
||||
width : 550, |
||||
height : 380 |
||||
}); |
||||
|
||||
$.getJSON( "<?php echo $url.'&a=get_skills' ?>", {},
|
||||
function(data) { |
||||
$.each(data, function(n, parent) { |
||||
// add a new option with the JSON-specified value and text |
||||
$("<option />").attr("value", parent.id).text(parent.name).appendTo("#parent_id"); |
||||
}); |
||||
} |
||||
); |
||||
|
||||
$.getJSON( "<?php echo $url.'&a=get_gradebooks' ?>", {},
|
||||
function(data) { |
||||
$.each(data, function(n, gradebook) { |
||||
// add a new option with the JSON-specified value and text |
||||
$("<option />").attr("value", gradebook.id).text(gradebook.name).appendTo("#gradebook_id"); |
||||
}); |
||||
} |
||||
); |
||||
|
||||
|
||||
|
||||
//Filling select |
||||
$("#add_item_link").click(function() { |
||||
$("#dialog-form").dialog("open"); |
||||
$("#gradebook_id").addClass('chzn-select'); |
||||
|
||||
$("#gradebook_id").chosen(); |
||||
$("#parent_id").chosen(); |
||||
}); |
||||
|
||||
var url = '<?php echo $url; ?>';
|
||||
|
||||
var name = $( "#name" ), |
||||
description = $( "#description" ), |
||||
allFields = $( [] ).add( name ).add( description ), tips = $(".validateTips"); |
||||
|
||||
|
||||
$("#dialog-form").dialog({ |
||||
buttons: { |
||||
"Add" : function() { |
||||
var bValid = true; |
||||
bValid = bValid && checkLength( name, "name", 1, 255 ); |
||||
var params = $("#add_item").serialize(); |
||||
|
||||
$.ajax({ |
||||
url: url+'&a=add&'+params, |
||||
success:function(data) { |
||||
|
||||
/*jsPlumb.connect({ |
||||
source : "block_2", |
||||
target : "block_1", |
||||
overlays : overlays |
||||
});*/ |
||||
|
||||
/* |
||||
calEvent.title = $("#name").val(); |
||||
calEvent.start = calEvent.start; |
||||
calEvent.end = calEvent.end; |
||||
calEvent.allDay = calEvent.allDay; |
||||
calEvent.description = $("#content").val(); |
||||
calendar.fullCalendar('updateEvent', |
||||
calEvent, |
||||
true // make the event "stick" |
||||
);*/ |
||||
|
||||
$("#dialog-form").dialog("close"); |
||||
} |
||||
}); |
||||
}, |
||||
}, |
||||
close: function() { |
||||
$("#name").attr('value', ''); |
||||
$("#description").attr('value', ''); |
||||
} |
||||
}); |
||||
|
||||
|
||||
$(".window").bind('click', function() { |
||||
var id = $(this).attr('id'); |
||||
id = id.split('_')[1]; |
||||
//$("#dialog-form").dialog("open"); |
||||
}); |
||||
|
||||
// chrome fix. |
||||
document.onselectstart = function () { return false; }; |
||||
|
||||
// render mode |
||||
var resetRenderMode = function(desiredMode) { |
||||
var newMode = jsPlumb.setRenderMode(desiredMode); |
||||
jsPlumbDemo.init(); |
||||
}; |
||||
resetRenderMode(jsPlumb.CANVAS); |
||||
|
||||
}); |
||||
|
||||
;(function() { |
||||
|
||||
prepare = function(elId, endpoint) { |
||||
jsPlumbDemo.initHover(elId); |
||||
//jsPlumbDemo.initAnimation(elId); |
||||
var e = jsPlumb.addEndpoint(elId, endpoint); |
||||
jsPlumbDemo.initjulio(e); |
||||
|
||||
return e; |
||||
}, |
||||
|
||||
window.jsPlumbDemo = { |
||||
initjulio :function(e) { |
||||
|
||||
}, |
||||
initHover :function(elId) { |
||||
|
||||
$("#" + elId).click(function() { |
||||
var all = jsPlumb.getConnections({source:elId}); |
||||
for (var i = 0; i < discs.length; i++) { |
||||
var d = document.getElementById(discs[i]); |
||||
if (d) d.parentNode.removeChild(d); |
||||
} |
||||
//var all = jsPlumb.getConnections({scope:"DEFAULT", source:elId}); |
||||
|
||||
console.log(all); |
||||
|
||||
//alert(elId); |
||||
// jsPlumb.hide(elId); |
||||
}); |
||||
|
||||
/*$("#" + elId).hover( |
||||
function() { $(this).addClass("bigdot-hover"); }, |
||||
function() { $(this).removeClass("bigdot-hover"); } |
||||
);*/ |
||||
}, |
||||
init : function() { |
||||
|
||||
jsPlumb.Defaults.DragOptions = { cursor: 'pointer', zIndex:2000 }; |
||||
jsPlumb.Defaults.PaintStyle = { strokeStyle:'#666' }; |
||||
jsPlumb.Defaults.EndpointStyle = { width:20, height:16, strokeStyle:'#666' }; |
||||
jsPlumb.Defaults.Endpoint = "Rectangle"; |
||||
jsPlumb.Defaults.Anchors = ["TopCenter", "TopCenter"]; |
||||
|
||||
var connections = []; |
||||
var updateConnections = function(conn, remove) { |
||||
if (!remove) connections.push(conn); |
||||
else { |
||||
var idx = -1; |
||||
for (var i = 0; i < connections.length; i++) { |
||||
if (connections[i] == conn) { |
||||
idx = i; break; |
||||
} |
||||
} |
||||
if (idx != -1) connections.splice(idx, 1); |
||||
} |
||||
if (connections.length > 0) { |
||||
var s = "<span>current connections</span><br/><br/><table><tr><th>scope</th><th>source</th><th>target</th></tr>"; |
||||
for (var j = 0; j < connections.length; j++) { |
||||
s = s + "<tr><td>" + connections[j].scope + "</td>" + "<td>" + connections[j].sourceId + "</td><td>" + connections[j].targetId + "</td></tr>"; |
||||
} |
||||
jsPlumbDemo.showConnectionInfo(s); |
||||
} else |
||||
jsPlumbDemo.hideConnectionInfo(); |
||||
}; |
||||
|
||||
jsPlumb.bind("jsPlumbConnection", function(e) { |
||||
updateConnections(e.connection); |
||||
}); |
||||
jsPlumb.bind("jsPlumbConnectionDetached", function(e) { |
||||
updateConnections(e.connection, true); |
||||
}); |
||||
|
||||
var exampleDropOptions = { |
||||
tolerance:'touch', |
||||
hoverClass:'dropHover', |
||||
activeClass:'dragActive' |
||||
}; |
||||
|
||||
/** |
||||
first example endpoint. it's a 25x21 rectangle (the size is provided in the 'style' arg to the Endpoint), and it's both a source |
||||
and target. the 'scope' of this Endpoint is 'exampleConnection', meaning any connection starting from this Endpoint is of type |
||||
'exampleConnection' and can only be dropped on an Endpoint target that declares 'exampleEndpoint' as its drop scope, and also that |
||||
only 'exampleConnection' types can be dropped here. |
||||
|
||||
the connection style for this endpoint is a Bezier curve (we didn't provide one, so we use the default), with a lineWidth of |
||||
5 pixels, and a gradient. |
||||
|
||||
note the use of the '$.extend' function to setup generic connection types. this will save you a lot of typing, and probably |
||||
errors. |
||||
|
||||
*/ |
||||
// this is the paint style for the connecting lines.. |
||||
var connectorPaintStyle = { |
||||
lineWidth:5, |
||||
strokeStyle:"#deea18", |
||||
joinstyle:"round" |
||||
}; |
||||
// .. and this is the hover style. |
||||
var connectorHoverStyle = { |
||||
lineWidth:7, |
||||
strokeStyle:"#2e2aF8" |
||||
}; |
||||
|
||||
|
||||
jsPlumb.Defaults.Overlays = [ |
||||
[ "Arrow", { location:0.9 } ], |
||||
[ "Label", { |
||||
location:0.1, |
||||
label:function(label) { |
||||
return label.connection.labelText || ""; |
||||
}, |
||||
cssClass:"aLabel", |
||||
|
||||
}] |
||||
]; |
||||
|
||||
//Settings when editing stuff |
||||
var edit_arrow_color = '#ccc'; |
||||
var editEndpoint = { |
||||
//connectorStyle:connectorPaintStyle, |
||||
connector:[ "Flowchart", { stub:40 } ], |
||||
hoverPaintStyle:connectorHoverStyle, |
||||
connectorHoverStyle:connectorHoverStyle, |
||||
anchors: ['BottomCenter','TopCenter'], |
||||
endpoint:"Rectangle", |
||||
paintStyle:{ width:25, height:21, fillStyle:edit_arrow_color }, |
||||
isSource:true, |
||||
scope:'blue rectangle', |
||||
maxConnections:10, |
||||
connectorStyle : { |
||||
gradient:{stops:[[0, edit_arrow_color], [0.5, edit_arrow_color], [1, edit_arrow_color]]}, //gradient stuff |
||||
lineWidth:5, |
||||
strokeStyle: edit_arrow_color |
||||
}, |
||||
isTarget:true, |
||||
dropOptions : exampleDropOptions |
||||
}; |
||||
|
||||
jsPlumb.setMouseEventsEnabled(true); |
||||
|
||||
|
||||
//Default |
||||
var default_arrow_color = '#ccc'; |
||||
var defaultEndpoint = { |
||||
anchors: ['BottomCenter','TopCenter'], |
||||
endpoint:"Rectangle", |
||||
paintStyle:{ width:1, height:1, fillStyle:default_arrow_color }, |
||||
isSource:false, |
||||
scope:'blue rectangle', |
||||
maxConnections:10, |
||||
connectorStyle : { |
||||
gradient:{stops:[[0, default_arrow_color], [0.5, default_arrow_color], [1, default_arrow_color]]}, |
||||
lineWidth:5, |
||||
strokeStyle:default_arrow_color |
||||
}, |
||||
isTarget:false, |
||||
setDraggableByDefault : false, |
||||
}; |
||||
|
||||
|
||||
// Done end point |
||||
var done_arrow_color = '#73982C'; |
||||
var doneEndpoint = { |
||||
endpoint:"Rectangle", |
||||
paintStyle:{ width:1, height:1, fillStyle:done_arrow_color}, |
||||
isSource:false, |
||||
scope:'blue rectangle', |
||||
maxConnections:10, |
||||
connectorStyle : { |
||||
gradient:{stops:[[0, done_arrow_color], [0.5, done_arrow_color], [1, done_arrow_color]]}, |
||||
lineWidth:5, |
||||
strokeStyle:done_arrow_color |
||||
}, |
||||
isTarget:false, |
||||
setDraggableByDefault : false, |
||||
|
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
<?php $skill_visualizer->display_js();?> |
||||
// three ways to do this - an id, a list of ids, or a selector (note the two different types of selectors shown here...anything that is valid jquery will work of course) |
||||
//jsPlumb.draggable("window1"); |
||||
//jsPlumb.draggable(["window1", "window2"]); |
||||
//jsPlumb.draggable($("#window1")); |
||||
var divsWithWindowClass = jsPlumbDemo.getSelector(".window"); |
||||
jsPlumb.draggable(divsWithWindowClass); |
||||
|
||||
// add the third example using the '.window' class. |
||||
//jsPlumb.addEndpoint(divsWithWindowClass, exampleEndpoint3); |
||||
|
||||
// each library uses different syntax for event stuff, so it is handed off |
||||
// to the draggableConnectorsDemo-<library>.js files. |
||||
jsPlumbDemo.attachBehaviour(); |
||||
} |
||||
}; |
||||
|
||||
})(); |
||||
|
||||
|
||||
|
||||
|
||||
$(document).ready( function() { |
||||
//When creating a connection see |
||||
//http://jsplumb.org/apidocs/files/jsPlumb-1-3-2-all-js.html#bind |
||||
jsPlumb.bind("jsPlumbConnection", function(conn) { |
||||
alert("Connection created " + conn.sourceId + " to " + conn.targetId + " "); |
||||
//jsPlumb.detach(conn); |
||||
}); |
||||
//When double clicking a connection |
||||
jsPlumb.bind("click", function(conn) { |
||||
if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?")) |
||||
jsPlumb.detach(conn); |
||||
}); |
||||
|
||||
//When double clicking a connection |
||||
jsPlumb.bind("click", function(endpoint) { |
||||
if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?")) |
||||
jsPlumb.detach(conn); |
||||
}) |
||||
|
||||
|
||||
|
||||
}); |
||||
|
||||
;(function() { |
||||
|
||||
jsPlumbDemo.showConnectionInfo = function(s) { |
||||
$("#list").html(s); |
||||
$("#list").fadeIn({complete:function() { jsPlumb.repaintEverything(); }}); |
||||
}; |
||||
|
||||
jsPlumbDemo.hideConnectionInfo = function() { |
||||
$("#list").fadeOut({complete:function() { jsPlumb.repaintEverything(); }}); |
||||
}; |
||||
|
||||
jsPlumbDemo.getSelector = function(spec) { |
||||
return $(spec); |
||||
}; |
||||
|
||||
jsPlumbDemo.attachBehaviour = function() { |
||||
$(".hide").click(function() { |
||||
jsPlumb.toggle($(this).attr("rel")); |
||||
}); |
||||
|
||||
$(".drag").click(function() { |
||||
var s = jsPlumb.toggleDraggable($(this).attr("rel")); |
||||
$(this).html(s ? 'disable dragging' : 'enable dragging'); |
||||
if (!s) $("#" + $(this).attr("rel")).addClass('drag-locked'); else $("#" + $(this).attr("rel")).removeClass('drag-locked'); |
||||
$("#" + $(this).attr("rel")).css("cursor", s ? "pointer" : "default"); |
||||
}); |
||||
|
||||
$(".detach").click(function() { |
||||
jsPlumb.detachAll($(this).attr("rel")); |
||||
}); |
||||
|
||||
$("#clear").click(function() { |
||||
jsPlumb.detachEverything(); showConnections(); |
||||
}); |
||||
}; |
||||
|
||||
})(); |
||||
|
||||
function checkLength( o, n, min, max ) { |
||||
if ( o.val().length > max || o.val().length < min ) { |
||||
o.addClass( "ui-state-error" ); |
||||
updateTips( "Length of " + n + " must be between " + |
||||
min + " and " + max + "." ); |
||||
return false; |
||||
} else { |
||||
return true; |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<a class="a_button gray" id="add_item_link" href="#">Add item</a> |
||||
|
||||
<div id="dialog-form" style="display:none;"> |
||||
<div style="width:500px"> |
||||
<form id="add_item" name="form"> |
||||
<div class="row"> |
||||
<div class="label"> |
||||
<label for="name">Name</label> |
||||
</div> |
||||
<div class="formw"> |
||||
<input type="text" name="name" id="name" size="40" /> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="label"> |
||||
<label for="name">Parent</label> |
||||
</div> |
||||
<div class="formw"> |
||||
<select id="parent_id" name="parent_id" /> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="row"> |
||||
<div class="label"> |
||||
<label for="name">Gradebook</label> |
||||
</div> |
||||
<div class="formw"> |
||||
<select id="gradebook_id" name="gradebook_id[]" multiple="multiple" /> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="label"> |
||||
<label for="name">Description</label> |
||||
</div> |
||||
<div class="formw"> |
||||
<textarea name="description" id="description" cols="40" rows="7"></textarea> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
<?php
|
||||
|
||||
Display::display_footer(); |
||||
|
||||
// The header. |
||||
/* |
||||
$tpl = new Template(); |
||||
|
||||
$tpl->assign('content', $content); |
||||
$tpl->display_one_col_template(); |
||||
|
||||
* |
||||
*/ |
||||
@ -0,0 +1,84 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
/** |
||||
* @package chamilo.admin |
||||
*/ |
||||
|
||||
// Language files that need to be included. |
||||
$language_file = array('admin'); |
||||
|
||||
$cidReset = true; |
||||
require_once '../inc/global.inc.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'skill.lib.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'gradebook.lib.php'; |
||||
|
||||
$this_section = SECTION_PLATFORM_ADMIN; |
||||
|
||||
api_protect_admin_script(); |
||||
//Adds the JS needed to use the jqgrid |
||||
$htmlHeadXtra[] = api_get_jquery_ui_js(true); |
||||
|
||||
Display::display_header(); |
||||
|
||||
// setting breadcrumbs |
||||
$interbreadcrumb[]=array('url' => 'index.php','name' => get_lang('PlatformAdmin')); |
||||
$interbreadcrumb[]=array('url' => 'career_dashboard.php','name' => get_lang('CareersAndPromotions')); |
||||
|
||||
|
||||
//jqgrid will use this URL to do the selects |
||||
|
||||
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_gradebooks'; |
||||
|
||||
//The order is important you need to check the the $column variable in the model.ajax.php file |
||||
$columns = array(get_lang('Name'), get_lang('Skills'), get_lang('Actions')); |
||||
|
||||
//Column config |
||||
$column_model = array( |
||||
array('name'=>'name', 'index'=>'name', 'width'=>'200', 'align'=>'left'), |
||||
array('name'=>'skills', 'index'=>'skills', 'width'=>'300', 'align'=>'left','sortable'=>'false'), |
||||
array('name'=>'actions', 'index'=>'actions', 'width'=>'100', 'align'=>'left','formatter'=>'action_formatter','sortable'=>'false') |
||||
); |
||||
//Autowidth |
||||
$extra_params['autowidth'] = 'true'; |
||||
//height auto |
||||
$extra_params['height'] = 'auto'; |
||||
|
||||
//With this function we can add actions to the jgrid (edit, delete, etc) |
||||
$action_links = 'function action_formatter(cellvalue, options, rowObject) { |
||||
return \'<a href="?action=add_skill&id=\'+options.rowId+\'">'.Display::return_icon('addd.gif', get_lang('AddSkill'),'',22).'</a>'. |
||||
'\'; |
||||
}'; |
||||
?> |
||||
<script> |
||||
$(function() { |
||||
<?php
|
||||
// grid definition see the $career->display() function |
||||
echo Display::grid_js('gradebooks', $url,$columns,$column_model,$extra_params, array(), $action_links,true); |
||||
?> |
||||
}); |
||||
</script> |
||||
<?php |
||||
$gradebook = new Gradebook(); |
||||
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'display'; |
||||
switch($action) { |
||||
case 'display': |
||||
$gradebook->display(); |
||||
break; |
||||
case 'add_skill': |
||||
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null; |
||||
$gradebook_info = $gradebook->get($id); |
||||
$url = api_get_self().'?action='.$action.'&id='.$id; |
||||
$form = $gradebook->show_skill_form($id, $url); |
||||
if ($form->validate()) { |
||||
$values = $form->exportValues(); |
||||
$res = $gradebook->update_skills_to_gradebook($values['id'], $values['skill']); |
||||
if ($res) { |
||||
Display::display_confirmation_message(get_lang('ItemAdded')); |
||||
} |
||||
} |
||||
echo Display::tag('h1',$gradebook_info['name']); |
||||
$form->display(); |
||||
break; |
||||
} |
||||
Display::display_footer(); |
||||
@ -0,0 +1,78 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
/** |
||||
* Responses to AJAX calls |
||||
*/ |
||||
|
||||
require_once '../global.inc.php'; |
||||
|
||||
require_once api_get_path(LIBRARY_PATH).'skill.lib.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'gradebook.lib.php'; |
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null; |
||||
|
||||
$skill = new Skill(); |
||||
$gradebook = new Gradebook(); |
||||
$skill_gradebook = new SkillRelGradebook(); |
||||
|
||||
switch ($action) { |
||||
case 'add': |
||||
$skill->add($_REQUEST); |
||||
break; |
||||
case 'find_skills': |
||||
$tag = Database::escape_string($_REQUEST['tag']); |
||||
$skills = $skill->find('all', array('where' => array('name LIKE %?% '=>$_REQUEST['tag']))); |
||||
$return_skills = array(); |
||||
foreach($skills as $skill) { |
||||
$skill['caption'] = $skill['name']; |
||||
$skill['value'] = $skill['id']; |
||||
$return_skills[] = $skill; |
||||
} |
||||
echo json_encode($return_skills); |
||||
break; |
||||
case 'get_gradebooks': |
||||
$gradebooks = $gradebook_list = $gradebook->get_all(); |
||||
/*$gradebook_list = array(); |
||||
if (!empty($gradebooks)) { |
||||
foreach($gradebooks as $gradebook) { |
||||
if ($gradebook['parent_id'] == 0) { |
||||
$gradebook['name'] = $gradebook['name']; |
||||
$gradebook_list[] = $gradebook; |
||||
} else { |
||||
// $gradebook['name'] = $gradebook_list[$gradebook['parent_id']]['name'].' > '.$gradebook['name']; |
||||
$gradebook_list[] = $gradebook; |
||||
} |
||||
|
||||
} |
||||
}*/ |
||||
echo json_encode($gradebook_list); |
||||
break; |
||||
case 'get_skills': |
||||
$load_user_data = isset($_REQUEST['load_user_data']) ? $_REQUEST['load_user_data'] : null; |
||||
$skills = $skill->get_all($load_user_data); |
||||
echo json_encode($skills); |
||||
break; |
||||
case 'skill_exists': |
||||
$skill_data = $skill->get($_REQUEST['skill_id']); |
||||
if (!empty($skill_data)) { |
||||
echo 1; |
||||
} else { |
||||
echo 0; |
||||
} |
||||
break; |
||||
case 'remove_skill': |
||||
if (!empty($_REQUEST['skill_id']) && !empty($_REQUEST['gradebook_id'])) { |
||||
|
||||
$skill_item = $skill_gradebook->get_skill_info($_REQUEST['skill_id'], $_REQUEST['gradebook_id']); |
||||
if (!empty($skill_item)) { |
||||
$skill_gradebook->delete($skill_item['id']); |
||||
echo 1; |
||||
} |
||||
} else { |
||||
echo 0; |
||||
} |
||||
break; |
||||
default: |
||||
echo ''; |
||||
} |
||||
exit; |
||||
@ -0,0 +1,134 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
/** |
||||
* This class provides methods for the notebook management. |
||||
* Include/require it in your code to use its features. |
||||
* @package chamilo.library |
||||
*/ |
||||
/** |
||||
* Code |
||||
*/ |
||||
|
||||
|
||||
|
||||
|
||||
class Gradebook extends Model { |
||||
var $columns = array('id', 'name','description', 'course_code', 'parent_id'); |
||||
|
||||
public function __construct() { |
||||
$this->table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY); |
||||
$this->table_skill = Database::get_main_table(TABLE_MAIN_SKILL); |
||||
$this->table_skill_rel_gradebook = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK); |
||||
} |
||||
|
||||
public function update_skills_to_gradebook($gradebook_id, $skill_list) { |
||||
|
||||
if (!empty($skill_list)) { |
||||
|
||||
//Cleaning skills |
||||
$skill_list = array_map('intval', $skill_list); |
||||
$skill_list = array_filter($skill_list); |
||||
$skill_gradebook = new SkillRelGradebook(); |
||||
$skill_gradebooks_source = $skill_gradebook->get_all(array('where'=>array('gradebook_id = ?' =>$gradebook_id))); |
||||
$clean_gradebook = array(); |
||||
if (!empty($skill_gradebooks_source)) { |
||||
foreach($skill_gradebooks_source as $source) { |
||||
$clean_gradebook[]= $source['skill_id']; |
||||
} |
||||
} |
||||
if (!empty($clean_gradebook)) { |
||||
$skill_to_remove = array_diff($clean_gradebook, $skill_list); |
||||
} |
||||
|
||||
foreach ($skill_list as $skill_id) { |
||||
$params = array(); |
||||
$params['gradebook_id'] = $gradebook_id; |
||||
$params['skill_id'] = $skill_id; |
||||
if (!$skill_gradebook->exists_gradebook_skill($gradebook_id, $skill_id)) { |
||||
$skill_gradebook->save($params); |
||||
} |
||||
} |
||||
|
||||
if (!empty($skill_to_remove)) { |
||||
foreach($skill_to_remove as $remove) { |
||||
$skill_item = $skill_gradebook->get_skill_info($remove, $gradebook_id); |
||||
$skill_gradebook->delete($skill_item['id']); |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* Returns a Form validator Obj |
||||
* @todo the form should be auto generated |
||||
* @param string url |
||||
* @param string action add, edit |
||||
* @return obj form validator obj |
||||
*/ |
||||
public function show_skill_form($gradebook_id, $url) { |
||||
|
||||
$form = new FormValidator('gradebook_add_skill', 'POST', $url); |
||||
// Settting the form elements |
||||
$header = get_lang('Add'); |
||||
$form->addElement('header', '', $header); |
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : ''; |
||||
$form->addElement('hidden', 'id', $id); |
||||
|
||||
//$status_list = $this->get_status_list(); |
||||
$skill = new Skill(); |
||||
$skills = $skill->get_all(); |
||||
$clean_skill_list = array(); |
||||
foreach ($skills as $skill) { |
||||
$clean_skill_list[$skill['id']] = $skill['name']; |
||||
} |
||||
$form->addElement('select', 'skill', get_lang('Skills'), $clean_skill_list, array('width'=>'450px', 'class'=>'chzn-select','multiple' => 'multiple')); |
||||
|
||||
$selected_skills = self::get_skills_by_gradebook($gradebook_id); |
||||
$clean_selected_skills = array(); |
||||
if (!empty($selected_skills)) { |
||||
foreach($selected_skills as $skill) { |
||||
$clean_selected_skills[] = $skill['id']; |
||||
} |
||||
} |
||||
|
||||
$form->addElement('style_submit_button', 'submit', get_lang('Add'), 'class="save"'); |
||||
|
||||
$form->setDefaults(array('skill'=>$clean_selected_skills)); |
||||
return $form; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
function get_children() { |
||||
} |
||||
|
||||
function get_skills_by_gradebook($gradebook_id) { |
||||
$gradebook_id = intval($gradebook_id); |
||||
$sql = "SELECT skill.id, skill.name FROM {$this->table_skill} skill INNER JOIN {$this->table_skill_rel_gradebook} skill_rel_gradebook |
||||
ON skill.id = skill_rel_gradebook.skill_id |
||||
WHERE skill_rel_gradebook.gradebook_id = $gradebook_id"; |
||||
$result = Database::query($sql); |
||||
$result = Database::store_result($result,'ASSOC'); |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Displays the title + grid |
||||
*/ |
||||
public function display() { |
||||
// action links |
||||
echo '<div class="actions" style="margin-bottom:20px">'; |
||||
echo '<a href="career_dashboard.php">'.Display::return_icon('back.png',get_lang('Back'),'','32').'</a>'; |
||||
// echo '<a href="'.api_get_self().'?action=add">'.Display::return_icon('new_career.png',get_lang('Add'),'','32').'</a>'; |
||||
echo '</div>'; |
||||
echo Display::grid_html('gradebooks'); |
||||
} |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,293 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
/** |
||||
* This class provides methods for the notebook management. |
||||
* Include/require it in your code to use its features. |
||||
* @package chamilo.library |
||||
*/ |
||||
/** |
||||
* Code |
||||
*/ |
||||
|
||||
/** |
||||
* @package chamilo.library |
||||
*/ |
||||
|
||||
define ('SKILL_TYPE_REQUIREMENT', 'required'); |
||||
define ('SKILL_TYPE_ACQUIRED', 'acquired'); |
||||
define ('SKILL_TYPE_BOTH', 'both'); |
||||
|
||||
class SkillRelSkill extends Model { |
||||
var $columns = array('skill_id', 'parent_id','relation_type', 'level'); |
||||
public function __construct() { |
||||
$this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL); |
||||
} |
||||
|
||||
/** |
||||
* Gets an element |
||||
*/ |
||||
public function get_skill_info($id) { |
||||
if (empty($id)) { return array(); } |
||||
$result = Database::select('*',$this->table, array('where'=>array('skill_id = ?'=>intval($id)))); |
||||
return $result; |
||||
} |
||||
|
||||
public function get_skill_parents($skill_id, $add_child_info = true) { |
||||
$skill_id = intval($skill_id); |
||||
$sql = 'SELECT child.* FROM '.$this->table.' child LEFT JOIN '.$this->table.' parent ON child.parent_id = parent.skill_id |
||||
WHERE child.skill_id = '.$skill_id.' '; |
||||
$result = Database::query($sql); |
||||
$skill = Database::store_result($result,'ASSOC'); |
||||
$skill = isset($skill[0]) ? $skill[0] : null; |
||||
|
||||
$parents = array(); |
||||
if (!empty($skill)) { |
||||
if ($skill['parent_id'] != null) { |
||||
$parents = self::get_skill_parents($skill['parent_id']); |
||||
} |
||||
if ($add_child_info) { |
||||
$parents[] = $skill; |
||||
} |
||||
} |
||||
return $parents; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @package chamilo.library |
||||
*/ |
||||
class SkillRelGradebook extends Model { |
||||
var $columns = array('id', 'gradebook_id','skill_id'); |
||||
|
||||
public function __construct() { |
||||
$this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK); |
||||
} |
||||
|
||||
public function exists_gradebook_skill($gradebook_id, $skill_id) { |
||||
$result = $this->find('all', array('where'=>array('gradebook_id = ? AND skill_id = ?' => array($gradebook_id, $skill_id)))); |
||||
if (!empty($result)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Gets an element |
||||
*/ |
||||
public function get_skill_info($skill_id, $gradebook_id) { |
||||
if (empty($skill_id)) { return array(); } |
||||
$result = Database::select('*',$this->table, array('where'=>array('skill_id = ? AND gradebook_id = ? '=>array($skill_id, $gradebook_id))),'first'); |
||||
return $result; |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* @package chamilo.library |
||||
*/ |
||||
class SkillRelUser extends Model { |
||||
var $columns = array('id', 'user_id','skill_id','acquired_skill_at','assigned_by'); |
||||
public function __construct() { |
||||
$this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER); |
||||
} |
||||
} |
||||
|
||||
|
||||
class Skill extends Model { |
||||
var $columns = array('id', 'name','description', 'access_url_id'); |
||||
|
||||
public function __construct() { |
||||
$this->table = Database::get_main_table(TABLE_MAIN_SKILL); |
||||
$this->table_skill_rel_gradebook = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK); |
||||
$this->table_skill_rel_user = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER); |
||||
$this->table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
||||
$this->table_skill_rel_skill = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL); |
||||
$this->table_gradebook = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY); |
||||
} |
||||
|
||||
public function skill_exists($skill_id) { |
||||
|
||||
|
||||
} |
||||
|
||||
function get_all($load_user_data = false) { |
||||
$sql = "SELECT id, name, description, parent_id, relation_type |
||||
FROM {$this->table} skill INNER JOIN {$this->table_skill_rel_skill} skill_rel_skill |
||||
ON skill.id = skill_rel_skill.skill_id "; |
||||
$result = Database::query($sql); |
||||
$skills = array(); |
||||
if (Database::num_rows($result)) { |
||||
while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||
$skill_rel_skill = new SkillRelSkill(); |
||||
$a = $skill_rel_skill->get_skill_parents($row['id']); |
||||
$row['level'] = count($a)-1; |
||||
$row['gradebooks'] = self::get_gradebooks_by_skill($row['id']); |
||||
$skills[$row['id']] = $row; |
||||
} |
||||
} |
||||
|
||||
if ($load_user_data) { |
||||
$passed_skills = $this->get_user_skills(api_get_user_id()); |
||||
|
||||
foreach ($skills as &$skill) { |
||||
$skill['done_by_user'] = 0; |
||||
if (in_array($skill['id'], $passed_skills)) { |
||||
$skill['done_by_user'] = 1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $skills; |
||||
} |
||||
|
||||
function get_gradebooks_by_skill($skill_id) { |
||||
$skill_id = intval($skill_id); |
||||
$sql = "SELECT g.* FROM {$this->table_gradebook} g INNER JOIN {$this->table_skill_rel_gradebook} sg |
||||
ON g.id = sg.gradebook_id |
||||
WHERE sg.skill_id = $skill_id"; |
||||
$result = Database::query($sql); |
||||
$result = Database::store_result($result,'ASSOC'); |
||||
return $result; |
||||
} |
||||
|
||||
public function add($params) { |
||||
if (!isset($params['parent_id'])) { |
||||
$params['parent_id'] = 1; |
||||
} |
||||
$skill_rel_skill = new SkillRelSkill(); |
||||
$skill_rel_gradebook = new SkillRelGradebook(); |
||||
|
||||
//Saving name, description |
||||
$skill_id = $this->save($params); |
||||
if ($skill_id) { |
||||
//Saving skill_rel_skill (parent_id, relation_type) |
||||
$attributes = array( |
||||
'skill_id' => $skill_id, |
||||
'parent_id' => $params['parent_id'], |
||||
'relation_type' => $params['relation_type'], |
||||
//'level' => $params['level'], |
||||
); |
||||
$skill_rel_skill->save($attributes); |
||||
|
||||
if (!empty($params['gradebook_id'])) { |
||||
foreach ($params['gradebook_id'] as $gradebook_id) { |
||||
$attributes = array(); |
||||
$attributes['gradebook_id'] = $gradebook_id; |
||||
$attributes['skill_id'] = $skill_id; |
||||
$skill_rel_gradebook->save($attributes); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* Return true if the user has the skill |
||||
* |
||||
* @param int $userId User's id |
||||
* @param int $skillId Skill's id |
||||
* @param int $checkInParents if true, function will search also in parents of the given skill id |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function user_has_skill($user_id, $skill_id) { |
||||
$skills = $this->get_user_skills($user_id); |
||||
foreach($skills as $my_skill_id) { |
||||
if ($my_skill_id == $skill_id) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public function add_skill_to_user($user_id, $gradebook_id) { |
||||
$skill_gradebook = new SkillRelGradebook(); |
||||
$skill_rel_user = new SkillRelUser(); |
||||
|
||||
$skill_gradebooks = $skill_gradebook->get_all(array('where'=>array('gradebook_id = ?' =>$gradebook_id))); |
||||
if (!empty($skill_gradebooks)) { |
||||
foreach ($skill_gradebooks as $skill_gradebook) { |
||||
$user_has_skill = $this->user_has_skill($user_id, $skill_gradebook['skill_id']); |
||||
if (!$user_has_skill) { |
||||
$params = array( 'user_id' => $user_id, |
||||
'skill_id' => $skill_gradebook['skill_id'], |
||||
'acquired_skill_at' => api_get_utc_datetime(), |
||||
); |
||||
$skill_rel_user->save($params); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public function remove_skill_to_user($user_id) { |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* Get user's skills |
||||
* |
||||
* @param int $userId User's id |
||||
|
||||
|
||||
*/ |
||||
public function get_user_skills($user_id, $get_skill_data = false) { |
||||
$user_id = intval($user_id); |
||||
//$sql = 'SELECT skill.*, user.* FROM '.$this->table_skill_rel_user.' user INNER JOIN '.$this->table_skill.' skill |
||||
|
||||
$sql = 'SELECT DISTINCT s.id, s.name FROM '.$this->table_skill_rel_user.' u INNER JOIN '.$this->table.' s |
||||
ON u.skill_id = s.id |
||||
WHERE user_id = '.$user_id; |
||||
$result = Database::query($sql); |
||||
$skills = Database::store_result($result, 'ASSOC'); |
||||
$clean_skill = array(); |
||||
if (!empty($skills)) { |
||||
foreach ($skills as $skill) { |
||||
if ($get_skill_data) { |
||||
$clean_skill[$skill['id']] = $skill; |
||||
} else { |
||||
$clean_skill[$skill['id']] = $skill['id']; |
||||
} |
||||
} |
||||
} |
||||
return $clean_skill; |
||||
} |
||||
|
||||
|
||||
public static function get_skills_tree($user_id = null) { |
||||
$skills = self::get_all(); |
||||
$refs = array(); |
||||
$skills_tree = null; |
||||
|
||||
// Create references for all nodes |
||||
if (!empty($skills)) { |
||||
foreach($skills as &$skill) { |
||||
if ($skill['parent'] == null) { |
||||
$skill['parent'] = 'root'; |
||||
} |
||||
|
||||
$skill['data'] = array('parent' => $skill['parent']); // because except main keys (id, name, children) others keys are not saved while in the space tree |
||||
|
||||
if ($user_id) { |
||||
$skill['data']['achieved'] = self::user_has_skill($user_id, $skill['id']); |
||||
} |
||||
$refs[$skill['id']] = &$skill; |
||||
} |
||||
|
||||
// Moving node to the children index of their parents |
||||
foreach($skills as $skillInd => &$skill) { |
||||
$refs[$skill['parent']]['children'][] = &$skill; |
||||
} |
||||
|
||||
$skills_tree = array( |
||||
'name' => get_lang('SkillRootName'), |
||||
'id' => 'root', |
||||
'children' => $refs['root']['children'], |
||||
'data' => array() |
||||
); |
||||
} |
||||
unset($skills); |
||||
return $skills_tree; |
||||
} |
||||
} |
||||
@ -0,0 +1,125 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
/** |
||||
* @package chamilo.admin |
||||
*/ |
||||
|
||||
class SkillVisualizer { |
||||
|
||||
private $offsetX = 100; |
||||
private $offsetY = 50; |
||||
|
||||
private $html = ''; |
||||
private $type = 'read'; |
||||
private $js = ''; |
||||
|
||||
function __construct($skills, $type = 'read') { |
||||
$this->skills = $skills; |
||||
$this->type = $type; |
||||
} |
||||
|
||||
function prepare_skill_box($skill, $position, $class) { |
||||
$block_id = $skill['id']; |
||||
$this->html .= '<div id="block_'.$block_id.'" class="window '.$class.'" style="top:' . $position['y'] . 'px; left:' . $position['x'] . 'px;">'; |
||||
$gradebook_string = ''; |
||||
if (!empty($skill['gradebooks'])) { |
||||
foreach($skill['gradebooks'] as $gradebook) { |
||||
$gradebook_string .= Display::span($gradebook['name'], array('class'=>'label_tag notice','style'=>'width:50px')); |
||||
} |
||||
} |
||||
$this->html .= $skill['name'].' '.$gradebook_string; |
||||
|
||||
if ($this->type == 'edit' && $skill['parent_id'] != 0) { |
||||
$this->html .= Display::url(get_lang('Edit'), '#', array('id=>"edit_block_'.$block_id,'class'=>'edit_block')); |
||||
$this->html .= Display::url(get_lang('Add'), '#', array('id=>"edit_block_'.$block_id,'class'=>'edit_block')); |
||||
$this->html .= Display::url(get_lang('Delete'), '#', array('id=>"edit_block_'.$block_id,'class'=>'edit_block')); |
||||
|
||||
} |
||||
$this->html .= '</div>'; |
||||
} |
||||
|
||||
/** |
||||
* Adds a node using jplumb |
||||
*/ |
||||
private function add_item($skill, $position) { |
||||
$block_id = $skill['id']; |
||||
|
||||
|
||||
$end_point = 'readEndpoint'; |
||||
//var_dump($skill); |
||||
$class = 'default_window'; |
||||
|
||||
if ($this->type == 'edit') { |
||||
$end_point = 'editEndpoint'; |
||||
$class = 'edit_window'; |
||||
} else { |
||||
if ($skill['done_by_user'] == 1) { |
||||
$end_point = 'doneEndpoint'; |
||||
$class = 'done_window'; |
||||
} else { |
||||
$end_point = 'defaultEndpoint'; |
||||
} |
||||
} |
||||
$this->prepare_skill_box($skill, $position, $class); |
||||
|
||||
if ($skill['parent_id'] == 0) { |
||||
return; |
||||
} |
||||
|
||||
//default_arrow_color |
||||
|
||||
$this->js .= 'var e'.$block_id.' = prepare("block_' . $block_id.'", '.$end_point.');'."\n"; |
||||
$this->js .= 'var e'.$skill['parent_id'].' = prepare("block_' . $skill['parent_id'].'", '.$end_point.');'."\n";; |
||||
|
||||
$this->js .= 'jsPlumb.connect({source: e'.$block_id.', target:e'.$skill['parent_id'].'});'."\n";; |
||||
} |
||||
|
||||
/** |
||||
* Displays the HTMl part of jplumb |
||||
*/ |
||||
public function display_html() { |
||||
if (empty($this->skills)) { |
||||
return ''; |
||||
} |
||||
$skill_count = sizeof($this->skills); |
||||
//$corner = 360 / $skill_count; |
||||
$count = 0; |
||||
|
||||
$brothers = array(); |
||||
|
||||
|
||||
//$this->add_item($skill, array('x' => $x + $this->offsetX, 'y' => $y + $this->offsetY)); |
||||
foreach ($this->skills as $skill) { |
||||
if (isset($brothers[$skill['parent_id']])) { |
||||
$brothers[$skill['parent_id']] +=2; |
||||
} else { |
||||
$brothers[$skill['parent_id']] = 1; |
||||
} |
||||
//$x = round($this->offsetX * sin(deg2rad($corner * $count))); |
||||
//$y = round($this->offsetY * cos(deg2rad($corner * $count))); |
||||
|
||||
$x = $brothers[$skill['parent_id']]*100; |
||||
$y = $skill['level']*120; |
||||
//$skill['description'] = "{$brothers[$skill['parent_id']]} $x - $y"; |
||||
$this->add_item($skill, array('x' => $this->offsetX + $x, 'y' => $this->offsetY +$y)); |
||||
} |
||||
echo $this->get_html(); |
||||
} |
||||
|
||||
/** |
||||
* Displays the Javascript part of jplumb |
||||
*/ |
||||
public function display_js() { |
||||
echo $this->get_js(); |
||||
} |
||||
|
||||
|
||||
private function get_html() { |
||||
return $this->html; |
||||
} |
||||
|
||||
private function get_js() { |
||||
return $this->js; |
||||
} |
||||
} |
||||
@ -0,0 +1 @@ |
||||
ski |
||||
Loading…
Reference in new issue