? cascade.patch
? config.php
? local
? test.php
? lib/locallib.patch
Index: admin/index.php
===================================================================
RCS file: /cvsroot/moodle/moodle/admin/index.php,v
retrieving revision 1.286.2.25
diff -u -r1.286.2.25 index.php
--- admin/index.php	27 Nov 2008 20:31:02 -0000	1.286.2.25
+++ admin/index.php	19 Dec 2008 11:53:47 -0000
@@ -459,7 +459,7 @@
 /// Check for local database customisations
 /// first old *.php update and then the new upgrade.php script
     require_once("$CFG->dirroot/lib/locallib.php");
-    upgrade_local_db("$CFG->wwwroot/$CFG->admin/index.php");  // Return here afterwards
+    upgrade_local_dbs("$CFG->wwwroot/$CFG->admin/index.php");  // Return here afterwards
 
 /// Check for changes to RPC functions
     require_once("$CFG->dirroot/$CFG->admin/mnet/adminlib.php");
Index: lib/accesslib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v
retrieving revision 1.421.2.94
diff -u -r1.421.2.94 accesslib.php
--- lib/accesslib.php	19 Dec 2008 08:56:01 -0000	1.421.2.94
+++ lib/accesslib.php	19 Dec 2008 11:53:53 -0000
@@ -3186,15 +3186,18 @@
  * @return array of capabilities
  */
 function get_cached_capabilities($component='moodle') {
+    global $CFG;
     if ($component == 'moodle') {
         $storedcaps = get_records_select('capabilities',
                         "name LIKE 'moodle/%:%'");
-    } else if ($component == 'local') {
-        $storedcaps = get_records_select('capabilities', 
-                        "name LIKE 'moodle/local:%'");
-    } else {
+   } else if (preg_match('/^local/', $component)) {
+     //downbrowses the cascade chain of local{n} subdirs. gets local, locallocal etc...
+        $pat = str_replace('/', '', $component);
         $storedcaps = get_records_select('capabilities',
-                        "name LIKE '$component:%'");
+                       "name LIKE 'moodle/{$pat}:%'");
+    } else {
+       $storedcaps = get_records_select('capabilities',
+                       "name LIKE '$component:%'");
     }
     return $storedcaps;
 }
Index: lib/locallib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/locallib.php,v
retrieving revision 1.10.2.4
diff -u -r1.10.2.4 locallib.php
--- lib/locallib.php	30 Jun 2008 06:01:13 -0000	1.10.2.4
+++ lib/locallib.php	19 Dec 2008 11:53:54 -0000
@@ -115,57 +115,90 @@
  * @uses $db to do something really evil with the debug setting that should probably be eliminated. TODO!
  * @param string $continueto a URL passed to print_continue() if the local upgrades succeed.
  */
