Created
April 8, 2016 02:08
-
-
Save andrewmclagan/c5e0fe601d23f3b859b89a9f8922be68 to your computer and use it in GitHub Desktop.
Dingo API - Eloquent model attributes as camel case
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http; | |
use Illuminate\Support\Str; | |
use Dingo\Api\Http\Response\Format\Json as JsonFormatter; | |
/** | |
* Formats json API responses | |
* | |
* @author Andrew McLagan <[email protected]> | |
*/ | |
class ResponseFormatter extends JsonFormatter | |
{ | |
/** | |
* Format an Eloquent model. | |
* | |
* @param \Illuminate\Database\Eloquent\Model $model | |
* | |
* @return string | |
*/ | |
public function formatEloquentModel($model) | |
{ | |
$key = Str::camel(Str::singular($model->getTable())); | |
$formattedModel = $this->camelCaseKeys($model->toArray()); | |
return $this->encode([$key => $formattedModel]); | |
} | |
/** | |
* Format an Eloquent collection. | |
* | |
* @param \Illuminate\Database\Eloquent\Collection $collection | |
* | |
* @return string | |
*/ | |
public function formatEloquentCollection($collection) | |
{ | |
if ($collection->isEmpty()) { | |
return $this->encode([]); | |
} | |
$model = $collection->first(); | |
$key = Str::camel(Str::plural($model->getTable())); | |
$formattedCollection = $this->camelCaseKeys($collection->toArray()); | |
return $this->encode([$key => $formattedCollection]); | |
} | |
/** | |
* Format an array or instance implementing Arrayable. | |
* | |
* @param array|\Illuminate\Contracts\Support\Arrayable $content | |
* | |
* @return string | |
*/ | |
public function formatArray($content) | |
{ | |
$result = []; | |
$content = $this->morphToArrayRecursive($content, $result); | |
return $this->encode($content); | |
} | |
/** | |
* Morph a value to an array. | |
* | |
* @param array|\Illuminate\Contracts\Support\Arrayable $value | |
* | |
* @return array | |
*/ | |
public function morphToArrayRecursive($array, $result) | |
{ | |
foreach ($array as $key => $item) { | |
if (is_array($this->morphToArray($item))) { | |
$result[Str::camel($key)] = $this->morphToArrayRecursive($this->morphToArray($item), $result); | |
} else { | |
$result[Str::camel($key)] = $this->morphToArray($item); | |
} | |
} | |
return $result; | |
} | |
/** | |
* Converts an arrays keys to camel case | |
* | |
* @param Array $array | |
* | |
* @return Array | |
*/ | |
protected function camelCaseKeys(Array $array) | |
{ | |
$formatted = []; | |
foreach ($array as $key => $value) { | |
if (is_array($value)) { | |
$formatted[Str::camel($key)] = $this->camelCaseKeys($value); | |
} else { | |
$formatted[Str::camel($key)] = $value; | |
} | |
} | |
return $formatted; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Foundation\Testing\DatabaseMigrations; | |
use App\Http\ResponseFormatter; | |
class ResponseFormatterTest extends TestCase | |
{ | |
/** | |
* Run before all tests | |
* | |
* @return Void | |
*/ | |
public function setUp() | |
{ | |
parent::setUp(); | |
$this->formatter = new ResponseFormatter; | |
} | |
/** | |
* @test | |
*/ | |
public function it_returns_json_responses() | |
{ | |
$user = factory(App\User\Eloquent\User::class)->make(); | |
json_decode($this->formatter->formatEloquentModel($user)); | |
$this->assertTrue(json_last_error() == JSON_ERROR_NONE); | |
$collection = factory(App\User\Eloquent\User::class, 5)->make(); | |
json_decode($this->formatter->formatEloquentCollection($collection)); | |
$this->assertTrue(json_last_error() == JSON_ERROR_NONE); | |
$array = [ | |
'foo_bar_bar' => 123, | |
'bar_foo_foo' => 456, | |
'fooFooFoo' => '789', | |
]; | |
json_decode($this->formatter->formatArray($array)); | |
$this->assertTrue(json_last_error() == JSON_ERROR_NONE); | |
} | |
/** | |
* @test | |
*/ | |
public function it_camel_cases_eloquent_model_attributes() | |
{ | |
$user = factory(App\User\Eloquent\User::class)->make(); | |
$formatted = $this->decode($this->formatter->formatEloquentModel($user)); | |
$this->assertTrue($formatted->user->firstName === $user->first_name); | |
$this->assertTrue($formatted->user->lastName === $user->last_name); | |
} | |
/** | |
* @test | |
*/ | |
public function it_camel_cases_eloquent_collections() | |
{ | |
$collection = factory(App\User\Eloquent\User::class, 5)->make(); | |
$formatted = $this->decode($this->formatter->formatEloquentCollection($collection)); | |
$collection = $collection->toArray(); | |
$this->assertTrue($formatted->users[0]->firstName === $collection[0]['first_name']); | |
$this->assertTrue($formatted->users[3]->firstName === $collection[3]['first_name']); | |
$this->assertTrue($formatted->users[1]->lastName === $collection[1]['last_name']); | |
$this->assertTrue($formatted->users[4]->lastName === $collection[4]['last_name']); | |
} | |
/** | |
* @test | |
*/ | |
public function it_camel_cases_arrays() | |
{ | |
$deepArray = [ | |
'snake_case_0' => [ | |
'snake_case_0' => 'bar', | |
'snake_case_1' => 'bar', | |
'InvalidCamelCase' => 'bar', | |
], | |
'snake_case_1' => [ | |
'snake_case_0' => [ | |
'snake_case_0' => [ | |
'snake_case_is_better' => 'bar' | |
], | |
'snake_case_1' => 'bar', | |
], | |
'snake_case_1' => 'bar', | |
'CamelCase' => 'bar', | |
], | |
]; | |
$formatted = $this->decode($this->formatter->formatArray($deepArray)); | |
dump($formatted); | |
$this->assertTrue($formatted->snakeCase0->invalidCamelCase === $deepArray['snake_case_0']['InvalidCamelCase']); | |
$this->assertTrue($formatted->snakeCase1->snakeCase0->snakeCase0->snakeCaseIsBetter === $deepArray['snake_case_1']['snake_case_0']['snake_case_0']['snake_case_is_better']); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment