Author: xavier
Date: 2010-05-14 17:30:15 +0200 (Fri, 14 May 2010)
New Revision: 29469

Added:
   plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializer.class.php
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerJson.class.php
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerXml.class.php
Removed:
   plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/sfRestInflector.class.php
Modified:
   plugins/sfDoctrineRestGeneratorPlugin/trunk/README
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/indexAction.php
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/parsePayload.php
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/generator.yml
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/view.yml
   
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/template/templates/indexSuccess.php
   plugins/sfDoctrineRestGeneratorPlugin/trunk/package.xml
Log:
[wiki:sfDoctrineRestGeneratorPlugin]: Added a JSON serializer, and fixed a few 
typos in the documentation

Modified: plugins/sfDoctrineRestGeneratorPlugin/trunk/README
===================================================================
--- plugins/sfDoctrineRestGeneratorPlugin/trunk/README  2010-05-14 15:21:14 UTC 
(rev 29468)
+++ plugins/sfDoctrineRestGeneratorPlugin/trunk/README  2010-05-14 15:30:15 UTC 
(rev 29469)
@@ -14,6 +14,7 @@
   * ability to limit the number of results, with/out pagination
   * support for constraints unions (ie.,  
http://api.example.org/city?city_id=12,13,14)
   * abstract and replaceable objects serialization
+  * serialization as XML or JSON feeds
 
 
 ## How to installed
@@ -118,6 +119,7 @@
               default:
         #        fields:                                # list here the fields.
         #          created_at:                  { date_format: 'Y-m-d\TH:i:s', 
tag_name: 'created' }      # for instance
+        #        formats_enabled:               [ xml, json ]    # enabled 
formats
         #        separator:                     ','     # separator used for 
multiple filters
               get:
         #        display:                       []      # list here fields to 
render in the response
@@ -155,9 +157,26 @@
   * `tag_name`: the tag name to use for displaying this field. For instance, 
you might want to associate the title of the post to the key "post_title", and 
not "title".
 
 
+#### formats_enabled
+
+This contains the list of the formats allowed in the communication with the
+API. The default allowed formats are json and XML, XML being the default
+format.
+
+This means that you can call a resource at the following URIs:
+
+  * http://api.example.com/post will return a XML formatted list of the posts,
+  * http://api.example.com/post.xml will return a XML formatted list of the 
posts,
+  * http://api.example.com/post.json will return a JSON formatted list of the 
posts.
+
+Would you want to add a new serialization format, you should add this format
+in the generator.yml, and create a serializer. See examples in the
+`lib/serializer` directory of the plugin.
+
+
 #### separator
 
-The separator to use in url when passing objects primary keys. The genertaed
+The separator to use in url when passing objects primary keys. The generated
 module allows to require several ressources identified by their ids:
 http://api.example.com/post/?id=12,17,19
 
@@ -166,11 +185,13 @@
 
 The `get` option lists several options specific to the "get" operation:
 
+
 #### display
 
-The `display` option contains the list of the fields to output in the XML
-feed. For example with the previously defines "Post" model, you can choose to
-only display the title and the author's id by changing this parameter:
+The `display` option contains the list of the fields to output in the XML or
+JSON feed. For example with the previously defines "Post" model, you can
+choose to only display the title and the author's id by changing this
+parameter:
 
             config:
               get:
@@ -215,9 +236,9 @@
 
 #### global_additional_fields
 
-In some case, you might want to embed some additionnal fields in he XML
-response. For instance, you might want to include the total number of posts,
-an average price, etc.
+In some case, you might want to embed some additionnal fields in the XML or
+JSON response. For instance, you might want to include the total number of
+posts, an average price, etc.
 
 The `global_additional_fields` is helpful in such a situation. It contains an
 array of the fields that you want to add and, for each field, the generator
@@ -349,26 +370,38 @@
 
 ## Serialization
 
-The response to a get request is formatted as a XML feed. The serializer
-generates a valid feed, enclosing the content of a field in CDATA sections if
-necessary.
+The response to a get request is formatted as a XML feed or a JSON array. The
+XML  serializer generates a valid feed, enclosing the content of a field in
+CDATA sections if necessary.
 
