Вчера в 12:31
Большие сомнения у меня в этом)
resComments — многоуровневые комментарии с пагинацией для ресурсов MODX3 3
07 января 2026, 15:36
вот этот сниппет
require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('web');
$modx->getService...
Проблемы с отправкой писем статус заказа из minishop2 5
06 января 2026, 20:15
Хотел проверить еще раз, теперь все работает. Спасибо.
MiniShop3 1.0.0-alpha.4 — Большое обновление админки 24
05 января 2026, 14:53
Тоже не понял зачем эти сложности, всегда этот скрипт юзал.
Почему в новых версиях MODX не работает сброс пароля через MD5 и как восстановить доступ в manager 4
30 декабря 2025, 22:52
Почему-то прочитал это голосом комментатора из Дома 2… Только про Minishop 3!) Спасибо всем за вклад в развитие и, достаточно неплохие итоги года)
Итоги 2025 года на MODX.pro 3
27 декабря 2025, 16:41
MODX, как и любой основанный на PHP фреймворк пишет 500 ошибки в error_log. Никаких специальных настроек в нем нет. Все зависит от настроек хостинга\с...
Отладка 500 ошибки MODX 1
24 декабря 2025, 22:11
Есть поле mail_smtp_user введи туда логин, если не сработает введи email. И не забудь в emailsender корректный email прописать.
Modx 2.8.8 еще подходит отправки почты через smtp.yandex.ru? 3
24 декабря 2025, 00:23
Нет, лайки всегда были привязаны ко времени публикации, чтобы лайками старых постов рейтинг не накручивали.
MiniShop3 - новый релиз. 1.0.0-alpha.2 15
Я вижу несколько вариантов решения.
1) на странице не должно быть отдельно блоков для мобильного и отдельно для десктопа. [[HeaderDesktop]], [[HeaderMobile]] это плохая практика. Внешний вид должен адаптироваться под разные устройства за счет каскадных стилей и медиа запросов, а не за счет скрытия блоков для десктопа и отображения блоков для мобильных. В таком случае и корзина у вас всегда будет существовать на странице, потому что шапка остается всегда одной и той же.
2) Я вижу что у вас используется скорее всего какой то готовый шаблон интернет магазина, взятый с бескрайних просторов интернета, а значит переверстывать никто не будет. Тогда действительно придется иметь два разных чанка для шапки, в каждом полноценно вызывать [[!msMiniCart?&tpl=`miniCart`]], а не подгружать по клику, НО решать какой из чанков показать вам нужно еще на уровне обработки запроса на сервере. Помоему для modx даже была какой-то сниппет типа MobileDetect или как то так, который позволяет определить с какого устройства пришел запрос.
Наверняка там содержится и поле id и вы можете сделать как написал выше Артур.
Синтаксис шаблонизатора феном можно посмотреть тут github.com/fenom-template/fenom/tree/master/docs/ru
Формы могут отправлять данные используя два метода http запросов — POST и GET
Следовательно вам нужно разместить на одной странице и форму и ваш сниппет.
Далее псевдо код, который не рассматривает вопросы безопасности.
Потому что даже подсказывать вам опасно, вы ведь сделаете по примеру и не подумаете о безопасности, о том, что давать возможность пользователю напрямую передавать данные из формы в sql запрос это очень опасно.
Автор говорит
насколько я понимаю, речь идет о том, что один товар minishop создан в одной категории, а в другие расставлен при помощи галочек. Но в таком случае, урл товара всегда одинаков ведь, разве нет? Не важно откуда мы на него перейдем, из основной категории или из виртуальной, урд товара будет один и тот же.
Но если без иронии, то тоже не понятно. Что в вашем понимании «отчет». Отчет чего или кого. Причем тут фильтр?
А ответ Артура следует понимать так — создать что либо в админ панели довольно сложно, вам нужно как минимум хорошо знать сам modx и фреймворк extjs который отвечает за отрисовку интерфейса. Поэтому гораздо проще создать в админке просто ресурс, но снять галочку — опубликован. Внутри этого ресурса, вставляйте какие угодно самописные (или нет) сниппеты, которые создадут нужную вам логику. Такую страницу можно открыть по урлу как любую другую, но изза того, что она неопубликована, видите ее только вы, предварительно авторизовавшись в админке.
уверен, что тот код который у вас приведен выше, вам не пригодится больше для вывода товаров.
ну и в целом, фильтровать что то у вас будет или невозможно или очень сложно.
Ваши значения заполняются вручную, в одном поле храниться как величина (10) так и единица измерения (кг), менеджер может в одном месте написать 3.4, а в другом 3,4 и так далее.
Мой совет — переделайте сайт используя минишоп и избавьтесь от характеристик на migx/
Это будет быстрее и правильнее.
Я использую такую блочную систему только если руководство требует ручного управления блоками на странице. Это нужно далеко не везде, чаще всего макеты страниц статичны.
Кода не будет, будут только общие концепции.
1) Есть конфигурация migx которая содержит
— название блока. Это для того чтобы менеджеру было сразу понятно, о чем этот блок. Никакой другой цели не несет.
— скриншот. Хранит скриншот того, как этот блок выглядит на странице. Тоже чтобы менеджеру было удобно.
— заголовок блока. Это текст, который может быть в блоке а может и нет. Например на одной странице нам нужно вывести иконки и написать вверху над ними — наши преимущества. А где то нужно обойтись только иконками.
— чекбокс Активен блок или нет.
— название чанка, хранящего верстку блока.
— описание. Для удобства менеджера, если управление блоком не очевидно и требует каких то комментариев.
— откуда брать данные для блока. Выпадающий список с такими вариантами. — брать с текущей страницы — брать с общих настроек. Детальнее что это опишу ниже.
2) На основании этой конфигурации создаем ТВ поле блок. Привязываем к нужным нам шаблонам.
3) Для удобства менеджера облегчим ему жизнь. Создадим несколько служебных ресурсов. Назовем их
— общие настройки
— категория товара
-товар
— инфостраница
Называем примерно так, чтобы была визуальна видна связь с шаблонам. Зачем нужны эти ресурсы. Они будут являться образцами. К примеру мы идем в служебный ресурс Товар и создаем там блоки (имеются ввиду ТВ поля типа migx).
Настраиваем их, располагаем в нужном нам порядке, так как хотим чтобы выглядела страница товара.
4) При создании любого ресурса срабатывает наш плагин (важно. именно при создании нового а не при обновлении) который понимает какой именно ресурс хотят создать (анализируя шаблон или анализируя родителя, внутри которого его хотят создать). К примеру плагин понял что хотят создать товар. Он идет в служебный ресурс товар и копирует оттуда все блоки, которые заранее настроил менеджер. Если плагину не удалось точно понять, какой ресурс хотят создать, он скопирует блоки с служебного ресурса — общие настройки.
5) мы сохранили новый ресурс и он уже заполнен блоками в нужном нам порядке. Но если менеджер хочет что то изменить, он может редактировать блоки уже принадлежащие этому ресурсу. Сделать эту страницу чем то отличающуюся от стандартного шаблона.
6) как это все работает и почему блоки отображаются на странице. А шаблонах не содержится верстки, кроме основного скелета html. На странице вызывается самописный сниппет buildpage задача которого получить значение migx tv с блоками на этой странице, получить инфу активен ли блок (нужно ли его вообще отображать на странице) и если активен — вызвать нужный чанк (имя которого тоже лежит в блоке). Очередность блоков задается менеджером путем перетаскивания строк в админке.
7) последнее время чанки, которые формируют внешний вид блока начал делать по типу компонентов vue. Имеется ввиду лишь идея, в чанке прописан как блок со стилями, так и html так и javascript относящийся к блоку. Соответственно если блок не активен, то нет и лишних стилей и скриптов.
8) осталось рассказать только об одном — о данных. Сами блоки — это лишь внешний вид, им нужно откуда то брать данные, причем эти данные могут быть разными для блока, в зависимости от того на какой странице он вызван. Данные для блоков храню так же в migx tv полях. Возьму для примера тот же блок — наши преимущества (не знаю как у вас но наши сеошники аж трясутся над этим блоком и пихают его чуть ли не по 10 штук на страницу). Так вот. Создаю конфигурацию migx задача которой хранить изображения. Создаю ТВ поле — блок наши преимущества, которые построен на этой конфигурации. Это ТВ поле есть как у служебных ресурсов, так и у реальных ресурсов, создаваемых менеджером. Настройка в блоке, с именем «Откуда брать данные» как раз и отвечает за это. Менеджер может заполнить один раз данные для блока преимущества (загрузить иконки, возможно написать текст) в служебном ресурсе Общие настройки. Активируя блок «наши преимущества» на любой странице сайта менеджер просто выбирает — брать данные из общих настроек. Если нужно для этой страницы задать индивидуальные данные, то нужно всего лишь перезаполнить соответствующее ТВ поле уже этого ресурса и выставить у блока — «брать данные с этой страницы».
В общем то и все.
Кто скажет, почему payload не шифруется а лишь кодируется? В чем сокральный смысл использовать base64, который очень просто раскодировать и узнать данные?
Как я понимаю жизненный цикл access токена:
— сервер авторизации и сервер, на котором мы хотим обратиться знают один и тот же ключ, при помощи которого создана сигнатура в токене.
— мы при каждом запросе мы передаем этот токен на сервер. Сервер (в каком то midleware ну или как там разработчик сделает) берет payload и кодирует тем же ключем. И сравнивает сигнатуру которую он получил с той, что пришла в токене.
— если сигнатуры совпали это говорит о том, что запрос пришел от того, кто обращался на наш сервис авторизации и смог получить токен.
— НО мы ничего еще не знаем о самом клиенте. Кто именно делает запрос. А если у нас есть деление на какие то роли и не каждый кто просто получил токен имеет пользоваться всем. Или же мы ведем логирование запросов и нам нужен хотя бы id пользователя. Тоесть как ни крути, там же на этапе аутентификации нужно раскодировать payload и получить исходные данные, чтобы получить например объект с перечислением ролей и определить, допустима ли тому, кто отправил запрос, операция удаления пользователей.
— тоесть сам факт проверки сигнатуры не дает еще полной картины, раскодировать payload прийдется каждый раз.
— и в такой схеме действительно возникает проблема. Если токен украли, то пока он «жив» вор может пользоваться им и нанести вред.
Теперь собственно моя идея.
— раз нам все равно на каждый запрос нужно раскодировать payload токена, то почему не включить в него информацию, которая позволит решить проблему с угоном токена. Что-то что будет служить дополнительной защитой.
— к примеру ip адрес того, кто обратился на сервер авторизации и получил токен. Добавим ip в payload и на этапе аутентификации на своем сервере, сравниваем, а тот ip что пришел в токене и реальный ip который мы получаем из самого запроса — совпадают ли?
— так же в случае если мы говорим про применение jwt не для общения с api, а для использования в браузере, в токен можно добавить user-agent, который даст информацию о том, с какой операционной системы и с какого браузера был получен токен. И есть еще масса уникальной информации, которую можно получить и использовать для идентификации того или иного устройства.
— что это нам дает. Решение классической проблемы — угнали токен и до конца его жизни могут пользоваться. Теперь даже в случае угона токена, он не будет принят на сервере, на который мы стучимся, потому что точно не пройдет проверку ip и скорее всего не пройдет проверку user-agent.
— нельзя конечно полностью утверждать, что это 100 процентная защита от угона токена, вернее от возможности его использование вором, но это уже сильно усложнит жизнь вору. Насколько я знаю, подделать ip с которого отправляешь свой запрос на какой то конкретный (а чтобы токен прошел валидацию нужен именно конкретный), не так уж и просто. Но предположим что супер хакеры умеют.
— и мы возвращаемся к моему вопросу — почему payload просто кодируют, а не шифруют? Тот кто украл токен имеет прямой доступ к информации, пусть даже и не знает ключа шифрования, при помощи которого была создана сигнатура. В моей схеме, вор получив токен сразу же использует его чтобы получить доступ к нашему сервису. Не выходит, банально потому что его ip не совпадает с тем с которого он совершает запрос.
— если payload только закодирован base64 вор получает с него данные и видит, что в данных содержится и ip. И начинает как то решать эту проблему и искать способ подделать свой ip на этот конкретный. Если время жизни токена невелико то и времени для поиска решения не много. Но ведь можно не дать ему и этого шанса. Не будем кодировать, будем шифровать payload. Мы уже используем один ключ, который создает сигнатуру. Можем использовать его или завести еще один. Чистые данные шифруем при помощи ключа. получаем payload. payload шифруем при помощи ключа — получаем сигнатуру. Складываем их вместе, получаем довольно безопасный токен.
— теперь даже если украсть токен, то «тупое» его использование ничего не даст и дело не во времени его жизни, а в несовпадении данных из токена с реальными данными запроса. И посмотреть что лежит в payload хакер тоже не может, данные не закодированы, а зашифрованы и не имея ключа их не расшифровать.
Такой подход, как мне кажется, даже позволит завести в свой системе авторизации пару приятных плюшек:
— автопродление токена. Поскольку у нас теперь токен содержит дополнительные уровни защиты, то в зависимости от уровня безопасности всего проекта, можно облегчить жизнь нашим пользователем. Если токен пришел на сервер и в нем все идеально, кроме времени жизни (он уже протух), можно не отправлять пользователя на повторную авторизацию руками, а самим сделать запрос на наш сервис авторизации, передать туда данные из payload и получить новый токен. Никто ведь из людей не любит очень часто вводить пароль. Но это для проектов, чей уровень безопасности не высок.
— можно вести статистику успешных и неуспешных использований токена и на основании ее изменять время жизни токена для конкретного пользователя. Если видим, что присылается токен с зашитым внутрь одним ip а запрос приходит с другого ip, то в следующий раз этому клиенты выдадим токен не на 30 минут, а на 5 минут.
Зачем использовать nginx, почему не настроить nitro на 80 порт и слушать запросы напрямую на нем?
Поэтому не соглашусь, что nodejs это для специалистов. Синтаксис там простой, библиотек море.
Вот ассемблер — это для специалистов.
php -S localhost:8080 -t public
естественно что так до нашей программы нельзя достучаться из браузера, поэтому мы запускаем еще и nginx который настраиваем на проксирование всех запросов с порта 80 на порт 8080 и оно даже будет работать, но вопрос — зачем.
Но вам чтобы увидеть приветственную страницу именно так и нужно сделать. Установить nginx, настроить его дефолтный конфигурационный файл на слушанье 80 порта и тупое проксирование всех запросов на тот порт, на котором запустился ваш nuxt