23 changed files with 682 additions and 43 deletions
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace DoctrineMigrations; |
||||
|
||||
use Doctrine\DBAL\Schema\Schema; |
||||
use Doctrine\Migrations\AbstractMigration; |
||||
|
||||
/** |
||||
* Remove deprecated home-curation kind-1 cache rows (no longer written or read). |
||||
*/ |
||||
final class Version20260428103000 extends AbstractMigration |
||||
{ |
||||
public function getDescription(): string |
||||
{ |
||||
return 'Delete event rows with storage_role magazine_curation_kind1_ref (curation strip is 30023-only)'; |
||||
} |
||||
|
||||
public function up(Schema $schema): void |
||||
{ |
||||
$this->addSql("DELETE FROM event WHERE storage_role = 'magazine_curation_kind1_ref'"); |
||||
} |
||||
|
||||
public function down(Schema $schema): void |
||||
{ |
||||
// Irreversible data purge; rows were ephemeral cache copies of relay notes. |
||||
} |
||||
} |
||||
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Util; |
||||
|
||||
use App\Enum\KindsEnum; |
||||
|
||||
/** |
||||
* NIP-51 kind 30004 (curation set) for the home strip: ordered `a` tags for kind **30023** only. |
||||
* Other address kinds and `e` tags are ignored. |
||||
*/ |
||||
final class CurationSet30004Home |
||||
{ |
||||
/** |
||||
* @param iterable<int, mixed> $tags Event tag rows (Nostr JSON shape) |
||||
* |
||||
* @return array{title: string, items: list<array{type: 'article', pk: string, slug: string}>} |
||||
*/ |
||||
public static function parseTitleAndOrderedRefs(iterable $tags): array |
||||
{ |
||||
$title = ''; |
||||
$items = []; |
||||
foreach ($tags as $tag) { |
||||
if (!\is_array($tag) || $tag === []) { |
||||
continue; |
||||
} |
||||
$name = isset($tag[0]) ? strtolower((string) $tag[0]) : ''; |
||||
$v = isset($tag[1]) ? (string) $tag[1] : ''; |
||||
if ($v === '') { |
||||
continue; |
||||
} |
||||
if ($name === 'title' && $title === '') { |
||||
$title = trim($v); |
||||
continue; |
||||
} |
||||
if ($name !== 'a') { |
||||
continue; |
||||
} |
||||
$parts = explode(':', $v, 3); |
||||
if (\count($parts) < 3) { |
||||
continue; |
||||
} |
||||
$kind = (int) $parts[0]; |
||||
if ($kind !== KindsEnum::LONGFORM->value) { |
||||
continue; |
||||
} |
||||
$pk = strtolower(trim($parts[1])); |
||||
$slug = trim($parts[2]); |
||||
if (64 !== \strlen($pk) || !ctype_xdigit($pk) || $slug === '') { |
||||
continue; |
||||
} |
||||
$items[] = ['type' => 'article', 'pk' => $pk, 'slug' => $slug]; |
||||
} |
||||
|
||||
return ['title' => $title, 'items' => $items]; |
||||
} |
||||
} |
||||
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Tests\Util; |
||||
|
||||
use App\Util\CurationSet30004Home; |
||||
use PHPUnit\Framework\TestCase; |
||||
|
||||
final class CurationSet30004HomeTest extends TestCase |
||||
{ |
||||
public function testParsesTitleAndOrdered30023RefsOnly(): void |
||||
{ |
||||
$eid = 'd78ba0d5dce22bfff9db0a9e996c9ef27e2c91051de0c4e1da340e0326b4941e'; |
||||
$tags = [ |
||||
['d', 'jvdy9i4'], |
||||
['title', 'Yaks'], |
||||
['image', 'https://example.com/y.jpg'], |
||||
['a', '30023:26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:slug-one'], |
||||
['e', $eid], |
||||
['a', '30024:26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:draft-only'], |
||||
['a', '30023:26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:slug-two'], |
||||
]; |
||||
$out = CurationSet30004Home::parseTitleAndOrderedRefs($tags); |
||||
self::assertSame('Yaks', $out['title']); |
||||
self::assertSame([ |
||||
['type' => 'article', 'pk' => '26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c', 'slug' => 'slug-one'], |
||||
['type' => 'article', 'pk' => '26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c', 'slug' => 'slug-two'], |
||||
], $out['items']); |
||||
} |
||||
|
||||
public function testSkipsNon30023ATags(): void |
||||
{ |
||||
$tags = [ |
||||
['a', '30040:26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:mag'], |
||||
['a', '30023:26dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:ok'], |
||||
]; |
||||
$out = CurationSet30004Home::parseTitleAndOrderedRefs($tags); |
||||
self::assertSame('', $out['title']); |
||||
self::assertCount(1, $out['items']); |
||||
self::assertSame('article', $out['items'][0]['type']); |
||||
self::assertSame('ok', $out['items'][0]['slug']); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue