# ─── Главная страница — index.html открывается по адресу домена ───────
DirectoryIndex index.html index.php

# ─── Сжатие ответов (PageSpeed: "Без сжатия") ──────────────────────────
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml
  AddOutputFilterByType DEFLATE application/javascript application/json application/xml
  AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/css text/plain text/xml
  AddOutputFilterByType BROTLI_COMPRESS application/javascript application/json application/xml
  AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>

# ─── Страницы ошибок ────────────────────────────────────────────────────
ErrorDocument 403 /403
ErrorDocument 404 /404
ErrorDocument 500 /500

RewriteEngine On
Options -Indexes

# ─── www -> non-www И http -> https, ОДНИМ правилом, для ВСЕГО сайта ───
# Раньше такое правило было только внизу файла и матчило лишь ^/?$ — то
# есть буквально саму главную страницу без пути. Из-за этого, например,
# http://www.quizo.ru/ru/cabinet/ вообще никуда не редиректился. Матчим
# теперь любой путь (^(.*)$) и подставляем его в итоговый https://quizo.ru/.
# Одно правило на оба условия (а не два последовательных редиректа) —
# заходя на http://www.quizo.ru/... пользователь получает ОДИН 301 прямо
# на https://quizo.ru/..., а не сначала на https://www.quizo.ru/... с
# последующим вторым редиректом на non-www следом.
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.quizo\.ru$ [NC]
RewriteRule ^(.*)$ https://quizo.ru/$1 [L,R=301]

# ─── sitemap.xml → sitemap.php ──────────────────────────────────────────
RewriteRule ^sitemap\.xml$ /sitemap.php [L]

# ─── /ru/ → / ────────────────────────────────────────────────────────────
# Только сам "голый" путь /ru/ (или /ru без слэша) — вложенные адреса вроде
# /ru/cabinet/ это правило не трогает, они продолжают работать как раньше.
RewriteRule ^ru/?$ / [R=301,L]

# ─── Чистые URL: без .html и без слэша на конце ────────────────────────
# /support вместо /support.html, /404 вместо /404.html и т.д.
# Реальные папки (/cabinet/, /qa/) это не трогает — для них !-d ниже.
#
# Папки-приложения (cabinet/creator/ai-creator/cards-creator/
# presentation-generator) дополнительно исключены явным условием в
# правилах (1) и (2) ниже, а не полагаются только на "!-d". НАЙДЕНО НА
# ПРАКТИКЕ: у presentation-generator (см. историю — сразу после создания
# папки) возникал цикл редиректов ровно между "presentation-generator/" и
# "presentation-generator" — правило (2) снимало слэш, решив, что это не
# папка, а Apache тут же добавлял его обратно, увидев, что папка есть.
# Похоже на кратковременное расхождение между тем, что видит mod_rewrite
# (-d), и тем, что видит сам Apache при раздаче каталога (возможно, кэш
# пути, оставшийся с первых неудачных попыток разместить файл). Раз для
# ЭТИХ конкретных папок правильное поведение всегда одно и то же
# (открываться СО слэшем на конце, отдавая index.html) — проще явно
# исключить их из логики "снять слэш" совсем, чем полагаться на то, что
# "-d" всегда отработает предсказуемо.

# 1) Если кто-то зашёл по прямой ссылке с .html — 301 на чистый адрес
RewriteCond %{REQUEST_URI} !^/ru/(cabinet|creator|ai-creator|cards-creator|presentation-generator)(/|$) [NC]
RewriteCond %{THE_REQUEST} \s/+(.+)\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,L]

