From 653029303077529c682e0ec920922e75b6b34248 Mon Sep 17 00:00:00 2001
From: Jon Marthaler <mart0969@umn.edu>
Date: Fri, 7 Feb 2014 14:51:11 -0600
Subject: [PATCH] Applied changes from f5820cdd3567a12e8d, to enable admin to
 reorder grade report, export, and imports in the
 navigation.

---
 admin/settings/grades.php    |    9 ++
 grade/edit/plugins/index.php |   36 ++++++
 grade/edit/plugins/lib.php   |  291 ++++++++++++++++++++++++++++++++++++++++++
 grade/lib.php                |   41 ++++++
 lang/en/grades.php           |    9 ++
 5 files changed, 386 insertions(+)
 create mode 100644 grade/edit/plugins/index.php
 create mode 100644 grade/edit/plugins/lib.php

diff --git a/admin/settings/grades.php b/admin/settings/grades.php
index b80bb43..6f58c58 100644
--- a/admin/settings/grades.php
+++ b/admin/settings/grades.php
@@ -217,5 +217,14 @@ if (has_capability('moodle/grade:manage', $systemcontext)
         }
     }
 
+    //20140206 mart0969 - Add new category and pages for managing navigation
+    // Navigation
+    $ADMIN->add('grades', new admin_category('gradenavigation', new lang_string('navigationsettings', 'grades')));
+    $reportadmin = new admin_externalpage('managegradereport', new lang_string('managegradereport','grades'), $CFG->wwwroot.'/grade/edit/plugins/index.php?type=gradereport', 'moodle/grade:manage');
+    $ADMIN->add('gradenavigation',$reportadmin);
+    $importadmin = new admin_externalpage('managegradeimport', new lang_string('managegradeimport','grades'), $CFG->wwwroot.'/grade/edit/plugins/index.php?type=gradeimport', 'moodle/grade:manage');
+    $ADMIN->add('gradenavigation',$importadmin);
+    $exportadmin = new admin_externalpage('managegradeexport', new lang_string('managegradeexport','grades'), $CFG->wwwroot.'/grade/edit/plugins/index.php?type=gradeexport', 'moodle/grade:manage');
+    $ADMIN->add('gradenavigation',$exportadmin);
 } // end of speedup
 