-function upgrade_local_db($continueto) {
+function upgrade_local_dbs($continueto) {
 
     global $CFG, $db;
 
-    // if we don't have code version or a db upgrade file, just return true, we're unneeded
-    if (!file_exists($CFG->dirroot.'/local/version.php') || !file_exists($CFG->dirroot.'/local/db/upgrade.php')) {
-        return true;
-    }
+    $path = '/local';
+    $pat = 'local';
+    $status = true;
+    $changed = false;
+    $firstloop = true;
+
+    while(is_dir($CFG->dirroot.$path)){
+        // if we don't have code version or a db upgrade file, check lower
+        if (!file_exists($CFG->dirroot."{$path}/version.php") || !file_exists($CFG->dirroot."{$path}/db/upgrade.php")){
+            $path .= '/local';
+            $pat .= 'local';
+            continue;
+        }
 
-    require_once ($CFG->dirroot .'/local/version.php');  // Get code versions
+        require_once ($CFG->dirroot ."{$path}/version.php");  // Get code versions
 
-    if (empty($CFG->local_version)) { // normally we'd install, but just replay all the upgrades.
-        $CFG->local_version = 0;
-    }
+        $cfgvarname = "{$pat}_version";
+
+        if (empty($CFG->{$cfgvarname})) { // normally we'd install, but just replay all the upgrades.
+            $CFG->{$cfgvarname} = 0;
+        }
+
+        $localversionvar = "{$pat}_version";
+
+        // echo "($localversionvar) ".$$localversionvar." > ($cfgvarname) ".$CFG->{$cfgvarname}."<br/>";
+
+        if ($$localversionvar > $CFG->{$cfgvarname}) { // something upgrades!
+
+            upgrade_log_start();
+            /// Capabilities
+            /// do this first *instead of* last , so that the installer has the chance to locally assign caps
+            if (!update_capabilities(substr($path, 1))) {
+                error('Could not set up the capabilities for ' . $pat . '!');
+            }
 
-    if ($local_version > $CFG->local_version) { // upgrade!
-        $strdatabaseupgrades = get_string('databaseupgrades');
-        print_header($strdatabaseupgrades, $strdatabaseupgrades,
-            build_navigation(array(array('name' => $strdatabaseupgrades, 'link' => null, 'type' => 'misc'))), '', upgrade_get_javascript());
-
-        upgrade_log_start();
-        require_once ($CFG->dirroot .'/local/db/upgrade.php');
-
-        $db->debug=true;
-        if (xmldb_local_upgrade($CFG->local_version)) {
-            $db->debug=false;
-            if (set_config('local_version', $local_version)) {
-                notify(get_string('databasesuccess'), 'notifysuccess');
-                notify(get_string('databaseupgradelocal', '', $local_version), 'notifysuccess');
-                print_continue($continueto);
-                print_footer('none');
-                exit;
+            if ($firstloop){
+                $strdatabaseupgrades = get_string('databaseupgrades');
+                print_header($strdatabaseupgrades, $strdatabaseupgrades,
+                    build_navigation(array(array('name' => $strdatabaseupgrades, 'link' => null, 'type' => 'misc'))), '', upgrade_get_javascript());
+                $firstloop = false;
+            }
+            $changed = true;
+
+            require_once ($CFG->dirroot ."{$path}/db/upgrade.php");
+
+            $db->debug = true;
+            $upgradefunc = "xmldb_{$pat}_upgrade";
+            if ($upgradefunc($CFG->{$cfgvarname})) {
+                $db->debug = false;
+                if (set_config($localversionvar, $$localversionvar)) {
+                    notify(get_string('databasesuccess'), 'notifysuccess');
+                    notify(get_string('databaseupgradelocal', '', $path.' >> '.$$localversionvar), 'notifysuccess');
+                } else {
+                    $status = false;
+                    error('Upgrade of local database customisations failed in $path! (Could not update version in config table)');
+                }
             } else {
-                error('Upgrade of local database customisations failed! (Could not update version in config table)');
+                $db->debug = false;
+                error("Upgrade failed!  See {$path}/version.php");
             }
-        } else {
-            $db->debug=false;
-            error('Upgrade failed!  See local/version.php');
+
+            if (!events_update_definition($pat)) {
+                error('Could not set up the events definitions for ' . $pat . '!');
+            }
+            upgrade_log_finish();
+
+        } else if ($$localversionvar < $CFG->{$cfgvarname}) {
+            notify('WARNING!!!  The local version you are using in $path is OLDER than the version that made these databases!');
         }
 
-    } else if ($local_version < $CFG->local_version) {
-        upgrade_log_start();
-        notify('WARNING!!!  The local version you are using is OLDER than the version that made these databases!');
-    }
 
-    /// Capabilities
-    if (!update_capabilities('local')) {
-        error('Could not set up the capabilities for local!');
+        $path .= '/local';
+        $pat .= 'local';
     }
 
-    upgrade_log_finish();
+    if ($changed){
+        print_continue($continueto);
+        print_footer('none');
+        exit;
+    }
 }
 
 /**