# 2) Финальный слэш у файлов (не у папок) — тоже 301 на адрес без слэша
RewriteCond %{REQUEST_URI} !^/ru/(cabinet|creator|ai-creator|cards-creator|presentation-generator)(/|$) [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s/+(.+)/[\s?] [NC]
RewriteRule ^(.+)/$ /$1 [R=301,L]

# 3) Внутренняя переадресация: отдаём name.html по запросу /name
RewriteCond %{REQUEST_URI} !^/ru/(cabinet|creator|ai-creator|cards-creator|presentation-generator)(/|$) [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [L]

# ─── Защита файлов с данными пользователей и секретами ─────────────────
# users.json/settings.json/reset_tokens.json/rates_cache.json лежат рядом
# с api.php и без этого блока отдаются браузером напрямую по прямой ссылке
# (там e-mail и bcrypt-хеши паролей). secrets.php сам по себе исполняется
# PHP и наружу ничего не печатает, но на всякий случай тоже закрыт —
# require_once из api.php это не затронет, он читает файл с диска,
# а не по HTTP. php-errors.log — лог PHP-ошибок (см. api/ai-generate-
# presentation.php и соседние) — в нём могут мелькать серверные пути и
# фрагменты данных из упавших запросов, наружу тоже ни к чему. Папка
# data/ — профили пользователей.
<FilesMatch "^(users|settings|reset_tokens|rates_cache)\.json$|^secrets\.php$|^php-errors\.log$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# ─── Публичные картинки внутри data/ — исключение из блока ниже ────────
# Картинки вопросов/ответов теста (data/qi/), обложки сертификатов
# (data/cert-bg/) и логотипы брендирования голосований (data/o/) должны
# открываться напрямую браузером — это не данные пользователей, а обычные
# статические файлы, на которые ссылаются <img>. Всё остальное в data/
# (сами JSON с тестами/результатами/голосованиями) по-прежнему закрыто
# правилом ниже — сюда подпадают только файлы с расширением картинки.
RewriteCond %{REQUEST_URI} ^/data/(qi|cert-bg|o|trial-qi)/.*\.(jpe?g|png|webp|gif)$ [NC]
RewriteRule ^ - [L]

RewriteRule ^data/ - [F,L]

# ─── CORS для api.php ───────────────────────────────────────────────────
# ВАЖНО: сама api.php уже выставляет Access-Control-Allow-Origin/Methods/
# Headers через PHP header(), с точным отражением Origin под credentials.
# Раньше .htaccess дублировал те же заголовки блоком "Header always set"
# для ЛЮБОГО .php-файла — Apache применяет "set" ко ВСЕМ ответам этого
# типа файлов (не только к OPTIONS), поэтому статический
# "Access-Control-Allow-Origin: *" из htaccess перетирал точный заголовок,
# который выставил PHP. А "*" вместе с Allow-Credentials: true браузеры
# просто отклоняют — то есть встраиваемый AI-виджет на чужих доменах мог
# из-за этого не проходить авторизованные запросы. Поэтому здесь CORS для
# api.php больше не трогаем — целиком отдаём его на откуп самому api.php,
# один источник правды вместо двух конфликтующих.
#
# Короткий путь для OPTIONS-preflight тоже убран по той же причине: он
# отдавал 204 в обход PHP, а значит вообще без корректных CORS-заголовков
# под конкретный Origin. api.php и так сам отвечает на OPTIONS корректно
# (в начале файла: выставляет заголовки, затем 204 и exit) — лишний виток
# в .htaccess только дублировал эту логику и в этом месте её ломал.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^t/([a-zA-Z0-9_-]+)/?$ /t.php?id=$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^v/([a-zA-Z0-9_-]+)/?$ /v.php?id=$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^o/([a-zA-Z0-9_-]+)/?$ /o.php?id=$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^p/([a-zA-Z0-9_-]+)/?$ /p.php?id=$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^c/([a-zA-Z0-9_-]+)/?$ /c.php?id=$1 [L,QSA]

# ─── Настоящий HTTP-заголовок Cache-Control для cabinet/creator/ai-creator ───
# Это статические HTML-файлы, не PHP, поэтому header('Cache-Control:...')
# внутри них невозможен — только <meta http-equiv>, которую браузеры
# (особенно Chrome — при решении, использовать ли bfcache) не считают
# равноценной заменой настоящему HTTP-заголовку. Из-за этого после
# редактирования теста/смены тарифа Chrome мог показывать старую версию
# страницы из bfcache или диск-кэша, хотя сервер отдавал актуальные данные
# через api.php. Раз PHP-заголовок в самом файле поставить нельзя — ставим
# его на уровне веб-сервера через mod_headers.
#
# /test сюда намеренно не включена — это анонимная посадочная страница,
# одинаковая для всех посетителей, без персональных данных, кэшировать
# её можно и нужно (см. работу над PageSpeed).
#
# Матчим по REQUEST_URI, а не по имени файла — cabinet/creator/ai-creator
# физически называются index.html каждый в своей папке, FilesMatch по
# имени задел бы заодно и /index.html главной страницы, которую как раз
# кэшировать можно и нужно (там нет персональных данных пользователя).
<IfModule mod_rewrite.c>
  RewriteCond %{REQUEST_URI} ^/ru/(cabinet|creator|ai-creator|cards-creator|presentation-generator)(/|$)
  RewriteRule ^ - [E=NOCACHE_PAGE:1]
</IfModule>
<IfModule mod_headers.c>
  Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0" env=NOCACHE_PAGE
  Header set Pragma "no-cache" env=NOCACHE_PAGE
</IfModule>