diff --git a/grade/edit/plugins/index.php b/grade/edit/plugins/index.php
new file mode 100644
index 0000000..fc84ab7
--- /dev/null
+++ b/grade/edit/plugins/index.php
@@ -0,0 +1,36 @@
+<?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/>.
+
+/**
+ * Allows the admin to manage grade plugins
+ *
+ * @package    grade
+ * @copyright 2014 University of Minnesota
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/** Include config.php */
+require_once '../../../config.php';
+/** Include the admin library */
+require_once 'lib.php';
+
+// create the class for this controller
+$pluginmanager = new grade_plugin_manager(required_param('type', PARAM_TEXT));
+
+$PAGE->set_context(get_system_context());
+
+// execute the controller
+$pluginmanager->execute(optional_param('action', null, PARAM_PLUGIN), optional_param('plugin', null, PARAM_PLUGIN));
diff --git a/grade/edit/plugins/lib.php b/grade/edit/plugins/lib.php
new file mode 100644
index 0000000..4abe357
--- /dev/null
+++ b/grade/edit/plugins/lib.php
@@ -0,0 +1,291 @@
+<?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/>.
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * This file contains the classes for the admin settings for grades
+ *
+ * @package   grade
+ * @copyright 2014 University of Minnesota
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/** Include adminlib.php */
+require_once($CFG->libdir . '/adminlib.php');
+
+class grade_plugin_manager {
+
+    /** @var object the url of the manage plugin page */
+    private $pageurl;
+    /** @var string any error from the current action */
+    private $error = '';
+    /** @var string either submission or feedback */
+    private $subtype = '';
+
+    /**
+     * Constructor for this assignment plugin manager
+     * @param string $subtype - either assignsubmission or assignfeedback
+     */
+    public function __construct($type) {
+        $this->pageurl = new moodle_url('/grade/edit/plugins/index.php', array('type'=>$type));
+        $this->subtype = $type;
+    }
+
+
+    /**
+     * Return a list of plugins sorted by the order defined in the admin interface
+     *
+     * @return array The list of plugins
+     */
+    public function get_sorted_plugins_list() {
+        $names = get_plugin_list($this->subtype);
+
+        $result = array();
+
+        foreach ($names as $name => $path) {
+            $idx = get_config($this->subtype . '_' . $name, 'sortorder');
+            if (!$idx) {
+                $idx = 0;
+            }
+            while (array_key_exists($idx, $result)) $idx +=1;
+            $result[$idx] = $name;
+        }
+        ksort($result);
+
+        return $result;
+    }
+
+
+    /**
+     * Util function for writing an action icon link
+     *
+     * @param string $action URL parameter to include in the link
+     * @param string $plugintype URL parameter to include in the link
+     * @param string $icon The key to the icon to use (e.g. 't/up')
+     * @param string $alt The string description of the link used as the title and alt text
+     * @return string The icon/link
+     */
+    private function format_icon_link($action, $plugintype, $icon, $alt) {
+        global $OUTPUT;
+
+        return $OUTPUT->action_icon(new moodle_url($this->pageurl,
+                array('action' => $action, 'plugin'=> $plugintype, 'sesskey' => sesskey())),
+                new pix_icon($icon, $alt, 'moodle', array('title' => $alt)),
+                null, array('title' => $alt)) . ' ';
+    }
+
+    /**
+     * Write the HTML for the plugins table.
+     *
+     * @return None
+     */
+    private function view_plugins_table() {
+        global $OUTPUT, $CFG;
+        /** Include tablelib.php */
+        require_once($CFG->libdir . '/tablelib.php');
+
+        // Set up the table.
+        $this->view_header();
+        $table = new flexible_table($this->subtype . 'pluginsadminttable');
+        $table->define_baseurl($this->pageurl);
+        $table->define_columns(array('pluginname', 'hideshow', 'order', 'settings'));
+        $table->define_headers(array(get_string($this->subtype , 'grades'),
+                get_string('hideshow', 'grades'), get_string('order'), get_string('settings')));
+        $table->set_attribute('id', $this->subtype . 'plugins');
+        $table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
+        $table->setup();
+
+
+        $plugins = $this->get_sorted_plugins_list();
+
+        foreach ($plugins as $idx => $plugin) {
+            $row = array();
+
+            $row[] = get_string('pluginname', $this->subtype . '_' . $plugin);
+
+            $visible = !get_config($this->subtype . '_' . $plugin, 'disabled');
+
+            if ($visible) {
+                $row[] = $this->format_icon_link('hide', $plugin, 't/hide', get_string('disable'));
+            } else {
+                $row[] = $this->format_icon_link('show', $plugin, 't/show', get_string('enable'));
+            }
+
+            $movelinks = '';
+            if (!$idx == 0) {
+                $movelinks .= $this->format_icon_link('moveup', $plugin, 't/up', get_string('up'));
+            } else {
+                $movelinks .= $OUTPUT->spacer(array('width'=>16));
+            }
+            if ($idx != count($plugins) - 1) {
+                $movelinks .= $this->format_icon_link('movedown', $plugin, 't/down', get_string('down'));
+            }
+            $row[] = $movelinks;
+
+            if ($row[1] != '' && file_exists($CFG->dirroot . '/grade/report/' . $plugin . '/settings.php')) {
+                $row[] = html_writer::link(new moodle_url('/admin/settings.php',
+                        array('section' => $this->subtype . $plugin)), get_string('settings'));
+            } else {
+                $row[] = '&nbsp;';
+            }
+            $table->add_data($row);
+        }
+
+
+        $table->finish_output();
+        $this->view_footer();
+    }
+
+    /**
+     * Write the page header
+     *
+     * @return None
+     */
+    private function view_header() {
+        global $OUTPUT;
+        admin_externalpage_setup('manage' . $this->subtype);
+        // Print the page heading.
+        echo $OUTPUT->header();
+        echo $OUTPUT->heading(get_string('manage' . $this->subtype, 'grades'));
+    }
+
+    /**
+     * Write the page footer
+     *
+     * @return None
+     */
+    private function view_footer() {
+        global $OUTPUT;
+        echo $OUTPUT->footer();
+    }
+
+    /**
+     * Check this user has permission to edit the list of installed plugins
+     *
+     * @return None
+     */
+    private function check_permissions() {
+        // Check permissions.
+        require_login();
+        $systemcontext = context_system::instance();
+        require_capability('moodle/site:config', $systemcontext);
+    }
+
+
+    /**
+     * Hide this plugin
+     *
+     * @param string $plugin - The plugin to hide
+     * @return string The next page to display
+     */
+    public function hide_plugin($plugin) {
+        set_config('disabled', 1, $this->subtype . '_' . $plugin);
+        return 'view';
+    }
+
+    /**
+     * Change the order of this plugin
+     *
+     * @param string $plugintomove - The plugin to move
+     * @param string $dir - up or down
+     * @return string The next page to display
+     */
+    public function move_plugin($plugintomove, $dir) {
+        // get a list of the current plugins
+        $plugins = $this->get_sorted_plugins_list();
+
+        $currentindex = 0;
+
+        // throw away the keys
+
+        $plugins = array_values($plugins);
+
+        // find this plugin in the list
+        foreach ($plugins as $key => $plugin) {
+            if ($plugin == $plugintomove) {
+                $currentindex = $key;
+                break;
+            }
+        }
+
+        // make the switch
+        if ($dir == 'up') {
+            if ($currentindex > 0) {
+                $tempplugin = $plugins[$currentindex - 1];
+                $plugins[$currentindex - 1] = $plugins[$currentindex];
+                $plugins[$currentindex] = $tempplugin;
+            }
+        } else if ($dir == 'down') {
+            if ($currentindex < (count($plugins) - 1)) {
+                $tempplugin = $plugins[$currentindex + 1];
+                $plugins[$currentindex + 1] = $plugins[$currentindex];
+                $plugins[$currentindex] = $tempplugin;
+            }
+        }
+
+        // save the new normal order
+        foreach ($plugins as $key => $plugin) {
+            set_config('sortorder', $key, $this->subtype . '_' . $plugin);
+        }
+        return 'view';
+    }
+
+
+    /**
+     * Show this plugin
+     *
+     * @param string $plugin - The plugin to show
+     * @return string The next page to display
+     */
+    public function show_plugin($plugin) {
+        set_config('disabled', 0, $this->subtype . '_' . $plugin);
+        return 'view';
+    }
+
+
+    /**
+     * This is the entry point for this controller class
+     *
+     * @param string $action - The action to perform
+     * @param string $plugin - Optional name of a plugin type to perform the action on
+     * @return None
+     */
+    public function execute($action, $plugin) {
+        if ($action == null) {
+            $action = 'view';
+        }
+
+        $this->check_permissions();
+
+        // process
+        if ($action == 'hide' && $plugin != null) {
+            $action = $this->hide_plugin($plugin);
+        } else if ($action == 'show' && $plugin != null) {
+            $action = $this->show_plugin($plugin);
+        } else if ($action == 'moveup' && $plugin != null) {
+            $action = $this->move_plugin($plugin, 'up');
+        } else if ($action == 'movedown' && $plugin != null) {
+            $action = $this->move_plugin($plugin, 'down');
+        }
+
+
+        // view
+        if ($action == 'view') {
+            $this->view_plugins_table();
+        }
+    }
+}
diff --git a/grade/lib.php b/grade/lib.php
index 9825986..3be3e4f 100644
--- a/grade/lib.php
+++ b/grade/lib.php
@@ -2578,8 +2578,12 @@ abstract class grade_helper {
         } else if (count($gradepreferences) == 0) {
             $gradepreferences = false;
             asort($gradereports);
+            //20140206 mart0969 - Sort plugins based on config in database
+            $gradereports = self::get_sorted_plugins($gradereports,'gradereport');
         } else {
             asort($gradereports);
+            //20140206 mart0969 - Sort plugins based on config in database
+            $gradereports = self::get_sorted_plugins($gradereports,'gradereport');
             asort($gradepreferences);
         }
         self::$gradereports = $gradereports;
