Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions app/Views/libri/scheda_libro.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,25 @@ class="inline-flex items-center px-2 py-1 rounded-full text-sm bg-gray-100 text-
<span class="font-medium"><?= __("Genere:") ?></span>
<?php
$genreParts = [];
if (!empty($libro['radice_id'])) {
$genreParts[] = [(int)$libro['radice_id'], (string)$libro['radice_nome']];
}
if (!empty($libro['genere_id'])) {
$genName = (string)$libro['genere_nome'];
if (strpos($genName, ' - ') !== false) {
$parts = explode(' - ', $genName);
$genName = end($parts);
$addGenrePart = static function (int $id, ?string $name) use (&$genreParts): void {
$name = trim((string)$name);
if ($id <= 0 || $name === '') {
return;
}
$genreParts[] = [(int)$libro['genere_id'], $genName];
}
if (!empty($libro['sottogenere_id'])) {
$genreParts[] = [(int)$libro['sottogenere_id'], (string)$libro['sottogenere_nome']];
}
if (strpos($name, ' - ') !== false) {
$parts = explode(' - ', $name);
$name = trim((string)end($parts));
}
foreach ($genreParts as $part) {
if ((int)$part[0] === $id) {
return;
}
}
$genreParts[] = [$id, $name];
};
$addGenrePart((int)($libro['radice_id'] ?? 0), $libro['radice_nome'] ?? null);
$addGenrePart((int)($libro['genere_id_cascade'] ?? $libro['genere_id'] ?? 0), $libro['genere_nome'] ?? null);
$addGenrePart((int)($libro['sottogenere_id_cascade'] ?? $libro['sottogenere_id'] ?? 0), $libro['sottogenere_nome'] ?? null);
Comment on lines +242 to +244

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Usare l’escaping previsto per le view.

La lista viene renderizzata alla Line 250 con App\Support\HtmlHelper::e($gp[1]). In app/Views/** va usato htmlspecialchars($gp[1], ENT_QUOTES, 'UTF-8').

As per path instructions, nelle view HtmlHelper::e() è vietato.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Views/libri/scheda_libro.php` around lines 242 - 244, Replace the
`App\Support\HtmlHelper::e()` usage that renders the genre list around
`$addGenrePart` output with `htmlspecialchars($gp[1], ENT_QUOTES, 'UTF-8')`.
Keep the existing rendering logic and escaping behavior unchanged otherwise, and
do not use `HtmlHelper::e()` anywhere in this view.

Source: Path instructions

?>
<?php if (!empty($genreParts)): ?>
<?php foreach ($genreParts as $i => $gp): ?>
Expand Down
6 changes: 5 additions & 1 deletion tests/full-test.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2918,8 +2918,12 @@ test.describe.serial('Phase 18: Issue Regressions', () => {
// 1) Admin book detail page
await page.goto(`${BASE}/admin/books/${bookId}`);
await page.waitForLoadState('domcontentloaded');
const genreText = await page.locator('[data-testid="genre-display"]').textContent();
const genreDisplay = page.locator('[data-testid="genre-display"]');
const genreText = await genreDisplay.textContent();
expect(genreText).toContain(childName);
await expect(genreDisplay.locator('a')).toHaveCount(2);
await expect(genreDisplay.locator('a').nth(0)).toHaveAttribute('href', new RegExp(`/admin/books\\?genere=${rootId}$`));
await expect(genreDisplay.locator('a').nth(1)).toHaveAttribute('href', new RegExp(`/admin/books\\?genere=${childId}$`));

// 2) Frontend (public) book detail page — uses different query path
await page.goto(`${BASE}/libro/${bookId}`);
Expand Down