Skip to content

Commit

Permalink
Merge branch '1.x' into 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
joetannenbaum authored Oct 10, 2024
2 parents 9b26d03 + ddf47e9 commit dc06a8d
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 103 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Release Notes

## [Unreleased](https://github.com/inertiajs/inertia-laravel/compare/v1.2.0...2.x)
## [Unreleased](https://github.com/inertiajs/inertia-laravel/compare/v1.3.0...2.x)

- Nothing yet!

## [v1.3.0](https://github.com/inertiajs/inertia-laravel/compare/v1.2.0...v1.3.0) - 2024-06-12

- Drop support for Laravel 8 and 9 ([#629](https://github.com/inertiajs/inertia-laravel/pull/629))
- Add "always" props using new `Inertia::always()` wrapper ([#627](https://github.com/inertiajs/inertia-laravel/pull/627))
- Revert dot-notation support in partial reloads ([#641](https://github.com/inertiajs/inertia-laravel/pull/641))

## [v1.2.0](https://github.com/inertiajs/inertia-laravel/compare/v1.1.0...v1.2.0) - 2024-05-17

Expand Down
3 changes: 1 addition & 2 deletions src/AlwaysProp.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@

class AlwaysProp
{
/** @var mixed */
protected $value;

/**
* @param mixed $value
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/CreateMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
namespace Inertia\Commands;

use Illuminate\Console\GeneratorCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'inertia:middleware')]
class CreateMiddleware extends GeneratorCommand
Expand Down
1 change: 1 addition & 0 deletions src/Commands/StartSsr.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Inertia\Ssr\SsrException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Process\Process;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'inertia:start-ssr')]
class StartSsr extends Command
Expand Down
2 changes: 1 addition & 1 deletion src/Middleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace Inertia;

use Closure;
use Inertia\Support\Header;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Inertia\Support\Header;
use Symfony\Component\HttpFoundation\Response;

class Middleware
Expand Down
51 changes: 26 additions & 25 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function __construct(string $component, array $props, string $rootView =
/**
* @param string|array $key
* @param mixed $value
*
* @return $this
*/
public function with($key, $value = null): self
Expand All @@ -70,6 +71,7 @@ public function with($key, $value = null): self
/**
* @param string|array $key
* @param mixed $value
*
* @return $this
*/
public function withViewData($key, $value = null): self
Expand Down Expand Up @@ -101,11 +103,14 @@ public function cache(string|array $cacheFor): self
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
$props = $this->resolveProperties($request, $this->props);
$props = $this->resolvePartialProps($request, $this->props);
$props = $this->resolveAlwaysProps($props);
$props = $this->evaluateProps($props, $request);

$page = array_merge(
[
Expand All @@ -129,9 +134,9 @@ public function toResponse($request)
}

/**
* Resolve the properites for the response.
* Resolve the `only` and `except` partial request props.
*/
public function resolveProperties(Request $request, array $props): array
public function resolvePartialProps(Request $request, array $props): array
{
$isPartial = $this->isPartial($request);

Expand Down Expand Up @@ -189,47 +194,34 @@ public function resolveArrayableProperties(array $props, Request $request, bool
public function resolveOnly(Request $request, array $props): array
{
$only = array_filter(explode(',', $request->header(Header::PARTIAL_ONLY, '')));
$except = array_filter(explode(',', $request->header(Header::PARTIAL_EXCEPT, '')));

$value = [];
$props = $only ? Arr::only($props, $only) : $props;

foreach ($only as $key) {
Arr::set($value, $key, data_get($props, $key));
}

return $value;
}

/**
* Resolve the `except` partial request props.
*/
public function resolveExcept(Request $request, array $props): array
{
$except = array_filter(explode(',', $request->header(Header::PARTIAL_EXCEPT, '')));

Arr::forget($props, $except);

return $props;
}

/**
* Resolve `always` properties that should always be included on all visits, regardless of "only" or "except" requests.
* Resolve `always` properties that should always be included on all visits,
* regardless of "only" or "except" requests.
*/
public function resolveAlways(array $props): array
public function resolveAlwaysProps(array $props): array
{
$always = array_filter($this->props, static function ($prop) {
return $prop instanceof AlwaysProp;
});

return array_merge(
$always,
$props
);
return array_merge($always, $props);
}

/**
* Resolve all necessary class instances in the given props.
*/
public function resolvePropertyInstances(array $props, Request $request): array
public function evaluateProps(array $props, Request $request, bool $unpackDotProps = true): array
{
foreach ($props as $key => $value) {
$resolveViaApp = collect([
Expand All @@ -253,11 +245,20 @@ public function resolvePropertyInstances(array $props, Request $request): array
$value = $value->toResponse($request)->getData(true);
}

if ($value instanceof Arrayable) {
$value = $value->toArray();
}

if (is_array($value)) {
$value = $this->resolvePropertyInstances($value, $request);
$value = $this->evaluateProps($value, $request, false);
}

$props[$key] = $value;
if ($unpackDotProps && str_contains($key, '.')) {
Arr::set($props, $key, $value);
unset($props[$key]);
} else {
$props[$key] = $value;
}
}

return $props;
Expand Down
1 change: 1 addition & 0 deletions src/ResponseFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Arr;
use Inertia\Support\Header;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
Expand Down
1 change: 1 addition & 0 deletions src/Testing/Concerns/Has.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function hasAll($key): self

/**
* @param mixed $value
*
* @return $this
*/
public function has(string $key, $value = null, ?Closure $scope = null): self
Expand Down
2 changes: 1 addition & 1 deletion tests/AlwaysPropTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace Inertia\Tests;

use Illuminate\Http\Request;
use Inertia\AlwaysProp;
use Illuminate\Http\Request;

class AlwaysPropTest extends TestCase
{
Expand Down
4 changes: 2 additions & 2 deletions tests/ResponseFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ public function test_location_redirects_are_not_modified(): void
public function test_location_response_for_non_inertia_requests_using_redirect_response_with_existing_session_and_request_properties(): void
{
$redirect = new RedirectResponse('https://inertiajs.com');
$redirect->setSession($session = new Store('test', new NullSessionHandler));
$redirect->setRequest($request = new HttpRequest);
$redirect->setSession($session = new Store('test', new NullSessionHandler()));
$redirect->setRequest($request = new HttpRequest());
$response = (new ResponseFactory())->location($redirect);

$this->assertInstanceOf(RedirectResponse::class, $response);
Expand Down
147 changes: 81 additions & 66 deletions tests/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,72 +434,6 @@ public function test_exclude_props_from_partial_response(): void
$this->assertSame('123', $page->version);
}

public function test_nested_partial_props(): void
{
$request = Request::create('/user/123', 'GET');
$request->headers->add(['X-Inertia' => 'true']);
$request->headers->add(['X-Inertia-Partial-Component' => 'User/Edit']);
$request->headers->add(['X-Inertia-Partial-Data' => 'auth.user,auth.refresh_token']);

$props = [
'auth' => [
'user' => new LazyProp(function () {
return [
'name' => 'Jonathan Reinink',
'email' => '[email protected]',
];
}),
'refresh_token' => 'value',
'token' => 'value',
],
'shared' => [
'flash' => 'value',
],
];

$response = new Response('User/Edit', $props);
$response = $response->toResponse($request);
$page = $response->getData();

$this->assertFalse(isset($page->props->shared));
$this->assertFalse(isset($page->props->auth->token));
$this->assertSame('Jonathan Reinink', $page->props->auth->user->name);
$this->assertSame('[email protected]', $page->props->auth->user->email);
$this->assertSame('value', $page->props->auth->refresh_token);
}

public function test_exclude_nested_props_from_partial_response(): void
{
$request = Request::create('/user/123', 'GET');
$request->headers->add(['X-Inertia' => 'true']);
$request->headers->add(['X-Inertia-Partial-Component' => 'User/Edit']);
$request->headers->add(['X-Inertia-Partial-Data' => 'auth']);
$request->headers->add(['X-Inertia-Partial-Except' => 'auth.user']);

$props = [
'auth' => [
'user' => new LazyProp(function () {
return [
'name' => 'Jonathan Reinink',
'email' => '[email protected]',
];
}),
'refresh_token' => 'value',
],
'shared' => [
'flash' => 'value',
],
];

$response = new Response('User/Edit', $props);
$response = $response->toResponse($request);
$page = $response->getData();

$this->assertFalse(isset($page->props->auth->user));
$this->assertFalse(isset($page->props->shared));
$this->assertSame('value', $page->props->auth->refresh_token);
}

public function test_lazy_props_are_not_included_by_default(): void
{
$request = Request::create('/users', 'GET');
Expand Down Expand Up @@ -678,4 +612,85 @@ public function test_the_page_url_doesnt_double_up(): void

$this->assertSame('/subpath/product/123', $page->url);
}

public function test_prop_as_basic_array(): void
{
$request = Request::create('/years', 'GET');

$response = new Response('Years', ['years' => [2022, 2023, 2024]], 'app', '123');
$response = $response->toResponse($request);
$view = $response->getOriginalContent();
$page = $view->getData()['page'];

$this->assertSame([2022, 2023, 2024], $page['props']['years']);
}

public function test_dot_notation_props_are_merged_with_shared_props(): void
{
$request = Request::create('/test', 'GET');

$response = new Response('Test', [
'auth' => ['user' => ['name' => 'Jonathan']],
'auth.user.is_super' => true,
], 'app', '123');
$response = $response->toResponse($request);
$view = $response->getOriginalContent();
$page = $view->getData()['page'];

$this->assertSame([
'auth' => [
'user' => [
'name' => 'Jonathan',
'is_super' => true,
],
],
], $page['props']);
}

public function test_dot_notation_props_are_merged_with_lazy_shared_props(): void
{
$request = Request::create('/test', 'GET');

$response = new Response('Test', [
'auth' => function () {
return ['user' => ['name' => 'Jonathan']];
},
'auth.user.is_super' => true,
], 'app', '123');

$response = $response->toResponse($request);
$view = $response->getOriginalContent();
$page = $view->getData()['page'];

$this->assertSame([
'auth' => [
'user' => [
'name' => 'Jonathan',
'is_super' => true,
],
],
], $page['props']);
}

public function test_dot_notation_props_are_merged_with_other_dot_notation_props(): void
{
$request = Request::create('/test', 'GET');

$response = new Response('Test', [
'auth.user' => ['name' => 'Jonathan'],
'auth.user.is_super' => true,
], 'app', '123');
$response = $response->toResponse($request);
$view = $response->getOriginalContent();
$page = $view->getData()['page'];

$this->assertSame([
'auth' => [
'user' => [
'name' => 'Jonathan',
'is_super' => true,
],
],
], $page['props']);
}
}
3 changes: 0 additions & 3 deletions tests/Stubs/ExampleMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@

class ExampleMiddleware extends Middleware
{
/**
* @var mixed
*/
protected $version;

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/Stubs/FakeResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FakeResource extends JsonResource
*
* @var string|null
*/
public static $wrap = null;
public static $wrap;

public function __construct(array $resource)
{
Expand Down

0 comments on commit dc06a8d

Please sign in to comment.