question bank: MDL-17302 refactor question bank display code into a class.

Step 3. Start working ot the code to initialise things from a list of columns, and build the corresponding SQL query.
This commit is contained in:
tjhunt
2009-01-21 08:49:15 +00:00
parent 874b756b70
commit b221dc6f23
2 changed files with 143 additions and 1 deletions
+1
View File
@@ -441,6 +441,7 @@ $string['unknownrole'] = 'Unknown role \"$a\"';
$string['unknownuseraction'] = 'Sorry, I do not understand this user action';
$string['unknownuserselector'] = 'Unknown user selector';
$string['unknownmodulename'] = 'Unknown module name for form';
$string['unknownsortcolumn'] = 'Unknown sort column $a';
$string['unknoworder'] = 'Unknown ordering';
$string['unknowparamtype'] = 'Unknown parameter type: $a';
$string['unknowquestiontype'] = 'Unsupported question type $a';
+142 -1
View File
@@ -238,7 +238,8 @@ abstract class question_bank_column_base {
/**
* @param object $question the row from the $question table, augmented with extra information.
* @return string internal name for this column. Used as a CSS class name, and to store information about the current sort.
* @return string internal name for this column. Used as a CSS class name,
* and to store information about the current sort. Must match PARAM_ALPHA.
*/
abstract protected function get_name();
@@ -262,6 +263,9 @@ abstract class question_bank_column_base {
* If to columns try to use the same alias with different joins, you get an error.
* The only table included by default is the question table, which is aliased to 'q'.
*
* It is importnat that your join simply adds additional data (or NULLs) to the
* existing rows of the query. It must not cause additional rows.
*
* @return array 'table_alias' => 'JOIN clause'
*/
public function get_extra_joins() {
@@ -625,6 +629,12 @@ class question_bank_view {
protected $quizorcourseid;
protected $contexts;
protected $cm;
protected $knowncolumntypes;
protected $visiblecolumns;
protected $requiredcolumns;
protected $sort;
protected $countsql;
protected $loadsql;
public function __construct($contexts, $pageurl, $cm = null) {
global $CFG, $COURSE;
@@ -647,6 +657,137 @@ class question_bank_view {
} else {
$this->editquestionurl->param('courseid', $COURSE->id);
}
$this->init_column_types();
$this->init_columns(array('checkbox', 'qtype', 'questionname', 'creatorname',
'modifiername', 'editaction', 'previewaction', 'moveaction', 'deleteaction'));
$this->init_sort();
}
protected function init_columns() {
$types = array(
new question_bank_checkbox_column($this),
new question_bank_question_type_column($this),
new question_bank_question_name_column($this),
new question_bank_creator_name_column($this),
new question_bank_modifier_name_column($this),
new question_bank_edit_action_column($this),
new question_bank_preview_action_column($this),
new question_bank_move_action_column($this),
new question_bank_delete_action_column($this),
);
$this->knowncolumntypes = array();
foreach ($columns as $col) {
$this->knowncolumntypes[$col->get_name()] = $col;
}
}
protected function init_columns($wanted) {
$this->visiblecolumns = array();
foreach ($wanted as $colname) {
if (!isset($this->knowncolumntypes[$colname])) {
throw new coding_exception('Unknown column type ' . $colname . ' requested in init columns.');
}
$this->visiblecolumns[$colname] = $this->knowncolumntypes[$colname];
}
$this->requiredcolumns = $this->visiblecolumns;
}
protected function init_sort() {
$this->init_sort_from_params();
if (empty($this->sort)) {
$this->sort = $this->default_sort();
}
}
/**
* Deal with a sort name of the forum columnname, or colname_subsort by
* breaking it up, validating the bits that are presend, and returning them.
* If there is no subsort, then $subsort is returned as ''.
* @return array array($colname, $subsort).
*/
protected function parse_subsort($sort) {
/// Do the parsing.
if (strpos($sort, '_') !== false) {
list($colname, $subsort) = explode('_', $sort, 2);
} else {
$colname = $sort;
$subsort = '';
}
/// Validate the column name.
if (!isset($this->knowncolumntypes[$colname]) || !$this->knowncolumntypes[$colname]->is_sortable()) {
$this->baseurl->remove_params('qbs1', 'qbs2', 'qbs3');
throw new moodle_exception('unknownsortcolumn', '', $link = $this->baseurl->out(), $colname);
}
/// Validate the subsort, if present.
if ($subsort) {
$subsorts = $this->knowncolumntypes[$colname]->is_sortable();
if (!is_array($subsorts) || !isset($subsorts[$subsort])) {
throw new moodle_exception('unknownsortcolumn', '', $link = $this->baseurl->out(), $sort);
}
}
return array($colname, $subsort);
}
protected function init_sort_from_params() {
$this->sort = array();
for ($i = 1; $i < 3; $i++) {
if (!$sort = optional_param('qbs1', '', PARAM_ALPHAEXT)) {
break;
}
// Work out the appropriate order.
$order = 1;
if ($sort[0] == '-') {
$order = -1;
$sort = substr($sort1, 1);
if (!$sort) {
break;
}
}
// Deal with subsorts.
list($colname, $subsort) = $this->parse_subsort($sort);
$this->requiredcolumns[$colname] = $this->knowncolumntypes[$colname];
$sort[$sort] = $order;
}
}
protected function default_sort() {
return array('qtype' => 1, 'questionname' => 1);
}
protected function build_query_sql() {
/// Get the required tables.
$joins = array();
foreach ($this->requiredcolumns as $column) {
$extrajoins = $column->get_extra_joins();
foreach ($extrajoins as $prefix => $join) {
if (isset($joins[$prefix]) && $joins[$prefix] != $join) {
throw new coding_exception('Join ' . $join . ' conflicts with previous join ' . $joins[$prefix]);
}
$joins[$prefix] = $join;
}
}
/// Get the required fields.
$fields = array();
foreach ($this->visiblecolumns as $column) {
$fields += $column->get_required_fields();
}
$fields = array_unique($fields);
/// Build the order by clause.
$sorts = array();
foreach ($this->sort as $sort => $order) {
list($colname, $subsort) = $this->parse_subsort($sort);
$sorts[] = $this->knowncolumntypes[$colname]->sort_expression($order < 0, $subsort);
}
/// Build the SQL.
$sql = ' FROM {question} q ' . implode(' ', $joins);
// TODO where clause.
$sql .= ' ORDER BY ' . implode(', ', $sorts);
$this->countsql = 'SELECT count(1)' . $sql;
$this->loadsql = 'SELECT ' . implode(', ', $fields) . $sql;
}
public function base_url($questionid) {