diff --git a/lib/db/install.xml b/lib/db/install.xml index b29a3f84417..ff92a464eaa 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -2535,6 +2535,7 @@ + diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index ea198d8cb3e..fc8ba43a926 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -1451,5 +1451,18 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2016030103.00); } + if ($oldversion < 2016030400.01) { + // Add the new services field. + $table = new xmldb_table('external_functions'); + $field = new xmldb_field('services', XMLDB_TYPE_CHAR, '1333', null, null, null, null, 'capabilities'); + + // Conditionally launch add field services. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + // Main savepoint reached. + upgrade_main_savepoint(true, 2016030400.01); + } + return true; } diff --git a/lib/upgradelib.php b/lib/upgradelib.php index 4f96d38b370..b3c92a20fe7 100644 --- a/lib/upgradelib.php +++ b/lib/upgradelib.php @@ -1080,6 +1080,28 @@ function external_update_descriptions($component) { $dbfunction->capabilities = $functioncapabilities; $update = true; } + + if (isset($function['services']) and is_array($function['services'])) { + sort($function['services']); + $functionservices = implode(',', $function['services']); + } else { + // Force null values in the DB. + $functionservices = null; + } + + if ($dbfunction->services != $functionservices) { + // Now, we need to check if services were removed, in that case we need to remove the function from them. + $servicesremoved = array_diff(explode(",", $dbfunction->services), explode(",", $functionservices)); + foreach ($servicesremoved as $removedshortname) { + if ($externalserviceid = $DB->get_field('external_services', 'id', array("shortname" => $removedshortname))) { + $DB->delete_records('external_services_functions', array('functionname' => $dbfunction->name, + 'externalserviceid' => $externalserviceid)); + } + } + + $dbfunction->services = $functionservices; + $update = true; + } if ($update) { $DB->update_record('external_functions', $dbfunction); } @@ -1092,6 +1114,15 @@ function external_update_descriptions($component) { $dbfunction->classpath = empty($function['classpath']) ? null : $function['classpath']; $dbfunction->component = $component; $dbfunction->capabilities = array_key_exists('capabilities', $function)?$function['capabilities']:''; + + if (isset($function['services']) and is_array($function['services'])) { + sort($function['services']); + $dbfunction->services = implode(',', $function['services']); + } else { + // Force null values in the DB. + $dbfunction->services = null; + } + $dbfunction->id = $DB->insert_record('external_functions', $dbfunction); } unset($functions); @@ -1200,6 +1231,52 @@ function external_update_descriptions($component) { } } +/** + * Allow plugins to add external functions to other plugins or core services. + * This function is executed just after all the plugins have been updated. + */ +function external_update_services() { + global $DB; + + // Look for external functions that want to be added in existing services. + $functions = $DB->get_records_select('external_functions', 'services IS NOT NULL'); + + $servicescache = array(); + foreach ($functions as $function) { + // Prevent edge cases. + if (empty($function->services)) { + continue; + } + $services = explode(',', $function->services); + + foreach ($services as $serviceshortname) { + // Get the service id by shortname. + if (!empty($servicescache[$serviceshortname])) { + $serviceid = $servicescache[$serviceshortname]; + } else if ($service = $DB->get_record('external_services', array('shortname' => $serviceshortname))) { + // If the component is empty, it means that is not a built-in service. + // We don't allow functions to inject themselves in services created by an user in Moodle. + if (empty($service->component)) { + continue; + } + $serviceid = $service->id; + $servicescache[$serviceshortname] = $serviceid; + } else { + // Service not found. + continue; + } + // Finally add the function to the service. + $newf = new stdClass(); + $newf->externalserviceid = $serviceid; + $newf->functionname = $function->name; + + if (!$DB->record_exists('external_services_functions', (array)$newf)) { + $DB->insert_record('external_services_functions', $newf); + } + } + } +} + /** * upgrade logging functions */ @@ -1657,6 +1734,9 @@ function upgrade_noncore($verbose) { foreach ($plugintypes as $type=>$location) { upgrade_plugins($type, 'print_upgrade_part_start', 'print_upgrade_part_end', $verbose); } + // Upgrade services. This function gives plugins a chance to add functions to existing core or non-core services. + external_update_services(); + // Update cache definitions. Involves scanning each plugin for any changes. cache_helper::update_definitions(); // Mark the site as upgraded. diff --git a/version.php b/version.php index 725a10533b1..90fc4b020fa 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2016030400.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2016030400.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.