mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #5877 from open-sausages/pulls/4.0/remove-data-formatters
API remove DataFormatter class and all subclasses
This commit is contained in:
commit
34c8324673
@ -1,320 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObjectInterface;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
/**
|
||||
* A DataFormatter object handles transformation of data from SilverStripe model objects to a particular output
|
||||
* format, and vice versa. This is most commonly used in developing RESTful APIs.
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage formatters
|
||||
*/
|
||||
abstract class DataFormatter extends Object {
|
||||
|
||||
/**
|
||||
* Set priority from 0-100.
|
||||
* If multiple formatters for the same extension exist,
|
||||
* we select the one with highest priority.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private static $priority = 50;
|
||||
|
||||
/**
|
||||
* Follow relations for the {@link DataObject} instances
|
||||
* ($has_one, $has_many, $many_many).
|
||||
* Set to "0" to disable relation output.
|
||||
*
|
||||
* @todo Support more than one nesting level
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $relationDepth = 1;
|
||||
|
||||
/**
|
||||
* Allows overriding of the fields which are rendered for the
|
||||
* processed dataobjects. By default, this includes all
|
||||
* fields in {@link DataObject::inheritedDatabaseFields()}.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customFields = null;
|
||||
|
||||
/**
|
||||
* Allows addition of fields
|
||||
* (e.g. custom getters on a DataObject)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customAddFields = null;
|
||||
|
||||
/**
|
||||
* Allows to limit or add relations.
|
||||
* Only use in combination with {@link $relationDepth}.
|
||||
* By default, all relations will be shown.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customRelations = null;
|
||||
|
||||
/**
|
||||
* Fields which should be expicitly excluded from the export.
|
||||
* Comes in handy for field-level permissions.
|
||||
* Will overrule both {@link $customAddFields} and {@link $customFields}
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $removeFields = null;
|
||||
|
||||
/**
|
||||
* Specifies the mimetype in which all strings
|
||||
* returned from the convert*() methods should be used,
|
||||
* e.g. "text/xml".
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $outputContentType = null;
|
||||
|
||||
/**
|
||||
* Used to set totalSize properties on the output
|
||||
* of {@link convertDataObjectSet()}, shows the
|
||||
* total number of records without the "limit" and "offset"
|
||||
* GET parameters. Useful to implement pagination.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $totalSize;
|
||||
|
||||
/**
|
||||
* Get a DataFormatter object suitable for handling the given file extension.
|
||||
*
|
||||
* @param string $extension
|
||||
* @return DataFormatter
|
||||
*/
|
||||
public static function for_extension($extension) {
|
||||
$classes = ClassInfo::subclassesFor("DataFormatter");
|
||||
array_shift($classes);
|
||||
$sortedClasses = array();
|
||||
foreach($classes as $class) {
|
||||
$sortedClasses[$class] = singleton($class)->stat('priority');
|
||||
}
|
||||
arsort($sortedClasses);
|
||||
foreach($sortedClasses as $className => $priority) {
|
||||
/** @var DataFormatter $formatter */
|
||||
$formatter = new $className();
|
||||
if(in_array($extension, $formatter->supportedExtensions())) {
|
||||
return $formatter;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatter for the first matching extension.
|
||||
*
|
||||
* @param array $extensions
|
||||
* @return DataFormatter
|
||||
*/
|
||||
public static function for_extensions($extensions) {
|
||||
foreach($extensions as $extension) {
|
||||
if($formatter = self::for_extension($extension)) return $formatter;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a DataFormatter object suitable for handling the given mimetype.
|
||||
*
|
||||
* @param string $mimeType
|
||||
* @return DataFormatter
|
||||
*/
|
||||
public static function for_mimetype($mimeType) {
|
||||
$classes = ClassInfo::subclassesFor("DataFormatter");
|
||||
array_shift($classes);
|
||||
$sortedClasses = array();
|
||||
foreach($classes as $class) {
|
||||
$sortedClasses[$class] = singleton($class)->stat('priority');
|
||||
}
|
||||
arsort($sortedClasses);
|
||||
foreach($sortedClasses as $className => $priority) {
|
||||
/** @var DataFormatter $formatter */
|
||||
$formatter = new $className();
|
||||
if(in_array($mimeType, $formatter->supportedMimeTypes())) {
|
||||
return $formatter;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatter for the first matching mimetype.
|
||||
* Useful for HTTP Accept headers which can contain
|
||||
* multiple comma-separated mimetypes.
|
||||
*
|
||||
* @param array $mimetypes
|
||||
* @return DataFormatter
|
||||
*/
|
||||
public static function for_mimetypes($mimetypes) {
|
||||
foreach($mimetypes as $mimetype) {
|
||||
if($formatter = self::for_mimetype($mimetype)) return $formatter;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function setCustomFields($fields) {
|
||||
$this->customFields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCustomFields() {
|
||||
return $this->customFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function setCustomAddFields($fields) {
|
||||
$this->customAddFields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $relations
|
||||
*/
|
||||
public function setCustomRelations($relations) {
|
||||
$this->customRelations = $relations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCustomRelations() {
|
||||
return $this->customRelations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCustomAddFields() {
|
||||
return $this->customAddFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function setRemoveFields($fields) {
|
||||
$this->removeFields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRemoveFields() {
|
||||
return $this->removeFields;
|
||||
}
|
||||
|
||||
public function getOutputContentType() {
|
||||
return $this->outputContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $size
|
||||
*/
|
||||
public function setTotalSize($size) {
|
||||
$this->totalSize = (int)$size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalSize() {
|
||||
return $this->totalSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all fields on the object which should be shown
|
||||
* in the output. Can be customised through {@link self::setCustomFields()}.
|
||||
*
|
||||
* @todo Allow for custom getters on the processed object (currently filtered through inheritedDatabaseFields)
|
||||
* @todo Field level permission checks
|
||||
*
|
||||
* @param DataObjectInterface|DataObject $obj
|
||||
* @return array
|
||||
*/
|
||||
protected function getFieldsForObj($obj) {
|
||||
$dbFields = array();
|
||||
|
||||
// if custom fields are specified, only select these
|
||||
if(is_array($this->customFields)) {
|
||||
foreach($this->customFields as $fieldName) {
|
||||
// @todo Possible security risk by making methods accessible - implement field-level security
|
||||
if($obj->hasField($fieldName) || $obj->hasMethod("get{$fieldName}")) {
|
||||
$dbFields[$fieldName] = $fieldName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// by default, all database fields are selected
|
||||
$dbFields = $obj->db();
|
||||
}
|
||||
|
||||
if(is_array($this->customAddFields)) {
|
||||
foreach($this->customAddFields as $fieldName) {
|
||||
// @todo Possible security risk by making methods accessible - implement field-level security
|
||||
if($obj->hasField($fieldName) || $obj->hasMethod("get{$fieldName}")) {
|
||||
$dbFields[$fieldName] = $fieldName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add default required fields
|
||||
$dbFields = array_merge($dbFields, array('ID' => 'Int'));
|
||||
|
||||
if(is_array($this->removeFields)) {
|
||||
$dbFields = array_diff_key($dbFields, array_combine($this->removeFields,$this->removeFields));
|
||||
}
|
||||
|
||||
return $dbFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the extensions that this data formatter supports
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function supportedExtensions();
|
||||
|
||||
/**
|
||||
* Get supported mime types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function supportedMimeTypes();
|
||||
|
||||
/**
|
||||
* Convert a single data object to this format.
|
||||
*
|
||||
* @param DataObjectInterface $do
|
||||
* @return string
|
||||
*/
|
||||
abstract public function convertDataObject(DataObjectInterface $do);
|
||||
|
||||
/**
|
||||
* Convert a data object set to this format.
|
||||
*
|
||||
* @param SS_List $set
|
||||
* @return string
|
||||
*/
|
||||
abstract public function convertDataObjectSet(SS_List $set);
|
||||
|
||||
/**
|
||||
* @param string $strData HTTP Payload as string
|
||||
* @return array
|
||||
*/
|
||||
abstract public function convertStringToArray($strData);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Accepts form encoded strings and converts them
|
||||
* to a valid PHP array via {@link parse_str()}.
|
||||
*
|
||||
* Example when using cURL on commandline:
|
||||
* <code>
|
||||
* curl -d "Name=This is a new record" http://host/api/v1/(DataObject)
|
||||
* curl -X PUT -d "Name=This is an updated record" http://host/api/v1/(DataObject)/1
|
||||
* </code>
|
||||
*
|
||||
* @todo Format response form encoded as well - currently uses XMLDataFormatter
|
||||
*
|
||||
* @author Cam Spiers <camspiers at gmail dot com>
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage formatters
|
||||
*/
|
||||
class FormEncodedDataFormatter extends XMLDataFormatter {
|
||||
|
||||
public function supportedExtensions() {
|
||||
return array(
|
||||
);
|
||||
}
|
||||
|
||||
public function supportedMimeTypes() {
|
||||
return array(
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
}
|
||||
|
||||
public function convertStringToArray($strData) {
|
||||
$postArray = array();
|
||||
parse_str($strData, $postArray);
|
||||
return $postArray;
|
||||
//TODO: It would be nice to implement this function in Convert.php
|
||||
//return Convert::querystr2array($strData);
|
||||
}
|
||||
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObjectInterface;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
/**
|
||||
* @package framework
|
||||
* @subpackage formatters
|
||||
*/
|
||||
class JSONDataFormatter extends DataFormatter {
|
||||
|
||||
/**
|
||||
* @config
|
||||
* @todo pass this from the API to the data formatter somehow
|
||||
*/
|
||||
private static $api_base = "api/v1/";
|
||||
|
||||
protected $outputContentType = 'application/json';
|
||||
|
||||
public function supportedExtensions() {
|
||||
return array(
|
||||
'json',
|
||||
'js'
|
||||
);
|
||||
}
|
||||
|
||||
public function supportedMimeTypes() {
|
||||
return array(
|
||||
'application/json',
|
||||
'text/x-json'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON representation of the given {@link DataObject}.
|
||||
*
|
||||
* @param DataObjectInterface $obj The object
|
||||
* @param array $fields If supplied, only fields in the list will be returned
|
||||
* @param array $relations Not used
|
||||
* @return String JSON
|
||||
*/
|
||||
public function convertDataObject(DataObjectInterface $obj, $fields = null, $relations = null) {
|
||||
return Convert::raw2json($this->convertDataObjectToJSONObject($obj, $fields, $relations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to do the conversion of a single data object. It builds an empty object and dynamically
|
||||
* adds the properties it needs to it. If it's done as a nested array, json_encode or equivalent won't use
|
||||
* JSON object notation { ... }.
|
||||
* @param DataObjectInterface|DataObject $obj
|
||||
* @param array $fields
|
||||
* @param array $relations
|
||||
* @return stdClass
|
||||
*/
|
||||
public function convertDataObjectToJSONObject(DataObjectInterface $obj, $fields = null, $relations = null) {
|
||||
$className = $obj->class;
|
||||
$id = $obj->ID;
|
||||
|
||||
$serobj = ArrayData::array_to_object();
|
||||
|
||||
foreach($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
|
||||
// Field filtering
|
||||
if($fields && !in_array($fieldName, $fields)) continue;
|
||||
|
||||
$fieldValue = $obj->obj($fieldName)->forTemplate();
|
||||
$serobj->$fieldName = $fieldValue;
|
||||
}
|
||||
|
||||
if($this->relationDepth > 0) {
|
||||
foreach($obj->hasOne() as $relName => $relClass) {
|
||||
if(!singleton($relClass)->stat('api_access')) continue;
|
||||
|
||||
// Field filtering
|
||||
if($fields && !in_array($relName, $fields)) continue;
|
||||
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
|
||||
|
||||
$fieldName = $relName . 'ID';
|
||||
if($obj->$fieldName) {
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$relClass/" . $obj->$fieldName);
|
||||
} else {
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName");
|
||||
}
|
||||
$serobj->$relName = ArrayData::array_to_object(array(
|
||||
"className" => $relClass,
|
||||
"href" => "$href.json",
|
||||
"id" => $obj->$fieldName
|
||||
));
|
||||
}
|
||||
|
||||
foreach($obj->hasMany() as $relName => $relClass) {
|
||||
if(!singleton($relClass)->stat('api_access')) continue;
|
||||
|
||||
// Field filtering
|
||||
if($fields && !in_array($relName, $fields)) continue;
|
||||
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
|
||||
|
||||
$innerParts = array();
|
||||
$items = $obj->$relName();
|
||||
foreach($items as $item) {
|
||||
//$href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName/$item->ID");
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID");
|
||||
$innerParts[] = ArrayData::array_to_object(array(
|
||||
"className" => $relClass,
|
||||
"href" => "$href.json",
|
||||
"id" => $item->ID
|
||||
));
|
||||
}
|
||||
$serobj->$relName = $innerParts;
|
||||
}
|
||||
|
||||
foreach($obj->manyMany() as $relName => $relClass) {
|
||||
if(!singleton($relClass)->stat('api_access')) continue;
|
||||
|
||||
// Field filtering
|
||||
if($fields && !in_array($relName, $fields)) continue;
|
||||
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
|
||||
|
||||
$innerParts = array();
|
||||
$items = $obj->$relName();
|
||||
foreach($items as $item) {
|
||||
//$href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName/$item->ID");
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID");
|
||||
$innerParts[] = ArrayData::array_to_object(array(
|
||||
"className" => $relClass,
|
||||
"href" => "$href.json",
|
||||
"id" => $item->ID
|
||||
));
|
||||
}
|
||||
$serobj->$relName = $innerParts;
|
||||
}
|
||||
}
|
||||
|
||||
return $serobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON representation of the given {@link SS_List}.
|
||||
*
|
||||
* @param SS_List $set
|
||||
* @param array $fields
|
||||
* @return String XML
|
||||
*/
|
||||
public function convertDataObjectSet(SS_List $set, $fields = null) {
|
||||
$items = array();
|
||||
foreach($set as $do) {
|
||||
if(!$do->canView()) continue;
|
||||
$items[] = $this->convertDataObjectToJSONObject($do, $fields);
|
||||
}
|
||||
|
||||
$serobj = ArrayData::array_to_object(array(
|
||||
"totalSize" => (is_numeric($this->totalSize)) ? $this->totalSize : null,
|
||||
"items" => $items
|
||||
));
|
||||
|
||||
return Convert::raw2json($serobj);
|
||||
}
|
||||
|
||||
public function convertStringToArray($strData) {
|
||||
return Convert::json2array($strData);
|
||||
}
|
||||
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObjectInterface;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
|
||||
/**
|
||||
* @package framework
|
||||
* @subpackage formatters
|
||||
*/
|
||||
class XMLDataFormatter extends DataFormatter {
|
||||
|
||||
/**
|
||||
* @config
|
||||
* @todo pass this from the API to the data formatter somehow
|
||||
*/
|
||||
private static $api_base = "api/v1/";
|
||||
|
||||
protected $outputContentType = 'text/xml';
|
||||
|
||||
public function supportedExtensions() {
|
||||
return array(
|
||||
'xml'
|
||||
);
|
||||
}
|
||||
|
||||
public function supportedMimeTypes() {
|
||||
return array(
|
||||
'text/xml',
|
||||
'application/xml',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an XML representation of the given {@link DataObject}.
|
||||
*
|
||||
* @param DataObjectInterface|DataObject $obj
|
||||
* @param array $fields
|
||||
* @return string XML
|
||||
*/
|
||||
public function convertDataObject(DataObjectInterface $obj, $fields = null) {
|
||||
$response = Controller::curr()->getResponse();
|
||||
if($response) {
|
||||
$response->addHeader("Content-Type", "text/xml");
|
||||
}
|
||||
|
||||
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . $this->convertDataObjectWithoutHeader($obj, $fields);
|
||||
}
|
||||
|
||||
public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $relations = null) {
|
||||
$className = $obj->class;
|
||||
$id = $obj->ID;
|
||||
$objHref = Director::absoluteURL($this->config()->api_base . "$obj->class/$obj->ID");
|
||||
|
||||
$xml = "<$className href=\"$objHref.xml\">\n";
|
||||
foreach($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
|
||||
// Field filtering
|
||||
if($fields && !in_array($fieldName, $fields)) {
|
||||
continue;
|
||||
}
|
||||
$fieldObject = $obj->obj($fieldName);
|
||||
$fieldValue = $fieldObject->forTemplate();
|
||||
if(!mb_check_encoding($fieldValue, 'utf-8')) {
|
||||
$fieldValue = "(data is badly encoded)";
|
||||
}
|
||||
|
||||
if(is_object($fieldValue) && is_subclass_of($fieldValue, 'Object') && $fieldValue->hasMethod('toXML')) {
|
||||
$xml .= $fieldValue->toXML();
|
||||
} else {
|
||||
if($fieldObject instanceof DBHTMLText) {
|
||||
// Escape HTML values using CDATA
|
||||
$fieldValue = sprintf('<![CDATA[%s]]>', str_replace(']]>', ']]]]><![CDATA[>', $fieldValue));
|
||||
}
|
||||
$xml .= "<$fieldName>$fieldValue</$fieldName>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if($this->relationDepth > 0) {
|
||||
foreach($obj->hasOne() as $relName => $relClass) {
|
||||
if(!singleton($relClass)->stat('api_access')) continue;
|
||||
|
||||
// Field filtering
|
||||
if($fields && !in_array($relName, $fields)) continue;
|
||||
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
|
||||
|
||||
$fieldName = $relName . 'ID';
|
||||
if($obj->$fieldName) {
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$relClass/" . $obj->$fieldName);
|
||||
} else {
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName");
|
||||
}
|
||||
$xml .= "<$relName linktype=\"has_one\" href=\"$href.xml\" id=\"" . $obj->$fieldName
|
||||
. "\"></$relName>\n";
|
||||
}
|
||||
|
||||
foreach($obj->hasMany() as $relName => $relClass) {
|
||||
if(!singleton($relClass)->stat('api_access')) continue;
|
||||
|
||||
// Field filtering
|
||||
if($fields && !in_array($relName, $fields)) continue;
|
||||
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
|
||||
|
||||
$xml .= "<$relName linktype=\"has_many\" href=\"$objHref/$relName.xml\">\n";
|
||||
$items = $obj->$relName();
|
||||
if ($items) {
|
||||
foreach($items as $item) {
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID");
|
||||
$xml .= "<$relClass href=\"$href.xml\" id=\"{$item->ID}\"></$relClass>\n";
|
||||
}
|
||||
}
|
||||
$xml .= "</$relName>\n";
|
||||
}
|
||||
|
||||
foreach($obj->manyMany() as $relName => $relClass) {
|
||||
if(!singleton($relClass)->stat('api_access')) continue;
|
||||
|
||||
// Field filtering
|
||||
if($fields && !in_array($relName, $fields)) continue;
|
||||
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
|
||||
|
||||
$xml .= "<$relName linktype=\"many_many\" href=\"$objHref/$relName.xml\">\n";
|
||||
$items = $obj->$relName();
|
||||
if ($items) {
|
||||
foreach($items as $item) {
|
||||
$href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID");
|
||||
$xml .= "<$relClass href=\"$href.xml\" id=\"{$item->ID}\"></$relClass>\n";
|
||||
}
|
||||
}
|
||||
$xml .= "</$relName>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$xml .= "</$className>";
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an XML representation of the given {@link SS_List}.
|
||||
*
|
||||
* @param SS_List $set
|
||||
* @param array $fields
|
||||
* @return String XML
|
||||
*/
|
||||
public function convertDataObjectSet(SS_List $set, $fields = null) {
|
||||
Controller::curr()->getResponse()->addHeader("Content-Type", "text/xml");
|
||||
$className = get_class($set);
|
||||
|
||||
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
$xml .= (is_numeric($this->totalSize)) ? "<$className totalSize=\"{$this->totalSize}\">\n" : "<$className>\n";
|
||||
foreach($set as $item) {
|
||||
$xml .= $this->convertDataObjectWithoutHeader($item, $fields);
|
||||
}
|
||||
$xml .= "</$className>";
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
public function convertStringToArray($strData) {
|
||||
return Convert::xml2array($strData);
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
class XMLDataFormatterTest extends SapphireTest {
|
||||
protected $arguments, $contents, $tagName;
|
||||
|
||||
protected static $fixture_file = 'XMLDataFormatterTest.yml';
|
||||
|
||||
public function setUp() {
|
||||
ShortcodeParser::get_active()->register('test_shortcode', array($this, 'shortcodeSaver'));
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
ShortcodeParser::get_active()->unregister('test_shortcode');
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected $extraDataObjects = array(
|
||||
'XMLDataFormatterTest_DataObject'
|
||||
);
|
||||
|
||||
public function testConvertDataObjectWithoutHeader() {
|
||||
$formatter = new XMLDataFormatter();
|
||||
$obj = $this->objFromFixture('XMLDataFormatterTest_DataObject', 'test-do');
|
||||
$xml = new SimpleXMLElement('<?xml version="1.0"?>' . $formatter->convertDataObjectWithoutHeader($obj));
|
||||
$this->assertEquals(
|
||||
Director::absoluteBaseURL() . sprintf('api/v1/XMLDataFormatterTest_DataObject/%d.xml', $obj->ID),
|
||||
(string) $xml['href']
|
||||
);
|
||||
$this->assertEquals('Test DataObject', (string) $xml->Name);
|
||||
$this->assertEquals('Test Company', (string) $xml->Company);
|
||||
$this->assertEquals($obj->ID, (int) $xml->ID);
|
||||
$this->assertEquals(
|
||||
'<Content><![CDATA[<a href="http://mysite.com">mysite.com</a> is a link in this HTML content.]]>'
|
||||
. '</Content>',
|
||||
$xml->Content->asXML()
|
||||
);
|
||||
$this->assertEquals(
|
||||
'<a href="http://mysite.com">mysite.com</a> is a link in this HTML content.',
|
||||
(string)$xml->Content
|
||||
);
|
||||
}
|
||||
|
||||
public function testShortcodesInDataObject() {
|
||||
$formatter = new XMLDataFormatter();
|
||||
|
||||
$page = new XMLDataFormatterTest_DataObject();
|
||||
$page->Content = 'This is some test content [test_shortcode]test[/test_shortcode]';
|
||||
|
||||
$xml = new SimpleXMLElement('<?xml version="1.0"?>' . $formatter->convertDataObjectWithoutHeader($page));
|
||||
$this->assertEquals('This is some test content test', (string)$xml->Content);
|
||||
|
||||
$page->Content = '[test_shortcode,id=-1]';
|
||||
$xml = new SimpleXMLElement('<?xml version="1.0"?>' . $formatter->convertDataObjectWithoutHeader($page));
|
||||
$this->assertEmpty((string)$xml->Content);
|
||||
|
||||
$page->Content = '[bad_code,id=1]';
|
||||
|
||||
$xml = new SimpleXMLElement('<?xml version="1.0"?>' . $formatter->convertDataObjectWithoutHeader($page));
|
||||
$this->assertContains('[bad_code,id=1]', (string)$xml->Content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the result of a shortcode parse in object properties for easy testing access.
|
||||
*/
|
||||
public function shortcodeSaver($arguments, $content = null, $parser, $tagName = null) {
|
||||
$this->arguments = $arguments;
|
||||
$this->contents = $content;
|
||||
$this->tagName = $tagName;
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
class XMLDataFormatterTest_DataObject extends DataObject implements TestOnly {
|
||||
|
||||
private static $db = array(
|
||||
'Name' => 'Varchar(50)',
|
||||
'Company' => 'Varchar(50)',
|
||||
'Content' => 'HTMLText'
|
||||
);
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
XMLDataFormatterTest_DataObject:
|
||||
test-do:
|
||||
Name: Test DataObject
|
||||
Company: Test Company
|
||||
Content: <a href="http://mysite.com">mysite.com</a> is a link in this HTML content.
|
Loading…
x
Reference in New Issue
Block a user