diff --git a/db/bolt_constraints.sql b/db/bolt_constraints.sql deleted file mode 100644 index ef51b84036..0000000000 --- a/db/bolt_constraints.sql +++ /dev/null @@ -1,11 +0,0 @@ -alter table bolt_course - add unique(name); - -alter table bolt_enrollment - add unique(user_id, course_id); - -alter table bolt_view - add index bv_cs(course_id, start_time); - -alter table bolt_refresh - add unique br_u(user_id, course_id, name); diff --git a/db/bolt_schema.sql b/db/bolt_schema.sql deleted file mode 100644 index 8e04e56f9b..0000000000 --- a/db/bolt_schema.sql +++ /dev/null @@ -1,154 +0,0 @@ -create table bolt_user ( - user_id integer not null, - birth_year integer not null, - sex tinyint not null, - flags integer not null, - attrs text not null, - -- project-defined. Use serialized PHP object - primary key (user_id) -); - -create table bolt_course ( - id integer not null auto_increment, - create_time integer not null, - short_name varchar(255) not null, - name varchar(255) not null, - description text not null, - hidden tinyint not null, - bossa_app_id integer not null, - -- on completion, go to this Bossa app - primary key (id) -); - -create table bolt_enrollment ( - create_time integer not null, - user_id integer not null, - course_id integer not null, - last_view_id integer not null, - -- ID of last study phase view - mastery double not null -); - --- Represents a view of an item; --- created when we show the item, --- and finalized when the user clicks on something to leave the page --- A special view is used to represent the end of a course; --- its mode is BOLT_MODE_FINISHED. --- -create table bolt_view ( - id integer not null auto_increment, - user_id integer not null, - course_id integer not null, - item_name varchar(255) not null, - -- name of the item - state text not null, - -- course state - mode integer not null, - -- distinguishes exercise show/answer - phase integer not null, - -- distinguishes study/review/refresh - action integer not null, - -- what the user clicked to leave page - start_time integer not null, - end_time integer not null, - prev_view_id integer not null, - -- for exercise answer views; - -- refers to the original exercise view - fraction_done double not null, - result_id integer not null, - -- if this was an exercise show, link to result record - refresh_id integer not null, - -- if unit was flagged for review, link to review record - -- ?? remove? - primary key (id) -); - --- represents the result of a single exercise --- -create table bolt_result ( - id integer not null auto_increment, - create_time integer not null, - user_id integer not null, - course_id integer not null, - view_id integer not null, - -- the display of exercise - item_name varchar(255) not null, - score double not null, - response text not null, - -- the query string containing user's responses - primary key(id) -); - --- represents the result of a completed exercise set, --- where "completed" means the last exercise was scored. --- In theory this could be reconstructed from the individual exercise results, --- but this table makes it easier for analytics --- -create table bolt_xset_result ( - id integer not null auto_increment, - create_time integer not null, - user_id integer not null, - course_id integer not null, - start_time integer not null, - end_time integer not null, - name varchar(255) not null, - -- logical name of exercise set unit - score double not null, - -- weighted average score - view_id integer not null, - -- the view of the answer page of last exercise in set - primary key(id) -); - --- represents the completion of a select structure --- -create table bolt_select_finished ( - id integer not null auto_increment, - user_id integer not null, - course_id integer not null, - end_time integer not null, - name varchar(255) not null, - -- logical name of the select unit - selected_unit varchar(255) not null, - -- name of selected subunit - view_id integer not null, - -- the view of the last item - primary key(id) -); - --- represents a refresh/repeat of an exercise set, --- either pending (not due yet), --- due but not started, or in progress. --- -create table bolt_refresh ( - id integer not null auto_increment, - create_time integer not null, - user_id integer not null, - course_id integer not null, - name varchar(255) not null, - -- logical name of result set unit - last_view_id integer not null, - -- if refresh is in progress, the last view - xset_result_id integer not null, - -- most recent result for this exercise set - due_time integer not null, - -- when refresh will be due - count integer not null, - -- index into intervals array - primary key (id) -); - -create table bolt_question ( - id integer not null auto_increment, - create_time integer not null, - user_id integer not null, - course_id integer not null, - name varchar(255) not null, - -- logical name of item where question was asked - mode integer not null, - -- distinguishes exercise show/answer - question text not null, - state integer not null, - -- whether question has been handled - primary key (id) -); diff --git a/db/bossa_constraints.sql b/db/bossa_constraints.sql deleted file mode 100644 index 8761c206bb..0000000000 --- a/db/bossa_constraints.sql +++ /dev/null @@ -1,10 +0,0 @@ -alter table bossa_app - add unique(name), - add unique(short_name); - -alter table bossa_job - add index bj_conf_needed(app_id, calibration, priority_0); - -alter table bossa_job_inst - add index bji_job(job_id), - add index bji_user(user_id); diff --git a/db/bossa_schema.sql b/db/bossa_schema.sql deleted file mode 100644 index 2ceda93689..0000000000 --- a/db/bossa_schema.sql +++ /dev/null @@ -1,63 +0,0 @@ -create table bossa_app ( - id integer not null auto_increment, - create_time integer not null, - name varchar(255) not null, - short_name varchar(255) not null, - description varchar(255) not null, - long_jobs tinyint not null, - hidden tinyint not null, - bolt_course_id integer not null, - time_estimate integer not null, - time_limit integer not null, - calibration_frac double not null, - info text, - -- app-specific info, JSON - primary key(id) -) engine = InnoDB; - -create table bossa_job ( - id integer not null auto_increment, - create_time integer not null, - app_id integer not null, - batch_id integer not null, - state integer not null, - info text, - calibration tinyint not null, - priority_0 double not null, - -- add more as needed - -- for calibration jobs, init to random and decrement on each view - primary key(id) -) engine=InnoDB; - -create table bossa_job_inst ( - id integer not null auto_increment, - create_time integer not null, - app_id integer not null, - job_id integer not null, - user_id integer not null, - batch_id integer not null, - finish_time integer not null, - timeout integer not null, - calibration tinyint not null, - info text, - primary key(id) -) engine=InnoDB; - -create table bossa_user ( - user_id integer not null, - category integer not null, - flags integer not null, - -- debug, show_all - info text, - -- Project-dependent info about users ability and performance. - primary key(user_id) -) engine = InnoDB; - -create table bossa_batch ( - id integer not null auto_increment, - create_time integer not null, - name varchar(255) not null, - app_id integer not null, - calibration tinyint not null, - primary key(id) -) engine = InnoDB; diff --git a/html/inc/bolt.inc b/html/inc/bolt.inc deleted file mode 100644 index ee2cbc6222..0000000000 --- a/html/inc/bolt.inc +++ /dev/null @@ -1,381 +0,0 @@ -. - -// Bolt course document API - -error_reporting(E_ALL); -ini_set('display_errors', true); -ini_set('display_startup_errors', true); - -abstract class BoltUnit { - public $name; - // Logical name. Changing this makes it a different unit. - // For items, this is the filename with query string; - // for structures, it must be specified with name() - public $title; - // Optional; used when showing course history outline. - public $is_item; - public $attrs; // course-defined - - abstract function walk(&$iter, $incr, &$frac_done); - // multi-purpose function for traversing a course. - // Create entry in $iter->state if not there. - // Recurse to first child. - // If first child is an item, set $iter->item - // If incr is set - // the bottom-level non-item unit should increment. - // return value: true if the caller should increment - // frac_done: Fraction done (of this unit and any subunits) -} - -// base class for exercise and lesson -// -class BoltItem extends BoltUnit { - public $filename; - public $query_string; - function __construct($filename, $title, $attrs) { - $p = strpos($filename, '?'); - if ($p === false) { - $this->filename = $filename; - $this->query_string = null; - } else { - $this->filename = substr($filename, 0, $p); - $this->query_string = substr($filename, $p+1); - } - $this->name = $filename; - $this->title = $title; - $this->is_item = true; - $this->attrs = $attrs; - } - function begin() { - return array(new BoltFrame($this)); - } - function walk(&$iter, $incr, &$frac_done) { - echo "SHOULDN'T BE HERE\n"; - } -} - -class BoltLesson extends BoltItem { - function is_exercise() { - return false; - } -} - -class BoltExercise extends BoltItem { - public $callback; - // called as func($student, $score, $query_string) after scoring - public $weight; - public $has_answer_page; - - function __construct( - $filename, $title, $attrs, $callback, $weight, $has_answer_page - ) { - parent::__construct($filename, $title, $attrs); - $this->callback = $callback; - $this->weight = $weight; - $this->has_answer_page = $has_answer_page; - } - function is_exercise() { - return true; - } -} - -// Base class for control structures (all units other than items). -// The state of a control structure has two parts: -// 1) a transient PHP object -// 2) a persistent "state record" (stored in JSON in the DB) -// -// The PHP object has the following properties: -// - a set of units -// - ordered: a flag for whether the set has been ordered yet -// - order($state_rec): a function for ordering this set, -// defined in the derived class -// (i.e., random, student-specific, or identity) -// This orders the set, sets "ordered", and adds info to the state rec -// saying how the ordering was done (e.g. RNG seed) -// - a number "ntoshow" for how many units to show -// -// The state record has the following items: -// - index: index into the unit array -// - nshown: for how many units completed so far -// - child_name: name of current child, or null -// -class BoltSet extends BoltUnit { - public $units; - function __construct($name, $units, $ntoshow, $attrs) { - $this->name = $name; - $this->is_item = false; - $this->units = $units; - $this->ntoshow = $ntoshow; - $this->ordered = false; - $this->attrs = $attrs; - } - - // restart this unit - set its state record to an initial state - // - function restart(&$iter) { - $state_rec = $iter->state[$this->name]; - if (!$state_rec) $state_rec = $this->init(); - $state_rec['nshown'] = 0; - $state_rec['child_name'] = null; - $iter->state[$this->name] = $state_rec; - } - - // initialize this unit (once per course) - // - function init(&$iter) { - $state_rec = array(); - $state_rec['index'] = 0; - $iter->state[$this->name] = $state_rec; - return $state_rec; - } - - function finished(&$iter) { - $this->restart($iter); - } - - function walk(&$iter, $incr, &$frac_done) { - $n = count($this->units); - if (array_key_exists($this->name, $iter->state)) { - $state_rec = $iter->state[$this->name]; - $child_name = $state_rec['child_name']; - $nshown = $state_rec['nshown']; - if (!$this->ordered) { - $this->order($iter); - } - - // look up unit by name - // - $child = null; - for ($i=0; $i<$n; $i++) { - $c = $this->units[$i]; - if ($c->name == $child_name) { - $child = $c; - break; - } - } - - // if not there, look up by index - // - if (!$child) { - $i = $state_rec['index']; - if ($i >= $n) { - // and if index is too big, use last unit - // - $i = $n-1; - } - $child = $this->units[$i]; - } - - // at this point, $child is the current unit, and $i is its index - // - if ($incr) { - if ($child->is_item) { - $my_inc = true; - } else { - $my_inc = $child->walk($iter, $incr, $frac_done); - } - if ($my_inc) { - $nshown++; - if ($nshown == $this->ntoshow) { - $frac_done = 1; - $this->finished($iter); - return true; - } else { - $i = ($i+1)%$n; - } - } - } - } else { - // here if no state record; initialize - // - $i = 0; - $nshown = 0; - $this->init($iter); - $this->order($iter); - } - - // at this point, $i is index of current child, $nshown is valid, - // and this unit has a record in the state array - // - $child = $this->units[$i]; - $frac_done = $nshown/$n; - $state_rec = $iter->state[$this->name]; - $state_rec['index'] = $i; - $state_rec['nshown'] = $nshown; - $state_rec['child_name'] = $child->name; - $iter->state[$this->name] = $state_rec; - if ($child->is_item) { - $iter->item = $child; - } else { - $child->walk($iter, false, $f); - $frac_done += $f*(1/$n); - } - return false; - } - - // return the name of our child, if we exist in the state - // - function get_child($state) { - if (array_key_exists($this->name, $state)) { - $state_rec = $state[$this->name]; - $child_name = $state_rec['child_name']; - foreach($this->units as $c) { - if ($c->name == $child_name) { - return $c; - } - } - } - return null; - } - -} - -function name($n) { - return array('name', $n); -} - -function title($n) { - return array('title', $n); -} - -function number($n) { - return array('number', $n); -} - -function filename($n) { - return array('filename', $n); -} - -function has_answer_page($n) { - return array('has_answer_page', $n); -} - -function attrs($n) { - return array('attrs', $n); -} - -function callback($n) { - return array('callback', $n); -} - -function lesson() { - $filename = ""; - $title = ""; - $attrs = null; - - $args = func_get_args(); - foreach ($args as $arg) { - if (is_array($arg)) { - switch ($arg[0]) { - case 'title': $title = $arg[1]; break; - case 'filename': $filename = $arg[1]; break; - case 'attrs': $attrs = $arg[1]; break; - default: echo "Unrecognized lesson parameter: ", $arg[0], "\n"; break; - } - } else { - echo "unprocessed arg of class ".get_class($arg); - } - } - if (!$title) { - $title = $filename; - } - if (!$filename) { - error_page("Missing filename in lesson"); - } - return new BoltLesson($filename, $title, $attrs); -} - -function exercise() { - $filename = ""; - $title = ""; - $attrs = null; - $weight = 1; - $has_answer_page = true; - - $args = func_get_args(); - $callback = null; - foreach ($args as $arg) { - if (is_array($arg)) { - switch ($arg[0]) { - case 'title': $title = $arg[1]; break; - case 'filename': $filename = $arg[1]; break; - case 'attrs': $attrs = $arg[1]; break; - case 'callback': $callback = $arg[1]; break; - case 'weight': $weight = $arg[1]; break; - case 'has_answer_page': $has_answer_page = $arg[1]; break; - default: echo "Unrecognized exercise parameter: ", $arg[0], "\n"; break; - } - } - } - if (!$title) { - $title = $filename; - } - if (!$filename) { - error_page("Missing filename in lesson"); - } - return new BoltExercise( - $filename, $title, $attrs, $callback, $weight, $has_answer_page - ); -} - -function item_attrs() { - global $item; - return $item->attrs; -} - -function student_sex() { - global $user; - return $user->bolt->sex; -} - -function student_age() { - global $user; - if (!$user->bolt->birth_year) return -1; - $date = getdate(); - $this_year = $date["year"]; - return $this_year - $user->bolt->birth_year; -} - -function student_country() { - global $user; - return $user->country; -} - -function student_name() { - global $user; - return $user->name; -} - -function student_attrs() { - global $user; - return unserialize($user->bolt->attrs); -} - -function set_student_attrs($attrs) { - global $user; - $attrs = serialize($attrs); - $user->bolt->update("attrs='$attrs'"); -} - -require_once('../inc/bolt_seq.inc'); -require_once('../inc/bolt_rnd.inc'); -require_once('../inc/bolt_xset.inc'); -require_once('../inc/bolt_select.inc'); - -?> diff --git a/html/inc/bolt_cat.inc b/html/inc/bolt_cat.inc deleted file mode 100644 index 96a0d9e7d7..0000000000 --- a/html/inc/bolt_cat.inc +++ /dev/null @@ -1,168 +0,0 @@ -. - -// represents a categorization of students -// -abstract class Categorization { - abstract function name(); - // returns descriptive name - abstract function categories(); - // returns list of categories - abstract function categorize($user); - // returns a student's category -} - -class CatSex extends Categorization { - function name() { - return "Sex"; - } - function categories() { - return array ("Male", "Female", "Unknown"); - } - function categorize($user) { - switch ($user->bolt->sex) { - case 1: return "Male"; - case 2: return "Female"; - default: return "Unknown"; - } - } -} - -$x = localtime(time(), true); -$this_year = 1900 + $x['tm_year']; - -class CatAge20 extends Categorization { - function name() { - return "Age (20-year groups)"; - } - function categories() { - return array("0-19", "20-39", "40-59", "60-79", "80+", "Unknown"); - } - function categorize($user) { - if (!$user->bolt->birth_year) return "Unknown"; - global $this_year; - $n = $this_year - $user->bolt->birth_year; - if ($n < 20) return "0-19"; - if ($n < 40) return "20-39"; - if ($n < 60) return "40-59"; - if ($n < 80) return "60-79"; - return "80+"; - } -} - -$categorizations = array(new CatSex(), new CatAge20()); - -function lookup_categorization($name) { - global $categorizations; - foreach ($categorizations as $c) { - if ($c->name() == $name) return $c; - } - return null; -} - -function filter_form($sel_name, $sel_cat) { - global $categorizations; - $checked = (!$sel_name || $sel_name == "none")?"checked":""; - echo " - Filter by: - "; -} - -function breakdown_form($sel_name) { - global $categorizations; - $checked = (!$sel_name || $sel_name == "none")?"checked":""; - echo " - Break down by: - "; -} - -// return filter and breakdown info for URLs -// -function filter_url() { - global $filter, $filter_cat, $breakdown, $breakdown_cat; - - $x = ""; - if ($filter && $filter_cat) { - $x .= "&filter=".$filter->name.":$filter_cat"; - } - if ($breakdown && $breakdown_cat) { - $x .= "&breakdown=".$breakdown->name.":$breakdown_cat"; - } - return $x; -} - -// get filter and breakdown from form vars -// -function get_filters_from_form() { - global $breakdown, $breakdown_cat, $filter, $filter_cat; - - $breakdown_cat = null; - $breakdown_info = get_str('breakdown', true); - if ($breakdown_info && $breakdown_info != 'none') { - $arr = explode(":", $breakdown_info); - $breakdown_name = $arr[0]; - if (count($arr) == 2) { - $breakdown_cat = $arr[1]; - } - $breakdown = lookup_categorization($breakdown_name); - if (!$breakdown) error_page("unknown breakdown $breakdown_name"); - } else { - $breakdown = null; - } - $filter_info = get_str('filter', true); - if ($filter_info && $filter_info != "none") { - $arr = explode(":", $filter_info); - $filter_name = $arr[0]; - $filter_cat = $arr[1]; - $filter = lookup_categorization($filter_name); - if (!$filter) error_page("unknown filter $filter_name"); - } else { - $filter_cat = ""; - $filter = null; - } -} - -?> diff --git a/html/inc/bolt_db.inc b/html/inc/bolt_db.inc deleted file mode 100644 index 4ea1132742..0000000000 --- a/html/inc/bolt_db.inc +++ /dev/null @@ -1,325 +0,0 @@ -. - -require_once("../inc/db_conn.inc"); -require_once("../inc/util.inc"); - -define('BOLT_PHASE_STUDY', 1); - // sequential progress through course -define('BOLT_PHASE_REVIEW', 2); - // review and repeat of an exercise set -define('BOLT_PHASE_REFRESH', 3); - // timed repeat of exercise set, and possibly review and repeat - -define('BOLT_MODE_LESSON', 1); -define('BOLT_MODE_SHOW', 2); -define('BOLT_MODE_SCORE', 3); -define('BOLT_MODE_ANSWER', 4); -define('BOLT_MODE_FINISHED', 5); - -define('BOLT_ACTION_NONE', 0); -define('BOLT_ACTION_NEXT', 1); -define('BOLT_ACTION_PREV', 2); -define('BOLT_ACTION_SUBMIT', 3); -define('BOLT_ACTION_QUESTION', 4); -define('BOLT_ACTION_COURSE_HOME', 5); -define('BOLT_ACTION_REVIEW', 6); -define('BOLT_ACTION_REPEAT', 7); - -define('BOLT_COURSE_NOT_STARTED', 1); -define('BOLT_COURSE_STARTED', 2); -define('BOLT_COURSE_FINISHED', 3); - -// bits in bolt_user.flags -define('BOLT_FLAGS_DEBUG', 1); // print debugging info in output pages -define('BOLT_FLAGS_SHOW_ALL', 2); // show hidden courses - -class BoltDb extends DbConn { - static $instance; - - static function get() { - if (web_stopped()) { - if ($generating_xml) { - xml_error(-183); - } else { - page_head("Page not available"); - echo "This page requires database access. - Our database server is temporarily shut down for maintenance. - Please try again later. - "; - page_tail(); - } - exit(); - } - if (!isset($instance)) { - $config = get_config(); - $name = parse_config($config, ''); - if (!$name) { - $name = parse_config($config, ''); - $user = parse_config($config, ''); - $passwd = parse_config($config, ''); - $host = parse_config($config, ''); - } else { - $user = parse_config($config, ''); - $passwd = parse_config($config, ''); - $host = parse_config($config, ''); - } - if ($host == null) { - $host = "localhost"; - } - $instance = new DbConn(); - $retval = $instance->init_conn($user, $passwd, $host, $name, true); - if (!$retval) $instance = null; - } - if (!$instance) { - error_page("no DB conn"); - } - return $instance; - } - static function escape_string($string) { - $db = self::get(); - return $db->base_escape_string($string); - } -} - -class BoltUser { - static $cache; - static function lookup_userid($id) { - $db = BoltDb::get(); - return $db->lookup('bolt_user', 'BoltUser', "user_id=$id"); - } - static function insert($clause) { - $db = BoltDb::get(); - return $db->insert('bolt_user', $clause); - } - static function lookup(&$user) { - if (!$user) return; - if (isset($user->bolt)) return; - if (isset(self::$cache[$user->id])) { - $bolt = self::$cache[$user->id]; - } else { - $bolt = self::lookup_userid($user->id); - if (!$bolt) { - self::insert("(user_id) values ($user->id)"); - $bolt = self::lookup_userid($user->id); - } - self::$cache[$user->id] = $bolt; - } - $user->bolt = $bolt; - } - function update($clause) { - $db = BoltDb::get(); - $clause = "$clause where user_id=$this->user_id"; - return $db->update_aux('bolt_user', $clause); - } -} - -class BoltCourse { - static function insert($clause) { - $db = BoltDb::get(); - $ret = $db->insert('bolt_course', $clause); - if (!$ret) return $ret; - return $db->insert_id(); - } - static function lookup_id($id) { - $db = BoltDb::get(); - return $db->lookup_id($id, 'bolt_course', 'BoltCourse'); - } - static function lookup_name($name) { - $db = BoltDb::get(); - $name = BoincDb::escape_string($name); - return $db->lookup('bolt_course', 'BoltCourse', "short_name='$name'"); - } - static function enum() { - $db = BoltDb::get(); - return $db->enum('bolt_course', 'BoltCourse'); - } - function update($clause) { - $db = BoltDb::get(); - return $db->update($this, 'bolt_course', $clause); - } - function doc_file() { - $sn = $this->short_name; - return "../inc/$sn.inc"; - } -} - -class BoltEnrollment { - static function insert($clause) { - $db = BoltDb::get(); - return $db->insert('bolt_enrollment', $clause); - } - static function lookup($user_id, $course_id) { - $db = BoltDb::get(); - return $db->lookup('bolt_enrollment', 'BoltEnrollment', "user_id=$user_id and course_id=$course_id"); - } - function update($clause) { - $db = BoltDb::get(); - $db->update_aux('bolt_enrollment', "$clause where user_id=$this->user_id and course_id=$this->course_id"); - } - static function delete($user_id, $course_id) { - $db = BoltDb::get(); - $db->delete_aux('bolt_enrollment', "user_id=$user_id and course_id=$course_id"); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_enrollment', $clause); - } -} - -class BoltView { - static function insert($clause) { - $db = BoltDb::get(); - $ret = $db->insert('bolt_view', $clause); - if (!$ret) return null; - return $db->insert_id(); - } - static function lookup_id($id) { - $db = BoltDb::get(); - return $db->lookup_id($id, 'bolt_view', 'BoltView'); - } - function update($clause) { - $db = BoltDb::get(); - $db->update($this, 'bolt_view', $clause); - } - static function enum($clause) { - $db = BoltDb::get(); - return $db->enum('bolt_view', 'BoltView', $clause); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_view', $clause); - } -} - -class BoltResult { - static function insert($clause) { - $db = BoltDb::get(); - $ret = $db->insert('bolt_result', $clause); - if (!$ret) return null; - return $db->insert_id(); - } - static function lookup_id($id) { - $db = BoltDb::get(); - return $db->lookup_id($id, 'bolt_result', 'BoltResult'); - } - static function enum($clause) { - $db = BoltDb::get(); - return $db->enum('bolt_result', 'BoltResult', $clause); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_result', $clause); - } -} - -class BoltXsetResult { - static function lookup_id($id) { - $db = BoltDb::get(); - return $db->lookup_id($id, 'bolt_xset_result', 'BoltXsetResult'); - } - static function insert($clause) { - $db = BoltDb::get(); - $ret = $db->insert('bolt_xset_result', $clause); - if (!$ret) return null; - return $db->insert_id(); - } - static function enum($clause) { - $db = BoltDb::get(); - return $db->enum('bolt_xset_result', 'BoltXsetResult', $clause); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_xset_result', $clause); - } -} - -class BoltRefreshRec { - static function lookup_id($id) { - $db = BoltDb::get(); - return $db->lookup_id($id, 'bolt_refresh', 'BoltRefreshRec'); - } - function lookup($clause) { - $db = BoltDb::get(); - return $db->lookup('bolt_refresh', 'BoltRefreshRec', $clause); - } - static function replace($clause) { - $db = BoltDb::get(); - return $db->replace('bolt_refresh', $clause); - } - static function insert($clause) { - $db = BoltDb::get(); - $ret = $db->insert('bolt_refresh', $clause); - if (!$ret) return null; - return $db->insert_id(); - } - static function enum($clause) { - $db = BoltDb::get(); - return $db->enum('bolt_refresh', 'BoltRefreshRec', $clause); - } - function update($clause) { - $db = BoltDb::get(); - $db->update($this, 'bolt_refresh', $clause); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_refresh', $clause); - } -} - -class BoltSelectFinished { - static function insert($clause) { - $db = BoltDb::get(); - return $db->insert('bolt_select_finished', $clause); - } - static function enum($clause) { - $db = BoltDb::get(); - return $db->enum('bolt_select_finished', 'BoltSelectFinished', $clause); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_select_finished', $clause); - } -} - -class BoltQuestion { - static function insert($clause) { - $db = BoltDb::get(); - return $db->insert('bolt_question', $clause); - } - static function enum($clause) { - $db = BoltDb::get(); - return $db->enum('bolt_question', 'BoltQuestion', $clause); - } - static function delete_aux($clause) { - $db = BoltDb::get(); - $db->delete_aux('bolt_question', $clause); - } -} - -// TODO: move this somewhere else, and think about whether it's correct -// -function bolt_course_status($course_id, $user_id) { - $e = BoltEnrollment::lookup($user_id, $course_id); - if (!$e) return BOLT_COURSE_NOT_STARTED; - $view = BoltView::lookup_id($e->last_view_id); - if ($view->fraction_done == 1) return BOLT_COURSE_FINISHED; - return BOLT_COURSE_STARTED; -} - -?> diff --git a/html/inc/bolt_ex.inc b/html/inc/bolt_ex.inc deleted file mode 100644 index e3fede5f5f..0000000000 --- a/html/inc/bolt_ex.inc +++ /dev/null @@ -1,347 +0,0 @@ -. - -// Bolt exercise API - -// The following is a global var accessed by exercise functions. -// -$bolt_ex = null; -$bolt_ex->mode = 0; // input: SHOW/SCORE/ANSWER -$bolt_ex->index = 0; // input: sequence of this exercise in file -$bolt_ex->score = 0; // input/output: cumulative score (if mode = SCORE) -$bolt_ex->weight = 0; // input/output: cumulative weight -$bolt_ex->query_string = ""; // user's response (if SCORE or ANSWER) - -function weight($w) { - return array('weight', $w); -} - -function exclusive_choice() { - global $bolt_ex; - $weight = 1; - - $choices = array(); - $args = func_get_args(); - foreach ($args as $arg) { - if (is_string($arg)) { - $choices[] = $arg; - } else if (is_array($arg)) { - switch ($arg[0]) { - case 'weight': $weight = $arg[1]; break; - default: echo "bad arg to exclusive_choice()"; - } - } else { - echo "bad arg to exclusive_choice()"; - } - } - - parse_str($bolt_ex->query_string); - - switch ($bolt_ex->mode) { - case BOLT_MODE_SHOW: - shuffle($choices); - $i = 0; - start_table(); - foreach ($choices as $choice) { - row2($choice, "index type=radio value=$i>"); - $i++; - } - end_table(); - break; - case BOLT_MODE_SCORE: - $right_ans = $choices[0]; - shuffle($choices); - $key = "q_$bolt_ex->index"; - if (isset($$key)) { - $response = $$key; - if ($choices[$response] == $right_ans) { - $bolt_ex->score += 1; - } - } - $bolt_ex->weight += $weight; - break; - case BOLT_MODE_ANSWER: - $right_ans = $choices[0]; - shuffle($choices); - $key = "q_$bolt_ex->index"; - if (isset($$key)) { - $response = $$key; - } else { - $response = -1; - } - $i = 0; - start_table(); - foreach ($choices as $choice) { - $x = "
"; - if ($response == $i) { - if ($choice == $right_ans) { - $x = "Right"; - } else { - $x = "You chose this answer"; - } - } else { - if ($choice == $right_ans) { - $x = "Right answer"; - } - } - echo "$choice $x "; - $i++; - } - end_table(); - break; - } - $bolt_ex->index++; -} - -function inclusive_choice() { - global $bolt_ex; - $weight = 1; - - $choices = array(); - $args = func_get_args(); - foreach ($args as $arg) { - if (is_array($arg)) { - $choices[] = $arg; - } else if (is_object($arg)) { - if (get_class($arg) == 'BoltWeight') { - $weight = $arg->weight; - } else { - echo "bad arg to inclusive_choice()"; - } - } else { - echo "bad arg to inclusive_choice()"; - } - } - - parse_str($bolt_ex->query_string); - - switch ($bolt_ex->mode) { - case BOLT_MODE_SHOW: - shuffle($choices); - $i = 0; - start_table(); - foreach ($choices as $choice) { - $c = $choice[0]; - row2("index."_$i type=checkbox>", $c); - $i++; - } - end_table(); - break; - case BOLT_MODE_SCORE: - $i = 0; - $n = count($choices); - $score = 0; - shuffle($choices); - foreach ($choices as $choice) { - $key = "q_".$bolt_ex->index."_$i"; - $response = isset($$key); - $r = $choice[1]; - $correct = ($r && $response) || (!$r && !$response); - if ($correct) $score += 1./$n; - $i++; - } - $bolt_ex->score += $score; - $bolt_ex->weight += $weight; - break; - case BOLT_MODE_ANSWER: - $i = 0; - $n = count($choices); - shuffle($choices); - start_table(); - table_header("Choice", "Correct?", "Your answer"); - foreach ($choices as $choice) { - $c = $choice[0]; - $key = "q_".$bolt_ex->index."_$i"; - $response = isset($$key); - $r = $choice[1]; - $correct = ($r && $response) || (!$r && !$response); - $color = $correct?"#88ff88":"#ff8888"; - table_row($c, $r?"yes":"no", - array($response?"yes":"no", "bgcolor=$color") - ); - $i++; - } - end_table(); - break; - } - $bolt_ex->index++; -} - -function image_rect($img, $rect) { - global $bolt_ex; - - parse_str($bolt_ex->query_string); - - switch ($bolt_ex->mode) { - case BOLT_MODE_SHOW: - echo "index src=$img> - "; - break; - case BOLT_MODE_SCORE: - $x = get_int("pic_".$bolt_ex->index."_x"); - $y = get_int("pic_".$bolt_ex->index."_y"); - $right = true; - if ($x < $rect[0]) $right = false; - if ($x > $rect[1]) $right = false; - if ($y < $rect[2]) $right = false; - if ($y > $rect[3]) $right = false; - if ($right) { - $bolt_ex->score += 1; - } - $bolt_ex->weight += $weight; - break; - case BOLT_MODE_ANSWER: - $x = get_int("pic_".$bolt_ex->index."_x"); - $y = get_int("pic_".$bolt_ex->index."_y"); - $right = true; - if ($x < $rect[0]) $right = false; - if ($x > $rect[1]) $right = false; - if ($y < $rect[2]) $right = false; - if ($y > $rect[3]) $right = false; - $cx = $rect[0]; - $cy = $rect[2]; - $sizex = $rect[1]-$rect[0]; - $sizey = $rect[3]-$rect[2]; - $ax = $x-4; - $ay = $y-4; - $color = $right?"green":"red"; - if ($right) { - echo "The point you selected (shown in green) is correct."; - } else { - echo "The point you selected (shown in red) is not correct."; - } - echo " -
-
-
- -
-
- "; - break; - } - $bolt_ex->index++; -} - -class BoltFitbField { - public $textarea, $nrows, $ncols; - function __construct($textarea, $nrows, $ncols) { - $this->textarea = $textarea; - $this->nrows = $nrows; - $this->ncols = $ncols; - } -} - -function field($n) { - return new BoltFitbField(false, 1, $n); -} - -function box($nr, $nc) { - return new BoltFitbField(true, $nr, $nc); -} - -class BoltFitbAnswer { - public $type; // 0=constant, 1=regexp, 2=func - public $ans; - function __construct($type, $ans) { - $this->type = $type; - $this->ans = $ans; - } -} - -function answer($ans) { - return new BoltFitbAnswer(0, $ans); -} - -function answer_regexp($ans) { - return new BoltFitbAnswer(1, $ans); -} - -function answer_func($ans) { - return new BoltFitbAnswer(2, $ans); -} - -function fitb() { - global $bolt_ex; - $args = func_get_args(); - $field = new BoltFitbField(false, 1, 20); - $answer = null; - foreach ($args as $arg) { - if (is_array($arg)) { - $choices[] = $arg; - } else if (is_object($arg)) { - if (get_class($arg) == 'BoltFitbField') { - $field = $arg; - } else if (get_class($arg) == 'BoltFitbAns') { - $answer = $arg; - } else { - echo "bad arg to fitb()"; - } - } else { - echo "bad arg to fitb()"; - } - } - - switch ($bolt_ex->mode) { - case BOLT_MODE_SHOW: - if ($field->textarea) { - echo " - "; - } else { - echo "index." length=$field->ncols>"; - } - break; - case BOLT_MODE_SCORE: - if (!$answer) break; - $bolt_ex->score = 0; - $key = "q_".$bolt_ex->index; - if (isset($$key)) { - $response = $$key; - } else { - $response = ""; - } - switch ($answer->type) { - case 0: - if ($response == $answer->ans) { - $bolt_ex->score = 1; - } - break; - case 1: - if (preg_match('/'.$answer->ans.'/', $response)) { - $bolt_ex->score = 1; - } - break; - case 2: - $bolt_ex->score = call_user_func($answer->ans, $response); - break; - } - break; - case BOLT_MODE_ANSWER: - $key = "q_".$bolt_ex->index; - if (isset($$key)) { - $response = $$key; - } else { - $response = ""; - } - break; - } - $bolt_ex->index++; -} - -?> diff --git a/html/inc/bolt_rnd.inc b/html/inc/bolt_rnd.inc deleted file mode 100644 index 2f9bf56976..0000000000 --- a/html/inc/bolt_rnd.inc +++ /dev/null @@ -1,75 +0,0 @@ -. - -class BoltRandom extends BoltSet { - public $units; - function __construct($name, $units, $number, $attrs) { - parent::__construct($name, $units, $number, $attrs); - } - - function order(&$iter) { - $state_rec = $iter->state[$this->name]; - if ($state_rec) { - if (array_key_exists('seed', $state_rec)) { - $seed = $state_rec['seed']; - } else { - $seed = ((double)microtime()*1000000); - $state_rec['seed'] = $seed; - $iter->state[$this->name] = $state_rec; - } - } else { - $state_rec = $this->init(); - $seed = ((double)microtime()*1000000); - $state_rec['seed'] = $seed; - $iter->state[$this->name] = $state_rec; - } - srand($seed); - shuffle($this->units); - $this->ordered = true; - } -} - -function random() { - $args = func_get_args(); - $units = array(); - $name = ""; - $number = 0; - $attrs = null; - foreach ($args as $arg) { - if (is_array($arg)) { - switch ($arg[0]) { - case 'name': $name = $arg[1]; break; - case 'title': $title = $arg[1]; break; - case 'number': $number = $arg[1]; break; - case 'attrs': $attrs = $arg[1]; break; - default: echo "Unrecognized array arg: ", $arg[0], "\n"; break; - } - } else if (is_object($arg)) { - if (is_subclass_of($arg, "BoltUnit")) { - $units[] = $arg; - } else { - echo "Unrecognized arg: "; - print_r($arg); - } - } - } - if ($number == 0) $number = count($units); - return new BoltRandom($name, $units, $number, $attrs); -} - -?> diff --git a/html/inc/bolt_sched.inc b/html/inc/bolt_sched.inc deleted file mode 100644 index 7f3c46b687..0000000000 --- a/html/inc/bolt_sched.inc +++ /dev/null @@ -1,81 +0,0 @@ -. - -// An iterator represents a user's position in a course. -// Its state is stored in the database, -// and the course may change underneath it. -// -// A state in a course is described by an associative array -// mapping logical names to state structures. -// Typically this includes the logical name of the current child -// and info such as a sequence index. -// This is kind of like a "call stack", -// except that it can contain units not currently active. - -// -class BoltIter { - public $top; // topmost unit - public $state; - public $xset; // exercise set, if any - - // the following are temps - public $item; // current item - public $frac_done; // fraction done - - function __construct($top) { - $this->top = $top; - $this->state = array(); - } - - function decode_state($encoded_state) { - $this->state = unserialize($encoded_state); - } - - function encode_state() { - return serialize($this->state); - } - - // get current item and fraction done - // - function at() { - $this->xset = null; - $this->top->walk($this, false, $this->frac_done); - } - - // move to the next item, and return it in $this->item - // (null if course finished) - // - function next() { - $this->top->walk($this, true, $this->frac_done); - } -} - -function enum_course($course) { - $iter = new BoltIter($course); - while (1) { - $x = $iter->at(); - if (!$x) break; - echo "at: $x->url\n"; - $x = $iter->next(); - if (!$x) break; - echo "next: $x->filename\n"; - } - echo "course over\n"; -} - -?> diff --git a/html/inc/bolt_select.inc b/html/inc/bolt_select.inc deleted file mode 100644 index 2a9b2bab4a..0000000000 --- a/html/inc/bolt_select.inc +++ /dev/null @@ -1,88 +0,0 @@ -. - -function select_cmp($a, $b) { - if ($a->value == $b->value) return 0; - return ($a->value < $b->value)?1:-1; -} - -class BoltSelect extends BoltSet { - public $valuator; - - function __construct($name, $units, $valuator, $attrs) { - $this->valuator = $valuator; - parent::__construct($name, $units, 1, $attrs); - } - - function order() { - global $student; - foreach ($this->units as $u) { - $func = $this->valuator; - $u->value = $func($student, $u); - } - usort($this->units, 'select_cmp'); - $this->ordered = true; - } - - function finished($iter) { - global $user; - global $course; - global $view; - - $state_rec = $iter->state[$this->name]; - $child_name = $state_rec['child_name']; - $now = time(); - BoltSelectFinished::insert("(user_id, course_id, end_time, name, selected_unit, view_id) values ($user->id, $course->id, $now, '$this->name', '$child_name', $view->id)"); - parent::finished($iter); - } -} - -function valuator($n) { - return array('valuator', $n); -} - -function select() { - $args = func_get_args(); - $units = array(); - $name = ""; - $attrs = null; - foreach ($args as $arg) { - if (is_array($arg)) { - switch ($arg[0]) { - case 'name': $name = $arg[1]; break; - case 'title': $title = $arg[1]; break; - case 'valuator': $valuator = $arg[1]; break; - case 'attrs': $attrs = $arg[1]; break; - default: echo "Unrecognized array arg: ", $arg[0], "\n"; break; - } - } else if (is_object($arg)) { - if (is_subclass_of($arg, "BoltUnit")) { - $units[] = $arg; - } else { - echo "Unrecognized arg: "; - print_r($arg); - } - } - } - if (!$valuator) { - error_page("missing valuator"); - } - return new BoltSelect($name, $units, $valuator, $attrs); -} - -?> diff --git a/html/inc/bolt_seq.inc b/html/inc/bolt_seq.inc deleted file mode 100644 index 6698465c23..0000000000 --- a/html/inc/bolt_seq.inc +++ /dev/null @@ -1,63 +0,0 @@ -. - -class BoltSequence extends BoltSet { - function __construct($name, $units, $attrs) { - parent::__construct($name, $units, count($units), $attrs); - } - - function order() { - $this->ordered = true; - } - - function restart(&$iter) { - $state_rec = $iter->state[$this->name]; - if (!$state_rec) $state_rec = $this->init(); - $state_rec['nshown'] = 0; - $state_rec['index'] = 0; - $state_rec['child_name'] = null; - $iter->state[$this->name] = $state_rec; - } -} - -function sequence() { - $args = func_get_args(); - $units = array(); - $name = ""; - $attrs = null; - foreach ($args as $arg) { - if (is_array($arg)) { - switch ($arg[0]) { - case 'name': $name = $arg[1]; break; - case 'title': $title = $arg[1]; break; - case 'attrs': $attrs = $arg[1]; break; - default: echo "Unrecognized array arg: ", $arg[0], "\n"; break; - } - } else if (is_object($arg)) { - if (is_subclass_of($arg, "BoltUnit")) { - $units[] = $arg; - } else { - echo "Unrecognized arg: "; - print_r($arg); - } - } - } - return new BoltSequence($name, $units, $attrs); -} - -?> diff --git a/html/inc/bolt_snap.inc b/html/inc/bolt_snap.inc deleted file mode 100644 index 78f9d2e9c8..0000000000 --- a/html/inc/bolt_snap.inc +++ /dev/null @@ -1,229 +0,0 @@ -. - - - -////// stuff related to snapshots -// -// There are 2 kinds of snapshots: "compare" and "map". -// -// A "compare snapshot" is a condensed representation of the results -// for a particular select/xset pair. -// Namely, it's an array whose elements contain -// bolt_user: the user -// xset_result: the user's first completion of the xset -// select_finished: the user's last completion of the select before this -// -// A "map snapshot" is: -// - an assoc array "views" mapping unit name to a list of views -// - an assoc array "results" mapping unit name to a list of results -// - an assoc array "xset_results" mapping unit name to a list of xset results -// - an assoc array "questions" mapping unit name to a list of questions -// - an assoc array "users" mapping user ID to user record -// - - -function compare_snapshot_filename($course_id, $select_name, $xset_name) { - @mkdir("../bolt_snap"); - $x = urlencode($course_id."_".$select_name."_".$xset_name); - return "../bolt_snap/compare_snapshot_$x"; -} - -function write_compare_snapshot($course_id, $select_name, $xset_name, $dur) { - $now = time(); - $start = $now - $dur*86400; - $xrs = BoltXsetResult::enum( - "course_id=$course_id and name='$xset_name' and create_time >= $start" - ); - $sfs = BoltSelectFinished::enum( - "course_id=$course_id and name='$select_name' and end_time >= $start" - ); - - // make an array $a, keyed by user ID, of earliest xset result - // - $a = array(); - foreach ($xrs as $xr) { - $uid = $xr->user_id; - if (!array_key_exists($uid, $a) || $xr->create_time < $a[$uid]->xr->create_time) { - $x = null; - $x->xr = $xr; - $a[$uid] = $x; - } - } - - // now scan select finishes, and for each user find last one before xset - // - foreach ($sfs as $sf) { - $uid = $sf->user_id; - if (!array_key_exists($uid, $a)) { - echo "no xset result"; - continue; - } - $x = $a[$uid]; - $xr = $x->xr; - if ($sf->end_time > $xr->create_time) { - //echo "select finish is too late"; - continue; - } - if (!isset($x->sf) || $sf->end_time > $x->sf->end_time) { - $x->sf = $sf; - $a[$uid] = $x; - } - } - - // cull array elements for which we didn't find a select finish. - // Look up user records for other elements. - // - foreach ($a as $uid=>$x) { - if (!isset($x->sf)) { - unset($a[$uid]); - } else { - $user = BoincUser::lookup_id($uid); - BoltUser::lookup($user); - $x->user = $user; - $a[$uid] = $x; - } - } - - $filename = compare_snapshot_filename($course_id, $select_name, $xset_name); - $f = fopen($filename, "w"); - - $s = null; - $s->recs = $a; - $s->dur = $dur; - $s->time = $now; - fwrite($f, serialize($s)); - fclose($f); - return $s; -} - -function read_compare_snapshot($course_id, $select_name, $xset_name) { - $filename = compare_snapshot_filename($course_id, $select_name, $xset_name); - $f = @fopen($filename, "r"); - if (!$f) return null; - $x = fread($f, filesize($filename)); - fclose($f); - return unserialize($x); -} - - -function map_snapshot_filename($course_id) { - return "../bolt_snap/map_snapshot_".$course_id; -} - -function write_map_snapshot($course_id, $dur) { - $now = time(); - $start = $now - $dur*86400; - - $views = array(); - $results = array(); - $xset_results = array(); - $users = array(); - $questions = array(); - - $vs = BoltView::enum("course_id=$course_id and start_time>$start"); - foreach ($vs as $v) { - if (array_key_exists($v->item_name, $views)) { - $x = $views[$v->item_name]; - $x[] = $v; - $views[$v->item_name] = $x; - } else { - $views[$v->item_name] = array($v); - } - if (!array_key_exists($v->user_id, $users)) { - $user = BoincUser::lookup_id($v->user_id); - BoltUser::lookup($user); - $users[$v->user_id] = $user; - } - } - - $rs = BoltResult::enum("course_id=$course_id and create_time>$start"); - foreach ($rs as $r) { - if (array_key_exists($r->item_name, $results)) { - $x = $results[$r->item_name]; - $x[] = $r; - $results[$r->item_name] = $x; - } else { - $results[$r->item_name] = array($r); - } - if (!array_key_exists($r->user_id, $users)) { - $user = BoincUser::lookup_id($r->user_id); - BoltUser::lookup($user); - $users[$r->user_id] = $user; - } - } - - $xrs = BoltXsetResult::enum("course_id=$course_id and create_time>$start"); - foreach ($xrs as $xr) { - if (array_key_exists($xr->name, $xset_results)) { - $x = $xset_results[$xr->name]; - $x[] = $xr; - $xset_results[$xr->name] = $x; - } else { - $xset_results[$xr->name] = array($xr); - } - if (!array_key_exists($xr->user_id, $users)) { - $user = BoincUser::lookup_id($xr->user_id); - BoltUser::lookup($user); - $users[$xr->user_id] = $user; - } - } - $qs = BoltQuestion::enum("course_id=$course_id and create_time>$start"); - foreach ($qs as $q) { - if (array_key_exists($q->name, $questions)) { - $x = $questions[$q->name]; - $x[] = $q; - $questions[$q->name] = $x; - } else { - $questions[$q->name] = array($q); - } - if (!array_key_exists($q->user_id, $users)) { - $user = BoincUser::lookup_id($q->user_id); - BoltUser::lookup($user); - $users[$q->user_id] = $user; - } - } - - $y = null; - $y->views = $views; - $y->results = $results; - $y->xset_results = $xset_results; - $y->users = $users; - $y->questions = $questions; - $y->dur = $dur; - $y->time = $now; - - $filename = map_snapshot_filename($course_id); - $f = fopen($filename, "w"); - fwrite($f, serialize($y)); - fclose($f); - - return $y; -} - -function read_map_snapshot($course_id) { - $filename = map_snapshot_filename($course_id); - $f = @fopen($filename, "r"); - if (!$f) return null; - $x = fread($f, filesize($filename)); - fclose($f); - return unserialize($x); -} - -?> diff --git a/html/inc/bolt_util.inc b/html/inc/bolt_util.inc deleted file mode 100644 index b238e7e8f1..0000000000 --- a/html/inc/bolt_util.inc +++ /dev/null @@ -1,110 +0,0 @@ -. - -// Utililty functions for student pages - -function info_incomplete($user) { - if (!$user->bolt->birth_year) return true; - if (!$user->bolt->sex) return true; - return false; -} - -function birth_year_select($user) { - $this_year = date("Y"); - $x = "\n"; - return $x; -} - -function sex_select($user) { - $x = "\n"; - return $x; -} - -function request_info($user, $course) { - page_head("About you"); - echo " - You may optionally tell us some facts about yourself. - This information will help us improve this course, - and will be kept private. -

