From: [EMAIL PROTECTED]
Date: July 19, 2008 12:47:41 AM GMT+02:00
To: [EMAIL PROTECTED]
Subject: svn commit: r678068 - in /incubator/shindig/trunk/php/src/
social-api: converters/ dataservice/ http/ samplecontainer/
Reply-To: [email protected]
Author: chabotc
Date: Fri Jul 18 15:47:41 2008
New Revision: 678068
URL: http://svn.apache.org/viewvc?rev=678068&view=rev
Log:
Initial support for the batch proxy request type.
The url is /social/rest/batchProxy and it uses the http multipart
format as described in the RESTful API specification.
It only supports ONE output format for a set of requests (which
is determined by the main url ?format=foo param, and defaults to
json). Input however will support mixing json and atom.
Atom input is still missing (has a debug dump right now) but support
for that will follow quickly.
OAuth and Atom input is still missing, but once their done PHP
Shindig will have full RESTful spec support, we're getting there!
Modified:
incubator/shindig/trunk/php/src/social-api/converters/
OutputAtomConverter.php
incubator/shindig/trunk/php/src/social-api/converters/
OutputConverter.php
incubator/shindig/trunk/php/src/social-api/converters/
OutputJsonConverter.php
incubator/shindig/trunk/php/src/social-api/dataservice/
PeopleHandler.php
incubator/shindig/trunk/php/src/social-api/dataservice/
RestRequestItem.php
incubator/shindig/trunk/php/src/social-api/http/RestServlet.php
incubator/shindig/trunk/php/src/social-api/samplecontainer/
BasicAppDataService.php
incubator/shindig/trunk/php/src/social-api/samplecontainer/
BasicPeopleService.php
Modified: incubator/shindig/trunk/php/src/social-api/converters/
OutputAtomConverter.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/OutputAtomConverter.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/
OutputAtomConverter.php (original)
+++ incubator/shindig/trunk/php/src/social-api/converters/
OutputAtomConverter.php Fri Jul 18 15:47:41 2008
@@ -1,4 +1,5 @@
<?php
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -19,7 +20,7 @@
/**
* Format = atom output converter, for format definition see:
- *
http://www.opensocial.org/Technical-Resources/opensocial-specification----implementation-version-08/restful-api-specification
+ *
http://sites.google.com/a/opensocial.org/opensocial/Technical-Resources/opensocial-spec-v08/restful-api-specification
*/
class OutputAtomConverter extends OutputConverter {
private static $nameSpace = 'http://www.w3.org/2005/Atom';
@@ -40,7 +41,7 @@
$data = $responseItem->getResponse();
$userId = $requestItem->getUser()->getUserId($requestItem-
>getToken());
$guid = 'urn:guid:' . $userId;
- $authorName = $_SERVER['HTTP_HOST'].':'.$userId;
+ $authorName = $_SERVER['HTTP_HOST'] . ':' . $userId;
$updatedAtom = date(DATE_ATOM);
// Check to see if this is a single entry, or a collection, and
construct either an atom
@@ -52,20 +53,18 @@
// The root Feed element
$entry = $this->addNode($doc, 'feed', '', false, self::
$nameSpace);
-
+
// Required Atom fields
$endPos = ($startIndex + $itemsPerPage) > $totalResults ?
$totalResults : ($startIndex + $itemsPerPage);
- $this->addNode($entry, 'title', $requestType.' feed for id '.
$authorName.' ('.$startIndex. ' - '. ($endPos - 1).' of '.
$totalResults.')');
+ $this->addNode($entry, 'title', $requestType . ' feed for id
' . $authorName . ' (' . $startIndex . ' - ' . ($endPos - 1) . ' of
' . $totalResults . ')');
$author = $this->addNode($entry, 'author');
$this->addNode($author, 'uri', $guid);
- $this->addNode($author, 'name', $authorName);
+ $this->addNode($author, 'name', $authorName);
$this->addNode($entry, 'updated', $updatedAtom);
$this->addNode($entry, 'id', $guid);
- $this->addNode($entry, 'link', '', array('rel' => 'self',
'href' => 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']));
-
+ $this->addNode($entry, 'link', '', array('rel' => 'self',
'href' => 'http://' . $_SERVER['HTTP_HOST'] .
$_SERVER['REQUEST_URI']));
// Add osearch & next link to the entry
$this->addPagingFields($entry, $startIndex, $itemsPerPage,
$totalResults);
-
// Add response entries to feed
$responses = $responseItem->getResponse()->getEntry();
foreach ($responses as $response) {
@@ -79,11 +78,10 @@
$this->addNode($author, 'uri', $guid);
$this->addNode($author, 'name', $authorName);
// Special hoisting rules for activities
-
if ($response instanceof Activity) {
$this->addNode($feedEntry, 'category', '', array('term' =>
'status'));
$this->addNode($feedEntry, 'updated', date(DATE_ATOM,
$response->postedTime));
- $this->addNode($feedEntry, 'id',
'urn:guid:'.$response->id);
+ $this->addNode($feedEntry, 'id',
'urn:guid:' . $response->id);
//FIXME should add a link field but don't have URL's available
yet:
// <link rel="self" type="application/atom+xml" href="http://api.example.org/activity/feeds/.../af3778
"/>
$this->addNode($feedEntry, 'title', strip_tags($response-
>title));
@@ -94,43 +92,49 @@
unset($response->title);
unset($response->body);
} else {
- $this->addNode($feedEntry, 'id',
'urn:guid:'.$idField);
- $this->addNode($feedEntry, 'title', $requestType.' feed entry
for id '.$idField);
+ $this->addNode($feedEntry, 'id',
'urn:guid:' . $idField);
+ $this->addNode($feedEntry, 'title', $requestType . ' feed
entry for id ' . $idField);
$this->addNode($feedEntry, 'updated',
$updatedAtom);
}
// recursively add responseItem data to the xml
structure
$this->addData($content, $requestType, $response, self::
$osNameSpace);
}
-
} else {
-
// Single entry = Atom:Entry
$entry = $doc->appendChild($doc->createElementNS(self::
$nameSpace, "entry"));
-
// Atom fields
- $this->addNode($entry, 'title', $requestType.' entry for '.
$authorName);
+ $this->addNode($entry, 'title', $requestType . ' entry for ' .
$authorName);
$author = $this->addNode($entry, 'author');
$this->addNode($author, 'uri', $guid);
$this->addNode($author, 'name', $authorName);
$this->addNode($entry, 'id', $guid);
$this->addNode($entry, 'updated', $updatedAtom);
$content = $this->addNode($entry, 'content', '', array('type' =>
'application/xml'));
-
// addData loops through the responseItem data recursively
creating a matching XML structure
$this->addData($content, $requestType, $data,
self::$osNameSpace);
}
$xml = $doc->saveXML();
- if (self::$includeOsearch && $responseItem->getResponse()
instanceof RestFulCollection) {
+ if ($responseItem->getResponse() instanceof RestFulCollection) {
//FIXME dirty hack until i find a way to add multiple name
spaces using DomXML functions
- $xml = str_replace('<feed xmlns="http://www.w3.org/2005/
Atom">', '<feed xmlns="http://www.w3.org/2005/Atom" xmlos:osearch="http://a9.com/-/spec/opensearch/1.1
">' ,$xml);
+ $xml = str_replace('<feed xmlns="http://www.w3.org/2005/
Atom">', '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:osearch="http://a9.com/-/spec/opensearch/1.1
">', $xml);
}
echo $xml;
}
function outputBatch(Array $responses, SecurityToken $token)
{
- //TODO once we support spec compliance batching, this needs to
be added too
+ $this->boundryHeaders();
+ foreach ($responses as $response) {
+ $request = $response['request'];
+ $response = $response['response'];
+ // output buffering supports multiple levels of it.. it's a
nice feature to abuse :)
+ ob_start();
+ $this->outputResponse($response, $request);
+ $part = ob_get_contents();
+ ob_end_clean();
+ $this->outputPart($part, $response->getError());
+ }
}
/**
@@ -174,11 +178,9 @@
*/
private function addPagingFields($entry, $startIndex,
$itemsPerPage, $totalResults)
{
- if (self::$includeOsearch) {
- $this->addNode($entry, 'osearch:totalResults',
$totalResults);
- $this->addNode($entry, 'osearch:startIndex', $startIndex ?
$startIndex : '0');
- $this->addNode($entry, 'osearch:itemsPerPage',
$itemsPerPage);
- }
+ $this->addNode($entry, 'osearch:totalResults', $totalResults);
+ $this->addNode($entry, 'osearch:startIndex', $startIndex ?
$startIndex : '0');
+ $this->addNode($entry, 'osearch:itemsPerPage', $itemsPerPage);
// Create a 'next' link based on our current url if this is a
pageable collection & there is more to display
if (($startIndex + $itemsPerPage) < $totalResults) {
$nextStartIndex = ($startIndex + $itemsPerPage) - 1;
@@ -255,6 +257,9 @@
}
$this->addData($newElement, $key, $val);
} else {
+ if (is_numeric($key)) {
+ $key = is_object($val) ?
get_class($val) : $key = $name;
+ }
$elm = $newElement->appendChild($this->doc-
>createElement($key));
$elm->appendChild($this->doc->createTextNode($val));
}
Modified: incubator/shindig/trunk/php/src/social-api/converters/
OutputConverter.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/OutputConverter.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/
OutputConverter.php (original)
+++ incubator/shindig/trunk/php/src/social-api/converters/
OutputConverter.php Fri Jul 18 15:47:41 2008
@@ -22,6 +22,50 @@
*
*/
abstract class OutputConverter {
+ private $boundry;
+
abstract function outputResponse(ResponseItem $responseItem,
RestRequestItem $requestItem);
abstract function outputBatch(Array $responses, SecurityToken
$token);
+
+ /**
+ * Output the multipart/mixed headers and returns the boundry
token used
+ *
+ */
+ public function boundryHeaders()
+ {
+ $this->boundry = '--batch-'.md5(rand(0,32000));
+ header("HTTP/1.1 200 OK", true);
+ header("Content-Type: multipart/mixed; boundary=$this->boundry",
true);
+ }
+
+ public function outputPart($part, $code)
+ {
+ $boundryHeader = "{$this->boundry}\n".
+ "Content-Type: application/http;version=1.1\n".
+ "Content-Transfer-Encoding: binary\n\n";
+ echo $boundryHeader;
+ switch ($code) {
+ case BAD_REQUEST:
+ $code = '400 Bad Request';
+ break;
+ case UNAUTHORIZED:
+ $code = '401 Unauthorized';
+ break;
+ case FORBIDDEN:
+ $code = '403 Forbidden';
+ break;
+ case FORBIDDEN:
+ $code = '404 Not Found';
+ break;
+ case NOT_IMPLEMENTED:
+ $code = '501 Not Implemented';
+ break;
+ case INTERNAL_ERROR:
+ default:
+ $code = '200 OK';
+ break;
+ }
+ echo "$code\n\n";
+ echo $part."\n";
+ }
}
Modified: incubator/shindig/trunk/php/src/social-api/converters/
OutputJsonConverter.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/OutputJsonConverter.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/
OutputJsonConverter.php (original)
+++ incubator/shindig/trunk/php/src/social-api/converters/
OutputJsonConverter.php Fri Jul 18 15:47:41 2008
@@ -30,6 +30,17 @@
function outputBatch(Array $responses, SecurityToken $token)
{
+ $this->boundryHeaders();
+ foreach ($responses as $response) {
+ $request = $response['request'];
+ $response = $response['response'];
+ $part = json_encode($response);
+ $this->outputPart($part, $response->getError());
+ }
+ }
+
+ function outputJsonBatch(Array $responses, SecurityToken $token)
+ {
echo json_encode(array("responses" => $responses, "error" =>
false));
}
}
Modified: incubator/shindig/trunk/php/src/social-api/dataservice/
PeopleHandler.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/dataservice/PeopleHandler.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/dataservice/
PeopleHandler.php (original)
+++ incubator/shindig/trunk/php/src/social-api/dataservice/
PeopleHandler.php Fri Jul 18 15:47:41 2008
@@ -20,7 +20,9 @@
class PeopleHandler extends DataRequestHandler {
private $service;
private static $PEOPLE_PATH = "/people/{userId}/{groupId}/
{personId}";
- protected static $DEFAULT_PERSON_FIELDS = array("id", "name",
"thumbnailUrl");
+ //FIXME change this back to array("id", "name", "thumbnailUrl")
once the dust settles
+ // on the spec discussion related to this
+ protected static $DEFAULT_PERSON_FIELDS = array('all' => 'all');
public function __construct()
{
Modified: incubator/shindig/trunk/php/src/social-api/dataservice/
RestRequestItem.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/dataservice/RestRequestItem.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/dataservice/
RestRequestItem.php (original)
+++ incubator/shindig/trunk/php/src/social-api/dataservice/
RestRequestItem.php Fri Jul 18 15:47:41 2008
@@ -45,12 +45,12 @@
public function createRequestItemWithRequest($request, $token)
{
- $this->url = $request->url;
- $this->parameters = $this->createParameterMap($request->url);
+ $this->url = $request['url'];
+ $this->parameters = $this->createParameterMap($request['url']);
$this->token = $token;
- $this->method = $request->method;
- if (isset($request->postData)) {
- $this->postData = $request->postData;
+ $this->method = $request['method'];
+ if (isset($request['postData'])) {
+ $this->postData = $request['postData'];
}
}
Modified: incubator/shindig/trunk/php/src/social-api/http/
RestServlet.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/http/RestServlet.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/http/RestServlet.php
(original)
+++ incubator/shindig/trunk/php/src/social-api/http/RestServlet.php
Fri Jul 18 15:47:41 2008
@@ -51,8 +51,6 @@
require 'src/social-api/converters/OutputAtomConverter.php';
require 'src/social-api/converters/OutputJsonConverter.php';
-//FIXME Delete should respond with a 204 No Content to indicate
success
-
class RestException extends Exception {}
/*
@@ -64,42 +62,80 @@
define('FORBIDDEN', "forbidden");
define('BAD_REQUEST', "badRequest");
define('INTERNAL_ERROR', "internalError");
+//FIXME Delete should respond with a 204 No Content to indicate
success
class RestServlet extends HttpServlet {
+ // The json Batch Route is used by the gadgets
private static $JSON_BATCH_ROUTE = "jsonBatch";
+ // The Batch Proxy route is used the one defined in the RESTful
API specification
+ private static $BATCH_PROXY_ROUTE = "batchProxy";
+
+ public function doGet()
+ {
+ $this->doPost('GET');
+ }
+ public function doPut()
+ {
+ $this->doPost('PUT');
+ }
+
+ public function doDelete()
+ {
+ $this->doPost('DELETE');
+ }
+
public function doPost($method = 'POST')
{
- $this->setNoCache(true);
- // if oauth, create a token from it's values instead of one
based on $_get['st']/$_post['st']
- // NOTE : if no token is provided an anonymous one is created
(owner = viewer = appId = modId = 0)
- // keep this in mind when creating your data services..
- $token = $this->getSecurityToken();
- $outputFormat = $this->getOutputFormat();
- switch ($outputFormat) {
- case 'json':
- $this->setContentType('application/json');
- $outputConverter = new OutputJsonConverter();
- break;
- case 'atom':
- $this->setContentType('application/atom+xml');
- $outputConverter = new OutputAtomConverter();
- break;
- default:
- $this->outputError(new ResponseItem(NOT_IMPLEMENTED, "Invalid
output format"));
- break;
- }
- if ($this->isBatchUrl()) {
- $responses = $this->handleBatchRequest($token);
- $outputConverter->outputBatch($responses, $token);
- } else {
- $response = $this->handleSingleRequest($token, $method);
- $outputConverter->outputResponse($response['response'],
$response['request']);
+ try {
+ $this->setNoCache(true);
+ // if oauth, create a token from it's values instead of one
based on $_get['st']/$_post['st']
+ // NOTE : if no token is provided an anonymous one is created
(owner = viewer = appId = modId = 0)
+ // keep this in mind when creating your data services..
+ $token = $this->getSecurityToken();
+ $outputFormat = $this->getOutputFormat();
+ switch ($outputFormat) {
+ case 'json':
+
$this->setContentType('application/json');
+ $outputConverter = new
OutputJsonConverter();
+ break;
+ case 'atom':
+
$this->setContentType('application/atom+xml');
+ $outputConverter = new
OutputAtomConverter();
+ break;
+ default:
+ $this->outputError(new ResponseItem(NOT_IMPLEMENTED, "Invalid
output format"));
+ break;
+ }
+ if ($this->isJsonBatchUrl()) {
+ // custom json batch format used by the gadgets
+ $responses =
$this->handleJsonBatchRequest($token);
+ $outputConverter->outputJsonBatch($responses,
$token);
+ } elseif ($this->isBatchProxyUrl()) {
+ // spec compliant batch proxy
+ $this->noHeaders = true;
+ $responses =
$this->handleBatchProxyRequest($token);
+ $outputConverter->outputBatch($responses,
$token);
+ } else {
+ // single rest request
+ $response = $this->handleRequest($token,
$method);
+ $outputConverter->outputResponse($response['response'],
$response['request']);
+ }
+ } catch (Exception $e) {
+ header("HTTP/1.0 500 Internal Server Error");
+ echo "<html><body><h1>500 Internal Server Error</h1>";
+ if (Config::get('debug')) {
+ echo "Message: ".$e->getMessage()."<br />\n";
+ echo "<pre>\n";
+ print_r(debug_backtrace());
+ echo "\n</pre>";
+ }
+ echo "</body></html>";
}
}
- private function handleSingleRequest($token, $method)
+ private function handleRequest($token, $method)
{
$params = $this->getListParams();
$requestItem = new RestRequestItem();
@@ -109,14 +145,115 @@
$responseItem = $this->getResponseItem($requestItem);
return array('request' => $requestItem, 'response' =>
$responseItem);
}
-
- private function getRouteFromParameter($pathInfo)
+
+ private function handleJsonBatchRequest($token)
{
- $pathInfo = substr($pathInfo, 1);
- $indexOfNextPathSeparator = strpos($pathInfo, "/");
- return $indexOfNextPathSeparator != - 1 ? substr($pathInfo, 0,
$indexOfNextPathSeparator) : $pathInfo;
+ // we support both a raw http post (without application/x-www-
form-urlencoded headers) like java does
+ // and a more php / curl safe version of a form post with
'request' as the post field that holds the request json data
+ if (isset($GLOBALS['HTTP_RAW_POST_DATA']) ||
isset($_POST['request'])) {
+ $requests = $this->getRequestParams();
+ $responses = array();
+ foreach ($requests as $key => $value) {
+ $requestItem = new RestRequestItem();
+
$requestItem->createRequestItemWithRequest($value, $token);
+ $responses[$key] =
$this->getResponseItem($requestItem);
+ }
+ return $responses;
+ } else {
+ throw new Exception("No post data set");
+ }
+ }
+
+ private function handleBatchProxyRequest($token)
+ {
+ // Is this is a multipath/mixed post? Check content type:
+ if (isset($GLOBALS['HTTP_RAW_POST_DATA']) &&
strpos($_SERVER['CONTENT_TYPE'], 'multipart/mixed') !== false &&
strpos($_SERVER['CONTENT_TYPE'],'boundary=') !== false) {
+ // Ok looks swell, see what our boundry is..
+ $boundry = substr($_SERVER['CONTENT_TYPE'],
strpos($_SERVER['CONTENT_TYPE'],'boundary=') + strlen('boundary='));
+ // Split up requests per boundry
+ $requests = explode($boundry,
$GLOBALS['HTTP_RAW_POST_DATA']);
+ $responses = array();
+ foreach ($requests as $request) {
+ $request = trim($request);
+ if (!empty($request)) {
+ // extractBatchRequest() does the magic parsing of the raw
post data to a meaninful request array
+ $request =
$this->extractBatchRequest($request);
+ $requestItem = new RestRequestItem();
+
$requestItem->createRequestItemWithRequest($request, $token);
+ $responses[] = array('request' => $requestItem, 'response' =>
$this->getResponseItem($requestItem));
+ }
+ }
+ } else {
+ $this->outputError(new ResponseItem(BAD_REQUEST, "Invalid
multipart/mixed request"));
+ }
+ return $responses;
}
+ private function extractBatchRequest($request)
+ {
+ /* Multipart request is formatted like:
+ * -batch-a73hdj3dy3mm347ddjjdf
+ * Content-Type: application/http;version=1.1
+ * Content-Transfer-Encoding: binary
+ *
+ * GET /people/@me/@friends?startPage=5&count=10&format=json
+ * Host: api.example.org
+ * If-None-Match: "837dyfkdi39df"
+ *
+ * but we only want to have the last bit (the actual request),
this filters that down first
+ */
+ $emptyFound = false;
+ $requestLines = explode("\n", $request);
+ $request = '';
+ foreach ($requestLines as $line) {
+ if ($emptyFound) {
+ $request .= $line."\n";
+ } elseif (empty($line)) {
+ $emptyFound = true;
+ }
+ }
+ // Now that we have the basic request in $request, split that up
again & parse it into a meaningful representation
+ $firstFound = $emptyFound = false;
+ $requestLines = explode("\n", $request);
+ $request = array();
+ $request['headers'] = array();
+ $request['postData'] = '';
+ foreach ($requestLines as $line) {
+ if (!$firstFound) {
+ $firstFound = true;
+ $parts = explode(' ', trim($line));
+ if (count($parts) != 2) {
+ throw new Exception("Mallshaped request uri in multipart
block");
+ }
+ $request['method'] =
strtoupper(trim($parts[0]));
+ // cut it down to an actual meaningful url without the prefix/
social/rest part right away
+ $request['url'] = substr(trim($parts[1]),
strlen(Config::get('web_prefix') . '/social/rest'));
+ } elseif (!$emptyFound && !empty($line)) {
+ // convert the key to the PHP 'CONTENT_TYPE' style naming
convention.. it's ugly but consitent
+ $key = str_replace('-', '_', strtoupper(trim(substr($line, 0,
strpos($line, ':')))));
+ $val = trim(substr($line, strpos($line, ':') +
1));
+ $request['headers'][$key] = $val;
+ } elseif (!$emptyFound && empty($line)) {
+ $emptyFound = true;
+ } else {
+ if (get_magic_quotes_gpc()) {
+ $line = stripslashes($line);
+ }
+ $request['postData'] .= $line."\n";
+ }
+ }
+ if (empty($request['postData'])) {
+ // don't trip the requestItem into thinking there is postData
when there's not
+ unset($request['postData']);
+ } else {
+ // if there was a post data blob present, decode it into an
array, the format is based on the
+ // content type header, which is either
application/json or
+ $format = isset($request['headers']['CONTENT_TYPE']) &&
strtolower($request['headers']['CONTENT_TYPE']) == 'application/atom
+xml' ? 'atom' : 'json';
+ $request['postData'] = $this-
>decodeRequests($request['postData'], $format);
+ }
+ return $request;
+ }
+
private function getResponseItem(RestRequestItem $requestItem)
{
$path = $this->getRouteFromParameter($requestItem->getUrl());
@@ -140,12 +277,26 @@
$class = new $class(null);
$response = $class->handleMethod($requestItem);
}
- if ($response->getError() != null && !$this->isBatchUrl()) {
+ if ($response->getError() != null && !$this->isJsonBatchUrl()
&& !$this->isBatchProxyUrl()) {
// Can't use http error codes in batch mode, instead we return
the error code in the response item
$this->outputError($response);
}
return $response;
}
+
+ private function decodeRequests($requestParam, $format = 'json')
+ {
+ // temp hack until i know what the intended way to detect format
is
+ if ($format == 'json') {
+ return json_decode($requestParam, true);
+ } elseif ($format == 'atom') {
+ $xml = simplexml_load_string($requestParam);
+ print_r($xml);
+ return $xml;
+ } else {
+ throw Exception("Invalid or unsupported input format");
+ }
+ }
private function getRequestParams()
{
@@ -154,44 +305,14 @@
if (get_magic_quotes_gpc()) {
$requestParam = stripslashes($requestParam);
}
- $requests = json_decode($requestParam);
- if ($requests == (isset($GLOBALS['HTTP_RAW_POST_DATA']) ?
$GLOBALS['HTTP_RAW_POST_DATA'] : $post)) {
- return new ResponseItem(BAD_REQUEST, "Malformed json
string");
- }
- return $requests;
- }
-
- private function handleBatchRequest($token)
- {
- // we support both a raw http post (without application/x-www-
form-urlencoded headers) like java does
- // and a more php / curl safe version of a form post with
'request' as the post field that holds the request json data
- if (isset($GLOBALS['HTTP_RAW_POST_DATA']) ||
isset($_POST['request'])) {
- $requests = $this->getRequestParams();
- $responses = array();
- foreach ($requests as $key => $value) {
- $requestItem = new RestRequestItem();
-
$requestItem->createRequestItemWithRequest($value, $token);
- $responses[$key] =
$this->getResponseItem($requestItem);
- }
- return $responses;
- } else {
- throw new Exception("No post data set");
- }
- }
-
- public function doGet()
- {
- $this->doPost('GET');
- }
-
- public function doPut()
- {
- $this->doPost('PUT');
+ return $this->decodeRequests($requestParam);
}
- public function doDelete()
+ private function getRouteFromParameter($pathInfo)
{
- $this->doPost('DELETE');
+ $pathInfo = substr($pathInfo, 1);
+ $indexOfNextPathSeparator = strpos($pathInfo, "/");
+ return $indexOfNextPathSeparator != - 1 ? substr($pathInfo, 0,
$indexOfNextPathSeparator) : $pathInfo;
}
private function outputError(ResponseItem $response)
@@ -217,7 +338,6 @@
default:
$code = '500 Internal Server Error';
break;
-
}
header("HTTP/1.0 $code", true);
echo "$code - $errorMessage";
@@ -265,8 +385,13 @@
return substr($_SERVER["REQUEST_URI"],
strlen(Config::get('web_prefix') . '/social/rest'));
}
- public function isBatchUrl()
+ public function isJsonBatchUrl()
{
return strrpos($_SERVER["REQUEST_URI"], RestServlet::
$JSON_BATCH_ROUTE) > 0;
}
+
+ public function isBatchProxyUrl()
+ {
+ return strrpos($_SERVER["REQUEST_URI"], RestServlet::
$BATCH_PROXY_ROUTE) > 0;
+ }
}
Modified: incubator/shindig/trunk/php/src/social-api/
samplecontainer/BasicAppDataService.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicAppDataService.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/samplecontainer/
BasicAppDataService.php (original)
+++ incubator/shindig/trunk/php/src/social-api/samplecontainer/
BasicAppDataService.php Fri Jul 18 15:47:41 2008
@@ -85,7 +85,7 @@
switch($groupId->getType()) {
case 'self':
foreach ($fields as $key) {
- $value = isset($values->$key) ? $values->$key :
(@isset($values[$key]) ? @$values[$key] : null);
+ $value = isset($values[$key]) ?
@$values[$key] : null;
XmlStateFileFetcher::get()->setAppData($userId-
>getUserId($token), $key, $value);
}
break;
Modified: incubator/shindig/trunk/php/src/social-api/
samplecontainer/BasicPeopleService.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicPeopleService.php?rev=678068&r1=678067&r2=678068&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- incubator/shindig/trunk/php/src/social-api/samplecontainer/
BasicPeopleService.php (original)
+++ incubator/shindig/trunk/php/src/social-api/samplecontainer/
BasicPeopleService.php Fri Jul 18 15:47:41 2008
@@ -76,7 +76,7 @@
if ($id == $token->getOwnerId()) {
$person->setIsOwner(true);
}
- if (is_array($profileDetails) &&
count($profileDetails)) {
+ if (is_array($profileDetails) && count($profileDetails) && !
in_array('all', $profileDetails)) {
$newPerson = array();
$newPerson['isOwner'] =
$person->isOwner;
$newPerson['isViewer'] =
$person->isViewer;