@@ -2735,6 +2739,8 @@ abstract class grade_helper {
 
         if (count($importplugins) > 0) {
             asort($importplugins);
+            //20140206 mart0969 - Sort plugins based on config in database
+            $importplugins = self::get_sorted_plugins($importplugins,'gradeimport');
             self::$importplugins = $importplugins;
         } else {
             self::$importplugins = false;
@@ -2771,6 +2777,8 @@ abstract class grade_helper {
         }
         if (count($exportplugins) > 0) {
             asort($exportplugins);
+            //20140206 Sort plugins based on config in database
+            $exportplugins = self::get_sorted_plugins($exportplugins,'gradeexport');
             self::$exportplugins = $exportplugins;
         } else {
             self::$exportplugins = false;
@@ -2778,6 +2786,39 @@ abstract class grade_helper {
         return self::$exportplugins;
     }
 
+    //20140206 mart0969 - Add function to sort plugins based on config in database
+    /**
+     * Sort list of plugins based on configuration in database
+     * @param array $plugins
+     * @param string $type
+     * @return array
+     */
+     public static function get_sorted_plugins($plugins, $type) {
+        $new = array();
+        $sorted = array();
+        //Check configuration in database
+        foreach ($plugins as $name => $data) {
+            //Check if plugin is hidden
+            $hidden = get_config($type . '_' . $name, 'disabled');
+            if ($hidden == 1) {
+                continue;
+            }
+            $idx = get_config($type . '_' . $name, 'sortorder');
+            if (!$idx) {
+                $idx = 0;
+            }
+            while (array_key_exists($idx, $sorted)) $idx +=1;
+            $sorted[$idx] = $name;
+        }
+        ksort($sorted);
+        //Now take the sorted list and get the data from the original list passed in
+        foreach ($sorted as $pluginname) {
+            $new[$pluginname] = $plugins[$pluginname];
+        }
+
+        return $new;
+     }
+
     /**
      * Returns the value of a field from a user record
      *
diff --git a/lang/en/grades.php b/lang/en/grades.php
index 799b259..1addb72 100644
--- a/lang/en/grades.php
+++ b/lang/en/grades.php
@@ -321,6 +321,8 @@ $string['hidelocks'] = 'Hide locks';
 $string['hidenooutcomes'] = 'Show outcomes';
 $string['hidequickfeedback'] = 'Hide quick feedback';
 $string['hideranges'] = 'Hide ranges';
+//20140206 mart0969 - Add string for hide/show
+$string['hideshow'] = 'Hide/Show';
 $string['hidetotalifhiddenitems'] = 'Hide totals if they contain hidden items';
 $string['hidetotalifhiddenitems_help'] = 'This setting specifies whether totals which contain hidden grade items are shown to students or replaced with a hyphen (-). If shown, the total may be calculated either excluding or including hidden items.
 
@@ -395,6 +397,11 @@ $string['locktimedate'] = 'Locked after: {$a}';
 $string['lockverbose'] = 'Lock {$a->category} {$a->itemmodule} {$a->itemname}';
 $string['lowest'] = 'Lowest';
 $string['lowgradeletter'] = 'Low';
+//20140206 mart0969 - Add strings for managing grade plugins
+$string['managegradeexport'] = 'Export item order';
+$string['managegradeimport'] = 'Import item order';
+$string['managegradereport'] = 'Report item order';
+//End 20140206
 $string['manualitem'] = 'Manual item';
 $string['mapfrom'] = 'Map from';
 $string['mappings'] = 'Grade item mappings';
@@ -417,6 +424,8 @@ $string['multfactorvalue'] = 'Multiplicator value for {$a}';
 $string['multfactor_help'] = 'The multiplicator is the factor by which all grades for this grade item will be multiplied, with a maximum value of the maximum grade. For example, if the multiplicator is 2 and the maximum grade is 100, then all grades less than 50 are multiplied by 2, and all grades 50 and above are changed to 100.';
 $string['mypreferences'] = 'My preferences';
 $string['myreportpreferences'] = 'My report preferences';
+//20140206 mart0969 - Add string for navigation settings category
+$string['navigationsettings'] = 'Navigation';
 $string['navmethod'] = 'Navigation method';
 $string['neverdeletehistory'] = 'Never delete history';
 $string['newcategory'] = 'New category';
-- 
1.7.9.5

