Главное изменение релиза — публичный REST API. Раньше API покрывал авторизацию и профиль,
теперь через него доступны лента, поиск, все разделы сайта, комментарии, вложения,
голосование, регистрация и свой аккаунт целиком. Спецификация собирается из ядра и модулей:
каждый модуль несёт свой openapi.json, выключенный модуль в документации не появляется.
Второе по важности — разделение app/Classes на публичный API и внутренности движка.
Схема базы этим релизом не меняется, новых миграций нет.
✨ Новое
- Публичный REST API: лента
/api/feed, поиск/api/search, записи всех разделов с комментариями постранично, вложения, голосование/api/rating - Регистрация, восстановление пароля и свой аккаунт целиком через API — профиль с полями модулей, настройки, пароль, почта, статус, цвет, фото и перевыпуск токена
- Списки пользователей: рейтинг, подсказка логинов для упоминаний, кто сейчас на сайте; жалобы, правила, стикеры, статусы и произвольные страницы
GET /api/stats— пользователи, онлайн и счётчики разделов; счётчик объявляет сам модуль черезRegistry::stat()илиstatу модели вmodule.php, замыканием — если разделу с модерацией нужен
свой запрос- Документация API на
/api: спецификация приходит из/api/openapi.json, пути без маршрута из неё вычищаются - Лимиты запросов к API, которых раньше не было: 120 в минуту на все методы и 10 на авторизацию, с заголовками
X-RateLimit-* - Капча для API стала stateless: фраза лежит в кэше, клиент получает картинку data-URI с одноразовым ключом
- Защита от прыжка через мажор: панель обновлений не показывает 15.0, пока сайт не дошёл до последнего релиза своей линии, и объясняет, до какой версии обновиться сначала; скачивание проверяет то же
самое - На карточке мажорного релиза перечисляются установленные модули, собранные под текущий мажор
- Поиск пользователя для автокомплита
- Модули покрыты тестами: реклама, кто-где, документация, игры, лотерея, чат админов, рассылка, phpinfo, рейтинг, счётчики, поля профиля, стикеры
🚀 Улучшения
app/Classesразделена по смыслу:app/Services— внутренности движка (лента, поиск, рейтинг, метрика, CloudFlare, рендер HTML, стикеры, комментарии, вложения),app/Support— то, на что
опираются модули (реестр, хуки, валидатор, санитайзер, счётчики)- Старые имена продолжают работать: автозагрузчик ловит
App\Classesи подставляет класс изApp\Support. Мост ленивый и живёт до 15.0, модули переезжают постепенно - Логика форм вынесена из контроллеров в сервисы —
CommentManager,ComplaintService,UserService,CaptchaService,FileUploader,SiteSearch,Rating: сайт и API проверяют формы одинаково - Наблюдатели модулей регистрируются там же, где морф-типы и секции api — тесты модулей идут в тех же условиях, что живой сайт
- Комментарии в API приходят лентой по дате с контекстом родителя, а не деревом: при пагинации родитель ответа оставался на другой странице
- Вложения разделены на
mediaиfiles— так же, как их делит вёрстка сайта - Элемент ленты получил
breadcrumbs— путь от корня раздела к категории записи - Автор записи отдаётся компактным
AuthorResourceвместо полного профиля на каждый из двадцати элементов ленты - Лимиты форм форума ядро больше не хардкодит — модуль объявляет свои настройки секцией
apiвmodule.php - Спецификация переехала из YAML в JSON — разбирает встроенный
json_decode - Просмотр архивов в модуле Load: карта записей кешируется на файл, картинки отдаются с ETag, перебор несуществующих номеров отбивается без открытия zip. Просмотр закрыт для гостей
- Добавлен каталог для загрузки файлов в предложения и проблемы
- Обновлён league/commonmark до 2.9.0
🐛 Исправления
- Ограничение размера загрузок было в 1024 раза слабее заявленного: настройка хранится в байтах, а правило
maxу Laravel считает килобайты - Сдвиг архива посещений в модуле Counter: итоги закрытого дня и часа писались под текущей датой, графики за неделю и месяц отставали на день
- Начисление баллов за статью и сообщение переживает отсутствующую настройку модуля
- Проверка новогодних дат в модуле Surprise переведена на
now()— раньше смешивались Carbon и нативныйdate(), дата не зависела от часового пояса сайта - Колбэк модуля со старым именем
Validatorпадал с TypeError: проверяя тип аргумента, PHP не зовёт автозагрузчик, поэтому алиас объявляется сразу - Пути
/articles/{slug}и/articles/{id}по спецификации считались одним путём — сведены к/articles/{id}, который и так принимал слаг - Из статистики убран блок про самого пользователя: непрочитанные приходят в
/messages/new, баллы и деньги — в/user, а/statsбольше не зависит от токена - Тесты убирают за собой загруженные файлы —
public/uploadsзарастал пустыми картинками - Страница 503 убрана из списка ошибок в админке
Full Changelog: v14.2.1...v14.3.0