Lecteur Markdown
CHECKLINKS_DOCUMENTATION
Checklinks #
Vérificateur automatique de liens morts dans BeamReactor.
Namespace: `ChecklinksScanner`
Version: 1.2.0
Niveau requis: Administrateur
Depuis: 2002
Vue d'ensemble #
Scanner multi-source qui détecte les liens HTTP morts (4xx, 5xx, timeout) en analysant automatiquement les tables de base de données configurées via des fichiers de configuration JSON par plugin.
Fonctionnalités #
- Scan automatique multi-plugins via configuration JSON
- Détection parallèle avec `curl_multi`
- Export CSV et JSON des liens morts
- Interface de lancement avec rapport détaillé
- Support de patterns d'URL complexes avec paramètres multiples
Architecture #
Fichier principal : `checklinks.php` #
Interface utilisateur :
- Bouton de lancement du scan
- Affichage des résultats en textarea
- Export CSV/JSON via formulaires POST
Bibliothèque : `checklinks.lib.inc.php` #
Classe `ChecklinksScanner` :
- `getAllUrls()` — Collecte des URLs depuis les configurations
- `scan(array $urls)` — Vérification HTTP parallèle
Configuration par plugin #
Chaque plugin peut définir ses sources d'URLs via :
Emplacement : `plugins/{plugin}/conf/{plugin}.sitemap.json`
Structure :
{
"enabled": true,
"sources": [
{
"type": "database",
"table": "nom_table",
"url_pattern": "index.php?obj=plugin.php&id=%s&lang=%s",
"url_params": ["id", "lang"],
"column_id": "id",
"column_lang": "language"
}
]
}
Champs de configuration #
| Champ | Type | Description |
|-------|------|-------------|
| `enabled` | bool | Active/désactive ce plugin |
| `type` | string | Toujours `"database"` |
| `table` | string | Nom de la table SQL |
| `url_pattern` | string | Pattern avec placeholders `%s` (compatible `vsprintf`) |
| `url_params` | array | Liste ordonnée des paramètres (ex: `["id", "lang"]`) |
| `column_{param}` | string | Nom de colonne SQL pour chaque paramètre |
Exemple multi-paramètres #
{
"url_pattern": "index.php?obj=docs.php&cat=%s&doc=%s&lang=%s",
"url_params": ["cat", "doc", "lang"],
"column_cat": "category_id",
"column_doc": "document_id",
"column_lang": "language"
}
Classe ChecklinksScanner #
Constructeur #
public function __construct()
Initialise `$baseUrl` depuis `$cfg[0]` en nettoyant les `/index.php` en fin de chaîne.
getAllUrls #
public function getAllUrls(): array
Retourne : Tableau d'items :
[
[
'url' => 'https://example.com/index.php?obj=blog.php&id=42&lang=fr',
'source' => 'blog',
'document' => '42',
'lang' => 'fr'
],
...
]
Comportement :
1. Parcourt `plugins//conf/.sitemap.json`
2. Vérifie `enabled: true`
3. Construit requêtes SQL dynamiques selon `url_params`
4. Génère URLs via `vsprintf($url_pattern, $values)`
5. Normalise les slashes et évite `index.php/index.php`
Gestion d'erreurs :
- Ignore plugins sans configuration
- Log les erreurs SQL via `error_log()`
- Continue en cas d'échec sur un plugin
scan #
public function scan(array $urls): array
Paramètres :
- `$urls` — Tableau retourné par `getAllUrls()`
Retourne : Liens morts uniquement :
[
[
'url' => 'https://...',
'code' => 404,
'source' => 'blog',
'document' => '42',
'lang' => 'fr'
],
...
]
Comportement :
- Utilise `curl_multi` pour parallélisation
- Options cURL :
- `CURLOPT_FOLLOWLOCATION` — Suit les redirections
- `CURLOPT_NOBODY` — HEAD request (pas de body)
- `CURLOPT_TIMEOUT` — 20 secondes
- Considère comme mort : `code >= 400` ou `code == 0` (timeout/DNS)
Interface utilisateur #
Lancement du scan #
<form method="post">
<button type="submit" name="launch">Lancer le scan</button>
</form>
Affichage des résultats #
Format textarea avec :
- Code HTTP
- URL complète
- Source (plugin)
- Document ID
- Langue
Export #
Deux boutons POST avec `base64_encode()` du contenu :
| Bouton | Paramètre | Format | Nom fichier |
|--------|-----------|--------|-------------|
| Export CSV | `export_csv` | CSV RFC 4180 | `liens-morts-{date}.csv` |
| Export JSON | `export_json` | JSON pretty-print | `liens-morts-{date}.json` |
Headers :
// CSV
Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="liens-morts-2026-01-15_143022.csv"
// JSON
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment; filename="liens-morts-2026-01-15_143022.json"
Locale #
Fichier : `getlocale('checklinks')`
Variable : `$dialchecklinks[]`
| Index | Usage |
|-------|-------|
| 1 | Message début de scan |
| 2 | Template durée (`sprintf`) |
| 5 | Label "liens morts" |
| 15 | Bouton export CSV |
| 16 | Bouton export JSON |
| 17 | Message "aucun lien mort" |
| 18 | Label bouton lancement |
Dépendances #
- `Beamreactor\Database\SQL` — Requêtes préparées
- `curl_multi_*()` — Extension cURL avec support multi
- `frameheader()` / `framefooter()` — Système de frame BeamReactor
Cas particuliers #
vsprintf vs sprintf #
`vsprintf()` est utilisé pour supporter N paramètres dynamiques sans connaître leur nombre à l'avance.
Exemple :
$url_pattern = "?obj=x.php&a=%s&b=%s&c=%s";
$url_params = ["a", "b", "c"];
$values = [1, 2, 3];
vsprintf($url_pattern, $values); // "?obj=x.php&a=1&b=2&c=3"
Limitations connues #
- Pas de support HTTPS avec certificats auto-signés (cURL strict)
- Timeout fixe à 20 secondes (non configurable)
- Pas de retry automatique
- `CURLOPT_NOBODY` peut échouer sur certains serveurs (préférer GET si problèmes)
Exemple de flux complet #
1. Admin clique "Lancer le scan"
2. `getAllUrls()` collecte 1500 URLs depuis 12 plugins
3. `scan()` lance 1500 requêtes HEAD parallèles
4. Détecte 23 liens morts (404, 500, timeout)
5. Affiche résultats en textarea
6. Admin exporte CSV pour traitement
7. Fichier téléchargé : `liens-morts-2026-01-15_143022.csv`
Performance #
Scan de 5000 URLs : ~45 secondes
Parallélisation : `curl_multi` limite hardware (~100 connexions simultanées)
Mémoire : Proportionnelle au nombre d'URLs (env. 200 bytes/URL)
Sécurité #
- Pas de validation externe des URLs (confiance totale dans la config JSON)
- Base64 pour transport POST (pas de chiffrement, juste encodage)
- Aucune sanitisation des données exportées (CSV échappé via `str_replace('"', '""')`)
- User-Agent personnalisé : `BeamReactor-DeadLinkScanner/2026`