Skip to content

Commit

Permalink
Merge pull request #370 from saloonphp/fix/issue-369
Browse files Browse the repository at this point in the history
Fix | Better Query Parameter Parsing
  • Loading branch information
Sammyjo20 committed Feb 12, 2024
2 parents fca735c + 99b2695 commit 558c48d
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
.php-cs-fixer.cache
.phpunit.result.cache
tests/Fixtures/Saloon/Testing
.phpunit.cache/test-results

# environments/configs
phpstan.neon
27 changes: 27 additions & 0 deletions src/Helpers/URLHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,31 @@ public static function isValidUrl(string $url): bool
{
return ! empty(filter_var($url, FILTER_VALIDATE_URL));
}

/**
* Parse a query string into an array
*
* @return array<string, mixed>
*/
public static function parseQueryString(string $query): array
{
if ($query === '') {
return [];
}

$parameters = [];

foreach (explode('&', $query) as $parameter) {
$name = urldecode((string)strtok($parameter, '='));
$value = urldecode((string)strtok('='));

if (! $name || str_starts_with($parameter, '=')) {
continue;
}

$parameters[$name] = $value;
}

return $parameters;
}
}
3 changes: 2 additions & 1 deletion src/Traits/PendingRequest/ManagesPsrRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Saloon\Traits\PendingRequest;

use Saloon\Helpers\URLHelper;
use Psr\Http\Message\UriInterface;
use Saloon\Data\FactoryCollection;
use Psr\Http\Message\RequestInterface;
Expand All @@ -27,7 +28,7 @@ public function getUri(): UriInterface
// and then we'll merge in Saloon's query parameters. Our query parameters will take
// priority over any that were defined in the URL.

parse_str($uri->getQuery(), $existingQuery);
$existingQuery = URLHelper::parseQueryString($uri->getQuery());

return $uri->withQuery(
http_build_query(array_merge($existingQuery, $this->query()->all()))
Expand Down
10 changes: 10 additions & 0 deletions tests/Unit/PsrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,13 @@
expect($uri->getQuery())->toEqual('include=hats&sort=first_name&per_page=100');
expect($uri->getFragment())->toEqual('fragment-123');
});

test('when using the url for query parameters you can use dots and value-less parameters', function () {
$connector = new TestConnector;
$request = new QueryParameterRequest('/user?account.id=1&checked&name=sam');

$pendingRequest = $connector->createPendingRequest($request);
$uri = $pendingRequest->getUri();

expect($uri->getQuery())->toEqual('account.id=1&checked=&name=sam&per_page=100');
});
15 changes: 14 additions & 1 deletion tests/Unit/URLHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Saloon\Helpers\URLHelper;

test('the URL helper will join two URLs together', function ($baseUrl, $endpoint, $expected) {
expect(URLHelper::join($baseUrl, $endpoint))->toEqual($expected);
expect(URLHelper::join($baseUrl, $endpoint))->toBe($expected);
})->with([
['https://google.com', '/search', 'https://google.com/search'],
['https://google.com', 'search', 'https://google.com/search'],
Expand All @@ -16,3 +16,16 @@
['', 'google.com/search', '/google.com/search'],
['https://google.com', 'https://api.google.com/search', 'https://api.google.com/search'],
]);

test('the URL helper can parse a variety of query parameters', function (string $query, array $expected) {
expect(URLHelper::parseQueryString($query))->toBe($expected);
})->with([
['foo=bar', ['foo' => 'bar']],
['foo=bar&name=sam', ['foo' => 'bar', 'name' => 'sam']],
['foo==bar&name=sam', ['foo' => 'bar', 'name' => 'sam']],
['=abc&name=sam', ['name' => 'sam']],
['foo&name=sam', ['foo' => '', 'name' => 'sam']],
['account.id=1', ['account.id' => '1']],
['name=cowboy%20sam', ['name' => 'cowboy sam']],
['name=sam&', ['name' => 'sam']],
]);

0 comments on commit 558c48d

Please sign in to comment.