45 lines
2.8 KiB
PHP
45 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\ContentCenter;
|
|
|
|
use App\Services\Ranking\ArticleDocument;
|
|
use Carbon\CarbonImmutable;
|
|
use Symfony\Component\Yaml\Yaml;
|
|
|
|
final class ArticleArtifact
|
|
{
|
|
public function build(array $data): array
|
|
{
|
|
validator($data, ['source_key' => 'required|string|max:160', 'revision' => 'required|string|size:64', 'generation' => 'required|integer|min:1', 'title' => 'required|string|max:200', 'text' => 'present|string|max:100000', 'sent_at' => 'required|date', 'images' => 'present|array|max:30', 'images.*.sha256' => 'required|regex:/^[a-f0-9]{64}$/D', 'images.*.mime' => 'required|in:image/png,image/jpeg,image/webp,image/gif', 'images.*.bytes' => 'required|integer|min:1|max:20971520'])->validate();
|
|
validator($data, ['links' => 'sometimes|array|max:100', 'links.*.offset' => 'required|integer|min:0', 'links.*.length' => 'required|integer|min:1', 'links.*.url' => 'required|string|max:4096'])->validate();
|
|
$code = 'telefox-'.substr(hash('sha256', $data['source_key']), 0, 24);
|
|
$body = "<div v-pre>\n".implode("\n", array_map(fn ($s) => '<p>'.htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8').'</p>', explode("\n", $data['text'])))."\n</div>\n\n";
|
|
$review = ReviewFormat::build($data);
|
|
if ($review) {
|
|
$body = $review['body'];
|
|
}
|
|
foreach ($data['images'] as $image) {
|
|
$body .= '.")\n\n";
|
|
}
|
|
$meta = ['title' => $review['title'] ?? $data['title'], 'createTime' => CarbonImmutable::parse($data['sent_at'], 'UTC')->setTimezone('Asia/Shanghai')->format('Y-m-d H:i:s'), 'permalink' => '/jccp/'.$code.'/', 'articleCode' => $code, 'tags' => $review['tags'] ?? [], 'sourceKey' => $data['source_key']];
|
|
$series = TitleSeries::metadata($meta['title'], $data['source_key']);
|
|
$meta = array_replace($meta, $series);
|
|
$document = ['meta' => $meta, 'body' => $body];
|
|
if (class_exists(ArticleDocument::class)) {
|
|
$document = ArticleDocument::enrich($document);
|
|
}
|
|
|
|
return ['source_key' => $data['source_key'], 'revision' => $data['revision'], 'generation' => $data['generation'], 'article_code' => $code, 'relative_path' => 'jccp/'.$code.'.md', 'permalink' => $meta['permalink'], 'title' => $document['meta']['title'], 'format_version' => 'ttc-native-v2', 'markdown' => "---\n".Yaml::dump($document['meta'], 6, 2)."---\n".$document['body'], 'images' => $data['images']];
|
|
}
|
|
|
|
public static function extension(string $mime): string
|
|
{
|
|
return ['image/png' => '.png', 'image/jpeg' => '.jpg', 'image/webp' => '.webp', 'image/gif' => '.gif'][$mime];
|
|
}
|
|
|
|
public static function hash(array $artifact): string
|
|
{
|
|
return hash('sha256', json_encode($artifact, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
}
|
|
}
|