From 10b7badd61e567c77f068532b51b99c3aef37288 Mon Sep 17 00:00:00 2001 From: Peter Dias <peter@moodle.com> Date: Tue, 15 Jun 2021 10:13:07 +0800 Subject: [PATCH] MDL-71914 mod_glossary: Add tertiary nav in glossary --- .../classes/local/views/secondary.php | 47 +++ mod/glossary/classes/output/renderer.php | 41 +++ .../classes/output/standard_action_bar.php | 285 ++++++++++++++++++ mod/glossary/edit.php | 1 + mod/glossary/export.php | 1 + mod/glossary/import.php | 1 + mod/glossary/lang/en/deprecated.txt | 1 + mod/glossary/lang/en/glossary.php | 8 +- mod/glossary/lib.php | 33 +- mod/glossary/tabs.php | 101 ++----- .../templates/standard_action_menu.mustache | 168 +++++++++++ mod/glossary/version.php | 2 +- mod/glossary/view.php | 102 ++----- 13 files changed, 621 insertions(+), 170 deletions(-) create mode 100644 mod/glossary/classes/local/views/secondary.php create mode 100644 mod/glossary/classes/output/renderer.php create mode 100644 mod/glossary/classes/output/standard_action_bar.php create mode 100644 mod/glossary/lang/en/deprecated.txt create mode 100644 mod/glossary/templates/standard_action_menu.mustache diff --git a/mod/glossary/classes/local/views/secondary.php b/mod/glossary/classes/local/views/secondary.php new file mode 100644 index 00000000000..83e2edd46e8 --- /dev/null +++ b/mod/glossary/classes/local/views/secondary.php @@ -0,0 +1,47 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +namespace mod_glossary\local\views; + +use core\navigation\views\secondary as core_secondary; + +/** + * Class secondary_navigation_view. + * + * Custom implementation for a plugin. + * + * @package mod_glossary + * @category navigation + * @copyright 2021 onwards Peter Dias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class secondary extends core_secondary { + /** + * Define a custom secondary nav order/view + * + * @return array + */ + protected function get_default_module_mapping(): array { + return [ + self::TYPE_SETTING => [ + 'modedit' => 1, + ], + self::TYPE_CUSTOM => [ + 'pendingapproval' => 2, + ], + ]; + } +} diff --git a/mod/glossary/classes/output/renderer.php b/mod/glossary/classes/output/renderer.php new file mode 100644 index 00000000000..701ecdbd3ba --- /dev/null +++ b/mod/glossary/classes/output/renderer.php @@ -0,0 +1,41 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +namespace mod_glossary\output; + +use plugin_renderer_base; + +/** + * Class actionbar - Display the action bar + * + * @package mod_glossary + * @copyright 2021 Peter Dias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class renderer extends plugin_renderer_base { + /** + * Render the glossary tertiary nav + * + * @param standard_action_bar $actionmenu + * @return bool|string + * @throws \moodle_exception + */ + public function main_action_bar(standard_action_bar $actionmenu) { + $context = $actionmenu->export_for_template($this); + + return $this->render_from_template('mod_glossary/standard_action_menu', $context); + } +} diff --git a/mod/glossary/classes/output/standard_action_bar.php b/mod/glossary/classes/output/standard_action_bar.php new file mode 100644 index 00000000000..699b6ac782d --- /dev/null +++ b/mod/glossary/classes/output/standard_action_bar.php @@ -0,0 +1,285 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +namespace mod_glossary\output; + +use moodle_url; +use context_module; +use renderable; +use renderer_base; +use single_button; +use templatable; +use url_select; + +/** + * Class standard_action_bar - Display the action bar + * + * @package mod_glossary + * @copyright 2021 Peter Dias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class standard_action_bar implements renderable, templatable { + /** @var object $cm The course module. */ + private $cm; + /** @var string $mode The type of view. */ + private $mode; + /** @var string $hook The term, entry, cat, etc... to look for based on mode. */ + private $hook; + /** @var string $sortkey Sorted view: CREATION | UPDATE | FIRSTNAME | LASTNAME. */ + private $sortkey; + /** @var string $sortorder The sort order (ASC or DESC). */ + private $sortorder; + /** @var int $offset Entries to bypass (for paging purposes). */ + private $offset; + /** @var int $pagelimit The page to resume with. */ + private $pagelimit; + /** @var int $context The context of the glossary. */ + private $context; + /** @var object $module The glossary record . */ + private $module; + /** @var int $fullsearch Full search (concept and definition) when searching. */ + private $fullsearch; + /** @var object $displayformat Override of the glossary display format. */ + private $displayformat; + /** @var string $tab Browsing entries by categories. */ + private $tab; + + /** + * standard_action_bar constructor. + * + * @param object $cm + * @param object $module + * @param object $displayformat + * @param string $mode + * @param string $hook + * @param string $sortkey + * @param string $sortorder + * @param int $offset + * @param int $pagelimit + * @param int $fullsearch + * @param string $tab + * @param string $defaulttab + * @throws \coding_exception + */ + public function __construct(object $cm, object $module, object $displayformat, string $mode, string $hook, + string $sortkey, string $sortorder, int $offset, int $pagelimit, int $fullsearch, + string $tab, string $defaulttab) { + $this->cm = $cm; + $this->module = $module; + $this->displayformat = $displayformat; + $this->mode = $mode; + $this->tab = $tab; + $this->hook = $hook; + $this->sortkey = $sortkey; + $this->sortorder = $sortorder; + $this->offset = $offset; + $this->pagelimit = $pagelimit; + $this->fullsearch = $fullsearch; + $this->context = context_module::instance($this->cm->id); + + if (!has_capability('mod/glossary:approve', $this->context) && $this->tab == GLOSSARY_APPROVAL_VIEW) { + // Non-teachers going to approval view go to defaulttab. + $this->tab = $defaulttab; + } + } + + /** + * Export the action bar + * + * @param renderer_base $output + * @return array + */ + public function export_for_template(renderer_base $output) { + return [ + 'addnewbutton' => $this->create_add_button($output), + 'searchbox' => $this->create_search_box(), + 'tools' => $this->get_additional_tools($output), + 'tabjumps' => $this->generate_tab_jumps($output) + ]; + } + + /** + * Render the search box with the checkbox + * + * @return array + */ + private function create_search_box(): array { + global $OUTPUT; + $fullsearchchecked = false; + if ($this->fullsearch || $this->mode != 'search') { + $fullsearchchecked = true; + } + + $check = [ + 'name' => 'fullsearch', + 'id' => 'fullsearch', + 'value' => '1', + 'checked' => $fullsearchchecked, + 'label' => get_string("searchindefinition", "glossary"), + ]; + + $checkbox = $OUTPUT->render_from_template('core/checkbox', $check); + + $hiddenfields = [ + (object) ['name' => 'id', 'value' => $this->cm->id], + (object) ['name' => 'mode', 'value' => 'search'], + ]; + $data = [ + 'action' => new moodle_url('/mod/glossary/view.php'), + 'hiddenfields' => $hiddenfields, + 'otherfields' => $checkbox, + 'inputname' => 'hook', + 'query' => ($this->mode == 'search') ? s($this->hook) : '', + 'searchstring' => get_string('search'), + ]; + + return $data; + } + + /** + * Render the add entry button + * + * @param renderer_base $output + * @return \stdClass + */ + private function create_add_button(renderer_base $output): \stdClass { + if (!has_capability('mod/glossary:write', $this->context)) { + return ''; + } + $btn = new single_button(new moodle_url('/mod/glossary/edit.php', ['cmid' => $this->cm->id]), + get_string('addsingleentry', 'glossary'), 'post', true); + + return $btn->export_for_template($output); + } + + /** + * Render the additional tools required by the glossary + * + * @param renderer_base $output + * @return array + */ + private function get_additional_tools(renderer_base $output): array { + global $USER, $CFG; + $items = []; + $buttons = []; + + if (has_capability('mod/glossary:import', $this->context)) { + $items['button'] = new single_button( + new moodle_url('/mod/glossary/import.php', ['id' => $this->cm->id]), + get_string('importentries', 'glossary') + ); + } + + if (has_capability('mod/glossary:export', $this->context)) { + $url = new moodle_url('/mod/glossary/export.php', [ + 'id' => $this->cm->id, + 'mode' => $this->mode, + 'hook' => $this->hook + ]); + $buttons[get_string('export', 'glossary')] = $url->out(false); + } + + if (has_capability('mod/glossary:manageentries', $this->context) or $this->module->allowprintview) { + $params = array( + 'id' => $this->cm->id, + 'mode' => $this->mode, + 'hook' => $this->hook, + 'sortkey' => $this->sortkey, + 'sortorder' => $this->sortorder, + 'offset' => $this->offset, + 'pagelimit' => $this->pagelimit + ); + $printurl = new moodle_url('/mod/glossary/print.php', $params); + $buttons[get_string('printerfriendly', 'glossary')] = $printurl->out(false); + } + + if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) + && $this->module->rsstype && $this->module->rssarticles + && has_capability('mod/glossary:view', $this->context)) { + require_once("$CFG->libdir/rsslib.php"); + $string = get_string('rssfeed', 'glossary'); + $url = new moodle_url(rss_get_url($this->context->id, $USER->id, 'mod_glossary', $this->cm->instance)); + $buttons[$string] = $url->out(false); + } + + foreach ($items as $key => $value) { + $items[$key] = $value->export_for_template($output); + } + + if ($buttons) { + foreach ($buttons as $index => $value) { + $items['select']['options'][] = [ + 'url' => $value, + 'string' => $index + ]; + } + } + + return $items; + } + + /** + * Generate a url select to match any types of glossary views + * + * @param renderer_base $output + * @return \stdClass|null + */ + private function generate_tab_jumps(renderer_base $output) { + $tabs = glossary_get_visible_tabs($this->displayformat); + $validtabs = [ + GLOSSARY_STANDARD => [ + 'mode' => 'letter', + 'descriptor' => 'standardview' + ], + GLOSSARY_CATEGORY => [ + 'mode' => 'cat', + 'descriptor' => 'categoryview' + ], + GLOSSARY_DATE => [ + 'mode' => 'date', + 'descriptor' => 'dateview' + ], + GLOSSARY_AUTHOR => [ + 'mode' => 'author', + 'descriptor' => 'authorview' + ], + ]; + + $baseurl = new moodle_url('/mod/glossary/view.php', ['id' => $this->cm->id]); + $active = null; + $options = []; + foreach ($validtabs as $key => $tabinfo) { + if (in_array($key, $tabs)) { + $baseurl->params(['mode' => $tabinfo['mode']]); + $active = $active ?? $baseurl->out(false); + $active = ($tabinfo['mode'] == $this->mode ? $baseurl->out(false) : $active); + $options[get_string($tabinfo['descriptor'], 'glossary')] = $baseurl->out(false); + } + } + + if ($this->tab < GLOSSARY_STANDARD_VIEW || $this->tab > GLOSSARY_AUTHOR_VIEW) { + $options[get_string('edit')] = '#'; + } + + if (count($options) > 1) { + $select = new url_select(array_flip($options), $active, null); + $select->set_label(get_string('explainalphabet', 'glossary'), ['class' => 'sr-only']); + return $select->export_for_template($output); + } + + return null; + } +} diff --git a/mod/glossary/edit.php b/mod/glossary/edit.php index 15d06e5ad50..830288b7a97 100644 --- a/mod/glossary/edit.php +++ b/mod/glossary/edit.php @@ -82,6 +82,7 @@ if (!empty($id)) { $PAGE->set_title($glossary->name); $PAGE->set_heading($course->fullname); +$PAGE->set_secondary_active_tab('modulepage'); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($glossary->name), 2); if ($glossary->intro) { diff --git a/mod/glossary/export.php b/mod/glossary/export.php index 56bdb8f3cd2..c8e8078930b 100644 --- a/mod/glossary/export.php +++ b/mod/glossary/export.php @@ -50,6 +50,7 @@ $PAGE->set_url('/mod/glossary/export.php', array('id'=>$cm->id)); $PAGE->navbar->add($strexportentries); $PAGE->set_title($glossary->name); $PAGE->set_heading($course->fullname); +$PAGE->set_secondary_active_tab('modulepage'); echo $OUTPUT->header(); echo $OUTPUT->heading($strexportentries); diff --git a/mod/glossary/import.php b/mod/glossary/import.php index 783864ef6d5..d73158b8008 100644 --- a/mod/glossary/import.php +++ b/mod/glossary/import.php @@ -49,6 +49,7 @@ $strimportentries = get_string('importentriesfromxml', 'glossary'); $PAGE->navbar->add($strimportentries); $PAGE->set_title($glossary->name); $PAGE->set_heading($course->fullname); +$PAGE->set_secondary_active_tab('modulepage'); echo $OUTPUT->header(); echo $OUTPUT->heading($strimportentries); diff --git a/mod/glossary/lang/en/deprecated.txt b/mod/glossary/lang/en/deprecated.txt new file mode 100644 index 00000000000..7b49b56cbca --- /dev/null +++ b/mod/glossary/lang/en/deprecated.txt @@ -0,0 +1 @@ +waitingapproval,mod_glossary diff --git a/mod/glossary/lang/en/glossary.php b/mod/glossary/lang/en/glossary.php index 0e64b561885..35500edabfa 100644 --- a/mod/glossary/lang/en/glossary.php +++ b/mod/glossary/lang/en/glossary.php @@ -26,6 +26,7 @@ $string['addcomment'] = 'Add comment'; $string['addcategory'] = 'Add category'; $string['addentry'] = 'Add a new entry'; +$string['addsingleentry'] = 'Add entry'; $string['addingcomment'] = 'Add a comment'; $string['alias'] = 'Keyword'; $string['aliases'] = 'Keyword(s)'; @@ -180,6 +181,7 @@ $string['explainalphabet'] = 'Browse the glossary using this index'; $string['explainexport'] = 'Click on the button below to export glossary entries.<br />You can import it anytime you wish in this or other course.<p>Please note that attachments (e.g. images) and authors are not exported.</p>'; $string['explainimport'] = 'You must specify the file to import and define the criteria of the process.<p>Submit your request and review the results.</p>'; $string['explainspecial'] = 'Shows entries that do not begin with a letter'; +$string['export'] = 'Export'; $string['exportedentry'] = 'Exported entry'; $string['exportentries'] = 'Export entries'; $string['exportentriestoxml'] = 'Export entries to XML file'; @@ -276,6 +278,7 @@ $string['onebyline'] = '(one per line)'; $string['page-mod-glossary-x'] = 'Any glossary module page'; $string['page-mod-glossary-edit'] = 'Glossary add/edit entry page'; $string['page-mod-glossary-view'] = 'View glossary edit page'; +$string['pendingapproval'] = 'Pending approval'; $string['pluginadministration'] = 'Glossary administration'; $string['pluginname'] = 'Glossary'; $string['popupformat'] = 'Popup format'; @@ -303,6 +306,7 @@ $string['resetglossariesall'] = 'Delete entries from all glossaries'; $string['rssarticles'] = 'Number of RSS recent articles'; $string['rssarticles_help'] = 'This setting specifies the number of glossary entry concepts to include in the RSS feed. Between 5 and 20 generally acceptable.'; $string['rsssubscriberss'] = 'Display the RSS feed for \'{$a}\' concepts'; +$string['rssfeed'] = 'RSS feed'; $string['rsstype'] = 'RSS feed for this activity'; $string['rsstype_help'] = 'To enable the RSS feed for this activity, select either concepts with author or concepts without author to be included in the feed.'; $string['search:activity'] = 'Glossary - activity information'; @@ -328,9 +332,11 @@ $string['totalentries'] = 'Total entries'; $string['usedynalink'] = 'Automatically link glossary entries'; $string['usedynalink_help'] = 'If site-wide glossary auto-linking has been enabled by an administrator and this setting is enabled, the "Add a new entry" form includes the option to automatically link the entry wherever the concept words and phrases appear throughout the rest of the course.'; $string['visibletabs'] = 'Visible tabs'; -$string['waitingapproval'] = 'Waiting approval'; $string['warningstudentcapost'] = '(Applies only if the glossary is not the main one)'; $string['withauthor'] = 'Concepts with author'; $string['withoutauthor'] = 'Concepts without author'; $string['writtenby'] = 'by'; $string['youarenottheauthor'] = 'You are not the author of this comment, so you are not allowed to edit it.'; + +// Deprecated since 4.0. +$string['waitingapproval'] = 'Waiting approval'; diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index 47e7640c670..e5c7bdcdf43 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -3142,22 +3142,32 @@ function glossary_extend_settings_navigation(settings_navigation $settings, navi $hook = optional_param('hook', 'ALL', PARAM_CLEAN); if (has_capability('mod/glossary:import', $PAGE->cm->context)) { - $glossarynode->add(get_string('importentries', 'glossary'), new moodle_url('/mod/glossary/import.php', array('id'=>$PAGE->cm->id))); + $node = $glossarynode->add(get_string('importentries', 'glossary'), + new moodle_url('/mod/glossary/import.php', ['id' => $PAGE->cm->id])); + $node->set_show_in_secondary_navigation(false); } if (has_capability('mod/glossary:export', $PAGE->cm->context)) { - $glossarynode->add(get_string('exportentries', 'glossary'), new moodle_url('/mod/glossary/export.php', array('id'=>$PAGE->cm->id, 'mode'=>$mode, 'hook'=>$hook))); - } - - if (has_capability('mod/glossary:approve', $PAGE->cm->context) && ($hiddenentries = $DB->count_records('glossary_entries', array('glossaryid'=>$PAGE->cm->instance, 'approved'=>0)))) { - $glossarynode->add(get_string('waitingapproval', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$PAGE->cm->id, 'mode'=>'approval'))); - } - - if (has_capability('mod/glossary:write', $PAGE->cm->context)) { - $glossarynode->add(get_string('addentry', 'glossary'), new moodle_url('/mod/glossary/edit.php', array('cmid'=>$PAGE->cm->id))); + $node = $glossarynode->add(get_string('exportentries', 'glossary'), + new moodle_url('/mod/glossary/export.php', ['id' => $PAGE->cm->id, 'mode' => $mode, 'hook' => $hook])); + $node->set_show_in_secondary_navigation(false); } $glossary = $DB->get_record('glossary', array("id" => $PAGE->cm->instance)); + $hiddenentries = $DB->count_records('glossary_entries', ['glossaryid' => $PAGE->cm->instance, 'approved' => 0]); + + // Safe guard check - Ideally, there shouldn't be any hidden entries if the glossary has 'defaultapproval'. + if (has_capability('mod/glossary:approve', $PAGE->cm->context) && (!$glossary->defaultapproval || $hiddenentries)) { + $glossarynode->add(get_string('pendingapproval', 'glossary'), + new moodle_url('/mod/glossary/view.php', ['id' => $PAGE->cm->id, 'mode' => 'approval']), + navigation_node::TYPE_CUSTOM, null, 'pendingapproval'); + } + + if (has_capability('mod/glossary:write', $PAGE->cm->context)) { + $node = $glossarynode->add(get_string('addentry', 'glossary'), + new moodle_url('/mod/glossary/edit.php', ['cmid' => $PAGE->cm->id])); + $node->set_show_in_secondary_navigation(false); + } if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) && $glossary->rsstype && $glossary->rssarticles && has_capability('mod/glossary:view', $PAGE->cm->context)) { require_once("$CFG->libdir/rsslib.php"); @@ -3165,7 +3175,8 @@ function glossary_extend_settings_navigation(settings_navigation $settings, navi $string = get_string('rsstype', 'glossary'); $url = new moodle_url(rss_get_url($PAGE->cm->context->id, $USER->id, 'mod_glossary', $glossary->id)); - $glossarynode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', '')); + $node = $glossarynode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', '')); + $node->set_show_in_secondary_navigation(false); } } diff --git a/mod/glossary/tabs.php b/mod/glossary/tabs.php index 015312baef3..1d8a7a572cf 100644 --- a/mod/glossary/tabs.php +++ b/mod/glossary/tabs.php @@ -1,81 +1,29 @@ <?php - if (!isset($sortorder)) { - $sortorder = ''; - } - if (!isset($sortkey)) { - $sortkey = ''; - } - - //make sure variables are properly cleaned - $sortkey = clean_param($sortkey, PARAM_ALPHA);// Sorted view: CREATION | UPDATE | FIRSTNAME | LASTNAME... - $sortorder = clean_param($sortorder, PARAM_ALPHA); // it defines the order of the sorting (ASC or DESC) - - $toolsrow = array(); - $browserow = array(); - $inactive = array(); - $activated = array(); - - if (!has_capability('mod/glossary:approve', $context) && $tab == GLOSSARY_APPROVAL_VIEW) { - /// Non-teachers going to approval view go to defaulttab - $tab = $defaulttab; - } - - // Get visible tabs for the format and check tab needs to be displayed. - $dt = glossary_get_visible_tabs($dp); - - if (in_array(GLOSSARY_STANDARD, $dt)) { - $browserow[] = new tabobject(GLOSSARY_STANDARD_VIEW, - $CFG->wwwroot.'/mod/glossary/view.php?id='.$id.'&mode=letter', - get_string('standardview', 'glossary')); - } - - if (in_array(GLOSSARY_CATEGORY, $dt)) { - $browserow[] = new tabobject(GLOSSARY_CATEGORY_VIEW, - $CFG->wwwroot.'/mod/glossary/view.php?id='.$id.'&mode=cat', - get_string('categoryview', 'glossary')); - } - - if (in_array(GLOSSARY_DATE, $dt)) { - $browserow[] = new tabobject(GLOSSARY_DATE_VIEW, - $CFG->wwwroot.'/mod/glossary/view.php?id='.$id.'&mode=date', - get_string('dateview', 'glossary')); - } - - if (in_array(GLOSSARY_AUTHOR, $dt)) { - $browserow[] = new tabobject(GLOSSARY_AUTHOR_VIEW, - $CFG->wwwroot.'/mod/glossary/view.php?id='.$id.'&mode=author', - get_string('authorview', 'glossary')); - } - - if ($tab < GLOSSARY_STANDARD_VIEW || $tab > GLOSSARY_AUTHOR_VIEW) { // We are on second row - $inactive = array('edit'); - $activated = array('edit'); - - $browserow[] = new tabobject('edit', '#', get_string('edit')); - } - -/// Put all this info together - - $tabrows = array(); - $tabrows[] = $browserow; // Always put these at the top - if ($toolsrow) { - $tabrows[] = $toolsrow; - } - -?> - <div class="glossarydisplay"> - - -<?php -if ($showcommonelements && (count($tabrows[0]) > 1)) { - print_tabs($tabrows, $tab, $inactive, $activated); -} -?> - - <div class="entrybox"> - -<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. +/** + * prints the tabbed bar + * + * @author Peter Dias + * @license http://www.gnu.org/copyleft/gpl.html GNU Public License + * @package mod_glossary + * @copyright 2021 Peter Dias + */ +defined('MOODLE_INTERNAL') || die; + echo html_writer::start_div('entrybox'); if (!isset($category)) { $category = ""; } @@ -120,4 +68,3 @@ if ($showcommonelements && (count($tabrows[0]) > 1)) { break; } echo html_writer::empty_tag('hr'); -?> \ No newline at end of file diff --git a/mod/glossary/templates/standard_action_menu.mustache b/mod/glossary/templates/standard_action_menu.mustache new file mode 100644 index 00000000000..a45ce837296 --- /dev/null +++ b/mod/glossary/templates/standard_action_menu.mustache @@ -0,0 +1,168 @@ +{{! + This file is part of Moodle - http://moodle.org/ + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Moodle. If not, see <http://www.gnu.org/licenses/>. +}} +{{! + @template mod_glossary/standard_action_menu + Actions panel at the bottom of the assignment grading UI. + Classes required for JS: + * none + Data attributes required for JS: + * none + Context variables required for this template: + * see mod/glossary/classes/output/standard_action_bar.php + Example context (json): + { + "addnewbutton": { + "method" : "get", + "url" : "#", + "primary" : true, + "tooltip" : "This is a tooltip", + "label" : "This is a the button text", + "attributes": [ + { + "name": "data-attribute", + "value": "yeah" + } + ] + }, + "tools": { + "button": { + "method" : "get", + "url" : "#", + "primary" : true, + "tooltip" : "This is a tooltip", + "label" : "This is a the button text", + "attributes": [ + { + "name": "data-attribute", + "value": "yeah" + } + ] + }, + "select": { + "options": [ + { + "url": "www.google.com", + "string": "Google" + }, + { + "url": "www.yahoo.com", + "string": "Yahoo" + } + ] + } + }, + "tabjumps": + { + "id": "url_select_test", + "action": "https://example.com/post", + "formid": "url_select_form", + "sesskey": "sesskey", + "label": "core/url_select", + "helpicon": { + "title": "Help with something", + "text": "Help with something", + "url": "http://example.org/help", + "linktext": "", + "icon":{ + "extraclasses": "iconhelp", + "attributes": [ + {"name": "src", "value": "../../../pix/help.svg"}, + {"name": "alt", "value": "Help icon"} + ] + } + }, + "showbutton": "Go", + "options": [{ + "name": "Group 1", "isgroup": true, "options": + [ + {"name": "Item 1", "isgroup": false, "value": "1"}, + {"name": "Item 2", "isgroup": false, "value": "2"} + ]}, + {"name": "Group 2", "isgroup": true, "options": + [ + {"name": "Item 3", "isgroup": false, "value": "3"}, + {"name": "Item 4", "isgroup": false, "value": "4"} + ]}], + "disabled": false, + "title": "Some cool title" + }, + "searchbox": { + "action": "http://localhost/stable/mod/glossary/view.php", + "hiddenfields": [ + { + "name": "id", + "value": 23 + }, + { + "name": "mode", + "value": "search" + } + ], + "otherfields": "<input type='checkbox'>Rendered checkbox", + "inputname": "hook", + "query": "hook", + "searchstring": "Search" + } + } +}} +<div class="container-fluid px-0"> + <div class="row mx-0"> + <div class="d-flex"> + <div class="col-xs"> + {{#addnewbutton}} + {{> core/single_button }} + {{/addnewbutton}} + </div> + </div> + + <div class="d-flex ml-auto"> + {{#tools}} + {{#button}} + <div class="pr-1"> + {{> core/single_button}} + </div> + {{/button}} + {{#select}} + <div> + <div class="btn-group"> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + ... + <span class="sr-only">{{#str}} exportentries, mod_glossary {{/str}}</span> + </button> + <div class="dropdown-menu"> + {{#options}} + <a class="dropdown-item" href="{{url}}">{{string}}</a> + {{/options}} + </div> + </div> + </div> + {{/select}} + {{/tools}} + </div> + </div> + <div class="row mt-2 ml-0"> + <div class="d-flex"> + {{#tabjumps}} + <div class="col-xs pr-1"> + {{> core/url_select }} + </div> + {{/tabjumps}} + {{#searchbox}} + <div class="col-xs"> + {{> core/search_input }} + </div> + {{/searchbox}} + </div> + </div> +</div> diff --git a/mod/glossary/version.php b/mod/glossary/version.php index a237d5d2bdf..dd7b89ed8da 100644 --- a/mod/glossary/version.php +++ b/mod/glossary/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2021052502; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2021052503; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2021052500; // Requires this Moodle version. $plugin->component = 'mod_glossary'; // Full name of the plugin (used for diagnostics) $plugin->cron = 0; diff --git a/mod/glossary/view.php b/mod/glossary/view.php index c363643f8a4..4e7f2357f1d 100644 --- a/mod/glossary/view.php +++ b/mod/glossary/view.php @@ -51,6 +51,7 @@ $cm = cm_info::create($cm); require_course_login($course->id, true, $cm); $context = context_module::instance($cm->id); require_capability('mod/glossary:view', $context); +$hassecondary = $PAGE->has_secondary_navigation(); // Prepare format_string/text options $fmtoptions = array( @@ -270,16 +271,20 @@ $straddentry = get_string("addentry", "glossary"); $strnoentries = get_string("noentries", "glossary"); $strsearchindefinition = get_string("searchindefinition", "glossary"); $strsearch = get_string("search"); -$strwaitingapproval = get_string('waitingapproval', 'glossary'); +$strwaitingapproval = get_string('pendingapproval', 'glossary'); /// If we are in approval mode, prit special header $PAGE->set_title($glossary->name); $PAGE->set_heading($course->fullname); $url = new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id)); -if (isset($mode)) { +if (isset($mode) && $mode) { $url->param('mode', $mode); } $PAGE->set_url($url); + +$renderer = $PAGE->get_renderer('mod_glossary'); +$actionbar = new \mod_glossary\output\standard_action_bar($cm, $glossary, $dp, $mode, $hook, + $sortkey, $sortorder, $offset, $pagelimit, $fullsearch, $tab, $defaulttab); $PAGE->force_settings_menu(); if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) @@ -288,22 +293,27 @@ if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) $rsstitle = format_string($course->shortname, true, array('context' => context_course::instance($course->id))) . ': '. format_string($glossary->name); rss_add_http_header($context, 'mod_glossary', $glossary, $rsstitle); } - if ($tab == GLOSSARY_APPROVAL_VIEW) { require_capability('mod/glossary:approve', $context); $PAGE->navbar->add($strwaitingapproval); - echo $OUTPUT->header(); - echo $OUTPUT->heading($strwaitingapproval); -} else { /// Print standard header - echo $OUTPUT->header(); } -echo $OUTPUT->heading(format_string($glossary->name), 2); +echo $OUTPUT->header(); +$hassecondary = $PAGE->has_secondary_navigation(); + +if (!$hassecondary) { + if ($tab == GLOSSARY_APPROVAL_VIEW) { + echo $OUTPUT->heading($strwaitingapproval); + } + echo $OUTPUT->heading(format_string($glossary->name), 2); +} // Render the activity information. $completiondetails = \core_completion\cm_completion_details::get_instance($cm, $USER->id); $activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id); echo $OUTPUT->activity_information($cm, $completiondetails, $activitydates); - +if ($showcommonelements) { + echo $renderer->main_action_bar($actionbar); +} /// All this depends if whe have $showcommonelements if ($showcommonelements) { /// To calculate available options @@ -331,7 +341,7 @@ if ($showcommonelements) { }*/ /// Decide about to print the approval link - if (has_capability('mod/glossary:approve', $context)) { + if (has_capability('mod/glossary:approve', $context) && !$hassecondary) { /// Check we have pending entries if ($hiddenentries = $DB->count_records('glossary_entries', array('glossaryid'=>$glossary->id, 'approved'=>0))) { if ($availableoptions) { @@ -340,8 +350,8 @@ if ($showcommonelements) { $availableoptions .='<span class="helplink">' . '<a href="' . $CFG->wwwroot . '/mod/glossary/view.php?id=' . $cm->id . '&mode=approval' . '"' . - ' title="' . s(get_string('waitingapproval', 'glossary')) . '">' . - get_string('waitingapproval', 'glossary') . ' ('.$hiddenentries.')</a>' . + ' title="' . s($strwaitingapproval) . '">' . + $strwaitingapproval . ' ('.$hiddenentries.')</a>' . '</span>'; } } @@ -351,27 +361,6 @@ if ($showcommonelements) { echo '<div class="glossarycontrol" style="text-align: right">'; echo $availableoptions; -/// The print icon - if ( $showcommonelements and $mode != 'search') { - if (has_capability('mod/glossary:manageentries', $context) or $glossary->allowprintview) { - $params = array( - 'id' => $cm->id, - 'mode' => $mode, - 'hook' => $hook, - 'sortkey' => $sortkey, - 'sortorder' => $sortorder, - 'offset' => $offset, - 'pagelimit' => $pagelimit - ); - $printurl = new moodle_url('/mod/glossary/print.php', $params); - $printtitle = get_string('printerfriendly', 'glossary'); - $printattributes = array( - 'class' => 'printicon', - 'title' => $printtitle - ); - echo html_writer::link($printurl, $printtitle, $printattributes); - } - } /// End glossary controls // print_box_end(); /// glossarycontrol echo '</div><br />'; @@ -384,52 +373,6 @@ if ($glossary->intro && $showcommonelements) { echo $OUTPUT->box(format_module_intro('glossary', $glossary, $cm->id), 'generalbox', 'intro'); } -/// Search box -if ($showcommonelements ) { - $fullsearchchecked = false; - if ($fullsearch || $mode != 'search') { - $fullsearchchecked = true; - } - - $check = [ - 'name' => 'fullsearch', - 'id' => 'fullsearch', - 'value' => '1', - 'checked' => $fullsearchchecked, - 'label' => $strsearchindefinition - ]; - - $checkbox = $OUTPUT->render_from_template('core/checkbox', $check); - - $hiddenfields = [ - (object) ['name' => 'id', 'value' => $cm->id], - (object) ['name' => 'mode', 'value' => 'search'], - ]; - $data = [ - 'action' => new moodle_url('/mod/glossary/view.php'), - 'hiddenfields' => $hiddenfields, - 'otherfields' => $checkbox, - 'inputname' => 'hook', - 'query' => ($mode == 'search') ? s($hook) : '', - 'searchstring' => get_string('search'), - 'extraclasses' => 'my-2' - ]; - echo $OUTPUT->render_from_template('core/search_input', $data); -} - -/// Show the add entry button if allowed -if (has_capability('mod/glossary:write', $context) && $showcommonelements ) { - echo '<div class="singlebutton glossaryaddentry">'; - echo "<form class=\"form form-inline mb-1\" id=\"newentryform\" method=\"get\" action=\"$CFG->wwwroot/mod/glossary/edit.php\">"; - echo '<div>'; - echo "<input type=\"hidden\" name=\"cmid\" value=\"$cm->id\" />"; - echo '<input type="submit" value="'.get_string('addentry', 'glossary').'" class="btn btn-secondary" />'; - echo '</div>'; - echo '</form>'; - echo "</div>\n"; -} - - require("tabs.php"); require("sql.php"); @@ -561,7 +504,6 @@ if ( $paging ) { echo '</div>'; } echo '<br />'; -glossary_print_tabbed_table_end(); /// Finish the page echo $OUTPUT->footer();