/** * Generate a label if the user has been registered in session * @return string The label */ public function getAlreadyRegisteredInSessionLabel() { $icon = '<em class="fa fa-smile-o"></em>'; return Display::div($icon . ' ' . get_lang("AlreadyRegisteredToSession"), array('class' => 'info-catalog')); }
$minutes = 60; $url = api_get_path(WEB_AJAX_PATH) . 'exercise.ajax.php?a=get_live_stats&exercise_id=' . $objExercise->id . '&minutes=' . $minutes; //The order is important you need to check the the $column variable in the model.ajax.php file $columns = array(get_lang('FirstName'), get_lang('LastName'), get_lang('Time'), get_lang('QuestionsAlreadyAnswered'), get_lang('Score')); //Column config $column_model = array(array('name' => 'firstname', 'index' => 'firstname', 'width' => '100', 'align' => 'left'), array('name' => 'lastname', 'index' => 'lastname', 'width' => '100', 'align' => 'left'), array('name' => 'start_date', 'index' => 'start_date', 'width' => '100', 'align' => 'left'), array('name' => 'question', 'index' => 'count_questions', 'width' => '60', 'align' => 'left', 'sortable' => 'false'), array('name' => 'score', 'index' => 'score', 'width' => '50', 'align' => 'left', 'sortable' => 'false')); //Autowidth $extra_params['autowidth'] = 'true'; //height auto $extra_params['height'] = 'auto'; ?> <script> function refreshGrid() { var grid = $("#live_stats"); grid.trigger("reloadGrid"); t = setTimeout("refreshGrid()", 10000); } $(function() { <?php echo Display::grid_js('live_stats', $url, $columns, $column_model, $extra_params, array(), null, true); ?> refreshGrid(); }); </script> <?php $actions = '<a href="exercise_report.php?exerciseId=' . intval($_GET['exerciseId']) . '&' . api_get_cidreq() . '">' . Display::return_icon('back.png', get_lang('GoBackToQuestionList'), '', ICON_SIZE_MEDIUM) . '</a>'; echo $actions = Display::div($actions, array('class' => 'actions')); echo Display::grid_html('live_stats'); Display::display_footer();
/** * Returns the category form. * @param Exercise $exercise_obj * @return string */ public function returnCategoryForm(Exercise $exercise_obj) { $categories = $this->getListOfCategoriesForTest($exercise_obj); $saved_categories = $exercise_obj->get_categories_in_exercise(); $return = null; if (!empty($categories)) { $nbQuestionsTotal = $exercise_obj->getNumberQuestionExerciseCategory(); $exercise_obj->setCategoriesGrouping(true); $real_question_count = count($exercise_obj->getQuestionList()); $warning = null; if ($nbQuestionsTotal != $real_question_count) { $warning = Display::return_message(get_lang('CheckThatYouHaveEnoughQuestionsInYourCategories'), 'warning'); } $return .= $warning; $return .= '<table class="data_table">'; $return .= '<tr>'; $return .= '<th height="24">' . get_lang('Categories') . '</th>'; $return .= '<th width="70" height="24">' . get_lang('Number') . '</th></tr>'; foreach ($categories as $category) { $cat_id = $category['iid']; $return .= '<tr>'; $return .= '<td>'; $return .= Display::div($category['parent_path']); $return .= '</td>'; $return .= '<td>'; $value = isset($saved_categories) && isset($saved_categories[$cat_id]) ? $saved_categories[$cat_id]['count_questions'] : -1; $return .= '<input name="category[' . $cat_id . ']" value="' . $value . '" />'; $return .= '</td>'; $return .= '</tr>'; } $return .= '</table>'; $return .= get_lang('ZeroMeansNoQuestionWillBeSelectedMinusOneMeansThatAllQuestionsWillBeSelected'); return $return; } }
/** * Displays messages of a group with nested view * @param $group_id * @param $topic_id * @param $is_member * @param $message_id * @return string */ public static function display_message_for_group($group_id, $topic_id, $is_member, $message_id) { global $my_group_role; $main_message = self::get_message_by_id($topic_id); if (empty($main_message)) { return false; } $rows = self::get_messages_by_group_by_message($group_id, $topic_id); $rows = self::calculate_children($rows, $topic_id); $current_user_id = api_get_user_id(); $items_per_page = 50; $query_vars = array('id' => $group_id, 'topic_id' => $topic_id, 'topics_page_nr' => 0); // Main message $links = ''; $main_content = ''; $items_page_nr = null; $html = ''; $delete_button = ''; if (api_is_platform_admin()) { $delete_button = Display::url(Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL), 'group_topics.php?action=delete&id=' . $group_id . '&topic_id=' . $topic_id); } $html .= Display::page_subheader(Security::remove_XSS($main_message['title'] . $delete_button, STUDENT, true)); $user_sender_info = api_get_user_info($main_message['user_sender_id']); $files_attachments = self::get_links_message_attachment_files($main_message['id']); $name = $user_sender_info['complete_name']; $topic_page_nr = isset($_GET['topics_page_nr']) ? intval($_GET['topics_page_nr']) : null; $links .= '<div id="message-reply-link">'; if ($my_group_role == GROUP_USER_PERMISSION_ADMIN || $my_group_role == GROUP_USER_PERMISSION_MODERATOR || $main_message['user_sender_id'] == $current_user_id) { $urlEdit = api_get_path(WEB_CODE_PATH); $urlEdit .= 'social/message_for_group_form.inc.php?'; $urlEdit .= http_build_query(['user_friend' => $current_user_id, 'group_id' => $group_id, 'message_id' => $main_message['id'], 'action' => 'edit_message_group', 'anchor_topic' => 'topic_' . $main_message['id'], 'topics_page_nr' => $topic_page_nr, 'items_page_nr' => $items_page_nr, 'topic_id' => $main_message['id']]); $links .= Display::url(Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL), $urlEdit, ['class' => 'ajax btn btn-default', 'title' => get_lang('Edit'), 'data-title' => get_lang('Edit'), 'data-size' => 'lg']); } $urlReply = api_get_path(WEB_CODE_PATH); $urlReply .= 'social/message_for_group_form.inc.php?'; $urlReply .= http_build_query(['user_friend' => api_get_user_id(), 'group_id' => $group_id, 'message_id' => $main_message['id'], 'action' => 'reply_message_group', 'anchor_topic' => 'topic_' . $main_message['id'], 'topics_page_nr' => $topic_page_nr, 'topic_id' => $main_message['id']]); $links .= Display::url(Display::return_icon('talk.png', get_lang('Reply')), $urlReply, ['class' => 'ajax btn btn-default', 'title' => get_lang('Reply'), 'data-title' => get_lang('Reply'), 'data-size' => 'lg']); $links .= '</div>'; $userPicture = $user_sender_info['avatar']; $main_content .= '<div class="message-group-author"> <img src="' . $userPicture . '" alt="' . $name . '" width="32" height="32" title="' . $name . '" /></div>'; $user_link = '<a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $main_message['user_sender_id'] . '">' . $name . ' </a>'; $date = ''; if ($main_message['send_date'] != $main_message['update_date']) { if (!empty($main_message['update_date']) && $main_message['update_date'] != '0000-00-00 00:00:00') { $date = '<div class="message-group-date"> ' . get_lang('LastUpdate') . ' ' . date_to_str_ago($main_message['update_date']) . '</div>'; } } else { $date = '<div class="message-group-date"> ' . get_lang('Created') . ' ' . date_to_str_ago($main_message['send_date']) . '</div>'; } $attachment = '<div class="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '') . '</div>'; $main_content .= '<div class="message-group-content">' . $links . $user_link . ' ' . $date . $main_message['content'] . $attachment . '</div>'; $main_content = Security::remove_XSS($main_content, STUDENT, true); $html .= Display::div(Display::div(Display::div($main_content, array('class' => 'group_social_sub_item', 'style' => 'background-color:#fff;')), array('class' => 'group_social_item')), array('class' => 'group_social_grid')); $topic_id = $main_message['id']; if (is_array($rows) && count($rows) > 0) { $topics = $rows; $array_html_items = array(); foreach ($topics as $index => $topic) { if (empty($topic['id'])) { continue; } $items_page_nr = isset($_GET['items_' . $topic['id'] . '_page_nr']) ? intval($_GET['items_' . $topic['id'] . '_page_nr']) : null; $links = ''; $html_items = ''; $user_sender_info = api_get_user_info($topic['user_sender_id']); $files_attachments = self::get_links_message_attachment_files($topic['id']); $name = $user_sender_info['complete_name']; $links .= '<div id="message-reply-link">'; if ($my_group_role == GROUP_USER_PERMISSION_ADMIN || $my_group_role == GROUP_USER_PERMISSION_MODERATOR || $topic['user_sender_id'] == $current_user_id) { $links .= '<a href="' . api_get_path(WEB_CODE_PATH) . 'social/message_for_group_form.inc.php?height=400&width=800&&user_friend=' . $current_user_id . '&group_id=' . $group_id . '&message_id=' . $topic['id'] . '&action=edit_message_group&anchor_topic=topic_' . $topic_id . '&topics_page_nr=' . $topic_page_nr . '&items_page_nr=' . $items_page_nr . '&topic_id=' . $topic_id . '" class="ajax btn" data-size="lg" data-title="' . get_lang('Edit') . '" title="' . get_lang('Edit') . '">' . Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL) . '</a>'; } $links .= ' <a href="' . api_get_path(WEB_CODE_PATH) . 'social/message_for_group_form.inc.php?height=400&width=800&&user_friend=' . api_get_user_id() . '&group_id=' . $group_id . '&message_id=' . $topic['id'] . '&action=reply_message_group&anchor_topic=topic_' . $topic_id . '&topics_page_nr=' . $topic_page_nr . '&items_page_nr=' . $items_page_nr . '&topic_id=' . $topic_id . '" class="ajax btn" data-size="lg" data-title="' . get_lang('Reply') . '" title="' . get_lang('Reply') . '">'; $links .= Display::return_icon('talk.png', get_lang('Reply')) . '</a>'; $links .= '</div>'; $userPicture = $user_sender_info['avatar']; $html_items .= '<div class="message-group-author"><img src="' . $userPicture . '" alt="' . $name . '" width="32" height="32" title="' . $name . '" /></div>'; $user_link = '<a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $topic['user_sender_id'] . '">' . $name . ' </a>'; $date = ''; if ($topic['send_date'] != $topic['update_date']) { if (!empty($topic['update_date']) && $topic['update_date'] != '0000-00-00 00:00:00') { $date = '<div class="message-group-date"> ' . get_lang('LastUpdate') . ' ' . date_to_str_ago($topic['update_date']) . '</div>'; } } else { $date = '<div class="message-group-date"> ' . get_lang('Created') . ' ' . date_to_str_ago($topic['send_date']) . '</div>'; } $attachment = '<div class="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '') . '</div>'; $html_items .= '<div class="message-group-content">' . $links . $user_link . ' ' . $date . Security::remove_XSS($topic['content'], STUDENT, true) . $attachment . '</div>'; $base_padding = 20; if ($topic['indent_cnt'] == 0) { $indent = $base_padding; } else { $indent = intval($topic['indent_cnt']) * $base_padding + $base_padding; } $class = 'group_social_sub_item'; if (isset($message_id) && $message_id == $topic['id']) { $class .= ' group_social_sub_item_highlight'; } $html_items = Display::div($html_items, array('class' => $class, 'id' => 'msg_' . $topic['id'])); $html_items = Display::div($html_items, array('class' => '', 'style' => 'margin-left:' . $indent . 'px')); $array_html_items[] = array($html_items); } // grids for items with paginations $options = array('hide_navigation' => false, 'per_page' => $items_per_page); $visibility = array(true, true, true, false); $style_class = array('item' => array('class' => 'group_social_item'), 'main' => array('class' => 'group_social_grid')); if (!empty($array_html_items)) { $html .= Display::return_sortable_grid('items_' . $topic['id'], array(), $array_html_items, $options, $query_vars, null, $visibility, false, $style_class); } } return $html; }
// if course is public, go to course without auth $tab_course_info = api_get_course_info($firstpage); api_set_firstpage_parameter($firstpage); $tpl = new Template(null, 1, 1); $action = api_get_self() . '?' . Security::remove_XSS($_SERVER['QUERY_STRING']); $action = str_replace('&', '&', $action); $form = new FormValidator('formLogin', 'post', $action, null, array('class' => 'form-stacked')); $form->addElement('text', 'login', null, array('placeholder' => get_lang('UserName'), 'class' => 'span3 autocapitalize_off')); //new $form->addElement('password', 'password', null, array('placeholder' => get_lang('Password'), 'class' => 'span3')); //new $form->addElement('style_submit_button', 'submitAuth', get_lang('LoginEnter'), array('class' => 'btn span3')); // see same text in main_api.lib.php function api_not_allowed if (api_is_cas_activated()) { $msg .= Display::return_message(sprintf(get_lang('YouHaveAnInstitutionalAccount'), api_get_setting("Institution")), '', false); $msg .= Display::div("<br/><a href='" . get_cas_direct_URL(api_get_course_id()) . "'>" . getCASLogoHTML() . " " . sprintf(get_lang('LoginWithYourAccount'), api_get_setting("Institution")) . "</a><br/><br/>", array('align' => 'center')); $msg .= Display::return_message(get_lang('YouDontHaveAnInstitutionAccount')); $msg .= "<p style='text-align:center'><a href='#' onclick='\$(this).parent().next().toggle()'>" . get_lang('LoginWithExternalAccount') . "</a></p>"; $msg .= "<div style='display:none;'>"; } $msg .= '<div class="well_login">'; $msg .= $form->return_form(); $msg .= '</div>'; if (api_is_cas_activated()) { $msg .= "</div>"; } $msg .= '<hr/><p style="text-align:center"><a href="' . api_get_path(WEB_PATH) . '">' . get_lang('ReturnToCourseHomepage') . '</a></p>'; $tpl->assign('content', '<h4>' . get_lang('LoginToGoToThisCourse') . '</h4>' . $msg); $tpl->display_one_col_template(); } else { api_delete_firstpage_parameter();
$result['description'] = Security::remove_XSS($result['description'], STUDENT, true); $id = $result['id']; $url_open = '<a href="group_view.php?id=' . $id . '">'; $url_close = '</a>'; $count_users_group = count($usergroup->get_users_by_group($id, false, array(GROUP_USER_PERMISSION_ADMIN, GROUP_USER_PERMISSION_READER, GROUP_USER_PERMISSION_MODERATOR), 0, 1000)); if ($count_users_group == 1) { $count_users_group = $count_users_group . ' ' . get_lang('Member'); } else { $count_users_group = $count_users_group . ' ' . get_lang('Members'); } $name = cut($result['name'], GROUP_TITLE_LENGTH, true); $picture = $usergroup->get_picture_group($result['id'], $result['picture'], 80); $result['picture'] = '<img class="social-groups-image" src="' . $picture['file'] . '" />'; $item_0 = Display::div($result['picture'], array('class' => 'box_description_group_image')); $members = Display::span($count_users_group, array('class' => 'box_description_group_member')); $item_1 = Display::div(Display::tag('h4', $url_open . $name . $url_close) . $members, array('class' => 'box_description_group_title')); if ($result['description'] != '') { $item_3 = '<div class="box_description_group_content" >' . cut($result['description'], 100, true) . '</div>'; } else { $item_2 = '<div class="box_description_group_title" ><span class="social-groups-text2"></span></div>'; $item_3 = '<div class="box_description_group_content" ></div>'; } $join_url = ''; if (!in_array($id, $my_group_list)) { $join_url = '<a class="btn" href="group_view.php?id=' . $id . '&action=join&u=' . api_get_user_id() . '">' . get_lang('JoinGroup') . '</a> '; } $item_4 = '<div class="box_description_group_actions" >' . $join_url . '</div>'; $grid_item_2 = $item_0 . $item_1 . $item_2 . $item_3 . $item_4; $grid_pop_groups[] = array($grid_item_2); } }
function print_recursive($elements, $default_data, $default_content) { $return = ''; foreach ($elements as $key => $item) { if (isset($item['load_data']) || empty($item['data'])) { $item['data'] = $default_data[$item['load_data']]; $item['type'] = $default_content[$item['load_data']]['item_type']; } $sub_list = ''; if (isset($item['type']) && $item['type'] == 'dokeos_chapter') { $sub_list = Display::tag('li', '', array('class' => 'sub_item empty')); // empty value } if (empty($item['children'])) { $sub_list = Display::tag('ul', $sub_list, array('id' => 'UL_' . $key, 'class' => 'record li_container')); $active = null; if (isset($_REQUEST['id']) && $key == $_REQUEST['id']) { $active = 'active'; } $return .= Display::tag('li', Display::div($item['data'], array('class' => "item_data {$active}")) . $sub_list, array('id' => $key, 'class' => 'record li_container')); } else { //sections if (isset($item['children'])) { $data = self::print_recursive($item['children'], $default_data, $default_content); } $sub_list = Display::tag('ul', $sub_list . $data, array('id' => 'UL_' . $key, 'class' => 'record li_container')); $return .= Display::tag('li', Display::div($item['data'], array('class' => 'item_data')) . $sub_list, array('id' => $key, 'class' => 'record li_container')); } } return $return; }
/** * @param int $user_id * @param $filter * @param bool $load_dirs * @param int $getCount * @param int $start * @param null $maxPerPage * @return null|string */ public static function displayCourses($user_id, $filter, $load_dirs, $getCount, $start = null, $maxPerPage = null) { // Table definitions $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE); $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); $TABLE_ACCESS_URL_REL_COURSE = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); $current_url_id = api_get_current_access_url_id(); // Get course list auto-register $special_course_list = self::get_special_course_list(); $without_special_courses = ''; if (!empty($special_course_list)) { //$without_special_courses = ' AND course.code NOT IN ("'.implode('","',$special_course_list).'")'; } $select = " SELECT DISTINCT\n course.id,\n course.title,\n course.code,\n course.subscribe subscr,\n course.unsubscribe unsubscr,\n course_rel_user.status status,\n course_rel_user.sort sort,\n course_rel_user.user_course_cat user_course_cat,\n course.id as real_id\n "; $from = "{$TABLECOURS} course, {$TABLECOURSUSER} course_rel_user, {$TABLE_ACCESS_URL_REL_COURSE} url "; $where = " course.id = course_rel_user.c_id AND\n url.c_id = course.id AND\n course_rel_user.user_id = '" . $user_id . "' AND\n course_rel_user.user_course_cat = 0\n "; $order = " ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC"; if ($getCount) { $select = "SELECT count(course.id) as total"; } $sql = "{$select} FROM {$from} WHERE {$where} {$without_special_courses} "; // corresponding to the current URL. if (api_get_multiple_access_url() && $current_url_id != -1) { $sql .= " AND url.c_id = course.id AND access_url_id='" . $current_url_id . "'"; } $sql .= $order; if (isset($start) && isset($maxPerPage)) { $start = intval($start); $maxPerPage = intval($maxPerPage); $limitCondition = " LIMIT {$start}, {$maxPerPage}"; $sql .= $limitCondition; } if ($getCount) { $result = Database::query($sql); $row = Database::fetch_array($result); return $row['total']; } $result = Database::query($sql); $html = null; $course_list = array(); // Browse through all courses. while ($course = Database::fetch_array($result)) { $course_info = api_get_course_info($course['code']); $course_info['id_session'] = null; $course_info['status'] = $course['status']; //In order to avoid doubles if (in_array($course_info['real_id'], $course_list)) { continue; } else { $course_list[] = $course_info['real_id']; } // For each course, get if there is any notification icon to show // (something that would have changed since the user's last visit). $show_notification = Display::show_notification($course_info); // New code displaying the user's status in respect to this course. $status_icon = Display::return_icon('blackboard.png', $course_info['title'], array(), ICON_SIZE_LARGE); $params = array(); $params['right_actions'] = ''; if (api_is_platform_admin()) { if ($load_dirs) { $params['right_actions'] .= '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview" href="javascript:void(0);">' . Display::return_icon('folder.png', get_lang('Documents'), array('align' => 'absmiddle'), ICON_SIZE_SMALL) . '</a>'; $params['right_actions'] .= '<a href="' . api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course['code'] . '">' . Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'), ICON_SIZE_SMALL) . '</a>'; $params['right_actions'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container')); } else { $params['right_actions'] .= '<a href="' . api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course['code'] . '">' . Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'), ICON_SIZE_SMALL) . '</a>'; } if ($course_info['status'] == COURSEMANAGER) { //echo Display::return_icon('teachers.gif', get_lang('Status').': '.get_lang('Teacher'), array('style'=>'width: 11px; height: 11px;')); } } else { if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) { if ($load_dirs) { $params['right_actions'] .= '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview" href="javascript:void(0);">' . Display::return_icon('folder.png', get_lang('Documents'), array('align' => 'absmiddle'), ICON_SIZE_SMALL) . '</a>'; $params['right_actions'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container')); } else { if ($course_info['status'] == COURSEMANAGER) { $params['right_actions'] .= '<a href="' . api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course['code'] . '">' . Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'), ICON_SIZE_SMALL) . '</a>'; } } } } $course_title_url = ''; if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED || $course['status'] == COURSEMANAGER) { //$course_title_url = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/index.php?id_session=0'; $course_title_url = api_get_path(WEB_COURSE_PATH) . $course_info['code'] . '/index.php?id_session=0'; $course_title = Display::url($course_info['title'], $course_title_url); } else { $course_title = $course_info['title'] . " " . Display::tag('span', get_lang('CourseClosed'), array('class' => 'item_closed')); } // Start displaying the course block itself if (api_get_setting('course.display_coursecode_in_courselist') == 'true') { $course_title .= ' (' . $course_info['visual_code'] . ') '; } $teachers = null; if (api_get_setting('course.display_teacher_in_courselist') == 'true') { $teachers = $course_info['teacher_list_formatted']; } $params['link'] = $course_title_url; $params['icon'] = $status_icon; $params['title'] = $course_title; $params['teachers'] = $teachers; if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) { $params['notifications'] = $show_notification; } $is_subcontent = true; if (empty($user_category_id)) { $is_subcontent = false; } $html .= self::course_item_html($params, $is_subcontent); } return $html; }
if (count($grid_pop_groups) > 0) { $popular_content = Display::return_sortable_grid( 'mygroups', array(), $grid_pop_groups, array('hide_navigation' => true, 'per_page' => 100), $query_vars, false, array(true, true, true, true, true) ); } } if (!empty($create_group_item)) { $social_right_content .= Display::div( $create_group_item, array('class' => 'span9') ); } $headers = array( get_lang('Newest'), get_lang('Popular'), get_lang('MyGroups') ); $social_right_content .= '<div class="span9">' . Display::tabs( $headers, array($newest_content, $popular_content, $my_group_content), 'tab_browse' ) . '</div>'; } $show_message = null;
/** * Displays message "You are not allowed here..." and exits the entire script. * @param bool $print_headers Whether or not to print headers (default = false -> does not print them) * @param string $message */ function api_not_allowed($print_headers = false, $message = null) { $message = get_lang('NotAllowed'); throw new Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException($message); if (api_get_setting('sso_authentication') === 'true') { global $osso; if ($osso) { $osso->logout(); } } $home_url = api_get_path(WEB_PATH); $user_id = api_get_user_id(); $course = api_get_course_id(); global $this_section; if (CustomPages::enabled() && !isset($user_id)) { if (empty($user_id)) { // Why the CustomPages::enabled() need to be to set the request_uri $_SESSION['request_uri'] = $_SERVER['REQUEST_URI']; } CustomPages::display(CustomPages::INDEX_UNLOGGED); } $origin = isset($_GET['origin']) ? $_GET['origin'] : ''; $msg = null; if (isset($message)) { $msg = $message; } else { $msg = Display::return_message(get_lang('NotAllowedClickBack') . '<br/><br/><a href="' . $home_url . '">' . get_lang('ReturnToCourseHomepage') . '</a>', 'error', false); } $msg = Display::div($msg, array('align' => 'center')); $show_headers = 0; if ($print_headers && $origin != 'learnpath') { $show_headers = 1; } $tpl = new Template(null, $show_headers, $show_headers); $tpl->assign('hide_login_link', 1); $tpl->assign('content', $msg); if ($user_id != 0 && !api_is_anonymous() && (!isset($course) || $course == -1) && empty($_GET['cidReq'])) { // if the access is not authorized and there is some login information // but the cidReq is not found, assume we are missing course data and send the user // to the user_portal $tpl->display_one_col_template(); exit; } if (!empty($_SERVER['REQUEST_URI']) && (!empty($_GET['cidReq']) || $this_section == SECTION_MYPROFILE || $this_section == SECTION_PLATFORM_ADMIN)) { $courseCode = api_get_course_id(); // Only display form and return to the previous URL if there was a course ID included if ($user_id != 0 && !api_is_anonymous()) { //if there is a user ID, then the user is not allowed but the session is still there. Say so and exit $tpl->assign('content', $msg); $tpl->display_one_col_template(); exit; } if (!is_null($courseCode)) { api_set_firstpage_parameter($courseCode); } // If the user has no user ID, then his session has expired $action = api_get_self() . '?' . Security::remove_XSS($_SERVER['QUERY_STRING']); $action = str_replace('&', '&', $action); $form = new FormValidator('formLogin', 'post', $action, null, array(), FormValidator::LAYOUT_BOX_NO_LABEL); $form->addElement('text', 'login', null, array('placeholder' => get_lang('UserName'), 'class' => 'autocapitalize_off')); $form->addElement('password', 'password', null, array('placeholder' => get_lang('Password'))); $form->addButton('submitAuth', get_lang('LoginEnter'), '', 'primary'); // see same text in auth/gotocourse.php and main_api.lib.php function api_not_allowed (above) $content = Display::return_message(get_lang('NotAllowed'), 'error', false); if (!empty($courseCode)) { $content .= '<h4>' . get_lang('LoginToGoToThisCourse') . '</h4>'; } if (api_is_cas_activated()) { $content .= Display::return_message(sprintf(get_lang('YouHaveAnInstitutionalAccount'), api_get_setting("Institution")), '', false); $content .= Display::div("<br/><a href='" . get_cas_direct_URL(api_get_course_id()) . "'>" . sprintf(get_lang('LoginWithYourAccount'), api_get_setting("Institution")) . "</a><br/><br/>", array('align' => 'center')); $content .= Display::return_message(get_lang('YouDontHaveAnInstitutionAccount')); $content .= "<p style='text-align:center'><a href='#' onclick='\$(this).parent().next().toggle()'>" . get_lang('LoginWithExternalAccount') . "</a></p>"; $content .= "<div style='display:none;'>"; } $content .= '<div class="well_login">'; $content .= $form->return_form(); $content .= '</div>'; if (api_is_cas_activated()) { $content .= "</div>"; } if (!empty($courseCode)) { $content .= '<hr/><p style="text-align:center"><a href="' . $home_url . '">' . get_lang('ReturnToCourseHomepage') . '</a></p>'; } else { $content .= '<hr/><p style="text-align:center"><a href="' . $home_url . '">' . get_lang('CampusHomepage') . '</a></p>'; } $tpl->setLoginBodyClass(); $tpl->assign('content', $content); $tpl->display_one_col_template(); exit; } if ($user_id != 0 && !api_is_anonymous()) { $tpl->display_one_col_template(); exit; } $msg = null; // The session is over and we were not in a course, // or we try to get directly to a private course without being logged if (!is_null(api_get_course_int_id())) { api_set_firstpage_parameter(api_get_course_id()); $tpl->setLoginBodyClass(); $action = api_get_self() . '?' . Security::remove_XSS($_SERVER['QUERY_STRING']); $action = str_replace('&', '&', $action); $form = new FormValidator('formLogin', 'post', $action, null, array('class' => 'form-stacked')); $form->addElement('text', 'login', null, array('placeholder' => get_lang('UserName'), 'class' => 'col-md-3 autocapitalize_off')); //new $form->addElement('password', 'password', null, array('placeholder' => get_lang('Password'), 'class' => 'col-md-3')); //new $form->addButtonNext(get_lang('LoginEnter'), 'submitAuth'); // see same text in auth/gotocourse.php and main_api.lib.php function api_not_allowed (bellow) $msg = Display::return_message(get_lang('NotAllowed'), 'error', false); $msg .= '<h4>' . get_lang('LoginToGoToThisCourse') . '</h4>'; if (api_is_cas_activated()) { $msg .= Display::return_message(sprintf(get_lang('YouHaveAnInstitutionalAccount'), api_get_setting("Institution")), '', false); $msg .= Display::div("<br/><a href='" . get_cas_direct_URL(api_get_course_int_id()) . "'>" . getCASLogoHTML() . " " . sprintf(get_lang('LoginWithYourAccount'), api_get_setting("Institution")) . "</a><br/><br/>", array('align' => 'center')); $msg .= Display::return_message(get_lang('YouDontHaveAnInstitutionAccount')); $msg .= "<p style='text-align:center'><a href='#' onclick='\$(this).parent().next().toggle()'>" . get_lang('LoginWithExternalAccount') . "</a></p>"; $msg .= "<div style='display:none;'>"; } $msg .= '<div class="well">'; $msg .= $form->return_form(); $msg .= '</div>'; if (api_is_cas_activated()) { $msg .= "</div>"; } $msg .= '<hr/><p style="text-align:center"><a href="' . $home_url . '">' . get_lang('ReturnToCourseHomepage') . '</a></p>'; } else { // we were not in a course, return to home page $msg = Display::return_message(get_lang('NotAllowed') . '<br/><br/><a href="' . $home_url . '">' . get_lang('ReturnToCourseHomepage') . '</a><br />', 'error', false); } $tpl->assign('content', $msg); $tpl->display_one_col_template(); exit; }
static function get_document_preview($course_info, $lp_id = false, $target = '', $session_id = 0, $add_move_button = false, $filter_by_folder = null, $overwrite_url = null) { if (empty($course_info['real_id']) || empty($course_info['code']) || !is_array($course_info)) { return ''; } $user_id = api_get_user_id(); $user_in_course = false; if (api_is_platform_admin()) { $user_in_course = true; } if (!$user_in_course) { if (CourseManager::is_course_teacher($user_id, $course_info['real_id'])) { $user_in_course = true; } } //condition for the session $session_id = intval($session_id); if (!$user_in_course) { if (empty($session_id)) { if (CourseManager::is_user_subscribed_in_course($user_id, $course_info['real_id'])) { $user_in_course = true; } //Check if course is open then we can consider that the student is regitered to the course if (isset($course_info) && in_array($course_info['visibility'], array(2, 3))) { $user_in_course = true; } } else { $user_status = SessionManager::get_user_status_in_course_session($user_id, $course_info['real_id'], $session_id); //is true if is an student, course session teacher or coach if (in_array($user_status, array('0', '2', '6'))) { $user_in_course = true; } } } $tbl_doc = Database::get_course_table(TABLE_DOCUMENT); $tbl_item_prop = Database::get_course_table(TABLE_ITEM_PROPERTY); $path = '/'; $path = Database::escape_string(str_replace('_', '\\_', $path)); $added_slash = $path == '/' ? '' : '/'; //$condition_session = " AND (id_session = '$session_id' OR (id_session = '0' AND insert_date <= (SELECT creation_date FROM $tbl_course WHERE code = '".$course_info['code']."' )))"; $condition_session = " AND (id_session = '{$session_id}' OR id_session = '0' )"; $add_folder_filter = null; if (!empty($filter_by_folder)) { $add_folder_filter = " AND docs.path LIKE '" . Database::escape_string($filter_by_folder) . "%'"; } $sql_doc = "SELECT last.visibility, docs.*\n\t\t\t\t\tFROM {$tbl_item_prop} AS last, {$tbl_doc} AS docs\n \t WHERE docs.id = last.ref AND\n docs.path LIKE '" . $path . $added_slash . "%' AND\n docs.path NOT LIKE '%_DELETED_%' AND\n last.tool = '" . TOOL_DOCUMENT . "' {$condition_session} AND\n last.visibility = '1' AND\n docs.c_id = {$course_info['real_id']} AND\n last.c_id = {$course_info['real_id']}\n {$add_folder_filter}\n ORDER BY docs.title ASC"; $res_doc = Database::query($sql_doc); $resources = Database::store_result($res_doc, 'ASSOC'); $resources_sorted = array(); $return = ''; if ($lp_id) { $return .= '<div class="lp_resource_element">'; $return .= Display::return_icon('new_doc.gif', '', array(), ICON_SIZE_SMALL); $return .= Display::url(get_lang('NewDocument'), api_get_self() . '?' . api_get_cidreq() . '&action=add_item&type=' . TOOL_DOCUMENT . '&lp_id=' . $_SESSION['oLP']->lp_id); $return .= '</div>'; } else { $return .= Display::div(Display::url(Display::return_icon('close.png', get_lang('Close'), array(), ICON_SIZE_SMALL), ' javascript:void(0);', array('id' => 'close_div_' . $course_info['real_id'] . '_' . $session_id, 'class' => 'close_div')), array('style' => 'position:absolute;right:10px')); } // If you want to debug it, I advise you to do "echo" on the eval statements. if (!empty($resources) && $user_in_course) { foreach ($resources as $resource) { $is_visible = self::is_visible_by_id($resource['id'], $course_info, $session_id, api_get_user_id()); if (!$is_visible) { continue; } $resource_paths = explode('/', $resource['path']); array_shift($resource_paths); $path_to_eval = $last_path = ''; $is_file = false; if ($resource['filetype'] == 'file') { foreach ($resource_paths as $key => $resource_path) { if ($key != count($resource_paths) - 1) { // It's a folder. $path_to_eval .= "['{$resource_path}']['files']"; } $is_file = true; } } else { foreach ($resource_paths as $key => $resource_path) { if ($key != count($resource_paths) - 1) { // It's a folder. $path_to_eval .= "['{$resource_path}']['files']"; } } } $last_path = $resource_path; //$data = json_encode(array('title'=>$resource['title'], 'path'=>$last_path)); //@todo not sure if it's a good thing using base64_encode. I tried with json_encode but i received the same error //Some testing is needed in order to prove the performance //Also change the explode to value from "/" to "|@j@|" it fixes #3780 $data = base64_encode($resource['title'] . '|@j@|' . $last_path); if ($is_file) { //for backward compatibility if (empty($resource['title'])) { $resource['title'] = basename($resource['path']); } eval('$resources_sorted' . $path_to_eval . '[' . $resource['id'] . '] = "' . $data . '" ; '); } else { eval('$resources_sorted' . $path_to_eval . '["' . $last_path . '"]["id"]=' . $resource['id'] . ';'); eval('$resources_sorted' . $path_to_eval . '["' . $last_path . '"]["title"]= "' . api_htmlentities($resource['title']) . '";'); } } } $label = get_lang('Documents'); $new_array[$label] = array('id' => 0, 'files' => $resources_sorted); $write_result = self::write_resources_tree($course_info, $session_id, $new_array, 0, $lp_id, $target, $add_move_button, $overwrite_url); $return .= $write_result; $img_path = api_get_path(WEB_IMG_PATH); if ($lp_id == false) { $return .= "<script>\n \t\t \t\$('.doc_folder').mouseover(function() {\n \t\t\t\t\tvar my_id = this.id.split('_')[2];\n \t\t\t\t\t\$('#res_'+my_id).show();\n \t\t\t\t});\n\n \t\t\t\t\$('.close_div').click(function() {\n \t\t\t\t\tvar course_id = this.id.split('_')[2];\n \t\t\t\t\tvar session_id = this.id.split('_')[3];\n \t\t\t\t\t\$('#document_result_'+course_id+'_'+session_id).hide();\n \t\t\t\t\t\$('.lp_resource').remove();\n \t\t\t\t});\n \t\t\t\t</script>"; } else { //For LPs $return .= "<script>\n\n \t\tfunction testResources(id, img) {\n\t \t\tif (document.getElementById(id).style.display=='block'){\n\t \t\t\tdocument.getElementById(id).style.display='none';\n var id = id.split('_')[1];\n\t \t\t\tdocument.getElementById('img_'+id).src='" . $img_path . "nolines_plus.gif';\n\t \t\t} else {\n\t \t\t\tdocument.getElementById(id).style.display='block';\n var id = id.split('_')[1];\n \t\t\t\tdocument.getElementById('img_'+id).src='" . $img_path . "nolines_minus.gif';\n \t\t\t}\n \t\t}\n \t\t</script>"; } if (!$user_in_course) { $return = ''; } return $return; }
/** * Shows a question * * @param int $questionId question id * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param bool $exercise_feedback * @param bool $show_answers * */ function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) { // Text direction for the current language $is_ltr_text_direction = api_get_text_direction() != 'rtl'; // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; //api_is_allowed_to_edit() && false; // Reads question information if (!($objQuestionTmp = Question::read($questionId))) { // Question not found return false; } if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { Testcategory::displayCategoryAndTitle($objQuestionTmp->id); echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); } if (!empty($questionDescription)) { echo Display::div($questionDescription, array('class' => 'question_description')); } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return ''; } echo '<div class="question_options">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $course_id = api_get_course_int_id(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if ($answerType == MATCHING) { $s .= '<table class="data_table">'; // Iterate through answers $x = 1; //mark letters for each answer $letter = 'A'; $answer_matching = array(); $cpt1 = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $answer = $objAnswerTmp->selectAnswer($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $cpt1[$x] = $letter; $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer); $x++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id']; $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $user_choice_array_position = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array_position[$item['position']] = $item['answer']; } } $num_suggestions = $nbrAnswers - $x + 1; } elseif ($answerType == FREE_ANSWER) { $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $oFCKeditor = new FCKeditor("choice[" . $questionId . "]"); $oFCKeditor->ToolbarSet = 'TestFreeAnswer'; $oFCKeditor->Width = '100%'; $oFCKeditor->Height = '200'; $oFCKeditor->Value = $fck_content; $s .= $oFCKeditor->CreateHtml(); } elseif ($answerType == ORAL_EXPRESSION) { //Add nanog if (api_get_setting('enable_nanogong') == 'true') { require_once api_get_path(LIBRARY_PATH) . 'nanogong.lib.php'; //@todo pass this as a parameter global $exercise_stat_info, $exerciseId, $exe_id; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); echo $nano->show_button(); } $oFCKeditor = new FCKeditor("choice[" . $questionId . "]"); $oFCKeditor->ToolbarSet = 'TestFreeAnswer'; $oFCKeditor->Width = '100%'; $oFCKeditor->Height = '150'; $oFCKeditor->ToolbarStartExpanded = false; $oFCKeditor->Value = ''; $s .= $oFCKeditor->CreateHtml(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { if (in_array($item, $objQuestionTmp->options)) { $header .= Display::tag('th', get_lang($item)); } else { $header .= Display::tag('th', $item); } } else { $header .= Display::tag('th', $item); } } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="data_table">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="data_table">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $comment = $objAnswerTmp->selectComment($answerId); $attributes = array(); // Unique answer if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer, STUDENT); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { /* * In the FILL_IN_BLANKS test * you mustn't have [ and ] in the textarea * you mustn't have :: in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ list($answer) = explode('::', $answer); // $correct_answer_list array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correct_answer_list); // get student answer to display it if student go back to previous fillBlank answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $user_choice[0]['answer'], $student_answer_list); $student_answer_list_tobecleaned = $student_answer_list[0]; $student_answer_list = array(); // here we got the student answer in a test // let's clean up the results /* Array ( [0] => Array ( [0] => [<font color="red"><s>yer</s></font> / <font color="green"><b>ici</b></font>] [1] => [<font color="red"><s>plop</s></font> / <font color="green"><b>/p</b></font>] ) ) */ for ($i = 0; $i < count($student_answer_list_tobecleaned); $i++) { $answer_corrected = $student_answer_list_tobecleaned[$i]; /* * we got if student answer is wrong * [<font color="red"><s>rrr</s></font> / <font color="green"><b>/p</b></font>] * or if student answer is good * [plop / <font color="green"><b>plop</b></font>] * or if student didn't answer [] */ $answer_corrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answer_corrected); /* * we got [<font color="red"><s>rrr</s></font> or [plop or [ */ $answer_corrected = api_preg_replace('/^\\[/', '', $answer_corrected); /* * we got <font color="red"><s>rrr</s></font> or plop * non breakable spaces from /main/exercice/exercise.class.php have been removed l 2391 and l 2370 */ $answer_corrected = api_preg_replace('|^<font color="red"><s>|', '', $answer_corrected); $answer_corrected = api_preg_replace('|</s></font>$|', '', $answer_corrected); $answer_corrected = '[' . $answer_corrected . ']'; /* * we got [rrr] or [plop] or [] */ $student_answer_list[] = $answer_corrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $student_answer_list = $correct_answer_list[0]; } /* Split the response by bracket tab_comments is an array with text surrounding the text to find we add a space before and after the answer_question to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tab_comments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correct_answer_list) && !empty($student_answer_list)) { $answer = ""; $i = 0; foreach ($student_answer_list as $student_item) { // remove surronding brackets $student_response = api_substr($student_item, 1, api_strlen($student_item) - 2); $size = strlen($student_item); $attributes['class'] = detectInputAppropriateClass($size); $answer .= $tab_comments[$i] . Display::input('text', "choice[{$questionId}][]", $student_response, $attributes); $i++; } $answer .= $tab_comments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correct_answer_list[0] as $item) { $size = strlen($item); $attributes['class'] = detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } /*$answer = api_preg_replace( '/\[[^]]+\]/', Display::input( 'text', "choice[$questionId][]", '', $attributes ), $answer);*/ } $s .= $answer; } elseif ($answerType == CALCULATED_ANSWER) { /* * In the CALCULATED_ANSWER test * you mustn't have [ and ] in the textarea * you mustn't have @@ in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ if ($origin !== null) { global $exe_id; $trackAttempts = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId; $rsLastAttempt = Database::query($sqlTrackAttempt); $rowLastAttempt = Database::fetch_array($rsLastAttempt); $answer = $rowLastAttempt['answer']; if (empty($answer)) { $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers); $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]); } } list($answer) = explode('@@', $answer); // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList); // get student answer to display it if student go back to previous calculated answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $answer, $studentAnswerList); $studentAnswerListTobecleaned = $studentAnswerList[0]; $studentAnswerList = array(); for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) { $answerCorrected = $studentAnswerListTobecleaned[$i]; $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected); $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected); $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected); $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected); $answerCorrected = '[' . $answerCorrected . ']'; $studentAnswerList[] = $answerCorrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $studentAnswerList = $correctAnswerList[0]; } /* Split the response by bracket tabComments is an array with text surrounding the text to find we add a space before and after the answerQuestion to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2); $size = strlen($studentItem); $attributes['class'] = detectInputAppropriateClass($size); $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes); $i++; } $answer .= $tabComments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correctAnswerList[0] as $item) { $size = strlen($item); $attributes['class'] = detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } } if ($origin !== null) { $s = $answer; break; } else { $s .= $answer; } } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) $s .= '<tr><td width="45%" valign="top">'; $parsed_answer = $answer; //left part questions $s .= ' <span style="float:left; width:8%;"><b>' . $lines_count . '</b>. </span> <span style="float:left; width:92%;">' . $parsed_answer . '</span></td>'; //middle part (matches selects) $s .= '<td width="10%" valign="top" align="center"> <select name="choice[' . $questionId . '][' . $numAnswer . ']">'; // fills the list-box foreach ($select_items as $key => $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; } } //$user_choice_array_position if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) { $selected = 'selected="selected"'; } /*if (isset($user_choice_array[$matching_correct_answer]) && $val['id'] == $user_choice_array[$matching_correct_answer]['answer']) { $selected = 'selected="selected"'; }*/ $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>'; } // end foreach() $s .= '</select></td>'; $s .= '<td width="45%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<span style="float:left; width:5%;"><b>' . $select_items[$lines_count]['letter'] . '.</b></span>' . '<span style="float:left; width:95%;">' . $select_items[$lines_count]['answer'] . '</span>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer']; $s .= "</td>\n \t\t\t\t\t\t</tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } } // end for() if ($show_comment) { $s .= '</table>'; } else { if ($answerType == MATCHING || $answerType == UNIQUE_ANSWER_NO_OPTION || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '</table>'; } } $s .= '</div>'; // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); if ($origin != 'export') { echo $s; } else { return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { require_once api_get_path(LIBRARY_PATH) . 'document.lib.php'; $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { echo Display::img($objQuestionTmp->selectPicturePath()); return; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); // get answers of hotpost $answers_hotspot = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId); } // display answers of hotpost order by id $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>'; if (!empty($answers_hotspot)) { ksort($answers_hotspot); foreach ($answers_hotspot as $key => $value) { $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />'; } } $answer_list .= '</dl></div>'; if ($answerType == HOT_SPOT_DELINEATION) { $answer_list = ''; $swf_file = 'hotspot_delineation_user'; $swf_height = 405; } else { $swf_file = 'hotspot_user'; $swf_height = 436; } if (!$only_questions) { if ($show_title) { Testcategory::displayCategoryAndTitle($objQuestionTmp->id); echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; } //@todo I need to the get the feedback type echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />'; echo '<table class="exercise_questions" > <tr> <td valign="top" colspan="2">'; echo $questionDescription; echo '</td></tr>'; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script> <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script> <script type="text/javascript"> <!-- // Globals // Major version of Flash required var requiredMajorVersion = 7; // Minor version of Flash required var requiredMinorVersion = 0; // Minor version of Flash required var requiredRevision = 0; // the version of javascript supported var jsVersion = 1.0; // --> </script> <script language="VBScript" type="text/vbscript"> <!-- // Visual basic helper required to detect Flash Player ActiveX control version information Function VBGetSwfVer(i) on error resume next Dim swControl, swVersion swVersion = 0 set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i)) if (IsObject(swControl)) then swVersion = swControl.GetVariable("$version") end if VBGetSwfVer = swVersion End Function // --> </script> <script language="JavaScript1.1" type="text/javascript"> <!-- // Detect Client Browser type var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; jsVersion = 1.1; // JavaScript helper required to detect Flash Player PlugIn version information function JSGetSwfVer(i) { // NS/Opera version >= 3 check for Flash plugin in plugin array if (navigator.plugins != null && navigator.plugins.length > 0) { if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; descArray = flashDescription.split(" "); tempArrayMajor = descArray[2].split("."); versionMajor = tempArrayMajor[0]; versionMinor = tempArrayMajor[1]; if ( descArray[3] != "" ) { tempArrayMinor = descArray[3].split("r"); } else { tempArrayMinor = descArray[4].split("r"); } versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; flashVer = versionMajor + "." + versionMinor + "." + versionRevision; } else { flashVer = -1; } } // MSN/WebTV 2.6 supports Flash 4 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; // WebTV 2.5 supports Flash 3 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; // older WebTV supports Flash 2 else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; // Can\'t detect in all other cases else { flashVer = -1; } return flashVer; } // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) { reqVer = parseFloat(reqMajorVer + "." + reqRevision); // loop backwards through the versions until we find the newest version for (i=25;i>0;i--) { if (isIE && isWin && !isOpera) { versionStr = VBGetSwfVer(i); } else { versionStr = JSGetSwfVer(i); } if (versionStr == -1 ) { return false; } else if (versionStr != 0) { if(isIE && isWin && !isOpera) { tempArray = versionStr.split(" "); tempString = tempArray[1]; versionArray = tempString .split(","); } else { versionArray = versionStr.split("."); } versionMajor = versionArray[0]; versionMinor = versionArray[1]; versionRevision = versionArray[2]; versionString = versionMajor + "." + versionRevision; // 7.0r24 == 7.24 versionNum = parseFloat(versionString); // is the major.revision >= requested major.revision AND the minor version >= requested minor if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) { return true; } else { return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false ); } } } } // --> </script>'; $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520"> <script> <!-- // Version check based upon the values entered above in "Globals" var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision); // Check to see if the version meets the requirements for playback if (hasReqestedVersion) { // if we\'ve detected an acceptable version var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\' + \'<param name="wmode" value="transparent">\' + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\' + \'<\\/object>\'; document.write(oeTags); // embed the Flash Content SWF when all tests are passed } else { // flash is too old or we can\'t detect the plugin var alternateContent = "Error<br \\/>" + "Hotspots requires Macromedia Flash 7.<br \\/>" + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>"; document.write(alternateContent); // insert non-flash content } // --> </script> </td> <td valign="top" align="left">' . $answer_list . '</td></tr> </table> </td></tr>'; echo $s; echo '</table>'; } return $nbrAnswers; }
<div class="span3"> <a class="profile_link" href="' . $userInfo['profile_url'] . '">' . $userInfo['complete_name'] . '</a> <div>' . $title . ' : ' . $content . '</div> <div>' . get_lang('DateSend') . ' : ' . $date . '</div> </div> </div>'; } } if (count($pending_invitations) > 0) { $social_right_content .= Display::page_subheader(get_lang('GroupsWaitingApproval')); $new_invitation = array(); foreach ($pending_invitations as $invitation) { $picture = $usergroup->get_picture_group($invitation['id'], $invitation['picture'], 80); $img = '<img class="social-groups-image" src="' . $picture['file'] . '" hspace="4" height="50" border="2" align="left" width="50" />'; $invitation['picture'] = '<a href="groups.php?id=' . $invitation['id'] . '">' . $img . '</a>'; $invitation['name'] = '<a href="groups.php?id=' . $invitation['id'] . '">' . Text::cut($invitation['name'], 120, true) . '</a>'; $invitation['join'] = '<a class="btn btn-primary" href="invitations.php?accept=' . $invitation['id'] . '">' . get_lang('AcceptInvitation') . '</a>'; $invitation['deny'] = '<a class="btn btn-danger" href="invitations.php?deny=' . $invitation['id'] . '">' . get_lang('DenyInvitation') . '</a>'; $invitation['description'] = Text::cut($invitation['description'], 220, true); $new_invitation[] = $invitation; } $social_right_content .= Display::return_sortable_grid('waiting_user', array(), $new_invitation, array('hide_navigation' => true, 'per_page' => 100), array(), false, array(true, true, true, false, false, true, true, true, true)); } $social_right_content = Display::div($social_right_content, array('class' => 'span9')); $tpl = $app['template']; $tpl->assign('social_left_content', $social_left_content); $tpl->assign('social_right_content', $social_right_content); $tpl->assign('message', $show_message); $tpl->assign('content', $content); $social_layout = $tpl->get_template('layout/social_layout.tpl'); $tpl->display($social_layout);
/** * @todo use the template system */ function show_right_block($title, $content, $id = null, $params = null) { if (!empty($id)) { $params['id'] = $id; } $params['class'] = 'well sidebar-nav'; $html = null; if (!empty($title)) { $html.= '<h4>'.$title.'</h4>'; } $html.= $content; $html = Display::div($html, $params); return $html; }
/** * This function returns the content of a table in a grid * Should not be use to edit information (edit/delete rows) only. * @param array options of visibility * @param bool hide navigation optionally * @param int content per page when show navigation (optional) * @param bool sort data optionally * @return string grid html */ public function display_simple_grid($visibility_options, $hide_navigation = true, $per_page = 20, $sort_data = true, $grid_class = array()) { $empty_table = false; $total = $this->get_total_number_of_items(); if ($this->get_total_number_of_items() == 0) { $cols = $this->getColCount(); //$this->setCellAttributes(1, 0, 'style="font-style: italic;text-align:center;" colspan='.$cols); $message_empty = api_xml_http_response_encode(get_lang('TheListIsEmpty')); $this->setCellContents(1, 0, $message_empty); $empty_table = true; } $html = ''; if (!$empty_table) { // If we show the pagination if (!$hide_navigation) { $form = ' '; if ($this->get_total_number_of_items() > $per_page) { if ($per_page > 10) { $form = $this->get_page_select_form(); } $nav = $this->get_navigation_html(); // This also must be moved $html = '<div class="sub-header">'; $html .= '<div class="grid_selectbox">' . $form . '</div>'; $html .= '<div class="grid_title">' . $this->get_table_title() . '</div>'; $html .= '<div class="grid_nav">' . $nav . '</div>'; $html .= '</div>'; } } $html .= '<div class="clear"></div>'; if (count($this->form_actions) > 0) { $script = '<script> /*<![CDATA[*/ function setCheckbox(value) { d = document.form_' . $this->table_name . '; for (i = 0; i < d.elements.length; i++) { if (d.elements[i].type == "checkbox") { d.elements[i].checked = value; } if (value) { $(d.elements[i]).parentsUntil("tr").parent().addClass("row_selected"); } else { $(d.elements[i]).parentsUntil("tr").parent().removeClass("row_selected"); } } } /*]]>*/ </script>'; $params = $this->get_sortable_table_param_string() . '&' . $this->get_additional_url_paramstring(); $html .= '<form method="post" action="' . api_get_self() . '?' . $params . '" name="form_' . $this->table_name . '">'; } } if ($hide_navigation) { $items = $this->table_data; // This is a faster way to get what we want } else { // The normal way $items = $this->get_clean_html($sort_data); // Getting the items of the table } // Generation of style classes must be improved. Maybe we need a a table name to create style on the fly: // i.e: .whoisonline_table_grid_container instead of .grid_container // where whoisonline is the table's name like drupal's template engine if (is_array($visibility_options)) { $filter = false; // The 2nd condition of the if will be loaded } else { $filter = $visibility_options !== false; } $item_css_class = $item_css_style = $grid_css_class = $grid_css_style = ''; if (!empty($grid_class)) { $grid_css_class = $grid_class['main']['class']; $item_css_class = $grid_class['item']['class']; $grid_css_style = isset($grid_class['main']['style']) ? $grid_class['main']['style'] : null; $item_css_style = isset($grid_class['item']['style']) ? $grid_class['item']['style'] : null; } $div = ''; if (is_array($items) && count($items) > 0) { foreach ($items as &$row) { $i = 0; $rows = ''; foreach ($row as &$element) { if ($filter || $visibility_options[$i]) { $rows .= '<div class="' . $this->table_name . '_grid_element_' . $i . '">' . $element . '</div>'; } $i++; } $div .= Display::div($rows, array('class' => $item_css_class . ' ' . $this->table_name . '_grid_item', 'style' => $item_css_style)); } } $html .= Display::div($div, array('class' => $grid_css_class . ' ' . $this->table_name . '_grid_container', 'style' => $grid_css_style)); $html .= '<div class="clear"></div>'; return $html; }
/** * Display the already registerd text in a course in the course catalog * @param $in_status */ function return_already_registered_label($in_status) { $icon = Display::return_icon('teacher.png', get_lang('Teacher'), null, ICON_SIZE_TINY); if ($in_status == 'student') { $icon = Display::return_icon('user.png', get_lang('Student'), null, ICON_SIZE_TINY); } $html = Display::div($icon . ' ' . get_lang("AlreadyRegisteredToCourse"), array('id' => 'register', 'class' => 'user-register')); return $html; }
/** * Shows a question * * @param int $questionId question id * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param bool $exercise_feedback * @param bool $show_answers * */ public static function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) { $course_id = api_get_course_int_id(); // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; // Reads question information if (!($objQuestionTmp = Question::read($questionId))) { // Question not found return false; } if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); } if (!empty($questionDescription)) { echo Display::div($questionDescription, array('class' => 'question_description')); } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return ''; } echo '<div class="question_options row">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) { if ($answerType == DRAGGABLE) { $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix"> <div class="clearfix"> <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">'; } else { $s .= <<<HTML <div id="drag{$questionId}_question" class="drag_question"> <table class="data_table"> HTML; } // Iterate through answers $x = 1; //mark letters for each answer $letter = 'A'; $answer_matching = array(); $cpt1 = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $cpt1[$x] = $letter; $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer); $x++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id']; $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $user_choice_array_position = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array_position[$item['position']] = $item['answer']; } } $num_suggestions = $nbrAnswers - $x + 1; } elseif ($answerType == FREE_ANSWER) { $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); $form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->returnForm(); } elseif ($answerType == ORAL_EXPRESSION) { // Add nanog if (api_get_setting('enable_nanogong') == 'true') { //@todo pass this as a parameter global $exercise_stat_info, $exerciseId, $exe_id; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); echo $nano->show_button(); } $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); //$form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->return_form(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { if (in_array($item, $objQuestionTmp->options)) { $header .= Display::tag('th', get_lang($item)); } else { $header .= Display::tag('th', $item); } } else { $header .= Display::tag('th', $item); } } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $comment = $objAnswerTmp->selectComment($answerId); $attributes = array(); // Unique answer if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($show_comment) { $s .= '<tr><td>'; } if ($answerType == UNIQUE_ANSWER_IMAGE) { if ($show_comment) { if (empty($comment)) { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image" style="text-align: center">'; } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-sm-12" style="text-align: center">'; } } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-md-3" style="text-align: center">'; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = null; if ($answerType == UNIQUE_ANSWER_IMAGE) { $attributes['style'] = 'display: none;'; $answer = '<div class="thumbnail">' . $answer . '</div>'; } $answer_input .= '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($answerType == UNIQUE_ANSWER_IMAGE) { $answer_input .= "</div>"; } if ($show_comment) { $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer, STUDENT); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); if (isset($item[1]) && isset($item[0])) { $my_choice[$item[0]] = $item[1]; } } } $answer = Security::remove_XSS($answer, STUDENT); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { // display the question, with field empty, for student to fill it, // or filled to display the answer in the Question preview of the exercice/admin.php page $displayForStudent = true; $listAnswerInformations = FillBlanks::getAnswerInfo($answer); $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); list($answer) = explode('::', $answer); //Correct answers $correctAnswerList = $listAnswerInformations['tabwords']; //Student's answer $studentAnswerList = array(); if (isset($user_choice[0]['answer'])) { $arrayStudentAnswer = FillBlanks::getAnswerInfo($user_choice[0]['answer'], true); $studentAnswerList = $arrayStudentAnswer['studentanswer']; } // If the question must be shown with the answer (in page exercice/admin.php) for teacher preview // set the student-answer to the correct answer if ($debug_mark_answer) { $studentAnswerList = $correctAnswerList; $displayForStudent = false; } if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common word $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); if (isset($studentAnswerList[$i])) { // If student already started this test and answered this question, // fill the blank with his previous answers // may be "" if student viewed the question, but did not fill the blanks $correctItem = $studentAnswerList[$i]; } $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, $correctItem, $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } else { // display empty [input] with the right width for student to fill it $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common words $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, '', $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } $s .= $answer; } elseif ($answerType == CALCULATED_ANSWER) { /* * In the CALCULATED_ANSWER test * you mustn't have [ and ] in the textarea * you mustn't have @@ in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ if ($origin !== null) { global $exe_id; $trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId; $rsLastAttempt = Database::query($sqlTrackAttempt); $rowLastAttempt = Database::fetch_array($rsLastAttempt); $answer = $rowLastAttempt['answer']; if (empty($answer)) { $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers); $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]); } } list($answer) = explode('@@', $answer); // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList); // get student answer to display it if student go back to previous calculated answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $answer, $studentAnswerList); $studentAnswerListTobecleaned = $studentAnswerList[0]; $studentAnswerList = array(); for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) { $answerCorrected = $studentAnswerListTobecleaned[$i]; $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected); $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected); $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected); $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected); $answerCorrected = '[' . $answerCorrected . ']'; $studentAnswerList[] = $answerCorrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $studentAnswerList = $correctAnswerList[0]; } /* Split the response by bracket tabComments is an array with text surrounding the text to find we add a space before and after the answerQuestion to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2); $size = strlen($studentItem); $attributes['class'] = self::detectInputAppropriateClass($size); $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes); $i++; } $answer .= $tabComments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correctAnswerList[0] as $item) { $size = strlen($item); $attributes['class'] = self::detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } } if ($origin !== null) { $s = $answer; break; } else { $s .= $answer; } } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) $s .= '<tr><td width="45%" valign="top">'; $parsed_answer = $answer; //left part questions $s .= '<p class="indent">' . $lines_count . '. ' . $parsed_answer . '</p></td>'; //middle part (matches selects) $s .= '<td width="10%" valign="top" align="center" > <div class="select-matching"> <select name="choice[' . $questionId . '][' . $numAnswer . ']">'; // fills the list-box foreach ($select_items as $key => $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; } } //$user_choice_array_position if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) { $selected = 'selected="selected"'; } $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>'; } // end foreach() $s .= '</select></div></td><td width="5%" class="separate"> </td>'; $s .= '<td width="40%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<div class="text-right"><p class="indent">' . $select_items[$lines_count]['letter'] . '. ' . $select_items[$lines_count]['answer'] . '</p></div>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer']; $s .= "</td>\n </tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } elseif ($answerType == DRAGGABLE) { if ($answerCorrect != 0) { $parsed_answer = $answer; /*$lines_count = ''; $data = $objAnswerTmp->getAnswerByAutoId($numAnswer); $data = $objAnswerTmp->getAnswerByAutoId($data['correct']); $lines_count = $data['answer'];*/ $windowId = $questionId . '_' . $lines_count; $s .= '<li class="touch-items" id="' . $windowId . '">'; $s .= Display::div($parsed_answer, ['id' => "window_{$windowId}", 'class' => "window{$questionId}_question_draggable exercise-draggable-answer-option"]); $selectedValue = 0; $draggableSelectOptions = []; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; } $draggableSelectOptions[$val['id']] = $val['letter']; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $draggableSelectOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'select_option', 'style' => 'display: none;'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { $s .= <<<JAVASCRIPT <script> \$(function() { DraggableAnswer.deleteItem( \$('#{$questionId}_{$selectedValue}'), \$('#drop_{$windowId}') ); }); </script> JAVASCRIPT; } if (isset($select_items[$lines_count])) { $s .= Display::div(Display::tag('b', $select_items[$lines_count]['letter']) . $select_items[$lines_count]['answer'], ['id' => "window_{$windowId}_answer", 'style' => 'display: none;']); } else { $s .= ' '; } $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= Display::tag('b', $select_items[$lines_count]['letter']); $s .= $select_items[$lines_count]['answer']; $lines_count++; } } $matching_correct_answer++; $s .= '</li>'; } } elseif ($answerType == MATCHING_DRAGGABLE) { if ($answerId == 1) { echo $objAnswerTmp->getJs(); } if ($answerCorrect != 0) { $parsed_answer = $answer; $windowId = "{$questionId}_{$lines_count}"; $s .= <<<HTML <tr> <td widht="45%"> <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question"> <strong>{$lines_count}.</strong> {$parsed_answer} </div> </td> <td width="10%"> HTML; $selectedValue = 0; $questionOptions = []; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; } $questionOptions[$val['id']] = $val['letter']; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $questionOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'hidden'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { // Show connect if is not freeze (question preview) if (!$freeze) { $s .= <<<JAVASCRIPT <script> jsPlumb.ready(function() { jsPlumb.connect({ source: 'window_{$windowId}', target: 'window_{$questionId}_{$selectedValue}_answer', endpoint: ['Blank', {radius: 15}], anchors: ['RightMiddle', 'LeftMiddle'], paintStyle: {strokeStyle: '#8A8888', lineWidth: 8}, connector: [ MatchingDraggable.connectorType, {curvines: MatchingDraggable.curviness} ] }); }); </script> JAVASCRIPT; } } $s .= <<<HTML </td> <td width="45%"> HTML; if (isset($select_items[$lines_count])) { $s .= <<<HTML <div id="window_{$windowId}_answer" class="window window_right_question"> <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']} </div> HTML; } else { $s .= ' '; } $s .= '</td></tr>'; $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= <<<HTML <tr> <td colspan="2"></td> <td> <strong>{$select_items[$lines_count]['letter']}</strong> {$select_items[$lines_count]['answer']} </td> </tr> HTML; $lines_count++; } } $matching_correct_answer++; } } } // end for() if ($show_comment) { $s .= '</table>'; } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE])) { $s .= '</table>'; } if ($answerType == DRAGGABLE) { $s .= "</ul></div>"; $counterAnswer = 1; $s .= '<div class="col-md-12"><div class="row">'; for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $windowId = $questionId . '_' . $counterAnswer; if ($answerCorrect) { $s .= Display::div($counterAnswer, ['id' => "drop_{$windowId}", 'class' => 'droppable col-md-2']); $counterAnswer++; } } $s .= '</div></div>'; } if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { $s .= '</div>'; } $s .= '</div>'; // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); if ($origin != 'export') { echo $s; } else { return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { echo Display::img($objQuestionTmp->selectPicturePath()); return; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); // get answers of hotpost $answers_hotspot = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId); } // display answers of hotpost order by id $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>'; if (!empty($answers_hotspot)) { ksort($answers_hotspot); foreach ($answers_hotspot as $key => $value) { $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />'; } } $answer_list .= '</dl></div>'; if ($answerType == HOT_SPOT_DELINEATION) { $answer_list = ''; $swf_file = 'hotspot_delineation_user'; $swf_height = 405; } else { $swf_file = 'hotspot_user'; $swf_height = 436; } if (!$only_questions) { if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; } //@todo I need to the get the feedback type echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />'; echo '<table class="exercise_questions" > <tr> <td valign="top" colspan="2">'; echo $questionDescription; echo '</td></tr>'; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script> <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script> <script type="text/javascript"> <!-- // Globals // Major version of Flash required var requiredMajorVersion = 7; // Minor version of Flash required var requiredMinorVersion = 0; // Minor version of Flash required var requiredRevision = 0; // the version of javascript supported var jsVersion = 1.0; // --> </script> <script language="VBScript" type="text/vbscript"> <!-- // Visual basic helper required to detect Flash Player ActiveX control version information Function VBGetSwfVer(i) on error resume next Dim swControl, swVersion swVersion = 0 set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i)) if (IsObject(swControl)) then swVersion = swControl.GetVariable("$version") end if VBGetSwfVer = swVersion End Function // --> </script> <script language="JavaScript1.1" type="text/javascript"> <!-- // Detect Client Browser type var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; jsVersion = 1.1; // JavaScript helper required to detect Flash Player PlugIn version information function JSGetSwfVer(i) { // NS/Opera version >= 3 check for Flash plugin in plugin array if (navigator.plugins != null && navigator.plugins.length > 0) { if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; descArray = flashDescription.split(" "); tempArrayMajor = descArray[2].split("."); versionMajor = tempArrayMajor[0]; versionMinor = tempArrayMajor[1]; if ( descArray[3] != "" ) { tempArrayMinor = descArray[3].split("r"); } else { tempArrayMinor = descArray[4].split("r"); } versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; flashVer = versionMajor + "." + versionMinor + "." + versionRevision; } else { flashVer = -1; } } // MSN/WebTV 2.6 supports Flash 4 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; // WebTV 2.5 supports Flash 3 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; // older WebTV supports Flash 2 else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; // Can\'t detect in all other cases else { flashVer = -1; } return flashVer; } // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) { reqVer = parseFloat(reqMajorVer + "." + reqRevision); // loop backwards through the versions until we find the newest version for (i=25;i>0;i--) { if (isIE && isWin && !isOpera) { versionStr = VBGetSwfVer(i); } else { versionStr = JSGetSwfVer(i); } if (versionStr == -1 ) { return false; } else if (versionStr != 0) { if(isIE && isWin && !isOpera) { tempArray = versionStr.split(" "); tempString = tempArray[1]; versionArray = tempString .split(","); } else { versionArray = versionStr.split("."); } versionMajor = versionArray[0]; versionMinor = versionArray[1]; versionRevision = versionArray[2]; versionString = versionMajor + "." + versionRevision; // 7.0r24 == 7.24 versionNum = parseFloat(versionString); // is the major.revision >= requested major.revision AND the minor version >= requested minor if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) { return true; } else { return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false ); } } } } // --> </script>'; $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520"> <script> <!-- // Version check based upon the values entered above in "Globals" var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision); // Check to see if the version meets the requirements for playback if (hasReqestedVersion) { // if we\'ve detected an acceptable version var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\' + \'<param name="wmode" value="transparent">\' + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\' + \'<\\/object>\'; document.write(oeTags); // embed the Flash Content SWF when all tests are passed } else { // flash is too old or we can\'t detect the plugin var alternateContent = "Error<br \\/>" + "Hotspots requires Macromedia Flash 7.<br \\/>" + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>"; document.write(alternateContent); // insert non-flash content } // --> </script> </td> <td valign="top" align="left">' . $answer_list . '</td></tr> </table> </td></tr>'; echo $s; echo '</table>'; } return $nbrAnswers; }
} $label_attributes = array(); $label_attributes['class'] = 'checkbox'; $label_attributes['for'] = $check_id; $label_attributes['class'] = "checkbox"; $checkbox = Display::input('checkbox', 'remind_list[' . $questionId . ']', '', $attributes); $url = 'exercise_submit.php?exerciseId=' . $objExercise->id . '&num=' . $counter . '&reminder=1'; $counter++; if ($objExercise->type == ONE_PER_PAGE) { $question_title = Display::url($counter . '. ' . cut($objQuestionTmp->selectTitle(), 40), $url); $question_title = $counter . '. ' . cut($objQuestionTmp->selectTitle(), 40); } else { $question_title = $counter . '. ' . cut($objQuestionTmp->selectTitle(), 40); } //Check if the question doesn't have an answer if (!in_array($questionId, $exercise_result)) { $question_title = Display::label($question_title, 'warning'); } $question_title = Display::tag('label', $checkbox . $question_title, $label_attributes); $table .= Display::div($question_title, array('class' => 'exercise_reminder_item')); } // end foreach() block that loops over all questions echo Display::div($table, array('class' => 'span10')); $exercise_actions = Display::url(get_lang('EndTest'), 'javascript://', array('onclick' => 'final_submit();', 'class' => 'btn btn-warning')); $exercise_actions .= ' ' . Display::url(get_lang('ReviewQuestions'), 'javascript://', array('onclick' => 'review_questions();', 'class' => 'btn btn-success')); echo Display::div('', array('class' => 'clear')); echo Display::div($exercise_actions, array('class' => 'form-actions')); if ($origin != 'learnpath') { // We are not in learnpath tool Display::display_footer(); }
/** * Shows a question * * @param int $questionId question id * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param bool $exercise_feedback * @param bool $show_answers * */ public static function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) { $course_id = api_get_course_int_id(); // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; // Reads question information if (!($objQuestionTmp = Question::read($questionId))) { // Question not found return false; } if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); } if (!empty($questionDescription)) { echo Display::div($questionDescription, array('class' => 'question_description')); } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return ''; } echo '<div class="question_options row">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) { if ($answerType == DRAGGABLE) { $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix"> <div class="clearfix"> <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">'; } else { $s .= '<div id="drag' . $questionId . '_question" class="drag_question"> <table class="data_table">'; } // Iterate through answers $x = 1; //mark letters for each answer $letter = 'A'; $answer_matching = array(); $cpt1 = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $cpt1[$x] = $letter; $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer); $x++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id_auto']; $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $user_choice_array_position = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array_position[$item['position']] = $item['answer']; } } $num_suggestions = $nbrAnswers - $x + 1; } elseif ($answerType == FREE_ANSWER) { $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); $form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->returnForm(); } elseif ($answerType == ORAL_EXPRESSION) { // Add nanog if (api_get_setting('document.enable_nanogong') == 'true') { //@todo pass this as a parameter global $exercise_stat_info, $exerciseId, $exe_id; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); echo $nano->show_button(); } $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); //$form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->returnForm(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { if (in_array($item, $objQuestionTmp->options)) { $header .= Display::tag('th', get_lang($item)); } else { $header .= Display::tag('th', $item); } } else { $header .= Display::tag('th', $item); } } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $comment = $objAnswerTmp->selectComment($answerId); $attributes = array(); // Unique answer if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($show_comment) { $s .= '<tr><td>'; } if ($answerType == UNIQUE_ANSWER_IMAGE) { if ($show_comment) { if (empty($comment)) { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image" style="text-align: center">'; } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-sm-12" style="text-align: center">'; } } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-md-3" style="text-align: center">'; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = null; if ($answerType == UNIQUE_ANSWER_IMAGE) { $attributes['style'] = 'display: none;'; $answer = '<div class="thumbnail">' . $answer . '</div>'; } $answer_input .= '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($answerType == UNIQUE_ANSWER_IMAGE) { $answer_input .= "</div>"; } if ($show_comment) { $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer, STUDENT); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); if (isset($item[1]) && isset($item[0])) { $my_choice[$item[0]] = $item[1]; } } } $answer = Security::remove_XSS($answer, STUDENT); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { // display the question, with field empty, for student to fill it, // or filled to display the answer in the Question preview of the exercice/admin.php page $displayForStudent = true; $listAnswerInformations = FillBlanks::getAnswerInfo($answer); $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); list($answer) = explode('::', $answer); //Correct answers $correctAnswerList = $listAnswerInformations['tabwords']; //Student's answer $studentAnswerList = array(); if (isset($user_choice[0]['answer'])) { $arrayStudentAnswer = FillBlanks::getAnswerInfo($user_choice[0]['answer'], true); $studentAnswerList = $arrayStudentAnswer['studentanswer']; } // If the question must be shown with the answer (in page exercice/admin.php) for teacher preview // set the student-answer to the correct answer if ($debug_mark_answer) { $studentAnswerList = $correctAnswerList; $displayForStudent = false; } if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common word $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); if (isset($studentAnswerList[$i])) { // If student already started this test and answered this question, // fill the blank with his previous answers // may be "" if student viewed the question, but did not fill the blanks $correctItem = $studentAnswerList[$i]; } $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, $correctItem, $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } else { // display empty [input] with the right width for student to fill it $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common words $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, '', $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } $s .= $answer; } elseif ($answerType == CALCULATED_ANSWER) { /* * In the CALCULATED_ANSWER test * you mustn't have [ and ] in the textarea * you mustn't have @@ in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ if ($origin !== null) { global $exe_id; $trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $sql = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId; $rsLastAttempt = Database::query($sql); $rowLastAttempt = Database::fetch_array($rsLastAttempt); $answer = $rowLastAttempt['answer']; if (empty($answer)) { $calculatedAnswerId = []; $calculatedAnswerId[$questionId] = mt_rand(1, $nbrAnswers); $answer = $objAnswerTmp->selectAnswer($calculatedAnswerId[$questionId]); Session::write('calculatedAnswerId', $calculatedAnswerId); } } list($answer) = explode('@@', $answer); // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList); // get student answer to display it if student go back to previous calculated answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $answer, $studentAnswerList); $studentAnswerListTobecleaned = $studentAnswerList[0]; $studentAnswerList = array(); for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) { $answerCorrected = $studentAnswerListTobecleaned[$i]; $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected); $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected); $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected); $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected); $answerCorrected = '[' . $answerCorrected . ']'; $studentAnswerList[] = $answerCorrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $studentAnswerList = $correctAnswerList[0]; } /* Split the response by bracket tabComments is an array with text surrounding the text to find we add a space before and after the answerQuestion to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2); $size = strlen($studentItem); $attributes['class'] = self::detectInputAppropriateClass($size); $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes); $i++; } $answer .= $tabComments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correctAnswerList[0] as $item) { $size = strlen($item); $attributes['class'] = self::detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } } if ($origin !== null) { $s = $answer; break; } else { $s .= $answer; } } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) $s .= '<tr><td width="45%" valign="top">'; $parsed_answer = $answer; //left part questions $s .= '<p class="indent">' . $lines_count . '. ' . $parsed_answer . '</p></td>'; //middle part (matches selects) $s .= '<td width="10%" valign="top" align="center" > <div class="select-matching"> <select name="choice[' . $questionId . '][' . $numAnswer . ']">'; // fills the list-box foreach ($select_items as $key => $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; } } //$user_choice_array_position if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) { $selected = 'selected="selected"'; } $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>'; } // end foreach() $s .= '</select></div></td><td width="5%" class="separate"> </td>'; $s .= '<td width="40%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<div class="text-right"><p class="indent">' . $select_items[$lines_count]['letter'] . '. ' . $select_items[$lines_count]['answer'] . '</p></div>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer']; $s .= "</td>\n </tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } elseif ($answerType == DRAGGABLE) { if ($answerCorrect != 0) { $parsed_answer = $answer; /*$lines_count = ''; $data = $objAnswerTmp->getAnswerByAutoId($numAnswer); $data = $objAnswerTmp->getAnswerByAutoId($data['correct']); $lines_count = $data['answer'];*/ $windowId = $questionId . '_' . $lines_count; $s .= '<li class="touch-items" id="' . $windowId . '">'; $s .= Display::div($parsed_answer, ['id' => "window_{$windowId}", 'class' => "window{$questionId}_question_draggable exercise-draggable-answer-option"]); $selectedValue = 0; $draggableSelectOptions = []; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; } $draggableSelectOptions[$val['id']] = $val['letter']; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $draggableSelectOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'select_option', 'style' => 'display: none;'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { $s .= <<<JAVASCRIPT <script> \$(function() { DraggableAnswer.deleteItem( \$('#{$questionId}_{$selectedValue}'), \$('#drop_{$windowId}') ); }); </script> JAVASCRIPT; } if (isset($select_items[$lines_count])) { $s .= Display::div(Display::tag('b', $select_items[$lines_count]['letter']) . $select_items[$lines_count]['answer'], ['id' => "window_{$windowId}_answer", 'style' => 'display: none;']); } else { $s .= ' '; } $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= Display::tag('b', $select_items[$lines_count]['letter']); $s .= $select_items[$lines_count]['answer']; $lines_count++; } } $matching_correct_answer++; $s .= '</li>'; } } elseif ($answerType == MATCHING_DRAGGABLE) { if ($answerId == 1) { echo $objAnswerTmp->getJs(); } if ($answerCorrect != 0) { $parsed_answer = $answer; $windowId = "{$questionId}_{$lines_count}"; $s .= <<<HTML <tr> <td widht="45%"> <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question"> <strong>{$lines_count}.</strong> {$parsed_answer} </div> </td> <td width="10%"> HTML; $selectedValue = 0; $selectedPosition = 0; $questionOptions = []; $iTempt = 0; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; $selectedPosition = $iTempt; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; $selectedPosition = $iTempt; } $questionOptions[$val['id']] = $val['letter']; $iTempt++; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $questionOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'hidden'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { // Show connect if is not freeze (question preview) if (!$freeze) { $s .= <<<JAVASCRIPT <script> \$(document).on('ready', function () { jsPlumb.ready(function() { jsPlumb.connect({ source: 'window_{$windowId}', target: 'window_{$questionId}_{$selectedPosition}_answer', endpoint: ['Blank', {radius: 15}], anchors: ['RightMiddle', 'LeftMiddle'], paintStyle: {strokeStyle: '#8A8888', lineWidth: 8}, connector: [ MatchingDraggable.connectorType, {curvines: MatchingDraggable.curviness} ] }); }); }); </script> JAVASCRIPT; } } $s .= <<<HTML </td> <td width="45%"> HTML; if (isset($select_items[$lines_count])) { $s .= <<<HTML <div id="window_{$windowId}_answer" class="window window_right_question"> <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']} </div> HTML; } else { $s .= ' '; } $s .= '</td></tr>'; $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= <<<HTML <tr> <td colspan="2"></td> <td> <strong>{$select_items[$lines_count]['letter']}</strong> {$select_items[$lines_count]['answer']} </td> </tr> HTML; $lines_count++; } } $matching_correct_answer++; } } } // end for() if ($show_comment) { $s .= '</table>'; } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE])) { $s .= '</table>'; } if ($answerType == DRAGGABLE) { $s .= "</ul>"; $s .= "</div>"; //clearfix $counterAnswer = 1; $s .= '<div class="col-md-12"><div class="row">'; for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $windowId = $questionId . '_' . $counterAnswer; if ($answerCorrect) { $s .= Display::div($counterAnswer, ['id' => "drop_{$windowId}", 'class' => 'droppable col-md-2']); $counterAnswer++; } } $s .= '</div>'; // row $s .= '</div>'; // col-md-12 $s .= '</div>'; // col-md-12 ui-widget ui-helper-clearfix } if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { $s .= '</div>'; //drag_question } $s .= '</div>'; //question_options row // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); if ($origin != 'export') { echo $s; } else { return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { global $exerciseId, $exe_id; // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { echo "\n <script>\n \$(document).on('ready', function () {\n new " . ($answerType == HOT_SPOT ? "HotspotQuestion" : "DelineationQuestion") . "({\n questionId: {$questionId},\n exerciseId: {$exerciseId},\n selector: '#hotspot-preview-{$questionId}',\n for: 'preview'\n });\n });\n </script>\n <div id=\"hotspot-preview-{$questionId}\"></div>\n "; return; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); // get answers of hotpost $answers_hotspot = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId); } $answerList = ''; if ($answerType != HOT_SPOT_DELINEATION) { $answerList = ' <div class="well well-sm"> <h5 class="page-header">' . get_lang('HotspotZones') . '</h5> <ol> '; if (!empty($answers_hotspot)) { ksort($answers_hotspot); $countAnswers = 1; foreach ($answers_hotspot as $value) { $answerList .= "<li><p>{$countAnswers} - {$value}</p></li>"; $countAnswers++; } } $answerList .= ' </ol> </div> '; } if (!$only_questions) { if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; } //@todo I need to the get the feedback type echo <<<HOTSPOT <input type="hidden" name="hidden_hotspot_id" value="{$questionId}" /> <div class="exercise_questions"> {$questionDescription} <div class="row"> HOTSPOT; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= "\n <div class=\"col-sm-8 col-md-9\">\n <div class=\"hotspot-image\"></div>\n <script>\n \$(document).on('ready', function () {\n new " . ($answerType == HOT_SPOT_DELINEATION ? 'DelineationQuestion' : 'HotspotQuestion') . "({\n questionId: {$questionId},\n exerciseId: {$exe_id},\n selector: '#question_div_' + {$questionId} + ' .hotspot-image',\n for: 'user'\n });\n });\n </script>\n </div>\n <div class=\"col-sm-4 col-md-3\">\n {$answerList}\n </div>\n "; echo <<<HOTSPOT {$s} </div> </div> HOTSPOT; } return $nbrAnswers; }
/** * Returns an HTML block with the notice, as found in the * home/home_notice_[lang].html file * @return string HTML <div> block * @assert () != '' */ public function returnNotice() { $sys_path = api_get_path(SYS_PATH); $user_selected_language = api_get_interface_language(); $home = api_get_home_path(); // Notice $home_notice = @(string) file_get_contents($sys_path . $home . 'home_notice_' . $user_selected_language . '.html'); if (empty($home_notice)) { $home_notice = @(string) file_get_contents($sys_path . $home . 'home_notice.html'); } if (!empty($home_notice)) { $home_notice = api_to_system_encoding($home_notice, api_detect_encoding(strip_tags($home_notice))); $home_notice = Display::div($home_notice, array('class' => 'homepage_notice')); $this->show_right_block(get_lang('Notice'), null, 'notice_block', array('content' => $home_notice)); } }
/** * @param array $course_info * @param bool $lp_id * @param string $target * @param int $session_id * @param bool $add_move_button * @param string $filter_by_folder * @param string $overwrite_url * @param bool $showInvisibleFiles * @param bool $showOnlyFolders * @param int $folderId * @return string */ public static function get_document_preview($course_info, $lp_id = false, $target = '', $session_id = 0, $add_move_button = false, $filter_by_folder = null, $overwrite_url = null, $showInvisibleFiles = false, $showOnlyFolders = false, $folderId = false) { if (empty($course_info['real_id']) || empty($course_info['code']) || !is_array($course_info)) { return ''; } $overwrite_url = Security::remove_XSS($overwrite_url); $user_id = api_get_user_id(); $user_in_course = false; if (api_is_platform_admin()) { $user_in_course = true; } if (!$user_in_course) { if (CourseManager::is_course_teacher($user_id, $course_info['code'])) { $user_in_course = true; } } // Condition for the session $session_id = intval($session_id); if (!$user_in_course) { if (empty($session_id)) { if (CourseManager::is_user_subscribed_in_course($user_id, $course_info['code'])) { $user_in_course = true; } // Check if course is open then we can consider that the student is registered to the course if (isset($course_info) && in_array($course_info['visibility'], array(2, 3))) { $user_in_course = true; } } else { $user_status = SessionManager::get_user_status_in_course_session($user_id, $course_info['real_id'], $session_id); //is true if is an student, course session teacher or coach if (in_array($user_status, array('0', '2', '6'))) { $user_in_course = true; } } } $tbl_doc = Database::get_course_table(TABLE_DOCUMENT); $tbl_item_prop = Database::get_course_table(TABLE_ITEM_PROPERTY); $condition_session = " AND (last.session_id = '{$session_id}' OR last.session_id = '0' OR last.session_id IS NULL)"; $add_folder_filter = null; if (!empty($filter_by_folder)) { $add_folder_filter = " AND docs.path LIKE '" . Database::escape_string($filter_by_folder) . "%'"; } // If we are in LP display hidden folder https://support.chamilo.org/issues/6679 $lp_visibility_condition = null; if ($lp_id) { // $lp_visibility_condition = " OR filetype='folder'"; if ($showInvisibleFiles) { $lp_visibility_condition .= ' OR last.visibility = 0'; } } $showOnlyFoldersCondition = null; if ($showOnlyFolders) { //$showOnlyFoldersCondition = " AND docs.filetype = 'folder' "; } $folderCondition = " AND docs.path LIKE '/%' "; if (!api_is_allowed_to_edit()) { $protectedFolders = self::getProtectedFolderFromStudent(); foreach ($protectedFolders as $folder) { $folderCondition .= " AND docs.path NOT LIKE '{$folder}' "; } } $parentData = []; if ($folderId !== false) { $parentData = self::get_document_data_by_id($folderId, $course_info['code']); if (!empty($parentData)) { $cleanedPath = $parentData['path']; $num = substr_count($cleanedPath, '/'); $notLikeCondition = null; for ($i = 1; $i <= $num; $i++) { $repeat = str_repeat('/%', $i + 1); $notLikeCondition .= " AND docs.path NOT LIKE '" . Database::escape_string($cleanedPath . $repeat) . "' "; } $folderCondition = " AND\n docs.id <> {$folderId} AND\n docs.path LIKE '" . $cleanedPath . "/%'\n {$notLikeCondition}\n "; } else { $folderCondition = " AND\n docs.filetype = 'file' "; } } $levelCondition = null; if ($folderId === false) { $levelCondition = " AND docs.path NOT LIKE'/%/%'"; } $sql = "SELECT last.visibility, docs.*\n FROM {$tbl_item_prop} AS last INNER JOIN {$tbl_doc} AS docs\n ON (docs.id = last.ref AND docs.c_id = last.c_id)\n WHERE\n docs.path NOT LIKE '%_DELETED_%' AND\n last.tool = '" . TOOL_DOCUMENT . "' {$condition_session} AND\n (last.visibility = '1' {$lp_visibility_condition}) AND\n last.visibility <> 2 AND\n docs.c_id = {$course_info['real_id']} AND\n last.c_id = {$course_info['real_id']}\n {$showOnlyFoldersCondition}\n {$folderCondition}\n {$levelCondition}\n {$add_folder_filter}\n ORDER BY docs.filetype DESC, docs.title ASC"; $res_doc = Database::query($sql); $resources = Database::store_result($res_doc, 'ASSOC'); $return = ''; if ($lp_id) { $learnPath = learnpath::getCurrentLpFromSession(); if ($folderId === false) { $return .= '<div class="lp_resource_element">'; $return .= Display::return_icon('new_doc.gif', '', array(), ICON_SIZE_SMALL); $return .= Display::url(get_lang('NewDocument'), api_get_self() . '?' . api_get_cidreq() . '&action=add_item&type=' . TOOL_DOCUMENT . '&lp_id=' . $learnPath->lp_id); $return .= '</div>'; } } else { $return .= Display::div(Display::url(Display::return_icon('close.png', get_lang('Close'), array(), ICON_SIZE_SMALL), ' javascript:void(0);', array('id' => 'close_div_' . $course_info['real_id'] . '_' . $session_id, 'class' => 'close_div')), array('style' => 'position:absolute;right:10px')); } // If you want to debug it, I advise you to do "echo" on the eval statements. $newResources = array(); if (!empty($resources) && $user_in_course) { foreach ($resources as $resource) { $is_visible = self::is_visible_by_id($resource['id'], $course_info, $session_id, api_get_user_id()); if (!$is_visible) { continue; } $newResources[] = $resource; } } $label = get_lang('Documents'); $documents = []; if ($folderId === false) { $documents[$label] = array('id' => 0, 'files' => $newResources); } else { if (!empty($parentData)) { $documents[$parentData['title']] = array('id' => intval($folderId), 'files' => $newResources); } } $write_result = self::write_resources_tree($course_info, $session_id, $documents, $lp_id, $target, $add_move_button, $overwrite_url, $folderId); $return .= $write_result; $img_path = api_get_path(WEB_IMG_PATH); if ($lp_id == false) { $url = api_get_path(WEB_AJAX_PATH) . 'lp.ajax.php?a=get_documents&url=' . $overwrite_url . '&lp_id=' . $lp_id . '&cidReq=' . $course_info['code']; $return .= "<script>\n \$('.doc_folder').click(function() {\n var realId = this.id;\n var my_id = this.id.split('_')[2];\n var tempId = 'temp_'+my_id;\n \$('#res_'+my_id).show();\n\n var tempDiv = \$('#'+realId).find('#'+tempId);\n if (tempDiv.length == 0) {\n \$.ajax({\n async: false,\n type: 'GET',\n url: '" . $url . "',\n data: 'folder_id='+my_id,\n success: function(data) {\n \$('#'+realId).append('<div id='+tempId+'>'+data+'</div>');\n }\n });\n }\n });\n\n \$('.close_div').click(function() {\n var course_id = this.id.split('_')[2];\n var session_id = this.id.split('_')[3];\n \$('#document_result_'+course_id+'_'+session_id).hide();\n \$('.lp_resource').remove();\n \$('.document_preview_container').html('');\n });\n\n </script>"; } else { //For LPs $url = api_get_path(WEB_AJAX_PATH) . 'lp.ajax.php?a=get_documents&lp_id=' . $lp_id . '&' . api_get_cidreq(); $return .= "<script>\n\n function testResources(id, img) {\n var numericId = id.split('_')[1];\n var parentId = 'doc_id_'+numericId;\n var tempId = 'temp_'+numericId;\n var image = \$('#'+img);\n\n if (image.hasClass('open')) {\n image.removeClass('open');\n image.attr('src', '" . $img_path . "nolines_plus.gif');\n \$('#'+id).show();\n \$('#'+tempId).hide();\n } else {\n image.addClass('open');\n image.attr('src', '" . $img_path . "nolines_minus.gif');\n \$('#'+id).hide();\n \$('#'+tempId).show();\n\n var tempDiv = \$('#'+parentId).find('#'+tempId);\n if (tempDiv.length == 0) {\n \$.ajax({\n type: 'GET',\n async: false,\n url: '" . $url . "',\n data: 'folder_id='+numericId,\n success: function(data) {\n tempDiv = \$('#doc_id_'+numericId).append('<div id='+tempId+'>'+data+'</div>');\n }\n });\n }\n }\n }\n </script>"; } if (!$user_in_course) { $return = ''; } return $return; }
/** * Displays the header for the gradebook containing the navigation tree and links * @param Category $catobj * @param int $showtree '1' will show the browse tree and naviation buttons * @param boolean $is_course_admin * @param boolean $is_platform_admin * @param boolean Whether to show or not the link to add a new qualification * (we hide it in case of the course-embedded tool where we have only one * calification per course or session) * @param boolean Whether to show or not the link to add a new item inside * the qualification (we hide it in case of the course-embedded tool * where we have only one calification per course or session) * @return void Everything is printed on screen upon closing */ static function display_header_gradebook($catobj, $showtree, $selectcat, $is_course_admin, $is_platform_admin, $simple_search_form, $show_add_qualification = true, $show_add_link = true, $certificateLinkInfo = null) { // Student. $status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id()); $objcat = new Category(); $course_id = Database::get_course_by_category($selectcat); $message_resource = $objcat->show_message_resource_delete($course_id); $grade_model_id = $catobj->get_grade_model_id(); $header = null; //@todo move these in a function $sum_categories_weight_array = array(); if (isset($catobj) && !empty($catobj)) { $categories = Category::load(null, null, null, $catobj->get_id()); if (!empty($categories)) { foreach ($categories as $category) { $sum_categories_weight_array[$category->get_id()] = $category->get_weight(); } } else { $sum_categories_weight_array[$catobj->get_id()] = $catobj->get_weight(); } } if (!$is_course_admin && $status != 1 && $selectcat != 0) { $user_id = api_get_user_id(); $catcourse = Category::load($catobj->get_id()); $main_weight = $catcourse[0]->get_weight(); $scoredisplay = ScoreDisplay::instance(); //$categories = Category::getCategories($catcourse[0]->get_id()); // generating the total score for a course /*if (count($categories) > 0) { foreach ($categories as $category) { $allevals = $category->get_evaluations($user_id, true); $alllinks = $category->get_links($user_id, true); $catEvalsLinks = array_merge($allevals, $alllinks); } }*/ $allevals = $catcourse[0]->get_evaluations($user_id, true); $alllinks = $catcourse[0]->get_links($user_id, true); $allEvalsLinks = array_merge($allevals, $alllinks); $item_value_total = 0; $scoreinfo = null; for ($count = 0; $count < count($allEvalsLinks); $count++) { $item = $allEvalsLinks[$count]; $score = $item->calc_score($user_id); if (!empty($score)) { $divide = $score[1] == 0 ? 1 : $score[1]; //$sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()]; //$item_value = $score[0] / $divide * $item->get_weight() / $sub_cat_percentage * $sub_cat_percentage / $main_weight * $main_weight; $item_value = $score[0] / $divide * $item->get_weight(); //var_dump($score[0], $divide, $item->get_weight(), $sub_cat_percentage, $main_weight, $item_value); $item_value_total += $item_value; } } $item_total = $main_weight; $total_score = array($item_value_total, $item_total); $scorecourse_display = $scoredisplay->display_score($total_score, SCORE_DIV_PERCENT); if (!$catobj->get_id() == '0' && !isset($_GET['studentoverview']) && !isset($_GET['search'])) { $certificateLink = null; if (!empty($certificateLinkInfo) && isset($certificateLinkInfo['certificate_link'])) { $certificateLink .= '<span style="float:right"> ' . $certificateLinkInfo['certificate_link'] . "</span>"; } $scoreinfo .= '<h4>' . get_lang('Total') . ' : ' . $scorecourse_display . $certificateLink . '</h4>'; } Display::display_normal_message($scoreinfo, false); } // show navigation tree and buttons? if ($showtree == '1' || isset($_GET['studentoverview'])) { $header = '<div class="actions"><table>'; $header .= '<tr>'; if (!$selectcat == '0') { $header .= '<td><a href="' . api_get_self() . '?selectcat=' . $catobj->get_parent_id() . '">' . Display::return_icon('back.png', get_lang('BackTo') . ' ' . get_lang('RootCat'), '', ICON_SIZE_MEDIUM) . '</a></td>'; } $header .= '<td>' . get_lang('CurrentCategory') . '</td>' . '<td><form name="selector"><select name="selectcat" onchange="document.selector.submit()">'; $cats = Category::load(); $tree = $cats[0]->get_tree(); unset($cats); $line = null; foreach ($tree as $cat) { for ($i = 0; $i < $cat[2]; $i++) { $line .= '—'; } $line = isset($line) ? $line : ''; if (isset($_GET['selectcat']) && $_GET['selectcat'] == $cat[0]) { $header .= '<option selected value=' . $cat[0] . '>' . $line . ' ' . $cat[1] . '</option>'; } else { $header .= '<option value=' . $cat[0] . '>' . $line . ' ' . $cat[1] . '</option>'; } $line = ''; } $header .= '</select></form></td>'; if (!empty($simple_search_form) && $message_resource === false) { $header .= '<td style="vertical-align: top;">' . $simple_search_form->toHtml() . '</td>'; } else { $header .= '<td></td>'; } if ($is_course_admin && $message_resource === false && $_GET['selectcat'] != 0) { /* $header .= '<td style="vertical-align: top;"><a href="gradebook_flatview.php?'.api_get_cidreq().'&selectcat=' . $catobj->get_id() . '"><img src="../img/view_list.gif" alt="' . get_lang('FlatView') . '" /> ' . get_lang('FlatView') . '</a>'; if ($is_course_admin && $message_resource===false) { $header .= '<td style="vertical-align: top;"><a href="gradebook_scoring_system.php?'.api_get_cidreq().'&selectcat=' . $catobj->get_id() .'"><img src="../img/acces_tool.gif" alt="' . get_lang('ScoreEdit') . '" /> ' . get_lang('ScoreEdit') . '</a>'; } */ } elseif (!isset($_GET['studentoverview'])) { if ($message_resource === false) { //$header .= '<td style="vertical-align: top;"><a href="'.api_get_self().'?'.api_get_cidreq().'&studentoverview=&selectcat=' . $catobj->get_id() . '"><img src="../img/view_list.gif" alt="' . get_lang('FlatView') . '" /> ' . get_lang('FlatView') . '</a>'; } } else { $header .= '<td style="vertical-align: top;"><a href="' . api_get_self() . '?' . api_get_cidreq() . '&studentoverview=&exportpdf=&selectcat=' . $catobj->get_id() . '" target="_blank"> <img src="../img/icons/32/pdf.png" alt="' . get_lang('ExportPDF') . '" /> ' . get_lang('ExportPDF') . '</a>'; } $header .= '</td></tr>'; $header .= '</table></div>'; } // for course admin & platform admin add item buttons are added to the header $header .= '<div class="actions">'; $my_category = $catobj->shows_all_information_an_category($catobj->get_id()); $user_id = api_get_user_id(); $my_api_cidreq = api_get_cidreq(); //$course_code = $my_category['course_code']; //$status_user = api_get_status_of_user_in_course ($user_id,$course_code); if (api_is_allowed_to_edit(null, true)) { if (empty($grade_model_id) || $grade_model_id == -1) { $header .= '<a href="gradebook_add_cat.php?' . api_get_cidreq() . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('new_folder.png', get_lang('AddGradebook'), array(), ICON_SIZE_MEDIUM) . '</a></td>'; } if ($selectcat == '0') { } else { $my_category = $catobj->shows_all_information_an_category($catobj->get_id()); if ($my_api_cidreq == '') { $my_api_cidreq = 'cidReq=' . $my_category['course_code']; } if ($show_add_link && !$message_resource) { $header .= '<td><a href="gradebook_add_eval.php?' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '" >' . Display::return_icon('new_evaluation.png', get_lang('NewEvaluation'), '', ICON_SIZE_MEDIUM) . '</a>'; $cats = Category::load($selectcat); if ($cats[0]->get_course_code() != null && !$message_resource) { $header .= '<td><a href="gradebook_add_link.php?' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('new_online_evaluation.png', get_lang('MakeLink'), '', ICON_SIZE_MEDIUM) . '</a>'; } else { $header .= '<td><a href="gradebook_add_link_select_course.php?' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('new_online_evaluation.png', get_lang('MakeLink'), '', ICON_SIZE_MEDIUM) . '</a>'; } } if (!$message_resource) { $header .= '<td style="vertical-align: top;"><a href="gradebook_flatview.php?' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('stats.png', get_lang('FlatView'), '', ICON_SIZE_MEDIUM) . '</a>'; $header .= '<td style="vertical-align: top;"><a href="gradebook_display_certificate.php?' . $my_api_cidreq . '&cat_id=' . (int) $_GET['selectcat'] . '">' . Display::return_icon('certificate_list.png', get_lang('GradebookSeeListOfStudentsCertificates'), '', ICON_SIZE_MEDIUM) . '</a>'; // Right icons $modify_icons = '<a href="gradebook_edit_cat.php?editcat=' . $catobj->get_id() . '&cidReq=' . $catobj->get_course_code() . '&id_session=' . $catobj->get_session_id() . '">' . Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_MEDIUM) . '</a>'; $modify_icons .= '<a href="../document/document.php?curdirpath=/certificates&' . $my_api_cidreq . '&origin=gradebook&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('certificate.png', get_lang('AttachCertificate'), '', ICON_SIZE_MEDIUM) . '</a>'; if (empty($categories)) { $modify_icons .= '<a href="gradebook_edit_all.php?id_session=' . api_get_session_id() . '&' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('percentage.png', get_lang('EditAllWeights'), '', ICON_SIZE_MEDIUM) . '</a>'; } $score_display_custom = api_get_setting('gradebook_score_display_custom'); if (api_get_setting('teachers_can_change_score_settings') == 'true' && $score_display_custom['my_display_custom'] == 'true') { $modify_icons .= '<a href="gradebook_scoring_system.php?' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('ranking.png', get_lang('ScoreEdit'), '', ICON_SIZE_MEDIUM) . '</a>'; } $header .= Display::div($modify_icons, array('class' => 'right')); } } } elseif (isset($_GET['search'])) { $header .= '<b>' . get_lang('SearchResults') . ' :</b>'; } $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(api_get_user_id(), api_get_course_info()); if ($isDrhOfCourse) { $header .= '<td style="vertical-align: top;"><a href="gradebook_flatview.php?' . $my_api_cidreq . '&selectcat=' . $catobj->get_id() . '">' . Display::return_icon('stats.png', get_lang('FlatView'), '', ICON_SIZE_MEDIUM) . '</a>'; /*$header .= '<td style="vertical-align: top;"><a href="gradebook_display_certificate.php?' . $my_api_cidreq . '&cat_id=' . (int) $_GET['selectcat'] . '">' . Display::return_icon('certificate_list.png', get_lang('GradebookSeeListOfStudentsCertificates'), '', ICON_SIZE_MEDIUM) . '</a>';*/ } $header .= '</div>'; echo $header; if (api_is_allowed_to_edit(null, true)) { $weight = intval($catobj->get_weight()) > 0 ? $catobj->get_weight() : 0; $weight = get_lang('TotalWeight') . ' : ' . $weight; $min_certification = intval($catobj->get_certificate_min_score() > 0) ? $catobj->get_certificate_min_score() : 0; $min_certification = get_lang('CertificateMinScore') . ' : ' . $min_certification; $edit_icon = '<a class="right_link" href="gradebook_edit_cat.php?editcat=' . $catobj->get_id() . '&cidReq=' . $catobj->get_course_code() . '&id_session=' . $catobj->get_session_id() . '">' . Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL) . '</a>'; //$msg = Display::tag('h3', $weight.' - '.$min_certification); $msg = Display::tag('h4', $weight . ' - ' . $min_certification . $edit_icon); //@todo show description $description = $catobj->get_description() == "" || is_null($catobj->get_description()) ? '' : '<strong>' . get_lang('GradebookDescriptionLog') . '</strong>' . ': ' . $catobj->get_description(); Display::display_normal_message($msg, false); if (!empty($description)) { echo Display::div($description, array()); } } }
/** * Shows the user detail progress (when clicking in the details link) * @param int $user_id * @param string $course_code * @param int $session_id * @return string html code */ public static function show_course_detail($user_id, $course_code, $session_id) { $html = ''; if (isset($course_code)) { $user_id = intval($user_id); $session_id = intval($session_id); $course = Database::escape_string($course_code); $course_info = CourseManager::get_course_information($course); $html .= Display::page_subheader($course_info['title']); $html .= '<table class="data_table" width="100%">'; //Course details $html .= ' <tr> <th class="head" style="color:#000">' . get_lang('Exercises') . '</th> <th class="head" style="color:#000">' . get_lang('Attempts') . '</th> <th class="head" style="color:#000">' . get_lang('BestAttempt') . '</th> <th class="head" style="color:#000">' . get_lang('Ranking') . '</th> <th class="head" style="color:#000">' . get_lang('BestResultInCourse') . '</th> <th class="head" style="color:#000">' . get_lang('Statistics') . ' ' . Display::return_icon('info3.gif', get_lang('OnlyBestResultsPerStudent'), array('align' => 'absmiddle', 'hspace' => '3px')) . '</th> </tr>'; if (empty($session_id)) { $user_list = CourseManager::get_user_list_from_course_code($course, $session_id, null, null, STUDENT); } else { $user_list = CourseManager::get_user_list_from_course_code($course, $session_id, null, null, 0); } // Show exercise results of invisible exercises? see BT#4091 $exercise_list = ExerciseLib::get_all_exercises($course_info, $session_id, false, null, false, 2); $to_graph_exercise_result = array(); if (!empty($exercise_list)) { $score = $weighting = $exe_id = 0; foreach ($exercise_list as $exercices) { $exercise_obj = new Exercise($course_info['real_id']); $exercise_obj->read($exercices['id']); $visible_return = $exercise_obj->is_visible(); $score = $weighting = $attempts = 0; // Getting count of attempts by user $attempts = Event::count_exercise_attempts_by_user(api_get_user_id(), $exercices['id'], $course_info['real_id'], $session_id); $html .= '<tr class="row_even">'; $url = api_get_path(WEB_CODE_PATH) . "exercice/overview.php?cidReq={$course_info['code']}&id_session={$session_id}&exerciseId={$exercices['id']}"; if ($visible_return['value'] == true) { $exercices['title'] = Display::url($exercices['title'], $url, array('target' => SESSION_LINK_TARGET)); } $html .= Display::tag('td', $exercices['title']); // Exercise configuration show results or show only score if ($exercices['results_disabled'] == 0 || $exercices['results_disabled'] == 2) { //For graphics $best_exercise_stats = Event::get_best_exercise_results_by_user($exercices['id'], $course_info['real_id'], $session_id); $to_graph_exercise_result[$exercices['id']] = array('title' => $exercices['title'], 'data' => $best_exercise_stats); $latest_attempt_url = ''; $best_score = $position = $percentage_score_result = '-'; $graph = $normal_graph = null; // Getting best results $best_score_data = ExerciseLib::get_best_attempt_in_course($exercices['id'], $course_info['real_id'], $session_id); $best_score = ''; if (!empty($best_score_data)) { $best_score = ExerciseLib::show_score($best_score_data['exe_result'], $best_score_data['exe_weighting']); } if ($attempts > 0) { $exercise_stat = ExerciseLib::get_best_attempt_by_user(api_get_user_id(), $exercices['id'], $course_info['real_id'], $session_id); if (!empty($exercise_stat)) { //Always getting the BEST attempt $score = $exercise_stat['exe_result']; $weighting = $exercise_stat['exe_weighting']; $exe_id = $exercise_stat['exe_id']; $latest_attempt_url .= api_get_path(WEB_CODE_PATH) . 'exercice/result.php?id=' . $exe_id . '&cidReq=' . $course_info['code'] . '&show_headers=1&id_session=' . $session_id; $percentage_score_result = Display::url(ExerciseLib::show_score($score, $weighting), $latest_attempt_url); $my_score = 0; if (!empty($weighting) && intval($weighting) != 0) { $my_score = $score / $weighting; } //@todo this function slows the page $position = ExerciseLib::get_exercise_result_ranking($my_score, $exe_id, $exercices['id'], $course_info['code'], $session_id, $user_list); $graph = self::generate_exercise_result_thumbnail_graph($to_graph_exercise_result[$exercices['id']]); $normal_graph = self::generate_exercise_result_graph($to_graph_exercise_result[$exercices['id']]); } } $html .= Display::div($normal_graph, array('id' => 'main_graph_' . $exercices['id'], 'class' => 'dialog', 'style' => 'display:none')); if (empty($graph)) { $graph = '-'; } else { $graph = Display::url('<img src="' . $graph . '" >', $normal_graph, array('id' => $exercices['id'], 'class' => 'expand-image')); } $html .= Display::tag('td', $attempts, array('align' => 'center')); $html .= Display::tag('td', $percentage_score_result, array('align' => 'center')); $html .= Display::tag('td', $position, array('align' => 'center')); $html .= Display::tag('td', $best_score, array('align' => 'center')); $html .= Display::tag('td', $graph, array('align' => 'center')); //$html .= Display::tag('td', $latest_attempt_url, array('align'=>'center', 'width'=>'25')); } else { // Exercise configuration NO results $html .= Display::tag('td', $attempts, array('align' => 'center')); $html .= Display::tag('td', '-', array('align' => 'center')); $html .= Display::tag('td', '-', array('align' => 'center')); $html .= Display::tag('td', '-', array('align' => 'center')); $html .= Display::tag('td', '-', array('align' => 'center')); } $html .= '</tr>'; } } else { $html .= '<tr><td colspan="5" align="center">' . get_lang('NoEx') . '</td></tr>'; } $html .= '</table>'; // LP table results $html .= '<table class="data_table">'; $html .= Display::tag('th', get_lang('Learnpaths'), array('class' => 'head', 'style' => 'color:#000')); $html .= Display::tag('th', get_lang('LatencyTimeSpent'), array('class' => 'head', 'style' => 'color:#000')); $html .= Display::tag('th', get_lang('Progress'), array('class' => 'head', 'style' => 'color:#000')); $html .= Display::tag('th', get_lang('Score'), array('class' => 'head', 'style' => 'color:#000')); $html .= Display::tag('th', get_lang('LastConnexion'), array('class' => 'head', 'style' => 'color:#000')); $html .= '</tr>'; $list = new LearnpathList(api_get_user_id(), $course_info['code'], $session_id, 'publicated_on ASC', true); $lp_list = $list->get_flat_list(); if (!empty($lp_list) > 0) { foreach ($lp_list as $lp_id => $learnpath) { $progress = Tracking::get_avg_student_progress($user_id, $course, array($lp_id), $session_id); $last_connection_in_lp = Tracking::get_last_connection_time_in_lp($user_id, $course, $lp_id, $session_id); $time_spent_in_lp = Tracking::get_time_spent_in_lp($user_id, $course, array($lp_id), $session_id); $percentage_score = Tracking::get_avg_student_score($user_id, $course, array($lp_id), $session_id); if (is_numeric($percentage_score)) { $percentage_score = $percentage_score . '%'; } else { $percentage_score = '0%'; } $time_spent_in_lp = api_time_to_hms($time_spent_in_lp); $html .= '<tr class="row_even">'; $url = api_get_path(WEB_CODE_PATH) . "newscorm/lp_controller.php?cidReq={$course_code}&id_session={$session_id}&lp_id={$lp_id}&action=view"; if ($learnpath['lp_visibility'] == 0) { $html .= Display::tag('td', $learnpath['lp_name']); } else { $html .= Display::tag('td', Display::url($learnpath['lp_name'], $url, array('target' => SESSION_LINK_TARGET))); } $html .= Display::tag('td', $time_spent_in_lp, array('align' => 'center')); if (is_numeric($progress)) { $progress = $progress . '%'; } $html .= Display::tag('td', $progress, array('align' => 'center')); $html .= Display::tag('td', $percentage_score); $last_connection = '-'; if (!empty($last_connection_in_lp)) { $last_connection = api_convert_and_format_date($last_connection_in_lp, DATE_TIME_FORMAT_LONG); } $html .= Display::tag('td', $last_connection, array('align' => 'center', 'width' => '180px')); $html .= "</tr>"; } } else { $html .= '<tr> <td colspan="4" align="center"> ' . get_lang('NoLearnpath') . ' </td> </tr>'; } $html .= '</table>'; } return $html; }
/** * Shows question title an description * * @param string $feedback_type * @param int $counter * @param float $score */ function return_header($feedback_type = null, $counter = null, $score = null) { $counter_label = ''; if (!empty($counter)) { $counter_label = intval($counter); } $score_label = get_lang('Wrong'); $class = 'error'; if ($score['pass'] == true) { $score_label = get_lang('Correct'); $class = 'success'; } if ($this->type == FREE_ANSWER || $this->type == ORAL_EXPRESSION) { $score['revised'] = isset($score['revised']) ? $score['revised'] : false; if ($score['revised'] == true) { $score_label = get_lang('Revised'); $class = ''; } else { $score_label = get_lang('NotRevised'); $class = 'error'; } } $question_title = $this->question; // display question category, if any $header = TestCategory::returnCategoryAndTitle($this->id); $show_media = null; if ($show_media) { $header .= $this->show_media_content(); } $header .= Display::page_subheader2($counter_label . ". " . $question_title); $header .= Display::div("<div class=\"rib rib-{$class}\"><h3>{$score_label}</h3></div> <h4>{$score['result']}</h4>", array('class' => 'ribbon')); $header .= Display::div($this->description, array('id' => 'question_description')); return $header; }
if (!empty($thematic_advance_data[$thematic['id']])) { echo '<table width="100%">'; foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) { $thematic_advance['start_date'] = api_get_local_time($thematic_advance['start_date']); $thematic_advance['start_date'] = api_format_date($thematic_advance['start_date'], DATE_TIME_FORMAT_LONG); echo '<tr>'; echo '<td width="90%" class="thematic_advance_content" id="thematic_advance_content_id_' . $thematic_advance['id'] . '">'; $edit_link = ''; if (api_is_allowed_to_edit(null, true)) { $edit_link = Display::url(Display::return_icon('edit.png', get_lang('EditThematicAdvance'), [], ICON_SIZE_SMALL), 'index.php?' . api_get_cidreq() . '&' . http_build_query(['action' => 'thematic_advance_edit', 'thematic_id' => $thematic['id'], 'thematic_advance_id' => $thematic_advance['id'], 'display' => 'no_header']), ['class' => 'ajax', 'data-title' => get_lang('EditThematicAdvance')]); $edit_link .= '<a onclick="javascript:if(!confirm(\'' . get_lang('AreYouSureToDelete') . '\')) return false;" href="index.php?' . api_get_cidreq() . '&action=thematic_advance_delete&thematic_id=' . $thematic['id'] . '&thematic_advance_id=' . $thematic_advance['id'] . '">' . Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL) . '</a></center>'; //Links $edit_link = Display::div(Display::div($edit_link, array('id' => 'thematic_advance_tools_' . $thematic_advance['id'], 'class' => 'thematic_advance_actions')), array('style' => 'height:20px;')); } $thematic_advance_item = isset($thematic_advance_div[$thematic['id']][$thematic_advance['id']]) ? $thematic_advance_div[$thematic['id']][$thematic_advance['id']] : null; echo Display::div($thematic_advance_item, array('id' => 'thematic_advance_' . $thematic_advance['id'])); echo $edit_link; echo '</td>'; //if (api_is_allowed_to_edit(null, true) && api_get_session_id() == $thematic['session_id']) { if (api_is_allowed_to_edit(null, true)) { if (empty($thematic_id)) { $checked = ''; if ($last_done_thematic_advance == $thematic_advance['id']) { $checked = 'checked'; } $style = ''; if ($thematic_advance['done_advance'] == 1) { $style = ' style="background-color:#E5EDF9" '; } else { $style = ' style="background-color:#fff" '; }
function panel($content = null, $title = null, $id = null, $style = null) { $html = ''; if (empty($style)) { $style = 'default'; } if (!empty($title)) { $panelTitle = Display::div($title, array('class' => 'panel-heading')); $panelBody = Display::div($content, array('class' => 'panel-body')); $panelParent = Display::div($panelTitle . $panelBody, array('id' => $id, 'class' => 'panel panel-' . $style)); } else { $panelBody = Display::div($html, array('class' => 'panel-body')); $panelParent = Display::div($panelBody, array('id' => $id, 'class' => 'panel panel-' . $style)); } $html .= $panelParent; return $html; }
/** * Show the monthcalender of the given month * @param array Agendaitems * @param int Month number * @param int Year number * @param array Array of strings containing long week day names (deprecated, you can send an empty array instead) * @param string The month name * @return void Direct output */ function display_mymonthcalendar($user_id, $agendaitems, $month, $year, $weekdaynames = array(), $monthName, $show_content = true) { global $DaysShort, $course_path; //Handle leap year $numberofdays = array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if ($year % 400 == 0 or $year % 4 == 0 and $year % 100 != 0) { $numberofdays[2] = 29; } //Get the first day of the month $dayone = getdate(mktime(0, 0, 0, $month, 1, $year)); //Start the week on monday $startdayofweek = $dayone['wday'] != 0 ? $dayone['wday'] - 1 : 6; $g_cc = isset($_GET['courseCode']) ? $_GET['courseCode'] : ''; $prev_icon = Display::return_icon('action_prev.png', get_lang('Previous')); $next_icon = Display::return_icon('action_next.png', get_lang('Next')); $next_month = $month == 1 ? 12 : $month - 1; $prev_month = $month == 12 ? 1 : $month + 1; $next_year = $month == 1 ? $year - 1 : $year; $prev_year = $month == 12 ? $year + 1 : $year; if ($show_content) { $back_url = Display::url($prev_icon, api_get_self() . "?coursePath=" . urlencode($course_path) . "&courseCode=" . Security::remove_XSS($g_cc) . "&action=view&view=month&month=" . $next_month . "&year=" . $next_year); $next_url = Display::url($next_icon, api_get_self() . "?coursePath=" . urlencode($course_path) . "&courseCode=" . Security::remove_XSS($g_cc) . "&action=view&view=month&month=" . $prev_month . "&year=" . $prev_year); } else { $back_url = Display::url($prev_icon, '', array('onclick' => "load_calendar('" . $user_id . "','" . $next_month . "', '" . $next_year . "'); ")); $next_url = Display::url($next_icon, '', array('onclick' => "load_calendar('" . $user_id . "','" . $prev_month . "', '" . $prev_year . "'); ")); } echo '<table id="agenda_list"><tr>'; echo '<th width="10%">' . $back_url . '</th>'; echo '<th width="80%" colspan="5"><br /><h3>' . $monthName . " " . $year . '</h3></th>'; echo '<th width="10%">' . $next_url . '</th>'; echo '</tr>'; echo '<tr>'; for ($ii = 1; $ii < 8; $ii++) { echo '<td class="weekdays">' . $DaysShort[$ii % 7] . '</td>'; } echo '</tr>'; $curday = -1; $today = getdate(); while ($curday <= $numberofdays[$month]) { echo "<tr>"; for ($ii = 0; $ii < 7; $ii++) { if ($curday == -1 && $ii == $startdayofweek) { $curday = 1; } if ($curday > 0 && $curday <= $numberofdays[$month]) { $bgcolor = $class = 'class="days_week"'; $dayheader = Display::div($curday, array('class' => 'agenda_day')); if ($curday == $today['mday'] && $year == $today['year'] && $month == $today['mon']) { $class = "class=\"days_today\" style=\"width:10%;\""; } echo "<td " . $class . ">" . $dayheader; if (!empty($agendaitems[$curday])) { $items = $agendaitems[$curday]; $items = ArrayClass::msort($items, 'start_date_tms'); foreach ($items as $value) { $value['title'] = Security::remove_XSS($value['title']); $start_time = api_format_date($value['start_date'], TIME_NO_SEC_FORMAT); $end_time = ''; if (!empty($value['end_date']) && $value['end_date'] != '0000-00-00 00:00:00') { $end_time = '- <i>' . api_format_date($value['end_date'], DATE_TIME_FORMAT_LONG) . '</i>'; } $complete_time = '<i>' . api_format_date($value['start_date'], DATE_TIME_FORMAT_LONG) . '</i> ' . $end_time; $time = '<i>' . $start_time . '</i>'; switch ($value['calendar_type']) { case 'personal': $bg_color = '#D0E7F4'; $icon = Display::return_icon('user.png', get_lang('MyAgenda'), array(), ICON_SIZE_SMALL); break; case 'global': $bg_color = '#FFBC89'; $icon = Display::return_icon('view_remove.png', get_lang('GlobalEvent'), array(), ICON_SIZE_SMALL); break; case 'course': $bg_color = '#CAFFAA'; $icon_name = 'course.png'; if (!empty($value['session_id'])) { $icon_name = 'session.png'; } if ($show_content) { $icon = Display::url(Display::return_icon($icon_name, $value['course_name'] . ' ' . get_lang('Course'), array(), ICON_SIZE_SMALL), $value['url']); } else { $icon = Display::return_icon($icon_name, $value['course_name'] . ' ' . get_lang('Course'), array(), ICON_SIZE_SMALL); } break; default: break; } $result = '<div class="rounded_div_agenda" style="background-color:' . $bg_color . ';">'; if ($show_content) { //Setting a personal event to green $icon = Display::div($icon, array('style' => 'float:right')); $link = $value['calendar_type'] . '_' . $value['id'] . '_' . $value['course_id'] . '_' . $value['session_id']; //Link to bubble $url = Display::url(Text::cut($value['title'], 40), '#', array('id' => $link, 'class' => 'opener')); $result .= $time . ' ' . $icon . ' ' . Display::div($url); //Hidden content $content = Display::div($icon . Display::tag('h2', $value['course_name']) . '<hr />' . Display::tag('h3', $value['title']) . $complete_time . '<hr />' . Security::remove_XSS($value['content'])); //Main div $result .= Display::div($content, array('id' => 'main_' . $link, 'class' => 'dialog', 'style' => 'display:none')); $result .= '</div>'; echo $result; //echo Display::div($content, array('id'=>'main_'.$value['calendar_type'].'_'.$value['id'], 'class' => 'dialog')); } else { echo $result .= $icon . '</div>'; } } } echo "</td>"; $curday++; } else { echo "<td></td>"; } } echo "</tr>"; } echo "</table>"; }
/** * */ function show_form_send_ticket() { global $types, $plugin; echo '<div class="divTicket">'; //Category List $categoryList = array(); foreach ($types as $type) { $categoryList[$type['category_id']] = $type['name'] . ": " . $type['description']; } //End Category List //Status List $statusList = array(); $statusAttributes = array('style' => 'display: none;', 'id' => 'status_id', 'for' => 'status_id'); $statusList[NEWTCK] = $plugin->get_lang('StatusNew'); if (api_is_platform_admin()) { $statusAttributes = array('id' => 'status_id', 'for' => 'status_id', 'style' => 'width: 562px;'); $statusList[PENDING] = $plugin->get_lang('StatusPending'); $statusList[UNCONFIRMED] = $plugin->get_lang('StatusUnconfirmed'); $statusList[CLOSE] = $plugin->get_lang('StatusClose'); $statusList[REENVIADO] = $plugin->get_lang('StatusForwarded'); } //End Status List //Source List $sourceList = array(); $sourceAttributes = array('style' => 'display: none;', 'id' => 'source_id', 'for' => 'source_id'); $sourceList[SRC_PLATFORM] = $plugin->get_lang('SrcPlatform'); if (api_is_platform_admin()) { $sourceAttributes = array('id' => 'source_id', 'for' => 'source_id', 'style' => 'width: 562px;'); $sourceList[SRC_EMAIL] = $plugin->get_lang('SrcEmail'); $sourceList[SRC_PHONE] = $plugin->get_lang('SrcPhone'); $sourceList[SRC_PRESC] = $plugin->get_lang('SrcPresential'); } //End Source List //Priority List $priorityList = array(); $priorityList[NORMAL] = $plugin->get_lang('PriorityNormal'); $priorityList[HIGH] = $plugin->get_lang('PriorityHigh'); $priorityList[LOW] = $plugin->get_lang('PriorityLow'); //End Priority List $form = new FormValidator('send_ticket', 'POST', api_get_self(), "", array('enctype' => 'multipart/form-data', 'onsubmit' => 'return validate()', 'class' => 'span8 offset1 form-horizontal')); $form->addElement('hidden', 'user_id_request', '', array('id' => 'user_id_request')); $form->addElement('hidden', 'project_id', '', array('id' => 'project_id')); $form->addElement('hidden', 'other_area', '', array('id' => 'other_area')); $form->addElement('hidden', 'email', '', array('id' => 'email')); $form->addElement('select', 'category_id', get_lang('Category'), $categoryList, array('onchange' => 'changeType()', 'id' => 'category_id', 'for' => 'category_id', 'style' => 'width: 562px;')); $form->addElement('html', Display::div('', array('id' => 'user_request'))); $form->addElement('select', 'status_id', get_lang('Status'), $statusList, $statusAttributes); $form->addElement('select', 'source_id', $plugin->get_lang('Source'), $sourceList, $sourceAttributes); $form->addElement('text', 'subject', get_lang('Subject'), array('id' => 'subject', 'style' => 'width: 550px;')); $form->addElement('text', 'personal_email', $plugin->get_lang('PersonalEmail'), array('id' => 'personal_email', 'style' => 'width: 550px;')); $form->addHtmlEditor('content', get_lang('Message'), false, false, array('ToolbarSet' => 'Profile', 'Width' => '600', 'Height' => '250')); $form->addElement('text', 'phone', get_lang('Phone') . ' (' . $plugin->get_lang('Optional') . ')', array('id' => 'phone')); $form->addElement('select', 'priority_id', $plugin->get_lang('Priority'), $priorityList, array('id' => 'priority_id', 'for' => 'priority_id')); $form->addElement('html', '<span id="filepaths">'); $form->addElement('html', '<div id="filepath_1">'); $form->addElement('file', 'attach_1', get_lang('FilesAttachment')); $form->addElement('html', '</div>'); $form->addElement('html', '</span>'); $form->addElement('html', '<div class="controls">'); $form->addElement('html', '<span id="link-more-attach" >'); $form->addElement('html', '<span class="label label-info" onclick="return add_image_form()">' . get_lang('AddOneMoreFile') . '</span>'); $form->addElement('html', '</span>'); $form->addElement('html', '(' . sprintf(get_lang('MaximunFileSizeX'), format_file_size(api_get_setting('message_max_upload_filesize'))) . ')'); $form->addElement('html', '<br/>'); $form->addElement('button', 'compose', get_lang('SendMessage'), null, null, null, 'save', array('id' => 'btnsubmit')); $form->display(); }
/** * Shows question title an description * * @param int $feedback_type * @param int $counter * @param array $score * @param bool $show_media * @param int $hideTitle * * @return string */ public function return_header($feedbackType = null, $counter = null, $score = null, $show_media = false, $hideTitle = 0) { $counterLabel = null; if (!empty($counter)) { $counterLabel = $counter; } $score_label = get_lang('Wrong'); $class = 'error'; if ($score['pass'] == true) { $score_label = get_lang('Correct'); $class = 'success'; } if ($this->type == FREE_ANSWER || $this->type == ORAL_EXPRESSION) { if ($score['revised'] == true) { $score_label = get_lang('Revised'); $class = ''; } else { $score_label = get_lang('NotRevised'); $class = 'error'; } } $header = null; // Display question category, if any if ($show_media) { $header .= $this->show_media_content(); } if ($hideTitle == 1) { $header .= Display::page_subheader2($counterLabel); } else { $header .= Display::page_subheader2($counterLabel . ". " . $this->question); } $header .= Display::div('<div class="rib rib-' . $class . '"><h3>' . $score_label . '</h3></div><h4>' . $score['result'] . ' </h4>', array('class' => 'ribbon')); $header .= Display::div($this->description, array('id' => 'question_description')); return $header; }
/** * Return the five star HTML * * @param string id of the rating ul element * @param string url that will be added (for jquery see hot_courses.tpl) * @param string point info array see function CourseManager::get_course_ranking() * @param bool add a div wrapper * @todo use templates **/ public static function return_rating_system($id, $url, $point_info = array(), $add_div_wrapper = true) { $number_of_users_who_voted = isset($point_info['users_who_voted']) ? $point_info['users_who_voted'] : null; $percentage = isset($point_info['point_average']) ? $point_info['point_average'] : 0; if (!empty($percentage)) { $percentage = $percentage * 125 / 100; } $accesses = isset($point_info['accesses']) ? $point_info['accesses'] : 0; $star_label = sprintf(get_lang('XStarsOutOf5'), $point_info['point_average_star']); $html = '<ul id="' . $id . '" class="star-rating"> <li class="current-rating" style="width:' . $percentage . 'px;"></li> <li><a href="javascript:void(0);" data-link="' . $url . '&star=1" title="' . $star_label . '" class="one-star">1</a></li> <li><a href="javascript:void(0);" data-link="' . $url . '&star=2" title="' . $star_label . '" class="two-stars">2</a></li> <li><a href="javascript:void(0);" data-link="' . $url . '&star=3" title="' . $star_label . '" class="three-stars">3</a></li> <li><a href="javascript:void(0);" data-link="' . $url . '&star=4" title="' . $star_label . '" class="four-stars">4</a></li> <li><a href="javascript:void(0);" data-link="' . $url . '&star=5" title="' . $star_label . '" class="five-stars">5</a></li> </ul>'; $labels = array(); $labels[] = $number_of_users_who_voted == 1 ? $number_of_users_who_voted . ' ' . get_lang('Vote') : $number_of_users_who_voted . ' ' . get_lang('Votes'); $labels[] = $accesses == 1 ? $accesses . ' ' . get_lang('Visit') : $accesses . ' ' . get_lang('Visits'); if (!empty($number_of_users_who_voted)) { $labels[] = get_lang('Average') . ' ' . $point_info['point_average_star'] . '/5'; } $labels[] = $point_info['user_vote'] ? get_lang('YourVote') . ' [' . $point_info['user_vote'] . ']' : get_lang('YourVote') . ' [?] '; if (!$add_div_wrapper && api_is_anonymous()) { $labels[] = Display::tag('span', get_lang('LoginToVote'), array('class' => 'error')); } $html .= Display::span(implode(' | ', $labels), array('id' => 'vote_label_' . $id, 'class' => 'vote_label_info')); $html .= ' ' . Display::span(' ', array('id' => 'vote_label2_' . $id)); if ($add_div_wrapper) { $html = Display::div($html, array('id' => 'rating_wrapper_' . $id)); } return $html; }