-

- - id> - "; - start_table(); - row2("Birth year", birth_year_select($user)); - row2("Sex", sex_select($user)); - row2("", ""); - end_table(); - echo "
\n"; - page_tail(); -} - -//////////// show refresh schedule ////////////// - -function show_refresh($r) { - echo " - $r->name - ".time_str($r->due_time)." - - "; - if ($r->last_view_id) { - echo " - course_id&refresh_id=$r->id&action=start>Restart - | course_id&refresh_id=$r->id&action=resume>Resume - "; - } else { - echo " - course_id&refresh_id=$r->id&action=start>Start - "; - } - echo " - - - "; -} - -function show_refreshes() { - global $user; - global $course; - - $refreshes = BoltRefreshRec::enum("user_id=$user->id and course_id=$course->id"); - if (!count($refreshes)) return; - start_table(); - echo "Refresh schedule\n"; - foreach ($refreshes as $r) { - show_refresh($r); - } - end_table(); -} - -?> diff --git a/html/inc/bolt_util_ops.inc b/html/inc/bolt_util_ops.inc deleted file mode 100644 index db2ddf505e..0000000000 --- a/html/inc/bolt_util_ops.inc +++ /dev/null @@ -1,230 +0,0 @@ -. - - -// Utility functions for admin pages - -require_once("../inc/util_ops.inc"); - -// get names of units of a given type - -function units_of_type($unit, $type) { - $names = array(); - if (get_class($unit) == $type) { - $names[] = $unit->name; - } - if (is_subclass_of($unit, "BoltSet")) { - foreach ($unit->units as $u) { - $n = units_of_type($u, $type); - $names = array_merge($names, $n); - } - } - return array_unique($names); -} - -// show a menu of select units -// -function choose_select($top_unit) { - echo ""; -} - -// show a menu of exercise sets -// -function choose_xset($top_unit) { - echo ""; -} - -// Find a unit of given name -// -function lookup_unit($top_unit, $name) { - if ($top_unit->name == $name) return $top_unit; - if (is_subclass_of($top_unit, "BoltSet")) { - foreach ($top_unit->units as $child) { - $u = lookup_unit($child, $name); - if ($u) return $u; - } - } - return null; -} - -////// Statistics - -// compute the mean and stdev of an array -// -function mean_stdev($array, &$mean, &$stdev) { - $n = 0; - $m = 0; - $m2 = 0; - - foreach ($array as $x) { - $n++; - $delta = $x - $m; - $m += $delta/$n; - $m2 += $delta*($x-$m); - } - $mean = $m; - $stdev = sqrt($m2/($n-1)); -} - -// approximate the 90% confidence interval for the mean of an array -// -function conf_int_90($array, &$lo, &$hi) { - $n = count($array); - mean_stdev($array, $mean, $stdev); - - // I'm too lazy to compute the t distribution - $t_90 = 1.7; - $d = $t_90 * $stdev / sqrt($n); - $lo = $mean - $d; - $hi = $mean + $d; -} - -function test_stats() { - $a = array(1,1,1,1,0,1,1,1,3, 1, 1, 1, 1); - mean_stdev($a, $mean, $stdev); - echo "mean: $mean stdev: $stdev\n"; - conf_int_90($a, $lo, $hi); - echo "lo $lo hi $hi\n"; -} - -//////////// graph drawing - -function compare_bar($title, $n, $width, $lo, $hi) { - $x1 = $width*$lo; - $x2 = $width*($hi-$lo); - $a1 = number_format($lo*100); - $a2 = number_format($hi*100); - return " - - $title

