}
- public static function services_discovery() {
- global $CFG, $DB;
- $externalfiles = array();
- webservice_lib::setListApiFiles($externalfiles, $CFG->dirroot);
-
- $wsnotification = array();
-
- //retrieve all saved services
- $services = $DB->get_records('external_services', array('custom' => 0)); //we only retrieve not custom service
- $dbservices = array();
- foreach ($services as $service) {
- $dbservices[$service->name] = false; //value false will define obsolote status
- //once we parse all services from the external files
- }
-
- //retrieve all saved servicefunction association including their function name,
- //service name, function id and service id
-
- $servicesfunctions = $DB->get_records_sql("SELECT fs.id as id, fs.enabled as enabled, s.name as servicename, s.id as serviceid, f.name as functionname, f.id as functionid
- FROM {external_services} s, {external_functions} f, {external_services_functions} fs
- WHERE fs.externalserviceid = s.id AND fs.externalfunctionid = f.id AND s.custom = 0");
- $dbservicesfunctions = array();
- foreach ($servicesfunctions as $servicefunction) {
- $dbservicesfunctions[$servicefunction->servicename][$servicefunction->functionname] = array('serviceid' => $servicefunction->serviceid,
- 'functionid' => $servicefunction->functionid,
- 'id' => $servicefunction->id,
- 'notobsolete' => false);
- //once we parse all services from the external files
- }
-
- foreach ($externalfiles as $file) {
- require($file);
- $classpath = substr($file,strlen($CFG->dirroot)+1); //remove the dir root + / from the file path
- $classpath = substr($classpath,0,strlen($classpath) - 13); //remove /external.php from the classpath
- $classpath = str_replace('/','_',$classpath); //convert all / into _
- $classname = $classpath."_external";
- $api = new $classname();
- if (method_exists($api, 'get_descriptions')) {
- $descriptions = $api->get_descriptions();
-
- //retrieve all saved function into the DB for this specific external file/component
- $functions = $DB->get_records('external_functions', array('component' => $classpath));
- //remove the obsolete ones
- $dbfunctions = array();
- foreach ($functions as $function) {
- $dbfunctions[$function->name] = false; //value false is not important we just need the key
- if (!array_key_exists($function->name, $descriptions)) {
- //remove all obsolete function from the db
- $DB->delete_records('external_functions', array('name' => $function->name, 'component' => $classpath));
- }
- }
-
- foreach ($descriptions as $functionname => $functiondescription) {
- if (array_key_exists('service', $functiondescription) && !empty($functiondescription['service'])) { //check that the service has been set in the description
- //only create the one not already saved into the database
- if (!array_key_exists($functionname, $dbfunctions)) {
- $newfunction = new object();
- $newfunction->component = $classpath;
- $newfunction->name = $functionname;
- $DB->insert_record('external_functions', $newfunction);
- $notifparams = new object();
- $notifparams->functionname = $functionname;
- $notifparams->servicename = $functiondescription['service'];
- $wsnotification[] = get_string('wsinsertfunction','webservice', $notifparams);
- }
-
- //check if the service is into the database
- if (!array_key_exists($functiondescription['service'], $dbservices)) {
- $newservice = new object();
- $newservice->name = $functiondescription['service'];
- $newservice->enabled = 0;
- $newservice->custom = 0;
- $DB->insert_record('external_services', $newservice);
- }
- $dbservices[$functiondescription['service']] = true; //mark the service as not obsolete
- //and add it if it wasn't in the list
- }
- else {
- $errors = new object();
- $errors->classname = $classname;
- $errors->functionname = $functionname;
- throw new moodle_exception("wsdescriptionserviceisempty",'','', $errors);
- }
-
- //check if the couple service/function is into the database
- if (!array_key_exists($functiondescription['service'], $dbservicesfunctions) || !array_key_exists($functionname, $dbservicesfunctions[$functiondescription['service']])) {
- $newassociation = new object();
- $newassociation->externalserviceid = $DB->get_field('external_services','id',array('name' => $functiondescription['service']));
- $newassociation->externalfunctionid = $DB->get_field('external_functions','id',array('name' => $functionname, 'component' => $classpath));
- $newassociation->enabled = 0;
- $DB->insert_record('external_services_functions', $newassociation);
- }
- $dbservicesfunctions[$functiondescription['service']][$functionname]['notobsolete'] = true;
- }
- }
- else {
- throw new moodle_exception("wsdoesntextendbaseclass",'','', $classname);
- }
- }
-
- //remove all obsolete service (not the custom ones)
- foreach ($dbservices as $servicename => $notobsolete) {
- if (!$notobsolete) {
- $DB->delete_records('external_services', array('name' => $servicename));
- }
- }
-
- //remove all obsolete association (not the custom ones)
- foreach ($dbservicesfunctions as $servicename => $servicefunctions ) {
- foreach ($servicefunctions as $functioname => $servicefunction) {
- if (!$servicefunction['notobsolete']) {
- $DB->delete_records('external_services_functions', array('id' => $servicefunction['id']));
- $notifparams = new object();
- $notifparams->functionname = $functionname;
- $notifparams->servicename = $servicename;
- $wsnotification[] = get_string('wsdeletefunction','webservice', $notifparams);
- }
- }
- }
-
- return $wsnotification;
- }
-
/**
* Check if the Moodle site has the web service protocol enable
* @global object $CFG