Return same-site illustration URLs in serialized articles

This commit is contained in:
Codex 2026-10-30 12:25:24 +08:00
parent 9d2cd9a895
commit ce27dbdd1e
3 changed files with 18 additions and 5 deletions

View File

@ -20,6 +20,16 @@ public function getSThumbAttribute($value)
return \App\Services\IllustrationPool::thumbnail($this->attributes, $value); return \App\Services\IllustrationPool::thumbnail($this->attributes, $value);
} }
public function attributesToArray(): array
{
$attributes = parent::attributesToArray();
// Laravel's snake-case mutator discovery misses the legacy camelCase column.
if (array_key_exists('sThumb', $attributes)) {
$attributes['sThumb'] = $this->getAttribute('sThumb');
}
return $attributes;
}
protected $appends = ['s_created_at_diff']; protected $appends = ['s_created_at_diff'];
use Searchable; use Searchable;

View File

@ -82,7 +82,7 @@ public static function assign(string $pool, array $keys): array
$selections = self::assignSource($pool, $keys); $selections = self::assignSource($pool, $keys);
if (LocalIllustrations::enabled()) { if (LocalIllustrations::enabled()) {
foreach ($selections as $key => &$image) { foreach ($selections as $key => &$image) {
$image['url'] = app(LocalIllustrations::class)->storeSelection($pool, $key, $image); $image['url'] = url(app(LocalIllustrations::class)->storeSelection($pool, $key, $image));
} }
unset($image); unset($image);
} }
@ -112,7 +112,8 @@ public static function thumbnail(array $article, ?string $original): ?string
$pool = config('illustrations.categories.'.($article['iCategoryId'] ?? '')); $pool = config('illustrations.categories.'.($article['iCategoryId'] ?? ''));
if (!$pool || empty($article['sSlug'])) return $original; if (!$pool || empty($article['sSlug'])) return $original;
if (LocalIllustrations::enabled()) { if (LocalIllustrations::enabled()) {
return app(LocalIllustrations::class)->thumbnail($pool, $article['sSlug']); $url = app(LocalIllustrations::class)->thumbnail($pool, $article['sSlug']);
return $url ? url($url) : null;
} }
if (!self::enabled()) return $original; if (!self::enabled()) return $original;
try { try {

View File

@ -71,7 +71,9 @@ public function test_content_hash_deduplicates_assets_and_page_reads_make_no_htt
config(['illustrations.enabled' => false]); // Frontend survives Resource being disabled. config(['illustrations.enabled' => false]); // Frontend survives Resource being disabled.
for ($i = 0; $i < 5; $i++) { for ($i = 0; $i < 5; $i++) {
$a = new Articles(['iCategoryId' => 1, 'sSlug' => 'fn1', 'sThumb' => 'https://old.invalid/image']); $a = new Articles(['iCategoryId' => 1, 'sSlug' => 'fn1', 'sThumb' => 'https://old.invalid/image']);
$this->assertSame($url, $a->sThumb); $this->assertSame(url($url), $a->sThumb);
$this->assertSame($a->sThumb, $a->toArray()['sThumb']);
$this->assertSame($a->sThumb, json_decode($a->toJson(), true)['sThumb']);
} }
Http::assertNothingSent(); Http::assertNothingSent();
} }
@ -103,9 +105,9 @@ public function test_new_article_assignment_downloads_before_returning_local_url
$this->fakeImages(); $this->fakeImages();
Http::fake(['https://resource-v2.gemcook.net/api/v2/pools/freenode/selections' => Http::response(['data' => ['selections' => ['fn1' => $this->image()]]])]); Http::fake(['https://resource-v2.gemcook.net/api/v2/pools/freenode/selections' => Http::response(['data' => ['selections' => ['fn1' => $this->image()]]])]);
$first = IllustrationPool::forArticle('freenode', 'fn1'); $first = IllustrationPool::forArticle('freenode', 'fn1');
$this->assertSame('/images/illustrations/'.$this->sha.'.png', $first); $this->assertSame(url('/images/illustrations/'.$this->sha.'.png'), $first);
$this->assertSame($first, IllustrationPool::forArticle('freenode', 'fn1')); $this->assertSame($first, IllustrationPool::forArticle('freenode', 'fn1'));
$this->assertSame($first, app(LocalIllustrations::class)->thumbnail('freenode', 'fn1')); $this->assertSame($first, url(app(LocalIllustrations::class)->thumbnail('freenode', 'fn1')));
Http::assertSentCount(4); // Two assignment requests; content downloaded once. Http::assertSentCount(4); // Two assignment requests; content downloaded once.
} }