($n students)

- - - - - -
$a1$a2
- - - "; -} - -function compare_bar_insuff($title, $width) { - return " - - $title - - - -
Insufficient data
- - - "; -} - -function outcome_graph($x, $width) { - $n = $x[0]+$x[1]+$x[2]; - if (!$n) return empty_cell(); - $x0 = $width*$x[1]/$n; - $x1 = $width*$x[0]/$n; - $x2 = $width*$x[2]/$n; - if ($x[1]/$n>0.05) { - $t0 = number_format(100*$x[1]/$n)."%"; - } else { - $t0 = ""; - } - $s = " - - "; - if ($x0) { - $s .= " - "; - } - if ($x1) { - $s .= " - "; - } - if ($x2) { - $s .= " - "; - } - $s .= "

$t0



- - "; - return $s; -} - -function time_graph($t, $w) { - if ($t == 0) return "---"; - $x = (log10($t)+2)*$w/4; - $t = number_format($t, 1); - return " - - -

$t sec

- "; -} - -function score_graph($t, $w) { - if ($t == 0) return "---"; - $x = $t*$w; - $y = (1-$t)*$w; - $t = number_format($t*100); - $s = " - - "; - if ($x) { - $s .= " - "; - } - if ($y) { - $s .= " - "; - } - $s .= "

$t%

- "; - return $s; -} - -function empty_cell() { - return "
"; -} - -function empty_row() { - return "
"; -} - -function bolt_style() { - echo " - - "; -} -?> diff --git a/html/inc/bolt_xset.inc b/html/inc/bolt_xset.inc deleted file mode 100644 index c5e17d7f7a..0000000000 --- a/html/inc/bolt_xset.inc +++ /dev/null @@ -1,209 +0,0 @@ -. - -class BoltExerciseSet extends BoltRandom { - public $repeats; - public $refresh; - public $weight; - public $callback; - - function __construct( - $name, $units, $number, $repeats, $refresh, $attrs, $callback, $weight - ) { - parent::__construct($name, $units, $number, $attrs); - - $this->repeats = $repeats; - $this->refresh = $refresh; - $this->callback = $callback; - $this->weight = $weight; - } - - // called when an exercise in this set has just been graded. - // - record the score in our state structure - // - return true if this was last exercise in the set - // - if so, also return a structure saying what navigation info to show: - // - review - // - repeat now - // - next - // - function xset_record_score( - &$iter, $score, $view_id, &$avg_score, &$repeat - ) { - global $course; - global $user; - - $nav_info = null; - $state_rec = $iter->state[$this->name]; - $nshown = $state_rec['nshown']; - $state_rec['scores'][$nshown] = $score; - $iter->state[$this->name] = $state_rec; - $is_last = ($nshown+1 == $this->ntoshow); - if (!$is_last) { - return false; - } - - // this exercise set is now "completed". - // - create exercise_set_result record - // - optionally create or update bolt_refresh record - // - $total_score = 0; - for ($i=0; $i<$nshown+1; $i++) { - $total_score += $state_rec['scores'][$i]; - } - $avg_score = $total_score/($nshown+1); - - $repeat = null; - $least = 2; - foreach ($this->repeats as $r) { - if ($avg_score < $r->score && $r->score<$least) { - $repeat = $r; - $least = $r->score; - } - } - return true; - } - - function walk(&$iter, $incr, &$frac_done) { - $iter->xset = $this; - // see if we're doing a review - // - if (array_key_exists($this->name, $iter->state)) { - $state_rec = $iter->state[$this->name]; - $child_name = $state_rec['child_name']; - foreach ($this->repeats as $r) { - if ($r->unit && ($r->unit->name == $child_name)) { - // we're doing a review - // - $child = $r->unit; - if ($incr) { - if ($child->is_item) { - $my_inc = true; - } else { - $my_inc = $child->walk($iter, $incr, $frac_done); - } - if ($my_inc) { - // we're done with review. do exercises again - // - $state_rec['child_name'] = null; - $state_rec['nshown'] = 0; - $iter->state[$this->name] = $state_rec; - } - } else { - if ($child->is_item) { - $iter->item = $child; - } else { - $child->walk($iter, false, $f); - } - } - return false; - } - } - } - - return parent::walk($iter, $incr, $frac_done); - } - - function start_review(&$iter, $unit_name) { - foreach ($this->repeats as $r) { - if ($r->unit->name == $unit_name) { - $state_rec = $iter->state[$this->name]; - $state_rec['child_name'] = $unit_name; - $iter->state[$this->name] = $state_rec; - if (!$r->unit->is_item) { - $r->unit->restart($iter); - } - return true; - } - } - return false; - } -} - -class BoltRefresh{ - public $intervals; - function __construct($i) { - $this->intervals = $i; - } -} - -class BoltRepeat { - public $score; - public $unit; - public $flags; - function __construct($s, $u, $f) { - $this->score = $s; - $this->unit = $u; - $this->flags = $f; - } -} - -define('REVIEW', 1); -define('REPEAT', 2); -define('NEXT', 4); - -function repeat($s, $u, $f) { - return new BoltRepeat($s, $u, $f); -} - -function refresh($a) { - return new BoltRefresh($a); -} - -function exercise_set() { - $args = func_get_args(); - $units = array(); - $repeats = array(); - $refresh = null; - $callback = null; - $name = ""; - $number = 0; - $attrs = null; - $weight = 1; - foreach ($args as $arg) { - if (is_array($arg)) { - switch ($arg[0]) { - case 'name': $name = $arg[1]; break; - case 'title': $title = $arg[1]; break; - case 'number': $number = $arg[1]; break; - case 'attrs': $attrs = $arg[1]; break; - case 'callback': $callback = $arg[1]; break; - case 'weight': $weight = $arg[1]; break; - default: echo "Unrecognized array arg: ", $arg[0], "\n"; break; - } - } else if (is_object($arg)) { - if (get_class($arg) == "BoltExercise") { - $units[] = $arg; - } else if (get_class($arg) == "BoltRepeat") { - $repeats[] = $arg; - } else if (get_class($arg) == "BoltRefresh") { - $refresh= $arg; - } else { - echo "Can't include object of type ".get_class($arg)." within an exercise set."; - } - } else { - echo "Unexpected arg to exercise_set(): "; print_r($arg); - } - } - - if ($number == 0) $number = count($units); - return new BoltExerciseSet( - $name, $units, $number, $repeats, $refresh, $attrs, $callback, $weight - ); -} - -?> diff --git a/html/inc/bossa.inc b/html/inc/bossa.inc deleted file mode 100644 index 625ca52ea7..0000000000 --- a/html/inc/bossa.inc +++ /dev/null @@ -1,63 +0,0 @@ -. - -require_once("../inc/util.inc"); -require_once("../inc/bossa_db.inc"); - -function bossa_job_create( - $app_id, $batch_id, $info, $calibration -) { - $job = new BossaJob; - $info = serialize($info); - if ($calibration) { - $priority = drand(); - $c = 1; - } else { - $priority = 1; - $c = 0; - } - - $now = time(); - $int_max = 2147483647; - $clause = "(create_time, app_id, batch_id, state, info, calibration, priority_0) values ($now, $app_id, $batch_id, 1, '$info', $c, $priority)"; - return $job->insert($clause); -} - -function bossa_batch_create($appid, $name, $calibration) { - $now = time(); - $c = $calibration?"1":"0"; - return BossaBatch::insert("(create_time, app_id, name, calibration) values ($now, $appid, '$name', $c)"); -} - -function bossa_app_lookup($name) { - $name = BoincDb::escape_string($name); - $app = BossaApp::lookup("short_name='$name'"); - if (!$app) return 0; - return $app->id; -} - -function bossa_lookup_job($instid, &$job, &$inst, &$user) { - $inst = BossaJobInst::lookup_id($instid); - if (!$inst) return false; - $job = BossaJob::lookup_id($inst->job_id); - $user = BoincUser::lookup_id($inst->user_id); - BossaUser::lookup($user); - return true; -} - -?> diff --git a/html/inc/bossa_db.inc b/html/inc/bossa_db.inc deleted file mode 100644 index 95c18bca58..0000000000 --- a/html/inc/bossa_db.inc +++ /dev/null @@ -1,291 +0,0 @@ -. - -require_once("../inc/db_conn.inc"); -require_once("../inc/util_basic.inc"); - -class BossaDb extends DbConn { - public static $instance; - - static function get() { - if (!isset($instance)) { - $config = get_config(); - $name = parse_config($config, ''); - if (!$name) { - $name = parse_config($config, ''); - $user = parse_config($config, ''); - $passwd = parse_config($config, ''); - $host = parse_config($config, ''); - } else { - $user = parse_config($config, ''); - $passwd = parse_config($config, ''); - $host = parse_config($config, ''); - } - if ($host == null) { - $host = "localhost"; - } - $instance = new DbConn(); - $retval = $instance->init_conn($user, $passwd, $host, $name, true); - if (!$retval) return null; - } - return $instance; - } - static function escape_string($string) { - $db = self::get(); - return $db->base_escape_string($string); - } - static function start_transaction() { - //echo "start transaction\n"; - return; - $db = BossaDb::get(); - $db->do_query("start transaction"); - } - static function commit() { - //echo "commit\n"; - return; - $db = BossaDb::get(); - $db->do_query("commit"); - } -} - -// use this as a local to ensure that transaction is committed -// regardless of exceptions -// -class BossaTransaction { - function __construct() { - BossaDb::start_transaction(); - } - function __destruct() { - BossaDb::commit(); - } -} - -class BossaUser { - static $cache; - static function lookup_userid($id) { - $db = BossaDb::get(); - return $db->lookup('bossa_user', 'BossaUser', "user_id=$id"); - } - static function insert($clause) { - $db = BossaDb::get(); - return $db->insert('bossa_user', $clause); - } - static function lookup(&$user) { - if (!$user) return; - if (isset($user->bossa)) return; - if (isset(self::$cache[$user->id])) { - $bossa = self::$cache[$user->id]; - } else { - $bossa = self::lookup_userid($user->id); - if (!$bossa) { - self::insert("(user_id) values ($user->id)"); - $bossa = self::lookup_userid($user->id); - } - self::$cache[$user->id] = $bossa; - } - $user->bossa = $bossa; - } - function update($clause) { - $db = BossaDb::get(); - $clause = "$clause where user_id=$this->user_id"; - return $db->update_aux('bossa_user', $clause); - } - - // app-callable: - // - function get_opaque_data() { - return unserialize($this->info); - } - function set_opaque_data($info) { - $info = serialize($info); - $this->update("info='$info'"); - } -} - -class BossaApp { - static function insert($clause) { - $db = BossaDb::get(); - return $db->insert('bossa_app', $clause); - } - - static function lookup($clause) { - $db = BossaDb::get(); - return $db->lookup('bossa_app', 'BossaApp', $clause); - } - - static function lookup_id($id) { - $db = BossaDb::get(); - return $db->lookup_id($id, 'bossa_app', 'BossaApp'); - } - - static function enum() { - $db = BossaDb::get(); - return $db->enum('bossa_app', 'BossaApp'); - } - function update($clause) { - $db = BossaDb::get(); - return $db->update($this, 'bossa_app', $clause); - } -} - -// values for bossa_job.state -// -define("BOSSA_JOB_EMBARGOED", 0); -define("BOSSA_JOB_IN_PROGRESS", 1); -define("BOSSA_JOB_DONE", 2); -define("BOSSA_JOB_INCONCLUSIVE", 3); - -class BossaJob { - static function insert($clause) { - $db = BossaDb::get(); - $ret = $db->insert('bossa_job', $clause); - if (!$ret) return 0; - return $db->insert_id(); - } - function update($clause) { - $db = BossaDb::get(); - return $db->update($this, 'bossa_job', $clause); - } - static function lookup_id($id) { - $db = BossaDb::get(); - return $db->lookup_id($id, 'bossa_job', 'BossaJob'); - } - static function enum($clause) { - $db = BossaDb::get(); - return $db->enum('bossa_job', 'BossaJob', $clause); - } - static function count($clause) { - $db = BossaDb::get(); - return $db->count('bossa_job', $clause); - } - - // app-callable: - // - function get_opaque_data() { - return unserialize($this->info); - } - function set_priority($x) { - return $this->update("priority_0=$x"); - } - function get_instances() { - return BossaJobInst::enum("job_id = $this->id"); - } - function get_finished_instances() { - return BossaJobInst::enum("job_id = $this->id and finish_time>0"); - } - function set_state($s) { - $this->update("state=$s"); - } -} - -class BossaJobInst { - function insert($clause) { - $db = BossaDb::get(); - $ret = $db->insert('bossa_job_inst', $clause); - if (!$ret) return 0; - return $db->insert_id(); - } - - static function lookup_id($id) { - $db = BossaDb::get(); - return $db->lookup_id($id, 'bossa_job_inst', 'BossaJobInst'); - } - static function enum($clause) { - $db = BossaDb::get(); - return $db->enum('bossa_job_inst', 'BossaJobInst', $clause); - } - - function update($clause) { - $db = BossaDb::get(); - return $db->update($this, 'bossa_job_inst', $clause); - } - - // Assign a job from the given app to the given user. - // Returns the job instance or NULL. - // - static function assign($app, $user) { - $db = BossaDb::get(); - - // first look for unfinished jobs previously assigned to this user - // - $job = $db->lookup("bossa_job_inst", "BossaJobInst", - "app_id=$app->id and user_id=$user->id and finish_time=0 limit 1" - ); - if ($job) return $job; - - if ($app->calibration_frac && drand() < $app->calibration_frac) { - $job = $db->lookup("bossa_job", "BossaJob", "app_id=$app->id and (select count(*) from ".$db->db_name.".bossa_job_inst where job_id=bossa_job.id and user_id=$user->id) = 0 and state=1 and calibration=1 order by priority_0 desc limit 1"); - if (!$job) return null; - $job->update("priority_0=priority_0-1"); - } else { - if (isset($user->bossa->category)) { - $prio = "priority_".$user->bossa->category; - } else { - $prio = "priority_0"; - } - // skips jobs for which this user - // has already been assigned an instance - // - $job = $db->lookup("bossa_job", "BossaJob", "app_id=$app->id and (select count(*) from ".$db->db_name.".bossa_job_inst where job_id=bossa_job.id and user_id=$user->id) = 0 and state=1 and calibration=0 order by $prio desc limit 1"); - if (!$job) return null; - } - - $now = time(); - $clause = "(create_time, app_id, job_id, user_id, batch_id, calibration) values ($now, $app->id, $job->id, $user->id, $job->batch_id, $job->calibration)"; - $id = BossaJobInst::insert($clause); - return BossaJobInst::lookup_id($id); - } - function delete_aux($clause) { - $db = BossaDb::get(); - return $db->delete_aux('bossa_job_inst', $clause); - } - - // app-callable functions - // - function set_opaque_data($info) { - $info = serialize($info); - return $this->update("info='$info'"); - } - function get_opaque_data() { - return unserialize($this->info); - } - function get_user() { - $user = BoincUser::lookup_id($this->user_id); - BossaUser::lookup($user); - return $user; - } -} - -class BossaBatch { - function insert($clause) { - $db = BossaDb::get(); - $ret = $db->insert('bossa_batch', $clause); - if (!$ret) return 0; - return $db->insert_id(); - } - static function enum($clause) { - $db = BossaDb::get(); - return $db->enum('bossa_batch', 'BossaBatch', $clause); - } - static function lookup_id($id) { - $db = BossaDb::get(); - return $db->lookup_id($id, 'bossa_batch', 'BossaBatch'); - } -} - -?> diff --git a/html/inc/bossa_example.inc b/html/inc/bossa_example.inc deleted file mode 100644 index 947f70de51..0000000000 --- a/html/inc/bossa_example.inc +++ /dev/null @@ -1,80 +0,0 @@ -. - -require_once("../inc/bossa.inc"); - -// Bossa example #1. -// Show the user an image and ask them to click on the ellipse -// This version does no replication. - -function job_show($job, $inst, $user) { - $info = $job->get_opaque_data($job); - $path = $info->path; - page_head("Find the Ellipse"); - echo " -
- Click on the center of the ellipse. - If you don't see one, click here: - -

- id> - -
- "; - page_tail(); -} - -function job_issued($job, $inst, $user) { - $job->set_priority(0); -} - -function job_finished($job, $inst) { - $response = new stdClass; - if (get_str('submit', true)) { - $response->have_ellipse = 0; - } else { - $response->have_ellipse = 1; - $response->cx = get_int('pic_x'); - $response->cy = get_int('pic_y'); - } - $inst->set_opaque_data($response); - $job->set_state(BOSSA_JOB_DONE); -} - -function job_timed_out($job, $inst, $user) { - $job->set_priority(1); -} - -function job_summary($job) { - $info = $job->get_opaque_data(); - return "path>View image"; -} - -function instance_summary($info) { - if ($info->have_ellipse) { - return "($info->cx, $info->cy)"; - } else { - return "no ellipse"; - } -} - -function user_summary($user) { - return ""; -} - -?> diff --git a/html/inc/bossa_example2.inc b/html/inc/bossa_example2.inc deleted file mode 100644 index c6bf281513..0000000000 --- a/html/inc/bossa_example2.inc +++ /dev/null @@ -1,135 +0,0 @@ -. - -require_once("../inc/bossa.inc"); - -// Bossa example #2. -// Show the user an image and ask them to click on the ellipse -// This version does replication; -// a job is considered done if either -// - 2 instances are positive and match within +- 20 pixels -// - 2 instances are negative -// - there are 10 finished instances -// (in which case the job is marked as inconclusive) - -function job_show($job, $inst, $user) { - $info = $job->get_opaque_data($job); - $path = $info->path; - echo " -

Find the Ellipse!

-
- Click on the center of the ellipse. - If you don't see one, click here: - -

- id> - -
- "; -} - -function job_issued($job, $inst, $user) { - $insts = $job->get_instances(); - if (count($insts) == 1) { - $job->set_priority(2); - } else { - $job->set_priority(0); - } -} - -function job_finished($job, $inst) { - // record the user's response - // - $response = null; - if (get_str('submit', true)) { - $response->have_ellipse = 0; - } else { - $response->have_ellipse = 1; - $response->cx = get_int('pic_x'); - $response->cy = get_int('pic_y'); - } - $inst->set_opaque_data($response); - - // see whether we have a consensus - // - $insts = $job->get_finished_instances(); - $n = count($insts); - - $results = null; - foreach ($insts as $inst) { - $results[] = $inst->get_opaque_data(); - } - for ($i=0; $i<$n-1; $i++) { - $r1 = $results[$i]; - for ($j=$i+1; $j<$n; $j++) { - $r2 = $results[$j]; - if (compatible($r1, $r2)) { - $job->set_state(BOSSA_JOB_DONE); - return; - } - } - } - - // no consensus - see whether we've reached replication limit - // - if ($n >= 10) { - $job->set_state(BOSSA_JOB_INCONCLUSIVE); - return; - } - - // still looking for consensus - get another instance - // - $job->set_priority(2); -} - -// two results are compatible if neither found an ellipse, -// or they both did and centers are within 20 pixels -// -function compatible($r1, $r2) { - if ($r1->have_ellipse) { - if ($r2->have_ellipse) { - $dx = ($r1->cx - $r2->cx); - $dy = ($r1->cy - $r2->cy); - $dsq = $dx*$dx + $dy*$dy; - return ($dsq < 400); - } else return false; - } else { - return !$r2->have_ellipse; - } -} - -function job_timed_out($job, $inst, $user) { - $job->set_priority(2); -} - -function job_summary($job) { - $info = $job->get_opaque_data(); - return "path>View image"; -} - -function instance_summary($info) { - if ($info->have_ellipse) { - return "ellipse ($info->cx, $info->cy)"; - } else { - return "no ellipse"; - } -} - -function user_summary($user) { - return ""; -} diff --git a/html/inc/bossa_example3.inc b/html/inc/bossa_example3.inc deleted file mode 100644 index 2be769c3f5..0000000000 --- a/html/inc/bossa_example3.inc +++ /dev/null @@ -1,224 +0,0 @@ -. - -// Bossa example #3 - calibration jobs. -// We maintain the following for each user: -// nneg # of negative calibration jobs shown -// nneg_err # of errors -// npos -// npos_err -// -// from these we derive -// neg_err_rate -// pos_err_rate -// -// a job is considered done if either -// - N instances are positive and match within +- 20 pixels, -// and prod(pos_err_rate)get_opaque_data(); - $path = $info->path; - page_head("Find the Ellipse"); - echo " -
- Click on the center of the ellipse. - If you don't see one, click here: - -

