FEATURE: Allow Use of ?fields=ID,Name,OtherField,RelName get variable on RESTful server queries, to restrict the fields and relations returned int the data set

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@62458 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2008-09-16 12:10:58 +00:00
parent 1e12016ed6
commit 4495f9c939
3 changed files with 38 additions and 11 deletions

View File

@ -29,12 +29,15 @@ class JSONDataFormatter extends DataFormatter {
* @param $includeHeader Include <?xml ...?> header (Default: true)
* @return String XML
*/
public function convertDataObject(DataObjectInterface $obj) {
public function convertDataObject(DataObjectInterface $obj, $fields = null) {
$className = $obj->class;
$id = $obj->ID;
$json = "{\n className : \"$className\",\n";
foreach($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
// Field filtering
if($fields && !in_array($fieldName, $fields)) continue;
$fieldValue = $obj->$fieldName;
if(is_object($fieldValue) && is_subclass_of($fieldValue, 'Object') && $fieldValue->hasMethod('toJSON')) {
$jsonParts[] = "$fieldName : " . $fieldValue->toJSON();
@ -45,6 +48,9 @@ class JSONDataFormatter extends DataFormatter {
if($this->relationDepth > 0) {
foreach($obj->has_one() as $relName => $relClass) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
$fieldName = $relName . 'ID';
if($obj->$fieldName) {
$href = Director::absoluteURL(self::$api_base . "$relClass/" . $obj->$fieldName);
@ -55,6 +61,9 @@ class JSONDataFormatter extends DataFormatter {
}
foreach($obj->has_many() as $relName => $relClass) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
$jsonInnerParts = array();
$items = $obj->$relName();
foreach($items as $item) {
@ -66,6 +75,9 @@ class JSONDataFormatter extends DataFormatter {
}
foreach($obj->many_many() as $relName => $relClass) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
$jsonInnerParts = array();
$items = $obj->$relName();
foreach($items as $item) {
@ -85,10 +97,10 @@ class JSONDataFormatter extends DataFormatter {
* @param DataObjectSet $set
* @return String XML
*/
public function convertDataObjectSet(DataObjectSet $set) {
public function convertDataObjectSet(DataObjectSet $set, $fields = null) {
$jsonParts = array();
foreach($set as $item) {
if($item->canView()) $jsonParts[] = $this->convertDataObject($item);
if($item->canView()) $jsonParts[] = $this->convertDataObject($item, $fields);
}
$json = "{\n";
$json .= 'totalSize: ';

View File

@ -182,15 +182,18 @@ class RestfulServer extends Controller {
}
$this->getResponse()->addHeader('Content-Type', $responseFormatter->getOutputContentType());
$rawFields = $this->request->getVar('fields');
$fields = $rawFields ? explode(',', $rawFields) : null;
if($obj instanceof DataObjectSet) {
$responseFormatter->setTotalSize($query->unlimitedRowCount());
return $responseFormatter->convertDataObjectSet($obj);
return $responseFormatter->convertDataObjectSet($obj, $fields);
} else if(!$obj) {
$responseFormatter->setTotalSize(0);
return $responseFormatter->convertDataObjectSet(new DataObjectSet());
return $responseFormatter->convertDataObjectSet(new DataObjectSet(), $fields);
} else {
return $responseFormatter->convertDataObject($obj);
return $responseFormatter->convertDataObject($obj, $fields);
}
}

View File

@ -28,19 +28,22 @@ class XMLDataFormatter extends DataFormatter {
* @param $includeHeader Include <?xml ...?> header (Default: true)
* @return String XML
*/
public function convertDataObject(DataObjectInterface $obj) {
public function convertDataObject(DataObjectInterface $obj, $fields = null) {
Controller::curr()->getResponse()->addHeader("Content-type", "text/xml");
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . $this->convertDataObjectWithoutHeader($obj);
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . $this->convertDataObjectWithoutHeader($obj, $fields);
}
public function convertDataObjectWithoutHeader(DataObject $obj) {
public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null) {
$className = $obj->class;
$id = $obj->ID;
$objHref = Director::absoluteURL(self::$api_base . "$obj->class/$obj->ID");
$json = "<$className href=\"$objHref.xml\">\n";
foreach($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
// Field filtering
if($fields && !in_array($fieldName, $fields)) continue;
$fieldValue = $obj->$fieldName;
if(!mb_check_encoding($fieldValue,'utf-8')) $fieldValue = "(data is badly encoded)";
@ -53,6 +56,9 @@ class XMLDataFormatter extends DataFormatter {
if($this->relationDepth > 0) {
foreach($obj->has_one() as $relName => $relClass) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
$fieldName = $relName . 'ID';
if($obj->$fieldName) {
$href = Director::absoluteURL(self::$api_base . "$relClass/" . $obj->$fieldName);
@ -63,6 +69,9 @@ class XMLDataFormatter extends DataFormatter {
}
foreach($obj->has_many() as $relName => $relClass) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
$json .= "<$relName linktype=\"has_many\" href=\"$objHref/$relName.xml\">\n";
$items = $obj->$relName();
foreach($items as $item) {
@ -74,6 +83,9 @@ class XMLDataFormatter extends DataFormatter {
}
foreach($obj->many_many() as $relName => $relClass) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
$json .= "<$relName linktype=\"many_many\" href=\"$objHref/$relName.xml\">\n";
$items = $obj->$relName();
foreach($items as $item) {
@ -95,14 +107,14 @@ class XMLDataFormatter extends DataFormatter {
* @param DataObjectSet $set
* @return String XML
*/
public function convertDataObjectSet(DataObjectSet $set) {
public function convertDataObjectSet(DataObjectSet $set, $fields = null) {
Controller::curr()->getResponse()->addHeader("Content-type", "text/xml");
$className = $set->class;
$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) {
if($item->canView()) $xml .= $this->convertDataObjectWithoutHeader($item);
if($item->canView()) $xml .= $this->convertDataObjectWithoutHeader($item, $fields);
}
$xml .= "</$className>";