From 0226119323e109e91b23aaa5aa2beeeb3792a577 Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Mon, 31 Oct 2011 18:48:25 +0100 Subject: [PATCH] Adding first draft of the Skills management; adding skill.lib.php, gradebook.lib.php, adding DB changes (not functional yet) see #1791 --- index.php | 7 + main/admin/index.php | 4 + main/admin/promotions.php | 1 - main/admin/skills.php | 472 ++++++++++++++++++ main/admin/skills_gradebook.php | 84 ++++ main/css/base.css | 60 ++- main/gradebook/gradebook_add_cat.php | 67 +++ main/gradebook/gradebook_edit_cat.php | 77 ++- main/gradebook/index.php | 6 +- main/gradebook/lib/be/category.class.php | 60 ++- main/gradebook/lib/fe/catform.class.php | 39 +- main/gradebook/lib/fe/displaygradebook.php | 2 +- .../gradebook/lib/fe/gradebooktable.class.php | 9 +- .../lib/gradebook_data_generator.class.php | 9 +- .../gradebook/lib/gradebook_functions.inc.php | 16 +- main/inc/ajax/agenda.ajax.php | 79 +-- main/inc/ajax/model.ajax.php | 41 +- main/inc/ajax/skill.ajax.php | 78 +++ main/inc/ajax/user_manager.ajax.php | 3 +- main/inc/lib/certificate.lib.php | 38 +- main/inc/lib/database.constants.inc.php | 8 + main/inc/lib/database.lib.php | 27 +- main/inc/lib/database.mysqli.lib.php | 14 +- main/inc/lib/document.lib.php | 35 +- main/inc/lib/gradebook.lib.php | 134 +++++ main/inc/lib/javascript/tag/style.css | 14 +- main/inc/lib/main_api.lib.php | 13 +- main/inc/lib/skill.lib.php | 293 +++++++++++ main/inc/lib/skill.visualizer.lib.php | 125 +++++ main/inc/lib/userportal.lib.php | 11 + main/install/db_main.sql | 48 +- main/install/migrate-db-1.8.8-1.9.0-pre.sql | 8 + main/lang/english/trad4all.inc.php | 3 + main/messages/new_message.php | 14 +- main/social/home.php | 151 +++--- main/social/skills_tree.php | 1 + main/template/default/layout/layout_2_col.tpl | 1 + user_portal.php | 5 + 38 files changed, 1800 insertions(+), 257 deletions(-) create mode 100644 main/admin/skills.php create mode 100644 main/admin/skills_gradebook.php create mode 100644 main/inc/ajax/skill.ajax.php mode change 100755 => 100644 main/inc/ajax/user_manager.ajax.php mode change 100755 => 100644 main/inc/lib/database.mysqli.lib.php create mode 100644 main/inc/lib/gradebook.lib.php mode change 100755 => 100644 main/inc/lib/javascript/tag/style.css create mode 100644 main/inc/lib/skill.lib.php create mode 100644 main/inc/lib/skill.visualizer.lib.php mode change 100755 => 100644 main/messages/new_message.php mode change 100755 => 100644 main/social/home.php create mode 100644 main/social/skills_tree.php diff --git a/index.php b/index.php index 23e2d83039..e5edb2fdfa 100644 --- a/index.php +++ b/index.php @@ -186,4 +186,11 @@ $controller->tpl->assign('home_page_block', $controller->return_home_page()); $controller->tpl->assign('notice_block', $controller->return_notice()); $controller->tpl->assign('plugin_campushomepage', $controller->return_plugin_campushomepage()); +if (api_is_platform_admin() || api_is_drh()) { + $controller->tpl->assign('skills_block', $controller->return_skills_links()); +} + + + + $controller->tpl->display_two_col_template(); \ No newline at end of file diff --git a/main/admin/index.php b/main/admin/index.php index 94208a02e9..8ef745af14 100644 --- a/main/admin/index.php +++ b/main/admin/index.php @@ -115,6 +115,10 @@ if (api_is_platform_admin()) { $items[] = array('url'=>'course_category.php', 'label' => get_lang('AdminCategories')); $items[] = array('url'=>'subscribe_user2course.php', 'label' => get_lang('AddUsersToACourse')); $items[] = array('url'=>'course_user_import.php', 'label' => get_lang('ImportUsersToACourse')); + + $items[] = array('url'=>'skills.php', 'label' => get_lang('SkillsTree')); + $items[] = array('url'=>'skills_gradebook.php', 'label' => get_lang('SkillsGradebook')); + if (isset($extAuthSource) && isset($extAuthSource['ldap']) && count($extAuthSource['ldap']) > 0) { $items[] = array('url'=>'ldap_import_students.php', 'label' => get_lang('ImportLDAPUsersIntoCourse')); diff --git a/main/admin/promotions.php b/main/admin/promotions.php index b50e23d9b9..02a4e34d77 100644 --- a/main/admin/promotions.php +++ b/main/admin/promotions.php @@ -10,7 +10,6 @@ $language_file = array('admin'); $cidReset = true; require_once '../inc/global.inc.php'; -require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php'; require_once api_get_path(LIBRARY_PATH).'promotion.lib.php'; require_once api_get_path(LIBRARY_PATH).'career.lib.php'; diff --git a/main/admin/skills.php b/main/admin/skills.php new file mode 100644 index 0000000000..f0146f51b8 --- /dev/null +++ b/main/admin/skills.php @@ -0,0 +1,472 @@ +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'; +?> + + + +Add item + + +assign('content', $content); +$tpl->display_one_col_template(); + + * + */ \ No newline at end of file diff --git a/main/admin/skills_gradebook.php b/main/admin/skills_gradebook.php new file mode 100644 index 0000000000..9a20a76580 --- /dev/null +++ b/main/admin/skills_gradebook.php @@ -0,0 +1,84 @@ + '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 \''.Display::return_icon('addd.gif', get_lang('AddSkill'),'',22).''. + '\'; + }'; +?> + +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(); diff --git a/main/css/base.css b/main/css/base.css index 6d9bcf80f5..e42b699d85 100644 --- a/main/css/base.css +++ b/main/css/base.css @@ -3240,7 +3240,7 @@ div.admin_section h4 { /* chosen javascript checkbox select width fix */ .chzn-select { - width: 200px; + min-width: 250px; } #lp_item_list { width:90%; @@ -3785,8 +3785,9 @@ form div.error input, form div.error textarea { } .label_tag { - /* padding: 1px 3px 2px; */ - padding:5px; + padding: 1px 3px 2px; + margin-right:3px; + /* padding:5px;*/ background-color: #bfbfbf; font-size: 9.75px; font-weight: bold; @@ -3878,4 +3879,55 @@ form div.error input, form div.error textarea { .lp_content_type_label { font-style: italic; color:#999; -} \ No newline at end of file +} + + +/* Plumb */ + +.window { + cursor:pointer; + box-shadow: 2px 2px 19px #aaa; + -o-box-shadow: 2px 2px 19px #aaa; + -webkit-box-shadow: 2px 2px 19px #aaa; + -moz-box-shadow: 2px 2px 19px #aaa; +} + +.window { + background-color: white; + border: 0.1em dotted #D4E06B; + color: black; + font-family: helvetica,sans; + font-size: 0.9em; + height: 4em; + opacity: 0.8; + padding-top: 0.9em; + position: absolute; + text-align: center; + width: 100px; + z-index: 40; +} + +.done_window { + background-color: #73982C; +} + +._jsPlumb_endpoint { + z-index: 50; +} + +.drag-locked { + border: 1px solid red; +} +._jsPlumb_endpoint { + z-index: 50; +} +._jsPlumb_connector { + z-index: 1; +} +.dropHover { + border: 1px dotted red; +} + +.dragActive { + border: 2px dotted orange; +} diff --git a/main/gradebook/gradebook_add_cat.php b/main/gradebook/gradebook_add_cat.php index c8a3855df7..ba778d79f6 100644 --- a/main/gradebook/gradebook_add_cat.php +++ b/main/gradebook/gradebook_add_cat.php @@ -20,6 +20,71 @@ require_once 'lib/gradebook_functions.inc.php'; require_once 'lib/fe/catform.class.php'; api_block_anonymous_users(); block_students(); + + + + +$htmlHeadXtra[] = ''; +$htmlHeadXtra[] = ''; + +$htmlHeadXtra[] = ''; + $get_select_cat = intval($_GET['selectcat']); $catadd = new Category(); @@ -56,6 +121,8 @@ if ($form->validate()) { } //Always add the gradebook to the course $cat->set_course_code(api_get_course_id()); + + $cat->set_skills($values['skills']); $cat->set_description($values['description']); $cat->set_user_id($values['hid_user_id']); diff --git a/main/gradebook/gradebook_edit_cat.php b/main/gradebook/gradebook_edit_cat.php index 67d31ec888..8e11bbd07f 100644 --- a/main/gradebook/gradebook_edit_cat.php +++ b/main/gradebook/gradebook_edit_cat.php @@ -10,6 +10,7 @@ $language_file = 'gradebook'; require_once '../inc/global.inc.php'; + require_once 'lib/be.inc.php'; require_once 'lib/gradebook_functions.inc.php'; require_once 'lib/fe/catform.class.php'; @@ -18,10 +19,79 @@ api_block_anonymous_users(); block_students(); $edit_cat = isset($_REQUEST['editcat']) ? $_REQUEST['editcat'] : ''; + + +$htmlHeadXtra[] = ''; +$htmlHeadXtra[] = ''; + +$htmlHeadXtra[] = ''; + + $catedit = Category :: load($edit_cat); -$form = new CatForm(CatForm :: TYPE_EDIT, $catedit[0], 'edit_cat_form'); +$form = new CatForm(CatForm :: TYPE_EDIT, $catedit[0], 'edit_cat_form'); + if ($form->validate()) { - $values = $form->exportValues(); + $values = $form->getSubmitValues(); + if (isset($values['skills'])) { + //$res = $gradebook->update_skills_to_gradebook($values['hid_id'], $values['skills']); + } + $cat = new Category(); $cat->set_id($values['hid_id']); $cat->set_name($values['name']); @@ -31,6 +101,9 @@ if ($form->validate()) { $cat->set_course_code($values['course_code']); } $cat->set_description($values['description']); + + $cat->set_skills($values['skills']); + $cat->set_user_id($values['hid_user_id']); $cat->set_parent_id($values['hid_parent_id']); $cat->set_weight($values['weight']); diff --git a/main/gradebook/index.php b/main/gradebook/index.php index 2afb0c2f9a..8811851a2a 100644 --- a/main/gradebook/index.php +++ b/main/gradebook/index.php @@ -63,7 +63,7 @@ $filter_warning_msg = true; ///direct access to one evaluation $cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init - +$first_time = null; if (empty($cats)) { $cats = Category :: load(0, null, $course_code, null, null, $session_id, false);//first time $first_time=1; @@ -618,7 +618,7 @@ if (isset ($_GET['studentoverview'])) { // one) category for this course or for this session. //hack for delete a gradebook from inside course - $clean_deletecat=Security::remove_XSS($_GET['deletecat']); + $clean_deletecat = isset($_GET['deletecat']) ? intval($_GET['deletecat']) : null; if (!empty($clean_deletecat)) { exit; } @@ -765,7 +765,7 @@ if (api_is_allowed_to_edit(null, true)) { } } } -if ($first_time==1 && api_is_allowed_to_edit(null,true)) { +if (isset($first_time) && $first_time==1 && api_is_allowed_to_edit(null,true)) { echo ''; } else { $cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init diff --git a/main/gradebook/lib/be/category.class.php b/main/gradebook/lib/be/category.class.php index 83c2c1fda9..5e07617a60 100644 --- a/main/gradebook/lib/be/category.class.php +++ b/main/gradebook/lib/be/category.class.php @@ -8,10 +8,14 @@ * Class * @package chamilo.gradebook */ + +require_once api_get_path(LIBRARY_PATH).'skill.lib.php'; +require_once api_get_path(LIBRARY_PATH).'gradebook.lib.php'; + class Category implements GradebookItem { -// PROPERTIES + // PROPERTIES private $id; private $name; @@ -23,15 +27,12 @@ class Category implements GradebookItem private $visible; private $certificate_min_score; private $session_id; - - -// CONSTRUCTORS + private $skills = array(); function __construct() { } - -// GETTERS AND SETTERS + // GETTERS AND SETTERS public function get_id() { return $this->id; @@ -54,8 +55,9 @@ class Category implements GradebookItem return $this->certificate_min_score; } else { return null; - } + } } + public function get_course_code() { return $this->course_code; } @@ -114,13 +116,34 @@ class Category implements GradebookItem $this->visible = $visible; } - public function get_type() - { + public function get_type() { return 'category'; } + + public function get_skills($from_db = true) { + if ($from_db) { + $cat_id = $this->get_id(); + + $gradebook = new Gradebook(); + $skills = $gradebook->get_skills_by_gradebook($cat_id); + } else { + $skills = $this->skills; + } + return $skills; + } + + function get_skills_for_select() { + $skills = $this->get_skills(); + $skill_select = array(); + if (!empty($skills)) { + foreach($skills as $skill) { + $skill_select[$skill['id']] = $skill['name']; + } + } + return $skill_select; + } - -// CRUD FUNCTIONS + // CRUD FUNCTIONS /** * Retrieve categories and return them as an array of Category objects @@ -197,7 +220,8 @@ class Category implements GradebookItem $paramcount ++; } //echo $sql; - $result = Database::query($sql); + $result = Database::query($sql); + $allcat = array(); if (Database::num_rows($result) > 0) { $allcat = Category::create_category_objects_from_sql_result($result); } @@ -280,6 +304,10 @@ class Category implements GradebookItem Database::query($sql); $id = Database::insert_id(); $this->set_id($id); + + $gradebook= new Gradebook(); + $res = $gradebook->update_skills_to_gradebook($this->id, $this->get_skills(false)); + return $id; } } @@ -319,6 +347,10 @@ class Category implements GradebookItem .', visible = '.intval($this->is_visible()) .' WHERE id = '.intval($this->id); Database::query($sql); + + $gradebook= new Gradebook(); + $res = $gradebook->update_skills_to_gradebook($this->id, $this->get_skills(false)); + } /** @@ -1097,6 +1129,10 @@ class Category implements GradebookItem public function get_item_type() { return 'C'; } + + public function set_skills($skills) { + $this->skills = $skills; + } public function get_date() { return null; diff --git a/main/gradebook/lib/fe/catform.class.php b/main/gradebook/lib/fe/catform.class.php index 6caeec54a9..124903f3fd 100644 --- a/main/gradebook/lib/fe/catform.class.php +++ b/main/gradebook/lib/fe/catform.class.php @@ -19,10 +19,11 @@ require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php'; class CatForm extends FormValidator { - const TYPE_ADD = 1; - const TYPE_EDIT = 2; - const TYPE_MOVE = 3; - const TYPE_SELECT_COURSE = 4; + const TYPE_ADD = 1; + const TYPE_EDIT = 2; + const TYPE_MOVE = 3; + const TYPE_SELECT_COURSE = 4; + private $category_object; /** @@ -115,11 +116,14 @@ class CatForm extends FormValidator { * Builds an form to edit a category */ protected function build_editing_form() { + $skills = $this->category_object->get_skills_for_select(); + $this->setDefaults(array( 'name' => $this->category_object->get_name(), 'description' => $this->category_object->get_description(), 'hid_user_id' => $this->category_object->get_user_id(), 'hid_parent_id' => $this->category_object->get_parent_id(), + 'skills' => $skills, 'weight' => $this->category_object->get_weight(), 'visible' => $this->category_object->is_visible(), 'certif_min_score' => $this->category_object->get_certificate_min_score(), @@ -138,7 +142,7 @@ class CatForm extends FormValidator { //we can't change the root category $this->freeze('name'); } - $models = api_get_settings_options('grading_model'); + $models = api_get_settings_options('grading_model'); $course_grading_model_id = api_get_course_setting('course_grading_model'); $grading_model = ''; if (!empty($course_grading_model_id)) { @@ -165,13 +169,26 @@ class CatForm extends FormValidator { //$this->addRule('weight',get_lang('ThisFieldIsRequired'),'required'); $this->freeze('weight'); } else { - $this->add_textfield('weight', get_lang('TotalWeight'),true,array('value'=>$value,'size'=>'4','maxlength'=>'5')); + $this->add_textfield('weight', array(get_lang('TotalWeight'), get_lang('TotalSumOfWeights')), true, array('value'=>$value,'size'=>'4','maxlength'=>'5')); $this->addRule('weight',get_lang('ThisFieldIsRequired'),'required'); } - - - $this->addElement('static', null, null, ''.get_lang('TotalSumOfWeights').''); - + + if (api_is_platform_admin() || api_is_drh()) { + //the magic should be here + + $skills = $this->category_object->get_skills(); + $this->addElement('select', 'skills', array(get_lang('SkillsAchievedWhenAchievingThisGradebook')), null, array('id'=>'skills', 'multiple'=>'multiple')); + $content = ''; + if (!empty($skills)) { + foreach($skills as $skill) { + $content .= Display::tag('li', $skill['name'].'', array('id'=>'skill_'.$skill['id'], 'class'=>'bit-box')); + } + } + $this->addElement('html', '
'. + Display::tag('ul', $content, array('class'=>'holder holder_simple')).'
' + ); + } + if (isset($this->category_object) && $this->category_object->get_parent_id() == 0) { $this->add_textfield('certif_min_score', get_lang('CertificateMinScore'),false,array('size'=>'4','maxlength'=>'5')); $this->addRule('certif_min_score', get_lang('ThisFieldIsRequired'), 'required'); @@ -191,7 +208,7 @@ class CatForm extends FormValidator { $this->addElement('hidden','editcat', intval($_GET['editcat'])); $this->addElement('style_submit_button', null, get_lang('EditCategory'), 'class="save"'); } - + if (!empty($grading_contents)) { $this->addRule('weight',get_lang('OnlyNumbers'),'numeric'); $this->addRule('weight',get_lang('NoDecimals'),'nopunctuation'); diff --git a/main/gradebook/lib/fe/displaygradebook.php b/main/gradebook/lib/fe/displaygradebook.php index bec7ea35be..a0646071ad 100644 --- a/main/gradebook/lib/fe/displaygradebook.php +++ b/main/gradebook/lib/fe/displaygradebook.php @@ -553,7 +553,7 @@ class DisplayGradebook $modify_icons .= ''. Display::return_icon('certificate.png', get_lang('AttachCertificate'),'','32').''; - $modify_icons .= ''.Display::return_icon('percentage.png', get_lang('EditAllWeights'),'','32').''; + $modify_icons .= ''.Display::return_icon('percentage.png', get_lang('EditAllWeights'),'','32').''; $modify_icons .= ''.Display::return_icon('ranking.png', get_lang('ScoreEdit'),'','32').''; diff --git a/main/gradebook/lib/fe/gradebooktable.class.php b/main/gradebook/lib/fe/gradebooktable.class.php index 83e25ee1e3..dbf494b364 100644 --- a/main/gradebook/lib/fe/gradebooktable.class.php +++ b/main/gradebook/lib/fe/gradebooktable.class.php @@ -272,10 +272,10 @@ class GradebookTable extends SortableTable { } // warning messages - + $view = isset($_GET['view']) ? $_GET['view']: null; if (api_is_allowed_to_edit()) { - if (isset($_GET['selectcat']) && $_GET['selectcat'] > 0 && $_GET['view'] <> 'presence') { + if (isset($_GET['selectcat']) && $_GET['selectcat'] > 0 && $view <> 'presence') { $id_cat = intval($_GET['selectcat']); $category = Category :: load($id_cat); $weight_category = intval($this->build_weight($category[0])); @@ -292,8 +292,9 @@ class GradebookTable extends SortableTable { } $content_html = DocumentManager::replace_user_info_into_html(api_get_user_id(), $course_code); - - $new_content = explode('',$content_html['content']); + if (!empty($content_html)) { + $new_content = explode('',$content_html['content']); + } if (empty($new_content[0])) { $warning_message = get_lang('ThereIsNotACertificateAvailableByDefault'); diff --git a/main/gradebook/lib/gradebook_data_generator.class.php b/main/gradebook/lib/gradebook_data_generator.class.php index f36b58752d..36bf34ac7f 100644 --- a/main/gradebook/lib/gradebook_data_generator.class.php +++ b/main/gradebook/lib/gradebook_data_generator.class.php @@ -73,7 +73,7 @@ class GradebookDataGenerator } elseif ($sorting & self :: GDG_SORT_WEIGHT) { usort($allitems, array('GradebookDataGenerator', 'sort_by_weight')); } elseif ($sorting & self :: GDG_SORT_DATE) { - usort($allitems, array('GradebookDataGenerator', 'sort_by_date')); + //usort($allitems, array('GradebookDataGenerator', 'sort_by_date')); } if ($sorting & self :: GDG_SORT_DESC) { $allitems = array_reverse($allitems); @@ -154,7 +154,12 @@ class GradebookDataGenerator if(is_int($item1->get_date())) { $timestamp1 = $item1->get_date(); } else { - $timestamp1 = api_strtotime($item1->get_date()); + $date = $item1->get_date(); + if (!empty($date)) { + $timestamp1 = api_strtotime($date); + } else { + $timestamp1 = null; + } } if(is_int($item2->get_date())) { diff --git a/main/gradebook/lib/gradebook_functions.inc.php b/main/gradebook/lib/gradebook_functions.inc.php index 3d9693631e..1a7f46e653 100644 --- a/main/gradebook/lib/gradebook_functions.inc.php +++ b/main/gradebook/lib/gradebook_functions.inc.php @@ -484,21 +484,7 @@ function parse_xml_data($file) { return $users; } -/** -* update user info about certificate -* @param int The category id -* @param int The user id -* @param string the path name of the certificate -* @return void() -*/ -function update_user_info_about_certificate ($cat_id,$user_id,$path_certificate) { - $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); - if (!UserManager::is_user_certified($cat_id,$user_id)) { - $sql='UPDATE '.$table_certificate.' SET path_certificate="'.Database::escape_string($path_certificate).'" - WHERE cat_id="'.intval($cat_id).'" AND user_id="'.intval($user_id).'" '; - $rs=Database::query($sql); - } -} + /** * register user info about certificate diff --git a/main/inc/ajax/agenda.ajax.php b/main/inc/ajax/agenda.ajax.php index bf69394cda..1d422b86df 100644 --- a/main/inc/ajax/agenda.ajax.php +++ b/main/inc/ajax/agenda.ajax.php @@ -6,86 +6,17 @@ require_once '../global.inc.php'; -require_once api_get_path(SYS_CODE_PATH).'calendar/agenda.inc.php'; -require_once api_get_path(SYS_CODE_PATH).'calendar/myagenda.inc.php'; -require_once api_get_path(SYS_CODE_PATH).'calendar/agenda.lib.php'; +require_once api_get_path(LIBRARY_PATH).'skill.lib.php'; $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null; -$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin')) ? $_REQUEST['type'] : 'personal'; -$agenda = new Agenda(); -$agenda->type = $type; +$skill = new Skill(); switch ($action) { - case 'add_event': - //For now we only save personal events - echo $agenda->add_event($_REQUEST['start'], $_REQUEST['end'], $_REQUEST['all_day'], $_REQUEST['view'], $_REQUEST['title'], $_REQUEST['content']); + case 'add': + $skill->add($_REQUEST['name'], $_REQUEST['description'], $_REQUEST['parent']); break; - case 'edit_event': - $id_list = explode('_', $_REQUEST['id']); - //$type = $id_list[0]; - $id = $id_list[1]; - $agenda->edit_event($id, $_REQUEST['start'], $_REQUEST['end'], $_REQUEST['all_day'], $_REQUEST['view'], $_REQUEST['title'], $_REQUEST['content']); - break; - case 'delete_event': - $id_list = explode('_', $_REQUEST['id']); - //$type = $id_list[0]; - $id = $id_list[1]; - $agenda->delete_event($id); - break; - case 'move_event': - $day_delta = $_REQUEST['day_delta']; - $minute_delta = $_REQUEST['minute_delta']; - //$type = $_REQUEST['type'][0]; - $id = explode('_', $_REQUEST['id']); - $id = $id[1]; - $agenda->move_event($id, $day_delta, $minute_delta); - break; - case 'get_events': - $start = $_REQUEST['start']; - $end = $_REQUEST['end']; - $events = $agenda->get_events($start, $end, api_get_user_id(), api_get_course_int_id()); - echo $events; - break; - case 'get_user_agenda': - //Used in the admin user list - api_protect_admin_script(); - - if (api_is_allowed_to_edit(null, true)) { - //@todo move this in the agenda class - $DaysShort = api_get_week_days_short(); - $MonthsLong = api_get_months_long(); - - $user_id = intval($_REQUEST['user_id']); - $my_course_list = CourseManager::get_courses_list_by_user_id($user_id, true); - if (!is_array($my_course_list)) { - // this is for the special case if the user has no courses (otherwise you get an error) - $my_course_list = array(); - } - $today = getdate(); - $year = (!empty($_GET['year'])? (int)$_GET['year'] : NULL); - if ($year == NULL) { - $year = $today['year']; - } - $month = (!empty($_GET['month'])? (int)$_GET['month']:NULL); - if ($month == NULL) { - $month = $today['mon']; - } - $day = (!empty($_GET['day']) ? (int)$_GET['day']:NULL); - if ($day == NULL) { - $day = $today['mday']; - } - $monthName = $MonthsLong[$month -1]; - - $agendaitems = get_myagendaitems($user_id, $my_course_list, $month, $year); - $agendaitems = get_global_agenda_items($agendaitems, $day, $month, $year, $week, "month_view"); - - if (api_get_setting('allow_personal_agenda') == 'true') { - $agendaitems = get_personal_agenda_items($user_id, $agendaitems, $day, $month, $year, $week, "month_view"); - } - display_mymonthcalendar($user_id, $agendaitems, $month, $year, array(), $monthName, false); - } - break; + default: echo ''; } diff --git a/main/inc/ajax/model.ajax.php b/main/inc/ajax/model.ajax.php index 26a65b5521..11f9e7259e 100644 --- a/main/inc/ajax/model.ajax.php +++ b/main/inc/ajax/model.ajax.php @@ -20,10 +20,16 @@ if (!in_array($sord, array('asc','desc'))) { } // get index row - i.e. user click to sort $sord = $_GET['sord']; // get the direction -if(!$sidx) $sidx = 1; +if (!$sidx) $sidx = 1; //2. Selecting the count FIRST +//@todo rework this switch ($action) { + case 'get_gradebooks': + require_once $libpath.'gradebook.lib.php'; + $obj = new Gradebook(); + $count = $obj->get_count(); + break; case 'get_careers': require_once $libpath.'career.lib.php'; $obj = new Career(); @@ -66,12 +72,35 @@ if ($_REQUEST['oper'] == 'del') { $obj->delete($_REQUEST['id']); } - - //4. Querying the DB for the elements $columns = array(); switch ($action) { - case 'get_careers': + case 'get_gradebooks': + $columns = array('name', 'skills', 'actions'); + if(!in_array($sidx, $columns)) { + $sidx = 'name'; + } + $result = Database::select('*', $obj->table, array('order'=>"$sidx $sord", 'LIMIT'=> "$start , $limit")); + $new_result = array(); + foreach($result as $item) { + $skills = $obj->get_skills_by_gradebook($item['id']); + + if (!empty($item['certif_min_score']) && !empty($item['document_id'])) { + $item['name'] .= '* (with_certificate)'; + } else { + $item['name'] .= ' (No certificate)'; + } + $skills_string = ''; + if (!empty($skills)) { + foreach($skills as $skill) { + $item['skills'] .= Display::span($skill['name'], array('class' => 'label_tag success')); + } + } + $new_result[] = $item; + } + $result = $new_result; + break; + case 'get_careers': $columns = array('name', 'description', 'actions'); if(!in_array($sidx, $columns)) { $sidx = 'name'; @@ -84,7 +113,7 @@ switch ($action) { } $new_result[] = $item; } - $result = $new_result; + $result = $new_result; break; case 'get_promotions': @@ -129,7 +158,7 @@ switch ($action) { //var_dump($result); //5. Creating an obj to return a json -if (in_array($action, array('get_careers','get_promotions','get_usergroups'))) { +if (in_array($action, array('get_careers','get_promotions','get_usergroups','get_gradebooks'))) { $response = new stdClass(); $response->page = $page; $response->total = $total_pages; diff --git a/main/inc/ajax/skill.ajax.php b/main/inc/ajax/skill.ajax.php new file mode 100644 index 0000000000..52bf8d3672 --- /dev/null +++ b/main/inc/ajax/skill.ajax.php @@ -0,0 +1,78 @@ +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; \ No newline at end of file diff --git a/main/inc/ajax/user_manager.ajax.php b/main/inc/ajax/user_manager.ajax.php old mode 100755 new mode 100644 index 905e45601e..e2afb63979 --- a/main/inc/ajax/user_manager.ajax.php +++ b/main/inc/ajax/user_manager.ajax.php @@ -14,8 +14,9 @@ switch ($action) { } else { if (UserManager::is_user_id_valid($_GET['user_id'])) { echo 1; + } else { + echo 0; } - echo 0; } break; case 'search_tags': diff --git a/main/inc/lib/certificate.lib.php b/main/inc/lib/certificate.lib.php index e9b582e1eb..e26985dc10 100644 --- a/main/inc/lib/certificate.lib.php +++ b/main/inc/lib/certificate.lib.php @@ -1,4 +1,7 @@ table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); @@ -118,8 +122,6 @@ class Certificate extends Model { * */ public function generate() { - - //The user directory should be set if (empty($this->certification_user_path) && $this->force_certificate_generation == false) { return false; @@ -155,7 +157,7 @@ class Certificate extends Model { if (is_dir($this->certification_user_path)) { if (!empty($this->certificate_data)) { $new_content_html = get_user_certificate_content($this->user_id, $my_category[0]->get_course_code(), false); - + if ($my_category[0]->get_id() == strval(intval($this->certificate_data['cat_id']))) { $name = $this->certificate_data['path_certificate']; $my_path_certificate = $this->certification_user_path.basename($name); @@ -180,8 +182,15 @@ class Certificate extends Model { $result = @file_put_contents($my_path_certificate, $my_new_content_html); if ($result) { - //@todo move function in this class - update_user_info_about_certificate($this->certificate_data['cat_id'], $this->user_id, $path_certificate); + //Updating the path + self::update_user_info_about_certificate($this->certificate_data['cat_id'], $this->user_id, $path_certificate); + + //If the gradebook is related to skills we added the skills to the user + + $skill = new Skill(); + $skill->add_skill_to_user($this->user_id, $this->certificate_data['cat_id']); + + $this->certificate_data['path_certificate'] = $path_certificate; if ($this->html_file_is_generated()) { @@ -199,6 +208,23 @@ class Certificate extends Model { } return false; } + + /** + * update user info about certificate + * @param int The category id + * @param int The user id + * @param string the path name of the certificate + * @return void() + */ + function update_user_info_about_certificate ($cat_id,$user_id,$path_certificate) { + $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); + if (!UserManager::is_user_certified($cat_id,$user_id)) { + $sql='UPDATE '.$table_certificate.' SET path_certificate="'.Database::escape_string($path_certificate).'" + WHERE cat_id="'.intval($cat_id).'" AND user_id="'.intval($user_id).'" '; + $rs = Database::query($sql); + } + } + /** * diff --git a/main/inc/lib/database.constants.inc.php b/main/inc/lib/database.constants.inc.php index 205eae0181..336e907d0b 100644 --- a/main/inc/lib/database.constants.inc.php +++ b/main/inc/lib/database.constants.inc.php @@ -322,3 +322,11 @@ define('TABLE_MAIN_STORED_VALUES_STACK', 'stored_values_stack'); define('TABLE_MAIN_EVENT_TYPE','event_type'); define('TABLE_MAIN_EVENT_TYPE_MESSAGE','event_type_message'); define('TABLE_MAIN_EVENT_TYPE_REL_USER','user_rel_event_type'); + +define('TABLE_MAIN_SKILL', 'skill'); +define('TABLE_MAIN_SKILL_REL_SKILL', 'skill_rel_skill'); +define('TABLE_MAIN_SKILL_REL_GRADEBOOK', 'skill_rel_gradebook'); +define('TABLE_MAIN_SKILL_REL_USER', 'skill_rel_user'); + + + diff --git a/main/inc/lib/database.lib.php b/main/inc/lib/database.lib.php index 0ca280a060..e9c5c0ad04 100644 --- a/main/inc/lib/database.lib.php +++ b/main/inc/lib/database.lib.php @@ -1138,7 +1138,7 @@ class Database { public static function select($columns = '*' , $table_name, $conditions = array(), $type_result = 'all', $option = 'ASSOC') { $conditions = self::parse_conditions($conditions); - + //@todo we could do a describe here to check the columns ... $clean_columns = ''; if (is_array($columns)) { @@ -1152,7 +1152,7 @@ class Database { } $sql = "SELECT $clean_columns FROM $table_name $conditions"; - //echo $sql.'
'; + //echo $sql.'
'; $result = self::query($sql); $array = array(); //if (self::num_rows($result) > 0 ) { @@ -1176,7 +1176,7 @@ class Database { * @param array * @todo lot of stuff to do here */ - public function parse_conditions($conditions) { + public function parse_conditions($conditions) { if (empty($conditions)) { return ''; } @@ -1187,23 +1187,26 @@ class Database { } $type_condition = strtolower($type_condition); switch($type_condition) { - case 'where': - foreach ($condition_data as $condition => $value_array) { + case 'where': + foreach ($condition_data as $condition => $value_array) { if (is_array($value_array)) { $clean_values = array(); foreach($value_array as $item) { $item = Database::escape_string($item); - $clean_values[]= "'$item'"; + $clean_values[]= $item; } } else { $value_array = Database::escape_string($value_array); - $clean_values = "'$value_array'"; + $clean_values = $value_array; } - if (!empty($condition) && !empty($clean_values)) { - //$condition = str_replace('%','@percentage@', $condition); - $condition = str_replace('?','%s', $condition); //we treat everything as string - $condition = vsprintf($condition, $clean_values); - //$condition = str_replace('@percentage@','%', $condition); + + if (!empty($condition) && $clean_values != '') { + $condition = str_replace('%',"'@percentage@'", $condition); //replace "%" + $condition = str_replace("'?'","%s", $condition); //we treat everything as string + //just in case + $condition = str_replace("?","%s", $condition); //we treat everything as string + $condition = vsprintf($condition, $clean_values); + $condition = str_replace('@percentage@','%', $condition); //replace "%" $where_return .= $condition; } } diff --git a/main/inc/lib/database.mysqli.lib.php b/main/inc/lib/database.mysqli.lib.php old mode 100755 new mode 100644 index e3455219b8..121523ceec --- a/main/inc/lib/database.mysqli.lib.php +++ b/main/inc/lib/database.mysqli.lib.php @@ -1132,15 +1132,19 @@ class Database { $clean_values = array(); foreach($value_array as $item) { $item = Database::escape_string($item); - $clean_values[]= "'$item'"; + $clean_values[]= $item; } } else { $value_array = Database::escape_string($value_array); - $clean_values = "'$value_array'"; + $clean_values = $value_array; } - if (!empty($condition) && !empty($clean_values)) { - $condition = str_replace('?','%s', $condition); //we treat everything as string - $condition = vsprintf($condition, $clean_values); + if (!empty($condition) && $clean_values != '') { + $condition = str_replace('%',"'@percentage@'", $condition); //replace "%" + $condition = str_replace("'?'","%s", $condition); //we treat everything as string + //just in case + $condition = str_replace("?","%s", $condition); //we treat everything as string + $condition = vsprintf($condition, $clean_values); + $condition = str_replace('@percentage@','%', $condition); //replace "%" $where_return .= $condition; } } diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php index d5a62a7c84..3891a9c6b3 100755 --- a/main/inc/lib/document.lib.php +++ b/main/inc/lib/document.lib.php @@ -1338,24 +1338,27 @@ return 'application/octet-stream'; $tbl_document = Database::get_course_table(TABLE_DOCUMENT); $course_id = $course_info['real_id']; $document_id = self::get_default_certificate_id($course_code); - - $sql = "SELECT path FROM $tbl_document WHERE c_id = $course_id AND id = $document_id"; - - $rs = Database::query($sql); - $new_content = ''; - $all_user_info = array(); - if (Database::num_rows($rs)) { - $row=Database::fetch_array($rs); - $filepath = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/document'.$row['path']; - if (is_file($filepath)) { - $my_content_html = file_get_contents($filepath); + if ($document_id) { + + $sql = "SELECT path FROM $tbl_document WHERE c_id = $course_id AND id = $document_id"; + + $rs = Database::query($sql); + $new_content = ''; + $all_user_info = array(); + if (Database::num_rows($rs)) { + $row=Database::fetch_array($rs); + $filepath = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/document'.$row['path']; + if (is_file($filepath)) { + $my_content_html = file_get_contents($filepath); + } + $all_user_info = self::get_all_info_to_certificate($user_id, $course_code, $is_preview); + $info_to_be_replaced_in_content_html=$all_user_info[0]; + $info_to_replace_in_content_html=$all_user_info[1]; + $new_content=str_replace($info_to_be_replaced_in_content_html,$info_to_replace_in_content_html, $my_content_html); } - $all_user_info = self::get_all_info_to_certificate($user_id, $course_code, $is_preview); - $info_to_be_replaced_in_content_html=$all_user_info[0]; - $info_to_replace_in_content_html=$all_user_info[1]; - $new_content=str_replace($info_to_be_replaced_in_content_html,$info_to_replace_in_content_html, $my_content_html); + return array('content' => $new_content, 'variables' => $all_user_info); } - return array('content' => $new_content, 'variables' => $all_user_info); + return array(); } /** diff --git a/main/inc/lib/gradebook.lib.php b/main/inc/lib/gradebook.lib.php new file mode 100644 index 0000000000..aecbe83646 --- /dev/null +++ b/main/inc/lib/gradebook.lib.php @@ -0,0 +1,134 @@ +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 '
'; + echo ''.Display::return_icon('back.png',get_lang('Back'),'','32').''; + // echo ''.Display::return_icon('new_career.png',get_lang('Add'),'','32').''; + echo '
'; + echo Display::grid_html('gradebooks'); + } + + +} \ No newline at end of file diff --git a/main/inc/lib/javascript/tag/style.css b/main/inc/lib/javascript/tag/style.css old mode 100755 new mode 100644 index 7715a72096..ad28b9fa2f --- a/main/inc/lib/javascript/tag/style.css +++ b/main/inc/lib/javascript/tag/style.css @@ -1,12 +1,14 @@ /* TextboxList sample CSS */ ul.holder { -moz-border-radius:5px 5px 5px 5px; - -web-kit-border-radius:5px 5px 5px 5px; - + -web-kit-border-radius:5px 5px 5px 5px; margin: 0; border: 1px solid #ccc; overflow: hidden; height: auto !important; height: 1%; padding: 4px 5px 0; } *:first-child+html ul.holder { padding-bottom: 2px; } * html ul.holder { padding-bottom: 2px; } /* ie7 and below */ ul.holder li { float: left; list-style-type: none; margin: 0 5px 4px 0; white-space:nowrap;} -ul.holder li.bit-box, ul.holder li.bit-input input { font: 11px "Lucida Grande", "Verdana"; } +ul.holder li.bit-box, ul.holder li.bit-input input { + font: 11px "Lucida Grande", "Verdana"; + box-shadow: none; +} ul.holder li.bit-box { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; border: 1px solid #CAD8F3; background: #DEE7F8; padding: 1px 5px 2px; } ul.holder li.bit-box-focus { border-color: #598BEC; background: #598BEC; color: #fff; } ul.holder li.bit-input input { @@ -55,4 +57,8 @@ ul.holder li.bit-box-focus a.closebutton, ul.holder li.bit-box-focus a.closebutt .hidden { display:none;} #demo ul.holder li.bit-input input { padding: 2px 0 1px; border: 1px solid #999; } -.ie6fix {height:1px;width:1px; position:absolute;top:0px;left:0px;z-index:1;} \ No newline at end of file +.ie6fix {height:1px;width:1px; position:absolute;top:0px;left:0px;z-index:1;} + +.holder_simple { + border:none !important; +} diff --git a/main/inc/lib/main_api.lib.php b/main/inc/lib/main_api.lib.php index b00c7dd805..de59757f11 100644 --- a/main/inc/lib/main_api.lib.php +++ b/main/inc/lib/main_api.lib.php @@ -1043,11 +1043,13 @@ function api_get_course_setting($setting_name, $course_code = null) { $course_info = api_get_course_info($course_code); $table = Database::get_course_table(TABLE_COURSE_SETTING); $setting_name = Database::escape_string($setting_name); - $sql = "SELECT value FROM $table WHERE c_id = {$course_info['real_id']} AND variable = '$setting_name'"; - $res = Database::query($sql); - if (Database::num_rows($res) > 0) { - $row = Database::fetch_array($res); - return $row['value']; + if (!empty($course_info['real_id']) && !empty($setting_name)) { + $sql = "SELECT value FROM $table WHERE c_id = {$course_info['real_id']} AND variable = '$setting_name'"; + $res = Database::query($sql); + if (Database::num_rows($res) > 0) { + $row = Database::fetch_array($res); + return $row['value']; + } } return -1; } @@ -3792,6 +3794,7 @@ function api_get_settings_options($var) { $table_settings_options = Database :: get_main_table(TABLE_MAIN_SETTINGS_OPTIONS); $sql = "SELECT * FROM $table_settings_options WHERE variable = '$var' ORDER BY id"; $result = Database::query($sql); + $settings_options_array = array(); while ($row = Database::fetch_array($result, 'ASSOC')) { //$temp_array = array ('value' => $row['value'], 'display_text' => $row['display_text']); $settings_options_array[] = $row; diff --git a/main/inc/lib/skill.lib.php b/main/inc/lib/skill.lib.php new file mode 100644 index 0000000000..99576961bc --- /dev/null +++ b/main/inc/lib/skill.lib.php @@ -0,0 +1,293 @@ +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; + } +} \ No newline at end of file diff --git a/main/inc/lib/skill.visualizer.lib.php b/main/inc/lib/skill.visualizer.lib.php new file mode 100644 index 0000000000..6ea82403b5 --- /dev/null +++ b/main/inc/lib/skill.visualizer.lib.php @@ -0,0 +1,125 @@ +skills = $skills; + $this->type = $type; + } + + function prepare_skill_box($skill, $position, $class) { + $block_id = $skill['id']; + $this->html .= '
'; + $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 .= '
'; + } + + /** + * 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; + } +} \ No newline at end of file diff --git a/main/inc/lib/userportal.lib.php b/main/inc/lib/userportal.lib.php index 3ef8b1f651..d67c83bf42 100644 --- a/main/inc/lib/userportal.lib.php +++ b/main/inc/lib/userportal.lib.php @@ -389,6 +389,17 @@ class IndexManager { } return $html; } + + function return_skills_links() { + $content = ''; + + $html = self::show_right_block(get_lang("Skills"), $content); + return $html; + } /** * Reacts on a failed login: diff --git a/main/install/db_main.sql b/main/install/db_main.sql index 43fc4f5c17..bf772be287 100644 --- a/main/install/db_main.sql +++ b/main/install/db_main.sql @@ -850,6 +850,7 @@ VALUES ('drh_autosubscribe', NULL, 'textfield', 'Platform', '', 'DRHAutosubscribeTitle', 'DRHAutosubscribeComment', NULL, NULL, 0), ('sessionadmin_autosubscribe', NULL, 'textfield', 'Platform', '', 'SessionadminAutosubscribeTitle', 'SessionadminAutosubscribeComment', NULL, NULL, 0), ('scorm_cumulative_session_time', NULL, 'radio', 'Course', 'true', 'ScormCumulativeSessionTimeTitle', 'ScormCumulativeSessionTimeComment', NULL, NULL, 0), +('allow_hr_skills_management', NULL, 'radio', 'Gradebook', 'true', 'AllowHRSkillsManagementTitle', 'AllowHRSkillsManagementComment', NULL, NULL, 1), ('chamilo_database_version',NULL,'textfield',NULL, '1.9.0.15858','DokeosDatabaseVersion','', NULL, NULL, 0); /* @@ -1146,7 +1147,10 @@ VALUES ('cas_add_user_activate', 'true', 'Yes'), ('cas_add_user_activate', 'false', 'No'), ('scorm_cumulative_session_time','true','Yes'), -('scorm_cumulative_session_time','false','No'); +('scorm_cumulative_session_time','false','No'), +('allow_hr_skills_management', 'true', 'Yes'), +('allow_hr_skills_management', 'false', 'No'); + /* ('use_custom_pages','true','Yes'), ('use_custom_pages','false','No'), @@ -2737,6 +2741,48 @@ CREATE TABLE notification ( ALTER TABLE notification ADD index mail_notify_sent_index (sent_at); ALTER TABLE notification ADD index mail_notify_freq_index (sent_at, send_freq, created_at); +-- Skills management + +CREATE TABLE skill ( + id int NOT NULL AUTO_INCREMENT, + name varchar(255) NOT NULL, + short_code varchar(100) NOT NULL, + description TEXT NOT NULL, + access_url_id int NOT NULL, + icon varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +INSERT INTO skill VALUES('Root'); + +CREATE TABLE skill_rel_gradebook ( + id int NOT NULL AUTO_INCREMENT, + gradebook_id int NOT NULL, + skill_id int NOT NULL, + type varchar(10) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE skill_rel_skill ( + skill_id int NOT NULL, + parent_id int NOT NULL, + relation_type int NOT NULL, + level int NOT NULL, +); + +INSERT INTO skill_rel_skill VALUES(1, 0, 0); + +CREATE TABLE skill_rel_user ( + id int NOT NULL AUTO_INCREMENT, + user_id int NOT NULL, + skill_id int NOT NULL, + acquired_skill_at datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + assigned_by int NOT NULL, + PRIMARY KEY (id) +); + + + -- -- Table structure for event alert sending -- Pending check and approval diff --git a/main/install/migrate-db-1.8.8-1.9.0-pre.sql b/main/install/migrate-db-1.8.8-1.9.0-pre.sql index e2831e3f65..32d4fb6476 100755 --- a/main/install/migrate-db-1.8.8-1.9.0-pre.sql +++ b/main/install/migrate-db-1.8.8-1.9.0-pre.sql @@ -122,6 +122,14 @@ CREATE TABLE stored_values_stack (user_id INT NOT NULL, sco_id INT NOT NULL, sta ALTER TABLE stored_values_stack ADD KEY (user_id, sco_id, course_id, sv_key, stack_order); ALTER TABLE stored_values_stack ADD UNIQUE (user_id, sco_id, course_id, sv_key, stack_order); +INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('allow_hr_skills_management', NULL, 'radio', 'Gradebook', 'true', 'AllowHRSkillsManagementTitle', 'AllowHRSkillsManagementComment', NULL, NULL, 1); + +INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_hr_skills_management', 'true', 'Yes'); +INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_hr_skills_management', 'false', 'No'); + + + + -- xxUSERxx -- xxCOURSExx diff --git a/main/lang/english/trad4all.inc.php b/main/lang/english/trad4all.inc.php index 250044e73d..d211f3c2ac 100644 --- a/main/lang/english/trad4all.inc.php +++ b/main/lang/english/trad4all.inc.php @@ -1143,4 +1143,7 @@ $NoJava = "Your browser does not support Java"; $JavaSun24 = "Your browser has a Java version not supported by this tool. To use it you have to install a Java Sun version higher than 24"; $NoMessageAnywere = "If you do not like see this message again during this session click here"; + +$SkillsAchievedWhenAchievingThisGradebook = 'Skills Achieved When Achieving This Gradebook'; + ?> \ No newline at end of file diff --git a/main/messages/new_message.php b/main/messages/new_message.php old mode 100755 new mode 100644 index b25214daed..21c5a3e05f --- a/main/messages/new_message.php +++ b/main/messages/new_message.php @@ -21,11 +21,10 @@ require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php'; api_block_anonymous_users(); -if (api_get_setting('allow_message_tool') !='true' ){ +if (api_get_setting('allow_message_tool') !='true') { api_not_allowed(); } -require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php'; require_once api_get_path(LIBRARY_PATH).'group_portal_manager.lib.php'; $nameTools = api_xml_http_response_encode(get_lang('Messages')); @@ -120,16 +119,7 @@ function add_image_form() { } } } - - -'; +'; $nameTools = get_lang('ComposeMessage'); /* FUNCTIONS */ diff --git a/main/social/home.php b/main/social/home.php old mode 100755 new mode 100644 index 1f4da356c6..b0c80fd96c --- a/main/social/home.php +++ b/main/social/home.php @@ -12,6 +12,7 @@ $cidReset = true; require_once '../inc/global.inc.php'; require_once api_get_path(LIBRARY_PATH).'group_portal_manager.lib.php'; +require_once api_get_path(LIBRARY_PATH).'skill.lib.php'; $user_id = api_get_user_id(); $show_full_profile = true; @@ -77,79 +78,109 @@ echo '
'; //this include the social menu div SocialManager::show_social_menu('home'); echo '
'; + + echo '
'; - echo ''; echo '
'; diff --git a/main/social/skills_tree.php b/main/social/skills_tree.php new file mode 100644 index 0000000000..1bbbf7da43 --- /dev/null +++ b/main/social/skills_tree.php @@ -0,0 +1 @@ +ski \ No newline at end of file diff --git a/main/template/default/layout/layout_2_col.tpl b/main/template/default/layout/layout_2_col.tpl index 8554482ab2..281f2fe03e 100644 --- a/main/template/default/layout/layout_2_col.tpl +++ b/main/template/default/layout/layout_2_col.tpl @@ -31,6 +31,7 @@ {$reservation_block} {$search_block} {$classes_block} + {$skills_block} {/block} diff --git a/user_portal.php b/user_portal.php index 06543101ca..b7cefe5001 100644 --- a/user_portal.php +++ b/user_portal.php @@ -236,6 +236,11 @@ $controller->tpl->assign('reservation_block', $controller->return_reservation $controller->tpl->assign('search_block', $controller->return_search_block()); $controller->tpl->assign('classes_block', $controller->return_classes_block()); +if (api_is_platform_admin() || api_is_drh()) { + $controller->tpl->assign('skills_block', $controller->return_skills_links()); +} + + $controller->tpl->display_two_col_template(); // Deleting the session_id.