';
echo '';
print_footer($this->course);
exit;
} else {
error("Category $categoryid not found", "category.php?id={$this->course->id}");
}
}
/**
* Outputs a table to allow editing of an existing category
*
* @param object category
*/
function output_edit_single_table($category) {
global $USER;
$publishoptions[0] = get_string("no");
$publishoptions[1] = get_string("yes");
$strupdate = get_string('update');
unset ($edittable);
$edittable->head = array ($this->str->parent, $this->str->category, $this->str->categoryinfo, $this->str->publish, $this->str->action);
$edittable->width = 200;
$edittable->data[] = array();
$edittable->tablealign = 'center';
/// Each section below adds a data cell to the table row
$viableparents = $this->categorystrings;
$this->set_viable_parents($viableparents, $category);
$viableparents = array(0=>$this->str->top) + $viableparents;
$edittable->align['parent'] = "left";
$edittable->wrap['parent'] = "nowrap";
$row['parent'] = choose_from_menu ($viableparents, "updateparent", "{$category->parent}", "", "", "", true);
$edittable->align['category'] = "left";
$edittable->wrap['category'] = "nowrap";
$row['category'] = '';
$edittable->align['info'] = "left";
$edittable->wrap['info'] = "nowrap";
$row['info'] = '';
$edittable->align['publish'] = "left";
$edittable->wrap['publish'] = "nowrap";
$selected = (boolean)$category->publish ? 1 : 0;
$row['publish'] = choose_from_menu ($publishoptions, "updatepublish", $selected, "", "", "", true);
$edittable->align['action'] = "left";
$edittable->wrap['action'] = "nowrap";
$row['action'] = '';
$edittable->data[] = $row;
// wrap the table in a form and output it
echo '';
}
/**
* Creates an array of "full-path" category strings
* Structure:
* key => string
* where key is the category id, and string contains the name of all ancestors as well as the particular category name
* E.g. '123'=>'Language / English / Grammar / Modal Verbs"
*
* @param array $categories an array containing categories arranged in a tree structure
*/
function expanded_category_strings($categories, $parent=null) {
$prefix = is_null($parent) ? '' : "$parent / ";
$categorystrings = array();
foreach ($categories as $key => $category) {
$expandedname = "$prefix$category->name";
$categorystrings[$key] = $expandedname;
if (isset($category->children)) {
$categorystrings = $categorystrings + $this->expanded_category_strings($category->children, $expandedname);
}
}
return $categorystrings;
}
/**
* Arranges the categories into a hierarchical tree
*
* If a category has children, it's "children" property holds an array of children
* The questioncount for each category is also calculated
*
* @param array records a flat list of the categories
* @return array categorytree a hierarchical list of the categories
*/
function arrange_categories($records) {
//todo: get the question count for all records with one sql statement: select category, count(*) from quiz_questions group by category
$levels = array();
// build a levels array, which places each record according to it's depth from the top level
$parents = array(0);
while (!empty($parents)) {
$children = array();
foreach ($records as $record) {
if (in_array($record->parent, $parents)) {
$children[] = $record->id;
}
}
if (!empty($children)) {
$levels[] = $children;
}
$parents = $children;
}
// if there is no hierarchy (e.g., if all records have parent == 0), set level[0] to these keys
if (empty($levels)) {
$levels[0] = array_keys($records);
}
// build a hierarchical array that depicts the parent-child relationships of the categories
$categorytree = array();
for ($index = count($levels) - 1; $index >= 0; $index--) {
foreach($levels[$index] as $key) {
$parentkey = $records[$key]->parent;
if (!($records[$key]->questioncount = count_records('quiz_questions', 'category', $records[$key]->id, 'hidden', 0))) {
$records[$key]->questioncount = 0;
}
if ($parentkey == 0) {
$categorytree[$key] = $records[$key];
} else {
$records[$parentkey]->children[$key] = $records[$key];
}
}
}
return $categorytree;
}
/**
* Sets the viable parents
*
* Viable parents are any except for the category itself, or any of it's descendants
* The parentstrings parameter is passed by reference and changed by this function.
*
* @param array parentstrings a list of parentstrings
* @param object category
*/
function set_viable_parents(&$parentstrings, $category) {
unset($parentstrings[$category->id]);
if (isset($category->children)) {
foreach ($category->children as $child) {
$this->set_viable_parents($parentstrings, $child);
}
}
}
/**
* Gets quiz categories
*
* @param int parent - if given, restrict records to those with this parent id.
* @param string sort - [[sortfield [,sortfield]] {ASC|DESC}]
* @return array categories
*/
function get_quiz_categories($parent=null, $sort="sortorder ASC") {
$admin = isadmin();
if ($admin) {
if (is_null($parent)) {
$categories = get_records("quiz_categories", "", "", $sort);
} else {
$categories = get_records("quiz_categories", "parent", $parent, $sort);
}
} else {
if (is_null($parent)) {
$categories = get_records('quiz_categories', 'course', "{$this->course->id}", $sort);
} else {
$select = "parent = '$parent' AND course = '{$this->course->id}'";
$categories = get_records_select('quiz_categories', $select, $sort);
}
}
return $categories;
}
/**
* Deletes an existing quiz category
*
* @param int deletecat id of category to delete
* @param int destcategoryid id of category which will inherit the orphans of deletecat
*/
function delete_category($deletecat, $destcategoryid = null) {
global $USER;
if (!$category = get_record("quiz_categories", "id", $deletecat)) { // security
error("No such category $deletecat!", "category.php?id={$this->course->id}");
}
if (!is_null($destcategoryid)) { // Need to move some questions before deleting the category
if (!$category2 = get_record("quiz_categories", "id", $destcategoryid)) { // security
error("No such category $destcategoryid!", "category.php?id={$this->course->id}");
}
if (! quiz_move_questions($category->id, $category2->id)) {
error("Error while moving questions from category '$category->name' to '$category2->name'", "category.php?id={$this->course->id}");
}
} else {
// todo: delete any hidden questions that are not actually in use any more
if ($count = count_records("quiz_questions", "category", $category->id)) {
$vars->name = $category->name;
$vars->count = $count;
print_simple_box(get_string("categorymove", "quiz", $vars), "center");
$this->initialize();
$categorystrings = $this->categorystrings;
unset ($categorystrings[$category->id]);
echo "";
print_footer($this->course);
exit;
}
}
delete_records("quiz_categories", "id", $category->id);
/// Send the children categories to live with their grandparent
if ($childcats = get_records("quiz_categories", "parent", $category->id)) {
foreach ($childcats as $childcat) {
if (! set_field("quiz_categories", "parent", $category->parent, "id", $childcat->id)) {
error("Could not update a child category!", "category.php?id={$this->course->id}");
}
}
}
/// Finally delete the category itself
if (delete_records("quiz_categories", "id", $category->id)) {
notify(get_string("categorydeleted", "quiz", $category->name), 'green');
}
}
/**
* Moves a category up or down in the display order
*
* @param string direction up|down
* @param int categoryid id of category to move
*/
function move_category_up_down ($direction, $categoryid) {
/// Move a category up or down
$swapcategory = NULL;
$movecategory = NULL;
if ($direction == 'up') {
if ($movecategory = get_record("quiz_categories", "id", $categoryid)) {
$categories = $this->get_quiz_categories("$movecategory->parent", 'parent, sortorder, name');
foreach ($categories as $category) {
if ($category->id == $movecategory->id) {
break;
}
$swapcategory = $category;
}
}
}
if ($direction == 'down') {
if ($movecategory = get_record("quiz_categories", "id", $categoryid)) {
$categories = $this->get_quiz_categories("$movecategory->parent", 'parent, sortorder, name');
$choosenext = false;
foreach ($categories as $category) {
if ($choosenext) {
$swapcategory = $category;
break;
}
if ($category->id == $movecategory->id) {
$choosenext = true;
}
}
}
}
if ($swapcategory and $movecategory) { // Renumber everything for robustness
$count=0;
foreach ($categories as $category) {
$count++;
if ($category->id == $swapcategory->id) {
$category = $movecategory;
} else if ($category->id == $movecategory->id) {
$category = $swapcategory;
}
if (! set_field("quiz_categories", "sortorder", $count, "id", $category->id)) {
notify("Could not update that category!");
}
}
}
}
/**
* Changes the parent of a category
*
* @param int categoryid
* @param int parentid
*/
function move_category($categoryid, $parentid) {
/// Move a category to a new parent
if ($tempcat = get_record("quiz_categories", "id", $categoryid)) {
if ($tempcat->parent != $parentid) {
if (! set_field("quiz_categories", "parent", $parentid, "id", $tempcat->id)) {
notify("Could not update that category!");
}
}
}
}
/**
* Changes the published status of a category
*
* @param boolean publish
* @param int categoryid
*/
function publish_category($publish, $categoryid) {
/// Hide or publish a category
$publish = ($publish == false) ? 0 : 1;
$tempcat = get_record("quiz_categories", "id", $categoryid);
if ($tempcat) {
if (! set_field("quiz_categories", "publish", $publish, "id", $tempcat->id)) {
notify("Could not update that category!");
}
}
}
/**
* Creates a new category with given params
*
* @param int newparent
* @param string newcategory the name
* @param string newinfo
* @param int newpublish
* @param int newcourse the id of the associated course
*/
function add_category($newparent, $newcategory, $newinfo, $newpublish, $newcourse) {
$cat = NULL;
$cat->parent = $newparent;
$cat->name = $newcategory;
$cat->info = $newinfo;
$cat->publish = $newpublish;
$cat->course = $newcourse;
$cat->sortorder = 999;
$cat->stamp = make_unique_id_code();
if (!insert_record("quiz_categories", $cat)) {
error("Could not insert the new quiz category '$newcategory'", "category.php?id={$newcourse}");
} else {
notify(get_string("categoryadded", "quiz", $newcategory), 'green');
}
}
/**
* Updates an existing category with given params
*
* @param int updateid
* @param int updateparent
* @param string updatename
* @param string updateinfo
* @param int updatepublish
* @param int courseid the id of the associated course
*/
function update_category($updateid, $updateparent, $updatename, $updateinfo, $updatepublish, $courseid) {
$cat = NULL;
$cat->id = $updateid;
$cat->parent = $updateparent;
$cat->name = $updatename;
$cat->info = $updateinfo;
$cat->publish = $updatepublish;
if (!update_record("quiz_categories", $cat)) {
error("Could not update the category '$updatename'", "category.php?id={$courseid}");
} else {
notify(get_string("categoryupdated", 'quiz'), 'green');
}
}
}
?>