- id> - -
- "; - page_tail(); -} - -function job_issued($job, $inst, $user) { - $insts = $job->get_instances(); - if (count($insts) > 1) { - $job->set_priority(0); - } -} - -function job_finished($job, $inst, $user) { - $response = null; - if (get_str('submit', true)) { - $response->have_ellipse = 0; - } else { - $response->have_ellipse = 1; - $response->cx = get_int('pic_x'); - $response->cy = get_int('pic_y'); - } - $inst->set_opaque_data($response); - - // if this is a calibration job, update user's opaque data - // - if ($job->calibration) { - $b = $user->bossa; - $info = $job->get_opaque_data(); - $answer = $info->answer; - $u = $b->get_opaque_data(); - if (!$u) { - $u->npos = 0; - $u->npos_err = 0; - $u->nneg = 0; - $u->nneg_err = 0; - } - if (compatible($response, $answer)) { - if ($answer->have_ellipse) { - $u->npos++; - } else { - $u->nneg++; - } - } else { - if ($answer->have_ellipse) { - $u->npos++; - $u->npos_err++; - } else { - $u->nneg++; - $u->nneg_err++; - } - } - $b->set_opaque_data($u); - return; - } - - // now see if job is done - // - $insts = $job->get_finished_instances(); - $n = count($insts); - - $results = null; - $users = null; - foreach ($insts as $inst) { - $results[] = $inst->get_opaque_data(); - $u = $inst->get_user(); - $users[] = $u->bossa->get_opaque_data(); - } - - // see if there's a negative consensus - // - $prob = 1; - for ($i=0; $i<$n; $i++) { - $r = $results[$i]; - if ($r1->have_ellipse) continue; - $u = $users[$i]; - $prob *= $u->neg_err_rate; - } - if ($prob < PROB_LIMIT) { - $job->set_state(BOSSA_JOB_DONE); - return; - } - - // see if there's a positive consensus - // - for ($i=0; $i<$n; $i++) { - $r1 = $results[$i]; - $u = $users[$i]; - $prob = $u->pos_error_rate; - for ($j=0; $j<$n; $j++) { - if ($j == $i) continue; - $r2 = $results[$j]; - if (compatible($r1, $r2)) { - $u2 = $users[$j]; - $prob *= $u2->pos_err_rate; - } - } - if ($prob < PROB_LIMIT) { - $job->set_state(BOSSA_JOB_DONE); - return; - } - } - - // see if there are too many instances without a consensus - // - if ($n >= 10) { - $job->set_state(BOSSA_JOB_INCONCLUSIVE); - return; - } - - // still looking for consensus - get another instance - // - $job->set_priority(2); - -} - -// two results are compatible if neither found an ellipse, -// or they both did and centers are within 20 pixels -// -function compatible($r1, $r2) { - if ($r1->have_ellipse) { - if ($r2->have_ellipse) { - $dx = ($r1->cx - $r2->cx); - $dy = ($r1->cy - $r2->cy); - $dsq = $dx*$dx + $dy*$dy; - return ($dsq < 400); - } else return false; - } else { - return !$r2->have_ellipse; - } -} - -function job_timed_out($job, $inst, $user) { - $job->set_priority(1); -} - -function job_summary($job) { - $info = $job->get_opaque_data(); - return "path>(view image)"; -} - -function instance_summary($info) { - if ($info->have_ellipse) { - return "ellipse ($info->cx, $info->cy)"; - } else { - return "no ellipse"; - } -} - -function user_summary($user) { - $b = $user->bossa; - $info = $b->get_opaque_data(); - if ($info) { - if ($info->npos) { - $pos_err = $info->npos_err/$info->npos; - } else { - $pos_err = "---"; - } - if ($info->nneg) { - $neg_err = $info->nneg_err/$info->nneg; - } else { - $neg_err = "---"; - } - return "error rate: positive $pos_err ($info->npos_err/$info->npos), - negative $neg_err ($info->nneg_err/$info->nneg) - "; - } else { - return "No data"; - } -} - -?> diff --git a/html/inc/bossa_example4.inc b/html/inc/bossa_example4.inc deleted file mode 100644 index 73c1174d55..0000000000 --- a/html/inc/bossa_example4.inc +++ /dev/null @@ -1,189 +0,0 @@ -. - -require_once("../inc/bossa.inc"); - -function job_show($job, $inst, $user) { - $output = $inst->get_opaque_data(); - $features = $output->features; - $input = $job->get_opaque_data(); - $path = $input->path; - - show_style(); - echo " - -
-
- - id\"> - - "; - $size = 100; - $size2 = 50; - $i = 0; - foreach ($features as $f) { - $cx = $f->x - $size2; - $cy = $f->y - $size2; - echo " - - "; - $c = $f->comment?"($f->comment)":""; - echo " - - - - - $f->type $c - - - - "; - echo " - id&action=delete&index=$i> - - "; - $i++; - } - echo " -
- "; - control_bar($features, $inst); - echo " -
- "; -} - -function job_issued($job, $inst, $user) { - $job->set_priority(0); -} - -function job_finished($job, $inst) { -} - -function job_timed_out($job, $inst, $user) { - $job->set_priority(1); -} - -function job_summary($job) { - $info = $job->get_opaque_data(); - return "path>View image"; -} - -function instance_summary($opaque_data) { - $features = $opaque_data->features; - $x = ""; - foreach ($features as $f) { - $c = $f->comment?"($f->comment)":""; - $x .= "$f->type $c
"; - } - return $x; -} - -function user_summary($user) { - return ""; -} - -function show_style() { - echo " - - "; -} - -function select_type() { - echo " - - "; -} - -function control_bar($features, $inst) { - if (count($features)) { - $str1 = "any more"; - $str2 = "another"; - } else { - $str1 = "any"; - $str2 = "a"; - } - echo " -
- id\"> - If you see $str2 feature: - "; - select_type(); - echo " - - - and click on its center. -
- If you don't see $str1 features, click - id>DONE -
- "; -} - -?> diff --git a/html/inc/bossa_impl.inc b/html/inc/bossa_impl.inc deleted file mode 100644 index 0e036ae09f..0000000000 --- a/html/inc/bossa_impl.inc +++ /dev/null @@ -1,38 +0,0 @@ -. - -function show_next_job($app, $user) { - $inst = BossaJobInst::assign($app, $user); - if ($inst) { - $job = BossaJob::lookup_id($inst->job_id); - $file = "../inc/$app->short_name.inc"; - require_once($file); - job_issued($job, $inst, $user); - job_show($job, $inst, $user); - } else { - page_head("No jobs available"); - echo " - Sorry, no jobs are available right now. -

- Please try again later. - "; - page_tail(); - } -} - -?> diff --git a/html/user/bolt.css b/html/user/bolt.css deleted file mode 100644 index a7ec6c5bec..0000000000 --- a/html/user/bolt.css +++ /dev/null @@ -1,414 +0,0 @@ -/* General */ - -a, a:link, a:visited, a:active { - color: #0069A1; - text-decoration: none; -} - -a:hover { text-decoration: underline; } - -body { - background-image: url("img/gray_gradient.png"); - background-repeat: repeat-x; - background-color: white; - font-family: Verdana, Arial, Sans Serif; - font-size: 13px; - margin: 5px 10px; - color: black; -} - -h1, h2 { - font-size: x-large; - font-weight: normal; -} - -h1 { - color: #203C66; - margin: 10px; -} - -h3, h4 { font-weight: bold; } - -hr { - size: 0px; - border-top: 2px solid #e8e8e8; - margin: 8px 2px; -} - -.table { - padding: 4px; - margin: 2px; -} - -.table-bordered { - border: 2px solid #e8e8e8; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; -} - -th { - background-color: #c0c0c0; - font-weight: bold; - vertical-align: top; -} - -td { - vertical-align: top; - padding: 4px; -} - -td.bordered { - border: 1px solid gray; -} - -td.indent { border-left: 4px solid white; } - -th, td.heading { - font-weight: bold; - margin: 4px 0px; - padding: 8px; - background-color: #d8d8d8; -} - -td.fieldname { - background-color: #eeeeee; - text-align: right; - padding-right: 10px; - margin: 2px 0px; -} - -td.fieldvalue { - margin: 2px 0px; - vertical-align: middle; -} - -td.fieldname_error { - background-color: #ff8888; - text-align: right; -} - -td.fieldvalue_error { - background-color: #ff8888; - font-weight: bold; -} - -td.navbar { - border: 0px; - text-align: center; - vertical-align: middle; -} - -td.friend { - background-color: #e8e8e8; - text-align: center; - vertical-align: middle; -} - -.row0 { - background-color: #d9d9d9; - text-align: left; -} -.row1 { - background-color: #eeeeee; - text-align: left; -} - -.highlighted_row0 { - background-color: #b9d9f9; - text-align: left; -} -.highlighted_row1 { - background-color: #ceeefe; - text-align: left; -} - -.row_hd0 { background-color: #cffacf; } - -.row_hd1 { background-color: #defade; } - -tr.message { background-color: #e0e0e0; } - -input[type="text"], select, textarea, .btn { - border: 1px solid #d8d8d8; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - padding: 2px 4px; - font-size: 12px; -} - -input[type="button"], input[type="submit"], input.btn { - margin: 2px 0px; - background: #d4d0c8; - margin-right: 0.6em; - color: #203C66; - border: 1px solid #a8a8a8; - font-size: 12px; - font-weight: normal; -} - -/* IE6 doesn't understand [type=XXXX] so we factor this out into its own */ -.btn { - margin: 2px 0px; - background: #d4d0c8; - margin-right: 0.6em; - white-space: nowrap; - color: #203C66; - border: 1px solid #a8a8a8; - font-size: 0.9em; - font-weight: normal; - line-height: 2em; -} - -.btn:hover { - background: #edece8; - text-decoration:none; -} - -input[type="button"]:hover, input[type="submit"]:hover, input.btn:hover, .forum_toplinks a:hover { - background: #edece8; -} - -.actionlist { - display: inline; - list-style: none; - margin: 0; - padding: 0; -} -.actionlist li { - display: inline; -} - - -img { border: 0px; } - -img.userimg { border: 0px; } - -/* Main Page */ - -#news { - background-color: #dff0ff; - border: 2px solid #add8e6; - padding: 10px; - margin: 4px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; -} - -#news h2, #uotd h2, #mainnav h2 { - margin-top: 0px; - font-size: 1.2em; - font-weight: bold; -} - -#news h3 { - color: #666666; - font-size: 1em; - margin-bottom: 2px; -} - -#news p { - margin-top: 0px; -} - -#uotd { - background-color: #d3d3d3; - border: 2px solid #eeeeee; - padding: 10px; - margin: 4px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; -} - -/* Forum */ - -td.category , tr.subtitle{ - background-color: #dddddd; - border: 0px; - font-weight: bold; - margin: 6px 0px; -} - -th { - font-weight: bold; - margin: 4px 2px; - padding: 4px; -} - -td.postheader { - background-color: #eeeeee; - height: 24px; - margin-left: 4px; - padding-left: 8px; - -moz-border-radius: 0px 0px 10px 10px; - -webkit-border-radius: 0px 0px 10px 10px; -} - -td.postbody { - font-size: 9pt; - margin-left: 4px; - background: transparent url('img/75pct_white.png'); -} - -td.postfooter { - background-color: #eeeeee; - height: 26px; - margin-left: 4px; - padding-left: 8px; - -moz-border-radius: 10px 10px 0px 0px; - -webkit-border-radius: 10px 10px 0px 0px; -} - -tr.helpdeskseparator { height: 10pt; } - -tr.postseparator { - background-color: #c8c8c8; - border: 1px solid #aaaaaa; - margin: 4px 0px; -} - -td.threadline { text-align: left; } - -td.numbers { - text-align: center; -} - -td.numbers { - text-align: left; -} - -td.lastpost { -} - -.title { - font-size: 14px; - font-weight: bold; -} - -.text-info, .description { - font-size: 80%; - font-weight: normal; -} - -.authorcol { - width: 136px; - overflow: hidden; -} - -div.authorcol { - border: 1px solid #c8c8c8; - background-color: white; - padding: 8px 5px; - width: 120px; - margin-left: 2px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; -} - -.authorinfo img { - border: 1px solid #a8a8a8; - margin: 3px 9px; -} - -.authorcol input { margin: 4px 10px; } - -blockquote.postbody { - border-left: 2px solid #0089e1; - background-color: #f5fffa; - padding: 2px 6px; - margin: 0px 6px 0px 10px; - font-style: italic; -} - -#thread { - width: 100%; - table-layout: fixed; - overflow: visible; -} - -.forum_toplinks td { - vertical-align: middle; -} - -span.page_title { - font-size: 24px; - margin: 20px; -} - -p.text-muted, span.note { - font-weight: normal; - font-size: 0.9em; - font-style: italic; -} - -span.news_date { - color: #646464; - font-size: 0.9em; -} -span.news_title { - font-weight: bold; -} - -span.inboxunread { - font-weight: bold; -} - -span.highlight { - background-color: #ffffcc; -} - -.nobr{ - white-space: nowrap; -} - -.code { - font-family: "Courier New", courier, monospace; - display: block; - margin-left: 5em; - border-left: 3px solid #ccaaaa; - padding-left: 1em; - white-space: nowrap; - overflow: auto; -} - -small { - font-size: 0.8em; -} - -p.text-danger, .error { - color: #ff0000; - font-weight: bold; - font-size: 1.1em; -} - -.notice { - color: #009900; - font-weight: bold; - font-size: 1.1em; -} - -#preview { - border: 2px solid #cccccc; - background-color: #eeeeee; - margin: 1em; - padding: 0.2em; -} - -#preview .header { - font-weight: bold; - font-size: 1.3em; - border-bottom: 1px solid #cccccc; -} - -/* Server Status Page */ - -td.running { background-color: #9aff4f; } - -td.notrunning { background-color: #feff6f; } - -td.disabled { background-color: #ff4f4f; } - -/* IE hack */ - -* html body .code { - white-space: normal; -} diff --git a/html/user/bolt.php b/html/user/bolt.php deleted file mode 100644 index 6ccda1c16a..0000000000 --- a/html/user/bolt.php +++ /dev/null @@ -1,71 +0,0 @@ -. - -require_once("../inc/bolt_db.inc"); -require_once("../inc/util.inc"); -require_once("../inc/bolt_util.inc"); - -page_head("Courses"); - -$user = get_logged_in_user(false); -if ($user) { - BoltUser::lookup($user); -} - -$courses = BoltCourse::enum(); -start_table(); -table_header( - "Course", "Status" -); -foreach ($courses as $course) { - if ($course->hidden && !($user->bolt->flags&BOLT_FLAG_SHOW_ALL)) { - continue; - } - $e = $user?BoltEnrollment::lookup($user->id, $course->id):null; - if ($e) { - $start = date_str($e->create_time); - $view = BoltView::lookup_id($e->last_view_id); - $ago = time_diff(time() - $view->start_time); - $pct = number_format($view->fraction_done*100, 0); - $status = "Started $start -
Last visit: $ago ago -
$pct% done - "; - if ($view->fraction_done < 1) { - $status .= "
id&action=resume>Resume - "; - } - $status .= "
id&action=start>Restart - | id>History - "; - } else { - $status = " - id&action=start>Start - "; - } - row2_init("$course->name -

