Альфа релиз альтернативной админки для MODX

Всем привет!

В продолжение недавней дискуссии публикую то, что удалось сделать за два дня (точнее за 23 часа).





Вообще внутри сделано мало (только страница пользователей со списком и простым фильтром, а так же страница самого пользователя, на которой выводится только юзернейм), но материала поразмыслить получилось довольно много, о чем я сейчас детали и поведаю.

Первое, что хотелось бы отметить, что MODX потенциально имеет API (Здесь и далее, говоря про API MODX, я буду иметь ввиду коннекторы и процессоры), чтобы можно было с админкой работать со стороны, но все же есть недочеты. Первый, который меня нормально так удивил и затребовал несколько часов на решение — это невозможность авторизоваться по API. То есть так-то есть процессор Security/Login, но проблема в том, что вызов любого коннектора блочится на уровне проверки доступов по кукису и токену, отдавая 401, если доступа нет. То есть получается замкнутый круг: вы не можете авторизоваться, потому что не авторизованы и процессор авторизации не может быть вызван. Если вы смеетесь, то зря. Наверняка же все сталкивались с появлением такого окошка:


Вот когда вы в следующий раз с ним столкнетесь, прежде чем отправить данные авторизации, удалите в браузере кукис PHPSESSID и попробуйте через него авторизоваться. Вы даже никакого сообщения не получите при такой попытке, просто не пройдет авторизация и все. А если сеть посмотреть, то можно увидеть, что ответы отбиваются с 401 ошибкой.


— Видишь окно авторизации
— Да
— А его нет…

А сессия может быть завершена не только по вашей инициативе, ведь кто-то может в админке нажать «Завершить все сеансы».

К слову, сейчас все чаще и чаще работают без всяких там кукисов, используя только токены, к примеру jwt. А в крупных компаниях вообще для управления авторизациями используют сторонние решения типа Keycloak.

В таком случае конечно же можно было создать свой собственный коннектор с указанием глобальной define('MODX_REQP', false) и тогда все ОК было бы, но мне интересно-то было сделать авторизацию без модификаций. И пришлось поизвращаться. Пришлось слать POST-запрос с данными авторизации на страницу самой админки (а не коннектор) и в ответе искать токен (а так же кукис в заголовках). И тут еще два подводных камня возникло: во-первых, MODX в любом случае при авторизации шлет в ответе данные редиректа. fetch по-умолчанию следует этим редиректам (то есть делает следующий запрос, следуя указанному правилу редиректа), и ответ содержит самые последние данные. При этом он не отправляет полученные кукисы (ну, потому что второй запрос-то не содержит в себе данных формы). Пришлось запретить ему это. Во-вторых, оказывается, MODX не имеет коннектора для возврата данных авторизованного пользователя. То есть если ты авторизован и хочешь получить свои данные, это можно сделать только через общий процессор получения данных пользователя и только с указанием id пользователя. То есть если ты не знаешь свой id, ты не можешь запросить свои данные. MODX конечно знает кто ты (ну, ты же авторизован), но он тебе ничего не скажет. В общем, пришлось где-то искать этот id, и найти его получилось на странице профиля пользователя, то есть /manager/?a=security/profile. Там в недрах можно найти небольшой кусочек JS-кода, в котором имеется user: $id (хотя это на самом деле было лишнее, потому что на всех страницах админки итак есть глобальный объект MODx.user). Проблема только в том, что эта страница легко может быть запрещена пользователю (есть такое правило в MODX). И получается, что если у пользователя нет доступа к этой странице, я не смогу получить его id и соответственно его объект. Очень не круто.

В общем, авторизация оказалась тем еще квестом, но ее получилось условно победить. Далее уже стоял вопрос непосредственно получать данные и выводить их в админке. И тут (при наличии авторизации) особых проблем нет. Но все же тоже не идеально. Чем же я не доволен?

Во-первых, с API приходится работать практически вслепую. То есть не ясно что можно запросить и что будет получено. Для сравнения, вот мое API:


Могу и общую схему изучить


Я четко понимаю какие методы есть, что я должен/могу передать, что могу получить.

В MODX мне все это неведомо. Приходится лезть в код и смотреть что там можно сделать. И комментарии к методам не особо помогают. К примеру, вот процессор получения списка пользователей. В нем написано:

