mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-42629 course: management resorting improvements
This commit is contained in:
parent
62846237ee
commit
c7a2291f8b
@ -671,14 +671,15 @@ class helper {
|
||||
*
|
||||
* @param \coursecat $category
|
||||
* @param string $sort One of fullname, shortname or idnumber
|
||||
* @param bool $cleanup If true cleanup will be done, if false you will need to do it manually later.
|
||||
* @return bool
|
||||
* @throws \moodle_exception
|
||||
*/
|
||||
public static function action_category_resort_courses(\coursecat $category, $sort) {
|
||||
public static function action_category_resort_courses(\coursecat $category, $sort, $cleanup = true) {
|
||||
if (!$category->can_resort_courses()) {
|
||||
throw new \moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort');
|
||||
}
|
||||
return $category->resort_courses($sort);
|
||||
return $category->resort_courses($sort, $cleanup);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +149,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
);
|
||||
}
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= $this->category_bulk_actions();
|
||||
$html .= $this->category_bulk_actions($category);
|
||||
$html .= html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
@ -217,6 +217,9 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$html .= html_writer::link($viewcaturl, $text, array('class' => 'float-left categoryname without-actions'));
|
||||
}
|
||||
$html .= html_writer::start_div('float-right');
|
||||
if ($category->idnumber) {
|
||||
$html .= html_writer::tag('span', s($category->idnumber), array('class' => 'dimmed idnumber'));
|
||||
}
|
||||
if ($hasactions) {
|
||||
$html .= $this->category_listitem_actions($category, $actions);
|
||||
}
|
||||
@ -264,7 +267,6 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$category = coursecat::get(0);
|
||||
}
|
||||
|
||||
$hasitems = false;
|
||||
if ($cancreatecategory) {
|
||||
$url = new moodle_url('/course/editcategory.php', array('parent' => $category->id));
|
||||
$actions[] = html_writer::link($url, get_string('createnewcategory'));
|
||||
@ -272,32 +274,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
if (coursecat::can_approve_course_requests()) {
|
||||
$actions[] = html_writer::link(new moodle_url('/course/pending.php'), get_string('coursespending'));
|
||||
}
|
||||
if (coursecat::get(0)->can_resort_subcategories()) {
|
||||
$hasitems = true;
|
||||
$params = array();
|
||||
$params['action'] = 'resortcategories';
|
||||
$params['sesskey'] = sesskey();
|
||||
if ($this->page->url->get_param('categoryid') !== null) {
|
||||
$params['selectedcategoryid'] = $this->page->url->get_param('categoryid');
|
||||
}
|
||||
$baseurl = new moodle_url('/course/management.php', $params);
|
||||
$menu = new action_menu(array(
|
||||
new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('resort' => 'name')),
|
||||
null,
|
||||
get_string('resortcategoriesbyname')
|
||||
),
|
||||
new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('resort' => 'idnumber')),
|
||||
null,
|
||||
get_string('resortcategoriesbyidnumber')
|
||||
)
|
||||
));
|
||||
$menu->actiontext = get_string('resortcategories');
|
||||
$menu->actionicon = new pix_icon('t/contextmenu', ' ', 'moodle', array('class' => 'iconsmall', 'title' => ''));
|
||||
$actions[] = $this->render($menu);
|
||||
}
|
||||
if (!$hasitems) {
|
||||
if (count($actions) === 0) {
|
||||
return '';
|
||||
}
|
||||
return html_writer::div(join(' | ', $actions), 'listing-actions category-listing-actions');
|
||||
@ -307,6 +284,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
* Renderers the actions for individual category list items.
|
||||
*
|
||||
* @param coursecat $category
|
||||
* @param array $actions
|
||||
* @return string
|
||||
*/
|
||||
public function category_listitem_actions(coursecat $category, array $actions = null) {
|
||||
@ -335,30 +313,72 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
/**
|
||||
* Renders bulk actions for categories.
|
||||
*
|
||||
* @param coursecat $category The currently selected category if there is one.
|
||||
* @return string
|
||||
*/
|
||||
public function category_bulk_actions() {
|
||||
public function category_bulk_actions(coursecat $category = null) {
|
||||
// Resort courses.
|
||||
// Change parent.
|
||||
$strgo = new lang_string('go');
|
||||
|
||||
$html = html_writer::start_div('category-bulk-actions bulk-actions');
|
||||
if (coursecat::can_resort_any()) {
|
||||
$options = array(
|
||||
'name' => get_string('resortbyname'),
|
||||
'idnumber' => get_string('resortbyidnumber'),
|
||||
$selectoptions = array(
|
||||
'selectedcategories' => get_string('selectedcategories'),
|
||||
'allcategories' => get_string('allcategories')
|
||||
);
|
||||
$select = html_writer::select(
|
||||
$options,
|
||||
'resortcategoriesby',
|
||||
'',
|
||||
array('' => 'choosedots'),
|
||||
array('aria-labelledby' => 'resortselectedcategoriesby')
|
||||
$form = html_writer::start_div();
|
||||
if ($category) {
|
||||
$selectoptions = array('thiscategory' => get_string('thiscategory')) + $selectoptions;
|
||||
$form .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'currentcategoryid', 'value' => $category->id));
|
||||
}
|
||||
$form .= html_writer::div(
|
||||
html_writer::span(get_string('for'), '', array('id' => 'selectsortby')) .
|
||||
' ' .
|
||||
html_writer::select(
|
||||
$selectoptions,
|
||||
'selectsortby',
|
||||
'',
|
||||
array('' => 'choosedots'),
|
||||
array('aria-labelledby' => 'selectsortby')
|
||||
)
|
||||
);
|
||||
$submit = array('type' => 'submit', 'name' => 'bulkresortcategories', 'value' => $strgo);
|
||||
$form .= html_writer::div(
|
||||
html_writer::span(get_string('sortcategoriesby'), '', array('id' => 'resortselectedcategoriesby')) .
|
||||
' ' .
|
||||
html_writer::select(
|
||||
array(
|
||||
'name' => get_string('resortbyname'),
|
||||
'idnumber' => get_string('resortbyidnumber'),
|
||||
'none' => get_string('dontsortcategories')
|
||||
),
|
||||
'resortcategoriesby',
|
||||
'',
|
||||
array('none' => 'choosedots'),
|
||||
array('aria-labelledby' => 'resortselectedcategoriesby')
|
||||
)
|
||||
);
|
||||
$form .= html_writer::div(
|
||||
html_writer::span(get_string('sortcoursesby'), '', array('id' => 'resortselectedcoursesby')) .
|
||||
' ' .
|
||||
html_writer::select(
|
||||
array(
|
||||
'fullname' => get_string('resortbyfullname'),
|
||||
'shortname' => get_string('resortbyshortname'),
|
||||
'idnumber' => get_string('resortbyidnumber'),
|
||||
'none' => get_string('dontsortcourses')
|
||||
),
|
||||
'resortcoursesby',
|
||||
'',
|
||||
array('none' => 'choosedots'),
|
||||
array('aria-labelledby' => 'resortselectedcoursesby')
|
||||
)
|
||||
);
|
||||
$form .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'bulksort', 'value' => $strgo));
|
||||
$form .= html_writer::end_div();
|
||||
$html .= $this->detail_pair(
|
||||
html_writer::span(get_string('resortselectedcategoriesby'), '', array('id' => 'resortselectedcategoriesby')),
|
||||
$select . html_writer::empty_tag('input', $submit)
|
||||
get_string('sorting'),
|
||||
$form
|
||||
);
|
||||
}
|
||||
if (coursecat::can_change_parent_any()) {
|
||||
@ -552,7 +572,9 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
|
||||
$html .= html_writer::start_div('float-right');
|
||||
$html .= html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
|
||||
if ($course->idnumber) {
|
||||
$html .= html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
|
||||
}
|
||||
$html .= $this->course_listitem_actions($category, $course);
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::end_div();
|
||||
|
@ -277,7 +277,7 @@ if ($action !== false && confirm_sesskey()) {
|
||||
case 'bulkaction':
|
||||
$bulkmovecourses = optional_param('bulkmovecourses', false, PARAM_BOOL);
|
||||
$bulkmovecategories = optional_param('bulkmovecategories', false, PARAM_BOOL);
|
||||
$bulkresortcategories = optional_param('bulkresortcategories', false, PARAM_BOOL);
|
||||
$bulkresortcategories = optional_param('bulksort', false, PARAM_BOOL);
|
||||
|
||||
if ($bulkmovecourses) {
|
||||
// Move courses out of the current category and into a new category.
|
||||
@ -341,18 +341,49 @@ if ($action !== false && confirm_sesskey()) {
|
||||
$notificationspass[] = get_string($movesuccessstrkey, 'moodle', $a);
|
||||
}
|
||||
} else if ($bulkresortcategories) {
|
||||
// Bulk resort selected categories.
|
||||
$categoryids = optional_param_array('bcat', false, PARAM_INT);
|
||||
$sort = required_param('resortcategoriesby', PARAM_ALPHA);
|
||||
if ($categoryids === false) {
|
||||
$for = required_param('selectsortby', PARAM_ALPHA);
|
||||
$sortcategoriesby = required_param('resortcategoriesby', PARAM_ALPHA);
|
||||
$sortcoursesby = required_param('resortcoursesby', PARAM_ALPHA);
|
||||
|
||||
if ($sortcategoriesby === 'none' && $sortcoursesby === 'none') {
|
||||
// They're not sorting anything.
|
||||
break;
|
||||
}
|
||||
$categories = coursecat::get_many($categoryids);
|
||||
foreach ($categories as $cat) {
|
||||
// Don't clean up here, we'll do it once we're all done.
|
||||
\core_course\management\helper::action_category_resort_subcategories($cat, $sort, false);
|
||||
|
||||
if ($for === 'thiscategory') {
|
||||
$categoryids = array(
|
||||
required_param('currentcategoryid', PARAM_INT)
|
||||
);
|
||||
$categories = coursecat::get_many($categoryids);
|
||||
} else if ($for === 'selectedcategories') {
|
||||
// Bulk resort selected categories.
|
||||
$categoryids = optional_param_array('bcat', false, PARAM_INT);
|
||||
$sort = required_param('resortcategoriesby', PARAM_ALPHA);
|
||||
if ($categoryids === false) {
|
||||
break;
|
||||
}
|
||||
$categories = coursecat::get_many($categoryids);
|
||||
} else if ($for === 'allcategories') {
|
||||
$categories = coursecat::get_all_visible();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
coursecat::resort_categories_cleanup();
|
||||
if (!in_array($sortcategoriesby, array('idnumber', 'name'))) {
|
||||
$sortcategoriesby = false;
|
||||
}
|
||||
if (!in_array($sortcoursesby, array('idnumber', 'fullname', 'shortname'))) {
|
||||
$sortcoursesby = false;
|
||||
}
|
||||
foreach ($categories as $cat) {
|
||||
if ($sortcategoriesby) {
|
||||
// Don't clean up here, we'll do it once we're all done.
|
||||
\core_course\management\helper::action_category_resort_subcategories($cat, $sortcategoriesby, false);
|
||||
}
|
||||
if (in_array($sortcoursesby, array('idnumber', 'fullname', 'shortname'))) {
|
||||
\core_course\management\helper::action_category_resort_courses($cat, $sortcoursesby, false);
|
||||
}
|
||||
}
|
||||
coursecat::resort_categories_cleanup($sortcoursesby !== false);
|
||||
if ($category === null && count($categoryids) === 1) {
|
||||
// They're bulk sorting just a single category and they've not selected a category.
|
||||
// Lets for convenience sake auto-select the category that has been resorted for them.
|
||||
|
@ -121,6 +121,7 @@ $string['ajaxuse'] = 'AJAX and Javascript';
|
||||
$string['all'] = 'All';
|
||||
$string['allactions'] = 'All actions';
|
||||
$string['allactivities'] = 'All activities';
|
||||
$string['allcategories'] = 'All categories';
|
||||
$string['alldays'] = 'All days';
|
||||
$string['allfieldsrequired'] = 'All fields are required';
|
||||
$string['allfiles'] = 'All files';
|
||||
@ -498,6 +499,8 @@ $string['dndworkingtextlink'] = 'Drag and drop text or links onto course section
|
||||
$string['dndworkingtext'] = 'Drag and drop text onto course sections to upload it';
|
||||
$string['dndworkinglink'] = 'Drag and drop links onto course sections to upload them';
|
||||
$string['documentation'] = 'Moodle documentation';
|
||||
$string['dontsortcategories'] = 'Don\'t sort categories';
|
||||
$string['dontsortcourses'] = 'Don\'t sort courses';
|
||||
$string['down'] = 'Down';
|
||||
$string['download'] = 'Download';
|
||||
$string['downloadall'] = 'Download all';
|
||||
@ -757,6 +760,7 @@ $string['folderclosed'] = 'Closed folder';
|
||||
$string['folderopened'] = 'Opened folder';
|
||||
$string['followingoptional'] = 'The following items are optional';
|
||||
$string['followingrequired'] = 'The following items are required';
|
||||
$string['for'] = 'For';
|
||||
$string['force'] = 'Force';
|
||||
$string['forcedmodeinbrackets'] = '{$a} (forced mode)';
|
||||
$string['forcelanguage'] = 'Force language';
|
||||
@ -1593,6 +1597,7 @@ $string['selectamodule'] = 'Please select an activity module';
|
||||
$string['selectanoptions'] = 'Select an option';
|
||||
$string['selectdefault'] = 'Select default';
|
||||
$string['selectedfile'] = 'Selected file';
|
||||
$string['selectedcategories'] = 'Selected categories';
|
||||
$string['selectednowmove'] = '{$a} files selected for moving. Now go into the destination folder and press \'Move files to here\'';
|
||||
$string['selectfiles'] = 'Select files';
|
||||
$string['selectmoduletoviewhelp'] = 'Select an activity or resource to view its help.
|
||||
@ -1676,6 +1681,9 @@ $string['sort'] = 'Sort';
|
||||
$string['sortby'] = 'Sort by';
|
||||
$string['sortbyx'] = 'Sort by {$a} ascending';
|
||||
$string['sortbyxreverse'] = 'Sort by {$a} descending';
|
||||
$string['sortcategoriesby'] = 'Sort categories by';
|
||||
$string['sortcoursesby'] = 'Sort courses by';
|
||||
$string['sorting'] = 'Sorting';
|
||||
$string['sourcerole'] = 'Source role';
|
||||
$string['specifyname'] = 'You must specify a name.';
|
||||
$string['standard'] = 'Standard';
|
||||
@ -1765,6 +1773,7 @@ $string['themes'] = 'Themes';
|
||||
$string['themesaved'] = 'New theme saved';
|
||||
$string['thereareno'] = 'There are no {$a} in this course';
|
||||
$string['therearecourses'] = 'There are {$a} courses';
|
||||
$string['thiscategory'] = 'This category';
|
||||
$string['thiscategorycontains'] = 'This category contains';
|
||||
$string['time'] = 'Time';
|
||||
$string['timezone'] = 'Timezone';
|
||||
|
@ -2422,11 +2422,15 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate {
|
||||
|
||||
/**
|
||||
* Cleans things up after categories have been resorted.
|
||||
* @param bool $includecourses If set to true we know courses have been resorted as well.
|
||||
*/
|
||||
public static function resort_categories_cleanup() {
|
||||
public static function resort_categories_cleanup($includecourses = false) {
|
||||
// This should not be needed but we do it just to be safe.
|
||||
fix_course_sortorder();
|
||||
cache_helper::purge_by_event('changesincoursecat');
|
||||
if ($includecourses) {
|
||||
cache_helper::purge_by_event('changesincourse');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1141,7 +1141,7 @@ class core_renderer extends renderer_base {
|
||||
if ((string)$icon->attributes['alt'] === $comparetoalt) {
|
||||
$icon->attributes['alt'] = ' ';
|
||||
}
|
||||
if ((string)$icon->attributes['title'] === $comparetoalt) {
|
||||
if (isset($icon->attributes['title']) && (string)$icon->attributes['title'] === $comparetoalt) {
|
||||
unset($icon->attributes['title']);
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +309,6 @@ input.titleeditor { width: 330px; vertical-align: text-bottom; }
|
||||
#course-category-listings li li li li li li li li .tree-icon {margin-left:5.5em;}
|
||||
|
||||
#course-listing .listitem .drag-handle {margin-right:0.5em;}
|
||||
#course-listing .listitem .idnumber {color:#a1a1a8;margin-right:2em;}
|
||||
#course-listing .listitem .categoryname {display:inline-block;margin-left:1em;color:#a1a1a8;}
|
||||
#course-listing .listitem .coursename {display:inline-block;}
|
||||
|
||||
@ -321,6 +320,7 @@ input.titleeditor { width: 330px; vertical-align: text-bottom; }
|
||||
#category-listing .listitem[data-selected='1'] > div > .ba-checkbox {margin:0 0.5em 0 0;padding:0;}
|
||||
.category-bulk-actions {margin: 0 0.5em 0.5em;}
|
||||
|
||||
#course-category-listings .listitem .idnumber {color:#a1a1a8;margin-right:2em;}
|
||||
#course-category-listings .listitem > div > .float-left {float:left;}
|
||||
#course-category-listings .listitem > div > .float-right {float:right;text-align:right;}
|
||||
#course-category-listings .listitem[data-visible="0"],
|
||||
|
@ -771,6 +771,10 @@ span.editinstructions {
|
||||
.without-actions {
|
||||
color: #333;
|
||||
}
|
||||
.idnumber {
|
||||
color:#a1a1a8;
|
||||
margin-right:2em;
|
||||
}
|
||||
}
|
||||
// The category or course is hidden.
|
||||
&[data-visible="0"] {
|
||||
@ -811,10 +815,6 @@ span.editinstructions {
|
||||
|
||||
#course-listing {
|
||||
.listitem {
|
||||
.idnumber {
|
||||
color:#a1a1a8;
|
||||
margin-right:2em;
|
||||
}
|
||||
.categoryname {
|
||||
display:inline-block;
|
||||
margin-left:1em;
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user