Skip to content

Commit

Permalink
Merge pull request #529 from bravo-kernel/dasherize-relationships
Browse files Browse the repository at this point in the history
Dasherize JSON API relationships node
  • Loading branch information
josegonzalez authored May 2, 2017
2 parents 70753e5 + e11e349 commit 2bbe099
Show file tree
Hide file tree
Showing 24 changed files with 457 additions and 25 deletions.
4 changes: 2 additions & 2 deletions docs/listeners/jsonapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ might request ``/countries/2?include=cultures,currencies`` to achieve the
same response. If the include parameter is provided, then only requested
relationships will be included in the ``included`` schema.

It is possible blacklist, or whitelist what the client is allowed to include.
It is possible to blacklist, or whitelist what the client is allowed to include.
This is done using the listener configuration:

.. code-block:: php
Expand Down Expand Up @@ -788,7 +788,7 @@ and then simply use search aliases named ``filter`` like shown below:
}
Please note that not
`all filtering options <https://github.com/FriendsOfCake/crud/issues/524`_
`all filtering options <https://github.com/FriendsOfCake/crud/issues/524>`_
have been implemented yet.

Schemas
Expand Down
2 changes: 2 additions & 0 deletions src/Listener/JsonApiListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ protected function _getAssociation(RepositoryInterface $repository, $include)
* @param array|bool $blacklist Blacklisted includes
* @param array|bool $whitelist Whitelisted options
* @param \Cake\ORM\Table|null $repository The repository
* @param array $path Include path
* @return string
* @throws \Cake\Network\Exception\BadRequestException
*/
Expand Down Expand Up @@ -658,6 +659,7 @@ protected function _getRepositoryList(RepositoryInterface $repository, $associat
* config option 'include'.
*
* @param \Cake\ORM\AssociationCollection $associations AssociationCollection
* @param bool $last What does this do?
* @return array
* @throws \InvalidArgumentException
*/
Expand Down
16 changes: 16 additions & 0 deletions src/Schema/JsonApi/DynamicEntitySchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ public function getRelationships($entity, $isPrimary, array $includeRelationship
continue;
}

// change related data in entity to dasherized if need be
if ($this->_view->viewVars['_inflect'] === 'dasherize') {
$dasherizedProperty = Inflector::dasherize($property);

if (empty($entity->$dasherizedProperty)) {
$entity->$dasherizedProperty = $entity->$property;
unset($entity->$property);
$property = $dasherizedProperty;
}
}

$relations[$property] = [
self::DATA => $data,
self::SHOW_SELF => true,
Expand Down Expand Up @@ -181,6 +192,10 @@ public function getSelfSubUrl($entity = null)
*/
public function getRelationshipSelfLink($entity, $name, $meta = null, $treatAsHref = false)
{
if ($this->_view->viewVars['_inflect'] === 'dasherize') {
$name = Inflector::underscore($name);
}

$association = $this->_repository->associations()->getByProperty($name);
$relatedRepository = $association->target();

Expand All @@ -198,6 +213,7 @@ public function getRelationshipSelfLink($entity, $name, $meta = null, $treatAsHr
'type' => $name,
], $this->_view->viewVars['_absoluteLinks']);
} else {
$name = Inflector::dasherize($name);
$relatedEntity = $entity[$name];

$url = Router::url($this->_getRepositoryRoutingParameters($relatedRepository) + [
Expand Down
17 changes: 17 additions & 0 deletions src/View/JsonApiView.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Cake\Event\EventManager;
use Cake\Network\Request;
use Cake\Network\Response;
use Cake\Utility\Inflector;
use Cake\View\View;
use Crud\Error\Exception\CrudException;
use Neomerx\JsonApi\Document\Link;
Expand Down Expand Up @@ -117,6 +118,10 @@ protected function _encodeWithoutSchemas()
*/
protected function _encodeWithSchemas()
{
if ($this->viewVars['_inflect'] === 'dasherize') {
$this->_dasherizeIncludesViewVar();
}

$schemas = $this->_entitiesToNeoMerxSchema($this->viewVars['_repositories']);

// Please note that a third NeoMerx EncoderOptions argument `depth`
Expand Down Expand Up @@ -353,4 +358,16 @@ protected function _jsonOptions()

return $jsonOptions;
}

/**
* Dasherizes all values in the '_includes` viewVar array.
*
* @return void
*/
protected function _dasherizeIncludesViewVar()
{
foreach ($this->viewVars['_include'] as $key => $value) {
$this->viewVars['_include'][$key] = Inflector::dasherize($value);
}
}
}
7 changes: 7 additions & 0 deletions tests/App/Model/Entity/NationalCapital.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
namespace Crud\Test\App\Model\Entity;

class NationalCapital extends \Cake\ORM\Entity
{

}
7 changes: 7 additions & 0 deletions tests/App/Model/Entity/NationalCity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
namespace Crud\Test\App\Model\Entity;

class NationalCity extends \Cake\ORM\Entity
{

}
2 changes: 2 additions & 0 deletions tests/App/Model/Table/CountriesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ class CountriesTable extends Table
public function initialize(array $config)
{
$this->belongsTo('Currencies');
$this->belongsTo('NationalCapitals');

$this->hasMany('Cultures');
$this->hasMany('NationalCities');
}

public function validationDefault(Validator $validator)
Expand Down
10 changes: 10 additions & 0 deletions tests/App/Model/Table/NationalCapitalsTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace Crud\Test\App\Model\Table;

class NationalCapitalsTable extends \Cake\ORM\Table
{
public function initialize(array $config)
{
$this->belongsTo('Countries');
}
}
10 changes: 10 additions & 0 deletions tests/App/Model/Table/NationalCitiesTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace Crud\Test\App\Model\Table;

class NationalCitiesTable extends \Cake\ORM\Table
{
public function initialize(array $config)
{
$this->belongsTo('Countries');
}
}
5 changes: 3 additions & 2 deletions tests/Fixture/CountriesFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ class CountriesFixture extends TestFixture
'code' => ['type' => 'string', 'length' => 2, 'null' => false],
'name' => ['type' => 'string', 'length' => 255, 'null' => false],
'currency_id' => ['type' => 'integer', 'null' => false],
'national_capital_id' => ['type' => 'integer', 'null' => false],
'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]],
];

public $records = [
['code' => 'NL', 'name' => 'The Netherlands', 'currency_id' => 1],
['code' => 'BE', 'name' => 'Belgium', 'currency_id' => 1],
['code' => 'NL', 'name' => 'The Netherlands', 'currency_id' => 1, 'national_capital_id' => 1],
['code' => 'BE', 'name' => 'Belgium', 'currency_id' => 1, 'national_capital_id' => 2]
];
}
2 changes: 1 addition & 1 deletion tests/Fixture/CulturesFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class CulturesFixture extends TestFixture
public $fields = [
'id' => ['type' => 'integer'],
'code' => ['type' => 'string', 'length' => 5, 'null' => false],
'name' => ['type' => 'string', 'length' => 255, 'null' => false],
'name' => ['type' => 'string', 'length' => 100, 'null' => false],
'country_id' => ['type' => 'integer', 'null' => false],
'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]],
];
Expand Down
2 changes: 1 addition & 1 deletion tests/Fixture/CurrenciesFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class CurrenciesFixture extends TestFixture
public $fields = [
'id' => ['type' => 'integer'],
'code' => ['type' => 'string', 'length' => 3, 'null' => false],
'name' => ['type' => 'string', 'length' => 255, 'null' => false],
'name' => ['type' => 'string', 'length' => 100, 'null' => false],
'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]],
];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"data": {
"type": "countries",
"id": "1",
"attributes": {
"code": "NL",
"name": "The Netherlands"
},
"relationships": {
"currency": {
"data": {
"type": "currencies",
"id": "1"
},
"links": {
"self": "\/currencies\/1"
}
},
"national-capital": {
"data": {
"type": "national-capitals",
"id": "1"
},
"links": {
"self": "\/national-capitals\/1"
}
},
"cultures": {
"data": [
{
"type": "cultures",
"id": "1"
}
],
"links": {
"self": "\/cultures?country_id=1"
}
},
"national-cities": {
"data": [
{
"type": "national-cities",
"id": "1"
},
{
"type": "national-cities",
"id": "2"
}
],
"links": {
"self": "\/national-cities?country_id=1"
}
}
},
"links": {
"self": "\/countries\/1"
}
},
"included": [
{
"type": "currencies",
"id": "1",
"attributes": {
"code": "EUR",
"name": "Euro"
},
"links": {
"self": "\/currencies\/1"
}
},
{
"type": "national-capitals",
"id": "1",
"attributes": {
"name": "Amsterdam",
"description": "National capital of the Netherlands"
},
"links": {
"self": "\/national-capitals\/1"
}
},
{
"type": "cultures",
"id": "1",
"attributes": {
"code": "nl-NL",
"name": "Dutch"
},
"links": {
"self": "\/cultures\/1"
}
},
{
"type": "national-cities",
"id": "1",
"attributes": {
"name": "Amsterdam"
},
"links": {
"self": "\/national-cities\/1"
}
},
{
"type": "national-cities",
"id": "2",
"attributes": {
"name": "Rotterdam"
},
"links": {
"self": "\/national-cities\/2"
}
}
]
}
37 changes: 37 additions & 0 deletions tests/Fixture/JsonApi/get_country_include_national-capital.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"data": {
"type": "countries",
"id": "1",
"attributes": {
"code": "NL",
"name": "The Netherlands"
},
"relationships": {
"national-capital": {
"data": {
"type": "national-capitals",
"id": "1"
},
"links": {
"self": "\/national-capitals\/1"
}
}
},
"links": {
"self": "\/countries\/1"
}
},
"included": [
{
"type": "national-capitals",
"id": "1",
"attributes": {
"name": "Amsterdam",
"description": "National capital of the Netherlands"
},
"links": {
"self": "\/national-capitals\/1"
}
}
]
}
Loading

0 comments on commit 2bbe099

Please sign in to comment.