/**
 * Gets a list of users
 * @param string $username (optional) Will filter the grid by searching for this username
 * @param integer $start (optional) The record to start at. Defaults to 0.
 * @param integer $limit (optional) The number of records to limit to. Defaults to 10.
 * @param string $sort (optional) The column to sort by. Defaults to name.
 * @param string $dir (optional) The direction of the sort. Defaults to ASC.
 * @package MODX\Revolution\Processors\Security\User
 */
То есть по идее это параметры, который в него можно передать в запросе. Здесь что-нибудь есть про параметр query? Нет. А он есть. При чем можно передавать не просто строку, но и разделенную знаком двоеточия (первая часть будет названием колонки в профиле (именно в профиле пользователя, а не в самом пользователе), а вторая — искомая подстрока).

Вот пример простого поиска:


Вот по fullname:


Вот по email:


А вот по username:


То есть как я и говорил, по колонкам таблицы самого пользователя не ищет. Более того, MODX просто пропускает такое условие, если первая часть не соответствует списку колонок таблицы профиля пользователя, так что если что-то надо будет в пользователей найти именно содержащее знак двоеточия, то сделать это будет весьма проблематочно.

К слову, кто у в безопасность шибко шарит? Вот здесь не видно вообще никаких средств по валидации/санитации запроса:
$c->where([
                    $c->getAlias() . '.username:LIKE' => '%' . $query . '%',
                    'Profile.fullname:LIKE' => '%' . $query . '%',
                    'Profile.email:LIKE' => '%' . $query . '%'
                ], xPDOQuery::SQL_OR);


Я знаю, что зами POST-запросы вроде как дополнительно санитайзятся немного, но вряд ли там все случаи закрываются.

Второе, что не удобно: совершенно не ясно с типизацией. То есть я не знаю истинную структуру ответа, не знаю набор возвращаемых полей. Сейчас опытным путем получилось выяснить, что в списке пользователей вот такие поля возвращаются:
{
      id: 10,
      username: 'tyjtyjty',
      class_key: 'modUser',
      active: false,
      remote_key: null,
      remote_data: null,
      hash_class: 'MODX\\Revolution\\Hashing\\modNative',
      primary_group: 0,
      session_stale: null,
      sudo: false,
      createdon: '2021-04-10 16:46:13',
      fullname: '',
      email: 'fdfsdf@localhost',
      blocked: false,
      cls: 'pupdate premove pcopy'
    }
А при запросе конкретного пользователя вот такие:
{
    id: 10,
    internalKey: 10,
    fullname: '',
    email: 'fdfsdf@localhost',
    phone: '',
    mobilephone: '',
    blocked: false,
    blockeduntil: '',
    blockedafter: '',
    logincount: 0,
    lastlogin: '',
    thislogin: 0,
    failedlogincount: 0,
    sessionid: '',
    dob: '',
    gender: 0,
    address: '',
    country: '',
    city: '',
    state: '',
    zip: '',
    fax: '',
    photo: '',
    comment: '',
    website: '',
    extended: [],
    username: 'tyjtyjty',
    class_key: 'modUser',
    active: false,
    remote_key: null,
    remote_data: null,
    hash_class: 'MODX\\Revolution\\Hashing\\modNative',
    salt: 'some_salt',
    primary_group: 0,
    session_stale: null,
    sudo: false,
    createdon: '2021-04-10 16:46:13'
  }
То есть если мы хотим, к примеру, вывести список пользователей вместе с их адресами и телефонами, просто так у нас не получится это сделать. Ну и вообще, не понимание что будет возвращено, а что нет, сильно усложняет работу с API.

В общем, не очень удобно со всем этим работать. Тем не менее, первый камень заложен, и если сообществу будет интересно, можно будет совместно продолжить этот эксперимент. Проект я выложил здесь: https://github.com/Fi1osof/modx-next-manager

Если на вашем компьютере нет node-js и вы вообще с таким не работаете, но хочется посмотреть это все в работе, можно сделать через https://vercel.com. Вот шаги:

1. Регаемся на github.com, если там нет еще аккаунта.
2. Клонируем к себе проект github.com/Fi1osof/modx-next-manager (справа вверху есть кнопочка Fork).
3. Регистрируемся а https://vercel.com, лучше всего через тот же github.com
4. В ЛК жмем New Project.


5. Находим свой склонированный проект


6. Выбираем вариант «Персональный аккаунт». Это тогда будет бесплатно. Команду не надо создавать.


7. Создаем в переменных окружения SITE_URL со ссылкой на ваш сайт (запросы никак не логируются и мне ничего доступно не будет, так что не беспокойтесь, проект ваш и создается в вашем профиле).


