/** * Invoke a service * * @param string $type The plugin type whose service is to be called * @param string $action The service action to be performed * @param array $args The arguments to be passed to the service invoked * @param array &$output The output variable that will contain the output after invocation * @param array &$svc_msg The output variable that will contain the service messages * @return int The result of the invocation * @link http://wiki.geeklog.net/index.php/Webservices_API * */ function PLG_invokeService($type, $action, $args, &$output, &$svc_msg) { global $_CONF; $retval = PLG_RET_ERROR; if ($type == 'story') { // ensure we can see the service_XXX_story functions require_once $_CONF['path_system'] . 'lib-story.php'; } $output = ''; $svc_msg = ''; // Check if the plugin type and action are valid $function = 'service_' . $action . '_' . $type; if (function_exists($function) && PLG_wsEnabled($type)) { if (!isset($args['gl_svc'])) { $args['gl_svc'] = false; } $retval = $function($args, $output, $svc_msg); } return $retval; }
/** * Handles the GET request */ function WS_get() { global $_CONF, $WS_PLUGIN, $WS_INTROSPECTION, $WS_VERBOSE, $_PLUGINS; if ($WS_VERBOSE) { COM_errorLog("WS: GET request received"); } WS_dissectURI($args); if ($WS_INTROSPECTION) { header('Content-type: application/atomsvc+xml; charset=UTF-8'); $atom_uri = $_CONF['site_url'] . '/webservices/atom/'; /* Determine which plugins have webservices enabled */ $_ws_plugins = array(); /* Handle the story 'plugin' separately */ if (PLG_wsEnabled('story')) { $_ws_plugins[] = 'story'; } if (is_array($_PLUGINS)) { foreach ($_PLUGINS as $pi) { if (PLG_wsEnabled($pi)) { $_ws_plugins[] = $pi; } } } /* It might be simpler to do this part directly :-/ */ $atom_doc = new DOMDocument('1.0', 'utf-8'); $root_elem = $atom_doc->createElementNS(WS_APP_NS, 'app:service'); $atom_doc->appendChild($root_elem); $atom_doc->createAttributeNS(WS_ATOM_NS, 'atom:service'); $atom_doc->createAttributeNS(WS_EXTN_NS, 'gl:service'); $workspace = $atom_doc->createElement('app:workspace'); $root_elem->appendChild($workspace); $title = $atom_doc->createElement('atom:title', $_CONF['site_name']); $workspace->appendChild($title); foreach ($_ws_plugins as $ws_plugin) { $atom_uri_for_plugin = $atom_uri . '?plugin=' . $ws_plugin; $collection = $atom_doc->createElement('app:collection'); $collection->setAttribute('href', $atom_uri_for_plugin); $workspace->appendChild($collection); $title = $atom_doc->createElement('atom:title', $ws_plugin); $collection->appendChild($title); $entry = $atom_doc->createElement('app:accept', 'application/atom+xml;type=entry'); $collection->appendChild($entry); $categories = $atom_doc->createElement('app:categories'); $categories->setAttribute('fixed', 'yes'); $collection->appendChild($categories); $topics = array(); $msg = array(); $ret = PLG_invokeService($ws_plugin, 'getTopicList', null, $topics, $msg); if ($ret == PLG_RET_OK) { foreach ($topics as $t) { $topic = $atom_doc->createElement('atom:category'); $topic->setAttribute('term', htmlentities($t)); $categories->appendChild($topic); } } } WS_write($atom_doc->saveXML()); return; } // @TODO Store array $args // object id has already been stored from the URI /* Indicates that the method is being called by the webservice */ $args['gl_svc'] = true; $ret = PLG_invokeService($WS_PLUGIN, 'get', $args, $out, $svc_msg); if ($ret == PLG_RET_OK) { header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK'); header('Content-type: application/atom+xml; charset=UTF-8'); // Output the actual object/objects here if (!$svc_msg['gl_feed']) { /* This is an entry, not a feed */ $etag = ''; if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { $etag = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"'); } if (!empty($etag) && $out['updated'] == $etag) { header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified'); exit; } else { header('Etag: "' . $out['updated'] . '"'); } $atom_doc = new DOMDocument('1.0', 'utf-8'); $entry_elem = $atom_doc->createElementNS(WS_ATOM_NS, 'atom:entry'); $atom_doc->appendChild($entry_elem); $atom_doc->createAttributeNS(WS_APP_NS, 'app:entry'); $atom_doc->createAttributeNS(WS_EXTN_NS, 'gl:entry'); WS_arrayToEntryXML($out, $svc_msg['output_fields'], $entry_elem, $atom_doc); WS_write($atom_doc->saveXML()); } else { /* Output the feed here */ $atom_doc = new DOMDocument('1.0', 'utf-8'); $feed_elem = $atom_doc->createElementNS(WS_ATOM_NS, 'atom:feed'); $atom_doc->appendChild($feed_elem); $atom_doc->createAttributeNS(WS_APP_NS, 'app:feed'); $atom_doc->createAttributeNS(WS_EXTN_NS, 'gl:feed'); $feed_id = $atom_doc->createElement('atom:id', $_CONF['site_name']); $feed_elem->appendChild($feed_id); $feed_title = $atom_doc->createElement('atom:title', $_CONF['site_name']); $feed_elem->appendChild($feed_title); $feed_updated = $atom_doc->createElement('atom:updated', date('c')); $feed_elem->appendChild($feed_updated); $feed_link = $atom_doc->createElement('atom:link'); $feed_link->setAttribute('rel', 'self'); $feed_link->setAttribute('type', 'application/atom+xml'); $feed_link->setAttribute('href', $_CONF['site_url'] . '/webservices/atom/?plugin=' . htmlentities($WS_PLUGIN)); $feed_elem->appendChild($feed_link); if (!empty($svc_msg['offset'])) { $next_link = $atom_doc->createElement('atom:link'); $next_link->setAttribute('rel', 'next'); $next_link->setAttribute('type', 'application/atom+xml'); $next_link->setAttribute('href', $_CONF['site_url'] . '/webservices/atom/?plugin=' . htmlentities($WS_PLUGIN) . '&offset=' . $svc_msg['offset']); $feed_elem->appendChild($next_link); } foreach ($out as $entry_array) { $entry_elem = $atom_doc->createElement('atom:entry'); WS_arrayToEntryXML($entry_array, $svc_msg['output_fields'], $entry_elem, $atom_doc); $feed_elem->appendChild($entry_elem); } WS_write($atom_doc->saveXML()); } return; } WS_error($ret, $svc_msg['error_desc']); }