2007-10-30 22:31:13 +00:00
|
|
|
<?php
|
|
|
|
|
2007-11-29 02:56:10 +00:00
|
|
|
// Bolt scheduler. GET args:
|
2007-10-30 22:31:13 +00:00
|
|
|
// course_id: course ID
|
|
|
|
// action:
|
2007-11-29 02:56:10 +00:00
|
|
|
// 'start' or none: show current (or first) item,
|
|
|
|
// and prompt for user info if any missing
|
2007-10-30 22:31:13 +00:00
|
|
|
// 'next': go to next lesson
|
|
|
|
// answers:
|
|
|
|
// JSON represenation of exercise answers
|
|
|
|
|
|
|
|
require_once("../inc/bolt.inc");
|
|
|
|
require_once("../inc/bolt_db.inc");
|
2007-11-29 23:26:49 +00:00
|
|
|
require_once("../inc/bolt_ex.inc");
|
2007-12-07 23:23:25 +00:00
|
|
|
require_once("../inc/bolt_util.inc");
|
2007-10-30 22:31:13 +00:00
|
|
|
require_once("../inc/util.inc");
|
|
|
|
|
|
|
|
$user = get_logged_in_user();
|
2007-11-29 02:56:10 +00:00
|
|
|
BoltUser::lookup($user);
|
2007-10-30 22:31:13 +00:00
|
|
|
$course_id = get_int('course_id');
|
|
|
|
$view_id = get_int('view_id', true);
|
|
|
|
$action = get_str('action', true);
|
|
|
|
|
|
|
|
$course = BoltCourse::lookup_id($course_id);
|
|
|
|
if (!$course) {
|
|
|
|
error_page("no such course");
|
|
|
|
}
|
|
|
|
|
2007-11-29 23:26:49 +00:00
|
|
|
function update_info() {
|
2007-12-18 20:28:08 +00:00
|
|
|
global $user;
|
2007-11-29 02:56:10 +00:00
|
|
|
$sex = get_int('sex');
|
|
|
|
$birth_year = get_int('birth_year');
|
|
|
|
$user->bolt->update("sex=$sex, birth_year=$birth_year");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-30 22:31:13 +00:00
|
|
|
$course_doc = require_once($course->doc_file);
|
|
|
|
|
2007-12-07 23:23:25 +00:00
|
|
|
function finalize_view($user, $view_id, $action) {
|
2007-11-29 23:26:49 +00:00
|
|
|
if (!$view_id) return null;
|
2007-10-30 22:31:13 +00:00
|
|
|
$view = BoltView::lookup_id($view_id);
|
2007-12-18 20:28:08 +00:00
|
|
|
if (!$view) {
|
|
|
|
error_page("no view");
|
|
|
|
}
|
|
|
|
if ($view->user_id != $user->id) {
|
|
|
|
error_page("wrong user");
|
|
|
|
}
|
|
|
|
if (!$view->end_time) {
|
2007-10-30 22:31:13 +00:00
|
|
|
$now = time();
|
2007-12-07 23:23:25 +00:00
|
|
|
$view->update("end_time=$now, action=$action");
|
2007-10-30 22:31:13 +00:00
|
|
|
}
|
2007-12-18 20:28:08 +00:00
|
|
|
return $view;
|
2007-10-30 22:31:13 +00:00
|
|
|
}
|
|
|
|
|
2007-12-07 23:23:25 +00:00
|
|
|
function default_mode($item) {
|
|
|
|
return $item->is_exercise()?BOLT_MODE_SHOW:BOLT_MODE_LESSON;
|
|
|
|
}
|
2007-10-30 22:31:13 +00:00
|
|
|
|
2007-12-18 20:28:08 +00:00
|
|
|
function create_view($user, $course, $iter, $mode, $prev_view_id) {
|
2007-11-29 02:56:10 +00:00
|
|
|
$now = time();
|
2007-12-12 04:43:04 +00:00
|
|
|
$item = $iter->item;
|
2007-12-18 21:48:36 +00:00
|
|
|
if (!$item) {
|
|
|
|
$item = null;
|
|
|
|
$item->name = '--end--';
|
|
|
|
}
|
2007-12-04 22:16:37 +00:00
|
|
|
$state = $iter->encode_state();
|
2007-12-18 20:28:08 +00:00
|
|
|
return BoltView::insert("(user_id, course_id, item_name, start_time, mode, state, fraction_done, prev_view_id) values ($user->id, $course->id, '$item->name', $now, $mode, '$state', $iter->frac_done, $prev_view_id)");
|
2007-10-30 22:31:13 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 21:48:36 +00:00
|
|
|
function show_finished_page($course, $view_id, $prev_view_id) {
|
|
|
|
page_head(null);
|
|
|
|
if (function_exists('bolt_header')) bolt_header("Course completed");
|
|
|
|
echo "Congratulation - you have completed this course.";
|
|
|
|
$prev = "<a href=bolt_sched.php?course_id=$course->id&action=prev&view_id=$view_id><< Prev</a>";
|
|
|
|
echo "
|
|
|
|
<p>
|
|
|
|
<center>
|
|
|
|
<table width=60%><tr>
|
|
|
|
<td width=33% align=left>$prev</td>
|
|
|
|
<td width=33% align=center><a href=bolt.php>Up</a></td>
|
|
|
|
<td width=33% align=right></td>
|
|
|
|
</table>
|
|
|
|
</center>
|
|
|
|
";
|
|
|
|
if (function_exists('bolt_footer')) bolt_footer();
|
|
|
|
}
|
|
|
|
|
2007-12-18 20:28:08 +00:00
|
|
|
function show_item($iter, $user, $course, $view_id, $prev_view_id, $mode) {
|
2007-12-07 23:23:25 +00:00
|
|
|
global $bolt_ex_mode;
|
|
|
|
global $bolt_ex_index;
|
2007-12-18 20:28:08 +00:00
|
|
|
global $bolt_ex_score;
|
2007-12-07 23:23:25 +00:00
|
|
|
|
2007-12-12 04:43:04 +00:00
|
|
|
$item = $iter->item;
|
2007-12-18 20:28:08 +00:00
|
|
|
page_head(null);
|
2007-12-18 21:48:36 +00:00
|
|
|
if (function_exists('bolt_header')) bolt_header($item->title);
|
2007-12-18 20:28:08 +00:00
|
|
|
|
2007-12-18 21:48:36 +00:00
|
|
|
if ($item->is_exercise()) {
|
2007-12-07 23:23:25 +00:00
|
|
|
$bolt_ex_mode = $mode;
|
2007-11-29 23:26:49 +00:00
|
|
|
$bolt_ex_index = 0;
|
2007-12-07 23:23:25 +00:00
|
|
|
switch ($mode) {
|
|
|
|
case BOLT_MODE_SHOW:
|
|
|
|
echo "
|
|
|
|
<form action=bolt_sched.php>
|
|
|
|
<input type=hidden name=view_id value=$view_id>
|
|
|
|
<input type=hidden name=course_id value=$course->id>
|
|
|
|
<input type=hidden name=action value=answer>
|
|
|
|
";
|
|
|
|
srand($view_id);
|
|
|
|
require($item->filename);
|
2007-12-18 20:28:08 +00:00
|
|
|
if (function_exists('bolt_divide')) bolt_divide();
|
|
|
|
$next = "<input type=submit value=OK></form>";
|
2007-12-07 23:23:25 +00:00
|
|
|
break;
|
|
|
|
case BOLT_MODE_ANSWER:
|
|
|
|
require($item->filename);
|
2007-12-18 20:28:08 +00:00
|
|
|
if (function_exists('bolt_divide')) bolt_divide();
|
|
|
|
$next = "<a href=bolt_sched.php?course_id=$course->id&action=next&view_id=$view_id>Next >></a>";
|
|
|
|
$score_pct = number_format($bolt_ex_score*100);
|
|
|
|
echo "Score: $score_pct%";
|
2007-12-07 23:23:25 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-12-18 21:48:36 +00:00
|
|
|
} else {
|
2007-11-29 23:26:49 +00:00
|
|
|
require_once($item->filename);
|
2007-12-18 20:28:08 +00:00
|
|
|
if (function_exists('bolt_divide')) bolt_divide();
|
|
|
|
$next = "<a href=bolt_sched.php?course_id=$course->id&action=next&view_id=$view_id>Next >></a>";
|
2007-11-29 23:26:49 +00:00
|
|
|
}
|
2007-10-30 22:31:13 +00:00
|
|
|
|
2007-12-18 20:28:08 +00:00
|
|
|
if ($prev_view_id) {
|
|
|
|
$prev = "<a href=bolt_sched.php?course_id=$course->id&action=prev&view_id=$view_id><< Prev</a>";
|
|
|
|
} else {
|
|
|
|
$prev = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "
|
|
|
|
<p>
|
|
|
|
<center>
|
|
|
|
<table width=60%><tr>
|
|
|
|
<td width=33% align=left>$prev</td>
|
|
|
|
<td width=33% align=center><a href=bolt.php>Up</a></td>
|
|
|
|
<td width=33% align=right>$next</td>
|
|
|
|
</table>
|
|
|
|
</center>
|
2007-12-07 23:23:25 +00:00
|
|
|
";
|
2007-12-18 20:28:08 +00:00
|
|
|
if (function_exists('bolt_footer')) bolt_footer();
|
|
|
|
|
|
|
|
$e = new BoltEnrollment();
|
|
|
|
$e->user_id = $user->id;
|
|
|
|
$e->course_id = $course->id;
|
|
|
|
$e->update("last_view_id=$view_id");
|
2007-12-07 23:23:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function start_course($user, $course, $course_doc) {
|
|
|
|
BoltEnrollment::delete($user->id, $course->id);
|
|
|
|
$iter = new BoltIter($course_doc);
|
|
|
|
$iter->at();
|
|
|
|
|
|
|
|
$now = time();
|
|
|
|
$mode = default_mode($iter->item);
|
2007-12-18 20:28:08 +00:00
|
|
|
$view_id = create_view($user, $course, $iter, $mode, 0);
|
2007-12-12 04:43:04 +00:00
|
|
|
BoltEnrollment::insert("(create_time, user_id, course_id, last_view_id) values ($now, $user->id, $course->id, $view_id)");
|
2007-12-18 20:28:08 +00:00
|
|
|
show_item($iter, $user, $course, $view_id, 0, $mode);
|
2007-11-29 23:26:49 +00:00
|
|
|
}
|
|
|
|
|
2007-12-04 22:16:37 +00:00
|
|
|
$e = BoltEnrollment::lookup($user->id, $course_id);
|
2007-11-29 23:26:49 +00:00
|
|
|
switch ($action) {
|
|
|
|
case 'start':
|
|
|
|
if (info_incomplete($user)) {
|
|
|
|
request_info($user, $course);
|
|
|
|
exit();
|
|
|
|
}
|
2007-12-04 22:16:37 +00:00
|
|
|
if ($e) {
|
|
|
|
page_head("Confirm start");
|
|
|
|
echo "You are already enrolled in $course->name.
|
|
|
|
Are you sure you want to start from the beginning?
|
|
|
|
";
|
|
|
|
show_button(
|
|
|
|
"bolt_sched.php?action=start_confirm&course_id=$course->id",
|
|
|
|
"Yes",
|
|
|
|
"Start this course from the beginning"
|
|
|
|
);
|
|
|
|
page_tail();
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
case 'start_confirm':
|
2007-11-29 23:26:49 +00:00
|
|
|
start_course($user, $course, $course_doc);
|
|
|
|
break;
|
|
|
|
case 'update_info':
|
|
|
|
update_info();
|
|
|
|
start_course($user, $course, $course_doc);
|
2007-12-12 04:43:04 +00:00
|
|
|
case 'prev':
|
2007-12-18 20:28:08 +00:00
|
|
|
$view = finalize_view($user, $view_id, BOLT_ACTION_PREV);
|
|
|
|
if ($view->prev_view_id) {
|
|
|
|
$view = BoltView::lookup_id($view->prev_view_id);
|
|
|
|
$iter = new BoltIter($course_doc);
|
|
|
|
$iter->decode_state($view->state);
|
|
|
|
$iter->at();
|
|
|
|
$mode = default_mode($iter->item);
|
|
|
|
$view_id = create_view(
|
|
|
|
$user, $course, $iter, $mode, $view->prev_view_id
|
|
|
|
);
|
|
|
|
show_item($iter, $user, $course, $view_id, $view->prev_view_id, $mode);
|
|
|
|
} else {
|
|
|
|
error_page("At start of course");
|
|
|
|
}
|
2007-12-12 04:43:04 +00:00
|
|
|
break;
|
2007-11-29 23:26:49 +00:00
|
|
|
case 'next': // "next" button in lesson or exercise answer page
|
2007-12-07 23:23:25 +00:00
|
|
|
$view = finalize_view($user, $view_id, BOLT_ACTION_NEXT);
|
2007-12-12 04:43:04 +00:00
|
|
|
|
|
|
|
$iter = new BoltIter($course_doc);
|
|
|
|
$iter->decode_state($view->state);
|
|
|
|
$iter->next();
|
|
|
|
|
2007-12-18 20:28:08 +00:00
|
|
|
if ($iter->item) {
|
|
|
|
$state = $iter->encode_state();
|
|
|
|
$mode = default_mode($iter->item);
|
|
|
|
$view_id = create_view($user, $course, $iter, $mode, $view->id);
|
|
|
|
show_item($iter, $user, $course, $view_id, $view->id, $mode);
|
|
|
|
} else {
|
2007-12-18 21:48:36 +00:00
|
|
|
$iter->frac_done = 1;
|
|
|
|
$fin_view_id = create_view($user, $course, $iter, BOLT_MODE_FINISHED, $view_id);
|
|
|
|
$e->update("last_view_id=$fin_view_id");
|
|
|
|
show_finished_page($course, $fin_view_id, $view->id);
|
2007-11-29 23:26:49 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'answer': // submit answer in exercise
|
2007-12-07 23:23:25 +00:00
|
|
|
$view = finalize_view($user, $view_id, BOLT_ACTION_SUBMIT);
|
2007-12-12 04:43:04 +00:00
|
|
|
$iter = new BoltIter($course_doc);
|
|
|
|
$iter->decode_state($view->state);
|
|
|
|
$iter->at();
|
|
|
|
|
2007-12-04 22:16:37 +00:00
|
|
|
$item = $iter->item;
|
2007-11-29 23:26:49 +00:00
|
|
|
if (!$item->is_exercise()) {
|
|
|
|
error_page("expected an exercise");
|
|
|
|
}
|
|
|
|
if ($view->item_name != $item->name) {
|
|
|
|
error_page("unexpected name");
|
|
|
|
}
|
|
|
|
$bolt_ex_mode = BOLT_MODE_SCORE;
|
|
|
|
$bolt_ex_index = 0;
|
|
|
|
$bolt_ex_score = 0;
|
2007-12-07 23:23:25 +00:00
|
|
|
$bolt_ex_response = "";
|
|
|
|
srand($view_id);
|
2007-11-30 00:38:38 +00:00
|
|
|
ob_start(); // turn on output buffering
|
2007-11-29 23:26:49 +00:00
|
|
|
require($item->filename);
|
2007-11-30 00:38:38 +00:00
|
|
|
ob_end_clean();
|
2007-12-10 22:13:48 +00:00
|
|
|
$bolt_ex_response = BoltDb::escape_string($bolt_ex_response);
|
2007-12-07 23:23:25 +00:00
|
|
|
|
2007-12-18 20:28:08 +00:00
|
|
|
$bolt_ex_score /= $bolt_ex_index;
|
|
|
|
|
2007-12-07 23:23:25 +00:00
|
|
|
$result_id = BoltResult::insert(
|
|
|
|
"(view_id, score, response)
|
|
|
|
values ($view->id, $bolt_ex_score, '$bolt_ex_response')"
|
|
|
|
);
|
|
|
|
$view->update("result_id=$result_id");
|
|
|
|
srand($view_id);
|
2007-12-18 20:28:08 +00:00
|
|
|
$view_id = create_view($user, $course, $iter, BOLT_MODE_ANSWER, $view->id);
|
|
|
|
show_item($iter, $user, $course, $view_id, $view->id, BOLT_MODE_ANSWER);
|
2007-12-07 23:23:25 +00:00
|
|
|
break;
|
|
|
|
default:
|
2007-12-18 20:28:08 +00:00
|
|
|
$view = $e?BoltView::lookup_id($e->last_view_id):null;
|
|
|
|
if (!$view) {
|
|
|
|
start_course($user, $course, $course_doc);
|
|
|
|
break;
|
|
|
|
}
|
2007-12-18 21:48:36 +00:00
|
|
|
if ($view->mode == BOLT_MODE_FINISHED) {
|
|
|
|
show_finished_page($course, $view->id, $view->prev_view_id);
|
|
|
|
break;
|
|
|
|
}
|
2007-12-12 04:43:04 +00:00
|
|
|
$iter = new BoltIter($course_doc);
|
|
|
|
$iter->decode_state($view->state);
|
|
|
|
$iter->at();
|
2007-12-07 23:23:25 +00:00
|
|
|
$mode = default_mode($iter->item);
|
2007-12-18 20:28:08 +00:00
|
|
|
$view_id = create_view($user, $course, $iter, $mode, $view->id);
|
|
|
|
show_item($iter, $user, $course, $view_id, $view->id, $mode);
|
2007-11-29 23:26:49 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-11-29 02:56:10 +00:00
|
|
|
|
2007-10-30 22:31:13 +00:00
|
|
|
?>
|