$course->description

", - $status - ); - show_refreshes(); - echo "\n"; -} -end_table(); -page_tail(); - -?> diff --git a/html/user/bolt_admin.css b/html/user/bolt_admin.css deleted file mode 100644 index 295c4ca6ca..0000000000 --- a/html/user/bolt_admin.css +++ /dev/null @@ -1,63 +0,0 @@ -table.bolt_bar { - margin: 0px; - padding: 0px; - border: 0px; - //border-collapse: collapse; - border-spacing: 0px; -} - -td.bolt_bar { - border: 1px solid #aaaaaa; - padding: 0px; - margin: 0px; -} - -span.green { - padding: 2px; - background-color: #88ff88; - font-size: 0.9em; - font-style: italic; -} -span.yellow { - padding: 2px; - background-color: #ffff88; - font-size: 0.9em; - font-style: italic; -} -span.red { - padding: 2px; - background-color: #ff8888; - font-size: 0.9em; - font-style: italic; -} - -td.bolt_bar1 { - padding: 0; - margin: 0px 0px; - font-size: 0.9em; - background-color: #dddddd; -} - -td.bolt_bar2 { - padding: 0; - margin: 0px 0px; - font-size: 0.9em; - background-color: #44bb44; -} - -tr.bolt_head1 { - background-color: #ccccff; - font-weight: bold; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; - -} - -tr.bolt_head2 { - background-color: #cccccc; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; -} - -span.bolt_small { -} diff --git a/html/user/bolt_course.php b/html/user/bolt_course.php deleted file mode 100644 index 9ba8a94aad..0000000000 --- a/html/user/bolt_course.php +++ /dev/null @@ -1,116 +0,0 @@ -. - -require_once("../inc/util.inc"); - -$user = get_logged_in_user(); - -function phase_name($phase) { - switch ($phase) { - case BOLT_PHASE_STUDY: return "study"; - case BOLT_PHASE_REVIEW: return "review"; - case BOLT_PHASE_REFRESH: return "refresh"; - default: return "unknown phase: $phase"; - } -} - -function mode_name($mode) { - switch ($mode) { - case BOLT_MODE_LESSON: return "lesson"; - case BOLT_MODE_SHOW: return "exercise"; - case BOLT_MODE_ANSWER: return "answer page"; - case BOLT_MODE_FINISHED: return "course completed"; - default: return "unknown mode: $mode"; - } -} - -function action_name($action) { - switch ($action) { - case BOLT_ACTION_NONE: return "None"; - case BOLT_ACTION_NEXT: return "Next"; - case BOLT_ACTION_PREV: return "Previous"; - case BOLT_ACTION_SUBMIT: return "Submit"; - case BOLT_ACTION_QUESTION: return "Question"; - case BOLT_ACTION_COURSE_HOME: return "Course home"; - default: return "unknown: $action"; - } -} - -function show_view($view) { - if ($view->end_time) { - $d = $view->end_time - $view->start_time; - $dur = "$d seconds"; - } else { - $dur = "---"; - } - - if ($view->result_id) { - $result = BoltResult::lookup_id($view->result_id); - $qs = str_replace("action=answer", "action=answer_page", $result->response); - $score = number_format($result->score*100); - $x = "
Score: $score% -
Answer page"; - } - echo " - $view->id - ".time_str($view->start_time)." - $dur - $view->item_name - ".mode_name($view->mode)." $x - "; - //".phase_name($view->phase)." - echo " - ".action_name($view->action)." - - "; -} - -function show_views() { - global $user; - global $course; - - $views = BoltView::enum("user_id=$user->id and course_id=$course->id order by id"); - start_table(); - - table_header("ID", "Time", "Duration", "Item", "Mode", - // "Phase", - "Action"); - foreach ($views as $view) { - show_view($view); - } - end_table(); -} - -require_once("../inc/bolt_db.inc"); -require_once("../inc/bolt_util.inc"); - -$course_id = get_int('course_id'); -$course = BoltCourse::lookup_id($course_id); -if (!$course) error_page("No such course"); -page_head("Your history in $course->name"); - -show_views(); -show_refreshes(); - -echo " - Resume course -

-"; - -page_tail(); -?> diff --git a/html/user/bolt_course_sample.php b/html/user/bolt_course_sample.php deleted file mode 100644 index 52dca82a3e..0000000000 --- a/html/user/bolt_course_sample.php +++ /dev/null @@ -1,136 +0,0 @@ -. - -require_once("../inc/bolt.inc"); - -function part2() { - return sequence( - name('inner seq'), - lesson( - name('lesson 3'), - filename('bolt_sample_lesson.php?n=3') - ) - ); -} - -function basic_review() { - return sequence( - lesson( - name('lesson 1'), - filename('bolt_sample_lesson.php?n=1') - ), - lesson( - name('lesson 2'), - filename('bolt_sample_lesson.php?n=2') - ) - ); -} - -function int_review() { - return lesson( - name('lesson 2'), - filename('bolt_sample_lesson.php?n=2') - ); -} - -function my_rand($student, $unit) { - return rand(); -} - -function sample_select() { - return select( - name('sample select'), - valuator('my_rand'), - lesson( - name('lesson 1'), - filename('bolt_sample_lesson.php?n=1') - ), - lesson( - name('lesson 2'), - filename('bolt_sample_lesson.php?n=2') - ), - lesson( - name('lesson 3'), - filename('bolt_sample_lesson.php?n=3') - ) - ); -} - -function sample_random() { - return random( - name('first lessons'), - number(2), - lesson( - name('lesson 1'), - filename('bolt_sample_lesson.php?n=1') - ), - lesson( - name('lesson 2'), - filename('bolt_sample_lesson.php?n=2') - ), - lesson( - name('lesson 3'), - filename('bolt_sample_lesson.php?n=3') - ) - ); -} - -function xset_with_review() { - return exercise_set( - name('exercise set 1'), - number(2), - exercise( - name('exercise 1'), - filename('bolt_sample_exercise.php?n=1') - ), - exercise( - name('exercise 2'), - filename('bolt_sample_exercise.php?n=2') - ), - exercise( - name('exercise 3'), - filename('bolt_sample_exercise.php?n=3') - ), - repeat(.3, basic_review(), REVIEW), - repeat(.7, int_review(), REVIEW|REPEAT), - repeat(1, null, REPEAT|NEXT), - refresh(array(7, 14, 28)) - ); -} - -function sample_xset() { - return exercise_set( - name('sample exercise set'), - number(1), - exercise( - name('exercise 1'), - filename('bolt_sample_exercise.php?n=1') - ) - ); -} - -return sequence( - name('course'), - // sample_random(), - // xset_with_review(), - sample_select(), - sample_xset(), - part2() -); - -?> diff --git a/html/user/bolt_sched.php b/html/user/bolt_sched.php deleted file mode 100644 index 940ecbf75a..0000000000 --- a/html/user/bolt_sched.php +++ /dev/null @@ -1,661 +0,0 @@ -. - -// Bolt scheduler. -// GET args: -// course_id: course ID -// action: see commands below - -require_once("../inc/bolt.inc"); -require_once("../inc/bolt_sched.inc"); -require_once("../inc/bolt_db.inc"); -require_once("../inc/bolt_ex.inc"); -require_once("../inc/bolt_util.inc"); -require_once("../inc/util.inc"); - -function debug_show_state($state, $tag) { - global $user; - global $refresh; - if ($user->bolt->flags&BOLT_FLAGS_DEBUG) { - echo "$tag state:

"; print_r($state); echo "
\n"; - if ($refresh) { - echo "

Refresh ID: $refresh->id

"; - } - echo "


\n"; - } -} -function debug_show_item($item) { - global $user; - if ($user->bolt->flags&BOLT_FLAGS_DEBUG) { - echo "Item:
"; print_r($item); echo "
\n"; - echo "
\n"; - } -} - -function update_info() { - global $user; - $sex = get_int('sex'); - $birth_year = get_int('birth_year'); - $user->bolt->update("sex=$sex, birth_year=$birth_year"); -} - -// The user clicked something on a page. -// Look up the view record (the ID is in the URL) and update it -// with the action and the time. -// Return the record. -// -function finalize_view($view_id, $action) { - global $user; - if (!$view_id) return null; - $view = BoltView::lookup_id($view_id); - if (!$view) { - error_page("no view"); - } - if ($view->user_id != $user->id) { - error_page("wrong user"); - } - if (!$view->end_time) { - $now = time(); - $view->update("end_time=$now, action=$action"); - } - return $view; -} - -function default_mode($item) { - return $item->is_exercise()?BOLT_MODE_SHOW:BOLT_MODE_LESSON; -} - -// A page is being shown to the user; make a record of it -// -function create_view($iter, $mode, $prev_view_id) { - global $user; - global $course; - - $now = time(); - $item = $iter->item; - if (!$item) { - $item = null; - $item->name = '--end--'; - } - $state = $iter->encode_state(); - debug_show_state($iter->state, "Ending"); - 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)"); -} - -function page_header() { - global $course; - echo " - $course->name - - - "; - if (function_exists('bolt_header')) bolt_header(); -} - -function page_footer() { - if (function_exists('bolt_footer')) bolt_footer(); - echo ""; -} - -// show a page saying the course has been completed -// -function show_finished_page($view_id, $prev_view_id) { - global $course; - global $url_args; - - page_header("Course completed"); - if ($course->bossa_app_id) { - require_once("../inc/bossa_db.inc"); - $app = BossaApp::lookup_id($course->bossa_app_id); - echo " - Congratulations - you have completed the training for $course->name. -

- You may now - bossa_app_id>do work. - "; - } else { - echo "Congratulations - you have completed this course."; - $links[] = ""; - $up_link = "Course home page"; - show_nav($links, $up_link, $view_id); - } - page_footer(); -} - -function show_refresh_finished() { - page_header("Refresh completed"); - echo "Return to courses"; - page_footer(); -} - -function show_nav($links, $up_link, $view_id) { - global $course; - - echo "

- - "; - foreach ($links as $link) { - echo "\n"; - } - echo "
$link
-
-
-
- id> - - - -
- -
-

- $up_link - "; -} - -// show an item (lesson, exercise, answer page) -// -function show_item($iter, $view_id, $prev_view_id, $mode, $repeat=null) { - global $user; - global $course; - global $bolt_ex; - global $refresh; - global $url_args; - - $item = $iter->item; - page_header(); - $bolt_query_string = $item->query_string; - - $links = array(); - if ($prev_view_id) { - $links[] = ""; - } - - $next = ""; - - if ($item->is_exercise()) { - $bolt_ex->mode = $mode; - $bolt_ex->index = 0; - switch ($mode) { - case BOLT_MODE_SHOW: - echo " -

- - id> - - "; - if ($refresh) { - echo " - id> - "; - } - srand($view_id); - require($item->filename); - if (function_exists('bolt_divide')) bolt_divide(); - $next = "
"; - break; - case BOLT_MODE_ANSWER: - require($item->filename); - if (function_exists('bolt_divide')) bolt_divide(); - $score_pct = number_format($bolt_ex->score*100); - echo "Score: $score_pct%"; - break; - } - } else { - require_once($item->filename); - if (function_exists('bolt_divide')) bolt_divide(); - } - - if ($repeat) { - $avg = number_format($repeat->avg_score*100, 0); - echo "

Score on this exercise set: $avg%"; - if ($repeat->flags & REVIEW) { - //echo "

";
-            //print_r($repeat);
-            //echo "
"; - $name = urlencode($repeat->unit->name); - $r = "Review, then repeat exercises"; - $links[] = $r; - } - if ($repeat->flags & REPEAT) { - $r = "Repeat exercises"; - $links[] = $r; - } - if ($repeat->flags & NEXT) { - $links[] = $next; - } - } else { - $links[] = $next; - } - - $up_link = "Course home page"; - show_nav($links, $up_link, $view_id); - - page_footer(); - - if ($refresh) { - $refresh->update("last_view_id=$view_id"); - } else { - $e = new BoltEnrollment(); - $e->user_id = $user->id; - $e->course_id = $course->id; - $e->update("last_view_id=$view_id"); - } -} - -// Show the student the results of an old exercise; no navigation items -// -function show_answer_page($iter, $score) { - global $bolt_ex; - - $bolt_ex->mode = BOLT_MODE_ANSWER; - $bolt_ex->index = 0; - - $item = $iter->item; - page_header(); - $bolt_query_string = $item->query_string; - require_once($item->filename); - if (function_exists('bolt_divide')) bolt_divide(); - $score_pct = number_format($score*100); - echo "Score: $score_pct%"; - page_footer(); -} - -function start_course() { - global $user; - global $course; - global $course_doc; - - BoltEnrollment::delete($user->id, $course->id); - $iter = new BoltIter($course_doc); - $iter->at(); - - $now = time(); - $mode = default_mode($iter->item); - $view_id = create_view($iter, $mode, 0); - BoltEnrollment::insert("(create_time, user_id, course_id, last_view_id) values ($now, $user->id, $course->id, $view_id)"); - show_item($iter, $view_id, 0, $mode); -} - -function start_refresh() { - global $course_doc; - global $refresh; - - $xset_result = BoltXsetResult::lookup_id($refresh->xset_result_id); - if (!$xset_result) error_page("Exercise set result not found"); - $view = BoltView::lookup_id($xset_result->view_id); - if (!$view) error_page("view not found"); - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - $iter->at(); - $xset = $iter->xset; - if (!$xset || $xset->name != $xset_result->name) { - error_page("missing exercise set"); - } - $xset->restart($iter); - $iter->at(); - $mode = default_mode($iter->item); - $view_id = create_view($iter, $mode, 0); - show_item($iter, $view_id, 0, $mode); -} - -function show_next($iter, $view) { - global $refresh, $user, $course; - $iter->next(); - - if ($refresh) { - $iter->at(); - if (!$iter->xset) { - // if we're doing a refresh and are no longer in an xset, - // we must have finished the refresh - // - show_refresh_finished(); - $refresh->update('count=count+1'); - return; - } - } - - if ($iter->item) { - $state = $iter->encode_state(); - $mode = default_mode($iter->item); - $view_id = create_view($iter, $mode, $view->id); - show_item($iter, $view_id, $view->id, $mode); - } else { - // course finished - $iter->frac_done = 1; - $fin_view_id = create_view($iter, BOLT_MODE_FINISHED, $view->id); - $e = new BoltEnrollment(); - $e->user_id = $user->id; - $e->course_id = $course->id; - $e->update("last_view_id=$fin_view_id"); - show_finished_page($fin_view_id, $view->id); - } -} - -$user = get_logged_in_user(); -BoltUser::lookup($user); -$course_id = get_int('course_id'); -$refresh_id = get_int('refresh_id', true); -$refresh = null; -$url_args = "course_id=$course_id"; -if ($refresh_id) { - $refresh = BoltRefreshRec::lookup_id($refresh_id); - if (!$refresh) error_page("No such refresh"); - if ($refresh->user_id != $user->id) error_page("Wrong user"); - if ($refresh->course_id != $course_id) error_page("Wrong course"); - $url_args .= "&refresh_id=$refresh_id"; -} -$course = BoltCourse::lookup_id($course_id); -if (!$course) { - error_page("no such course"); -} -$view_id = get_int('view_id', true); -$action = sanitize_tags(get_str('action', true)); -$course_doc = require_once($course->doc_file()); - -switch ($action) { -case 'start': - if (info_incomplete($user)) { - request_info($user, $course); - exit(); - } - if ($refresh) { - start_refresh(); - exit(); - } - $e = BoltEnrollment::lookup($user->id, $course_id); - if ($e) { - page_header(); - echo "You are already enrolled in $course->name. -

