mirror of
https://github.com/silverstripe/silverstripe-restfulserver
synced 2024-10-22 14:05:58 +02:00
Compare commits
No commits in common. "810f87cc4951d5a0172493ef0761e6278accc997" and "9f39cb180aed7fd481d38dca9aceb9e5b784a300" have entirely different histories.
810f87cc49
...
9f39cb180a
@ -32,6 +32,8 @@ abstract class DataFormatter
|
||||
* ($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;
|
||||
@ -288,6 +290,9 @@ abstract class DataFormatter
|
||||
* 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 DataObject $obj
|
||||
* @return array
|
||||
*/
|
||||
@ -298,6 +303,7 @@ abstract class DataFormatter
|
||||
// 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) && !is_object($obj->getField($fieldName)))
|
||||
|| $obj->hasMethod("get{$fieldName}")
|
||||
) {
|
||||
@ -312,6 +318,7 @@ abstract class DataFormatter
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace SilverStripe\RestfulServer\DataFormatter;
|
||||
* 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>
|
||||
*/
|
||||
@ -36,5 +37,7 @@ class FormEncodedDataFormatter extends XMLDataFormatter
|
||||
$postArray = array();
|
||||
parse_str($strData ?? '', $postArray);
|
||||
return $postArray;
|
||||
//TODO: It would be nice to implement this function in Convert.php
|
||||
//return Convert::querystr2array($strData);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ class JSONDataFormatter extends DataFormatter
|
||||
{
|
||||
/**
|
||||
* @config
|
||||
* @todo pass this from the API to the data formatter somehow
|
||||
*/
|
||||
private static $api_base = "api/v1/";
|
||||
|
||||
|
@ -22,6 +22,7 @@ class XMLDataFormatter extends DataFormatter
|
||||
|
||||
/**
|
||||
* @config
|
||||
* @todo pass this from the API to the data formatter somehow
|
||||
*/
|
||||
private static $api_base = "api/v1/";
|
||||
|
||||
|
@ -22,6 +22,23 @@ use SilverStripe\Security\Security;
|
||||
* Relies on serialization/deserialization into different formats provided
|
||||
* by the DataFormatter APIs in core.
|
||||
*
|
||||
* @todo Implement PUT/POST/DELETE for relations
|
||||
* @todo Access-Control for relations (you might be allowed to view Members and Groups,
|
||||
* but not their relation with each other)
|
||||
* @todo Make SearchContext specification customizeable for each class
|
||||
* @todo Allow for range-searches (e.g. on Created column)
|
||||
* @todo Filter relation listings by $api_access and canView() permissions
|
||||
* @todo Exclude relations when "fields" are specified through URL (they should be explicitly
|
||||
* requested in this case)
|
||||
* @todo Custom filters per DataObject subclass, e.g. to disallow showing unpublished pages in
|
||||
* SiteTree/Versioned/Hierarchy
|
||||
* @todo URL parameter namespacing for search-fields, limit, fields, add_fields
|
||||
* (might all be valid dataobject properties)
|
||||
* e.g. you wouldn't be able to search for a "limit" property on your subclass as
|
||||
* its overlayed with the search logic
|
||||
* @todo i18n integration (e.g. Page/1.xml?lang=de_DE)
|
||||
* @todo Access to extendable methods/relations like SiteTree/1/Versions or SiteTree/1/Version/22
|
||||
* @todo Respect $api_access array notation in search contexts
|
||||
*/
|
||||
class RestfulServer extends Controller
|
||||
{
|
||||
@ -102,6 +119,7 @@ class RestfulServer extends Controller
|
||||
{
|
||||
/* This sets up SiteTree the same as when viewing a page through the frontend. Versioned defaults
|
||||
* to Stage, and then when viewing the front-end Versioned::choose_site_stage changes it to Live.
|
||||
* TODO: In 3.2 we should make the default Live, then change to Stage in the admin area (with a nicer API)
|
||||
*/
|
||||
if (class_exists(SiteTree::class)) {
|
||||
singleton(SiteTree::class)->extend('modelascontrollerInit', $this);
|
||||
@ -244,6 +262,8 @@ class RestfulServer extends Controller
|
||||
* - static $api_access must be set. This enables the API on a class by class basis
|
||||
* - $obj->canView() must return true. This lets you implement record-level security
|
||||
*
|
||||
* @todo Access checking
|
||||
*
|
||||
* @param string $className
|
||||
* @param int $id
|
||||
* @param string $relation
|
||||
@ -299,6 +319,7 @@ class RestfulServer extends Controller
|
||||
return $this->notFound();
|
||||
}
|
||||
|
||||
// TODO Avoid creating data formatter again for relation class (see above)
|
||||
$responseFormatter = $this->getResponseDataFormatter($obj->dataClass());
|
||||
}
|
||||
} else {
|
||||
@ -341,6 +362,8 @@ class RestfulServer extends Controller
|
||||
* an existing query object (mostly a component query from {@link DataObject})
|
||||
* with search clauses.
|
||||
*
|
||||
* @todo Allow specifying of different searchcontext getters on model-by-model basis
|
||||
*
|
||||
* @param string $className
|
||||
* @param array $params
|
||||
* @return SS_List
|
||||
@ -533,6 +556,9 @@ class RestfulServer extends Controller
|
||||
/**
|
||||
* Handler for object append / method call.
|
||||
*
|
||||
* @todo Posting to an existing URL (without a relation)
|
||||
* current resolves in creatig a new element,
|
||||
* rather than a "Conflict" message.
|
||||
*/
|
||||
protected function postHandler($className, $id, $relation)
|
||||
{
|
||||
@ -652,6 +678,7 @@ class RestfulServer extends Controller
|
||||
$data[$newkey] = $value;
|
||||
}
|
||||
|
||||
// @todo Disallow editing of certain keys in database
|
||||
$data = array_diff_key($data ?? [], ['ID', 'Created']);
|
||||
|
||||
$apiAccess = singleton($className)->config()->api_access;
|
||||
@ -839,6 +866,7 @@ 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
|
||||
|
@ -7,6 +7,13 @@ use SilverStripe\RestfulServer\Tests\Stubs\JSONDataFormatterTypeTestObject;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\RestfulServer\DataFormatter\JSONDataFormatter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @todo Test Relation getters
|
||||
* @todo Test filter and limit through GET params
|
||||
* @todo Test DELETE verb
|
||||
*
|
||||
*/
|
||||
class JSONDataFormatterTest extends SapphireTest
|
||||
{
|
||||
protected static $fixture_file = 'JSONDataFormatterTest.yml';
|
||||
|
@ -22,6 +22,13 @@ use Page;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\RestfulServer\DataFormatter\XMLDataFormatter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @todo Test Relation getters
|
||||
* @todo Test filter and limit through GET params
|
||||
* @todo Test DELETE verb
|
||||
*
|
||||
*/
|
||||
class RestfulServerTest extends SapphireTest
|
||||
{
|
||||
protected static $fixture_file = 'RestfulServerTest.yml';
|
||||
@ -94,6 +101,7 @@ class RestfulServerTest extends SapphireTest
|
||||
$thing1 = $this->objFromFixture(RestfulServerTestSecretThing::class, 'thing1');
|
||||
$comment1 = $this->objFromFixture(RestfulServerTestComment::class, 'comment1');
|
||||
|
||||
// @todo create additional mock object with authenticated VIEW permissions
|
||||
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestSecretThing::class);
|
||||
$url = "{$this->baseURI}/api/v1/$urlSafeClassname/" . $thing1->ID;
|
||||
$response = Director::test($url, null, null, 'GET');
|
||||
@ -150,6 +158,7 @@ class RestfulServerTest extends SapphireTest
|
||||
$rating1 = $this->objFromFixture(RestfulServerTestAuthorRating::class, 'rating1');
|
||||
$rating2 = $this->objFromFixture(RestfulServerTestAuthorRating::class, 'rating2');
|
||||
|
||||
// @todo should be set up by fixtures, doesn't work for some reason...
|
||||
$author1->Ratings()->add($rating1);
|
||||
$author1->Ratings()->add($rating2);
|
||||
|
||||
@ -178,6 +187,7 @@ class RestfulServerTest extends SapphireTest
|
||||
$author1 = $this->objFromFixture(RestfulServerTestAuthor::class, 'author1');
|
||||
$rating1 = $this->objFromFixture(RestfulServerTestAuthorRating::class, 'rating1');
|
||||
|
||||
// @todo should be set up by fixtures, doesn't work for some reason...
|
||||
$author1->Ratings()->add($rating1);
|
||||
|
||||
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestAuthor::class);
|
||||
|
Loading…
Reference in New Issue
Block a user