Skip to content

Commit

Permalink
$field->toResolvedUrls()
Browse files Browse the repository at this point in the history
  • Loading branch information
distantnative committed Nov 21, 2023
1 parent c9ebccc commit c1ba8b1
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 11 deletions.
31 changes: 31 additions & 0 deletions config/methods.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\NotFoundException;
use Kirby\Image\QrCode;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Dom;
use Kirby\Toolkit\Str;
use Kirby\Toolkit\V;
use Kirby\Toolkit\Xml;
use Kirby\Uuid\Uuid;

/**
* Field method setup
Expand Down Expand Up @@ -247,6 +250,34 @@
return $field->isNotEmpty() ? new QrCode($field->value) : null;
},

/**
* Parses the field value as DOM and replaces
* any permalinks in href/src attributes with
* the regular url
*/
'toResolvedUrls' => function (Field $field): Field {
if ($field->isNotEmpty() === true) {
$dom = new Dom($field->value);
$attributes = ['href', 'src'];
$elements = $dom->query('//*[' . implode(' | ', A::map($attributes, fn ($attribute) => '@' . $attribute)) . ']');

foreach ($elements as $element) {
foreach ($attributes as $attribute) {
if ($url = $element->getAttribute($attribute)) {
if ($uuid = Uuid::for($url)) {
$url = $uuid->model()->url();
$element->setAttribute($attribute, $url);
}
}
}
}

$field->value = $dom->toString();
}

return $field;
},

/**
* Converts a yaml field to a Structure object
*/
Expand Down
34 changes: 24 additions & 10 deletions src/Uuid/Uuid.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,30 @@ final public static function for(

// for UUID string
if (is_string($seed) === true) {
return match (Str::before($seed, '://')) {
'page' => new PageUuid(uuid: $seed, context: $context),
'file' => new FileUuid(uuid: $seed, context: $context),
'site' => new SiteUuid(uuid: $seed, context: $context),
'user' => new UserUuid(uuid: $seed, context: $context),
// TODO: activate for uuid-block-structure-support
// 'block' => new BlockUuid(uuid: $seed, context: $context),
// 'struct' => new StructureUuid(uuid: $seed, context: $context),
default => throw new InvalidArgumentException('Invalid UUID URI: ' . $seed)
};
if ($uri = Str::before($seed, '://')) {
return match ($uri) {
'page' => new PageUuid(uuid: $seed, context: $context),
'file' => new FileUuid(uuid: $seed, context: $context),
'site' => new SiteUuid(uuid: $seed, context: $context),
'user' => new UserUuid(uuid: $seed, context: $context),
// TODO: activate for uuid-block-structure-support
// 'block' => new BlockUuid(uuid: $seed, context: $context),
// 'struct' => new StructureUuid(uuid: $seed, context: $context),
default => throw new InvalidArgumentException('Invalid UUID URI: ' . $seed)
};
}

// permalinks
if ($url = Str::after($seed, '/@/')) {
$parts = explode('/', $url);

return static::for(
$parts[0] . '://' . $parts[1],
$context
);
}

throw new InvalidArgumentException('Invalid UUID string: ' . $seed);
}

// for model object
Expand Down
35 changes: 34 additions & 1 deletion tests/Content/FieldMethodsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,39 @@ public function testToQrCode()
$this->assertNull($this->field()->toQrCode());
}

public function testToResolvedUrls()
{
$app = new App([
'roots' => [
'index' => $this->tmp
],
'site' => [
'children' => [
[
'slug' => 'a',
'content' => [
'uuid' => 'my-page'
],
'files' => [
[
'filename' => 'test.jpg',
'content' => [
'uuid' => 'my-file',
]
]
]
],
]
]
]);

$field = $this->field('<p>This is a <a href="/@/page/my-page">test</a><img src="/@/file/my-file"></p>');
$result = $field->toResolvedUrls();
$hash = $app->file('a/test.jpg')->mediaHash();

$this->assertSame('<p>This is a <a href="/a">test</a><img src="/media/pages/a/' . $hash . '/test.jpg"></p>', (string)$result);
}

public function testToStructure()
{
$data = [
Expand Down Expand Up @@ -440,7 +473,7 @@ public function testToDefaultUrl()
$this->assertSame($expected, $field->toUrl());
}

public function testToCustomUrl()
public function testToUrlCustom()
{
$app = new App([
'roots' => [
Expand Down
40 changes: 40 additions & 0 deletions tests/Uuid/UuidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Kirby\Uuid;

use Generator;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\LogicException;
use Kirby\Toolkit\Str;

Expand Down Expand Up @@ -161,6 +162,45 @@ public function testForUuidString()
// $this->assertInstanceOf(StructureUuid::class, Uuid::for('struct://my-id'));
}

/**
* @covers ::for
*/
public function testForUuidStringInvalid()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid UUID URI: foo://my-id');
Uuid::for('foo://my-id');
}

/**
* @covers ::for
*/
public function testForPermalinkString()
{
$this->assertInstanceOf(PageUuid::class, Uuid::for('/@/page/my-id'));
$this->assertInstanceOf(FileUuid::class, Uuid::for('/@/file/my-id'));
}

/**
* @covers ::for
*/
public function testForPermalinkStringInvalid()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid UUID URI: foo://my-id');
Uuid::for('/@/foo/my-id');
}

/**
* @covers ::for
*/
public function testForStringInvalid()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid UUID string: foo˜bar');
Uuid::for('foo˜bar');
}

/**
* @covers ::for
*/
Expand Down

0 comments on commit c1ba8b1

Please sign in to comment.