Giter VIP home page Giter VIP logo

laravel-api-query-builder's Introduction

laravel-api-query-builder's People

Contributors

mahmutbayri avatar royxiang avatar selahattinunlu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-api-query-builder's Issues

Undefined index: PATH_INFO {"exception":"[object] (ErrorException(code: 0): Undefined index: PATH_INFO at vendor/unlu/laravel-api-query-builder/src/RequestCreator.php:36)

Getting the following error when using custom requests with an URL without a trailing Slash.

Undefined index: PATH_INFO {"exception":"[object] (ErrorException(code: 0): Undefined index: PATH_INFO at vendor/unlu/laravel-api-query-builder/src/RequestCreator.php:36)

$requestUri = $_SERVER['PATH_INFO'];

Refer: https://stackoverflow.com/questions/9879225/serverpath-info-on-localhost for the issue.

Modifying the Query before Building

I'm not seeing an appropriate way to make modifications to the query before calling QueryBuilder::build(). I'd like to add a ->where('user_id', Auth::guard()->user->id) clause onto the resulting where to filter results to only those owned by the currently authenticated user.

How am I supposed to accomplish this?

Thanks!

Eloquent lists() deprecated

In QueryBuilder, query->lists() has been renamed to ->pluck as of laravel 5.2:

"The lists method on the Collection, query builder and Eloquent query builder objects has been renamed to pluck. The method signature remains the same."

pivots relation

In my project I have a bunch of many to many relations, and my pivot usually have relations as well. The most common case is user to group with permissions/roles on the pivot table. Is there a way to use this package with this case?

How to select relation field

Hi ,
I have News and NewsCategory module.
How to search in NewsCategory name field
When I use this
news_categories.name=test&columns=*&title=test*&includes=NewsCategory
show me error

Unknown column 'news_categories.name'

But when I use this
columns=*&title=test*&includes=NewsCategory
Show me all news with NewsCategory have test in title

RequestCreator

Laravel 5.5

Endpoint: /decks/{id}

I just want to merge "id" in request object. I have tried $request->merge(['id '=> $id]), but i got error from Laravel. So I have tried:

 public function show(Request $request, $id)
    {
        $request = $request->all();
        $request['id'] = $id;
        $request = RequestCreator::createWithParameters($request);

        return Deck::get($request);
    }

Error

Undefined index: PATH_INFO

Lumen compatibility

Support for Lumen would be great! Right now, I get an uncaught ReflectionException:

( ! ) Fatal error: Uncaught ReflectionException: Class path.storage does not exist in /home/vagrant/Code/parties-api/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 738

How create a new Custom orderBy?

I have a product table and a related visits table that keep visit of products.

how can I create a new custom orderBy so when &order_by=visits_count,desc do this:

$products->withCount('visits')->orderBy('visits_count', 'desc');

and sort products by their visits.

Adding additional 'where' clause

I'd like to apply an extra 'where' clause to every request.

ie: For an incoming API request I want to limit the results to only return results that are "owned" by the requesting user. I need to add an additional where clause for "organisation_id", which cannot be overridden through the URL's GET parameters.

Without success, I've already tried $request->query->add(['organisation_id' => 5]); and $_GET['organisation_id'] = 5.

Any suggestions?

According to URI Generic Syntax:

Hi!

Excellent piece of art :) Just a small concern:

https://tools.ietf.org/html/rfc3986#page-12

"The mark characters that are typically unsafe to decode, including the exclamation mark ("!"), asterisk ("*"), single-quote ("'"), and open and close parentheses ("(" and ")"), have been moved to the reserved set in order to clarify the distinction between reserved and unreserved and, hopefully, to answer the most common question of scheme designers."

Thanks in advance!

Using resources

In the documentation (Usage) is the following code snippet:

namespace App\Whatever\Api\Controllers;

use App\Http\Requests;
use App\User;
use Illuminate\Http\Request;

// Add this line
use Unlu\Laravel\Api\QueryBuilder;

class UsersController extends Controller
{
  public function index(Request $request)
  {
    $queryBuilder = new QueryBuilder(new User, $request);
    
    return response()->json([
      'data' => $queryBuilder->build()->paginate(),
      .
      .
    ]);
  }
}

I had already defined resources for my models. Your code snippet will ignore the resources. Is there a way to use it with my resources? Because in my resources are defined, which data will be showed and i defined custom names for the output.

/users/{id}

Nice lib! Thanks :)

