Version: current

      1 <?php
      2 /**
      3  * @package sapphire
      4  * @subpackage formatters
      5  */
      6 class JSONDataFormatter extends DataFormatter {
      7     /**
      8      * @todo pass this from the API to the data formatter somehow
      9      */
     10     static $api_base = "api/v1/";
     11
     12     protected $outputContentType = 'application/json';
     13
     14     public function supportedExtensions() {
     15         return array(
     16             'json',
     17             'js'
     18         );
     19     }
     20
     21     public function supportedMimeTypes() {
     22         return array(
     23             'application/json',
     24             'text/x-json'
     25         );
     26     }
     27
     28     /**
     29      * Generate an XML representation of the given {@link DataObject}.
     30      *
     31      * @param DataObject $obj
     32      * @param $includeHeader Include <?xml ...?> header (Default: true)
     33      * @return String XML
     34      */
     35     public function convertDataObject(DataObjectInterface $obj, $fields = null, $relations = null) {
     36         $className = $obj->class;
     37         $id = $obj->ID;
     38
     39         $json = "{\n  \"className\" : \"$className\",\n";
     40         foreach($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
     41             // Field filtering
     42             if($fields && !in_array($fieldName, $fields)) continue;
     43
     44             $fieldValue = $obj->$fieldName;
     45             if(is_object($fieldValue) && is_subclass_of($fieldValue, 'Object') && $fieldValue->hasMethod('toJSON')) {
     46                 $jsonParts[] = "\"$fieldName\" : " . $fieldValue->toJSON();
     47             } else {
     48                 $jsonParts[] = "\"$fieldName\" : " . Convert::raw2json($fieldValue);
     49             }
     50         }
     51
     52         if($this->relationDepth > 0) {
     53             foreach($obj->has_one() as $relName => $relClass) {
     54                 if(!singleton($relClass)->stat('api_access')) continue;
     55
     56                 // Field filtering
     57                 if($fields && !in_array($relName, $fields)) continue;
     58                 if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
     59
     60                 $fieldName = $relName . 'ID';
     61                 if($obj->$fieldName) {
     62                     $href = Director::absoluteURL(self::$api_base . "$relClass/" . $obj->$fieldName);
     63                 } else {
     64                     $href = Director::absoluteURL(self::$api_base . "$className/$id/$relName");
     65                 }
     66                 $jsonParts[] = "$relName : { \"className\" : \"$relClass\", \"href\" : \"$href.json\", \"id\" : \"{$obj->$fieldName}\" }";
     67             }
     68
     69             foreach($obj->has_many() as $relName => $relClass) {
     70                 if(!singleton($relClass)->stat('api_access')) continue;
     71
     72                 // Field filtering
     73                 if($fields && !in_array($relName, $fields)) continue;
     74                 if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
     75
     76                 $jsonInnerParts = array();
     77                 $items = $obj->$relName();
     78                 foreach($items as $item) {
     79                     //$href = Director::absoluteURL(self::$api_base . "$className/$id/$relName/$item->ID");
     80                     $href = Director::absoluteURL(self::$api_base . "$relClass/$item->ID");
     81                     $jsonInnerParts[] = "{ \"className\" : \"$relClass\", \"href\" : \"$href.json\", \"id\" : \"{$obj->$fieldName}\" }";
     82                 }
     83                 $jsonParts[] = "$relName : [\n    " . implode(",\n    ", $jsonInnerParts) . "  \n  ]";
     84             }
     85
     86             foreach($obj->many_many() as $relName => $relClass) {
     87                 if(!singleton($relClass)->stat('api_access')) continue;
     88
     89                 // Field filtering
     90                 if($fields && !in_array($relName, $fields)) continue;
     91                 if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
     92
     93                 $jsonInnerParts = array();
     94                 $items = $obj->$relName();
     95                 foreach($items as $item) {
     96                     //$href = Director::absoluteURL(self::$api_base . "$className/$id/$relName/$item->ID");
     97                     $href = Director::absoluteURL(self::$api_base . "$relClass/$item->ID");
     98                     $jsonInnerParts[] = "    { \"className\" : \"$relClass\", \"href\" : \"$href.json\", \"id\" : \"{$obj->$fieldName}\" }";
     99                 }
    100                 $jsonParts[] = "$relName : [\n    " . implode(",\n    ", $jsonInnerParts) . "\n  ]";
    101             }
    102         }
    103
    104         return "{\n  " . implode(",\n  ", $jsonParts) . "\n}";  }
    105
    106     /**
    107      * Generate an XML representation of the given {@link DataObjectSet}.
    108      *
    109      * @param DataObjectSet $set
    110      * @return String XML
    111      */
    112     public function convertDataObjectSet(DataObjectSet $set, $fields = null) {
    113         $jsonParts = array();
    114         foreach($set as $item) {
    115             if($item->canView()) $jsonParts[] = $this->convertDataObject($item, $fields);
    116         }
    117         $json = "{\n";
    118         $json .= '"totalSize": ';
    119         $json .= (is_numeric($this->totalSize)) ? $this->totalSize : 'null';
    120         $json .= ",\n";
    121         $json .= "\"items\": [\n" . implode(",\n", $jsonParts) . "\n]\n";
    122         $json .= "}\n";
    123
    124         return $json;
    125     }
    126
    127     public function convertStringToArray($strData) {
    128         return Convert::json2array($strData);
    129     }
    130
    131 }

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -