selahattinunlu / laravel-api-query-builder

Laravel & Lumen Api Query Builder Package
331 stars 66 forks source link

Improving : paginate() and supporting dynamic appends #12

Closed robsontenorio closed 7 years ago

robsontenorio commented 7 years ago

Improving: add original query string on paginate() method

Problem The current paginate() method does not includes the original query parameters on "url pages"

http://localhost:8025/app/public/users?includes=city&country=US&limit=10&page=4 results ...

[...]
"next_page_url": "http://localhost:8025/app/public/users?page=4",
[...]

Proposal

//QueryBuilder.php

[...]
$qs = [];
parse_str($this->uriParser->hasQueryUri(), $qs);
$resultado = $this->query->paginate($this->limit)->appends($qs);
[...]

Now "next_page_url" and "prev_page_url" includes the original query string

{
  "next_page_url": "http://localhost:8025/app/public/users?includes=city&country=US&limit=10&page=4",
  "prev_page_url": "http://localhost:8025/app/public/users?includes=city&country=US&limit=10&page=4",

Supporting dynamic appends() on Laravel models

Static way On Laravel models we have "$appends = ['is_admin', 'balance']" attribute that allow us to add some custom attributes to our model.

Dynamic way

$user = User::find(1)->append(['is_admin', 'balance']);

public function getIsAdminAttribute()
{
   $this->attributes['is_admin'] = 'yes';  // some logic in here
} 

public function getBalanceAttribute()
{
   $this->attributes['balance'] = '1200.00';  // some logic in here
} 

Full solution : fixing query string on paginate() and adding support to dynamic append()

http://localhost:8025/app/public/users?&appends=is_admin,balance

//QueryBuilder.php

public function paginate()
 {
             if (! $this->hasLimit()) {
            throw new Exception("You can't use unlimited option for pagination", 1);
            }

               //******* EDIT 
                $qs = [];
        parse_str($this->uriParser->hasQueryUri(), $qs);

        $result = $this->query->paginate($this->limit)->appends($qs);

        if ($this->uriParser->hasQueryParameter('appends') <> NULL)
        {           
             $result->map(function($item) {
                return $item->append(explode(',', $this->uriParser->queryParameter('appends')['value']));
             });            
        }
        //******* END

         return $result;
    }

NOTE: The same append() logic would be applied on get() method (except "query string" issue).

selahattinunlu commented 7 years ago

@robsontenorio Hi and thanks for your proposal. I am examining :)

selahattinunlu commented 7 years ago

@robsontenorio Hi again, I fixed pagination issue. Your proposal is cool but I can't use directly. Because this package is using several operator other than "=" (eg: <=, != etc.)

So, I fixed this issue by adding new Paginator class that extends from LengthAwarePaginator.

You can check this out https://github.com/selahattinunlu/laravel-api-query-builder/commit/73ffd510556283086fd8c961bb2f7d9d45e95ab7

I'm working on "appends" idea now. I will release new version after complete it. I will inform you on here.

Finally, @tttwb I'm so sorry for late. I did not get any notification about your issue from Github :|

selahattinunlu commented 7 years ago

@robsontenorio @tttwb

I released new version. 💯 👍 You can use it after composer update.

https://github.com/selahattinunlu/laravel-api-query-builder/releases/tag/v1.5.0