Skip to content

Commit

Permalink
Use parent localization when resolving link (#7093)
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurperton authored Nov 29, 2022
1 parent c1a979a commit 45cdf7b
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/Fieldtypes/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function augment($value)
return null;
}

$redirect = ResolveRedirect::resolve($value, $this->field->parent());
$redirect = ResolveRedirect::resolve($value, $this->field->parent(), true);

return $redirect === 404 ? null : $redirect;
}
Expand Down
27 changes: 23 additions & 4 deletions src/Routing/ResolveRedirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

namespace Statamic\Routing;

use Statamic\Contracts\Data\Localization;
use Statamic\Contracts\Entries\Entry;
use Statamic\Facades;
use Statamic\Facades\Site;
use Statamic\Structures\Page;
use Statamic\Support\Str;

class ResolveRedirect
{
public function __invoke($redirect, $parent = null)
public function __invoke($redirect, $parent = null, $localize = false)
{
return $this->resolve($redirect, $parent);
return $this->resolve($redirect, $parent, $localize);
}

public function resolve($redirect, $parent = null)
public function resolve($redirect, $parent = null, $localize = false)
{
if (is_null($redirect)) {
return null;
Expand All @@ -26,7 +28,7 @@ public function resolve($redirect, $parent = null)

if (Str::startsWith($redirect, 'entry::')) {
$id = Str::after($redirect, 'entry::');
$redirect = optional(Facades\Entry::find($id))->url() ?? 404;
$redirect = optional($this->findEntry($id, $parent, $localize))->url() ?? 404;
}

if (Str::startsWith($redirect, 'asset::')) {
Expand All @@ -37,6 +39,23 @@ public function resolve($redirect, $parent = null)
return is_numeric($redirect) ? (int) $redirect : $redirect;
}

private function findEntry($id, $parent, $localize)
{
if (! ($entry = Facades\Entry::find($id))) {
return null;
}

if (! $localize) {
return $entry;
}

$site = $parent instanceof Localization
? $parent->locale()
: Site::current()->handle();

return $entry->in($site) ?? $entry;
}

private function firstChildUrl($parent)
{
if (! $parent || ! $parent instanceof Entry) {
Expand Down
8 changes: 4 additions & 4 deletions tests/Feature/GraphQL/Fieldtypes/LinkFieldtypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function it_gets_a_hardcoded_url()
],
]);

ResolveRedirect::shouldReceive('resolve')->once()->with('/hardcoded', $entry)->andReturn('/hardcoded');
ResolveRedirect::shouldReceive('resolve')->once()->with('/hardcoded', $entry, true)->andReturn('/hardcoded');

$this->assertGqlEntryHas('link', ['link' => '/hardcoded']);
}
Expand All @@ -47,7 +47,7 @@ public function it_gets_an_entry()
],
]);

ResolveRedirect::shouldReceive('resolve')->once()->with('entry::123', $entry)->andReturn('/the-entry-url');
ResolveRedirect::shouldReceive('resolve')->once()->with('entry::123', $entry, true)->andReturn('/the-entry-url');

$this->assertGqlEntryHas('link', ['link' => '/the-entry-url']);
}
Expand All @@ -62,7 +62,7 @@ public function it_gets_a_child_url()
],
]);

ResolveRedirect::shouldReceive('resolve')->once()->with('@child', $entry)->andReturn('/the-first-child');
ResolveRedirect::shouldReceive('resolve')->once()->with('@child', $entry, true)->andReturn('/the-first-child');

$this->assertGqlEntryHas('link', ['link' => '/the-first-child']);
}
Expand All @@ -77,7 +77,7 @@ public function it_gets_a_404()
],
]);

ResolveRedirect::shouldReceive('resolve')->once()->with('entry::unknown', $entry)->andReturn(404);
ResolveRedirect::shouldReceive('resolve')->once()->with('entry::unknown', $entry, true)->andReturn(404);

$this->assertGqlEntryHas('link', ['link' => null]);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/Fieldtypes/LinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class LinkTest extends TestCase
public function it_augments_to_url()
{
ResolveRedirect::shouldReceive('resolve')
->with('entry::test', $parent = new Entry)
->with('entry::test', $parent = new Entry, true)
->once()
->andReturn('/the-redirect');

Expand All @@ -31,7 +31,7 @@ public function it_augments_invalid_entry_to_null()
// invalid entries come back from the ResolveRedirect class as a 404 integer

ResolveRedirect::shouldReceive('resolve')
->with('entry::test', $parent = new Entry)
->with('entry::test', $parent = new Entry, true)
->once()
->andReturn(404);

Expand Down
29 changes: 28 additions & 1 deletion tests/Routing/ResolveRedirectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,33 @@ public function it_resolves_references_to_entries()
$this->assertEquals('/the-entry', $resolver('entry::123'));
}

/** @test */
public function it_resolves_references_to_entries_localized()
{
$resolver = new ResolveRedirect;

$parentEntry = Mockery::mock(Entry::class);
$frenchEntry = Mockery::mock(Entry::class)->shouldReceive('url')->once()->andReturn('/le-entry')->getMock();
$defaultEntry = Mockery::mock(Entry::class)->shouldReceive('in')->once()->andReturn($frenchEntry)->getMock();
Facades\Entry::shouldReceive('find')->with('123')->once()->andReturn($defaultEntry);

$this->assertEquals('/le-entry', $resolver('entry::123', $parentEntry, true));
}

/** @test */
public function it_resolves_references_to_entries_localized_with_fallback()
{
$resolver = new ResolveRedirect;

$parentEntry = Mockery::mock(Entry::class);
$entry = Mockery::mock(Entry::class);
$entry->shouldReceive('in')->once()->andReturn(null);
$entry->shouldReceive('url')->once()->andReturn('/the-entry');
Facades\Entry::shouldReceive('find')->with('123')->once()->andReturn($entry);

$this->assertEquals('/the-entry', $resolver('entry::123', $parentEntry, true));
}

/** @test */
public function it_resolves_references_to_assets()
{
Expand All @@ -170,7 +197,7 @@ public function it_can_invoke_the_class_or_call_resolve()
{
$resolve = $this->partialMock(ResolveRedirect::class);

$resolve->shouldReceive('resolve')->once()->with('foo', 'bar')->andReturn('hello');
$resolve->shouldReceive('resolve')->once()->with('foo', 'bar', false)->andReturn('hello');

$this->assertEquals('hello', $resolve('foo', 'bar'));
}
Expand Down

0 comments on commit 45cdf7b

Please sign in to comment.