mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-nostr.git
synced 2026-04-10 14:38:41 +00:00
✨ Add rich Markdown normalization and paste handling.
- 🛠 Introduce `RichTextMarkdownNormalizer` to convert Markdown and mixed input to cleaner HTML. - 🗂 Include a new Blade partial to enable Markdown-on-paste behavior in rich-text editors. - 📋 Enhance `create` and `edit` forms to normalize descriptions and support Markdown conversion. - 🧪 Add test coverage for Markdown normalization scenarios. - 🛠 Add CLI command to normalize project proposal descriptions in bulk. - 🔧 Update `vite.config.js` for improved development setup (e.g., ignored paths).
This commit is contained in:
101
app/Console/Commands/NormalizeProjectProposalDescriptions.php
Normal file
101
app/Console/Commands/NormalizeProjectProposalDescriptions.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\ProjectProposal;
|
||||
use App\Support\RichTextMarkdownNormalizer;
|
||||
use Illuminate\Console\Attributes\Description;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
#[Signature('project-proposals:normalize-descriptions
|
||||
{--dry-run : Show what would change without writing to the database}
|
||||
{--id=* : Limit to specific proposal IDs}
|
||||
{--show-diff : Print a short before/after preview for every change}')]
|
||||
#[Description('Normalize project proposal descriptions so all rows contain clean HTML (converts legacy plain-text and mixed Markdown/HTML content).')]
|
||||
class NormalizeProjectProposalDescriptions extends Command
|
||||
{
|
||||
public function handle(): int
|
||||
{
|
||||
$dryRun = (bool) $this->option('dry-run');
|
||||
$showDiff = (bool) $this->option('show-diff');
|
||||
$ids = array_filter((array) $this->option('id'));
|
||||
|
||||
$normalizer = new RichTextMarkdownNormalizer;
|
||||
|
||||
$query = ProjectProposal::query()->orderBy('id');
|
||||
|
||||
if ($ids !== []) {
|
||||
$query->whereIn('id', $ids);
|
||||
}
|
||||
|
||||
$total = (clone $query)->count();
|
||||
|
||||
if ($total === 0) {
|
||||
$this->warn('No project proposals to process.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$this->info(sprintf(
|
||||
'%s %d project proposal description(s)%s.',
|
||||
$dryRun ? 'Analyzing' : 'Normalizing',
|
||||
$total,
|
||||
$dryRun ? ' (dry-run)' : '',
|
||||
));
|
||||
|
||||
$changed = 0;
|
||||
$unchanged = 0;
|
||||
$failed = 0;
|
||||
|
||||
$query->lazy()->each(function (ProjectProposal $proposal) use ($normalizer, $dryRun, $showDiff, &$changed, &$unchanged, &$failed): void {
|
||||
$original = (string) ($proposal->description ?? '');
|
||||
|
||||
try {
|
||||
$normalized = (string) ($normalizer->normalize($original) ?? '');
|
||||
} catch (\Throwable $exception) {
|
||||
$failed++;
|
||||
$this->error(sprintf('#%d %s — normalization failed: %s', $proposal->id, $proposal->name, $exception->getMessage()));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($original === $normalized) {
|
||||
$unchanged++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$changed++;
|
||||
$this->line(sprintf('<fg=yellow>~</> #%d %s', $proposal->id, $proposal->name));
|
||||
|
||||
if ($showDiff) {
|
||||
$this->line(' <fg=red>- '.$this->preview($original).'</>');
|
||||
$this->line(' <fg=green>+ '.$this->preview($normalized).'</>');
|
||||
}
|
||||
|
||||
if (! $dryRun) {
|
||||
$proposal->description = $normalized;
|
||||
$proposal->saveQuietly();
|
||||
}
|
||||
});
|
||||
|
||||
$this->newLine();
|
||||
$this->info(sprintf(
|
||||
'Done. Changed: %d, unchanged: %d, failed: %d%s',
|
||||
$changed,
|
||||
$unchanged,
|
||||
$failed,
|
||||
$dryRun ? ' (no writes performed)' : '',
|
||||
));
|
||||
|
||||
return $failed > 0 ? self::FAILURE : self::SUCCESS;
|
||||
}
|
||||
|
||||
private function preview(string $value): string
|
||||
{
|
||||
$collapsed = preg_replace('/\s+/', ' ', trim($value)) ?? '';
|
||||
|
||||
return mb_strimwidth($collapsed, 0, 140, '…');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user