MDL-50032 webservice: Allow plugins to add functions into services

This commit is contained in:
Juan Leyva 2016-03-03 09:42:27 +01:00
parent 7adc7ef14f
commit 186eba1b2e
4 changed files with 95 additions and 1 deletions

View File

@ -2535,6 +2535,7 @@
<FIELD NAME="classpath" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="capabilities" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="all capabilities that are required to be run by the function (separated by comma)"/>
<FIELD NAME="services" TYPE="char" LENGTH="1333" NOTNULL="false" SEQUENCE="false" COMMENT="all the services (by shortname) where this function must be included"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>

View File

@ -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;
}

View File

@ -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.

View File

@ -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.