- Are you sure you want to start over from the beginning? -

- "; - show_button( - "bolt_sched.php?action=start_confirm&$url_args", - "Yes", - "Start this course from the beginning" - ); - show_button( - "bolt_sched.php?action=resume&$url_args", - "Resume", - "Resume course from current position" - ); - page_footer(); - exit(); - } - // fall through -case 'start_confirm': - start_course(); - break; -case 'update_info': - update_info(); - start_course(); - break; -case 'prev': - $view = finalize_view($view_id, BOLT_ACTION_PREV); - debug_show_state(unserialize($view->state), "Initial"); - 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 = $view->mode; - if ($mode == BOLT_MODE_ANSWER) { - $v2 = BoltView::lookup_id($view->prev_view_id); - $result = BoltResult::lookup_id($v2->result_id); - srand($v2->id); - $bolt_ex->score = $result->score; - $bolt_ex->query_string = $result->response; - } - $view_id = create_view($iter, $mode, $view->prev_view_id); - show_item($iter, $view_id, $view->prev_view_id, $mode); - } else { - error_page("At start of course"); - } - break; -case 'next': // "next" button in lesson or exercise answer page - $view = finalize_view($view_id, BOLT_ACTION_NEXT); - debug_show_state(unserialize($view->state), "Initial"); - - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - show_next($iter, $view); - break; -case 'answer': // submit answer in exercise - $view = finalize_view($view_id, BOLT_ACTION_SUBMIT); - debug_show_state(unserialize($view->state), "Initial"); - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - $iter->at(); - - debug_show_item($iter->item); - $item = $iter->item; - if (!$item->is_exercise()) { - print_r($item); - error_page("expected an exercise"); - } - if ($view->item_name != $item->name) { - error_page("unexpected name"); - } - - // compute the score - - $bolt_ex->query_string = $_SERVER['QUERY_STRING']; - $bolt_ex->mode = BOLT_MODE_SCORE; - $bolt_ex->index = 0; - $bolt_ex->score = 0; - $bolt_query_string = $item->query_string; - srand($view_id); - ob_start(); // buffer output to avoid showing exercise text - require($item->filename); - ob_end_clean(); - - $bolt_ex->score /= $bolt_ex->index; - - if ($item->callback) { - call_user_func( - $item->callback, $bolt_ex->score, $bolt_ex->query_string - ); - } - - // make a record of the result - - $qs = BoltDb::escape_string($_SERVER['QUERY_STRING']); - $now = time(); - $result_id = BoltResult::insert( - "(create_time, user_id, course_id, view_id, item_name, score, response) - values ($now, $user->id, $course->id, $view->id, '$view->item_name', $bolt_ex->score, '$qs')" - ); - $view->update("result_id=$result_id"); - - // If this is part of an exercise set, call its callback function - // - $repeat = null; - $xset = $iter->xset; - if ($xset) { - $is_last = $xset->xset_record_score( - $iter, $bolt_ex->score, $view->id, $avg_score, $repeat - ); - if ($repeat) $repeat->avg_score = $avg_score; - if ($is_last) { - // if the exercise set if finished, make or update DB records - // - if ($xset->callback) { - call_user_func($xset->callback, $avg_score); - } - $now = time(); - $id = BoltXsetResult::insert("(create_time, user_id, course_id, name, score, view_id) values ($now, $user->id, $course->id, '$xset->name', $avg_score, $view_id)"); - $refresh_intervals = $xset->refresh; - if ($refresh_intervals) { - $refresh_rec = BoltRefreshRec::lookup( - "user_id=$user->id and course_id=$course->id and name='$xset->name'" - ); - if ($refresh_rec) { - $count = $refresh_rec->count; - $n = count($refresh_intervals->intervals); - if ($count >= $n) { - $count = $n - 1; - } - $due_time = time() + $refresh_intervals->intervals[$count]*86400; - $refresh_rec->update("create_time=$now, xset_result_id=$id, due_time=$due_time"); - } else { - $due_time = time() + $refresh_intervals->intervals[0]*86400; - BoltRefreshRec::insert( - "(user_id, course_id, name, create_time, xset_result_id, due_time, count) values ($user->id, $course->id, '$xset->name', $now, $id, $due_time, 0)" - ); - } - } - } - } - - // show the answer page - - if ($item->has_answer_page) { - srand($view_id); - $view_id = create_view($iter, BOLT_MODE_ANSWER, $view->id); - show_item($iter, $view_id, $view->id, BOLT_MODE_ANSWER, $repeat); - } else { - show_next($iter, $view); - } - break; -case 'answer_page': - $view = BoltView::lookup_id($view_id); - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - $iter->at(); - if ($iter->item->name != $view->item_name) { - error_page("Exercise no longer exists in course"); - } - $result = BoltResult::lookup_id($view->result_id); - srand($view_id); - $bolt_ex->query_string = $result->response; - show_answer_page($iter, $result->score); - break; -case 'course_home': - $view = finalize_view($view_id, BOLT_ACTION_COURSE_HOME); - Header("Location: bolt.php"); - break; -case 'review': - // user chose to do review then repeat an exercise set - // - $view = finalize_view($view_id, BOLT_ACTION_REVIEW); - debug_show_state(unserialize($view->state), "Initial"); - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - $iter->at(); - if (!$iter->xset) { - echo "NO XSET"; exit; - } - $xset = $iter->xset; - $unit_name = sanitize_tags(get_str('unit_name')); - $found = $xset->start_review($iter, $unit_name); - if (!$found) { - echo "REVIEW UNIT MISSING"; exit; - } - $iter->at(); - $mode = default_mode($iter->item); - $view_id = create_view($iter, $mode, $view->id); - show_item($iter, $view_id, $view->id, $mode); - break; -case 'repeat': - // user chose to repeat an exercise set - // - $view = finalize_view($view_id, BOLT_ACTION_REPEAT); - debug_show_state(unserialize($view->state), "Initial"); - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - $iter->at(); - if (!$iter->xset) { - echo "NO XSET"; exit; - } - $xset = $iter->xset; - $xset->restart($iter); - $iter->at(); - $mode = default_mode($iter->item); - $view_id = create_view($iter, $mode, $view->id); - show_item($iter, $view_id, $view->id, $mode); - break; -case 'resume': - // user chose to resume a course or refresh - // - if ($refresh) { - if ($refresh->last_view_id) { - $view = BoltView::lookup_id($refresh->last_view_id); - } else { - start_refresh(); - exit(); - } - } else { - $view = null; - $e = BoltEnrollment::lookup($user->id, $course_id); - if ($e) { - $view = BoltView::lookup_id($e->last_view_id); - } - if (!$view) { - start_course(); - break; - } - } - if ($view->mode == BOLT_MODE_FINISHED) { - show_finished_page($view->id, $view->prev_view_id); - break; - } - $iter = new BoltIter($course_doc); - $iter->decode_state($view->state); - $iter->at(); - $mode = $view->mode; - if ($view->item_name == $iter->item->name && ($mode == BOLT_MODE_ANSWER)) { - // if we're returning to an answer page, - // we need to look up the user's responses and the score. - // - $view_orig = BoltView::lookup_id($view->prev_view_id); - $result = BoltResult::lookup_id($view_orig->result_id); - srand($view_orig->id); - $bolt_ex->query_string = $result->response; - $bolt_ex->score = $result->score; - $bolt_ex->index = 0; - $view_id = create_view($iter, $mode, $view_orig->id); - show_item($iter, $view_id, $view_orig->id, $mode); - } else { - $view_id = create_view($iter, $mode, $view->id); - show_item($iter, $view_id, $view->id, $mode); - } - break; -case 'question': - $view = finalize_view($view_id, BOLT_ACTION_QUESTION); - debug_show_state(unserialize($view->state), "Initial"); - $now = time(); - $question = BoltDb::escape_string(get_str('question')); - BoltQuestion::insert("(create_time, user_id, course_id, name, mode, question, state) values ($now, $user->id, $course->id, '$view->item_name', $view->mode, '$question', 0)"); - page_header(); - echo " - Thanks; we have recorded your question. - Questions help us improve this course. - We aren't able to individually respond to all questions. - Responses are delivered as private messages. -

- Resume course - "; - page_footer(); - break; -default: - error_page("unknown action: $action"); -} - -?> diff --git a/html/user/bossa_apps.php b/html/user/bossa_apps.php deleted file mode 100644 index e2593cac38..0000000000 --- a/html/user/bossa_apps.php +++ /dev/null @@ -1,69 +0,0 @@ -. - -require_once("../inc/util.inc"); -require_once("../inc/bossa_db.inc"); -require_once("../inc/bolt_db.inc"); - -function show_app($app) { - global $user; - if ($app->bolt_course_id) { - if ($user) { - switch (bolt_course_status($app->bolt_course_id, $user->id)) { - case BOLT_COURSE_NOT_STARTED: - $x = "bolt_course_id>Take training course"; - break; - case BOLT_COURSE_STARTED: - $x = "bolt_course_id>Finish training course"; - break; - case BOLT_COURSE_FINISHED: - $x = "id>Get job"; - break; - } - } else { - $x = "bolt_course_id>Take training course"; - } - } else { - $x = "id>Get job"; - } - $est = number_format($app->time_estimate/60., 2); - $limit = number_format($app->time_limit/60., 2); - row2("$app->name

$app->description
Time: $est min. average, $limit min limit

", $x); -} - -function show_apps() { - $apps = BossaApp::enum(); - foreach ($apps as $app) { - if ($app->hidden) continue; - show_app($app); - } -} - -function main() { - page_head("Bossa apps"); - start_table(); - show_apps(); - end_table(); - page_tail(); -} - -$user = get_logged_in_user(); - -main(); - -?> diff --git a/html/user/bossa_example4.php b/html/user/bossa_example4.php deleted file mode 100644 index f1d2d829e8..0000000000 --- a/html/user/bossa_example4.php +++ /dev/null @@ -1,69 +0,0 @@ -. - -require_once("../inc/util.inc"); -require_once("../inc/bossa.inc"); -require_once("../inc/bossa_example4.inc"); - -function handle_add($job, $inst) { - $f = null; - $f->x = get_int('pic_x'); - $f->y = get_int('pic_y'); - $f->type = sanitize_tags(get_str('type')); - $c = sanitize_tags(get_str('comment', true)); - if (strstr($c, "(optional)")) $c = ""; - $f->comment = $c; - $output = $inst->get_opaque_data(); - $output->features[] = $f; - $inst->set_opaque_data($output); - header("location: bossa_example4.php?bji=$inst->id"); -} - -function handle_delete($job, $inst, $index) { - $output = $inst->get_opaque_data(); - $features = $output->features; - array_splice($features, $index, 1); - $output->features = $features; - $inst->set_opaque_data($output); - header("location: bossa_example4.php?bji=$inst->id"); -} - -$bji = get_int("bji"); -if (!bossa_lookup_job($bji, $job, $inst, $u)) { - error_page("No such instance"); -} -$user = get_logged_in_user(); -if ($u->id != $user->id) { - error_page("Not your job"); -} - -$action = get_str("action", true); -switch ($action) { -case "add": - handle_add($job, $inst); - break; -case "delete": - $index = get_int("index"); - handle_delete($job, $inst, $index); - break; -default: - job_show($job, $inst, $user); - break; -} - -?> diff --git a/html/user/bossa_get_job.php b/html/user/bossa_get_job.php deleted file mode 100644 index 34c054343f..0000000000 --- a/html/user/bossa_get_job.php +++ /dev/null @@ -1,38 +0,0 @@ -. - -require_once("../inc/util.inc"); -require_once("../inc/bossa_db.inc"); -require_once("../inc/bossa_impl.inc"); - -$user = get_logged_in_user(); -BossaUser::lookup($user); - -$bossa_app_id = get_int('bossa_app_id'); -$app = BossaApp::lookup_id($bossa_app_id); - -if (!$app) { - error_page("no such app: $bossa_app_id"); -} - -{ - $trans = new BossaTransaction(); - show_next_job($app, $user); -} - -?> diff --git a/html/user/bossa_job_finished.php b/html/user/bossa_job_finished.php deleted file mode 100644 index 3ef0a82752..0000000000 --- a/html/user/bossa_job_finished.php +++ /dev/null @@ -1,54 +0,0 @@ -. - -require_once("../inc/util.inc"); -require_once("../inc/bossa_db.inc"); -require_once("../inc/bossa_impl.inc"); - -$user = get_logged_in_user(); -$inst = BossaJobInst::lookup_id(get_int('bji')); -if (!$inst) { - error_page("No such job instance"); -} -if ($inst->user_id != $user->id) { - error_page("Bad user ID"); -} -if ($inst->finish_time) { - error_page("You already finished this job"); -} -$job = BossaJob::lookup_id($inst->job_id); -if (!$job) { - error_page("No such job"); -} - -$app = BossaApp::lookup_id($job->app_id); -$file = "../inc/$app->short_name.inc"; -require_once($file); - -{ - $trans = new BossaTransaction(); - - $now = time(); - $inst->update("finish_time=$now, timeout=0"); - - BossaUser::lookup($user); - job_finished($job, $inst, $user); - show_next_job($app, $user); -} - -?>