From e2246853fa4bbf1620ccfe1e60722fb3e2ecefe9 Mon Sep 17 00:00:00 2001 From: absszero Date: Sun, 25 Sep 2016 15:24:06 +0800 Subject: [PATCH 1/3] fix array not convert to json format --- composer.json | 3 ++- src/Torann/RemoteModel/Model.php | 15 +++++++++++++++ tests/ModelTest.php | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index fe32700..7aa0750 100755 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ }, "require-dev": { "phpunit/phpunit": "^4.8", - "mockery/mockery": "^0.9.4" + "mockery/mockery": "^0.9.4", + "orchestra/testbench": "^3.3" }, "autoload": { "psr-4": { diff --git a/src/Torann/RemoteModel/Model.php b/src/Torann/RemoteModel/Model.php index cde04d9..0eaa097 100644 --- a/src/Torann/RemoteModel/Model.php +++ b/src/Torann/RemoteModel/Model.php @@ -230,6 +230,17 @@ public static function setDateFormat($format) Date::setToStringFormat($format); } + /** + * Encode the given value as JSON. + * + * @param mixed $value + * @return string + */ + protected function asJson($value) + { + return json_encode($value); + } + /** * Get the value of the model's primary key. * @@ -1444,6 +1455,10 @@ public function setAttribute($key, $value) return $this->{'set' . studly_case($key) . 'Attribute'}($value); } + if ($this->isJsonCastable($key) && ! is_null($value)) { + $value = $this->asJson($value); + } + $this->attributes[$key] = $value; } diff --git a/tests/ModelTest.php b/tests/ModelTest.php index 0206575..fdfa1ce 100644 --- a/tests/ModelTest.php +++ b/tests/ModelTest.php @@ -2,7 +2,7 @@ use Carbon\Carbon; -class ModelTest extends PHPUnit_Framework_TestCase +class ModelTest extends Orchestra\Testbench\TestCase { public function testAttributeManipulation() { From 01dec13067aabafbb4700dc971d3658f948b66df Mon Sep 17 00:00:00 2001 From: absszero Date: Sun, 25 Sep 2016 17:49:57 +0800 Subject: [PATCH 2/3] use get method to implement find, first and all method get, find, first and all methods use the same function signature by Illuminate\Database\Eloquent\Builder --- src/Torann/RemoteModel/Model.php | 188 +++++++++++++++++-------------- tests/ModelTest.php | 26 ++--- tests/stubs/EndpointStub.php | 84 ++++++++------ 3 files changed, 163 insertions(+), 135 deletions(-) diff --git a/src/Torann/RemoteModel/Model.php b/src/Torann/RemoteModel/Model.php index 0eaa097..c2dea89 100644 --- a/src/Torann/RemoteModel/Model.php +++ b/src/Torann/RemoteModel/Model.php @@ -7,13 +7,29 @@ use JsonSerializable; use Jenssegers\Date\Date; use Illuminate\Support\Arr; +use Illuminate\Support\Collection; use Illuminate\Http\UploadedFile; use Illuminate\Contracts\Support\Jsonable; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Pagination\Paginator; use Illuminate\Pagination\LengthAwarePaginator; abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable { + /** + * The url query data + * + * @var array + */ + protected $query = []; + + /** + * pagination + * + * @var array + */ + protected $pagination = []; + /** * The client associated with the model. * @@ -368,37 +384,6 @@ public function newInstance($attributes = [], $exists = false) return $model; } - /** - * Create a collection of models from plain arrays. - * - * @param array $items - * @return array - */ - public static function hydrate(array $items, $class = null) - { - $items = array_map(function ($item) use ($class) { - // Single class given - if (gettype($class) === 'string') { - return new $class($item); - } - - // Map an array of classes - if (gettype($class) === 'array') { - - if (isset($item['type']) && isset($class[$item['type']])) { - return new $class[$item['type']]($item); - } - - return null; - } - - return new static($item, static::getParentID()); - - }, $items); - - return array_filter($items); - } - /** * Paginate items. * @@ -432,24 +417,33 @@ public function paginateHydrate($result, $modelClass = null) 'last' ]) : []; - return new LengthAwarePaginator($this->hydrate($items, $modelClass), $total, $perPage, $currentPage, - array_merge($options, [ - 'path' => LengthAwarePaginator::resolveCurrentPath() - ])); + return new LengthAwarePaginator( + $items, + $total, + $perPage, + $currentPage, + array_merge( + $options, + [ + 'path' => LengthAwarePaginator::resolveCurrentPath(), +// 'pageName' => $pageName, + ] + ) + ); } /** * Execute the query and get the first result. * * @param string $id - * @param array $params + * @param array $columns * @return mixed|static */ - public static function find($id, array $params = []) + public static function find($id, $columns = ['*']) { $instance = new static([], static::getParentID()); - return $instance->request($instance->getEndpoint(), 'find', [$id, $params]); + return $instance->where($instance->getKeyName(), $id)->first($columns); } /** @@ -470,54 +464,59 @@ public static function create(array $attributes = []) /** * Make an all paginated request. * - * @param array $params - * @return \Illuminate\Pagination\LengthAwarePaginator + * @param array $columns + * @return \Illuminate\Support\Collection|static[] */ - public static function all(array $params = []) + public static function all(array $columns = ['*']) { - // Remove empty params - $params = array_filter($params); - $instance = new static([], static::getParentID()); - // Make request - $result = $instance->makeRequest($instance->getEndpoint(), 'all', [$params]); - - // Hydrate object - $result = $instance->paginateHydrate($result); - - // Append search params - $result->appends($params); - - return $result; + return $instance->get($columns); } /** - * Paginate request. + * Get Pagination * - * @param string $method - * @param array $params - * @return \Illuminate\Pagination\LengthAwarePaginator + * @return array */ - public static function paginate($method, array $params = []) + public function getPagination() { - // Set request params - $params = array_filter(array_merge([ - 'page' => 1 - ], $params)); - - $instance = new static([], static::getParentID());; - - // Make request - $result = $instance->makeRequest($instance->getEndpoint(), $method, [$params]); - - // Hydrate object - $result = $instance->paginateHydrate($result); + return $this->pagination; + } - // Append search params - $result->appends($params); + /** + * Paginate the given query. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * + * @throws \InvalidArgumentException + */ + public static function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) + { + $instance = new static([], static::getParentID()); - return $result; + if ($perPage) { + $instance->take($perPage); + } + $instance->query['_page'] = $page ?: Paginator::resolveCurrentPage($pageName); + + $items = $instance->get($columns); + $pagination = $instance->getPagination(); + + return new LengthAwarePaginator( + $items, + $pagination['total'], + $pagination['per_page'], + $pagination['current_page'], + [ + 'path' => Paginator::resolveCurrentPath(), + 'pageName' => $pageName, + ] + ); } /** @@ -904,13 +903,21 @@ public function getClientError() /** * Execute the query and get the first result. * - * @param string $id - * @param array $params - * @return mixed|static + * @param array $columns + * @return \Illuminate\Support\Collection|static[] */ - public function get($id, array $params = []) + public function get($columns = ['*']) { - return $this->request($this->getEndpoint(), 'find', [$id, $params]); + $this->query['_columns'] = $columns; + $results = $this->makeRequest($this->getEndpoint(), 'get', [$this->query]); + $items = array_pull($results, 'data'); + $this->pagination = $results; + + $collection = collect($items)->map(function ($item, $key) { + return $this->newInstance($item, true); + }); + + return $collection; } /** @@ -1057,28 +1064,37 @@ public function getRouteKey() */ public function where($column, $value = null) { - $this->setAttribute($column, $value); + $this->query[$column] = $value; + return $this; + } + /** + * Set the "limit" value of the query. + * + * @param int $value + * @return $this + */ + public function take($value) + { + $this->query['_take'] = $value; return $this; } /** * Execute the query and get the first result. * - * NOTE: Used for route binding - * * @return mixed|static */ - public function first() + public function first($columns = ['*']) { - $result = $this->get($this->getRouteKey()); + $result = $this->take(1)->get($columns); // After route event if ($result && method_exists($result, 'afterRoute')) { $result->afterRoute(); } - return $result; + return count($result) > 0 ? $result->pop() : null; } /** @@ -1771,7 +1787,7 @@ protected function request($endpoint = null, $method, $params) * * @return mixed */ - protected function makeRequest($endpoint = null, $method, $params) + protected function makeRequest($endpoint, $method, $params) { $endpoint = $endpoint ?: $this->getEndpoint(); diff --git a/tests/ModelTest.php b/tests/ModelTest.php index fdfa1ce..d1bf4a5 100644 --- a/tests/ModelTest.php +++ b/tests/ModelTest.php @@ -204,48 +204,48 @@ public function testStaticCreateMethod() public function testStaticFindMethod() { + $rawData = (new EndpointStub)->get(['_take'=>1])['data'][0]; + ModelStub::setClient(new ClientStub); - $model = ModelStub::find(1); - $this->assertEquals(1, $model->id); + $model = ModelStub::find($rawData['id']); + $this->assertEquals($rawData['id'], $model->id); } public function testStaticAllMethod() { ModelStub::setClient(new ClientStub); + $total = count((new EndpointStub)->get([])['data']); $model = ModelStub::all(); - $this->assertEquals(1, $model->count()); + $this->assertEquals($total, $model->count()); } public function testStaticPaginateMethod() { ModelStub::setClient(new ClientStub); + $total = count((new EndpointStub)->get([])['data']); - $model = ModelStub::paginate('paginateTest'); - $this->assertEquals(2, $model->count()); + $model = ModelStub::paginate(); + $this->assertEquals($total, $model->count()); } public function testUpdateMethod() { ModelStub::setClient(new ClientStub); - + $rawData = (new EndpointStub)->get(['_take'=>1])['data'][0]; $model = ModelStub::find(1); $model->update([ 'name' => 'John Doe' ]); - - $this->assertEquals([ - 'id' => 1, - 'name' => 'John Doe' - ], $model->getAttributes()); + $rawData['name'] = 'John Doe'; + $this->assertEquals($rawData, $model->getAttributes()); } public function testPaginateHydrateMethod() { ModelStub::setClient(new ClientStub); - $model = ModelStub::find(1); $newModel = $model->paginateHydrate([ @@ -263,4 +263,4 @@ public function testPaginateHydrateMethod() $this->assertEquals(1, $newModel->count()); } -} \ No newline at end of file +} diff --git a/tests/stubs/EndpointStub.php b/tests/stubs/EndpointStub.php index 60df209..512a977 100644 --- a/tests/stubs/EndpointStub.php +++ b/tests/stubs/EndpointStub.php @@ -2,13 +2,6 @@ class EndpointStub { - public function find($id) - { - return [ - 'id' => $id - ]; - } - public function create(array $params) { return $params; @@ -19,38 +12,57 @@ public function update($id, array $params) return $params; } - public function all(array $params) + public function get(array $params) { - return [ - 'pagination' => [ - 'next' => '', - 'perPage' => 15, - 'last' => 1 + $request = [ + 'total' => 10, + 'per_page' => 3, + 'current_page' => 1, + 'last_page' => 4, + 'next_page_url' => null, + 'prev_page_url' => null, + 'from' => 1, + 'to' => 10, + 'data' => + [ + 0 => + [ + 'id' => 11, + 'username' => 'austin45', + 'first_name' => 'Nolan', + 'last_name' => 'Wisozk', + 'email' => 'alf.leannon@stark.com', + 'created_at' => '2015-03-05 14:04:28', + 'updated_at' => '2015-03-05 14:04:28', + ], + 1 => + [ + 'id' => 12, + 'username' => 'heidenreich.jesse', + 'first_name' => 'Sydnie', + 'last_name' => 'Hand', + 'email' => 'rturcotte@gmail.com', + 'created_at' => '2015-03-05 14:04:28', + 'updated_at' => '2015-03-05 14:04:28', ], - 'items' => [ - [ - 'name' => 'John Doe' - ] + 2 => + [ + 'id' => 13, + 'username' => 'doyle.bradford', + 'first_name' => 'German', + 'last_name' => 'Hintz', + 'email' => 'sienna.kreiger@hotmail.com', + 'created_at' => '2015-03-05 14:04:28', + 'updated_at' => '2015-03-05 14:04:28', ] + ] ]; - } - public function paginateTest(array $params) - { - return [ - 'pagination' => [ - 'next' => '', - 'perPage' => 15, - 'last' => 1 - ], - 'items' => [ - [ - 'name' => 'John Doe' - ], - [ - 'name' => 'Jone Doe' - ] - ] - ]; + $take = array_get($params, '_take'); + if ($take) { + $request['data'] = array_slice($request['data'], 0, $take); + } + + return $request; } -} \ No newline at end of file +} From 60b544d34c021f880c2fd53b6eab6ee9fbc5d3f2 Mon Sep 17 00:00:00 2001 From: absszero Date: Sun, 25 Sep 2016 17:56:51 +0800 Subject: [PATCH 3/3] change findOrFail method called by find method --- src/Torann/RemoteModel/Model.php | 16 ++++++---------- tests/ModelTest.php | 4 ++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Torann/RemoteModel/Model.php b/src/Torann/RemoteModel/Model.php index c2dea89..1371b6f 100644 --- a/src/Torann/RemoteModel/Model.php +++ b/src/Torann/RemoteModel/Model.php @@ -426,7 +426,6 @@ public function paginateHydrate($result, $modelClass = null) $options, [ 'path' => LengthAwarePaginator::resolveCurrentPath(), -// 'pageName' => $pageName, ] ) ); @@ -523,22 +522,19 @@ public static function paginate($perPage = null, $columns = ['*'], $pageName = ' * Find a model by its primary key or throw an exception * * @param string $id - * @param array $params + * @param array $columns * @return mixed|static * * @throws \Torann\RemoteModel\NotFoundException */ - public static function findOrFail($id, array $params = []) + public static function findOrFail($id, $columns = ['*']) { - $instance = new static([], static::getParentID()); - - // Make request - if (!is_null($result = $instance->request($instance->getEndpoint(), 'find', [$id, $params]))) { - return $result; + $result = static::find($id, $columns); + if (is_null($result)) { + throw new NotFoundException; } - // Not found - throw new NotFoundException; + return $result; } /** diff --git a/tests/ModelTest.php b/tests/ModelTest.php index d1bf4a5..d816185 100644 --- a/tests/ModelTest.php +++ b/tests/ModelTest.php @@ -202,13 +202,13 @@ public function testStaticCreateMethod() $this->assertEquals($params, $model->getAttributes()); } - public function testStaticFindMethod() + public function testStaticFindOrFailMethod() { $rawData = (new EndpointStub)->get(['_take'=>1])['data'][0]; ModelStub::setClient(new ClientStub); - $model = ModelStub::find($rawData['id']); + $model = ModelStub::findOrFail($rawData['id']); $this->assertEquals($rawData['id'], $model->id); }