Skip to content

Instantly share code, notes, and snippets.

@andrewmclagan
Created April 8, 2016 02:08
Show Gist options
  • Save andrewmclagan/c5e0fe601d23f3b859b89a9f8922be68 to your computer and use it in GitHub Desktop.
Save andrewmclagan/c5e0fe601d23f3b859b89a9f8922be68 to your computer and use it in GitHub Desktop.
Dingo API - Eloquent model attributes as camel case
<?php
namespace App\Http;
use Illuminate\Support\Str;
use Dingo\Api\Http\Response\Format\Json as JsonFormatter;
/**
* Formats json API responses
*
* @author Andrew McLagan <andrew@ethicaljobs.com.au>
*/
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;
}
}
<?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