/** * adds an exercise into the exercise list * * @author - Olivier Brouckaert * @param integer $exerciseId - exercise ID * @param boolean $fromSave - coming from $this->save() or not */ public function addToList($exerciseId, $fromSave = false) { $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); $id = $this->id; // checks if the exercise ID is not in the list if (!in_array($exerciseId, $this->exerciseList)) { $this->exerciseList[] = $exerciseId; $new_exercise = new Exercise(); $new_exercise->read($exerciseId); $count = $new_exercise->selectNbrQuestions(); $count++; $sql = "INSERT INTO {$TBL_EXERCICE_QUESTION} (c_id, question_id, exercice_id, question_order) VALUES\n\t\t\t\t ({$this->course['real_id']}, '" . Database::escape_string($id) . "','" . Database::escape_string($exerciseId) . "', '{$count}' )"; Database::query($sql); // we do not want to reindex if we had just saved adnd indexed the question if (!$fromSave) { $this->search_engine_edit($exerciseId, true); } } }
/** * @param Application $app * @return string */ public function indexAction(Application $app) { $request = $app['request']; $language_file = array('admin', 'exercice', 'gradebook', 'tracking'); // 1. Setting variables needed by jqgrid $action = $request->get('a'); $page = $request->get('page'); //page $limit = $request->get('rows'); //quantity of rows $sidx = $request->get('sidx'); //index (field) to filter $sord = $request->get('sord'); //asc or desc if (strpos(strtolower($sidx), 'asc') !== false) { $sidx = str_replace(array('asc', ','), '', $sidx); $sord = 'asc'; } if (strpos(strtolower($sidx), 'desc') !== false) { $sidx = str_replace(array('desc', ','), '', $sidx); $sord = 'desc'; } if (!in_array($sord, array('asc', 'desc'))) { $sord = 'desc'; } if (!in_array($action, array('get_exercise_results', 'get_hotpotatoes_exercise_results', 'get_work_user_list', 'get_timelines', 'get_user_skill_ranking', 'get_usergroups_teacher', 'get_question_list', 'get_user_list_plugin_widescale'))) { api_protect_admin_script(true); } if ($action == 'get_user_list_plugin_widescale') { $allowed = api_is_drh() || api_is_platform_admin(); if (!$allowed) { api_not_allowed(); } } // Search features. // If there is no search request sent by jqgrid, $where should be empty. $where_condition = ""; $operation = $request->get('oper'); $export_format = $request->get('export_format'); $search_field = $request->get('searchField'); $search_oper = $request->get('searchOper'); $search_string = $request->get('searchString'); $isSearch = $request->get('_search'); $filters = $request->get('filters'); $type = $request->get('type'); $extra_fields = array(); $questionFields = array(); if ($isSearch == 'true') { $where_condition = ' 1 = 1 '; $where_condition_in_form = $this->getWhereClause($search_field, $search_oper, $search_string); if (!empty($where_condition_in_form)) { $where_condition .= ' AND ' . $where_condition_in_form; } $filters = isset($filters) ? json_decode($filters) : false; // for now if (!empty($filters)) { switch ($action) { case 'get_questions': $extraFieldtype = 'question'; break; case 'get_sessions': $extraFieldtype = 'session'; break; } // Extra field. $extraField = new \ExtraField($extraFieldtype); $result = $extraField->getExtraFieldRules($filters, 'extra_'); $extra_fields = $result['extra_fields']; $condition_array = $result['condition_array']; if (!empty($condition_array)) { $where_condition .= ' AND ( '; $where_condition .= implode($filters->groupOp, $condition_array); $where_condition .= ' ) '; } // Question field. $resultQuestion = $extraField->getExtraFieldRules($filters, 'question_'); $questionFields = $resultQuestion['extra_fields']; $condition_array = $resultQuestion['condition_array']; if (!empty($condition_array)) { $where_condition .= ' AND ( '; $where_condition .= implode($filters->groupOp, $condition_array); $where_condition .= ' ) '; } } } // get index row - i.e. user click to sort $sord = $_GET['sord']; // get the direction if (!$sidx) { $sidx = 1; } //2. Selecting the count FIRST //@todo rework this switch ($action) { case 'get_questions': $categoryId = $request->get('categoryId'); $exerciseId = $request->get('exerciseId'); //$courseId = null; //$request->get('courseId'); $courseId = $request->get('courseId'); // Question manager can view all questions if (api_is_question_manager()) { $courseId = null; } $count = \Question::getQuestions($app, $categoryId, $exerciseId, $courseId, array('where' => $where_condition, 'extra' => $extra_fields, 'question' => $questionFields), true); break; case 'get_user_list_plugin_widescale': $count = \UserManager::get_user_data(null, null, null, null, true); break; case 'get_question_list': require_once api_get_path(SYS_CODE_PATH) . 'exercice/exercise.class.php'; $exerciseId = $request->get('exerciseId'); $exercise = new \Exercise(api_get_course_int_id()); $exercise->read($exerciseId); $count = $exercise->selectNbrQuestions(); break; case 'get_group_reporting': $course_id = $request->get('course_id'); $group_id = $request->get('gidReq'); $count = \Tracking::get_group_reporting($course_id, $group_id, 'count'); break; case 'get_user_course_report_resumed': $count = \CourseManager::get_count_user_list_from_course_code(true, 'ruc'); break; case 'get_user_course_report': $count = \CourseManager::get_count_user_list_from_course_code(false); break; case 'get_course_exercise_medias': $course_id = api_get_course_int_id(); $count = \Question::get_count_course_medias($course_id); break; case 'get_user_skill_ranking': $skill = new \Skill(); $count = $skill->get_user_list_skill_ranking_count(); break; case 'get_work_user_list': require_once api_get_path(SYS_CODE_PATH) . 'work/work.lib.php'; $work_id = $request->get('work_id'); //$_REQUEST['work_id']; $count = get_count_work($work_id); break; case 'get_exercise_results': $exercise_id = $request->get('exerciseId'); //$_REQUEST['exerciseId']; $filter_by_user = $request->get('filter_by_user'); if (isset($filter_by_user) && !empty($filter_by_user)) { $filter_user = intval($filter_by_user); if ($where_condition == "") { $where_condition .= " te.exe_user_id = '{$filter_user}'"; } else { $where_condition .= " AND te.exe_user_id = '{$filter_user}'"; } } $count = \ExerciseLib::get_count_exam_results($exercise_id, $where_condition); break; case 'get_hotpotatoes_exercise_results': $hotpot_path = $request->get('path'); //$_REQUEST['path']; $count = \ExerciseLib::get_count_exam_hotpotatoes_results($hotpot_path); break; case 'get_sessions': $list_type = $request->get('list_type'); if ($list_type == 'simple' || empty($list_type)) { $count = \SessionManager::get_sessions_admin(array('where' => $where_condition, 'extra' => $extra_fields), true); } else { $count = \SessionManager::get_count_admin_complete(array('where' => $where_condition, 'extra' => $extra_fields)); } break; case 'get_extra_fields': $obj = new \ExtraField($type); $count = $obj->get_count(); break; case 'get_extra_field_options': $field_id = $request->get('field_id'); $obj = new \ExtraFieldOption($type); $count = $obj->get_count_by_field_id($field_id); break; case 'get_timelines': $obj = new \Timeline(); $count = $obj->get_count(); break; case 'get_gradebooks': $obj = new \Gradebook(); $count = $obj->get_count(); break; case 'get_event_email_template': $obj = new \EventEmailTemplate(); $count = $obj->get_count(); break; case 'get_careers': $obj = new \Career(); $count = $obj->get_count(); break; case 'get_promotions': $obj = new \Promotion(); $count = $obj->get_count(); break; case 'get_grade_models': $obj = new \GradeModel(); $count = $obj->get_count(); break; case 'get_usergroups': $obj = new \UserGroup(); $count = $obj->get_count(); break; case 'get_usergroups_teacher': $obj = new \UserGroup(); $course_id = api_get_course_int_id(); if ($type == 'registered') { $count = $obj->get_usergroup_by_course_with_data_count($course_id); } else { $count = $obj->get_count(); } break; default: exit; } //3. Calculating first, end, etc $total_pages = 0; if ((int) $count > 0) { if (!empty($limit)) { $total_pages = ceil($count / $limit); } } if ($page > $total_pages) { $page = $total_pages; } $start = $limit * $page - $limit; if ($start < 0) { $start = 0; } //4. Deleting an element if the user wants to if ($operation == 'del') { $obj->delete($request->get('id')); } $is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_allowed_to_edit(true) || api_is_drh(); //5. Querying the DB for the elements $columns = array(); switch ($action) { case 'get_questions': $columns = \Question::getQuestionColumns(api_get_course_id(), $extra_fields, $questionFields, true); $columns = $columns['simple_column_name']; $result = \Question::getQuestions($app, $categoryId, $exerciseId, $courseId, array('where' => $where_condition, 'order' => "{$sidx} {$sord}", 'extra' => $extra_fields, 'question' => $questionFields, 'limit' => "{$start} , {$limit}")); //var_dump($result); break; case 'get_user_list_plugin_widescale': $columns = array('username', 'firstname', 'lastname', 'exam_password'); $column_names = array(get_lang('Username'), get_lang('Firstname'), get_lang('Lastname'), get_lang('Password')); $result = \UserManager::get_user_data($start, $limit, $sidx, $sord); break; case 'get_question_list': if (isset($exercise) && !empty($exercise)) { $columns = array('question', 'type', 'category', 'level', 'score', 'actions'); $result = $exercise->getQuestionListPagination($start, $limit, $sidx, $sord, $where_condition); } break; case 'get_group_reporting': $columns = array('name', 'time', 'progress', 'score', 'works', 'messages', 'actions'); $result = \Tracking::get_group_reporting($course_id, $group_id, 'all', $start, $limit, $sidx, $sord, $where_condition); break; case 'get_course_exercise_medias': $columns = array('question'); $result = \Question::get_course_medias($course_id, $start, $limit, $sidx, $sord, $where_condition); if (!empty($result)) { foreach ($result as &$media) { $media['id'] = $media['iid']; } } break; case 'get_user_course_report_resumed': $columns = array('extra_ruc', 'training_hours', 'count_users', 'count_users_registered', 'average_hours_per_user', 'count_certificates'); $column_names = array(get_lang('Company'), get_lang('TrainingHoursAccumulated'), get_lang('CountOfSubscriptions'), get_lang('CountOfUsers'), get_lang('AverageHoursPerStudent'), get_lang('CountCertificates')); $result = \CourseManager::get_user_list_from_course_code(null, null, "LIMIT {$start}, {$limit}", " {$sidx} {$sord}", null, null, true, true, 'ruc'); $new_result = array(); if (!empty($result)) { foreach ($result as $row) { $row['training_hours'] = api_time_to_hms($row['training_hours']); $row['average_hours_per_user'] = api_time_to_hms($row['average_hours_per_user']); $new_result[] = $row; } $result = $new_result; } break; case 'get_user_course_report': $columns = array('course', 'user', 'time', 'certificate', 'progress_100', 'progress'); $column_names = array(get_lang('Course'), get_lang('User'), get_lang('ManHours'), get_lang('CertificateGenerated'), get_lang('Approved'), get_lang('CourseAdvance')); $extra_fields = \UserManager::get_extra_fields(0, 100, null, null, true, true); if (!empty($extra_fields)) { foreach ($extra_fields as $extra) { $columns[] = $extra['1']; $column_names[] = $extra['3']; } } $result = \CourseManager::get_user_list_from_course_code(null, null, "LIMIT {$start}, {$limit}", " {$sidx} {$sord}", null, null, true); break; case 'get_user_skill_ranking': $columns = array('photo', 'firstname', 'lastname', 'skills_acquired', 'currently_learning', 'rank'); $result = $skill->get_user_list_skill_ranking($start, $limit, $sidx, $sord, $where_condition); $result = \ArrayClass::msort($result, 'skills_acquired', 'asc'); $skills_in_course = array(); if (!empty($result)) { //$counter = 1; foreach ($result as &$item) { $user_info = api_get_user_info($item['user_id']); $personal_course_list = \UserManager::get_personal_session_course_list($item['user_id']); $count_skill_by_course = array(); foreach ($personal_course_list as $course_item) { if (!isset($skills_in_course[$course_item['code']])) { $count_skill_by_course[$course_item['code']] = $skill->get_count_skills_by_course($course_item['code']); $skills_in_course[$course_item['code']] = $count_skill_by_course[$course_item['code']]; } else { $count_skill_by_course[$course_item['code']] = $skills_in_course[$course_item['code']]; } } $item['photo'] = \Display::img($user_info['avatar_small']); $item['currently_learning'] = !empty($count_skill_by_course) ? array_sum($count_skill_by_course) : 0; } } break; case 'get_work_user_list': if (isset($type) && $type == 'simple') { $columns = array('type', 'firstname', 'lastname', 'username', 'title', 'qualification', 'sent_date', 'qualificator_id', 'actions'); } else { $columns = array('type', 'firstname', 'lastname', 'username', 'title', 'sent_date', 'actions'); } $result = get_work_user_list($start, $limit, $sidx, $sord, $work_id, $where_condition); break; case 'get_exercise_results': $course = api_get_course_info(); //used inside get_exam_results_data() $documentPath = api_get_path(SYS_COURSE_PATH) . $course['path'] . "/document"; if ($is_allowedToEdit) { $columns = array('firstname', 'lastname', 'username', 'group_name', 'exe_duration', 'start_date', 'exe_date', 'score', 'status', 'lp', 'actions'); } else { //$columns = array('exe_duration', 'start_date', 'exe_date', 'score', 'status', 'actions'); } $result = \ExerciseLib::get_exam_results_data($start, $limit, $sidx, $sord, $exercise_id, $where_condition); break; case 'get_hotpotatoes_exercise_results': $course = api_get_course_info(); //used inside get_exam_results_data() $documentPath = api_get_path(SYS_COURSE_PATH) . $course['path'] . "/document"; $columns = array('firstname', 'lastname', 'username', 'group_name', 'exe_date', 'score', 'actions'); $result = ExerciseLib::get_exam_results_hotpotatoes_data($start, $limit, $sidx, $sord, $hotpot_path, $where_condition); //get_exam_results_data($start, $limit, $sidx, $sord, $exercise_id, $where_condition); break; case 'get_sessions': $session_columns = \SessionManager::get_session_columns($list_type); $columns = $session_columns['simple_column_name']; if ($list_type == 'simple') { $result = SessionManager::get_sessions_admin(array('where' => $where_condition, 'order' => "{$sidx} {$sord}", 'extra' => $extra_fields, 'limit' => "{$start} , {$limit}"), false); } else { $result = SessionManager::get_sessions_admin_complete(array('where' => $where_condition, 'order' => "{$sidx} {$sord}", 'extra' => $extra_fields, 'limit' => "{$start} , {$limit}")); } break; case 'get_timelines': $columns = array('headline', 'actions'); //$columns = array('headline', 'type', 'start_date', 'end_date', 'text', 'media', 'media_credit', 'media_caption', 'title_slide', 'parent_id'); if (!in_array($sidx, $columns)) { $sidx = 'headline'; } $course_id = api_get_course_int_id(); $result = Database::select('*', $obj->table, array('where' => array('parent_id = ? AND c_id = ?' => array('0', $course_id)), 'order' => "{$sidx} {$sord}", 'LIMIT' => "{$start} , {$limit}")); $new_result = array(); foreach ($result as $item) { if (!$item['status']) { $item['name'] = '<font style="color:#AAA">' . $item['name'] . '</font>'; } $item['headline'] = Display::url($item['headline'], api_get_path(WEB_CODE_PATH) . 'timeline/view.php?id=' . $item['id']); $item['actions'] = Display::url(Display::return_icon('add.png', get_lang('AddItems')), api_get_path(WEB_CODE_PATH) . 'timeline/?action=add_item&parent_id=' . $item['id']); $item['actions'] .= Display::url(Display::return_icon('edit.png', get_lang('Edit')), api_get_path(WEB_CODE_PATH) . 'timeline/?action=edit&id=' . $item['id']); $item['actions'] .= Display::url(Display::return_icon('delete.png', get_lang('Delete')), api_get_path(WEB_CODE_PATH) . 'timeline/?action=delete&id=' . $item['id']); $new_result[] = $item; } $result = $new_result; break; case 'get_gradebooks': $columns = array('name', 'certificates', 'skills', 'actions', 'has_certificates'); 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) { if ($item['parent_id'] != 0) { continue; } $skills = $obj->get_skills_by_gradebook($item['id']); //Fixes bug when gradebook doesn't have names if (empty($item['name'])) { $item['name'] = $item['course_code']; } else { //$item['name'] = $item['name'].' ['.$item['course_code'].']'; } $item['name'] = Display::url($item['name'], api_get_path(WEB_CODE_PATH) . 'gradebook/index.php?id_session=0&cidReq=' . $item['course_code']); if (!empty($item['certif_min_score']) && !empty($item['document_id'])) { $item['certificates'] = Display::return_icon('accept.png', get_lang('WithCertificate'), array(), ICON_SIZE_SMALL); $item['has_certificates'] = '1'; } else { $item['certificates'] = Display::return_icon('warning.png', get_lang('NoCertificate'), array(), ICON_SIZE_SMALL); $item['has_certificates'] = '0'; } if (!empty($skills)) { foreach ($skills as $skill) { $item['skills'] .= Display::span($skill['name'], array('class' => 'label_tag skill')); } } $new_result[] = $item; } $result = $new_result; break; case 'get_event_email_template': $columns = array('subject', 'event_type_name', 'language_id', 'activated', 'actions'); if (!in_array($sidx, $columns)) { $sidx = 'subject'; } $result = Database::select('*', $obj->table, array('order' => "{$sidx} {$sord}", 'LIMIT' => "{$start} , {$limit}")); $new_result = array(); foreach ($result as $item) { $language_info = api_get_language_info($item['language_id']); $item['language_id'] = $language_info['english_name']; $item['actions'] = Display::url(Display::return_icon('edit.png', get_lang('Edit')), api_get_path(WEB_CODE_PATH) . 'admin/event_type.php?action=edit&event_type_name=' . $item['event_type_name']); $item['actions'] .= Display::url(Display::return_icon('delete.png', get_lang('Delete')), api_get_path(WEB_CODE_PATH) . 'admin/event_controller.php?action=delete&id=' . $item['id']); /*if (!$item['status']) { $item['name'] = '<font style="color:#AAA">'.$item['subject'].'</font>'; }*/ $new_result[] = $item; } $result = $new_result; break; case 'get_careers': $columns = array('name', 'description', '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) { if (!$item['status']) { $item['name'] = '<font style="color:#AAA">' . $item['name'] . '</font>'; } $new_result[] = $item; } $result = $new_result; break; case 'get_promotions': $columns = array('name', 'career', 'description', 'actions'); if (!in_array($sidx, $columns)) { $sidx = 'name'; } $result = Database::select('p.id,p.name, p.description, c.name as career, p.status', "{$obj->table} p LEFT JOIN " . Database::get_main_table(TABLE_CAREER) . " c ON c.id = p.career_id ", array('order' => "{$sidx} {$sord}", 'LIMIT' => "{$start} , {$limit}")); $new_result = array(); foreach ($result as $item) { if (!$item['status']) { $item['name'] = '<font style="color:#AAA">' . $item['name'] . '</font>'; } $new_result[] = $item; } $result = $new_result; break; case 'get_grade_models': $columns = array('name', 'description', '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) { $new_result[] = $item; } $result = $new_result; break; case 'get_usergroups': $columns = array('name', 'users', 'courses', 'sessions', 'group_type', 'actions'); $result = Database::select('*', $obj->table, array('order' => "name {$sord}", 'LIMIT' => "{$start} , {$limit}")); $new_result = array(); if (!empty($result)) { foreach ($result as $group) { $group['sessions'] = count($obj->get_sessions_by_usergroup($group['id'])); $group['courses'] = count($obj->get_courses_by_usergroup($group['id'])); $group['users'] = count($obj->get_users_by_usergroup($group['id'])); switch ($group['group_type']) { case '0': $group['group_type'] = Display::label(get_lang('Class'), 'info'); break; case '1': $group['group_type'] = Display::label(get_lang('Social'), 'success'); break; } $new_result[] = $group; } $result = $new_result; } $columns = array('name', 'users', 'courses', 'sessions', 'group_type'); if (!in_array($sidx, $columns)) { $sidx = 'name'; } //Multidimensional sort ArrayClass::msort($result, $sidx); break; case 'get_extra_fields': $obj = new \ExtraField($type); $columns = array('field_display_text', 'field_variable', 'field_type', 'field_changeable', 'field_visible', 'field_filter', 'field_order'); $result = \Database::select('*', $obj->table, array('order' => "{$sidx} {$sord}", 'LIMIT' => "{$start} , {$limit}")); $new_result = array(); if (!empty($result)) { foreach ($result as $item) { $item['field_type'] = $obj->get_field_type_by_id($item['field_type']); $item['field_changeable'] = $item['field_changeable'] ? Display::return_icon('right.gif') : Display::return_icon('wrong.gif'); $item['field_visible'] = $item['field_visible'] ? Display::return_icon('right.gif') : Display::return_icon('wrong.gif'); $item['field_filter'] = $item['field_filter'] ? Display::return_icon('right.gif') : Display::return_icon('wrong.gif'); $new_result[] = $item; } $result = $new_result; } break; case 'get_extra_field_options': $obj = new \ExtraFieldOption($type); $columns = array('option_display_text', 'option_value', 'option_order'); $result = \Database::select('*', $obj->table, array('where' => array("field_id = ? " => $field_id), 'order' => "{$sidx} {$sord}", 'LIMIT' => "{$start} , {$limit}")); /*$new_result = array(); if (!empty($result)) { foreach ($result as $item) { $item['field_type'] = $obj->get_field_type_by_id($item['field_type']); $item['field_changeable'] = $item['field_changeable'] ? Display::return_icon('right.gif') : Display::return_icon('wrong.gif'); $item['field_visible'] = $item['field_visible'] ? Display::return_icon('right.gif') : Display::return_icon('wrong.gif'); $item['field_filter'] = $item['field_filter'] ? Display::return_icon('right.gif') : Display::return_icon('wrong.gif'); $new_result[] = $item; } $result = $new_result; }*/ break; case 'get_usergroups_teacher': $columns = array('name', 'users', 'actions'); $options = array('order' => "name {$sord}", 'LIMIT' => "{$start} , {$limit}"); $options['course_id'] = $course_id; switch ($type) { case 'not_registered': $options['where'] = array(" (course_id IS NULL OR course_id != ?) " => $course_id); $result = $obj->get_usergroup_not_in_course($options); break; case 'registered': $options['where'] = array(" usergroup.course_id = ? " => $course_id); $result = $obj->get_usergroup_in_course($options); break; } $new_result = array(); if (!empty($result)) { foreach ($result as $group) { $group['users'] = count($obj->get_users_by_usergroup($group['id'])); if ($obj->usergroup_was_added_in_course($group['id'], $course_id)) { $url = 'class.php?action=remove_class_from_course&id=' . $group['id']; $icon = Display::return_icon('delete.png', get_lang('Remove')); } else { $url = 'class.php?action=add_class_to_course&id=' . $group['id']; $icon = Display::return_icon('add.png', get_lang('Add')); } $group['actions'] = Display::url($icon, $url); $new_result[] = $group; } $result = $new_result; } if (!in_array($sidx, $columns)) { $sidx = 'name'; } //Multidimensional sort \ArrayClass::msort($result, $sidx); break; default: exit; } $allowed_actions = array('get_careers', 'get_promotions', 'get_usergroups', 'get_usergroups_teacher', 'get_gradebooks', 'get_sessions', 'get_exercise_results', 'get_hotpotatoes_exercise_results', 'get_work_user_list', 'get_timelines', 'get_grade_models', 'get_event_email_template', 'get_user_skill_ranking', 'get_extra_fields', 'get_extra_field_options', 'get_course_exercise_medias', 'get_user_course_report', 'get_user_course_report_resumed', 'get_group_reporting', 'get_question_list', 'get_user_list_plugin_widescale', 'get_questions'); //5. Creating an obj to return a json if (in_array($action, $allowed_actions)) { $response = new \stdClass(); $response->page = $page; $response->total = $total_pages; $response->records = $count; if ($operation && $operation == 'excel') { $j = 1; $array = array(); if (empty($column_names)) { $column_names = $columns; } //Headers foreach ($column_names as $col) { $array[0][] = $col; } foreach ($result as $row) { foreach ($columns as $col) { $array[$j][] = strip_tags($row[$col]); } $j++; } switch ($export_format) { case 'xls': Export::export_table_xls($array, 'company_report'); break; case 'csv': default: Export::export_table_csv($array, 'company_report'); break; } exit; } $i = 0; if (!empty($result)) { foreach ($result as $row) { //print_r($row); // if results tab give not id, set id to $i otherwise id="null" for all <tr> of the jqgrid - ref #4235 if (!isset($row['id']) || isset($row['id']) && $row['id'] == "") { $response->rows[$i]['id'] = $i; } else { $response->rows[$i]['id'] = $row['id']; } $array = array(); foreach ($columns as $col) { $array[] = isset($row[$col]) ? $row[$col] : null; } $response->rows[$i]['cell'] = $array; $i++; } } return json_encode($response); } }
/** * Exports an exercise as a SCO. * This method is intended to be called from the prepare method. * * @note There's a lot of nearly cut-and-paste from exercise.lib.php here * because of some little differences... * Perhaps something that could be refactorised ? * * @see prepare * @param $quizId The quiz * @param $raw_to_pass The needed score to attain * @return False on error, True if everything went well. * @author Thanos Kyritsis <*****@*****.**> * @author Amand Tihon <*****@*****.**> */ function prepareQuiz($quizId, $raw_to_pass = 50) { global $langQuestion, $langOk, $langScore, $claro_stylesheet, $clarolineRepositorySys; global $charset, $langExerciseDone; // those two variables are needed by display_attached_file() global $attachedFilePathWeb; global $attachedFilePathSys; $attachedFilePathWeb = 'Exercises'; $attachedFilePathSys = $this->destDir . '/Exercises'; // Generate standard page header $pageHeader = '<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=' . $charset . '"> <meta http-equiv="expires" content="Tue, 05 DEC 2000 07:00:00 GMT"> <meta http-equiv="Pragma" content="no-cache"> <link rel="stylesheet" type="text/css" href="bootstrap-custom.css" /> <link rel="stylesheet" type="text/css" href="' . $claro_stylesheet . '" media="screen, projection, tv" /> <script language="javascript" type="text/javascript" src="APIWrapper.js"></script> <script language="javascript" type="text/javascript" src="scores.js"></script> ' . "\n"; $pageBody = '<body onload="loadPage()"> <div id="claroBody"><form id="quiz"> <table class="table-default"><tr><td>' . "\n"; // read the exercise $quiz = new Exercise(); if (!$quiz->read($quizId)) { $this->error[] = $GLOBALS['langErrorLoadingExercise']; return false; } // Get the question list $questionList = $quiz->selectQuestionList(); $questionCount = $quiz->selectNbrQuestions(); // Keep track of raw scores (ponderation) for each question $questionPonderationList = array(); // Keep track of correct texts for fill-in type questions $fillAnswerList = array(); // Counter used to generate the elements' id. Incremented after every <input> or <select> $idCounter = 0; // Display each question $questionCount = 0; foreach ($questionList as $questionId) { // Update question number $questionCount++; // read the question, abort on error $question = new Question(); if (!$question->read($questionId)) { $this->error[] = $GLOBALS['langErrorLoadingQuestion']; return false; } $qtype = $question->selectType(); $qtitle = $question->selectTitle(); $qdescription = $question->selectDescription(); $questionPonderationList[$questionId] = $question->selectWeighting(); // Generic display, valid for all kind of question $pageBody .= '<table class="table-default"> <tr><th valign="top" colspan="2">' . $langQuestion . ' ' . $questionCount . '</th></tr> <tfoot> <tr><td valign="top" colspan="2">' . $qtitle . '</td></tr> <tr><td valign="top" colspan="2"><i>' . parse_user_text($qdescription) . '</i></td></tr>' . "\n"; // Attached file, if it exists. //$attachedFile = $question->selectAttachedFile(); if (!empty($attachedFile)) { // copy the attached file if (!claro_copy_file($this->srcDirExercise . '/' . $attachedFile, $this->destDir . '/Exercises')) { $this->error[] = $GLOBALS['langErrorCopyAttachedFile'] . $attachedFile; return false; } // Ok, if it was an mp3, we need to copy the flash mp3-player too. $extension = substr(strrchr($attachedFile, '.'), 1); if ($extension == 'mp3') { $this->mp3Found = true; } $pageBody .= '<tr><td colspan="2">' . display_attached_file($attachedFile) . '</td></tr>' . "\n"; } /* * Display the possible answers */ $answer = new Answer($questionId); $answerCount = $answer->selectNbrAnswers(); // Used for matching: $letterCounter = 'A'; $choiceCounter = 1; $Select = array(); for ($answerId = 1; $answerId <= $answerCount; $answerId++) { $answerText = $answer->selectAnswer($answerId); $answerCorrect = $answer->isCorrect($answerId); // Unique answer if ($qtype == UNIQUE_ANSWER || $qtype == TRUE_FALSE) { // Construct the identifier $htmlQuestionId = 'unique_' . $questionCount . '_x'; $pageBody .= '<tr><td width="5%" align="center"> <input type="radio" name="' . $htmlQuestionId . '" id="scorm_' . $idCounter . '" value="' . $answer->selectWeighting($answerId) . '"></td> <td width="95%"><label for="scorm_' . $idCounter . '">' . $answerText . '</label> </td></tr>'; $idCounter++; } // Multiple answers elseif ($qtype == MULTIPLE_ANSWER) { // Construct the identifier $htmlQuestionId = 'multiple_' . $questionCount . '_' . $answerId; // Compute the score modifier if this answer is checked $raw = $answer->selectWeighting($answerId); $pageBody .= '<tr><td width="5%" align="center"> <input type="checkbox" name="' . $htmlQuestionId . '" id="scorm_' . $idCounter . '" value="' . $raw . '"></td> <td width="95%"><label for="scorm_' . $idCounter . '">' . $answerText . '</label> </td></tr>'; $idCounter++; } // Fill in blanks elseif ($qtype == FILL_IN_BLANKS || $qtype == FILL_IN_BLANKS_TOLERANT) { $pageBody .= '<tr><td colspan="2">'; // We must split the text, to be able to treat each input independently // separate the text and the scorings $explodedAnswer = explode('::', $answerText); $phrase = (isset($explodedAnswer[0])) ? $explodedAnswer[0] : ''; $weighting = (isset($explodedAnswer[1])) ? $explodedAnswer[1] : ''; $fillType = (!empty($explodedAnswer[2])) ? $explodedAnswer[2] : 1; // default value if value is invalid if ($fillType != TEXTFIELD_FILL && $fillType != LISTBOX_FILL) { $fillType = TEXTFIELD_FILL; } $wrongAnswers = (!empty($explodedAnswer[3])) ? explode('[', $explodedAnswer[3]) : array(); // get the scorings as a list $fillScoreList = explode(',', $weighting); $fillScoreCounter = 0; //listbox if ($fillType == LISTBOX_FILL) { // get the list of propositions (good and wrong) to display in lists // add wrongAnswers in the list $answerList = $wrongAnswers; // add good answers in the list // we save the answer because it will be modified $temp = $phrase; while (1) { // quits the loop if there are no more blanks if (($pos = strpos($temp, '[')) === false) { break; } // removes characters till '[' $temp = substr($temp, $pos + 1); // quits the loop if there are no more blanks if (($pos = strpos($temp, ']')) === false) { break; } // stores the found blank into the array $answerList[] = substr($temp, 0, $pos); // removes the character ']' $temp = substr($temp, $pos + 1); } // alphabetical sort of the array natcasesort($answerList); } // Split after each blank $responsePart = explode(']', $phrase); $acount = 0; foreach ($responsePart as $part) { // Split between text and (possible) blank if (strpos($part, '[') !== false) { list($rawtext, $blankText) = explode('[', $part); } else { $rawtext = $part; $blankText = ""; } $pageBody .= $rawtext; // If there's a blank to fill-in after the text (this is usually not the case at the end) if (!empty($blankText)) { // Build the element's name $name = 'fill_' . $questionCount . '_' . $acount; // Keep track of the correspondance between element's name and correct value + scoring $fillAnswerList[$name] = array($blankText, $fillScoreList[$fillScoreCounter]); if ($fillType == LISTBOX_FILL) {// listbox $pageBody .= '<select name="' . $name . '" id="scorm_' . $idCounter . '">' . "\n" . '<option value=""> </option>'; foreach ($answerList as $answer) { $pageBody .= '<option value="' . htmlspecialchars($answer) . '">' . $answer . '</option>' . "\n"; } $pageBody .= '</select>' . "\n"; } else { $pageBody .= '<input type="text" name="' . $name . '" size="10" id="scorm_' . $idCounter . '">'; } $fillScoreCounter++; $idCounter++; } $acount++; } $pageBody .= '</td></tr>' . "\n"; } // Matching elseif ($qtype == MATCHING) { if (!$answer->isCorrect($answerId)) { // Add the option as a possible answer. $Select[$answerId] = $answerText; } else { $pageBody .= '<tr><td colspan="2"> <table border="0" cellpadding="0" cellspacing="0" width="99%"> <tr> <td width="40%" valign="top"><b>' . $choiceCounter . '.</b> ' . $answerText . '</td> <td width="20%" valign="center"> <select name="matching_' . $questionCount . '_' . $answerId . '" id="scorm_' . $idCounter . '"> <option value="0">--</option>'; $idCounter++; // fills the list-box $letter = 'A'; foreach ($Select as $key => $val) { $scoreModifier = ( $key == $answer->isCorrect($answerId) ) ? $answer->selectWeighting($answerId) : 0; $pageBody .= '<option value="' . $scoreModifier . '">' . $letter++ . '</option>'; } $pageBody .= '</select></td><td width="40%" valign="top">'; if (isset($Select[$choiceCounter])) { $pageBody .= '<b>' . $letterCounter . '.</b> ' . $Select[$choiceCounter]; } $pageBody .= ' </td></tr></table></td></tr>' . "\n"; // Done with this one $letterCounter++; $choiceCounter++; // If the left side has been completely displayed : if ($answerId == $answerCount) { // Add all possibly remaining answers to the right while (isset($Select[$choiceCounter])) { $pageBody .= '<tr><td colspan="2"> <table border="0" cellpadding="0" cellspacing="0" width="99%"> <tr> <td width="40%"> </td> <td width="20%"> </td> <td width="40%"><b>' . $letterCounter . '.</b> ' . $Select[$choiceCounter] . '</td> </tr> </table> </td></tr>' . "\n"; $letterCounter++; $choiceCounter++; } // end while } // end if } // else } // end if (MATCHING) } // end for each answer // End of the question $pageBody .= '</tfoot></table>' . "\n\n"; } // foreach($questionList as $questionId) // No more questions, add the button. $pageEnd = '</td></tr> <tr> <td align="center"><br><input class="btn btn-primary" type="button" value="' . $langOk . '" onClick="calcScore()"></td> </tr> </table> </form> </div></body></html>' . "\n"; /* Generate the javascript that'll calculate the score * We have the following variables to help us : * $idCounter : number of elements to check. their id are "scorm_XY" * $raw_to_pass : score (on 100) needed to pass the quiz * $fillAnswerList : a list of arrays (text, score) indexed on <input>'s names * */ $pageHeader .= ' <script type="text/javascript" language="javascript"> var raw_to_pass = '******'; var weighting = ' . array_sum($questionPonderationList) . '; var rawScore; var scoreCommited = false; var showScore = true; var fillAnswerList = new Array();' . "\n"; // Add the data for fillAnswerList foreach ($fillAnswerList as $key => $val) { $pageHeader .= " fillAnswerList['" . $key . "'] = new Array('" . $val[0] . "', '" . $val[1] . "');\n"; } // This is the actual code present in every exported exercise. $pageHeader .= ' function calcScore() { if( !scoreCommited ) { rawScore = CalculateRawScore(document, ' . $idCounter . ', fillAnswerList); var score = Math.max(Math.round(rawScore * 100 / weighting), 0); var oldScore = doGetValue("cmi.score.raw"); doSetValue("cmi.score.max", weighting); doSetValue("cmi.score.min", 0); computeTime(); if (score > oldScore) // Update only if score is better than the previous time. { doSetValue("cmi.score.raw", rawScore); } var oldStatus = doGetValue( "cmi.success_status" ) if (score >= raw_to_pass) { doSetValue("cmi.success_status", "passed"); } else if (oldStatus != "passed" ) // If passed once, never mark it as failed. { doSetValue("cmi.success_status", "failed"); } doCommit(); doTerminate(); scoreCommited = true; if(showScore) alert(\'' . clean_str_for_javascript($langScore) . ' :\n\' + rawScore + \'/\' + weighting + \'\n\' + \'' . clean_str_for_javascript($langExerciseDone) . '\'); } } </script> '; // Construct the HTML file and save it. $filename = "quiz_" . $quizId . ".html"; $pageContent = $pageHeader . $pageBody . $pageEnd; if (!$f = fopen($this->destDir . '/' . $filename, 'w')) { $this->error[] = $GLOBALS['langErrorCreatingFile'] . $filename; return false; } fwrite($f, $pageContent); fclose($f); // Went well. return True; }
if (is_string($val)) { $_POST[$key] = stripslashes($val); } elseif (is_array($val)) { foreach ($val as $key2 => $val2) { $_POST[$key][$key2] = stripslashes($val2); } } $GLOBALS[$key] = $_POST[$key]; } } // construction of the Exercise object $objExercise = new Exercise(); if (isset($_GET['exerciseId'])) { $exerciseId = intval($_GET['exerciseId']); $objExercise->read($exerciseId); $nbrQuestions = $objExercise->selectNbrQuestions(); } // intializes the Question object if (isset($_GET['editQuestion']) || isset($_GET['newQuestion']) || isset($_GET['modifyQuestion']) || isset($_GET['modifyAnswers'])) { // construction of the Question object $objQuestion = new Question(); // reads question data if (isset($_GET['editQuestion']) || isset($_GET['modifyQuestion']) || isset($_GET['modifyAnswers'])) { if (isset($_GET['editQuestion'])) { $question_id = intval($_GET['editQuestion']); } elseif (isset($_GET['modifyQuestion'])) { $question_id = intval($_GET['modifyQuestion']); } elseif (isset($_GET['modifyAnswers'])) { $question_id = intval($_GET['modifyAnswers']); } // if question not found