По умолчанию в запросах будут использоваться manager/ и connectors/. Если на вашем сайте эти разделы изменены, укажите тогда явно тут же переменные MANAGER_URL и CONNECTORS_URL (полностью, включая домен/раздел/ (слеш на конце обязателен)).

Жмем deploy. Пойдет процесс.


Если все ОК, то появится панель проекта.


Когда все соберется и запустится, переходите по ссылке из проекта и пробуйте свой логин/пароль. Если что будет не так, пишите в комментах.

Ну а для тех, кто хочет локально попробовать, да еще и с кодом поиграться, все относительно просто:

1. Клонируем себе проект
git clone github.com/Fi1osof/modx-next-manager
cd modx-next-manager

2. Создаем файл переменных окружения и редактируем его (Там надо указать адрес MODX-сайта, лучше локального, если есть запущенный на компе).
cp .env.sample .env

3. Устанавливаем зависимости
yarn install

4. Запускаем проект
yarn dev

По умолчанию будет работать на localhost:3000. Можно изменить порт PORT=3333 yarn dev

По адресу localhost:3000/api будет доступен GraphQL Playground, чтобы писать GraphQL-запросы. Сейчас вот эти в помощь:
query me {
  me (
    where:{
      id: 1
    }
  ){
    ...user
  }
}

query user {
  user (
    where: {
      id: 10
    }
  ){
    ...user
  }
}

query usersConnection {
  usersConnection (
    start: 0
    limit: 10
    where:{
      # query: "test"
    },
  ){
    total
    users {
    	...user
    }
  }
}

mutation signin {
  signin (
    username: "username"
    password: "password"
  ) {
    token
    userId
  }
}


fragment user on User {
  id
  username
  fullname
  email
  active
  blocked
  createdon
  cls
}
Только в настройки надо зайти и изменить «request.credentials»: «omit» на «request.credentials»: «same-origin» (Не забываем сохранить настройки). Это чтобы в запросах кукисы отправлялись.



При успешном выполнении запроса авторизации signin, в ответ вы получите токен. Его надо указать в заголовки Authorization, чтобы выполнять авторизованные запросы.


Если кто вообще захочет углубиться во все это, вот есть двухчасовое обзорное видео по используемому движку: https://www.youtube.com/watch?v=1gaLnlbaGG8. Скучновато и затянуто, но зато почти все необходимое показано и рассказано.

Какие возможны пути развития? Сам я не хочу делать полноценную админку на замену текущей. Тем не менее здесь есть интересные моменты. К примеру, при изменении фильтра в списке пользователей, меняется и УРЛ. Помните эту частую проблему, когда указал условия поиска, нашел, что хотел, перешел в редактирование, вернулся назад, а там опять список без условий поиска? Вот тут такого нет. Даже можно страницу обновить. Во-вторых, все работает без перезагрузки страниц, а не так, как в классической панели, когда любой переход — обновление всей панели, и спасение только в быстрых действиях (типа Быстро обновить). Но вы быстрых действиях панели не полные, да еще и приходится два интерфейса под одну сущность тянуть. Вот тут тоже этой проблемы нет. В третьих, в классической панели при сохранении новой сущности опять-таки происходит обновление страницы, что тоже не круто. И еще ряд моментов, которые можно обыграть гораздо лучше. И хотя я не сделал страницу редактирования/создания пользователя/ресурса и т.п., это очень даже можно сделать, методики отработанные. Просто итак два дня потратил, а еще не ясно нужно все это кому или нет. К слову, тут еще момент есть, который мне никогда не нравился в MODX: необходимость при обновлении передавать все данные объекта. То есть если вы хотите отредактировать только заголовок документа, вам все равно надо передавать все данные этого документа, в том числе TVшки. Бррр…

Я хочу сказать, что с MODX в том виде, какой он сейчас есть, просто не получится сделать все замысленное. Тем не менее, данную наработку можно использовать и развивать для нестандартных панелей. То есть если у вас есть проект, в котором идет активная работа и требуется своя специфическая панель, вот это вполне можно использовать. Более того, как я писал раньше, у меня есть опыт более тесной интеграцией с базой данных напрямую, и тогда вообще можно писать свои SQL-запросы и в целом работать без MODX как такового. Но и другой вариант: написание компонентов для текущей админки. То есть можно написать интерфейсы, которые будут работать без JS на стороне сервера, а просто как фронт-компоненты, при этому интегрировать их в админку. Будет ряд ограничений, но зато это будет работать полностью нативно и без отдельного гемора с авторизацией.

