Author: bhofmann
Date: Wed Nov  3 09:28:22 2010
New Revision: 1030372

URL: http://svn.apache.org/viewvc?rev=1030372&view=rev
Log:
SHINDIG-1459: added JSONP support for PHP Shindig REST and RPC API

Modified:
    shindig/trunk/php/src/social/converters/OutputJsonConverter.php
    shindig/trunk/php/src/social/servlet/JsonRpcServlet.php
    shindig/trunk/php/test/social/OutputJsonConverterTest.php

Modified: shindig/trunk/php/src/social/converters/OutputJsonConverter.php
URL: 
http://svn.apache.org/viewvc/shindig/trunk/php/src/social/converters/OutputJsonConverter.php?rev=1030372&r1=1030371&r2=1030372&view=diff
==============================================================================
--- shindig/trunk/php/src/social/converters/OutputJsonConverter.php (original)
+++ shindig/trunk/php/src/social/converters/OutputJsonConverter.php Wed Nov  3 
09:28:22 2010
@@ -32,11 +32,7 @@ class OutputJsonConverter extends Output
     }
     // several service calls return a null value
     if (! is_null($response)) {
-      if (Config::get('debug')) {
-        echo self::json_format(json_encode($response)); // TODO: add a query 
option to pretty-print json output
-      } else {
-        echo json_encode($response);
-      }
+        $this->encodeAndSendResponse($response);
     }
   }
 
@@ -51,7 +47,25 @@ class OutputJsonConverter extends Output
   }
 
   function outputJsonBatch(Array $responses, SecurityToken $token) {
-    echo json_encode(array("responses" => $responses, "error" => false));
+    $this->encodeAndSendResponse(array("responses" => $responses, "error" => 
false));
+  }
+
+  /**
+   * encodes data to json, adds jsonp callback if requested and sends response
+   * to client
+   *
+   * @param array $data
+   */
+  private function encodeAndSendResponse($data) {
+    if (isset($_GET['callback']) && preg_match('/^[a-zA-Z0-9\_\.]*$/', 
$_GET['callback'])) {
+        echo $_GET['callback'] . '(' . json_encode($data) . ')';
+        return;
+    }
+    if (Config::get('debug')) {
+        echo self::json_format(json_encode($data)); // TODO: add a query 
option to pretty-print json output
+    } else {
+        echo json_encode($data);
+    }
   }
 
   /**

Modified: shindig/trunk/php/src/social/servlet/JsonRpcServlet.php
URL: 
http://svn.apache.org/viewvc/shindig/trunk/php/src/social/servlet/JsonRpcServlet.php?rev=1030372&r1=1030371&r2=1030372&view=diff
==============================================================================
--- shindig/trunk/php/src/social/servlet/JsonRpcServlet.php (original)
+++ shindig/trunk/php/src/social/servlet/JsonRpcServlet.php Wed Nov  3 09:28:22 
2010
@@ -86,7 +86,7 @@ class JsonRpcServlet extends ApiServlet 
       $responseItem = $this->getJSONResponse($key, 
$this->getResponseItem($responses[$i]));
       $result[] = $responseItem;
     }
-    echo json_encode($result);
+    $this->encodeAndSendResponse($result);
   }
 
   public function dispatch($request, $token) {
@@ -99,7 +99,7 @@ class JsonRpcServlet extends ApiServlet 
     // TODO: should use shared deadline across each request
     $response = $this->getResponseItem($this->handleRequestItem($requestItem));
     $result = $this->getJSONResponse($key, $response);
-    echo json_encode($result);
+    $this->encodeAndSendResponse($result);
   }
 
   private function getJSONResponse($key, ResponseItem $responseItem) {
@@ -136,9 +136,25 @@ class JsonRpcServlet extends ApiServlet 
     return $error;
   }
 
+  /**
+   * encodes data to json, adds jsonp callback if requested and sends response
+   * to client
+   * 
+   * @param array $data
+   */
+  private function encodeAndSendResponse($data) {
+    // TODO: Refactor this class to use the OutputJsonConverter, so that we do 
not have to duplicate
+    // encoding and JSONP handling here
+    if (isset($_GET['callback']) && preg_match('/^[a-zA-Z0-9\_\.]*$/', 
$_GET['callback'])) {
+        echo $_GET['callback'] . '(' . json_encode($data) . ')';
+        return;
+    }
+    echo json_encode($data);
+  }
+
   public function sendError(ResponseItem $responseItem) {
     $error = $this->getErrorJson($responseItem);
-    echo json_encode($error);
+    $this->encodeAndSendResponse($error);
   }
 
   private function sendBadRequest($t, $response) {

Modified: shindig/trunk/php/test/social/OutputJsonConverterTest.php
URL: 
http://svn.apache.org/viewvc/shindig/trunk/php/test/social/OutputJsonConverterTest.php?rev=1030372&r1=1030371&r2=1030372&view=diff
==============================================================================
--- shindig/trunk/php/test/social/OutputJsonConverterTest.php (original)
+++ shindig/trunk/php/test/social/OutputJsonConverterTest.php Wed Nov  3 
09:28:22 2010
@@ -74,5 +74,44 @@ class OutputJsonConverterTest extends PH
     $this->assertEquals($expectedJson, $outputJson);
   }
 
+  public function testOutputJsonPResponse() {
+    $_GET['callback'] = 'cb';
+    $outputConverter = new OutputJsonConverter();
+    $servletRequest = array('url' => '/people/1/@self');
+    $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 
'domain', 'appUrl', '1', 'default');
+    $requestItem = RestRequestItem::createWithRequest($servletRequest, $token, 
'convertJson', $outputConverter);
+    $requestItem->applyUrlTemplate("/people/{userId}/{groupId}/{personId}");
+    $response = array(
+        'entry' => array('isOwner' => false, 'isViewer' => false, 
'displayName' => '1 1',
+            'id' => '1'));
+    $responseItem = new ResponseItem(null, null, $response);
+    ob_start();
+    $outputConverter->outputResponse($responseItem, $requestItem);
+    $output = ob_get_clean();
+    $expected = 
'cb({"entry":{"isOwner":false,"isViewer":false,"displayName":"1 1","id":"1"}})';
+    unset($_GET['callback']);
+    $this->assertEquals($expected, $output);
+  }
+
+  public function testOutputJsonPResponseWithInvalidCallback() {
+    $_GET['callback'] = 'alert(1);cb';
+    $outputConverter = new OutputJsonConverter();
+    $servletRequest = array('url' => '/people/1/@self');
+    $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 
'domain', 'appUrl', '1', 'default');
+    $requestItem = RestRequestItem::createWithRequest($servletRequest, $token, 
'convertJson', $outputConverter);
+    $requestItem->applyUrlTemplate("/people/{userId}/{groupId}/{personId}");
+    $response = array(
+        'entry' => array('isOwner' => false, 'isViewer' => false, 
'displayName' => '1 1',
+            'id' => '1'));
+    $responseItem = new ResponseItem(null, null, $response);
+    ob_start();
+    $outputConverter->outputResponse($responseItem, $requestItem);
+    $output = ob_get_clean();
+    $expected = '{"entry":{"isOwner":false,"isViewer":false,"displayName":"1 
1","id":"1"}}';
+    unset($_GET['callback']);
+    $outputJson = json_decode($output);
+    $expectedJson = json_decode($expected);
+    $this->assertEquals($expectedJson, $outputJson);
+  }
 }
 


Reply via email to