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;
/**
* 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.
@ -167,6 +176,20 @@ abstract class DataFormatter extends Object {
$this->customAddFields = $fields;
}
/**
* @param array $relations
*/
public function setCustomRelations($relations) {
$this->customRelations = $relations;
}
/**
* @return array
*/
public function getCustomRelations() {
return $this->customRelations;
}
/**
* @return array
*/

View File

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

View File

@ -82,6 +82,12 @@ class RestfulServer extends Controller {
*/
protected static $default_mimetype = "text/xml";
/**
* @uses authenticate()
* @var Member
*/
protected $member;
/*
function handleItem($request) {
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();
// authenticate through HTTP BasicAuth
$member = $this->authenticate();
$this->member = $this->authenticate();
// handle different HTTP verbs
if($this->request->isGET() || $this->request->isHEAD()) return $this->getHandler($className, $id, $relation);
@ -257,9 +263,12 @@ class RestfulServer extends Controller {
$formatter = DataFormatter::for_extension(self::$default_extension);
}
if(!$formatter) return false;
// set custom fields
if($customAddFields = $this->request->getVar('add_fields')) $formatter->setCustomAddFields(explode(',',$customAddFields));
if($customFields = $this->request->getVar('fields')) $formatter->setCustomFields(explode(',',$customFields));
$formatter->setCustomRelations($this->getAllowedRelations($this->urlParams['ClassName']));
// set relation depth
$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;
$id = $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) {
// Field filtering
if($fields && !in_array($relName, $fields)) continue;
if($this->customRelations && !in_array($relName, $this->customRelations)) continue;
$fieldName = $relName . 'ID';
if($obj->$fieldName) {
@ -71,6 +72,7 @@ class XMLDataFormatter extends DataFormatter {
foreach($obj->has_many() as $relName => $relClass) {
// Field filtering
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";
$items = $obj->$relName();
@ -85,6 +87,7 @@ class XMLDataFormatter extends DataFormatter {
foreach($obj->many_many() as $relName => $relClass) {
// Field filtering
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";
$items = $obj->$relName();