В общем, вариантов куча. Был бы интерес.

P.S.: страничка проекта с задачами, комментариями и т.п.: https://freecode.academy/office/projects/cknadbc18qelo0730a9bunpn3

Если будет работа над проектом, то ее вполне можно организовать.
Fi1osof
11 апреля 2021, 14:11
modx.pro
3
1 792
+17

Комментарии: 27

Руслан Алеев
11 апреля 2021, 14:50
0
Спасибо за статью и потраченное время!
Про авторизацию частично обсуждалось modx.pro/howto/18977#comment-114090, видимо, многие спотыкаются :)

Помните эту частую проблему, когда указал условия поиска, нашел, что хотел, перешел в редактирование, вернулся назад, а там опять список без условий поиска?
Это, кстати, частично исправлено в текущей админке MODX 3, можно в системных настройках увидеть.
    Fi1osof
    11 апреля 2021, 15:45
    +1
    Не за что!

    Про авторизацию частично обсуждалось modx.pro/howto/18977#comment-114090, видимо, многие спотыкаются :)
    Нее, там совсем чуть-чуть и вообще про REST-контроллеры. Я же хотел заюзать нативные средства без каких-то движений на стороне кода сайта. Уточню разницу: РЕСТ-контроллер, это всего-лишь общий класс на чтение данных и отдачу ответа. То есть да, в нем есть возможность добавить логику, всякие вещи дописать и все, но все это на уровне кастомных контроллеров. Но если смотреть имеющиеся системные процессоры, то там много всякой логики, особенно на создание/редактирование всяких объектов (включая пользователей, ресурсы и т.п.). Гляньте хотя бы тот же процессор создания ресурса, который в том числе обрабатывает логику с ТВшками, группами ресурсов и т.д. и т.п. А еще в этих процессорах уже прописана проверка всяких прав. Переписывать все это на уровне кастомных контроллеров — дикий оверхед. Задача же была написать панель, которая не требует никаких лишних движений на стороне кода сайта, при этом максимально поддерживала бы базовые функции, да еще можно было бы что-то свое докрутить. По-хорошему в MODX на уровне ядра надо поправить возможность авторизацию без проверки уже имеющейся, а не как сейчас. Для особых параноиков можно системную настройку сделать, чтобы можно было это блокировать. Ну и текущего пользователя возможность получать. Тогда будет вообще ОК.

    Это, кстати, частично исправлено в текущей админке MODX 3, можно в системных настройках увидеть.
    Какая именно? Не нашел.
    Сергей Шлоков
    11 апреля 2021, 16:25
    0
    А почему нельзя для аутентификации использовать текущий подход с редиректом? Я понимаю про всякие приложения — нужен нормальный вариант через REST. Но тут же речь про админку.

    П.С. На странице админки для действия «security/login» блокировки вроде нет.
      Fi1osof
      11 апреля 2021, 16:31
      0
      Да не, можно. Но это как-то ненадежно. Хотелось бы поменьше костылей.
        Сергей Шлоков
        11 апреля 2021, 16:33
        0
        Так наоборот вроде проще. Нажал «Войти», загрузилась SPA страница с токеном и работой на здоровье.
          Fi1osof
          11 апреля 2021, 17:39
          0
          Либо я тебя не понимаю, либо ты меня. Я выше писал, что одного только токена не достаточно, нужен еще и кукис (во всяком случае для обращения к MODX). Во-вторых, сам этот токен получить — не просто так.

          Еще и по сути нет средств проверить авторизован ты или нет, то есть нет метода типа Security/User/GetCurrentUser. В чем проблема здесь? В том, чтобы понять когда ты авторизован, а когда нет. Единственный вариант тут — это просто реагировать на 401-ые ошибки (как это сейчас MODX делает). Но проблема тут в том, что у нас неоднозначная система доступов, и легко могут быть случаи, когда интерфейс загружен, а на определенный запрос нет прав. То есть ты запросил что-то, а в ответ получил 401-ый код серверный (что MODX делает много где) и это одновременно может быть признаком того, что ты не авторизован, хотя не гарантирует это (ты на самом деле авторизован, но нет прав на этот запрос и получил 401). В общем, все это делает работу с API неудобной и неоднозначной.
            Сергей Шлоков
            11 апреля 2021, 18:01
            +1
            нет средств проверить авторизован ты или нет
            Такого API нет.

            Но проблема тут в том, что у нас неоднозначная система доступов, и легко могут быть случаи, когда интерфейс загружен, а на определенный запрос нет прав.
            Я по этому поводу уже говорил, что в MODX нет корректного кода ответа — на все действия он отвечает кодом 401. Хотя 401 означает — требуется аутентификация, а код для отсутствия прав — 403.
              Fi1osof
              11 апреля 2021, 18:02
              0
              Хотя 401 означает — требуется аутентификация, а код для отсутствия прав — 403.
              Люто плюсую.
        Fi1osof
        11 апреля 2021, 17:34
        0
        П.С. На странице админки для действия «security/login» блокировки вроде нет.
        Проверь сам. Я ссылку на кусок кода дал, там блокируются вообще все запросы на коннектор, если пользователь не авторизован. А авторизация в админку работает через обычную форму с POST-запросом на саму страницу, а не через Ajax-запрос, и авторизация выполняется на уровне контроллера самой админки, а не через коннектор. При заходе на страницу админки, ответ обрабатывается через modManagerResponse, и если пользователь не авторизован, то вызывается контроллер security/login, и если отправляются данные авторизации, срабатывает handleLogin(), и там уже вызывается процессор Security/Login. То есть этот механизм не через коннекторы работает.
          Сергей Шлоков
          11 апреля 2021, 17:56
          0
          Я в курсе этого механизма. Поэтому и говорю, его оставить, через него залогиниться, а дальше работать со своей реализацией. Но у тебя будет и токен и куки.

          Кстати, чтобы не блокировало, нужно передать в форме action = «security/login».
            Fi1osof
            11 апреля 2021, 18:05
            0
            Покажи пример запроса. Я action=security/login первым делом проверял. И в статье показывал скриншопы, что без кукиса даже из админки через модалку не залогиниться. Вот здесь отбивает же запрос.
              Сергей Шлоков
              11 апреля 2021, 18:09
              +1
              MODX под рукой нет.

              Теоретически, вот тут определяется константа, которая позволяет пройти твоё блокирующее условие.
                Fi1osof
                11 апреля 2021, 18:51
                +1
                Я докопался до проблемы :)
                Я конечно же все это проверял, но не достаточно глубоко. Попробовал как должно быть, не сработало, подумал никогда и не было. А оказывается было. Во второй вертке проверяет
                $isLogin = $target == 'login' || $target == 'security/login';
                а в 3-ей (на которой я и экспериментировал) уже вот так:
                $isLogin = $target == 'Login' || $target == 'Security/Login';
                Но в коннекторе-то проверяется именно на 'security/login', чтобы выставить define('MODX_REQP', false);

                И никак не думал, что сам Джейсон такую засаду сделает :)

                Всегда считал его мегаконсервативным в плане изменения кода, а тут фигак и в продакшн.

                Отправил простенький PR. Лечит проблему.
                  Сергей Шлоков
                  11 апреля 2021, 18:56
                  0
                  И никак не думал, что сам Джейсон такую засаду сделает :)
                  Бывает со всеми.

                  Отправил простенький PR. Лечит проблему.
                  Я видел. Я же теперь интегратор ) Ну ты хоть в описании опиши. )
                    Fi1osof
                    11 апреля 2021, 19:01
                    0
                    Я в комменте написал.
                      Fi1osof
                      11 апреля 2021, 19:13
                      +1
                      К слову, еще одна причина почему не хочется заниматься кодингом в ядро: я отправил ПР, но видите ли не достаточно хорошо его оформил (точнее совсем не оформил). Почему я должен на это тратить время? Это не issue, где бы я спрашивал «А как мне сделать то-то». Это PR. То есть я потратил не мало своего времени, нашел проблему, пофиксил ее, и еще должен что-то там разжевывать? А мейнтейнеры на что? Это уже не программисты, а менеджеры какие-то. Как будто все это должно мне быть важнее, чем им.
                        Іван Клімчук
                        11 апреля 2021, 20:44
                        +7
                        Бля, а интеграторам потом сиди и ломай голову, нахрена оно там нужно? 2 строки пояснения написать — жопа не отвалится, ну серьезно. Нам больше делать нечего, как сидеть и гадать на картах Таро, что там автор имел ввиду. Мы не за зарплату там сидим, есть дела и поважнее. Ты ж вроде говоришь, что активно в open source серьезном участвуешь, так там считается правилом хорошего тона описать твое изменение и зачем оно нужно, иначе просто закрывают PR, как формально не соответствующий правилам. Не только твое время дорого стоит. Никто ж не требует простыни писать, для ленивых даже сделали удобный шаблон, чтобы максимально не думать о структуре, а просто написать 2 ответа и все.
                          Fi1osof
                          11 апреля 2021, 23:27
                          0
                          Нам больше делать нечего, как сидеть и гадать на картах Таро, что там автор имел ввиду.
                          Это одна строчка кода, Карл. Одна. Чего там думать? Я переписывал свой сайт, 400 000 строк изменений, и все ОК. А у вас от одной строчки мозг ломается? Ох, измельчали нынче программисты.

                          Мы не за зарплату там сидим, есть дела и поважнее.
                          Так и я не зарплате, если что.

                          иначе просто закрывают PR
                          Ну так надо было закрыть и все. ОК, я сам закрыл. И больше ничего не отправлю, даже трогать не буду.
                            Іван Клімчук
                            11 апреля 2021, 23:31
                            +1
                            Есть элементарные правила и уважение к ним. Они не просто так были придуманы, а ты пришел, и всех облил говном, мол вы чего, тупые тут все? Марк вежливо попросил, я в общем-то тоже. Ну и PR сам по себе не решает задачу, давай будем объективны.
                            Fi1osof
                            12 апреля 2021, 08:33
                            +2
                            Нет, бля, не я облил говном, а мне предъявили «Ты что так медленно перемещаешься на коленочках недостаточно усердно нам пытаешься помогать?!». И конкретно ты начал тыкать, что это мозговыносящий код и все такое. Вот на это я только и могу сделать рука-лицо. Вам там надо половину переписывать, фишки новые вводить (о чем вас просят давно), а вы ломаете что есть, а потом губки дуете, что вам там плохо что-то оформляют? Такими темпами у вас и еще через 5 лет будет все то же самое, что и было.

                            Марк вежливо попросил, я в общем-то тоже.
                            Я в комменте дал пояснение. А мне в ответ «А что не туда?». Бля, да какая разница? Информация есть, есть.

                            Ну и PR сам по себе не решает задачу, давай будем объективны.
                            Я проблему здесь довольно подробно раскрыл. Там показал, что именно в этой строчке проблема. Далее уже кто лучше знает обстановку, может принять, или отменить и поправить. Хотя бы есть информация.
                            Fi1osof
                            13 апреля 2021, 20:19
                            0
                            Вот привет нормальной реакции на PR: github.com/graphql-nexus/nexus/pull/887#pullrequestreview-633574197

                            ty!
                            Все. Достаточно! Мерж и ОК. И проект развивается дальше. А тут болтовни тонна, а толку мало. Так и будете топтаться на месте.
                    Іван Клімчук
                    11 апреля 2021, 20:47
                    0
                    Я уже отписал в PR, чтобы это была часть рефакторинга, переезд на PSR-4, следовательно имена классов теперь «правильные», с учетом регистра, поэтому и пути к actions теперь с учетом регистра. Это правили, но видимо не везде нашлось.
          Артем
          11 апреля 2021, 17:06
          +1
          Как заготовка — прикольно, но для админки, на мой взгляд, NextJS лишний, тем более со своим файловым роутингом, который на больших проектах заставляет страдать.
          Ты взял NextJS потому что привык и удобно, либо из-за какой-то его конкретной фичи?
            Fi1osof
            11 апреля 2021, 17:46
            +2
            Я его взял потому что довольно хорошо знаю его, и знаю, что роутинг на файлах для него — совсем не обязательная штука. К примеру вот этот роутер обрабатывает вообще все УРЛы, который не попали в логику явного роутинга, и в зависимости от типа ресурса я выдаю ту или иную конечную вьюху. И да, это MODX-ресурсы, берущиеся из таблицы site_content, только уже не средствами MODX (но это не особо важно).

            А вот здесь и вовсе прописана обработка входящих запросов еще до вызова некста. Так что некст — это следствие, а не причина.

            А некст я взял, потому что посмотрев имеющиеся решения на рынке, он больше всего понравился своей относительной минималистичностью и гибкостью в кастомизации.
            Павел Бигель
            11 апреля 2021, 21:46
            +2
            Вот вроде и минус ставить не хочется (человек старался + олд + по содержательности явно лучше многих статей тут), но и лайк ставить не за что.
            Практического смысла и применения в этом околонулевая
              Сергей Шлоков
              11 апреля 2021, 22:19
              +3
              Практического смысла и применения в этом околонулевая
              Кому как.
                Fi1osof
                11 апреля 2021, 23:29
                +2
                Каждый ученик извлекает из урока ровно столько, сколько он может извлечь.
                Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                27