Actually I m working with the D7 version with all http://drupal.org/node/1129282#comment-4605446 but I could select it. (perhaps a dev release would be nice.)

Anyway I believe it should be possible for module to override the controller.

Normaly a drupal webservice is [module].[method_name] but we want the service for example to understand getEvents directly so we could implement a hook that allows that. That way we can create the proper name like defined in hook_services_resources and call it directly. (This is what happend when a premade wsdl without knowing about drupal has to be implemented.)

Example:
This is a hook_services_resources()

function ao_service_services_resources() {
  return array(
    'ao_service' => array(        
      'getEvents' => array(
        'file' => array('type' => 'inc', 'module' => 'ao_service', 'name' => 'resources/ao_service.resource'),
        'help'   => t('This method returns a list of events.'),
        'access callback' => 'ao_service_get_events_access',
        'callback' => 'ao_service_get_events',
        'args'     => array(
          array(
            'name'         => 'date',
            'type'         => 'string',
            'description'  => t('date.'),
            'source'       => 'data',
            'optional'     => FALSE,
          ),            
        ),
      ),        
    ),    
  );
}

We can add the check in class ServicesSoapServer

class ServicesSoapServer {
  public function __call($method_name, $args) {  	
    // Handle the request.      
    $info =  services_server_info_object();
    $endpoint = services_endpoint_load($info->endpoint);
     
    //Invoke the hook to override the controller          
    $controller_overrides = module_invoke_all('soap_server_controller', $method_name, $endpoint->name); 
    if (empty($controller_overrides) && !$args['prevent_override']) {
      $services_method_name = str_replace('_soap_', '.', $method_name);
      $controller = services_controller_get($services_method_name, $endpoint->name);    
    }
    else {
      $controller = services_controller_get(array_shift($controller_overrides)); 
    }
    
    // make sure any arguments not passed have default values inserted if they are supplied 
    // TODO: should we be validating argument types here?
    foreach ($controller['args'] as $key => $arg_config) {
      if (!isset($args[$key]) && isset($arg_config['default value'])) {
        $args[$key] = $arg_config['default value'];
      }
    }

    if ($endpoint->debug) {
      watchdog('soap server', "METHOD_NAME:<pre>". print_r($method_name, TRUE)."</pre");
      watchdog('soap server', "ENDPOINT:<pre>". print_r($endpoint, TRUE)."</pre");
      watchdog('soap server', "ARGS:<pre>". print_r($args, TRUE)."</pre");
      watchdog('soap server', "CONTROLLER:<pre>". print_r($controller, TRUE)."</pre");
    }
    try {
      $ret = services_controller_execute($controller, $args);
    }
    catch (Exception $e) {
      $code = $e->getCode();
      $soap_fault = new SoapFault($e->getMessage(), $code);
      watchdog('soap_server', $e->getMessage(), 'error');
      throw $soap_fault;
    }
    return $ret;
  }
}

We implment the hook soap_servcer_controller to override

function ao_service_soap_server_controller($method_name, $endpoint) {
	if ($method_name == 'getEvents' && $endpoint == 'soap_server') {
	  return 'ao_service.getEvents';
	}
}

Now this will work (using wsclient module to operate the client)

  $service = wsclient_service_load('ao');	 
  $out = $service->invoke('getEvents', array());  

You could still tell drupal not to listen to the override if needed, so the normal way can still work.

  $service = wsclient_service_load('ao');	 
  $args['prevent_override'] = true;
  $out = $service->invoke('ao_service.getEvents', true); 

I didnt roll a patch because this is allready code that is patch 17 times (http://drupal.org/node/1129282#comment-4605446) I hope I m making sense and the possibility is added to the module.

Comments

marcus_clements’s picture

Sounds like a good idea - are you using this system in a working site?
Please roll a patch against 7.x-3.x dev if you have time.