Many many through syntax support added.

This commit is contained in:
Mojmir Fendek 2018-04-06 11:10:32 +12:00
parent 5f7861e0ac
commit a60751bd74
6 changed files with 83 additions and 0 deletions

View File

@ -2,6 +2,7 @@
namespace SilverStripe\RestfulServer\DataFormatter;
use SilverStripe\RestfulServer\RestfulServer;
use SilverStripe\View\ArrayData;
use SilverStripe\Core\Convert;
use SilverStripe\RestfulServer\DataFormatter;
@ -121,6 +122,8 @@ class JSONDataFormatter extends DataFormatter
}
foreach ($obj->hasMany() + $obj->manyMany() as $relName => $relClass) {
$relClass = RestfulServer::parseRelationClass($relClass);
//remove dot notation from relation names
$parts = explode('.', $relClass);
$relClass = array_shift($parts);

View File

@ -10,6 +10,7 @@ use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\Control\Director;
use SilverStripe\ORM\SS_List;
use SilverStripe\RestfulServer\RestfulServer;
/**
* Formats a DataObject's member fields into an XML string
@ -196,6 +197,8 @@ class XMLDataFormatter extends DataFormatter
}
foreach ($obj->manyMany() as $relName => $relClass) {
$relClass = RestfulServer::parseRelationClass($relClass);
//remove dot notation from relation names
$parts = explode('.', $relClass);
$relClass = array_shift($parts);

View File

@ -122,6 +122,32 @@ class RestfulServer extends Controller
return str_replace('-', '\\', $className);
}
/**
* Parse many many relation class (works with through array syntax)
*
* @param string|array $class
* @return string|array
*/
public static function parseRelationClass($class)
{
// detect many many through syntax
if (is_array($class)
&& array_key_exists('through', $class)
&& array_key_exists('to', $class)
) {
$toRelation = $class['to'];
$hasOne = Config::inst()->get($class['through'], 'has_one');
if (empty($hasOne) || !is_array($hasOne) || !array_key_exists($toRelation, $hasOne)) {
return $class;
}
return $hasOne[$toRelation];
}
return $class;
}
/**
* This handler acts as the switchboard for the controller.
* Since no $Action url-param is set, all requests are sent here.
@ -802,6 +828,8 @@ class RestfulServer extends Controller
$relations = (array)$obj->hasOne() + (array)$obj->hasMany() + (array)$obj->manyMany();
if ($relations) {
foreach ($relations as $relName => $relClass) {
$relClass = static::parseRelationClass($relClass);
//remove dot notation from relation names
$parts = explode('.', $relClass);
$relClass = array_shift($parts);

View File

@ -2,6 +2,7 @@
namespace SilverStripe\RestfulServer\Tests;
use SilverStripe\RestfulServer\RestfulServer;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestComment;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestExceptionThrown;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestSecretThing;
@ -701,4 +702,17 @@ class RestfulServerTest extends SapphireTest
$responseArr = Convert::xml2array($response->getBody());
$this->assertEquals(\Exception::class, $responseArr['type']);
}
public function testParseClassName()
{
$manyMany = RestfulServerTestAuthor::config()->get('many_many');
// simple syntax (many many standard)
$className = RestfulServer::parseRelationClass($manyMany['RelatedPages']);
$this->assertEquals(RestfulServerTestPage::class, $className);
// array syntax (many many through)
$className = RestfulServer::parseRelationClass($manyMany['SortedPages']);
$this->assertEquals(RestfulServerTestPage::class, $className);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace SilverStripe\RestfulServer\Tests\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class AuthorSortedPageRelation extends DataObject implements TestOnly
{
/**
* @var string
*/
private static $table_name = 'AuthorSortedPageRelation';
/**
* @var array
*/
private static $has_one = [
'Parent' => RestfulServerTestAuthor::class,
'SortedPage' => RestfulServerTestPage::class,
];
/**
* @var array
*/
private static $db = [
'Sort' => 'Int',
];
}

View File

@ -18,11 +18,17 @@ class RestfulServerTestAuthor extends DataObject implements TestOnly
private static $many_many = array(
'RelatedPages' => RestfulServerTestPage::class,
'RelatedAuthors' => RestfulServerTestAuthor::class,
'SortedPages' => [
'through' => AuthorSortedPageRelation::class,
'from' => 'Parent',
'to' => 'SortedPage',
],
);
private static $has_many = array(
'PublishedPages' => RestfulServerTestPage::class,
'Ratings' => RestfulServerTestAuthorRating::class,
'SortedPagesRelation' => AuthorSortedPageRelation::class . '.Parent',
);
public function canView($member = null)