# Module Concert Magellio

Mini-site **concerts** isolé dans `pages/concert/` — même architecture que le module tennis, prêt pour un déploiement par copie de répertoire.

## Structure

```
pages/concert/
├── concerts.php              # Liste (semaine prochaine + mois suivant + tableau)
├── concert-details.php       # Fiche concert + hôtels (cache HTML 15 j)
├── concert-sync.php          # Endpoint cron JSON (token)
├── admin_bootstrap.inc.php   # Hooks admin (chargé par pages/admin.php)
├── .htaccess                 # URLs propres concert-tour-*-C{id}.html
├── README.md
├── data/
│   ├── top100_artists.json   # Top 100 artistes (Wikipedia best-selling)
│   └── refresh_top100.php    # Script CLI pour regénérer la liste
├── sql/
│   └── concerts_schema.sql   # CREATE TABLE concerts
└── includes/
    ├── concert_functions.php
    ├── concert_top100.inc.php
    ├── concert-display-concerts.php
    ├── header-concert.php
    ├── concert_sync.inc.php
    ├── concert_sync_wikipedia.inc.php
    ├── concert_sync_seed.inc.php
    ├── magellio_concert_sync.inc.php
    ├── magellio_concert_cron.inc.php
    ├── magellio_admin_concert_view.inc.php
    ├── concert_page_cache.inc.php
    ├── concert_hotel_curator.inc.php
    ├── concert-detail-styles.inc.php
    └── concert-hero.inc.php
```

## Déploiement serveur

1. **Copier le dossier** `pages/concert/` sur le serveur (FTP/rsync).
2. **Exécuter le SQL** : `sql/concerts_schema.sql` sur la base Magellio.
3. **Vhost prod** (recommandé) : `concert.magellio.com` → document root pointant vers `pages/concert/` ou rewrite vers ce sous-répertoire. La marque est déjà déclarée dans `pages/includes/start.php` (`concert.magellio.com`).
4. **Alternative** : laisser sous `www.magellio.com/pages/concert/concerts.php` (local : `http://magellio.test/pages/concert/concerts.php`).
5. **Cron** : activer depuis Admin → Concerts, ou appeler :
   ```
   curl -fsS 'https://www.magellio.com/pages/concert/concert-sync.php?token=TOKEN&months=12'
   ```
   Token par défaut : variable d’env `MAGELLIO_CONCERT_SYNC_TOKEN` ou valeur dans `magellio_concert_sync.inc.php`.
6. **Cache** : `content/concert/cache/concert-tours/` (prod) ou `pages/content/concert/` (local).

## Intégration site principal (minimale)

- `pages/includes/start.php` : host `concert.magellio.com` + override local si URL contient `/concert/`.
- `pages/admin.php` : `require` de `concert/admin_bootstrap.inc.php` + vue `?view=concert`.

Aucun fichier concert dans `pages/includes/` (sauf ce glue).

## Sources de données (MVP)

| Source | Statut |
|--------|--------|
| Wikipedia `Category:YYYY_concert_tours` | Implémenté (infobox + **dates par show** pour top 100) |
| Wikipedia EN `YYYY concert tours` | Implémenté (tableau, si la page existe) |
| **Top 100 artistes** (`data/top100_artists.json`) | Filtre sync + visibilité DB |
| Seed local (Coldplay, Taylor Swift, Oasis…) | Fallback si toutes les sources vides |
| Ticketmaster Discovery API | Recommandé prochaine étape (clé gratuite, dates réelles) |
| Songkick / Bandsintown | Non implémenté (API payante / partenariat requis) |

## Filtre Top 100 artistes mondiaux

Seules les tournées dont l’artiste figure dans le **top 100 des meilleures ventes mondiales** (Wikipedia) sont synchronisées et affichées.

### Source retenue (MVP)

**Wikipedia — [List of best-selling music artists](https://en.wikipedia.org/wiki/List_of_best-selling_music_artists)**  
Pas de clé API. Les 100 premiers artistes des paliers « 250M+ », « 200M+ », « 120M+ », « 100M+ » ventes certifiées sont extraits dans `data/top100_artists.json`.

Alternatives évaluées :

| Approche | Verdict |
|----------|---------|
| Wikipedia best-selling | **Retenu** — gratuit, stable, critère « artistes mondiaux » |
| Last.fm chart API | Gratuit mais reflète l’écoute récente, pas les ventes globales |
| Spotify Top Artists | OAuth + quotas, trop lourd pour le MVP |
| Billboard scrape | Fragile juridiquement / HTML instable |
| MusicBrainz | Identifiants utiles mais pas de classement « top 100 » |
| JSON statique curaté | Complément via `aliases` dans le JSON |

### Matching flou

Lors de la sync, le nom d’artiste est comparé à la liste avec normalisation :

- minuscules, sans accents
- suppression du préfixe « The »
- suppression des parenthèses `(band)`, `(musician)`…
- comparaison aussi sur le titre complet (`Artist — Tour name`)

### Rafraîchir la liste top 100

```bash
php pages/concert/data/refresh_top100.php
```

Le script interroge l’API MediaWiki Wikipedia, met à jour `data/top100_artists.json` (100 artistes) et conserve les `aliases` existants. À lancer manuellement ou en cron trimestriel.

Pour ajouter un alias manuel (ex. variante de nom) :

```json
"aliases": {
  "weeknd": "The Weeknd"
}
```

### Sync avec filtre

```bash
curl -s 'http://magellio.test/pages/concert/concert-sync.php?token=magellio-concert-sync-8e4b0d3f2c95e7160a9f3b2e5d8c7f1'
```

La réponse JSON inclut :

- `fetched` : concerts retenus après filtre top 100
- `top100.skipped` : concerts ignorés (artiste hors liste)
- `top100.skipped_artists` : noms des artistes exclus
- `stats.top100_hidden` : lignes existantes masquées en base

Les concerts déjà en base mais hors top 100 passent à `display = 0` à chaque sync.

## Packages hôtel (quand sont-ils créés ?)

| Mécanisme | Moment | Persistant ? |
|-----------|--------|--------------|
| **`selection_id > 0`** | Admin / scripts `buildPack` | Oui — lignes dans `Packages` |
| **Curation automatique** | **Première visite** (ou cache expiré) de `concert-details.php` | Non — 3×5★, 3×4★, 3×3★, 3 appartements via Booking + WS Magellio |
| **Sync concert** | Cron `concert-sync.php` | Non pour les packages — enrichit ville, aéroport (`ZRH`…), GPS, dates |

Si `selection_id = 0` (cas Linkin Park / Zurich), les hôtels apparaissent quand même grâce à `getConcertHotelsCurated()` — pas besoin d’attendre une sync package.

### Photos hôtel (cartes fiche concert)

Les cartes utilisent la **photo principale Booking** (`main_photo` dans `getHoteldetails_V3`), comme le module tennis. Si `hoteldeals.Hotel_Main_Photo` est vide au moment de la curation, un appel batch WS Magellio récupère la photo avant affichage ; le slider tennis (`tennis-2.webp`) n’est utilisé qu’en dernier recours sans photo WS.

## Tests locaux

```bash
php -l pages/concert/concerts.php
php pages/concert/data/refresh_top100.php
curl -s 'http://magellio.test/pages/concert/concerts.php' | head
curl -s 'http://magellio.test/pages/concert/concert-sync.php?token=...'
```

## URLs

- Liste : `/pages/concert/concerts.php`
- Détail : `/pages/concert/concert-tour-{slug}-C{id}.html` (avec `.htaccess`)
- Admin : `/pages/admin.php?view=concert`
