Fix article links and include full content in PHP feeds

Two bugs found by testing real links from the feed:
- Link format was wrong (?news=<internal-id>), landing on the general
  listing instead of the article. Traced the real network call the site
  makes when opening an item and found the actual pattern:
  /actualites/<slug>?u=<UID> (agenda: /agenda/<slug>?u=<UID>), where the
  JS router reads the `u` query param to fetch @results?UID=...&fullobjects=1.
- Description only used the short teaser (description_fr) even though the
  API response already includes the full rich-text body (text_fr.data) and
  attachments (items[].file.download) in the same call — no extra request
  needed, just wasn't being used.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
para
2026-09-25 23:45:55 +02:00
co-authored by Claude Sonnet 5
parent 113616995f
commit 7da5a7a3e6
3 changed files with 63 additions and 10 deletions
+50
View File
@@ -98,6 +98,56 @@ function strip_html(?string $text): string
return trim(preg_replace('/\s+/', ' ', $text));
}
/**
* Reproduit le slug d'URL genere par le site (cosmetique : le routeur
* JS de silly.be lit en realite le parametre `u` pour savoir quel item
* afficher, pas ce segment de chemin - mais autant coller a l'URL
* "officielle" telle qu'on la voit dans la barre d'adresse).
*/
function slugify(string $text): string
{
$ascii = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $text);
if ($ascii === false) {
$ascii = $text;
}
$ascii = strtolower($ascii);
$ascii = preg_replace('/[^a-z0-9]+/', '-', $ascii);
return trim($ascii, '-');
}
/**
* Construit le HTML des liens vers les pieces jointes (PDF, etc.)
* renvoyees par l'API dans le champ "items" de chaque actualite/evenement.
*/
function attachments_html(array $item): string
{
$html = '';
foreach ($item['items'] ?? [] as $sub) {
$url = $sub['file']['download'] ?? $sub['targetUrl'] ?? null;
if (!$url) {
continue;
}
$label = $sub['title'] ?? basename($url);
$html .= '<p><a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">'
. htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '</a></p>';
}
return $html;
}
/**
* Corps HTML complet d'un item (texte riche + pieces jointes), avec
* repli sur le resume court si le texte complet est vide.
*/
function full_body_html(array $item): string
{
$body = trim($item['text_fr']['data'] ?? '');
if ($body === '') {
$summary = strip_html($item['description_fr'] ?? $item['description'] ?? null);
$body = $summary !== '' ? '<p>' . htmlspecialchars($summary, ENT_QUOTES, 'UTF-8') . '</p>' : '';
}
return $body . attachments_html($item);
}
function rfc822(?string $isoDate): string
{
try {