Can i get it by using a rest resource like "/users/{id}" instead of "/users?id={id}"?

Security Issue

As I see in the code,

Virtually, everything is possible to do in where condition, eager loading and some cool stuff. But, to use this package in one of our upcoming project. We would like to know what about security. What we have taken care for security?

Thanks.

Date= and date between not giving proper results

date equal to and date between not giving proper results.
created_at is time stamp for record create
i tried
created_at=2017-01-25,

and also date created_at<2017-01-25&created_at>2017-01-20 for date between but the results are not as expected

can you please describe a full example to use it or what modification do i need to use the date and date time queries

QueryBuilder->hasTableColumn does not respect DB connection

I have a multi-tenant database setup, and when trying to query a model I get "Unknown column 'id'". Turns out the method \Unlu\Laravel\Api\QueryBuilder::hasTableColumn calls Schema::hasColumn without setting connection first. Should be:

private function hasTableColumn($column)
{
    return (Schema::connection($this->model->getConnectionName())->hasColumn($this->model->getTable(), $column));
}

Support for orWhere

Are you planning to add support for an orWhere parameter with the same operators as the where statement. Its not uncommon to need a where or where query so it should be a nice addition in my opinion.

URL Token Param

Hi,

I'm having trouble passing the token as a parameter of the request. By default it's playing as a column.

Any suggestions about it to get around this?

Not working if the searching key word includes "&" character

Hi there,
Your library is a very good idea to implement the advanced searching.
But it will not work if the key word includes & characters (something like this name="abc & 123"), because you are splitting the url params by this function array_filter(explode('&', $queryUri)).
So it will be error in this case.
Could you think how to fix it?
I'm thinking the solution too

Method `\Unlu\Laravel\Api\QueryBuilder::paginate()` does not work

Hi there,
Your library is a perfect solution for resolving search criteria via URI, but it has some bugs.

Preconditions:

  • PHP 8.2
  • slim/slim-skeleton
  • illuminate/database
  • illuminate/http
  • illuminate/pagination
  • illuminate/validation
  • robmorgan/phinx
  • unlu/laravel-api-query-builder

Issues:

  • Query without indicating parameters returns error:

image

  • Paginator object, retrieved from Method \Unlu\Laravel\Api\QueryBuilder::paginate() contains incorrect items:

image

image

Using join in filters

First thank you for a great lib! I hope i will use it in my app.

I have a problem using join in filter.

I have 3 models in next hierarchy:

  • Project
    • Task (related to Project model by project_id column)
      • TimeEntry (related to Task model by task_id column)

in my TimeEntryController i have next code:

public function index(Request $request)
    {
      $queryBuilder = new TimeEntryQueryBuilder(new TimeEntry, $request);
      return $queryBuilder->build()->paginate();
    }

in my TimeEntryQueryBuilder a have next:

public function filterByProject($query, $id)
    {
      return $query->join('tasks', 'time_entries.task_id', '=', 'tasks.id')->where('project_id', $id);
    }

so when a make request for /timeentries/project=2 i want to get all TimeEntries, that assigned to tasks, that assigned to project with id=2, but i have the following error:

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous (SQL: select * from `time_entries` inner join `tasks` on `time_entries`.`task_id` = `tasks`.`id` where `project_id` = 2 order by `id` desc limit 100 offset 0)

Maybe you can help me, pls? )

Passing an array as a query parameter

When trying to pass an array of data as a query parameter for example:

?countries[]=germany&countries[]=france&countries[]=ireland

It throws the error:

UnknownColumnException in QueryBuilder.php line 254:
Unknown column 'countries[]'

Is there a way to tell it to ignore the '[]' after countries so that the array can be passed correctly and then used as a custom filter as below:

return $query->whereIn('country', $countries);

Lumen configuration file

Thank you so much for Lumen compatibility!

Is there any way to allow for extending/modifying the functionality with Lumen? If not, some way to do that would be very useful.

Default orderBy

api-query-builder.php

return [
    'limit' => 15,
    'orderBy' => [
        [
            'column' => 'id',
            'direction' => 'desc'
        ]
    ],
    'excludedParameters' => [],
];

The problem is some old fashioned DB has no column "ID".

ERROR:  "ID": invalid identifier
SELECT * from "USERLAGCY" order by "ID" desc 

So, it would be usefull if we just ignore "order by" statment on query builder.

    'orderBy' => [
        [
            'column' => null,
            'direction' => null
        ]
.
.
or
.
.
    'orderBy' => []
.
.
.
    'orderBy' => null

@selahattinunlu

Previous and next page urls in pagination response

When making a query to an end point that returns all the data for the current user if there are no filters but then only returns a subset with filters applied e.g:

http://example.com/api/orders?status=completed&dispatched=1&date_from=01-10-2016&date_to=01-11-2016&page=1

The response pagination data for the next and previous pages do not include any of the filters from the original request, so if using these to change page it will return all the data with no filters.

{
  "data": {
    "total": 100,
    "per_page": 15,
    "current_page": 2,
    "last_page": 7,
    "next_page_url": "http://example.com/api/orders?page=3",
    "prev_page_url": "http://example.com/api/orders?page=1",
    "from": 16,
    "to": 30,
    "data": [.....]
  }
}

Is there a way to make the next_page_url and prev_page_url include all the same filters with simply the page = 2 etc?

Laravel 5.5 - Undefined index: PATH_INFO

It seems new release 5.5 of Laravel does not include 'PATH_INFO' on global $SERVER.

$request->merge(['id' => $id]);
$request = RequestCreator::createWithParameters($request->all());

ERROR

Undefined index: PATH_INFO

Proposal - Use "array of params" instead $request

Problem

Sometimes i need to call model`s methods, that uses a QueryBuilder instance. So , i "can not trust" on $request object, in this case. Because, not all parameters in current querystring are applied for both QueryBuilder instances.

Proposal

This is my current implementation, for solve my problem, and i would like to share if you. Its a braking change.

Change QUERYBUILDER.PHP

FROM

__construct(Model $model, Request $request)

TO

__construct(Model $model, array $params = [])

QueryBuilder.php

public function __construct(Model $model, array $params = []) {
                 ...

		$this->uriParser = new UriParser($params);

		...
}

UriParser.php

public function __construct(array $params = []) {

		$this->uri = (count($params) > 0) ? '?' . http_build_query($params) : NULL;
                ....
}
               

Example

MODELS/USER


// generic get all items method
public static function listAll(array $params = []) {
		
		$users = (new QueryBuilder(new User, $params))->build()->paginate();
		
		return $users;
	
	}

MODELS/TOURNAMENT

// generic get all items method
public static function listAll(array $params = []) {
		
		$tournaments = (new QueryBuilder(new Tournament, $params))->build()->paginate();
		
		return $tournaments;
	
	}

CONTROLLERS/DASHBOARD

public function recents(Request $request) {


                //now on the same request i can use diferent QueryBuilder instances to filter my collections, based on ARRAY OF PARAMS

		$recentUsers = User::listAll( /*** custom params array here ***/ );
		$recentTournametns = Tournament::listAll( /**** we can even use "$request->all()" to obtain a array of parameters from current request  *** /);
	        
                 return ['users' => $recentUsers, 'tournaments' => $recentTournaments]
	}

Improving : paginate() and supporting dynamic appends

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).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.