| 1 |
<?php |
<?php |
| 2 |
// $Id: services.module,v 1.8.2.88.2.8 2009/10/15 03:59:55 marcingy Exp $ |
// $Id: services.module,v 1.8.2.88.2.9 2009/11/04 20:26:54 heyrocker Exp $ |
| 3 |
/** |
/** |
| 4 |
* @author Services Dev Team |
* @author Services Dev Team |
| 5 |
* @file |
* @file |
| 117 |
// Find which module the server is part of |
// Find which module the server is part of |
| 118 |
foreach (module_implements('server_info') as $module) { |
foreach (module_implements('server_info') as $module) { |
| 119 |
$info = module_invoke($module, 'server_info'); |
$info = module_invoke($module, 'server_info'); |
| 120 |
if ($info['#path'] == $server_path) { |
services_strip_hashes($info); |
| 121 |
|
|
| 122 |
|
if ($info['path'] == $server_path) { |
| 123 |
|
|
| 124 |
// call the server |
// call the server |
| 125 |
services_set_server_info($module); |
services_set_server_info($module); |
| 238 |
// Get information about the current auth module |
// Get information about the current auth module |
| 239 |
$func = services_auth_info($method, $module); |
$func = services_auth_info($method, $module); |
| 240 |
if ($func) { |
if ($func) { |
| 241 |
if ($file = services_auth_info('#file')) { |
if ($file = services_auth_info('file')) { |
| 242 |
require_once(drupal_get_path('module', $module) . '/' . $file); |
require_once(drupal_get_path('module', $module) . '/' . $file); |
| 243 |
} |
} |
| 244 |
|
|
| 258 |
// Get information about the auth module |
// Get information about the auth module |
| 259 |
$func = services_auth_info($method, $module); |
$func = services_auth_info($method, $module); |
| 260 |
if ($func) { |
if ($func) { |
| 261 |
if ($file = services_auth_info('#file', $module)) { |
if ($file = services_auth_info('file', $module)) { |
| 262 |
require_once(drupal_get_path('module', $module) . '/' . $file); |
require_once(drupal_get_path('module', $module) . '/' . $file); |
| 263 |
} |
} |
| 264 |
|
|
| 278 |
* This is the magic function through which all remote method calls must pass. |
* This is the magic function through which all remote method calls must pass. |
| 279 |
*/ |
*/ |
| 280 |
function services_method_call($method_name, $args = array(), $browsing = FALSE) { |
function services_method_call($method_name, $args = array(), $browsing = FALSE) { |
| 281 |
if (is_array($method_name) && isset($method_name['#callback'])) { |
if (is_array($method_name) && isset($method_name['callback'])) { |
| 282 |
$method = $method_name; |
$method = $method_name; |
| 283 |
} |
} |
| 284 |
else { |
else { |
| 292 |
|
|
| 293 |
// Check for missing args |
// Check for missing args |
| 294 |
$hash_parameters = array(); |
$hash_parameters = array(); |
| 295 |
foreach ($method['#args'] as $key => $arg) { |
foreach ($method['args'] as $key => $arg) { |
| 296 |
if (!$arg['#optional']) { |
if (!$arg['optional']) { |
| 297 |
if (!isset($args[$key]) && !is_array($args[$key]) && !is_bool($args[$key])) { |
if (!isset($args[$key]) && !is_array($args[$key]) && !is_bool($args[$key])) { |
| 298 |
return services_error(t('Missing required arguments.'), 406); |
return services_error(t('Missing required arguments.'), 406); |
| 299 |
} |
} |
| 311 |
} |
} |
| 312 |
|
|
| 313 |
// Load the proper file. |
// Load the proper file. |
| 314 |
if ($file = $method['#file']) { |
if ($file = $method['file']) { |
| 315 |
// Initialize file name if not given. |
// Initialize file name if not given. |
| 316 |
$file += array('file name' => ''); |
$file += array('file name' => ''); |
| 317 |
module_load_include($file['file'], $file['module'], $file['file name']); |
module_load_include($file['file'], $file['module'], $file['file name']); |
| 318 |
} |
} |
| 319 |
|
|
| 320 |
// Construct access arguments array |
// Construct access arguments array |
| 321 |
if (isset($method['#access arguments'])) { |
if (isset($method['access arguments'])) { |
| 322 |
$access_arguments = $method['#access arguments']; |
$access_arguments = $method['access arguments']; |
| 323 |
if (isset($method['#access arguments append']) && $method['#access arguments append']) { |
if (isset($method['access arguments append']) && $method['access arguments append']) { |
| 324 |
$access_arguments[] = $args; |
$access_arguments[] = $args; |
| 325 |
} |
} |
| 326 |
} |
} |
| 330 |
} |
} |
| 331 |
|
|
| 332 |
// Call default or custom access callback |
// Call default or custom access callback |
| 333 |
if (call_user_func_array($method['#access callback'], $access_arguments) != TRUE) { |
if (call_user_func_array($method['access callback'], $access_arguments) != TRUE) { |
| 334 |
return services_error(t('Access denied'), 401); |
return services_error(t('Access denied'), 401); |
| 335 |
} |
} |
| 336 |
|
|
| 341 |
if ($server_info) { |
if ($server_info) { |
| 342 |
chdir($server_info->drupal_path); |
chdir($server_info->drupal_path); |
| 343 |
} |
} |
| 344 |
$result = call_user_func_array($method['#callback'], $args); |
$result = call_user_func_array($method['callback'], $args); |
| 345 |
if ($server_info) { |
if ($server_info) { |
| 346 |
chdir($server_root); |
chdir($server_root); |
| 347 |
} |
} |
| 401 |
else { |
else { |
| 402 |
$resources = module_invoke_all('service_resource'); |
$resources = module_invoke_all('service_resource'); |
| 403 |
drupal_alter('service_resources', $resources); |
drupal_alter('service_resources', $resources); |
| 404 |
|
services_strip_hashes($resources); |
| 405 |
|
|
| 406 |
$controllers = array(); |
$controllers = array(); |
| 407 |
services_process_resources($resources, $controllers); |
services_process_resources($resources, $controllers); |
| 408 |
|
|
| 409 |
foreach ($controllers as &$controller) { |
foreach ($controllers as &$controller) { |
| 410 |
if (!isset($controller['#access callback'])) { |
if (!isset($controller['access callback'])) { |
| 411 |
$controller['#access callback'] = 'services_access_menu'; |
$controller['access callback'] = 'services_access_menu'; |
| 412 |
} |
} |
| 413 |
|
|
| 414 |
if (!isset($controller['#auth'])) { |
if (!isset($controller['auth'])) { |
| 415 |
$controller['#auth'] = TRUE; |
$controller['auth'] = TRUE; |
| 416 |
} |
} |
| 417 |
|
|
| 418 |
if (!isset($controller['#key'])) { |
if (!isset($controller['key'])) { |
| 419 |
$controller['#key'] = TRUE; |
$controller['key'] = TRUE; |
| 420 |
} |
} |
| 421 |
} |
} |
| 422 |
|
|
| 461 |
|
|
| 462 |
function _services_process_resource($name, &$resource, &$controllers) { |
function _services_process_resource($name, &$resource, &$controllers) { |
| 463 |
$path = join($name, '/'); |
$path = join($name, '/'); |
| 464 |
$resource['#name'] = $path; |
$resource['name'] = $path; |
| 465 |
|
|
| 466 |
$keys = array('#retrieve','#create','#update','#delete'); |
$keys = array('retrieve', 'create', 'update', 'delete'); |
| 467 |
foreach ($keys as $key) { |
foreach ($keys as $key) { |
| 468 |
if (isset($resource[$key])) { |
if (isset($resource[$key])) { |
| 469 |
$controllers[$path . '/' . $key] = &$resource[$key]; |
$controllers[$path . '/' . $key] = &$resource[$key]; |
| 470 |
} |
} |
| 471 |
} |
} |
| 472 |
|
|
| 473 |
if (isset($resource['#index'])) { |
if (isset($resource['index'])) { |
| 474 |
$controllers[$path . '/#index'] = &$resource['#index']; |
$controllers[$path . '/index'] = &$resource['index']; |
| 475 |
} |
} |
| 476 |
|
|
| 477 |
if (isset($resource['#relationships'])) { |
if (isset($resource['relationships'])) { |
| 478 |
foreach ($resource['#relationships'] as $relname => $rel) { |
foreach ($resource['relationships'] as $relname => $rel) { |
| 479 |
// Run some inheritance logic |
// Run some inheritance logic |
| 480 |
if (isset($resource['#retrieve'])) { |
if (isset($resource['retrieve'])) { |
| 481 |
if (empty($rel['#args']) || $rel['#args'][0]['#name'] !== $resource['#retrieve']['#args'][0]['#name']) { |
if (empty($rel['args']) || $rel['args'][0]['name'] !== $resource['retrieve']['args'][0]['name']) { |
| 482 |
array_unshift($rel['#args'], $resource['#retrieve']['#args'][0]); |
array_unshift($rel['args'], $resource['retrieve']['args'][0]); |
| 483 |
} |
} |
| 484 |
$resource['#relationships'][$relname] = array_merge($resource['#retrieve'], $rel); |
$resource['relationships'][$relname] = array_merge($resource['retrieve'], $rel); |
| 485 |
} |
} |
| 486 |
$controllers[$path . '/relationship/' . $relname] = &$resource['#relationships'][$relname]; |
$controllers[$path . '/relationship/' . $relname] = &$resource['relationships'][$relname]; |
| 487 |
} |
} |
| 488 |
} |
} |
| 489 |
|
|
| 490 |
if (isset($resource['#actions'])) { |
if (isset($resource['actions'])) { |
| 491 |
foreach ($resource['#actions'] as $actname => $act) { |
foreach ($resource['actions'] as $actname => $act) { |
| 492 |
// Run some inheritance logic |
// Run some inheritance logic |
| 493 |
if (isset($resource['#update'])) { |
if (isset($resource['update'])) { |
| 494 |
$up = $resource['#update']; |
$up = $resource['update']; |
| 495 |
unset($up['#args']); |
unset($up['args']); |
| 496 |
$resource['#actions'][$actname] = array_merge($up, $act); |
$resource['actions'][$actname] = array_merge($up, $act); |
| 497 |
} |
} |
| 498 |
$controllers[$path . '/action/' . $actname] = &$resource['#actions'][$actname]; |
$controllers[$path . '/action/' . $actname] = &$resource['actions'][$actname]; |
| 499 |
} |
} |
| 500 |
} |
} |
| 501 |
|
|
| 502 |
if (isset($resource['#targeted actions'])) { |
if (isset($resource['targeted actions'])) { |
| 503 |
foreach ($resource['#targeted actions'] as $actname => $act) { |
foreach ($resource['targeted actions'] as $actname => $act) { |
| 504 |
// Run some inheritance logic |
// Run some inheritance logic |
| 505 |
if (isset($resource['#update'])) { |
if (isset($resource['update'])) { |
| 506 |
if (empty($act['#args']) || $act['#args'][0]['#name'] !== $resource['#update']['#args'][0]['#name']) { |
if (empty($act['args']) || $act['args'][0]['name'] !== $resource['update']['args'][0]['name']) { |
| 507 |
array_unshift($act['#args'], $resource['#update']['#args'][0]); |
array_unshift($act['args'], $resource['update']['args'][0]); |
| 508 |
} |
} |
| 509 |
$resource['#targeted actions'][$actname] = array_merge($resource['#update'], $act); |
$resource['targeted actions'][$actname] = array_merge($resource['update'], $act); |
| 510 |
} |
} |
| 511 |
$controllers[$path . '/targeted_action/' . $actname] = &$resource['#actions'][$actname]; |
$controllers[$path . '/targeted_action/' . $actname] = &$resource['actions'][$actname]; |
| 512 |
} |
} |
| 513 |
} |
} |
| 514 |
} |
} |
| 535 |
} |
} |
| 536 |
else { |
else { |
| 537 |
$methods = module_invoke_all('service'); |
$methods = module_invoke_all('service'); |
| 538 |
|
services_strip_hashes($methods); |
| 539 |
|
|
| 540 |
foreach ($methods as $key => $method) { |
foreach ($methods as $key => $method) { |
| 541 |
|
|
| 542 |
if (!isset($methods[$key]['#access callback'])) { |
if (!isset($methods[$key]['access callback'])) { |
| 543 |
$methods[$key]['#access callback'] = 'services_access_menu'; |
$methods[$key]['access callback'] = 'services_access_menu'; |
| 544 |
} |
} |
| 545 |
|
|
| 546 |
if (!isset($methods[$key]['#args'])) { |
if (!isset($methods[$key]['args'])) { |
| 547 |
$methods[$key]['#args'] = array(); |
$methods[$key]['args'] = array(); |
| 548 |
} |
} |
| 549 |
|
|
| 550 |
// set defaults for args |
// set defaults for args |
| 551 |
foreach ($methods[$key]['#args'] as $arg_key => $arg) { |
foreach ($methods[$key]['args'] as $arg_key => $arg) { |
| 552 |
if (is_array($arg)) { |
if (is_array($arg)) { |
| 553 |
if (!isset($arg['#optional'])) { |
if (!isset($arg['optional'])) { |
| 554 |
$methods[$key]['#args'][$arg_key]['#optional'] = FALSE; |
$methods[$key]['args'][$arg_key]['optional'] = FALSE; |
| 555 |
} |
} |
| 556 |
} |
} |
| 557 |
else { |
else { |
| 558 |
$arr_arg = array(); |
$arr_arg = array(); |
| 559 |
$arr_arg['#name'] = t('unnamed'); |
$arr_arg['name'] = t('unnamed'); |
| 560 |
$arr_arg['#type'] = $arg; |
$arr_arg['type'] = $arg; |
| 561 |
$arr_arg['#description'] = t('No description given.'); |
$arr_arg['description'] = t('No description given.'); |
| 562 |
$arr_arg['#optional'] = FALSE; |
$arr_arg['optional'] = FALSE; |
| 563 |
$methods[$key]['#args'][$arg_key] = $arr_arg; |
$methods[$key]['args'][$arg_key] = $arr_arg; |
| 564 |
} |
} |
| 565 |
} |
} |
| 566 |
reset($methods[$key]['#args']); |
reset($methods[$key]['args']); |
| 567 |
} |
} |
| 568 |
|
|
| 569 |
// Allow auth module to alter the methods |
// Allow auth module to alter the methods |
| 604 |
static $method_cache; |
static $method_cache; |
| 605 |
if (!isset($method_cache[$method_name])) { |
if (!isset($method_cache[$method_name])) { |
| 606 |
foreach (services_get_all() as $method) { |
foreach (services_get_all() as $method) { |
| 607 |
if ($method_name == $method['#method']) { |
if ($method_name == $method['method']) { |
| 608 |
$method_cache[$method_name] = $method; |
$method_cache[$method_name] = $method; |
| 609 |
break; |
break; |
| 610 |
} |
} |
| 614 |
} |
} |
| 615 |
|
|
| 616 |
/** |
/** |
| 617 |
|
* Cleanup function to remove unnecessary hashes from service definitions. |
| 618 |
|
*/ |
| 619 |
|
function services_strip_hashes(&$array) { |
| 620 |
|
foreach ($array as $key => $value) { |
| 621 |
|
if (is_array($value)) { |
| 622 |
|
services_strip_hashes($array[$key]); |
| 623 |
|
} |
| 624 |
|
if (strpos($key, '#') === 0) { |
| 625 |
|
$array[substr($key, 1)] = $array[$key]; |
| 626 |
|
unset($array[$key]); |
| 627 |
|
} |
| 628 |
|
} |
| 629 |
|
} |
| 630 |
|
|
| 631 |
|
/** |
| 632 |
* Make any changes we might want to make to node. |
* Make any changes we might want to make to node. |
| 633 |
*/ |
*/ |
| 634 |
function services_node_load($node, $fields = array()) { |
function services_node_load($node, $fields = array()) { |