source: sipes/modules_contrib/soap_server/soap_server.module @ b0e683a

stableversion-3.0
Last change on this file since b0e683a was b0e683a, checked in by root <root@…>, 8 años ago

se comento un valor para establecer la conexion

  • Propiedad mode establecida a 100644
File size: 13.5 KB
Línea 
1<?php
2// $Id: soap_server.module,v 1.2.2.2.2.2.2.10 2011/02/01 14:27:50 rayvaughn Exp $
3/**
4 * @file
5 * Enable SOAP for services module (6.x-3.x).
6 *
7 * The XMLRPC style {resource}.{method} method names have been replaced with
8 * {resource}_{method} which are valid PHP function names.
9 *
10 * The WSDL provides type information for request parameters which is generated from the resource
11 * info. Response
12 */
13
14/**
15 * Drupal core hooks.
16 */
17
18/**
19 * Implementation of hook_menu().
20 */
21function soap_server_menu() {
22  $items['soap_server/debug_wsdl/%soap_server_endpoint'] = array(
23    'type' => MENU_CALLBACK,
24    'title' => 'Soap Server 3 Debug WSDL',
25    'page callback' => 'soap_server_debug_wsdl',
26    'page arguments' => array(2),
27    'access arguments' => array('debug soap server'),
28  );
29    $items['soap_server/debug_client/%soap_server_endpoint/%node'] = array(
30    'title'            => 'Soap Server Debug Client',
31    'access arguments' => array('debug soap server'),
32    'page callback'    => 'soap_server_debug_client',
33    'page arguments'   => array(2, 3),
34    'type'             => MENU_CALLBACK,
35  );
36  return $items;
37}
38
39/**
40 * endpoint menu loader
41 *
42 * Return the services endpoint object from the endpoint name.
43 *
44 * @param unknown_type $endpoint_name
45 */
46function soap_server_endpoint_load($endpoint_name) {
47  $endpoint = services_endpoint_load($endpoint_name);
48  if (is_object($endpoint)) {
49    return $endpoint;
50  }
51  return FALSE;
52}
53
54/**
55 * Implementation of hook_perm().
56 */
57function soap_server_perm() {
58  return array('access soap server', 'debug soap server');
59}
60
61/**
62 * Implementation of hook_server_info().
63 *
64 * This function tells services module that we are providing a server
65 */
66function soap_server_server_info() {
67  return array(
68    'name' => 'SOAP',
69  );
70}
71
72/**
73 * Services 3 hooks.
74 */
75
76/**
77 * Implementation of hook_server().
78 *
79 * The services endpoint callback function that handles all requests to a SOAP
80 * server 3 endpoint. If ?wsdl is appended to the URL, the WSDL is served.
81 */
82function soap_server_server() {
83  $info =  services_server_info_object();
84  $endpoint = services_endpoint_load($info->endpoint);
85  $get = $_GET;
86  // Serve the WSDL if ?wsdl is appended to the URL.
87  if (in_array('wsdl', array_keys($get))) {
88    // The soap_server_wsdl_output() function delivers the WSDL and exits.
89    soap_server_wsdl_output($endpoint);
90  }
91  // Disable the WSDL cache so it's not stored in memory or on disk.
92  ini_set("soap.wsdl_cache_enabled", "0");
93  $wsdl_url = url($endpoint->path, array('absolute' => TRUE, )) . '?wsdl';
94  //se configura para que el servidor no compruebe el certificado
95  $context = array(
96    'ssl' => array(
97      // set some SSL/TLS specific options
98      'verify_peer' => false,
99      //'verify_peer_name' => false,
100    ),
101  );
102  $options = array(
103    'stream_context'=> stream_context_create($context),
104  );
105  try {
106    $server = new SoapServer($wsdl_url, $options);
107    $server->setClass(ServicesSoapServer);
108    $server->handle();
109  }
110  catch (Exception $e) {
111    watchdog('soap_server', $e->getMessage(), 'error');
112  }
113  exit;
114}
115
116/**
117 * Get a WSDL for the given endpoint.
118 *
119 * The WSDL provides a soap method for each method of the configured resources.
120 * See /admin/build/services/your_endpoint/resources
121 *
122 * @param $endpoint
123 */
124function soap_server_get_wsdl($endpoint) {
125  // allow other modules to provide the wsdl
126  $wsdl_overrides = module_invoke_all('soap_server_wsdl', $endpoint);
127  if (is_array($wsdl_overrides) && !empty($wsdl_overrides)) {
128    // if there is more than 1 wsdl the first takes priority allowing modules to override others by
129    // setting system weight
130    $wsdl = array_shift($wsdl_overrides);
131    return $wsdl;
132  }
133  $service_endpoint = url($endpoint->path, array('absolute' => TRUE));
134  // get the content of the schema for each hose_xml profile using the standard namespace xs:
135  $methods = _soap_server_get_methods($endpoint->name);
136  foreach ($methods as $method_name => $method_config) {
137    // requests can specify which field to use to identify the node - default is nid
138    $parts = "";
139    // add parameters from the args array in the resource
140    foreach ((array)$method_config['args'] as $arg) {
141      switch ($arg['type']) {
142        case 'int':
143        case 'string':
144        case 'struct':
145          $parts .= "
146    <part name='"  . $arg['name'] ."' type='xsd1:". $arg['type'] ."' />";
147          break;
148        // we can work out how to deal with other parameter types later
149        default:
150          $parts .= "
151    <part name='". $arg['name'] ."' type='xsd1:any'/>";
152      }   
153    }
154    $requests .= "
155  <message name='". $method_name ."_request'>". $parts ."
156  </message>";
157    // we don't know what the response will be so go for struct - seems like this is appropriate
158    // for most resources
159    $responses .= "
160  <message name='". $method_name ."_response'>
161    <part name='response_object' type='xsd1:struct'/>
162  </message>";
163    $port_type_operations .= "
164  <operation name='$method_name'>
165    <input message='tns:". $method_name ."_request'/>
166    <output message='tns:". $method_name ."_response'/>
167  </operation>";
168    $binding_operations .= "
169  <operation name='$method_name'>
170    <soap:operation soapAction='urn:xmethods-delayed-quotes#$method_name'/>
171    <input>
172      <soap:body
173        use='literal'
174        namespace='urn:xmethods-delayed-quotes' />
175    </input>
176    <output>
177      <soap:body
178        use='literal'
179        namespace='urn:xmethods-delayed-quotes' />
180    </output>
181  </operation>
182";
183  }
184  $include = drupal_get_path('module', 'soap_server') . '/wsdl/soap_server.wsdl.inc';
185  if (!is_file($include)) {
186    return t("Could not load include @inc", array('@inc' => $include));
187  }
188  else {
189    require_once($include);
190    // $wsdl_content is assigned in the include file
191    return $wsdl_content;
192  }
193}
194
195/**
196 * Delivers XML suitable for supplying WSDL to Soap clients.
197 *
198 * @param $xml
199 *   The content of the WSDL to serve
200 */
201function soap_server_wsdl_output($endpoint) {
202  $wsdl_content = soap_server_get_wsdl($endpoint);
203  ob_end_clean();
204  drupal_set_header('Connection: close');
205  drupal_set_header('Content-Length: ' . drupal_strlen($wsdl_content));
206  drupal_set_header('Content-Type: application/wsdl+xml; charset=utf-8');
207  drupal_set_header('Date: '. date('r'));
208  echo $wsdl_content;
209  exit;
210}
211
212
213/**
214 * Soap Server 3 Class for handling soap requests.
215 */
216class ServicesSoapServer {
217  public function __call($method_name, $args) {
218    // Handle the request.
219    $info =  services_server_info_object();
220    $endpoint = services_endpoint_load($info->endpoint);
221    $services_method_name = str_replace('_soap_', '.', $method_name);   
222    $controller = services_controller_get($services_method_name, $endpoint->name);
223    // make sure any arguments not passed have default values inserted if they are supplied
224    // TODO: should we be validating argument types here?
225    foreach ($controller['args'] as $key => $arg_config) {
226      if (!isset($args[$key]) && isset($arg_config['default value'])) {
227        $args[$key] = $arg_config['default value'];
228      }
229    }
230   
231    if ($endpoint->debug) {
232      watchdog('soap server', "METHOD_NAME:<pre>". print_r($method_name, TRUE)."</pre");
233      watchdog('soap server', "ENDPOINT:<pre>". print_r($endpoint, TRUE)."</pre");
234      watchdog('soap server', "ARGS:<pre>". print_r($args, TRUE)."</pre");
235      watchdog('soap server', "CONTROLLER:<pre>". print_r($controller, TRUE)."</pre");
236    }
237    try {
238      $ret = services_controller_execute($controller, $args);
239    }
240    catch (Exception $e) {
241      $code = $e->getCode();
242      $soap_fault = new SoapFault($e->getMessage(), $code);
243      watchdog('soap_server', $e->getMessage(), 'error');
244      throw $soap_fault;
245    }
246    return $ret;
247  }
248}
249
250/**
251 * Return a list of service methods for the endopint
252 * Method names are created from {resource}_{method} or {resource}_action_{method}
253 * NB: These method names are different from the XMLRPC names because PHP5 can't have a . in function
254 * names
255 *
256 * @param $endpoint
257 */
258function _soap_server_get_methods($endpoint) {
259  $resources = services_get_resources($endpoint);
260  // traverse the resources retrieving valid methods and action methods
261  // TODO: inspect services to confirm the validity of this approach
262  foreach ($resources as $resource_name => $resource_info) {
263    foreach ($resource_info as $method_name => $method_data) {
264      if (!is_array($method_data)) {
265        // it's not a method
266        continue;
267      }
268      if ( isset($method_data['callback'])) {
269        // if this element has a callback we'll assume it is a method
270        $soap_method_name = $resource_name .'_soap_'. $method_name;
271        $supported_methods[$soap_method_name] = $method_data;
272      }
273      if ($method_name == "actions") {
274        // TODO: confirm that all actions elements are valid methods
275        foreach ($method_data as $action_name => $action_data) {
276          $soap_method_name = $resource_name .'_soap_'. $action_name;
277          $supported_methods[$soap_method_name] = $action_data;
278        }
279      }
280    }
281  }
282  return $supported_methods;
283}
284
285/**
286 * Debug function for soap_server services. The devel module is required to use
287 * this function.
288 *
289 * @param $nid
290 */
291function soap_server_debug_client($endpoint, $node) {
292  if (!module_exists('devel')) {
293    drupal_set_message(t('Devel module is required for the debug client function.'), 'error');
294    return t("fail");
295  }
296  $debug_output == array(
297    'endpoint' => $endpoint,
298        'node' => $node,
299  );
300  if (empty($endpoint)) {
301    watchdog('soap_server', 'no endpoint obj in debug client', 'error');
302    return 'fail - no endpoint obj in debug client';
303  }
304  ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
305  $wsdl_url = url($endpoint->path, array('absolute' => TRUE, )) . '?wsdl';
306  try {
307    $client = new SoapClient($wsdl_url, array(
308      'trace' => 1
309    ));
310    // show the available functions as specified in the WSDL
311    $functions = $client->__getFunctions();
312    $debug_output['client functions'] = $functions;
313   
314    // retrieve a node  -  need node access for anonymous
315    $return = $client->node_soap_retrieve($node->nid);
316    $response = $client->__getLastResponse();
317    $request = $client->__getLastRequest();
318    $debug_output["node_soap_retrieve"] = array(
319      $node->nid => array('request' => $request, 'response' => $response, 'return' => $return)
320    );
321   
322    //retrieve a variable - enable services "get a system variable" permission for anonymous
323    $return = $client->system_soap_get_variable('css_js_query_string');
324    $response = $client->__getLastResponse();
325    $request = $client->__getLastRequest();
326    $debug_output["system_soap_get_variable"] = array(
327      'css_js_query_string' => array('request' => $request, 'response' => $response, 'return' => $return)
328    ); 
329   
330    // retrieve a user  - needs acess for anonymous
331    $return = $client->user_soap_retrieve(1);  // anonymous user needs "access user profiles" perm
332    $response = $client->__getLastResponse();
333    $request = $client->__getLastRequest();
334    $debug_output["user_soap_retrieve"] = array(
335      1 => array('request' => $request, 'response' => $response, 'return' => $return)
336    );
337   
338  } catch (Exception $e) {
339    $debug_output['client'] = $e;
340  }
341  dsm($debug_output);
342  return t("done");
343}
344
345/**
346 * Display the content of the WSDL for debugging.
347 *
348 * @param $endpoint
349 */
350function soap_server_debug_wsdl($endpoint) {
351  $wsdl_content = soap_server_get_wsdl($endpoint);
352  $wsdl_content = _soap_server_beautify_wsdl($wsdl_content);
353  if (module_exists('geshifilter')) {
354    $geshi_inc = drupal_get_path('module', 'geshifilter') .'/geshifilter.pages.inc';
355    require_once $geshi_inc;
356    $wsdl_content = geshifilter_geshi_process($wsdl_content, 'xml', TRUE);
357  }
358  else {
359    $wsdl_content = "<code>". htmlspecialchars($wsdl_content) ."</code>";
360  }
361  return $wsdl_content;
362}
363
364/**
365 * Make the WSDL look nice. 
366 *
367 * WARNING: This is NOT a general XML formatter because it will remove whitespace
368 * between tags and in CDATA blocks
369 *
370 * @param unknown_type $xml
371 */
372function _soap_server_beautify_wsdl($xml) {
373  // remove whitespace between tags
374  $xml = preg_replace('/(>)(\s*)(<)/', '$1$3', $xml);
375  // limit spaces and tabs one space
376  $xml = preg_replace('/([ \t]{2,})/', ' ', $xml);
377  // add marker linefeeds to aid the pretty-tokeniser (adds a linefeed between all tag-end boundaries)
378  $xml = preg_replace('/(>)\s*(<)(\/*)/', "$1\n$2$3", $xml);
379 
380  // now indent the tags
381  $token      = strtok($xml, "\n");
382  $result     = ''; // holds formatted version as it is built
383  $pad        = 1; // initial indent
384  $matches    = array(); // returns from preg_matches()
385 
386  // scan each line and adjust indent based on opening/closing tags
387  while ($token !== false) :
388 
389    // test for the various tag states
390   
391    // 1. open and closing tags on same line - no change
392    if (preg_match('/.+<\/\w[^>]*>$/', $token, $matches)) :
393      $indent=0;
394    // 2. closing tag - outdent now
395    elseif (preg_match('/^<\/\w/', $token, $matches)) :
396      $pad--;
397    // 3. opening tag - don't pad this one, only subsequent tags
398    elseif (preg_match('/^<\w[^>]*[^\/]>.*$/', $token, $matches)) :
399      $indent=1;
400    // 4. no indentation needed
401    else :
402      $indent = 0;
403    endif;
404   
405    // pad the line with the required number of leading spaces
406    $line    = str_pad($token, strlen($token)+$pad, ' ', STR_PAD_LEFT);
407    $result .= $line . "\n"; // add to the cumulative result, with linefeed
408    $token   = strtok("\n"); // get the next token
409    $pad    += $indent; // update the pad size for subsequent lines   
410  endwhile;
411 
412  return $result;
413}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.