Skip to content

Commit

Permalink
make Link field arrayable
Browse files Browse the repository at this point in the history
  • Loading branch information
edalzell committed Nov 1, 2023
1 parent b6f37d3 commit 7d24800
Showing 1 changed file with 91 additions and 2 deletions.
93 changes: 91 additions & 2 deletions src/Fieldtypes/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
namespace Statamic\Fieldtypes;

use Facades\Statamic\Routing\ResolveRedirect;
use Statamic\Contracts\Assets\Asset as AssetContract;
use Statamic\Contracts\Data\Localization;
use Statamic\Contracts\Entries\Collection;
use Statamic\Contracts\Entries\Entry;
use Statamic\Facades;
use Statamic\Facades\Asset;
use Statamic\Facades\Blink;
use Statamic\Facades\Site;
use Statamic\Fields\ArrayableString;
use Statamic\Fields\Field;
use Statamic\Fields\Fieldtype;
use Statamic\Structures\Page;
use Statamic\Support\Str;

class Link extends Fieldtype
Expand Down Expand Up @@ -46,9 +51,13 @@ public function augment($value)
return null;
}

$redirect = ResolveRedirect::resolve($value, $this->field->parent(), true);
if (is_null($item = $this->resolve($value))) {
return null;
}

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

return $redirect === 404 ? null : $redirect;
return new ArrayableLink($item);
}

public function preload()
Expand Down Expand Up @@ -174,4 +183,84 @@ private function showAssetOption()
{
return $this->config('container') !== null;
}

private function resolve($value): string|Entry|AssetContract|null
{
if ($value === '@child') {
return $this->firstChildUrl($this->field->parent());
}

if (Str::startsWith($value, 'entry::')) {
return $this->findEntry(
Str::after($value, 'entry::'),
$this->field->parent(),
true
);
}

if (Str::startsWith($value, 'asset::')) {
return Asset::find(Str::after($value, 'asset::'));
}

return $value;
}

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) {
throw new \Exception("Cannot resolve a page's child redirect without providing a page.");
}

if (! $parent instanceof Page && $parent instanceof Entry) {
$parent = $parent->page();
}

$children = $parent->isRoot()
? $parent->structure()->in($parent->locale())->pages()->all()->slice(1, 1)
: $parent->pages()->all();

if ($children->isEmpty()) {
return 404;
}

return $children->first()->url();
}
}

class ArrayableLink extends ArrayableString
{
public function value()
{
if (is_string($this->value)) {
return $this->value;
}

return $this->value->url();
}

public function toArray()
{
if (is_string($this->value)) {
return ['url' => $this->value];
}

return $this->value->toAugmentedArray();
}
}

0 comments on commit 7d24800

Please sign in to comment.