Skip to content

Commit

Permalink
Merge pull request #420 from Braunson/v3
Browse files Browse the repository at this point in the history
Feature | Added support to Response object method to now accept a dot notation like json()
  • Loading branch information
Sammyjo20 authored Jun 9, 2024
2 parents 0cb74a3 + 55d8fe0 commit 29ced5f
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/php-cs-fixer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ on:
permissions:
contents: write

concurrency:
group: ${{ github.head_ref || github.ref || github.run_id }}_php_cs_fixer
cancel-in-progress: true

jobs:
php-cs-fixer:
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/phpstan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
branches:
- '*'

concurrency:
group: ${{ github.head_ref || github.ref || github.run_id }}_phpstan
cancel-in-progress: true

jobs:
phpstan:
name: phpstan
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.head_ref || github.ref || github.run_id }}_tests
cancel-in-progress: true

jobs:
tests:
runs-on: ${{ matrix.os }}
Expand Down
37 changes: 37 additions & 0 deletions src/Helpers/ObjectHelpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Saloon\Helpers;

/**
* @internal
*/
final class ObjectHelpers
{
/**
* Get an item from an object using "dot" notation.
*/
public static function get(object $object, string $key, mixed $default = null): mixed
{
// Split the dot notation into individual keys

$keys = explode('.', $key);

// Navigate through the object properties

foreach ($keys as $dot) {
// Check if the object is an array or object and if the key exists
if (is_object($object) && isset($object->{$dot})) {
$object = $object->{$dot};
} elseif (is_array($object) && isset($object[$dot])) {
$object = $object[$dot];
} else {
// Return null if the key doesn't exist
return null;
}
}

return $object;
}
}
22 changes: 18 additions & 4 deletions src/Http/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Saloon\Traits\Macroable;
use InvalidArgumentException;
use Saloon\Helpers\ArrayHelpers;
use Saloon\Helpers\ObjectHelpers;
use Saloon\XmlWrangler\XmlReader;
use Illuminate\Support\Collection;
use Saloon\Contracts\FakeResponse;
Expand Down Expand Up @@ -53,6 +54,11 @@ class Response
*/
protected array $decodedJson;

/**
* The decoded JSON response object.
*/
protected mixed $decodedJsonObject;

/**
* The decoded XML response.
*/
Expand Down Expand Up @@ -223,19 +229,27 @@ public function array(int|string|null $key = null, mixed $default = null): mixed
}

/**
* Get the JSON decoded body of the response as an object.
* Get the JSON decoded body of the response as an object or scalar value.
*/
public function object(): object
public function object(string|int|null $key = null, mixed $default = null): mixed
{
return json_decode($this->body(), false, 512, JSON_THROW_ON_ERROR);
if (! isset($this->decodedJsonObject)) {
$this->decodedJsonObject = json_decode($this->body() ?: '{}', false, 512, JSON_THROW_ON_ERROR);
}

if (is_null($key)) {
return $this->decodedJsonObject;
}

return ObjectHelpers::get($this->decodedJsonObject, (string)$key, $default);
}

/**
* Convert the XML response into a SimpleXMLElement.
*
* Suitable for reading small, simple XML responses but not suitable for
* more advanced XML responses with namespaces and prefixes. Consider
* using the xmlReader method instead for better compatability.
* using the xmlReader method instead for better compatibility.
*
* @see https://www.php.net/manual/en/book.simplexml.php
*/
Expand Down
17 changes: 17 additions & 0 deletions tests/Unit/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@
expect($response)->object()->toEqual($dataAsObject);
});

test('the object method with a dot notation key value will return a nested string', function () {
$data = [
'contacts' => [
['name' => 'Sam', 'work' => 'Codepotato'],
['name' => 'Braunson', 'work' => 'Geekybeaver'],
],
];

$mockClient = new MockClient([
MockResponse::make($data, 500),
]);

$response = connector()->send(new UserRequest, $mockClient);

expect($response)->object('contacts.1.name')->toEqual('Braunson');
});

test('the collect method will return a collection', function () {
$mockClient = new MockClient([
MockResponse::make(['name' => 'Sam', 'work' => 'Codepotato'], 500),
Expand Down

0 comments on commit 29ced5f

Please sign in to comment.