Architektura
Sdílený systém pro Mall, Alza, feedy a budoucí konzumenty.
Žádný consumer NEdrží vlastní orig cache — všechny tahají z jednoho centrálního images_orig/
skladu, který se synchronizuje z Karat BLOB (databáze KARAT_PRILOHY).
Karat KARAT_PRILOHY.dba.w_WEB3_soubory_data
│
↓ (BLOB hex chunks → hex2bin → ZIP unwrap)
│
import-export/images_orig/{shard}/{idFile_filename} ← orig cache
│
↓ (variant processory - lazy on-demand nebo proaktivně)
│
import-export/mallImage/{…} ← Mall (2000px + 3:4 crop)
import-export/feedImage/{…} ← Feed (watermark v centru)
│
↓ (mirror do www pro public access)
│
www/imagesMall/{shard}/{webalized} ← Mall.si static URL
www/imagesFeed/{shard}/{raw} ← Feed static URL (BC sove)
Sync z Karatu
Lazy on-demand
Kdykoliv variant processor (MallImageProcessor, FeedWatermarkProcessor)
nebo public endpoint (PicturePresenter::actionFeed) potřebuje orig a nemá ho na disku,
zavolá KaratImageDownloader::downloadIfMissing($idFile, $fileName):
SELECT data, poradi FROM KARAT_PRILOHY.dba.w_WEB3_soubory_data WHERE id_file = ?- Concatenace hex chunků →
hex2bin() - Zápis do
images_orig/{shard}/{idFile_filename} - Pokud ZIP, extract a přejmenuj first inner soubor
Proaktivní batch (cron)
NomenImageBatchSync::sync($type, $nomen, $minutes) — cron */15 sync-from-karat?type=update.
Update mod = SELECT z w_WEB3_nomen_soubory WHERE ts >= now - 15 min.
Plný mod (1× týdně manuálně) = vše.
Diff strategy: KaratImageSyncLog drží per-file karat_ts. Pokud
logged_ts >= karat_ts a soubor existuje → cached (žádný download).
Varianty
| Varianta | Processor | Operace | Mirror |
|---|---|---|---|
| Mall | MallImageProcessor |
Resize na max 2000px + crop na poměr 3:4 | www/imagesMall/ (webalize) |
| Feed | FeedWatermarkProcessor |
$image->place($wm, center) — watermark v centru |
www/imagesFeed/ (raw filename, BC) |
Watermark image path v parameters.imageStorage.watermarkImagePath (common.neon) —
aktivní: %wwwDir%/assets/feed-watermark.png (VAPOL.cz logo převzaté ze sovy,
umístí se do středu). NULL = watermark vypnut, fallback raw orig kopie do mirroru.
Cache gotcha: ensureProcessed při existujícím mirroru vrací cache hit
bez přegenerování. Při zapnutí/změně watermark PNG proto smaž www/imagesFeed/ +
import-export/feedImage/, jinak se staré (nezvodoznakované) mirrory nepřegenerují.
Per-partner volba s/bez vodoznaku: partner_col_perm.obrazek_bez_vodoznaku
(default true = raw orig BEZ znaku). false = watermarked /imagesFeed/.
Viz feed docu.
Public endpointy
| URL | Auth | Vrací |
|---|---|---|
{imagesMall/shard/file}.png |
— | Apache static (Mall.si zná URL z PUT payloadu) |
/picture/alza/{shard}/{file}?hash=… |
today hash | raw orig přes FileResponse |
/picture/feed/{shard}/{file}?hash=… |
today hash | raw orig přes FileResponse |
{imagesFeed/shard/file}.png |
— | watermarked static (stabilní URL bez hashe) + generate-on-miss |
Generate-on-miss (watermark obrázky)
Feed emituje statickou URL {base}/imagesFeed/{shard}/{file}
(bez hashe — partneři obrázky zobrazují dlouhodobě). Existující mirror servuje Apache přímo.
Pokud soubor chybí, www/.htaccess (RewriteCond !-f +
RewriteRule ^imagesFeed/ index.php) pošle request do PHP na routu
imagesFeed/{shard}/{file} → PicturePresenter::actionFeedWatermark,
která ho lazy vygeneruje do www/imagesFeed/ a pošle. Každý další hit už jde
staticky přes Apache (bez PHP) — vhodné pro objem (obrázky = ~88 % feed provozu).
Today hash
md5('today is ' . date('Y-m-d'))
// rotuje denně, sove pattern 1:1 — jen raw orig (/picture/feed, /picture/alza)
Tracking (sync log)
Tabulka karat_image_sync_log drží per-file stav (single source of truth).
| id_file | BIGINT PK |
|---|---|
| id_nomenklatury | VARCHAR(45) |
| file_name, karat_ts, last_sync_ts, size_bytes | — |
| status | pending | ok | error |
| error_message | TEXT |
| variants | JSONB — např. ["mall", "feed"] |
Variant processory volají markVariantProcessed($idFile, $tag) po prvním
úspěšném runu (JSONB append, idempotent). Admin v UI vidí které varianty už mají mirror.
Microsecond precision gotcha: Karat w_WEB3_nomen_soubory.ts
má .uuu. Log ukládá s format('Y-m-d H:i:s.u'), NEcastovat na string
při čtení (ztratíš µs → diff vždy false → re-download).
Core:
- Services/Image/ImagePathResolver
- Services/Image/KaratImageDownloader
- Services/Image/PictureAuthService
- Services/Image/PictureEndpointRegistry
Sync:
- Services/Image/Sync/KaratImageSyncLog
- Services/Image/Sync/NomenImageBatchSync
Variant:
- Services/Image/Variant/MallImageProcessor
- Services/Image/Variant/FeedWatermarkProcessor
Presenter:
- Presenters/PicturePresenter
- Presenters/NomenImagePresenter (admin)
- ConsoleModule/Presenters/ConsoleNomenImagesPresenter
Karat:
- KaratService::getNomenKaratPictures
- KaratService::getNomenPicturesForNomens
- KaratService::getNomenPicturesBatch