Version: current

      1 <?php
      2 /**
      3  * @package sapphire
      4  * @subpackage formatters
      5  */
      6 class XMLDataFormatter 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 = 'text/xml';
     13
     14     public function supportedExtensions() {
     15         return array(
     16             'xml'
     17         );
     18     }
     19
     20     public function supportedMimeTypes() {
     21         return array(
     22             'text/xml',
     23             'application/xml',
     24         );
     25     }
     26
     27     /**
     28      * Generate an XML representation of the given {@link DataObject}.
     29      *
     30      * @param DataObject $obj
     31      * @param $includeHeader Include <?xml ...?> header (Default: true)
     32      * @return String XML
     33      */
     34     public function convertDataObject(DataObjectInterface $obj, $fields = null) {
     35         $response = Controller::curr()->getResponse();
     36         if($response) {
     37             $response->addHeader("Content-Type", "text/xml");
     38         }
     39
     40         return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . $this->convertDataObjectWithoutHeader($obj, $fields);
     41     }
     42
     43
     44     public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $relations = null) {
     45         $className = $obj->class;
     46         $id = $obj->ID;
     47         $objHref = Director::absoluteURL(self::$api_base . "$obj->class/$obj->ID");
     48
     49         $xml = "<$className href=\"$objHref.xml\">\n";
     50         foreach($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
     51             // Field filtering
     52             if($fields && !in_array($fieldName, $fields)) continue;
     53
     54             $fieldValue = $obj->$fieldName;
     55             if(!mb_check_encoding($fieldValue,'utf-8')) $fieldValue = "(data is badly encoded)";
     56
     57             if(is_object($fieldValue) && is_subclass_of($fieldValue, 'Object') && $fieldValue->hasMethod('toXML')) {
     58                 $xml .= $fieldValue->toXML();
     59             } else {
     60                 $xml .= "<$fieldName>" . Convert::raw2xml($fieldValue) . "</$fieldName>\n";
     61             }
     62         }
     63
     64         if($this->relationDepth > 0) {
     65             foreach($obj->has_one() as $relName => $relClass) {
     66                 if(!singleton($relClass)->stat('api_access')) continue;
     67
     68                 // Field filtering
     69                 if($fields && !in_array($relName, $fields)) continue;
     70                 if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
     71
     72                 $fieldName = $relName . 'ID';
     73                 if($obj->$fieldName) {
     74                     $href = Director::absoluteURL(self::$api_base . "$relClass/" . $obj->$fieldName);
     75                 } else {
     76                     $href = Director::absoluteURL(self::$api_base . "$className/$id/$relName");
     77                 }
     78                 $xml .= "<$relName linktype=\"has_one\" href=\"$href.xml\" id=\"" . $obj->$fieldName . "\"></$relName>\n";
     79             }
     80
     81             foreach($obj->has_many() as $relName => $relClass) {
     82                 if(!singleton($relClass)->stat('api_access')) continue;
     83
     84                 // Field filtering
     85                 if($fields && !in_array($relName, $fields)) continue;
     86                 if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
     87
     88                 $xml .= "<$relName linktype=\"has_many\" href=\"$objHref/$relName.xml\">\n";
     89                 $items = $obj->$relName();
     90                 if ($items) {
     91                     foreach($items as $item) {
     92                         //$href = Director::absoluteURL(self::$api_base . "$className/$id/$relName/$item->ID");
     93                         $href = Director::absoluteURL(self::$api_base . "$relClass/$item->ID");
     94                         $xml .= "<$relClass href=\"$href.xml\" id=\"{$item->ID}\"></$relClass>\n";
     95                     }
     96                 }
     97                 $xml .= "</$relName>\n";
     98             }
     99
    100             foreach($obj->many_many() as $relName => $relClass) {
    101                 if(!singleton($relClass)->stat('api_access')) continue;
    102
    103                 // Field filtering
    104                 if($fields && !in_array($relName, $fields)) continue;
    105                 if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
    106
    107                 $xml .= "<$relName linktype=\"many_many\" href=\"$objHref/$relName.xml\">\n";
    108                 $items = $obj->$relName();
    109                 if ($items) {
    110                     foreach($items as $item) {
    111                         $href = Director::absoluteURL(self::$api_base . "$relClass/$item->ID");
    112                         $xml .= "<$relClass href=\"$href.xml\" id=\"{$item->ID}\"></$relClass>\n";
    113                     }
    114                 }
    115                 $xml .= "</$relName>\n";
    116             }
    117         }
    118
    119         $xml .= "</$className>";
    120
    121         return $xml;
    122     }
    123
    124     /**
    125      * Generate an XML representation of the given {@link DataObjectSet}.
    126      *
    127      * @param DataObjectSet $set
    128      * @return String XML
    129      */
    130     public function convertDataObjectSet(DataObjectSet $set, $fields = null) {
    131         Controller::curr()->getResponse()->addHeader("Content-Type", "text/xml");
    132         $className = $set->class;
    133
    134         $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    135         $xml .= (is_numeric($this->totalSize)) ? "<$className totalSize=\"{$this->totalSize}\">\n" : "<$className>\n";
    136         foreach($set as $item) {
    137             if($item->canView()) $xml .= $this->convertDataObjectWithoutHeader($item, $fields);
    138         }
    139         $xml .= "</$className>";
    140
    141         return $xml;
    142     }
    143
    144     public function convertStringToArray($strData) {
    145         return Convert::xml2array($strData);
    146     }
    147 }

[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. -