ENHANCEMENT Don't like relations without $api_access in RestfulServer, added RestfulServer->getAllowedRelations()

ENHANCEMENT Added DataFormatter->setCustomRelations()

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@64003 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2008-10-09 14:47:25 +00:00
parent 4134f92dad
commit 06d78ee993
4 changed files with 61 additions and 3 deletions

View File

@ -44,6 +44,15 @@ abstract class DataFormatter extends Object {
*/ */
protected $customAddFields = null; 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. * Fields which should be expicitly excluded from the export.
* Comes in handy for field-level permissions. * Comes in handy for field-level permissions.
@ -166,6 +175,20 @@ abstract class DataFormatter extends Object {
public function setCustomAddFields($fields) { public function setCustomAddFields($fields) {
$this->customAddFields = $fields; $this->customAddFields = $fields;
} }
/**
* @param array $relations
*/
public function setCustomRelations($relations) {
$this->customRelations = $relations;
}
/**
* @return array
*/
public function getCustomRelations() {
return $this->customRelations;
}
/** /**
* @return array * @return array

View File

@ -29,7 +29,7 @@ class JSONDataFormatter extends DataFormatter {
* @param $includeHeader Include <?xml ...?> header (Default: true) * @param $includeHeader Include <?xml ...?> header (Default: true)
* @return String XML * @return String XML
*/ */
public function convertDataObject(DataObjectInterface $obj, $fields = null) { public function convertDataObject(DataObjectInterface $obj, $fields = null, $relations = null) {
$className = $obj->class; $className = $obj->class;
$id = $obj->ID; $id = $obj->ID;
@ -50,6 +50,7 @@ class JSONDataFormatter extends DataFormatter {
foreach($obj->has_one() as $relName => $relClass) { foreach($obj->has_one() as $relName => $relClass) {
// Field filtering // Field filtering
if($fields && !in_array($relName, $fields)) continue; if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$fieldName = $relName . 'ID'; $fieldName = $relName . 'ID';
if($obj->$fieldName) { if($obj->$fieldName) {
@ -63,6 +64,7 @@ class JSONDataFormatter extends DataFormatter {
foreach($obj->has_many() as $relName => $relClass) { foreach($obj->has_many() as $relName => $relClass) {
// Field filtering // Field filtering
if($fields && !in_array($relName, $fields)) continue; if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$jsonInnerParts = array(); $jsonInnerParts = array();
$items = $obj->$relName(); $items = $obj->$relName();
@ -77,6 +79,7 @@ class JSONDataFormatter extends DataFormatter {
foreach($obj->many_many() as $relName => $relClass) { foreach($obj->many_many() as $relName => $relClass) {
// Field filtering // Field filtering
if($fields && !in_array($relName, $fields)) continue; if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$jsonInnerParts = array(); $jsonInnerParts = array();
$items = $obj->$relName(); $items = $obj->$relName();

View File

@ -82,6 +82,12 @@ class RestfulServer extends Controller {
*/ */
protected static $default_mimetype = "text/xml"; protected static $default_mimetype = "text/xml";
/**
* @uses authenticate()
* @var Member
*/
protected $member;
/* /*
function handleItem($request) { function handleItem($request) {
return new RestfulServer_Item(DataObject::get_by_id($request->param("ClassName"), $request->param("ID"))); return new RestfulServer_Item(DataObject::get_by_id($request->param("ClassName"), $request->param("ID")));
@ -108,7 +114,7 @@ class RestfulServer extends Controller {
if(!singleton($className)->stat('api_access')) return $this->permissionFailure(); if(!singleton($className)->stat('api_access')) return $this->permissionFailure();
// authenticate through HTTP BasicAuth // authenticate through HTTP BasicAuth
$member = $this->authenticate(); $this->member = $this->authenticate();
// handle different HTTP verbs // handle different HTTP verbs
if($this->request->isGET() || $this->request->isHEAD()) return $this->getHandler($className, $id, $relation); if($this->request->isGET() || $this->request->isHEAD()) return $this->getHandler($className, $id, $relation);
@ -256,10 +262,13 @@ class RestfulServer extends Controller {
} else { } else {
$formatter = DataFormatter::for_extension(self::$default_extension); $formatter = DataFormatter::for_extension(self::$default_extension);
} }
if(!$formatter) return false;
// set custom fields // set custom fields
if($customAddFields = $this->request->getVar('add_fields')) $formatter->setCustomAddFields(explode(',',$customAddFields)); if($customAddFields = $this->request->getVar('add_fields')) $formatter->setCustomAddFields(explode(',',$customAddFields));
if($customFields = $this->request->getVar('fields')) $formatter->setCustomFields(explode(',',$customFields)); if($customFields = $this->request->getVar('fields')) $formatter->setCustomFields(explode(',',$customFields));
$formatter->setCustomRelations($this->getAllowedRelations($this->urlParams['ClassName']));
// set relation depth // set relation depth
$relationDepth = $this->request->getVar('relationdepth'); $relationDepth = $this->request->getVar('relationdepth');
@ -470,6 +479,26 @@ class RestfulServer extends Controller {
} }
} }
/**
* Return only relations which have $api_access enabled.
* @todo Respect field level permissions once they are available in core
*
* @param string $class
* @param Member $member
* @return array
*/
protected function getAllowedRelations($class, $member = null) {
$allowedRelations = array();
$obj = singleton($class);
$relations = (array)$obj->has_one() + (array)$obj->has_many() + (array)$obj->many_many();
if($relations) foreach($relations as $relName => $relClass) {
if(singleton($relClass)->stat('api_access')) {
$allowedRelations[] = $relName;
}
}
return $allowedRelations;
}
} }
/** /**

View File

@ -34,7 +34,7 @@ class XMLDataFormatter extends DataFormatter {
} }
public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null) { public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $relations = null) {
$className = $obj->class; $className = $obj->class;
$id = $obj->ID; $id = $obj->ID;
$objHref = Director::absoluteURL(self::$api_base . "$obj->class/$obj->ID"); $objHref = Director::absoluteURL(self::$api_base . "$obj->class/$obj->ID");
@ -58,6 +58,7 @@ class XMLDataFormatter extends DataFormatter {
foreach($obj->has_one() as $relName => $relClass) { foreach($obj->has_one() as $relName => $relClass) {
// Field filtering // Field filtering
if($fields && !in_array($relName, $fields)) continue; if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$fieldName = $relName . 'ID'; $fieldName = $relName . 'ID';
if($obj->$fieldName) { if($obj->$fieldName) {
@ -71,6 +72,7 @@ class XMLDataFormatter extends DataFormatter {
foreach($obj->has_many() as $relName => $relClass) { foreach($obj->has_many() as $relName => $relClass) {
// Field filtering // Field filtering
if($fields && !in_array($relName, $fields)) continue; if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$json .= "<$relName linktype=\"has_many\" href=\"$objHref/$relName.xml\">\n"; $json .= "<$relName linktype=\"has_many\" href=\"$objHref/$relName.xml\">\n";
$items = $obj->$relName(); $items = $obj->$relName();
@ -85,6 +87,7 @@ class XMLDataFormatter extends DataFormatter {
foreach($obj->many_many() as $relName => $relClass) { foreach($obj->many_many() as $relName => $relClass) {
// Field filtering // Field filtering
if($fields && !in_array($relName, $fields)) continue; if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$json .= "<$relName linktype=\"many_many\" href=\"$objHref/$relName.xml\">\n"; $json .= "<$relName linktype=\"many_many\" href=\"$objHref/$relName.xml\">\n";
$items = $obj->$relName(); $items = $obj->$relName();