+The serialization is done directly in the action, not in the template, in
+order to improve the performance when output escaping is enabled.
+
+
 ## Whishlist
- * a JSON serializer. Currently, the plugin only allows to serialize the 
resultsets as a XML field (see the chapter "Serialization"). Mobile clients, 
which require the most compact possible streams, would take benefit from a JSON 
or even a BSON serialization.
+ * more serializers (BSON for example). Currently, the plugin only allows to 
serialize the resultsets as a XML or JSON feeds (see the chapter 
"Serialization"). Mobile clients, which require the most compact possible 
streams, would take benefit from a JSON or even a BSON serialization.
  * all the possible feedback!
 
+
 ## Contribute to the plugin, ask for help
 
 Please ask for help on how to use the plugin on Symfony's users mailing list.
 You can also send me a mail directly : [email protected].
 
+
 ## License and credits
 
 This plugin has been developed by [Xavier Lacot](http://lacot.org/) and is
 licensed under the MIT license.
 
+
 ## Changelog
 
+### version 0.9 - 2010-05-14
+
+Added a json serializer.
+
+
 ### version 0.8 - 2010-05-09
 
 Initial public release. Features REST module generation with validation and a

Modified: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/indexAction.php
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/indexAction.php
    2010-05-14 15:21:14 UTC (rev 29468)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/indexAction.php
    2010-05-14 15:30:15 UTC (rev 29469)
@@ -7,6 +7,14 @@
   {
     $this->forward404Unless($request->isMethod(sfRequest::GET));
     $params = $request->getParameterHolder()->getAll();
+    $format = $params['sf_format'];
+    $request->setRequestFormat('html');
+
+    if (!in_array($format, <?php 
var_export($this->configuration->getValue('default.formats_enabled', 
array('json', 'xml'))) ?>))
+    {
+      $format = 'xml';
+    }
+
     unset($params['sf_format']);
     unset($params['module']);
     unset($params['action']);
@@ -99,6 +107,8 @@
     }
 <?php endif; ?>
 
-    $this->xml = sfRestInflector::arrayToXml($this->objects, $this->model);
+    $serializer = sfResourceSerializer::getInstance($format);
+    $this->getResponse()->setContentType($serializer->getContentType());
+    $this->output = $serializer->serialize($this->objects, $this->model);
     unset($this->objects);
   }

Modified: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/parsePayload.php
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/parsePayload.php
   2010-05-14 15:21:14 UTC (rev 29468)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/parts/parsePayload.php
   2010-05-14 15:30:15 UTC (rev 29469)
