Merge branch '42299-26' of git://github.com/samhemelryk/moodle

Conflicts:
	version.php
This commit is contained in:
Dan Poltawski
2013-10-24 15:47:48 +08:00
13 changed files with 252 additions and 9 deletions
+12
View File
@@ -104,6 +104,18 @@ switch ($action) {
);
}
break;
case 'expandcategory':
$categoryid = required_param('categoryid', PARAM_INT);
$coursecat = coursecat::get($categoryid);
\core_course\management\helper::record_expanded_category($coursecat);
$outcome->outcome = true;
break;
case 'collapsecategory':
$categoryid = required_param('categoryid', PARAM_INT);
$coursecat = coursecat::get($categoryid);
\core_course\management\helper::record_expanded_category($coursecat, false);
$outcome->outcome = true;
break;
case 'getsubcategorieshtml' :
$categoryid = required_param('categoryid', PARAM_INT);
/* @var core_course_management_renderer $renderer */
+90
View File
@@ -41,6 +41,13 @@ defined('MOODLE_INTERNAL') || die;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class helper {
/**
* The expanded category structure if its already being loaded from the cache.
* @var null|array
*/
protected static $expandedcategories = null;
/**
* Returns course details in an array ready to be printed.
*
@@ -811,4 +818,87 @@ class helper {
$params = array('path' => $path);
return $DB->get_records_sql($sql, $params);
}
/**
* Records when a category is expanded or collapsed so that when the user
*
* @param \coursecat $coursecat The category we're working with.
* @param bool $expanded True if the category is expanded now.
*/
public static function record_expanded_category(\coursecat $coursecat, $expanded = true) {
// If this ever changes we are going to reset it and reload the categories as required.
self::$expandedcategories = null;
$categoryid = $coursecat->id;
$path = $coursecat->get_parents();
/* @var \cache_session $cache */
$cache = \cache::make('core', 'userselections');
$categories = $cache->get('categorymanagementexpanded');
if (!is_array($categories)) {
if (!$expanded) {
// No categories recorded, nothing to remove.
return;
}
$categories = array();
}
if ($expanded) {
$ref =& $categories;
foreach ($coursecat->get_parents() as $path) {
if (!isset($ref[$path]) || !is_array($ref[$path])) {
$ref[$path] = array();
}
$ref =& $ref[$path];
}
if (!isset($ref[$categoryid])) {
$ref[$categoryid] = true;
}
} else {
$found = true;
$ref =& $categories;
foreach ($coursecat->get_parents() as $path) {
if (!isset($ref[$path])) {
$found = false;
break;
}
$ref =& $ref[$path];
}
if ($found) {
$ref[$categoryid] = null;
unset($ref[$categoryid]);
}
}
$cache->set('categorymanagementexpanded', $categories);
}
/**
* Returns the categories that should be expanded when displaying the interface.
*
* @param int|null $withpath If specified a path to require as the parent.
* @return \coursecat[] An array of Category ID's to expand.
*/
public static function get_expanded_categories($withpath = null) {
if (self::$expandedcategories === null) {
/* @var \cache_session $cache */
$cache = \cache::make('core', 'userselections');
self::$expandedcategories = $cache->get('categorymanagementexpanded');
if (self::$expandedcategories === false) {
self::$expandedcategories = array();
}
}
if (empty($withpath)) {
return array_keys(self::$expandedcategories);
}
$parents = explode('/', trim($withpath, '/'));
$ref =& self::$expandedcategories;
foreach ($parents as $parent) {
if (!isset($ref[$parent])) {
return array();
}
$ref =& $ref[$parent];
}
if (is_array($ref)) {
return array_keys($ref);
} else {
return array($parent);
}
}
}
+9 -4
View File
@@ -118,7 +118,9 @@ class core_course_management_renderer extends plugin_renderer_base {
$selectedparents[] = $category->id;
$selectedcategory = $category->id;
}
$catatlevel = array_shift($selectedparents);
$catatlevel = \core_course\management\helper::get_expanded_categories('');
$catatlevel[] = array_shift($selectedparents);
$catatlevel = array_unique($catatlevel);
$listing = coursecat::get(0)->get_children();
@@ -135,7 +137,7 @@ class core_course_management_renderer extends plugin_renderer_base {
foreach ($listing as $listitem) {
// Render each category in the listing.
$subcategories = array();
if ($listitem->id == $catatlevel) {
if (in_array($listitem->id, $catatlevel)) {
$subcategories = $listitem->get_children();
}
$html .= $this->category_listitem(
@@ -166,6 +168,7 @@ class core_course_management_renderer extends plugin_renderer_base {
*/
public function category_listitem(coursecat $category, array $subcategories, $totalsubcategories,
$selectedcategory = null, $selectedcategories = array()) {
$isexpandable = ($totalsubcategories > 0);
$isexpanded = (!empty($subcategories));
$activecategory = ($selectedcategory === $category->id);
@@ -224,9 +227,11 @@ class core_course_management_renderer extends plugin_renderer_base {
$html .= html_writer::end_div();
if ($isexpanded) {
$html .= html_writer::start_tag('ul', array('class' => 'ml', 'role' => 'group'));
$catatlevel = array_shift($selectedcategories);
$catatlevel = \core_course\management\helper::get_expanded_categories($category->path);
$catatlevel[] = array_shift($selectedcategories);
$catatlevel = array_unique($catatlevel);
foreach ($subcategories as $listitem) {
$childcategories = ($listitem->id == $catatlevel) ? $listitem->get_children() : array();
$childcategories = (in_array($listitem->id, $catatlevel)) ? $listitem->get_children() : array();
$html .= $this->category_listitem(
$listitem,
$childcategories,
+1 -1
View File
@@ -1233,7 +1233,7 @@ class behat_course extends behat_base {
throw new ExpectationException("Could not find the actions for $listingtype", $this->getSession());
}
$actionnode = $actionsnode->find('css', '.action-'.$action);
if ($actionnode === null && $this->running_javascript()) {
if ($this->running_javascript() && !$actionnode->isVisible()) {
$actionsnode->find('css', 'a.toggle-display')->click();
if ($actionnode) {
$actionnode = $listingnode->find('css', '.action-'.$action);
@@ -693,3 +693,109 @@ Feature: Course category management interface performs as expected
# Redirect
And I should see "Edit course settings"
And I should see "Course 1"
@javascript
Scenario: Test AJAX expanded categories stay open.
Given the following "categories" exists:
| name | category | idnumber |
| Cat 1 | 0 | CAT1 |
| Cat 2 | 0 | CAT2 |
| Cat 1-1 | CAT1 | CAT3 |
| Cat 1-2 | CAT1 | CAT4 |
| Cat 1-1-1 | CAT3 | CAT5 |
| Cat 1-1-2 | CAT3 | CAT6 |
| Cat 2-1 | CAT2 | CAT7 |
| Cat 2-1-1 | CAT7 | CAT8 |
| Cat 2-1-1-1 | CAT8 | CAT10 |
| Cat 2-1-2 | CAT7 | CAT9 |
| Cat 2-1-2-1 | CAT9 | CAT11 |
And I log in as "admin"
And I go to the courses management page
And I should see the "Course categories" management page
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
And I click to expand category "CAT2" in the management interface
# AJAX action - no redirect.
And I click to expand category "CAT7" in the management interface
# AJAX action - no redirect.
And I click to expand category "CAT9" in the management interface
# AJAX action - no redirect.
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-2" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 2-1-1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-2-1" in the "#course-category-listings ul.ml" "css_element"
And I click on "Cat 1" "link"
# Redirect.
And I should see the "Course categories and courses" management page
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-2" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 2-1-1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-2-1" in the "#course-category-listings ul.ml" "css_element"
And I click on "Re-sort subcategories" "link" in the ".category-listing-actions" "css_element"
And I click on "By idnumber" "link" in the ".category-listing-actions" "css_element"
# Redirect.
And I should see the "Course categories and courses" management page
And I should see "Cat 1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 1-2" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-2" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat 2-1-1-1" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat 2-1-2-1" in the "#course-category-listings ul.ml" "css_element"
@javascript
Scenario: Test category expansion after deletion
Given the following "categories" exists:
| name | category | idnumber |
| Cat A (1) | 0 | CAT1 |
| Cat B (2) | 0 | CAT2 |
| Cat C (1-1) | CAT1 | CAT3 |
| Cat D (2-1) | CAT2 | CAT4 |
| Cat E (2-1-1) | CAT4 | CAT5 |
And I log in as "admin"
And I go to the courses management page
And I should see the "Course categories" management page
And I should see "Cat A (1)" in the "#course-category-listings ul.ml" "css_element"
And I should see "Cat B (2)" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat C (1-1)" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat D (2-1)" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat E (2-1-1)" in the "#course-category-listings ul.ml" "css_element"
And I click to expand category "CAT1" in the management interface
And I should see "Cat C (1-1)" in the "#course-category-listings ul.ml" "css_element"
# AJAX action - no redirect.
And I click to expand category "CAT2" in the management interface
And I should see "Cat D (2-1)" in the "#course-category-listings ul.ml" "css_element"
# AJAX action - no redirect.
And I click to expand category "CAT4" in the management interface
And I should see "Cat E (2-1-1)" in the "#course-category-listings ul.ml" "css_element"
# AJAX action - no redirect.
And I click on "delete" action for "Cat B (2)" in management category listing
# Redirect.
And I should see "Delete category: Cat B (2)"
And I should see "Contents of Cat B (2)"
And I press "Delete"
# Redirect
And I should see "Delete category: Cat B (2)"
And I should see "Deleted course category Cat B (2)"
And I press "Continue"
# Redirect.
And I should see the "Course categories and courses" management page
And I should see "Cat A (1)" in the "#course-category-listings ul.ml" "css_element"
And I should not see "Cat B (2)" in the "#course-category-listings ul.ml" "css_element"
@@ -423,6 +423,11 @@ Console.prototype = {
args.action = action;
args.ajax = '1';
args.sesskey = M.cfg.sesskey;
if (callback === null) {
callback = function() {
Y.log("'Action '"+action+"' completed", 'debug', 'moodle-course-management');
};
}
io.send(this.get('ajaxurl'), {
method : 'POST',
on : {
@@ -1155,6 +1160,7 @@ Category.prototype = {
title : M.util.get_string('collapse', 'moodle'),
alt : M.util.get_string('collapse', 'moodle')
});
this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this);
},
/**
@@ -1170,6 +1176,7 @@ Category.prototype = {
title : M.util.get_string('expand', 'moodle'),
alt : M.util.get_string('expand', 'moodle')
});
this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this);
},
/**
File diff suppressed because one or more lines are too long
@@ -416,6 +416,10 @@ Console.prototype = {
args.action = action;
args.ajax = '1';
args.sesskey = M.cfg.sesskey;
if (callback === null) {
callback = function() {
};
}
io.send(this.get('ajaxurl'), {
method : 'POST',
on : {
@@ -1130,6 +1134,7 @@ Category.prototype = {
title : M.util.get_string('collapse', 'moodle'),
alt : M.util.get_string('collapse', 'moodle')
});
this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this);
},
/**
@@ -1145,6 +1150,7 @@ Category.prototype = {
title : M.util.get_string('expand', 'moodle'),
alt : M.util.get_string('expand', 'moodle')
});
this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this);
},
/**
+2
View File
@@ -155,6 +155,7 @@ Category.prototype = {
title : M.util.get_string('collapse', 'moodle'),
alt : M.util.get_string('collapse', 'moodle')
});
this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this);
},
/**
@@ -170,6 +171,7 @@ Category.prototype = {
title : M.util.get_string('expand', 'moodle'),
alt : M.util.get_string('expand', 'moodle')
});
this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this);
},
/**
+5
View File
@@ -421,6 +421,11 @@ Console.prototype = {
args.action = action;
args.ajax = '1';
args.sesskey = M.cfg.sesskey;
if (callback === null) {
callback = function() {
Y.log("'Action '"+action+"' completed", 'debug', 'moodle-course-management');
};
}
io.send(this.get('ajaxurl'), {
method : 'POST',
on : {
+1
View File
@@ -55,6 +55,7 @@ $string['cachedef_plugin_manager'] = 'Plugin info manager';
$string['cachedef_questiondata'] = 'Question definitions';
$string['cachedef_repositories'] = 'Repositories instances data';
$string['cachedef_string'] = 'Language string cache';
$string['cachedef_userselections'] = 'Data used to persist user selections throughout Moodle';
$string['cachedef_yuimodules'] = 'YUI Module definitions';
$string['cachelock_file_default'] = 'Default file locking';
$string['cachestores'] = 'Cache stores';
+9
View File
@@ -196,4 +196,13 @@ $definitions = array(
'mode' => cache_store::MODE_APPLICATION,
'simplekeys' => true,
),
// This is the session user selections cache.
// It's a special cache that is used to record user selections that should persist for the lifetime of the session.
// Things such as which categories the user has expanded can be stored here.
// It uses simple keys and simple data, please ensure all uses conform to those two constraints.
'userselections' => array(
'mode' => cache_store::MODE_SESSION,
'simplekeys' => true,
'simpledata' => true
),
);
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2013102203.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2013102400.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.