commit 7e15aeaf522581b32c15fe0b1110d827639afe42
Author: Dan Marsden <dan@catalyst.net.nz>
Date:   Mon Jul 19 13:06:47 2010 +1200

    Droplist settings page

diff --git a/admin/settings/appearance.php b/admin/settings/appearance.php
index 1278df2..483deab 100644
--- a/admin/settings/appearance.php
+++ b/admin/settings/appearance.php
@@ -21,6 +21,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
         )));
     $ADMIN->add('themes', $temp);
     $ADMIN->add('themes', new admin_externalpage('themeselector', get_string('themeselector','admin'), $CFG->wwwroot . '/theme/index.php'));
+    $ADMIN->add('themes', new admin_externalpage('thememenu', get_string('thememenu','admin'), $CFG->wwwroot . '/theme/menu.php'));
 
     // calendar
     $temp = new admin_settingpage('calendar', get_string('calendarsettings','admin'));
diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php
index 056bc25..98210b8 100644
--- a/lang/en_utf8/admin.php
+++ b/lang/en_utf8/admin.php
@@ -732,6 +732,8 @@ $string['systempaths'] = 'System Paths';
 $string['tabselectedtofront'] = 'On tables with tabs, should the row with the currently selected tab be placed at the front';
 $string['tabselectedtofronttext'] = 'Bring selected tab row to front';
 $string['themelist'] = 'Theme list';
+$string['thememenu'] = 'Drop-list configuration';
+$string['thememenuurl'] = 'URL';
 $string['themeselector'] = 'Theme Selector';
 $string['themesettings'] = 'Theme settings';
 $string['therewereerrors'] = 'There were errors in your data';
diff --git a/local/db/upgrade.php b/local/db/upgrade.php
index f0e907b..58ae62a 100644
--- a/local/db/upgrade.php
+++ b/local/db/upgrade.php
@@ -37,7 +37,19 @@ function xmldb_local_upgrade($oldversion) {
         /// Launch add field name
         $result = $result && add_field($table, $field);
     }