@@ -1,17 +1,31 @@
-  protected function parsePayload($xml, $force = false)
+  protected function parsePayload($payload, $force = false)
   {
     if ($force || !isset($this->_payload_array))
     {
-       $dom = @simplexml_load_string($xml);
+      $format = $this->getRequest()->getParameter('sf_format);
 
-       if (!$dom)
+      if (!in_array($format, <?php 
var_export($this->configuration->getValue('default.formats_enabled', 
array('json', 'xml'))) ?>))
+      {
+        $format = 'xml';
+      }
+
+      if ('xml' == $format)
+      {
+         $payload_array = @simplexml_load_string($payload);
+      }
+      elseif ('json' == $format)
+      {
+         $payload_array = json_decode($payload, true);
+      }
+
+       if (!isset($payload_array) || !$payload_array)
        {
          throw new sfException('Could not load payload, obviously not a valid 
XML!');
        }
 
       $this->_payload_array = array();
 
-      foreach ($dom as $name => $value)
+      foreach ($payload_array as $name => $value)
       {
        $name = sfInflector::underscore($name);
        $this->_payload_array[$name] = trim(rtrim((string)$value));

Modified: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/generator.yml
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/generator.yml
    2010-05-14 15:21:14 UTC (rev 29468)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/generator.yml
    2010-05-14 15:30:15 UTC (rev 29469)
@@ -7,6 +7,7 @@
       default:
 #        fields:                                 # list here the fields.
 #          created_at:                  { date_format: 'Y-m-d\TH:i:s', 
tag_name: 'created' }      # for instance
+#        formats_enabled:               [ xml, json ]    # enabled formats
 #        separator:                     ','     # separator used for multiple 
filters
       get:
 #        display:                       []      # list here fields to render 
in the response

Modified: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/view.yml
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/view.yml
 2010-05-14 15:21:14 UTC (rev 29468)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/skeleton/config/view.yml
 2010-05-14 15:30:15 UTC (rev 29469)
@@ -1,4 +1,2 @@
 all:
-  http_metas:
-    content-type: text/xml
   has_layout:   false
\ No newline at end of file

Modified: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/template/templates/indexSuccess.php
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/template/templates/indexSuccess.php
      2010-05-14 15:21:14 UTC (rev 29468)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/data/generator/sfDoctrineRestGenerator/default/template/templates/indexSuccess.php
      2010-05-14 15:30:15 UTC (rev 29469)
@@ -1 +1 @@
-[?php echo $sf_data->getRaw('xml');
\ No newline at end of file
+[?php echo $sf_data->getRaw('output');
\ No newline at end of file

Added: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializer.class.php
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializer.class.php
                           (rev 0)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializer.class.php
   2010-05-14 15:30:15 UTC (rev 29469)
@@ -0,0 +1,20 @@
+<?php
+
+abstract class sfResourceSerializer
+{
+  abstract public function getContentType();
+
+  public static function getInstance($format = 'xml')
+  {
+    $classname = sprintf('sfResourceSerializer%s', ucfirst($format));
+
+    if (!class_exists($classname))
+    {
+      throw new sfException(sprintf('Could not find seriaizer "%s"', 
$classname));
+    }
+
+    return new $classname;
+  }
+
+  abstract public function serialize($array, $rootNodeName = 'data');
+}
\ No newline at end of file

Added: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerJson.class.php
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerJson.class.php
                               (rev 0)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerJson.class.php
       2010-05-14 15:30:15 UTC (rev 29469)
@@ -0,0 +1,14 @@
+<?php
+
+class sfResourceSerializerJson extends sfResourceSerializer
+{
+  public function getContentType()
+  {
+    return 'application/json';
+  }
+
+  public function serialize($array, $rootNodeName = 'data')
+  {
+    return json_encode($array);
+  }
+}
\ No newline at end of file

Added: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerXml.class.php
===================================================================
--- 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerXml.class.php
                                (rev 0)
+++ 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/serializer/sfResourceSerializerXml.class.php
        2010-05-14 15:30:15 UTC (rev 29469)
@@ -0,0 +1,71 @@
+<?php
+
+class sfResourceSerializerXml extends sfResourceSerializer
+{
+  public function getContentType()
+  {
+    return 'application/xml';
+  }
+
+  public function serialize($array, $rootNodeName = 'data')
+  {
+    return $this->arrayToXml($array, $rootNodeName, 0);
+  }
+
+  public function arrayToXml($array, $rootNodeName = 'data', $level = 0)
+  {
+    $xml = '';
+
+    if (0 == $level)
+    {
+      $xml .= '<?xml version="1.0" 
encoding="utf-8"?><'.ucfirst(sfInflector::camelize($rootNodeName)).'s>';
+    }
+
+    foreach ($array as $key => $value)
+    {
+      $key = ucfirst(sfInflector::camelize($key));
+
+      if (is_numeric($key))
+      {
+        $key = ucfirst(sfInflector::camelize($rootNodeName));
+      }
+
+      if (is_array($value))
+      {
+        $real_key = $key;
+
+        if (!count($value) || isset($value[0]))
+        {
+          $real_key .= 's';
+        }
+
+        $xml .= '<'.$real_key.'>';
+        $xml .= $this->arrayToXml($value, $key, $level + 1);
+        $xml .= '</'.$real_key.'>';
+      }
+      else
+      {
+        $trimed_value = ($value !== false) ? trim($value) : '0';
+
+        if ($trimed_value !== '')
+        {
+          if (htmlspecialchars($trimed_value) != $trimed_value)
+          {
+            $xml .= '<'.$key.'><![CDATA['.$trimed_value.']]></'.$key.'>';
+          }
+          else
+          {
+            $xml .= '<'.$key.'>'.$trimed_value.'</'.$key.'>';
+          }
+        }
+      }
+    }
+
+    if (0 == $level)
+    {
+      $xml .= '</'.ucfirst(sfInflector::camelize($rootNodeName)).'s>';
+    }
+
+    return $xml;
+  }
+}
\ No newline at end of file

Deleted: 
plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/sfRestInflector.class.php
===================================================================
--- plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/sfRestInflector.class.php   
2010-05-14 15:21:14 UTC (rev 29468)
+++ plugins/sfDoctrineRestGeneratorPlugin/trunk/lib/sfRestInflector.class.php   
2010-05-14 15:30:15 UTC (rev 29469)
@@ -1,61 +0,0 @@
-<?php
-
-class sfRestInflector extends sfInflector
-{
-  public static function arrayToXml($array, $rootNodeName = 'data', $level = 0)
-  {
-    $xml = '';
-
-    if (0 == $level)
-    {
-      $xml .= '<?xml version="1.0" 
encoding="utf-8"?><'.ucfirst(sfInflector::camelize($rootNodeName)).'s>';
-    }
-
-    foreach ($array as $key => $value)
-    {
-      $key = ucfirst(sfInflector::camelize($key));
-
-      if (is_numeric($key))
-      {
-        $key = ucfirst(sfInflector::camelize($rootNodeName));
-      }
-
-      if (is_array($value))
-      {
-        $real_key = $key;
-
-        if (!count($value) || isset($value[0]))
-        {
-          $real_key .= 's';
-        }
-
-        $xml .= '<'.$real_key.'>';
-        $xml .= self::arrayToXml($value, $key, $level + 1);
-        $xml .= '</'.$real_key.'>';
-      }
-      else
-      {
-        $trimed_value = ($value !== false) ? trim($value) : '0';
-
-        if ($trimed_value !== '')
-        {
-          if (htmlspecialchars($trimed_value) != $trimed_value)
-          {
-            $xml .= '<'.$key.'><![CDATA['.$trimed_value.']]></'.$key.'>';
-          }
-          else
-          {
-            $xml .= '<'.$key.'>'.$trimed_value.'</'.$key.'>';
-          }
-        }
-      }
-    }
-
-    if (0 == $level)
-    {
-      $xml .= '</'.ucfirst(sfInflector::camelize($rootNodeName)).'s>';
-    }
-
-    return $xml;
-  }
-}
\ No newline at end of file

Modified: plugins/sfDoctrineRestGeneratorPlugin/trunk/package.xml
===================================================================
--- plugins/sfDoctrineRestGeneratorPlugin/trunk/package.xml     2010-05-14 
15:21:14 UTC (rev 29468)
+++ plugins/sfDoctrineRestGeneratorPlugin/trunk/package.xml     2010-05-14 
15:30:15 UTC (rev 29469)
@@ -21,11 +21,11 @@
     <email>[email protected]</email>
     <active>yes</active>
   </lead>
-  <date>2010-05-09</date>
-  <time>10:05:19</time>
+  <date>2010-05-14</date>
+  <time>17:35:12</time>
   <version>
-    <release>0.8.0</release>
-    <api>0.8.0</api>
+    <release>0.9.0</release>
+    <api>0.9.0</api>
   </version>
   <stability>
     <release>beta</release>
@@ -89,7 +89,11 @@
           <file name="sfDoctrineRestGenerator.class.php" role="data"/>
           <file name="sfDoctrineRestGeneratorConfiguration.class.php" 
role="data"/>
         </dir>
-        <file name="sfRestInflector.class.php" role="data"/>
+        <dir name="serializer">
+          <file name="sfResourceSerializer.class.php" role="data"/>
+          <file name="sfResourceSerializerJson.class.php" role="data"/>
+          <file name="sfResourceSerializerXml.class.php" role="data"/>
+        </dir>
         <dir name="task">
           <file name="sfDoctrineRestGenerateModuleTask.class.php" role="data"/>
         </dir>
@@ -119,6 +123,21 @@
   <changelog>
   <release>
    <version>
+    <release>0.9.0</release>
+    <api>0.9.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2010-05-14</date>
+   <license 
uri="http://www.opensource.org/licenses/mit-license.html";>MIT</license>
+   <notes>
+  * added a JSON serializer
+   </notes>
+  </release>
+  <release>
+   <version>
     <release>0.8.0</release>
     <api>0.8.0</api>
    </version>

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to