selahattinunlu / laravel-api-query-builder Goto Github PK
View Code? Open in Web Editor NEWLaravel & Lumen Api Query Builder Package
Laravel & Lumen Api Query Builder Package
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)
Refer: https://stackoverflow.com/questions/9879225/serverpath-info-on-localhost for the issue.
I have a table with a primary key like this "model_id", I do not using "id", so what is the best way to override the array configuration (config/api-query-builder.php
)?
After the last update I'm having problems with version 5.1 of Laravel.
https://github.com/selahattinunlu/laravel-api-query-builder/blob/master/src/QueryBuilder.php#L406
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!
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."
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?
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
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
Hello. I want get all column from object when I pass the column only relation.
And now.
I fix code to
if (empty($this->columns)) {
$this->columns = ['*'];
}
$this->query->select($this->columns);
you can add it to project.
Thanks.
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
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.
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?
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!
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.
Nice lib! Thanks :)
Can i get it by using a rest resource like "/users/{id}" instead of "/users?id={id}"?
The hasTableColumn($column)
method does not support multiple databases.
It should use the connection parameter that is set on the model.
Just like the title says.
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 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
Hello, there is a way to work with this library and implement the new Laravel 5.5 feature API Resources?
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));
}
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.
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?
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
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:
Method \Unlu\Laravel\Api\QueryBuilder::paginate()
contains incorrect items:I found an issue with Soft Delete (https://laravel.com/docs/5.5/eloquent#soft-deleting)
The pagination returns "total" property which includes records with "deleted_at" attribute.
Is it a bug, or I am missing something?
Thanks!
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:
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? )
Refactor QueryBuilder into facade/service like object
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);
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.
Can you please throw some light on how to change default limit, orderBy and excludedParameters parameters in Lumen ?
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
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?
I cant find examples about null values
https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Other-Examples
Is that possible?
/users?updated_at=null
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
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.
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;
....
}
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]
}
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",
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).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.