Comments (6)
Just testet everything with PHP v5.6, but the errors remained the same; the resulting sql query always treats the params as attributes.
I then tried to debug the APIHandler and was able to isolate the issue to the Parser->getFilterParams()
Function.
At least for me the array_diff_ukey
in Line 277 doesn't return a correct array of filter params for some reason i can't get my head around yet.
Parser.php - Line 272-286:
protected function getFilterParams()
{
$reserved = array_fill_keys($this->functions, true);
$prefix = $this->prefix;
$filterParams = array_diff_ukey($this->params, $reserved, function ($a, $b) use ($prefix) {
return $a != $prefix . $b;
});
if (count($filterParams) > 0) {
return $filterParams;
}
return false;
}
For Example when provided with _limit
the key will be removed from the filter params but the _sort
key won't. It seems the function is not comparing all pairs of keys provided correctly.
To check this i added a simple echo
output to the compare callback function as below:
$filterParams = array_diff_ukey($this->params, $reserved, function ($a, $b) use ($prefix) {
echo("\$a:" . $a . " != \$b:" . $prefix . $b . " | " . (($a != $prefix . $b) ? 'true' : 'FALSE') . "<br/>");
return $a != $prefix . $b;
});
Requesting: /api/users?_limit=1&_with=roles&_sort=name&email-lk=*com
the output then shows:
$a:offset != $b:_sort | true
$a:offset != $b:_limit | true
$a:offset != $b:_fields | true
$a:offset != $b:_config | true
$a:offset != $b:_with | true
$a:q != $b:_offset | true
$a:limit != $b:_sort | true
$a:limit != $b:_with | true
$a:limit != $b:_fields | true
$a:config != $b:_limit | true
$a:sort != $b:_fields | true
$a:with != $b:_sort | true
$a:_limit != $b:_limit | FALSE
$a:_with != $b:_limit | true
$a:_with != $b:_offset | true
$a:_with != $b:_q | true
$a:_sort != $b:_limit | true
$a:_sort != $b:_offset | true
$a:_sort != $b:_q | true
$a:email-lk != $b:_limit | true
$a:email-lk != $b:_offset | true
$a:email-lk != $b:_q | true
As you can see the _limit will successfully be removed, while the rest aren't compared to all predefined params and therefore will be passed on as filters resulting in my previous sql errors.
So, to make this work for now i tried the array_diff_key
function to replace the ukey
like so:
protected function getFilterParams() {
$_functions = ['_fields', '_sort', '_limit', '_offset', '_config', '_with', '_q'];
$reserved = array_fill_keys($_functions, true);
$prefix = $this->prefix;
$filterParams = array_diff_key($this->params, $reserved);
if (count($filterParams) > 0) {
return $filterParams;
}
return false;
}
.. and then _with
, _sort
and _fields
instantly work as intended!
However, i can't believe or explain how i'm the only one having this issue and i've no idea how so :(
Perhaps you might be better suited to deduce how this might occur? I would really like to be able to use your project as vendor dependency instead of this hack, but it's at least some progress, right? :D'
I'm kind of confused what might be wrong with my php environment, since i tried this with clean laravel/homestead vagrant boxes, version 0.3.3 (PHP5.6.99) and 0.4.4. (PHP7.0.5)
Maybe this will at least be of some future help for someone having similar problems.
Edit: changed some spelling and few mistakes in the explanation
from laravel-api-handler.
I'll check this out and will try to reproduce it as soon as I can, thanks for investigating.
from laravel-api-handler.
There is no need to do anything more. Looks like somehow _sort
and _with
are not detected as predefined parameters. I used this code with many Laravel versions including 5.1 and never had such issues.
Can you post the code where you call the handler and the PHP version you're using?
from laravel-api-handler.
Hey Marcel,
thank you for the quick reply. Sadly i still haven't figured out what is causing my failure.
The Php Version that came with my vagrant seems to be PHP 7.0.5. Maybe that causes the issue?
Here are the relevant code snippets:
Post Controller:
public function index(Request $request) {
// find all posts with selected nested relations
$posts = Post::with('address');
// remove unwanted params from request
$searchParams = $request->except(['token']);
$searchable = ['id', 'name', 'latitude', 'longitude'];
try {
// apply optional search query parameters as filter and return result
return \ApiHandler::parseMultiple($posts, $searchable, $searchParams)->getResponse();
} catch (Exception $e) {/*...*/}
}
Post Model:
/**
* @Relation
*/
public function address() {
return $this->belongsTo(Address::class);
}
/**
* @Relation
*/
public function user() {
return $this->belongsTo(User::class);
}
When calling /api/posts?_with=user
:
SQLSTATE[42S22]: Column not found: Unknown column '_with' in 'where clause' (SQL: select * from `posts` where `posts`.`deleted_at` is null and `_with` = user)
Im still kind of confused how most of the other _parameter work nicely. But maybe you get an idea with these snippets?
from laravel-api-handler.
Hmm I can't see an issue on the first glimpse. But I didn't really test the library against PHP 7 yet so It is possible that there is some different behaviour. Is it possible for you to test your code on PHP 5.6 without too much hassle?
from laravel-api-handler.
Using the handler with many PHP 7+ versions, I cannot reproduce. If there is still a problem, the next major version will probably make it go away anyway.
from laravel-api-handler.
Related Issues (20)
- Add offset, limit and filter to meta HOT 1
- Transformers / Include related models HOT 1
- Sorting datetime field HOT 4
- Why parseSingle HOT 2
- Returning relationship model data even when not requested when Accessor is used in model HOT 1
- The last version not working with larave 5.3 HOT 2
- better if this package support more than two layer "_fields" nesting HOT 1
- Is there any chance to use with Doctrine?
- Not able to use on Lumen without Facades HOT 1
- Great job! HOT 1
- Non-static method Marcelgwerder\\ApiHandler\\ApiHandler::parseMultiple() should not be called statically HOT 2
- Search in joined table HOT 9
- Support for Laravel 5.5 Resources HOT 1
- [question] Use library with repository HOT 2
- How can i use custom get param HOT 3
- Proposal - Appends HOT 1
- Security question HOT 1
- Allow to selectively use soft-deleted entities HOT 1
- [Next] Setting sortable columns does not work properly
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from laravel-api-handler.