View source
<?php
define('OPIGNO_QUIZ_APP_PASSED', 'passed');
define('OPIGNO_QUIZ_APP_FAILED', 'failed');
define('OPIGNO_QUIZ_APP_PENDING', 'pending');
function opigno_quiz_app_menu() {
return array(
'user/%/achievements' => array(
'title' => "My achievements",
'page callback' => 'opigno_quiz_app_user_results',
'page arguments' => array(
1,
),
'access callback' => 'opigno_quiz_app_access_user_achievements',
'access arguments' => array(
1,
),
'file' => 'includes/opigno_quiz_app.pages.inc',
'type' => MENU_LOCAL_TASK,
),
'my-achievements' => array(
'title' => "My achievements",
'page callback' => 'opigno_quiz_app_user_results',
'access arguments' => array(
'access own results',
),
'file' => 'includes/opigno_quiz_app.pages.inc',
'type' => MENU_CALLBACK,
),
'my-results' => array(
'title' => "My results",
'page callback' => 'opigno_quiz_app_current_user_results',
'access callback' => 'user_is_logged_in',
'file' => 'includes/opigno_quiz_app.pages.inc',
'type' => MENU_CALLBACK,
),
'node/%node/teacher-results' => array(
'title' => "Student results",
'description' => "Displays all student results to teachers",
'page callback' => 'opigno_quiz_app_course_results',
'page arguments' => array(
1,
),
'access callback' => 'opigno_quiz_app_access_node_teacher_results',
'access arguments' => array(
1,
NULL,
),
'file' => 'includes/opigno_quiz_app.pages.inc',
'type' => MENU_CALLBACK,
),
'node/%node/sort-quizzes' => array(
'title' => "Sort @quiz_name_plural",
'title arguments' => array(
'@quiz_name_plural' => defined('QUIZ_NAME_PLURAL') ? QUIZ_NAME_PLURAL : 'quizzes',
),
'description' => "Sort quizzes inside the course",
'page callback' => 'drupal_get_form',
'page arguments' => array(
'opigno_quiz_app_sort_course_quizzes_form',
1,
),
'access callback' => 'opigno_quiz_app_access_node_sort_quizzes',
'access arguments' => array(
1,
),
'file' => 'includes/opigno_quiz_app.pages.inc',
'type' => MENU_CALLBACK,
),
'admin/opigno/students/teacher-results' => array(
'title' => "My course student results",
'description' => "Displays all course student results to teachers",
'page callback' => 'opigno_quiz_app_courses_results',
'access arguments' => array(
'access teacher results',
),
'file' => 'includes/opigno_quiz_app.pages.inc',
),
'node/%node/resume' => array(
'title' => 'Resume',
'page callback' => 'opigno_quiz_app_course_resume',
'page arguments' => array(
1,
),
'access callback' => 'opigno_quiz_app_course_resume_access',
'access arguments' => array(
1,
),
),
);
}
function opigno_quiz_app_course_resume_access($node) {
if (in_array($node->type, array(
'course',
'class',
))) {
return node_access('view', $node);
}
return FALSE;
}
function opigno_quiz_app_course_resume($node) {
if ($node->type == 'class') {
$courses = opigno_class_app_get_class_courses($node);
if (empty($courses)) {
drupal_set_message(t('This class does not have any courses.'), 'status', FALSE);
drupal_goto('node/' . $node->nid);
}
}
else {
if ($node->type == 'course') {
$courses = array(
$node->nid,
);
}
else {
drupal_goto('<front>');
}
}
foreach ($courses as $course_nid) {
$path = opigno_quiz_app_course_resume_get_path($course_nid);
if ($path != '<front>' && $path != 'node/' . $course_nid && drupal_valid_path($path)) {
drupal_goto($path);
}
}
$first_lesson = opigno_quiz_app_get_first_lesson_from_group($node);
if ($first_lesson != null && drupal_valid_path('node/' . $first_lesson . '/take')) {
drupal_goto('node/' . $first_lesson . '/take');
}
drupal_set_message(t('This @type does not have any lessons.', array(
'@type' => $node->type,
)), 'status', FALSE);
drupal_goto('node/' . $node->nid);
}
function opigno_quiz_app_course_resume_get_path($course_nid) {
global $user;
$last_viewed_lesson_in_course = opigno_quiz_app_course_get_last_viewed($course_nid, $user->uid);
if (!$last_viewed_lesson_in_course) {
$lessons = opigno_quiz_app_course_lessons($course_nid);
if (isset($lessons[$course_nid])) {
$first_lesson = key($lessons[$course_nid]);
return 'node/' . $first_lesson . '/take';
}
else {
return '<front>';
}
}
else {
$last_viewed_lesson_in_course_result = $last_viewed_lesson_in_course['result_id'];
$last_viewed_lesson_in_course = $last_viewed_lesson_in_course['quiz_nid'];
$lesson_to_go = 0;
if (!opigno_quiz_app_user_finished_quiz_result($last_viewed_lesson_in_course, $last_viewed_lesson_in_course_result, $user->uid)) {
$lesson_to_go = $last_viewed_lesson_in_course;
}
else {
$lessons = opigno_quiz_app_course_lessons($course_nid);
if (isset($lessons[$course_nid])) {
$current_position = array_search($last_viewed_lesson_in_course, array_keys($lessons[$course_nid]));
if ($current_position == count($lessons[$course_nid]) - 1) {
return 'node/' . $course_nid;
}
else {
$keys = array_keys($lessons[$course_nid]);
$next_lesson = $keys[array_search($last_viewed_lesson_in_course, $keys) + 1];
$lesson_to_go = $next_lesson;
}
}
}
if ($lesson_to_go) {
$lesson_node = node_load($lesson_to_go);
if ($lesson_node) {
return 'node/' . $lesson_to_go . '/take';
}
else {
$lessons = opigno_quiz_app_course_lessons($course_nid);
if (isset($lessons[$course_nid])) {
$first_lesson = key($lessons[$course_nid]);
return 'node/' . $first_lesson . '/take';
}
else {
return '<front>';
}
}
}
}
}
function opigno_quiz_app_course_get_last_viewed($course_nid, $uid) {
$result = db_select('opigno_quiz_app_course_latest_viewed', 'lv');
$result
->leftJoin('og_membership', 'ogm', 'ogm.etid = lv.quiz_nid');
$result
->leftJoin('node', 'n', 'n.nid = lv.quiz_nid');
$result = $result
->fields('lv', array(
'quiz_nid',
'result_id',
))
->fields('ogm', array(
'gid',
))
->fields('n', array(
'nid',
))
->condition('lv.course_nid', $course_nid)
->condition('lv.uid', $uid)
->condition('ogm.group_type', 'node')
->condition('ogm.gid', $course_nid)
->condition('ogm.state', 1)
->condition('ogm.field_name', 'og_group_ref')
->condition('n.status', 1)
->execute()
->fetchAssoc();
return empty($result) ? 0 : $result;
}
function opigno_quiz_app_user_finished_quiz_result($quiz_nid, $result_id, $uid) {
$result = db_select('quiz_node_results', 'r')
->fields('r', array(
'result_id',
))
->condition('r.uid', $uid)
->condition('r.time_end', 0, '>')
->condition('r.nid', $quiz_nid, '=')
->condition('r.result_id', $result_id, '=')
->execute()
->fetchField();
return empty($result) ? 0 : $result;
}
function opigno_quiz_app_course_last_viewed($course_nid, $quiz_nid, $result_id, $uid) {
db_merge('opigno_quiz_app_course_latest_viewed')
->key(array(
'course_nid' => $course_nid,
'uid' => $uid,
))
->fields(array(
'course_nid' => $course_nid,
'quiz_nid' => $quiz_nid,
'uid' => $uid,
'result_id' => $result_id,
))
->execute();
}
function opigno_quiz_app_user_delete($account) {
db_delete('opigno_quiz_app_course_latest_viewed')
->condition('uid', $account->uid)
->execute();
}
function opigno_quiz_app_menu_alter(&$items) {
$items['node/%node/take']['page callback'] = 'opigno_quiz_app_quiz_take';
$items['node/%node/take']['file'] = 'includes/opigno_quiz_app.pages.inc';
$items['node/%node/take']['file path'] = drupal_get_path('module', 'opigno_quiz_app');
}
function opigno_quiz_app_permission() {
return array(
'access all results' => array(
'title' => t("Access all user results"),
),
'access own results' => array(
'title' => t("Access own results"),
),
'access teacher results' => array(
'title' => t('Access teacher results'),
'description' => t('Allows course teachers to access all their student results.'),
),
);
}
function opigno_quiz_app_access_user_achievements($uid) {
global $user;
if ($user->uid) {
if (user_access('access all results')) {
return TRUE;
}
elseif ($user->uid == $uid && user_access('access own results')) {
return TRUE;
}
}
return FALSE;
}
function opigno_quiz_app_og_permission() {
return array(
'skip display of results' => array(
'title' => t("Skip displaying results on teacher results page"),
'description' => t("Some roles might be allowed to take quizzes, but these should not be shown on the teacher results page."),
),
'sort quizzes' => array(
'title' => t("Sort quizzes inside this course"),
),
);
}
function opigno_quiz_app_node_insert($node) {
if ($node->type == 'quiz' && !empty($node->nid) && !empty($node->og_group_ref)) {
foreach ($node->og_group_ref as $lang => $items) {
foreach ($items as $item) {
opigno_quiz_app_set_course_quiz_weight($item['target_id'], $node->nid);
}
}
}
}
function opigno_quiz_app_node_update($node) {
if ($node->type == 'quiz' && !empty($node->nid) && !empty($node->og_group_ref)) {
$original_node = $node->original;
foreach ($node->og_group_ref as $lang => $items) {
foreach ($items as $item) {
if (!opigno_quiz_app_is_in_entity_reference($item['target_id'], $original_node->og_group_ref)) {
opigno_quiz_app_set_course_quiz_weight($item['target_id'], $node->nid);
}
}
}
foreach ($original_node->og_group_ref as $lang => $items) {
foreach ($items as $item) {
if (!opigno_quiz_app_is_in_entity_reference($item['target_id'], $node->og_group_ref)) {
opigno_quiz_app_delete_course_quiz_weight($item['target_id'], $node->nid);
}
}
}
}
}
function opigno_quiz_app_is_in_entity_reference($target_id, $field) {
foreach ($field as $lang => $items) {
foreach ($items as $item) {
if ($target_id == $item['target_id']) {
return TRUE;
}
}
}
return FALSE;
}
function opigno_quiz_app_og_context_negotiation_info() {
$providers = array();
$paths = array();
foreach (opigno_quiz_app_get_quiz_question_types() as $type) {
$type = str_replace('_', '-', $type);
$paths[] = "node/add/{$type}";
}
$providers['opigno_quiz_app_question_add'] = array(
'name' => t('Opigno Quiz App: add question'),
'description' => t("Determine context by checking node/add/[question type]."),
'callback' => 'opigno_quiz_app_og_context_handler',
'menu path' => $paths,
);
return $providers;
}
function opigno_quiz_app_og_context_handler() {
if (opigno_quiz_app_is_node_add_question()) {
$args = explode('/', current_path());
$node = (object) array(
'type' => str_replace('-', '_', array_pop($args)),
);
og_quiz_node_prepare($node);
if (isset($node->og_group_ref)) {
$items = array_shift($node->og_group_ref);
$gid = $items[0]['target_id'];
return array(
'node' => array(
$gid,
),
);
}
}
}
function opigno_quiz_app_opigno_breadcrumbs($gid) {
$breadcrumbs = array();
$node = menu_get_object();
if (isset($node->type) && $node->type == 'quiz' || current_path() == 'node/add/quiz' || preg_match('/^node\\/[0-9]+\\/sort-quizzes$/', current_path()) || opigno_quiz_app_is_node_add_question()) {
$breadcrumbs[] = l(opigno_quiz_app_get_quizzes_view_title(), "node/{$gid}/quizzes");
if (isset($node->type) && $node->type == 'quiz' && preg_match('/^node\\/[0-9]+\\/.+/', current_path())) {
$breadcrumbs[] = l($node->title, "node/{$node->nid}");
}
if (opigno_quiz_app_is_node_add_question() && !empty($_GET['quiz_nid'])) {
$quiz = node_load($_GET['quiz_nid']);
$breadcrumbs[] = l($quiz->title, "node/{$_GET['quiz_nid']}");
$breadcrumbs[] = l(t("Manage questions"), "node/{$_GET['quiz_nid']}/questions");
}
}
if (!empty($breadcrumbs)) {
return $breadcrumbs;
}
}
function opigno_quiz_app_menu_local_tasks_alter(&$data, $router_item, $root_path) {
if ($root_path == 'node/%') {
$node = node_load(arg(1));
if (isset($node->type) && in_array($node->type, array(
"course",
"class",
)) && og_user_access('node', $node->nid, 'access quiz')) {
$item = menu_get_item('node/' . $node->nid . '/resume');
$item['title'] = t("Continue");
$item['options']['attributes']['class'][] = $item['localized_options']['attributes']['class'][] = 'opigno-quiz-app-course-start';
$data['actions']['output'][] = array(
'#theme' => 'menu_local_action',
'#link' => $item,
);
}
}
if ($root_path == 'node/%/quizzes') {
$gid = arg(1);
if (og_user_access('node', $gid, 'create quiz content')) {
$item = menu_get_item('node/add/quiz');
$item['title'] = t("Add a new @quiz_name", array(
'@quiz_name' => QUIZ_NAME,
));
$item['options']['query']['og_group_ref'] = $item['localized_options']['query']['og_group_ref'] = $gid;
$item['options']['attributes']['class'][] = $item['localized_options']['attributes']['class'][] = 'opigno-quiz-app-add-quiz';
$data['actions']['output'][] = array(
'#theme' => 'menu_local_action',
'#link' => $item,
);
}
$node = node_load($gid);
if (opigno_quiz_app_access_node_sort_quizzes($node, NULL)) {
$item = menu_get_item("node/{$gid}/sort-quizzes");
$destination = request_path();
$item['options']['query']['destination'] = $item['localized_options']['query']['destination'] = $destination;
$item['options']['attributes']['class'][] = $item['localized_options']['attributes']['class'][] = 'opigno-quiz-app-sort-quizzes';
$data['actions']['output'][] = array(
'#theme' => 'menu_local_action',
'#link' => $item,
);
}
}
}
function opigno_quiz_app_theme() {
return array(
'opigno_quiz_app_user_results' => array(
'variables' => array(
'user' => NULL,
'results' => NULL,
),
),
'opigno_quiz_app_user_course_results' => array(
'variables' => array(
'user' => NULL,
'course_node' => NULL,
'course_results' => NULL,
),
),
'opigno_quiz_app_course_results' => array(
'variables' => array(
'course' => NULL,
'results' => NULL,
),
),
'opigno_quiz_app_course_user_results' => array(
'variables' => array(
'course' => NULL,
'user' => NULL,
'results' => NULL,
),
),
'opigno_quiz_app_sort_course_quizzes_form' => array(
'render element' => 'form',
),
);
}
function opigno_quiz_app_views_api() {
return array(
'api' => '3.0',
);
}
function opigno_quiz_app_views_data() {
$data['opigno_quiz_app_quiz_sort']['table']['group'] = t("Opigno Quiz App");
$data['opigno_quiz_app_quiz_sort']['table']['join'] = array(
'node' => array(
'left_field' => 'nid',
'field' => 'quiz_nid',
),
);
$data['opigno_quiz_app_quiz_sort']['gid'] = array(
'title' => t("The Quiz group"),
'help' => t("The gid of the quiz weight table"),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'relationship' => array(
'base' => 'node',
'base field' => 'nid',
'field' => 'gid',
'handler' => 'views_handler_relationship',
'label' => t("Group"),
),
'argument' => array(
'handler' => 'views_handler_argument_numeric',
),
);
$data['opigno_quiz_app_quiz_sort']['quiz_nid'] = array(
'title' => t("The Quiz weight (as in order) inside a group"),
'relationship' => array(
'base' => 'node',
'base field' => 'nid',
'label' => t("Quiz"),
),
);
$data['opigno_quiz_app_quiz_sort']['weight'] = array(
'title' => t("Quiz weight (as in order)"),
'help' => t("The weight of the quiz inside a specific group"),
'field' => array(
'handler' => 'opigno_quiz_app_field_course_quiz_weight',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'opigno_quiz_app_field_course_quiz_weight',
),
'sort' => array(
'handler' => 'opigno_quiz_app_sort_course_quiz_weight',
),
'argument' => array(
'handler' => 'views_handler_argument_numeric',
),
);
$data['opigno_quiz_app_quiz_sort']['course_class_progress'] = array(
'title' => t("Progression"),
'help' => t('Show the course or class progression for the logged user'),
'field' => array(
'handler' => 'opigno_quiz_app_field_course_class_progress',
),
);
return $data;
}
function opigno_quiz_app_modules_enabled($modules) {
if (in_array('opigno_calendar_app', $modules)) {
module_load_install('opigno_quiz_app');
opigno_quiz_app_enable_calendar_integration();
}
}
function opigno_quiz_app_quiz_finished($quiz, $score, $rid, $taker = NULL) {
if (module_exists('rules')) {
global $user;
$taker = isset($taker) ? $taker : clone $user;
$author = user_load($quiz->uid);
$quiz = node_load($quiz->nid);
rules_invoke_event('opigno_quiz_app_rules_quiz_taken', $taker, $author, $quiz);
if ($score['passing'] == true && $score['percentage_score'] >= $quiz->pass_rate) {
rules_invoke_event('opigno_quiz_app_rules_quiz_passed', $taker, $author, $quiz);
drupal_set_message(t("You successfully completed this lesson."));
}
else {
rules_invoke_event('opigno_quiz_app_rules_quiz_failed', $taker, $author, $quiz);
}
}
setcookie('opigno_quiz_app_fs', 'false');
}
function opigno_quiz_app_quiz_scored($quiz, $score, $rid) {
$taker = user_load(db_select('quiz_node_results', 'r')
->fields('r', array(
'uid',
))
->condition('result_id', $rid)
->execute()
->fetchField());
opigno_quiz_app_quiz_finished($quiz, $score, $rid, $taker);
}
function opigno_quiz_app_opigno_tool($node = NULL) {
return array(
'quiz' => array(
'name' => t("Quiz"),
'path' => isset($node) ? "node/{$node->nid}/quizzes" : '',
'description' => t("Quizzes allow teachers to assess students and provide scenario-like information."),
'actions' => array(
'add_quiz' => array(
'title' => t("Add a new Quiz"),
'href' => 'node/add/quiz',
'access_arguments' => array(
'node',
isset($node) ? $node->nid : 0,
'create quiz content',
),
'access_callback' => 'og_user_access',
'query' => array(
'og_group_ref' => isset($node) ? $node->nid : '',
),
),
),
),
);
}
function opigno_quiz_app_access_node_teacher_results($node, $quiz = NULL, $account = NULL) {
if (!isset($account)) {
global $user;
$account = clone $user;
}
$access = user_access('view any quiz results', $account) || og_user_access('node', $node->nid, 'view any quiz results', $account);
if (!$access && isset($quiz)) {
$access = (user_access('view results for own quiz', $account) || og_user_access('node', $node->nid, 'view results for own quiz', $account)) && $quiz->uid == $account->uid;
}
return $access;
}
function opigno_quiz_app_access_node_sort_quizzes($node, $account = NULL) {
if (!isset($account)) {
global $user;
$account = clone $user;
}
return og_user_access('node', $node->nid, 'sort quizzes', $account);
}
function opigno_quiz_app_take_access($node, $account = NULL) {
if (!isset($account)) {
global $user;
$account = clone $user;
}
return og_user_access('node', $node->nid, 'access quiz', $account);
}
function opigno_quiz_app_get_quizzes_view_title() {
$cache = cache_get('opigno_quiz_app:view_title:opigno_quizzes');
if ($cache) {
return $cache->data;
}
else {
$view = views_get_view('opigno_quizzes');
if (!empty($view->display['default']->display_options['title'])) {
$quiz_view_title = $view->display['default']->display_options['title'];
}
else {
$quiz_view_title = t("Quizzes");
}
cache_set('opigno_quiz_app:view_title:opigno_quizzes', $quiz_view_title, 'cache', CACHE_TEMPORARY);
return $quiz_view_title;
}
}
function opigno_quiz_app_get_course_quizzes($node) {
$quizzes =& drupal_static(__FUNCTION__);
if (!isset($quizzes[$node->nid])) {
$quizzes[$node->nid] = array();
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'quiz')
->fieldCondition('og_group_ref', 'target_id', $node->nid, '=')
->addMetaData('account', user_load(1));
$result = $query
->execute();
$temp = array();
if (!empty($result['node'])) {
foreach (array_keys($result['node']) as $quiz_nid) {
$temp[$quiz_nid] = opigno_quiz_app_get_course_quiz_weight($node->nid, $quiz_nid);
}
}
asort($temp);
$quizzes[$node->nid] = array_keys($temp);
}
return $quizzes[$node->nid];
}
function opigno_quiz_app_get_course_quiz_weight($gid, $nid) {
$weight = db_select('opigno_quiz_app_quiz_sort', 'w')
->fields('w', array(
'weight',
))
->condition('w.gid', $gid)
->condition('w.quiz_nid', $nid)
->execute()
->fetchField();
return empty($weight) ? 0 : $weight;
}
function opigno_quiz_app_set_course_quiz_weight($gid, $nid, $weight = 0) {
db_merge('opigno_quiz_app_quiz_sort')
->key(array(
'gid' => $gid,
'quiz_nid' => $nid,
))
->fields(array(
'gid' => $gid,
'quiz_nid' => $nid,
'weight' => $weight,
))
->execute();
}
function opigno_quiz_app_delete_course_quiz_weight($gid, $nid) {
db_delete('opigno_quiz_app_quiz_sort')
->condition('gid', $gid)
->condition('quiz_nid', $nid)
->execute();
}
function opigno_quiz_app_get_all_required_quizzes($node) {
$quizzes =& drupal_static(__FUNCTION__);
if (!isset($quizzes[$node->nid])) {
$quizzes[$node->nid] = array();
if (isset($node->course_required_quiz_ref[LANGUAGE_NONE])) {
foreach ($node->course_required_quiz_ref[LANGUAGE_NONE] as $item) {
$nody = node_load($item['target_id']);
if ($nody->type == "quiz") {
$nody = node_load($item['target_id']);
$quizzes[$node->nid][$item['target_id']] = node_load($item['target_id']);
}
}
}
}
return $quizzes[$node->nid];
}
function opigno_quiz_app_user_passed($nid, $uid) {
$cache =& drupal_static(__FUNCTION__);
if (!isset($cache["{$nid}:{$uid}"])) {
$cache["{$nid}:{$uid}"] = FALSE;
$node = node_load($nid);
if ($node->type == OPIGNO_COURSE_BUNDLE) {
$cache["{$nid}:{$uid}"] = TRUE;
$quizzes = opigno_quiz_app_get_all_required_quizzes($node);
$all_scores = quiz_get_score_data(array_keys($quizzes), $uid);
foreach ($all_scores as $score) {
if ($score->percent_pass > $score->percent_score) {
$cache["{$nid}:{$uid}"] = FALSE;
break;
}
}
if (module_exists('opigno_in_house_training_app')) {
$iht = opigno_in_house_get_all_required_iht($node);
foreach ($iht as $index => $rest) {
$value = opigno_in_house_training_score_form_get_default_value($index, $uid);
if ($value['status'] != 1) {
$cache["{$nid}:{$uid}"] = FALSE;
break;
}
}
}
if (module_exists('opigno_webex_app')) {
$webx = opigno_webex_app_get_all_required_quizzes($node);
foreach ($webx as $index => $rest) {
$value = opigno_webex_attendance_form_get_default_value($index, $uid);
if ($value['status'] != 1) {
$cache["{$nid}:{$uid}"] = FALSE;
break;
}
}
}
if (module_exists('opigno_live_meetings')) {
$meetings = opigno_live_meetings_get_all_required_meetings($node);
foreach ($meetings as $index => $rest) {
$value = opigno_live_meetings_score_get_db_values($index, $uid);
if ($value['status'] != 1) {
$cache["{$nid}:{$uid}"] = FALSE;
break;
}
}
}
}
}
if ($cache["{$nid}:{$uid}"]) {
if (module_exists('opigno_statistics_app')) {
$results = opigno_statistics_app_query_status_from_course_and_user($nid, $uid);
if (empty($results)) {
module_invoke_all('opigno_course_passed', $nid, $uid);
}
}
else {
module_invoke_all('opigno_course_passed', $nid, $uid);
}
}
return $cache["{$nid}:{$uid}"];
}
function opigno_quiz_app_get_course_data_result($uid, $nid, $filter_access = FALSE) {
$cache =& drupal_static(__FUNCTION__);
$filter_access = (int) $filter_access;
if (!isset($cache["{$nid}:{$uid}:{$filter_access}"])) {
$node = node_load($nid);
$quizzes = opigno_quiz_app_get_all_required_quizzes($node);
$final_score = 0;
$failed = OPIGNO_QUIZ_APP_PASSED;
$total_time = 0;
$count = 0;
if ($filter_access) {
$temp = array();
foreach ($quizzes as $quiz_nid => $quiz) {
if (opigno_quiz_app_access_node_teacher_results($node, $quiz)) {
$temp[$quiz_nid] = $quiz;
}
}
$quizzes = $temp;
}
if (empty($quizzes)) {
$cache["{$nid}:{$uid}:{$filter_access}"] = FALSE;
return FALSE;
}
$nids = array_keys($quizzes);
$all_scores = opigno_quiz_app_get_score_data($nids, $uid);
$quiz_total_time = array();
foreach ($all_scores as $quiz_nid => $results) {
foreach ($results as $rid => $score) {
if ($score->time_end != 0) {
if (!isset($quiz_total_time[$quiz_nid])) {
$quiz_total_time[$quiz_nid] = 0;
}
$total_time += $score->time_end - $score->time_start;
$quiz_total_time[$quiz_nid] += $score->time_end - $score->time_start;
}
}
}
$all_scores = quiz_get_score_data($nids, $uid);
foreach ($all_scores as $score) {
if (isset($quizzes[$score->nid])) {
$info['quizzes'][$quizzes[$score->nid]->title]['passed'] = isset($score->percent_score) ? $score->percent_score >= $score->percent_pass ? OPIGNO_QUIZ_APP_PASSED : OPIGNO_QUIZ_APP_FAILED : OPIGNO_QUIZ_APP_PENDING;
$info['quizzes'][$quizzes[$score->nid]->title]['score'] = isset($score->percent_score) ? $score->percent_score : NULL;
$info['quizzes'][$quizzes[$score->nid]->title]['total_time'] = isset($quiz_total_time[$score->nid]) ? $quiz_total_time[$score->nid] : NULL;
if (isset($score->percent_score) && isset($quizzes[$score->nid]->quiz_weight[LANGUAGE_NONE][0]['value'])) {
$final_score += $quizzes[$score->nid]->quiz_weight[LANGUAGE_NONE][0]['value'] * $score->percent_score;
$count += $quizzes[$score->nid]->quiz_weight[LANGUAGE_NONE][0]['value'];
}
elseif (isset($score->percent_score)) {
$final_score += $score->percent_score;
$count++;
}
else {
$failed = OPIGNO_QUIZ_APP_PENDING;
}
if ($failed !== OPIGNO_QUIZ_APP_PENDING && $failed !== OPIGNO_QUIZ_APP_FAILED && $score->percent_score < $score->percent_pass) {
$failed = OPIGNO_QUIZ_APP_FAILED;
}
}
}
if (module_exists('opigno_in_house_training_app')) {
$iht = opigno_in_house_get_all_required_iht($node);
foreach ($iht as $index => $rest) {
$value = opigno_in_house_training_score_form_get_default_value($index, $uid);
$info['iht'][$rest->title]['passed'] = OPIGNO_QUIZ_APP_PASSED;
$info['iht'][$rest->title]['score'] = t("Attended");
$info['iht'][$rest->title]['total_time'] = opigno_calendar_app_get_node_duration($rest);
if ($value['status'] != 1) {
$failed = OPIGNO_QUIZ_APP_FAILED;
$info['iht'][$rest->title]['passed'] = OPIGNO_QUIZ_APP_FAILED;
$info['iht'][$rest->title]['score'] = t("Absent");
$info['iht'][$rest->title]['total_time'] = 0;
}
$total_time += $info['iht'][$rest->title]['total_time'];
}
}
if (module_exists('opigno_live_meetings')) {
$meetings = opigno_live_meetings_get_all_required_meetings($node);
foreach ($meetings as $index => $rest) {
$value = opigno_live_meetings_score_get_db_values($index, $uid);
$info['live_meeting'][$rest->title]['passed'] = OPIGNO_QUIZ_APP_PASSED;
$info['live_meeting'][$rest->title]['score'] = t("Attended");
$info['live_meeting'][$rest->title]['total_time'] = opigno_calendar_app_get_node_duration($rest);
if ($value['status'] != 1) {
$failed = OPIGNO_QUIZ_APP_FAILED;
$info['live_meeting'][$rest->title]['passed'] = OPIGNO_QUIZ_APP_FAILED;
$info['live_meeting'][$rest->title]['score'] = t("Absent");
$info['live_meeting'][$rest->title]['total_time'] = 0;
}
$total_time += $info['live_meeting'][$rest->title]['total_time'];
}
}
if (module_exists('opigno_webex_app')) {
$webx = opigno_webex_app_get_all_required_quizzes($node);
foreach ($webx as $index => $rest) {
$value = opigno_webex_attendance_form_get_default_value($index, $uid);
$info['webx'][$rest->title]['passed'] = OPIGNO_QUIZ_APP_PASSED;
$info['webx'][$rest->title]['score'] = t("Attended");
$info['webx'][$rest->title]['total_time'] = opigno_calendar_app_get_node_duration($rest);
if ($value['status'] != 1) {
$failed = OPIGNO_QUIZ_APP_FAILED;
$info['webx'][$rest->title]['passed'] = OPIGNO_QUIZ_APP_FAILED;
$info['webx'][$rest->title]['score'] = t("Absent");
$info['webx'][$rest->title]['total_time'] = 0;
}
$total_time += $info['webx'][$rest->title]['total_time'];
}
}
if (empty($info['quizzes'])) {
$cache["{$nid}:{$uid}:{$filter_access}"] = FALSE;
return FALSE;
}
$info['passed'] = $failed;
$info['total_score'] = $count ? round($final_score / $count) : 0;
$info['total_time'] = $total_time;
$cache["{$nid}:{$uid}:{$filter_access}"] = $info;
}
return $cache["{$nid}:{$uid}:{$filter_access}"];
}
function opigno_quiz_get_score_data($nids, $uid) {
drupal_set_message('Called deprecated opigno_quiz_get_score_data(). Should be replaced with opigno_quiz_app_get_score_data()', 'warning');
if (function_exists('dpm')) {
dpm(debug_backtrace(), 'Callstack to deprecated opigno_quiz_get_score_data()');
}
return opigno_quiz_app_get_score_data($nids, $uid);
}
function opigno_quiz_app_get_score_data($nids, $uid) {
$scores = array();
$query = db_select('quiz_node_results', 'r');
$query
->leftJoin('quiz_node_properties', 'p', 'r.vid = p.vid');
$query
->addField('r', 'score', 'percent_score');
$query
->addField('p', 'pass_rate', 'percent_pass');
$result = $query
->fields('r', array(
'result_id',
'nid',
'time_start',
'time_end',
))
->condition('r.uid', $uid)
->condition('r.time_end', 0, '>')
->condition('r.nid', $nids, 'IN')
->execute();
while ($score = $result
->fetchObject()) {
$scores[$score->nid][$score->result_id] = $score;
}
return $scores;
}
function opigno_quiz_app_get_certificate($nid, $uid) {
$download_certificate = '';
if (function_exists('opigno_certificate_app_get_certificate_path')) {
$certificate_path = opigno_certificate_app_get_certificate_path($nid, $uid);
if ($certificate_path) {
$download_certificate = '<a href="' . url($certificate_path) . '" class="opigno-quiz-app-download-certificate opigno-certificate-app-download-certificate-link"><div class="d-inline-block">' . t("certificate") . '</div></a>';
}
else {
$download_certificate = '<span class="opigno-quiz-app-download-certificate"><div class="d-inline-block">' . t("certificate") . '</div></span>';
}
}
return $download_certificate;
}
function theme_opigno_quiz_app_user_results($vars) {
$html = '';
foreach ($vars['results'] as $course_info) {
$html .= theme('opigno_quiz_app_user_course_results', array(
'user' => $vars['user'],
'course_node' => $course_info['node'],
'course_results' => $course_info,
));
}
return $html;
}
function theme_opigno_quiz_app_user_course_results($vars) {
switch ($vars['course_results']['passed']) {
case OPIGNO_QUIZ_APP_PASSED:
$img_name = 'passed.jpg';
$status_text = t('Passed');
break;
case OPIGNO_QUIZ_APP_FAILED:
$img_name = 'failed.jpg';
$status_text = t('Failed');
break;
case OPIGNO_QUIZ_APP_PENDING:
default:
$img_name = 'pending.jpg';
$status_text = t('Pending');
break;
}
$download_certificate = opigno_quiz_app_get_certificate($vars['course_node']->nid, $vars['user']->uid);
$header = array(
0 => array(
'class' => array(
'opigno-quiz-app-course-status',
),
'colspan' => 4,
),
);
if (path_is_admin(current_path())) {
$detailspath = "/node/{$vars['course_node']->nid}/quiz-results/{$vars['user']->uid}";
$header[0]['data'] = t("@title (!status - <a href='!url'>see details</a>)", array(
'@title' => $vars['course_node']->title,
'!status' => $status_text,
'!url' => url($detailspath),
));
}
else {
if (!empty($vars['course_node']->nid)) {
$detailspath = "/node/{$vars['course_node']->nid}/my-quiz-results";
$header[0]['data'] = t("@title (!status - <a href='!url'>see details</a>)", array(
'@title' => $vars['course_node']->title,
'!status' => $status_text,
'!url' => url($detailspath),
));
}
else {
$header[0]['data'] = t("No required lessons for this course");
}
}
$result = '<div class="d-inline-block v-align-top mr-4"><img src="' . url(drupal_get_path('module', 'opigno_quiz_app') . '/img/' . $img_name) . '" alt="" /></div>';
$result .= '<div class="d-inline-block v-align-top"><div><strong>' . $status_text . '</strong></div>';
$result .= '<div>' . t('Score:') . ' ' . (isset($vars['course_results']['total_score']) ? $vars['course_results']['total_score'] : '-') . '%</div></div>';
$rows = array();
$rows[] = array(
'data' => array(
$result,
array(
'data' => '<div class="bar" style="width :' . (isset($vars['course_results']['total_score']) ? $vars['course_results']['total_score'] : 0) . '%"></div><div>' . (isset($vars['course_results']['total_score']) ? $vars['course_results']['total_score'] : '-') . '%</div>',
'class' => 'percent-bar text-center',
),
array(
'data' => isset($vars['course_results']['total_time']) ? gmdate('H:i:s', $vars['course_results']['total_time']) : '-',
'class' => 'global-time text-center',
),
array(
'data' => $download_certificate,
'class' => 'text-center',
),
),
'class' => array(
'header-row',
),
);
if (!empty($vars['course_results']['quizzes'])) {
foreach ($vars['course_results']['quizzes'] as $quiz_title => $score) {
$rows[] = array(
'data' => array(
check_plain($quiz_title),
array(
'data' => isset($score['score']) ? $score['score'] . '%' : '-',
'class' => 'text-right',
),
array(
'data' => isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
'class' => 'text-right',
),
array(
'data' => NULL,
'class' => 'text-right',
),
),
);
}
}
if (!empty($vars['course_results']['iht'])) {
foreach ($vars['course_results']['iht'] as $quiz_title => $score) {
$rows[] = array(
'data' => array(
check_plain($quiz_title),
array(
'data' => isset($score['score']) ? $score['score'] . '%' : '-',
'class' => 'text-right',
),
array(
'data' => isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
'class' => 'text-right',
),
array(
'data' => NULL,
'class' => 'text-right',
),
),
);
}
}
if (!empty($vars['course_results']['live_meeting'])) {
foreach ($vars['course_results']['live_meeting'] as $quiz_title => $score) {
$rows[] = array(
'data' => array(
check_plain($quiz_title),
array(
'data' => isset($score['score']) ? $score['score'] . '%' : '-',
'class' => 'text-right',
),
array(
'data' => isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
'class' => 'text-right',
),
array(
'data' => NULL,
'class' => 'text-right',
),
),
);
}
}
if (!empty($vars['course_results']['webx'])) {
foreach ($vars['course_results']['webx'] as $quiz_title => $score) {
$rows[] = array(
'data' => array(
check_plain($quiz_title),
array(
'data' => isset($score['score']) ? $score['score'] . '%' : '-',
'class' => 'text-right',
),
array(
'data' => isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
'class' => 'text-right',
),
array(
'data' => NULL,
'class' => 'text-right',
),
),
);
}
}
return theme('table', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'class' => array(
'opigno-quiz-app-results-table',
'opigno-quiz-app-results-collapsible-table',
'opigno-quiz-app-user-course-results-table',
),
),
));
}
function theme_opigno_quiz_app_course_results($vars) {
$html = '';
foreach ($vars['results'] as $results) {
$html .= theme('opigno_quiz_app_course_user_results', array(
'user' => $results['user'],
'course' => $vars['course'],
'results' => $results,
));
}
return $html;
}
function theme_opigno_quiz_app_course_user_results($vars) {
$download_certificate = opigno_quiz_app_get_certificate($vars['course']->nid, $vars['user']->uid);
$header = array(
array(
'data' => t("@name (!status)", array(
'@name' => $vars['user']->name,
'!status' => $vars['results']['passed'] == OPIGNO_QUIZ_APP_PASSED ? t("Passed") : ($vars['results']['passed'] == OPIGNO_QUIZ_APP_FAILED ? t("Failed") : t("Pending")),
)) . $download_certificate,
'class' => array(
'opigno-quiz-app-course-status',
'opigno-quiz-app-course-status-' . ($vars['results']['passed'] == OPIGNO_QUIZ_APP_PASSED ? 'passed' : ($vars['results']['passed'] == OPIGNO_QUIZ_APP_FAILED ? 'failed' : 'pending')),
),
),
array(
'data' => isset($vars['results']['total_score']) ? $vars['results']['total_score'] : '-',
'class' => array(
'opigno-quiz-app-course-total-score',
),
),
array(
'data' => isset($vars['results']['total_time']) ? gmdate('H:i:s', $vars['results']['total_time']) : '-',
'class' => array(
'opigno-quiz-app-course-total-time',
),
),
);
$rows = array();
if (!empty($vars['results']['quizzes'])) {
foreach ($vars['results']['quizzes'] as $quiz_title => $score) {
$rows[] = array(
'class' => array(
'opigno-quiz-app-quiz-result',
'opigno-quiz-app-quiz-result-' . ($score['passed'] == OPIGNO_QUIZ_APP_PASSED ? 'passed' : ($score['passed'] == OPIGNO_QUIZ_APP_FAILED ? 'failed' : 'pending')),
),
'data' => array(
check_plain($quiz_title),
isset($score['score']) ? $score['score'] : '-',
isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
),
);
}
}
if (!empty($vars['results']['iht'])) {
foreach ($vars['results']['iht'] as $quiz_title => $score) {
$rows[] = array(
'class' => array(
'opigno-quiz-app-quiz-result',
'opigno-quiz-app-quiz-result-' . ($score['passed'] == OPIGNO_QUIZ_APP_PASSED ? 'passed' : ($score['passed'] == OPIGNO_QUIZ_APP_FAILED ? 'failed' : 'pending')),
),
'data' => array(
check_plain($quiz_title),
isset($score['score']) ? $score['score'] : '-',
isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
),
);
}
}
if (!empty($vars['results']['live_meeting'])) {
foreach ($vars['results']['live_meeting'] as $quiz_title => $score) {
$rows[] = array(
'class' => array(
'opigno-quiz-app-quiz-result',
'opigno-quiz-app-quiz-result-' . ($score['passed'] == OPIGNO_QUIZ_APP_PASSED ? 'passed' : ($score['passed'] == OPIGNO_QUIZ_APP_FAILED ? 'failed' : 'pending')),
),
'data' => array(
check_plain($quiz_title),
isset($score['score']) ? $score['score'] : '-',
isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
),
);
}
}
if (!empty($vars['results']['webx'])) {
foreach ($vars['results']['webx'] as $quiz_title => $score) {
$rows[] = array(
'class' => array(
'opigno-quiz-app-quiz-result',
'opigno-quiz-app-quiz-result-' . ($score['passed'] == OPIGNO_QUIZ_APP_PASSED ? 'passed' : ($score['passed'] == OPIGNO_QUIZ_APP_FAILED ? 'failed' : 'pending')),
),
'data' => array(
check_plain($quiz_title),
isset($score['score']) ? $score['score'] : '-',
isset($score['total_time']) ? gmdate('H:i:s', $score['total_time']) : '-',
),
);
}
}
return theme('table', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'class' => array(
'opigno-quiz-app-results-table',
'opigno-quiz-app-results-collapsible-table',
'opigno-quiz-app-course-user-results-table',
),
),
));
}
function theme_opigno_quiz_app_sort_course_quizzes_form($vars) {
$form = $vars['form'];
drupal_add_tabledrag('opigno-quiz-app-sort-course-quizzes', 'order', 'sibling', 'opigno-quiz-app-sort-course-quizzes-weight');
$header = array(
function_exists('locale') ? locale(QUIZ_NAME) : QUIZ_NAME,
t("Weight"),
);
$rows = array();
foreach ($form['table'] as $key => $item) {
if (preg_match('/quiz_[0-9]+/', $key)) {
$data = array();
$data[] = drupal_render($item['title']) . drupal_render($item['nid']);
$data[] = drupal_render($item['weight']);
$rows[] = array(
'data' => $data,
'class' => array(
'draggable',
),
);
}
}
$form['table'] = array(
'#markup' => theme('table', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'id' => 'opigno-quiz-app-sort-course-quizzes',
),
)),
'#weight' => 1,
);
return drupal_render_children($form);
}
function _opigno_quiz_app_enable_fullscreen($node) {
$included =& drupal_static(__FUNCTION__);
if (empty($included)) {
drupal_add_library('system', 'jquery.cookie');
$path = drupal_get_path('module', 'opigno_quiz_app');
drupal_add_css("{$path}/css/opigno_quiz_app.css");
drupal_add_js("{$path}/js/opigno_quiz_app.fullscreen.js");
$included = TRUE;
}
drupal_add_js(array(
'opignoQuizApp' => array(
'fullScreen' => array(
array(
'nid' => $node->nid,
),
),
),
), 'setting');
}
function opigno_quiz_app_is_node_add_question() {
static $result;
if (!isset($result)) {
$question_types = opigno_quiz_app_get_quiz_question_types();
$result = preg_match('/^node\\/add\\/(' . str_replace('_', '-', implode('|', $question_types)) . ')$/', current_path());
}
return $result;
}
function opigno_quiz_app_get_quiz_question_types() {
static $types;
if (!isset($types)) {
$types = array_keys(_quiz_question_get_implementations());
}
return $types;
}
function opigno_quiz_app_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == "quiz_node_form" && isset($form['type']['#value']) && $form['type']['#value'] == "quiz") {
$form['field_add_to_calendar']['#parent'] = 'quiz_availability';
$form['opigno_calendar_date']['#parent'] = 'quiz_availability';
$form['opigno_calendar_date']['#states'] = array(
'invisible' => array(
'#edit-field-add-to-calendar-und' => array(
'checked' => FALSE,
),
),
);
$form['quiz_availability']['field_add_to_calendar'] = $form['field_add_to_calendar'];
$form['quiz_availability']['opigno_calendar_date'] = $form['opigno_calendar_date'];
$form['#submit'][] = 'opigno_quiz_app_unset_opigno_calendar_date';
unset($form['field_add_to_calendar']);
unset($form['opigno_calendar_date']);
$form['#validate'][] = "opigno_quiz_app_check_questions_for_type";
}
elseif ($form_id == 'quiz_question_answering_form') {
if (isset($form['question_nid'])) {
$q_node = node_load($form['question_nid']['#value']);
if ($q_node->type === 'quiz_drag_drop') {
$form['#attached']['js'][] = drupal_get_path('module', 'opigno_quiz_app') . '/js/jquery.ui.touch-punch.min.js';
}
}
$form['is_doubtful']['#weight'] = 49;
$form['navigation']['#weight'] = 50;
if (!user_is_logged_in()) {
if (isset($form['#attributes']['data-confirm-message'])) {
unset($form['navigation']['submit']);
unset($form['navigation']['op']);
}
}
$path = drupal_get_path('module', 'opigno_quiz_app');
drupal_add_js("{$path}/js/opigno_quiz_app.js");
}
}
function opigno_quiz_app_check_questions_for_type($form, &$form_state) {
if (isset($form_state['values']['quiz_type'][LANGUAGE_NONE][0]['value']) && isset($form_state['values']['nid']) && isset($form_state['values']['vid'])) {
switch ($form_state['values']['quiz_type'][LANGUAGE_NONE][0]['value']) {
case 'quiz':
$quiz_questions = quiz_get_questions($form_state['values']['nid'], $form_state['values']['vid'], TRUE, TRUE, TRUE, TRUE);
foreach ($quiz_questions as $index => $value) {
if ($value->type == "quiz_directions") {
form_set_error('quiz_type', t('You cannot set this lesson as quiz type, remove all slides questions first.'));
}
}
break;
case "theory":
$quiz_questions = quiz_get_questions($form_state['values']['nid'], $form_state['values']['vid'], TRUE, TRUE, TRUE, TRUE);
foreach ($quiz_questions as $index => $value) {
if ($value->type != "quiz_directions") {
form_set_error('quiz_type', t('You cannot set this lesson as theory type, remove all non slides questions first.'));
}
}
break;
case "mix":
break;
}
}
}
function opigno_quiz_app_unset_opigno_calendar_date($form, &$form_state) {
if ($form_state['values']['field_add_to_calendar'][LANGUAGE_NONE][0]['value'] == 0) {
$form_state['values']['opigno_calendar_date'][LANGUAGE_NONE][0]['value'] = NULL;
$form_state['values']['opigno_calendar_date'][LANGUAGE_NONE][0]['value2'] = NULL;
$form_state['values']['opigno_calendar_date'][LANGUAGE_NONE][0]['timezone'] = NULL;
$form_state['values']['opigno_calendar_date'][LANGUAGE_NONE][0]['offset'] = NULL;
$form_state['values']['opigno_calendar_date'][LANGUAGE_NONE][0]['offset2'] = NULL;
$form_state['values']['opigno_calendar_date'][LANGUAGE_NONE][0]['rrule'] = NULL;
}
}
function opigno_quiz_app_preprocess_page(&$vars) {
$group = og_context('node');
if (!empty($group['gid'])) {
$class_context = NULL;
$node = node_load($group['gid']);
if ($node->type == "course") {
global $user;
if (module_exists("opigno_class_app")) {
$classes = opigno_class_app_classes_of_course_that_user_is_part_of($node->nid, $user->uid);
if ($classes) {
$class = key($classes);
$node = node_load($class);
}
else {
$vars['group_state']['course'][$node->nid]['quiz'] = opigno_quiz_app_course_lessons_progress_and_time($group['gid']);
return;
}
}
else {
$vars['group_state']['course'][$node->nid]['quiz'] = opigno_quiz_app_course_lessons_progress_and_time($group['gid']);
}
}
if ($node->type == "class") {
if (isset($node->opigno_class_courses[LANGUAGE_NONE])) {
foreach ($node->opigno_class_courses[LANGUAGE_NONE] as $cindex => $course) {
$vars['group_state']['course'][$course['target_id']]['quiz'] = opigno_quiz_app_course_lessons_progress_and_time($course['target_id']);
if (module_exists("opigno_sort_groups")) {
$vars['group_state']['course'][$course['target_id']]['weight'] = opigno_sort_groups_get_groups_weight($node->nid, $course['target_id']);
}
}
}
}
}
if (isset($vars['node']) && $vars['node']->type == "quiz") {
if (user_is_logged_in()) {
$lesson_id = opigno_quiz_app_is_quiz_path(current_path());
if ($lesson_id) {
global $user;
$lesson = node_load($lesson_id);
$courses_field = field_get_items('node', $lesson, 'og_group_ref');
if ($courses_field) {
foreach ($courses_field as $index => $target_id) {
if (isset($_SESSION['quiz_' . $lesson_id]['result_id'])) {
opigno_quiz_app_course_last_viewed($target_id['target_id'], $lesson_id, $_SESSION['quiz_' . $lesson_id]['result_id'], $user->uid);
}
}
}
}
}
}
}
function opigno_quiz_app_is_quiz_path($path) {
$menu_item = menu_get_item($path);
if (isset($menu_item['path']) && $menu_item['path'] === 'node/%/take') {
return $menu_item['original_map'][1];
}
return FALSE;
}
function opigno_quiz_app_course_lessons($course_nid) {
global $user;
$lessons = array();
$query = db_select('node', 'n')
->fields('n', array(
'nid',
'title',
'vid',
))
->condition('n.status', 1, '=')
->condition('n.type', 'quiz', '=');
$query
->join('og_membership', 'og_m', 'og_m.etid = n.nid');
$query
->fields('og_m', array(
'gid',
))
->condition('og_m.gid', $course_nid, '=')
->condition('og_m.field_name', 'og_group_ref', '=')
->condition('og_m.state', 1, '=')
->condition('og_m.entity_type', 'node', '=');
$result = $query
->execute();
if (opigno_quiz_app_course_has_been_sorted($result, $course_nid)) {
$query
->join('opigno_quiz_app_quiz_sort', 'oqs', 'oqs.quiz_nid = n.nid');
$query
->fields('oqs', array(
'weight',
))
->condition('oqs.gid', $course_nid, '=')
->orderBy('oqs.weight', 'ASC');
}
$result = $query
->execute();
while ($record = $result
->fetchAssoc()) {
if ($router_item = menu_get_item('node/' . $record['nid'])) {
if ($router_item['access']) {
$lessons[$course_nid][$record['nid']]['vid'] = $record['vid'];
}
}
}
return $lessons;
}
function opigno_quiz_app_course_lessons_progress_and_time($course_nid, $account = NULL) {
if ($account == NULL) {
global $user;
$account = $user;
$uid = $account->uid;
}
$lessons = opigno_quiz_app_course_lessons($course_nid);
$lessons_ = array();
foreach ($lessons as $course_nid => $quizs) {
foreach ($quizs as $quiz_id => $quiz) {
$score = quiz_get_score_data(array(
$quiz_id,
), $uid);
$lessons_[$course_nid][$quiz['vid']] = $score[$quiz['vid']];
$total_time = 0;
$all_scores = opigno_quiz_app_get_score_data(array(
$quiz_id,
), $uid);
foreach ($all_scores as $quiz_nid => $results) {
foreach ($results as $rid => $score) {
if ($score->time_end != 0) {
if (!isset($quiz_total_time[$quiz_nid])) {
$quiz_total_time[$quiz_nid] = 0;
}
$total_time += $score->time_end - $score->time_start;
$quiz_total_time[$quiz_nid] += $score->time_end - $score->time_start;
}
}
}
$lessons_[$course_nid][$quiz['vid']]->total_time = $total_time;
}
}
$displayinfo = array();
$displayinfo['courses'] = $lessons_;
if (!empty($lessons_)) {
return theme_opigno_quiz_app_course_lessons($displayinfo);
}
}
function theme_opigno_quiz_app_course_lessons($vars) {
$rows = array();
if (!empty($vars['courses'])) {
foreach ($vars['courses'] as $course_id => $lessons) {
foreach ($lessons as $lesson_id => $lesson) {
$selected = "";
if (strpos(current_path(), 'node/' . $lesson->nid) !== false) {
$selected = "selected";
}
$rows[] = array(
'class' => array(),
'data' => array(
l($lesson->title, 'node/' . $lesson->nid . '/take', array(
'attributes' => array(
'class' => array(
$selected,
),
),
)),
isset($lesson->percent_score) ? '<div class="opigno-quiz-app-group-status-quiz-result-' . ($lesson->percent_score >= $lesson->percent_pass ? "passed" : "failed") . '">' . $lesson->percent_score . '<div>' : '-',
isset($lesson->total_time) && $lesson->total_time > 0 ? gmdate('H:i:s', $lesson->total_time) : '-',
),
);
}
}
}
$header = array(
array(
'data' => t('Lessons'),
'class' => array(
'opigno-quiz-app-course-name',
),
),
array(
'data' => t('Score'),
'class' => array(
'opigno-quiz-app-course-total-score',
),
),
array(
'data' => t('Total Time'),
'class' => array(
'opigno-quiz-app-course-total-time',
),
),
);
return theme('table', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'class' => array(),
),
));
}
function opigno_quiz_app_course_has_been_sorted($result, $course_nid) {
while ($record = $result
->fetchAssoc()) {
$query = db_select('opigno_quiz_app_quiz_sort', 'oqs')
->fields('oqs')
->condition('oqs.gid', $course_nid, '=')
->condition('oqs.quiz_nid', $record['nid'], '=');
$result = $query
->execute();
if (!($record = $result
->fetchAssoc())) {
return false;
}
}
return true;
}
function opigno_quiz_app_theme_registry_alter(&$theme_registry) {
if (isset($theme_registry['quiz_no_feedback'])) {
$theme_registry['quiz_no_feedback']['function'] = 'theme_opigno_quiz_no_feedback';
}
if (isset($theme_registry['quiz_take_summary'])) {
$theme_registry['quiz_take_summary']['function'] = 'theme_opigno_quiz_take_summary';
}
}
function theme_opigno_quiz_no_feedback() {
return t('Thank you for taking the lesson!');
}
function theme_opigno_quiz_take_summary($variables) {
$quiz = $variables['quiz'];
$questions = $variables['questions'];
$score = $variables['score'];
$summary = $variables['summary'];
$rid = $variables['rid'];
drupal_set_title($quiz->title);
$output = '';
if (!empty($score['possible_score'])) {
if (!$score['is_evaluated']) {
if (user_access('score taken quiz answer')) {
$msg = t('Parts of this @quiz have not been evaluated yet. The score below is not final. <a class="self-score" href="!result_url">Click here</a> to give scores on your own.', array(
'@quiz' => QUIZ_NAME,
'!result_url' => url('node/' . $quiz->nid . '/results/' . $rid),
));
}
else {
$msg = t('Parts of this @quiz have not been evaluated yet. The score below is not final.', array(
'@quiz' => QUIZ_NAME,
));
}
drupal_set_message($msg, 'warning');
}
$output .= '<div id="quiz_score_possible">' . t('You got %num_correct of %question_count possible points.', array(
'%num_correct' => $score['numeric_score'],
'%question_count' => $score['possible_score'],
)) . '</div>' . "\n";
$output .= '<div id="quiz_score_percent">' . t('Your score: %score %', array(
'%score' => $score['percentage_score'],
)) . '</div>' . "\n";
}
if (isset($summary['passfail'])) {
$output .= '<div id="quiz_summary">' . $summary['passfail'] . '</div>' . "\n";
}
if (isset($summary['result'])) {
$output .= '<div id="quiz_summary">' . $summary['result'] . '</div>' . "\n";
}
if ($quiz->display_feedback) {
$form = drupal_get_form('quiz_report_form', $questions);
$output .= drupal_render($form);
}
$group = og_context('node');
$nextlink = "";
if (!empty($group['gid'])) {
global $user;
$course_nid = $group['gid'];
$classes = opigno_class_app_classes_of_course_that_user_is_part_of($group['gid'], $user->uid);
if (!empty($classes)) {
$class = key($classes);
$group = node_load($class);
}
else {
$group = node_load($group['gid']);
}
$continue = opigno_quiz_app_get_next_lesson_from_course($course_nid, $quiz->nid);
if (isset($continue)) {
$nextlink = l(t("To next lesson"), "node/" . $continue . "/take", array(
'attributes' => array(
'class' => array(
'opigno-quiz-action',
'action-element',
),
),
));
}
else {
$nextlink = l(t("Back to @type", array(
'@type' => $group->type,
)), "node/" . $group->nid, array(
'attributes' => array(
'class' => array(
'opigno-quiz-action',
'action-element',
),
),
));
}
}
return $output . '<div id="nextlink">' . $nextlink . '</div>';
}
function opigno_quiz_app_views_query_alter(&$view, &$query) {
if ($view->name == "opigno_quiz_student_course_results" && $view->current_display == "page_1" || $view->name == "opigno_quiz_student_views" && $view->current_display == "page_1") {
if (isset($query->table_queue['quiz_node_results']['join']->left_table)) {
$query->table_queue['quiz_node_results']['join']->left_field = "nid";
$query->table_queue['quiz_node_results']['join']->field = "nid";
$query->table_queue['quiz_node_results']['join']->definition['left_field'] = "nid";
$query->table_queue['quiz_node_results']['join']->definition['field'] = "nid";
}
}
}
function opigno_quiz_app_init() {
if (user_is_logged_in()) {
$page_node = menu_get_object();
if (isset($page_node->type) && $page_node->type == "quiz") {
if (isset($page_node->og_group_ref['und'][0]['target_id'])) {
global $user;
foreach ($page_node->og_group_ref[LANGUAGE_NONE] as $group) {
if (og_is_member("node", $group['target_id'], 'user', $user, $states = array(
OG_STATE_ACTIVE,
))) {
opigno_db_insert_group_activity($group['target_id'], $user->uid);
if (module_exists("opigno_class_app")) {
$classes = opigno_class_app_classes_of_course_that_user_is_part_of($group['target_id'], $user->uid);
foreach ($classes as $class) {
opigno_db_insert_group_activity($class, $user->uid);
}
}
}
}
}
}
}
}
function opigno_quiz_get_continue_group($node) {
global $user;
if ($node->type == "class") {
$courses = opigno_class_app_get_class_courses($node);
foreach ($courses as $course) {
$course = node_load($course);
$quiz_to_continue = opigno_quiz_get_continue_course($course, $user->uid);
if (!empty($quiz_to_continue)) {
return $quiz_to_continue;
}
}
}
elseif ($node->type == "course") {
return opigno_quiz_get_continue_course($node, $user->uid);
}
return null;
}
function opigno_quiz_get_continue_course($node, $uid) {
$lessons = opigno_quiz_app_course_lessons($node->nid);
if (!empty($lessons[$node->nid])) {
$lessons_ids = array_keys($lessons[$node->nid]);
foreach ($lessons_ids as $lesson_id) {
$results = quiz_get_score_data(array(
$lesson_id,
), $uid, FALSE);
foreach ($results as $score) {
if ($score->percent_pass > $score->percent_score) {
return $lesson_id;
}
}
}
}
return NULL;
}
function opigno_quiz_app_get_first_lesson_from_group($node) {
if (!empty($node->type) && $node->type == 'class') {
$courses_nids = opigno_class_app_get_class_courses($node);
if (empty($courses_nids)) {
return NULL;
}
$nid = $courses_nids[0];
}
else {
$nid = $node->nid;
}
$lessons = opigno_quiz_app_course_lessons($nid);
if (empty($lessons[$nid])) {
return null;
}
$lessons_ids = array_keys($lessons[$nid]);
return empty($lessons_ids[0]) ? null : $lessons_ids[0];
}
function opigno_quiz_app_get_next_lesson_from_course($course_nid, $current_lesson_nid) {
$lessons = opigno_quiz_app_course_lessons($course_nid);
if (empty($lessons[$course_nid])) {
return NULL;
}
$return_next_lesson = false;
foreach ($lessons[$course_nid] as $lesson_nid => $lesson_vid) {
if ($return_next_lesson) {
return $lesson_nid;
}
if ($lesson_nid == $current_lesson_nid) {
$return_next_lesson = true;
}
}
return NULL;
}
function opigno_quiz_app_get_course_class_progression($group_nid, $uid = null) {
$node = node_load($group_nid);
switch ($node->type) {
case 'class':
return opigno_quiz_app_get_class_progression($group_nid, $uid);
case 'course':
return opigno_quiz_app_get_course_progression($group_nid, $uid);
default:
return 0;
}
}
function opigno_quiz_app_get_course_progression($course_nid, $uid = null) {
if ($uid === null) {
global $user;
$uid = $user->uid;
}
$course = node_load($course_nid);
$quizzes_nids = opigno_quiz_app_get_course_quizzes($course);
$scores = quiz_get_score_data($quizzes_nids, $uid);
$passed_lessons = 0;
$total_lessons = count($quizzes_nids);
foreach ($scores as $score) {
if ($score->percent_score >= $score->percent_pass) {
$passed_lessons++;
}
}
if ($total_lessons == 0) {
return 100;
}
else {
return round($passed_lessons * 100 / $total_lessons);
}
}
function opigno_quiz_app_get_class_progression($class_nid, $uid = null) {
if ($uid === null) {
global $user;
$uid = $user->uid;
}
$class = node_load($class_nid);
if (empty($class->opigno_class_courses['und'])) {
return 100;
}
$courses_total_progression = 0;
$nb_courses = 0;
foreach ($class->opigno_class_courses['und'] as $course_value_raw) {
$course_nid = $course_value_raw['target_id'];
$courses_total_progression += opigno_quiz_app_get_course_progression($course_nid, $uid);
$nb_courses++;
}
if ($nb_courses == 0) {
return 100;
}
else {
return round($courses_total_progression / $nb_courses);
}
}
function opigno_quiz_app_get_course_class_score_average($node_nid, $uid = null) {
if ($uid === null) {
global $user;
$uid = $user->uid;
}
$node = node_load($node_nid);
if ($node->type == 'class') {
if (empty($node->opigno_class_courses[LANGUAGE_NONE])) {
return 0;
}
$courses_nids = array_map(function ($entry) {
return $entry['target_id'];
}, $node->opigno_class_courses[LANGUAGE_NONE]);
}
else {
if ($node->type == 'course') {
$courses_nids = array(
$node_nid,
);
}
else {
return 0;
}
}
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'node');
$query
->propertyCondition('type', 'quiz');
$query
->fieldCondition('og_group_ref', 'target_id', $courses_nids);
$lessons_nids = $query
->execute();
if (empty($lessons_nids)) {
return 0;
}
$lessons_nids = array_keys($lessons_nids['node']);
$scores = quiz_get_score_data($lessons_nids, $uid);
$nb_quizzes_done = 0;
$total_score = 0;
foreach ($scores as $score) {
if ($score->percent_score === null) {
continue;
}
$total_score += $score->percent_score;
$nb_quizzes_done++;
}
return $nb_quizzes_done == 0 ? 0 : round($total_score / $nb_quizzes_done);
}
function opigno_quiz_app_course_class_passed($nid, $uid = null) {
if ($uid === null) {
global $user;
$uid = $user->uid;
}
$node = node_load($nid);
switch ($node->type) {
case 'class':
if (empty($node->opigno_class_courses[LANGUAGE_NONE])) {
return true;
}
$courses_nids = array_map(function ($entry) {
return $entry['target_id'];
}, $node->opigno_class_courses[LANGUAGE_NONE]);
break;
case 'course':
$courses_nids = array(
$nid,
);
break;
default:
return false;
}
foreach ($courses_nids as $course_nid) {
if (!opigno_quiz_app_user_passed($course_nid, $uid)) {
return false;
}
}
return true;
}
function opigno_quiz_app_course_is_started($node_nid, $uid = null) {
if ($uid === null) {
global $user;
$uid = $user->uid;
}
$last_viewed_lesson_in_course = opigno_quiz_app_course_get_last_viewed($node_nid, $uid);
if (!$last_viewed_lesson_in_course) {
return false;
}
$last_viewed_lesson_in_course_result = $last_viewed_lesson_in_course['result_id'];
$last_viewed_lesson_in_course = $last_viewed_lesson_in_course['quiz_nid'];
if (!opigno_quiz_app_user_finished_quiz_result($last_viewed_lesson_in_course, $last_viewed_lesson_in_course_result, $uid)) {
return true;
}
$lessons = opigno_quiz_app_course_lessons($node_nid);
if (isset($lessons[$node_nid])) {
$current_position = array_search($last_viewed_lesson_in_course, array_keys($lessons[$node_nid]));
if ($current_position == count($lessons[$node_nid]) - 1) {
return false;
}
else {
return true;
}
}
return false;
}