-
+    if ($result && $oldversion < 2009091501) {
+
+        /// Define table theme_menu
+        $table = new XMLDBTable('theme_menu');
+        /// Adding fields to table mdl_course_approval_status
+        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+        $table->addFieldInfo('root', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+        $table->addFieldInfo('pos', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null );
+        $table->addFieldInfo('name', XMLDB_TYPE_TEXT, '100', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+        $table->addFieldInfo('link', XMLDB_TYPE_TEXT, '300', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $result = $result && create_table($table);
+    }
 
     return $result;
 }
diff --git a/theme/menu.php b/theme/menu.php
new file mode 100644
index 0000000..e076ec2
--- /dev/null
+++ b/theme/menu.php
@@ -0,0 +1,238 @@
+<?php
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards Martin Dougiamas     http://dougiamas.com  //
+//           (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com  //
+//                                                                       //
+// This program 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 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program 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:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+// This file is the admin frontend to execute all the checks available
+// in the environment.xml file. It includes database, php and
+// php_extensions. Also, it's possible to update the xml file
+// from moodle.org be able to check more and more versions.
+
+    require_once('../config.php');
+    require_once($CFG->libdir.'/adminlib.php');
+    require_once($CFG->libdir.'/formslib.php');
+
+    admin_externalpage_setup('thememenu');
+
+class menu_item_form extends moodleform {
+
+    function definition() {
+
+        global $CFG;
+        $mform    =& $this->_form;
+
+        $itm = $this->_customdata['itm'];
+
+        $mform->addElement('header', 'general', '');
+        $mform->addElement('text', 'name', get_string('name'), 'size="48"');
+        $mform->setType('name', PARAM_TEXT);
+        $mform->addRule('name', get_string('required'), 'required', null, 'client');
+
+        $mform->addElement('text', 'link', get_string('thememenuurl', 'admin'), 'size="48"');
+        $mform->setType('link', PARAM_TEXT);
+        $mform->addRule('link', get_string('required'), 'required', null, 'client');
+        
+        $par = array();
+        $par[0] = 'None';
+        if($roots = get_records('theme_menu', 'root', '0','`pos` ASC')) {
+            foreach($roots as $root) {
+                $par[$root->id] = $root->name;
+            }
+        }
+        $mform->addElement('select', 'root', get_string('category'), $par);
+        
+        $mform->addElement('hidden', 'id', 0);
+        $mform->setType('id', PARAM_INT);
+        $mform->addElement('hidden', 'pos', 0);
+        $mform->setType('pos', PARAM_INT);
+
+        $this->add_action_buttons(true);
+    }
+
+    function validation($data, $files) {
+        $errors = parent::validation($data, $files);
+
+        return $errors;
+    }
+
+}
+
+/// Parameters
+    $action  = optional_param('action', '', PARAM_ACTION);
+    $id = optional_param('id', -1, PARAM_INT);
+    
+    $mform = new menu_item_form('menu.php?action='.$action.'&id='.$id);
+    
+    if ($action == 'delete') {
+        if($id) {
+            if(!delete_records('theme_menu', 'id', $id)) {
+                error("Could not delete menu item");
+            }
+            make_main_menu();
+        }
+    }
+    elseif ($action == 'down') {
+        if($id) {
+           if($data = get_record('theme_menu', 'id', $id)) {
+               $root = $data->root;
+               $oldpos = $data->pos;
+               $newpos = $oldpos + 1;
+               
+               if(execute_sql("UPDATE {$CFG->prefix}theme_menu SET pos = ".$oldpos.' WHERE root = '.$root.' AND pos = '.$newpos, false)) {
+                   execute_sql("UPDATE {$CFG->prefix}theme_menu SET pos = ".$newpos.' WHERE id = '.$id, false);
+               }
+               make_main_menu();
+           }
+        }
+    }
+    elseif ($action == 'up') {
+        if($id) {
+           if($data = get_record('theme_menu', 'id', $id)) {
+               $root = $data->root;
+               $oldpos = $data->pos;
+               $newpos = $oldpos - 1;
+               
+               if(execute_sql("UPDATE {$CFG->prefix}theme_menu SET pos = ".$oldpos.' WHERE root = '.$root.' AND pos = '.$newpos, false)) {
+                   execute_sql("UPDATE {$CFG->prefix}theme_menu SET pos = ".$newpos.' WHERE id = '.$id, false);
+               }
+               make_main_menu();
+           }
+        }
+    }
+    if ($fromform = $mform->get_data()) {
+        $fromform->name = htmlspecialchars($fromform->name);
+        if ($action == 'edit') {
+            if($id > 0) {
+                if(!update_record('theme_menu', $fromform)) {
+                    error("Could not update menu item.");
+                }
+            } else {
+                $fromform->pos = count_records('theme_menu', 'root', $fromform->root);
+                if(!insert_record('theme_menu', $fromform, true)) {
+                    error("Could not create menu item.");
+                }
+            }
+            make_main_menu();
+        }
+        $action = '';
+    }
+
+
+
+/// Print the header stuff
+    admin_externalpage_print_header();
+    
+    print_heading(get_string('thememenu', 'admin'));
+    
+    print_simple_box_start();
+    
+    if($action == 'edit') {
+        if($data = get_record('theme_menu', 'id', $id)) {
+            $mform->set_data($data);
+            $mform->display();
+        } else {
+            $mform->display();
+        }
+    } else {
+        echo '<form action="menu.php" style="text-align: right;">'."\r\n";
+        echo '<input type="hidden" name="action" value="edit" />'."\r\n";
+        echo '<input type="submit" value="'.get_string('new').'" />'."\r\n";
+        echo '</form>'."\r\n";
+        if($roots = get_records('theme_menu', 'root', '0','`pos` ASC')) {
+            $maxroot = get_record_sql("SELECT MAX(pos) AS max FROM {$CFG->prefix}theme_menu WHERE root = 0")->max;
+            foreach($roots as $root) {
+                echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$root->id.'&action=delete"><img src="'.$CFG->pixpath.'/t/delete.gif" /></a>'."\r\n";
+                echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$root->id.'&action=edit"><img src="'.$CFG->pixpath.'/t/edit.gif" /></a>'."\r\n";
+                if ($root->pos > 0)
+                {
+                    echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$root->id.'&action=up"><img src="'.$CFG->pixpath.'/t/up.gif" /></a>'."\r\n";
+                } else {
+                    echo '<img src="'.$CFG->pixpath.'/t/spacer.gif" />'."\r\n";
+                }
+                if ($root->pos < $maxroot)
+                {
+                    echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$root->id.'&action=down"><img src="'.$CFG->pixpath.'/t/down.gif" /></a>'."\r\n";
+                } else {
+                    echo '<img src="'.$CFG->pixpath.'/t/spacer.gif" />'."\r\n";
+                }
+                echo '<a href="'.$root->link.'" >'.$root->name.'</a><br />'."\r\n";
+                
+                if($children = get_records('theme_menu', 'root', $root->id,'`pos` ASC')) {
+                    $maxchild = get_record_sql("SELECT MAX(pos) AS max FROM {$CFG->prefix}theme_menu WHERE root = ".$root->id)->max;
+                    foreach($children as $child) {
+                        
+                        echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$child->id.'&action=delete"><img src="'.$CFG->pixpath.'/t/delete.gif" /></a>'."\r\n";
+                        echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$child->id.'&action=edit"><img src="'.$CFG->pixpath.'/t/edit.gif" /></a>'."\r\n";
+                        echo '<img src="'.$CFG->pixpath.'/t/spacer.gif" /><img src="'.$CFG->pixpath.'/t/spacer.gif" />'."\r\n";
+                        if ($child->pos > 0)
+                        {
+                            echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$child->id.'&action=up"><img src="'.$CFG->pixpath.'/t/up.gif" /></a>'."\r\n";
+                        } else {
+                            echo '<img src="'.$CFG->pixpath.'/t/spacer.gif" />'."\r\n";
+                        }
+                        if ($child->pos < $maxchild)
+                        {
+                            echo '<a href="'.$CFG->wwwroot.'/theme/menu.php?id='.$child->id.'&action=down"><img src="'.$CFG->pixpath.'/t/down.gif" /></a>'."\r\n";
+                        } else {
+                            echo '<img src="'.$CFG->pixpath.'/t/spacer.gif" />'."\r\n";
+                        }
+                        echo '<a href="'.$child->link.'" >'.$child->name.'</a><br />'."\r\n";
+                    }
+                }
+            }
+        }
+    }
+    
+    print_simple_box_end();
+    
+    admin_externalpage_print_footer();
+
+//Function that creates html used by drop list - saves as a file in dataroot to allow collection by the theme.
+function make_main_menu(){
+    global $CFG, $db;
+    $result = '<ul>';
+
+    if($roots = get_records('theme_menu', 'root', '0','`pos` ASC')){
+        foreach($roots as $root) {
+            $result .= '<li>'."\r\n";
+            $result .= '<a href="'.$root->link.'">'.$root->name.'</a>'."\r\n";
+
+            if($children = get_records('theme_menu', 'root',$root->id,'`pos` ASC')) {
+                $result .= '<ul>'."\r\n";
+                foreach($children as $child) {
+                    $result .= '<li><a href="'.$child->link.'">'.$child->name.'</a></li>'."\r\n";
+                }
+                $result .= '</ul>'."\r\n";
+            }
+
+            $result .= '</li>'."\r\n";
+        }
+        $result .= '</ul>'."\r\n";
+    }
+    $fp = fopen($CFG->dataroot.'/droplist.htm', 'w');
+    fwrite($fp, $result);
+    fclose($fp);
+}
+
+?>
\ No newline at end of file

