diff --git a/src/Builders/Builder.php b/src/Builders/Builder.php index d390884..998f48e 100644 --- a/src/Builders/Builder.php +++ b/src/Builders/Builder.php @@ -1,19 +1,18 @@ parseFilters( $filters ); return $this->request->handleWithExceptions( function () use ( $urlFilters ) { - $response = $this->request->client->get( "{$this->entity}{$urlFilters}" ); + $response = $this->request->client->get( "{$this->entity}{$urlFilters}" ); + $fetchedItems = $this->getResponse( $response ); + return $this->populateModelsFromResponse( $fetchedItems->first() ); + } ); + } - $responseData = json_decode( (string) $response->getBody() ); - $fetchedItems = collect( $responseData ); - $items = collect( [] ); - $pages = $responseData->pages; - - foreach ( $fetchedItems->first() as $index => $item ) { + /** + * @param $response + * + * @return \Illuminate\Support\Collection|Model + */ + protected function populateModelsFromResponse( $response ) { + $items = collect(); + if ( is_iterable( $response ) ) { + foreach ( $response as $index => $item ) { + /** @var Model $model */ $modelClass = $this->getModelClass( $item ); $model = new $modelClass( $this->request, $item ); $items->push( $model ); } + } else { + $modelClass = $this->getModelClass( $response ); - return $items; - } ); - } - - protected function parseFilters( $filters = [] ) { - - $limit = array_search( 'limit', array_column( $filters, 0 ) ); - if ( $limit !== false && $limit !== ( count( $filters ) - 1 ) ) { - - unset( $filters[ count( $filters ) - 1 ] ); + return new $modelClass( $this->request, $response ); } - $urlFilters = ''; - - if ( count( $filters ) > 0 ) { - - $filters = array_unique( $filters, SORT_REGULAR ); - $i = 1; - - $urlFilters .= '?'; - - foreach ( $filters as $filter ) { - - $sign = ! empty( $filter[2] ) ? $filter[1] : '='; - $value = $filter[2] ?? $filter[1]; - - $urlFilters .= $filter[0] . $sign . urlencode( $value ); - - if ( count( $filters ) > $i ) { - - $urlFilters .= '&'; - } - - $i++; - } - } + return $items; - return $urlFilters; } /** @@ -107,16 +82,12 @@ protected function parseFilters( $filters = [] ) { */ public function all( $filters = [] ) { $page = 1; + $this->limit( 1000 ); $items = collect(); $response = function ( $filters, $page ) { - - /** - * Default filters, limit must be always set last otherwise it will not work - */ - $filters[] = [ 'page', '=', $page ]; - $filters[] = [ 'limit', '=', 1000 ]; + $this->page( $page ); $urlFilters = $this->parseFilters( $filters ); @@ -125,17 +96,9 @@ public function all( $filters = [] ) { $response = $this->request->client->get( "{$this->entity}{$urlFilters}" ); $responseData = json_decode( (string) $response->getBody() ); - $fetchedItems = collect( $responseData ); - $items = collect( [] ); + $fetchedItems = $this->getResponse( $response ); $pages = $responseData->pages; - - foreach ( $fetchedItems->first() as $index => $item ) { - /** @var Model $model */ - $modelClass = $this->getModelClass( $item ); - $model = new $modelClass( $this->request, $item ); - - $items->push( $model ); - } + $items = $this->populateModelsFromResponse( $fetchedItems->first() ); return (object) [ @@ -171,15 +134,16 @@ public function all( $filters = [] ) { * @throws \Rackbeat\Exceptions\RackbeatRequestException */ public function find( $id, $filters = [] ) { + unset( $this->wheres['limit'], $this->wheres['page'] ); + $urlFilters = $this->parseFilters( $filters ); $id = rawurlencode( rawurlencode( $id ) ); return $this->request->handleWithExceptions( function () use ( $id, $urlFilters ) { $response = $this->request->client->get( "{$this->entity}/{$id}{$urlFilters}" ); - $responseData = collect( json_decode( (string) $response->getBody() ) ); - $modelClass = $this->getModelClass( $responseData->first() ); + $responseData = $this->getResponse( $response ); - return new $modelClass( $this->request, $responseData->first() ); + return $this->populateModelsFromResponse( $responseData->first() ); } ); } @@ -195,13 +159,12 @@ public function find( $id, $filters = [] ) { public function create( $data ) { return $this->request->handleWithExceptions( function () use ( $data ) { - $response = $this->request->client->post( "{$this->entity}", [ + $response = $this->request->client->post( $this->entity, [ 'json' => $data, ] ); - $responseData = collect( json_decode( (string) $response->getBody() ) ); - $modelClass = $this->getModelClass( $responseData->first() ); + $responseData = $this->getResponse( $response ); - return new $modelClass( $this->request, $responseData->first() ); + return $this->populateModelsFromResponse( $responseData->first() ); } ); } @@ -218,4 +181,8 @@ public function setEntity( $new_entity ) { protected function getModelClass( $item ) { return $this->model; } + + protected function getResponse( ResponseInterface $response ) { + return collect( json_decode( (string) $response->getBody() ) ); + } } diff --git a/src/Traits/ApiFiltering.php b/src/Traits/ApiFiltering.php new file mode 100644 index 0000000..6348ce5 --- /dev/null +++ b/src/Traits/ApiFiltering.php @@ -0,0 +1,172 @@ + 1000, + 'page' => 1 + ]; + + /** + * @param array $filters + * + * @return string + */ + protected function parseFilters( $filters = [] ) { + + foreach ( $filters as $filter ) { + call_user_func_array( [ $this, 'where' ], array_values( $filter ) ); + } + + + $urlFilters = ''; + + if ( count( $this->wheres ) > 0 ) { + $i = 1; + + $urlFilters .= '?'; + + foreach ( $this->wheres as $key => $filter ) { + + if ( ! is_array( $filter ) ) { + $sign = '='; + $value = $filter; + } else { + [ $sign, $value ] = $filter; + } + + $urlFilters .= $key . $sign . urlencode( $value ); + + if ( count( $this->wheres ) > $i ) { + + $urlFilters .= '&'; + } + + $i++; + } + } + + return $urlFilters; + } + + /** + * Search for resources that only match your criteria, this method can be used in multiple ways + * Example 1: + * ->where('name', 'Test') + * + * Example 2: + * ->where('name', '=', 'Test') + * + * Example 3: + * ->where('is_active') + * + * If you use third example it will be sent as `is_active=true` + * + * @param string $key + * @param string|null $operator + * @param mixed $value + * + * @return $this + */ + public function where( string $key, string $operator = null, $value = null ): self { + if ( func_num_args() === 1 ) { + $value = true; + + $operator = '='; + } + + if ( func_num_args() === 2 ) { + $value = $operator; + + $operator = '='; + } + + $this->wheres[ $key ] = [ $operator, $value ]; + + return $this; + } + + /** + * How many resources we should load (max 1000, min 1) + * + * @param int $limit + * + * @return $this + */ + public function limit( $limit = 1000 ): self { + $this->wheres['limit'] = $limit; + + return $this; + } + + /** + * @param int $page + * + * @return $this + */ + public function page( $page = 1 ): self { + $this->wheres['page'] = $page; + + return $this; + } + + /** + * Set the return fields that you want + * + * @param array $fields + * + * @return $this + */ + public function fields( array $fields = [] ): self { + $this->wheres['fields'] = implode( ',', $fields ); + + return $this; + } + + /** + * What should be expanded (loaded) in relation to requested resource (only field_values for now) + * + * @param string $expand + * + * @return $this + */ + public function expand( string $expand = 'field_values' ): self { + $this->wheres['expand'] = $expand; + + return $this; + } + + /** + * Search for exact field match, if you need to use starting_with match use ->field($id, $value) + * + * @param int $id + * @param $value + * + * @return $this + */ + public function fieldEq( int $id, $value ): self { + $this->wheres[ 'field_eq[' . $id . ']' ] = $value; + + return $this; + } + + /** + * Search by field, this is not equal search so it can return more field, use ->fieldEq($id, $value) if you want to search for exact field + * + * @param int $id + * @param $value + * + * @return $this + */ + public function field( int $id, $value ): self { + $this->wheres[ 'field[' . $id . ']' ] = $value; + + return $this; + } +} \ No newline at end of file diff --git a/src/Utils/Model.php b/src/Utils/Model.php index 1660b0e..289b74e 100644 --- a/src/Utils/Model.php +++ b/src/Utils/Model.php @@ -1,112 +1,105 @@ request = $request; + $data = (array) $data; - public function __construct( Request $request, $data = [] ) - { - $this->request = $request; - $data = (array) $data; + foreach ( $data as $key => $value ) { - foreach ( $data as $key => $value ) { + $customSetterMethod = 'set' . ucfirst( Str::camel( $key ) ) . 'Attribute'; - $customSetterMethod = 'set' . ucfirst(\Str::camel($key)) . 'Attribute'; + if ( !method_exists( $this, $customSetterMethod ) ) { - if ( !method_exists( $this, $customSetterMethod ) ) { + $this->setAttribute( $key, $value ); - $this->setAttribute( $key, $value ); + } else { - } else { + $this->setAttribute( $key, $this->{$customSetterMethod}( $value ) ); + } + } + } - $this->setAttribute( $key, $this->{$customSetterMethod}( $value ) ); - } - } - } + protected function setAttribute( $attribute, $value ) { + if ($attribute === $this->primaryKey) { - protected function setAttribute( $attribute, $value ) - { - if ($attribute === $this->primaryKey) { + $this->url_friendly_id = rawurlencode(rawurlencode($value)); + } - $this->url_friendly_id = rawurlencode(rawurlencode($value)); - } + $this->{$attribute} = $value; - $this->{$attribute} = $value; + } - } + public function __toString() { + return json_encode( $this->toArray() ); + } - public function __toString() - { - return json_encode( $this->toArray() ); - } + public function toArray() { + $data = []; + $class = new \ReflectionObject( $this ); + $properties = $class->getProperties( \ReflectionProperty::IS_PUBLIC ); - public function toArray() - { - $data = []; - $class = new \ReflectionObject( $this ); - $properties = $class->getProperties( \ReflectionProperty::IS_PUBLIC ); + foreach ( $properties as $property ) { - /** @var \ReflectionProperty $property */ - foreach ( $properties as $property ) { + $name = $property->getName(); + $data[ $name ] = $this->{$name}; + } - $data[ $property->getName() ] = $this->{$property->getName()}; - } + return $data; + } - return $data; - } + public function delete() { + return $this->request->handleWithExceptions( function () { - public function delete() - { - return $this->request->handleWithExceptions( function () { + $response = $this->request->client->delete("{$this->entity}/{$this->url_friendly_id}"); - $response = $this->request->client->delete("{$this->entity}/{$this->url_friendly_id}"); + return json_decode((string)$response->getBody()); + } ); + } - return json_decode((string)$response->getBody()); - } ); - } + public function update( $data = [] ) { - public function update( $data = [] ) - { + return $this->request->handleWithExceptions( function () use ( $data ) { - return $this->request->handleWithExceptions( function () use ( $data ) { + $response = $this->request->client->put("{$this->entity}/{$this->url_friendly_id}", [ + 'json' => $data, + ]); - $response = $this->request->client->put("{$this->entity}/{$this->url_friendly_id}", [ - 'json' => $data, - ]); + $responseData = $this->getResponse( $response ); - $responseData = collect(json_decode((string)$response->getBody())); + return new $this->modelClass($this->request, $responseData->first()); + } ); + } - return new $this->modelClass($this->request, $responseData->first()); - } ); - } + public function getEntity() { + return $this->entity; + } - public function getEntity() - { - return $this->entity; - } + public function setEntity( $new_entity ) { + $this->entity = $new_entity; + } - public function setEntity( $new_entity ) - { - $this->entity = $new_entity; - } + protected function getResponse( $response ) { + return collect( json_decode( (string) $response->getBody() ) ); + } } \ No newline at end of file