Александр Мельник

Александр Мельник

С нами с 02 сентября 2016; Место в рейтинге пользователей: #52
09 июня 2022, 08:41
0
ваши страницы станут открываться в разы или десятки раз медленнее. Особенно если это какая то категория товаров и отображается 60 товаров и нужно в реальном времени «наложить» 60 водяных знаков. Обновили страницу — и все по новой, снова накладываем 60 водяных знаков.
31 мая 2022, 22:13
+1
Задача заключается в том, чтобы сделать так, чтобы при клике на корзинку в мобильной версии, выезжало это боковое меню сразу с развернутыми, добавленными товарами, а не пустым. Это ж не логично.
но зачем вы тогда используете подгрузку содержимого корзины по клику?
Я вижу несколько вариантов решения.
1) на странице не должно быть отдельно блоков для мобильного и отдельно для десктопа. [[HeaderDesktop]], [[HeaderMobile]] это плохая практика. Внешний вид должен адаптироваться под разные устройства за счет каскадных стилей и медиа запросов, а не за счет скрытия блоков для десктопа и отображения блоков для мобильных. В таком случае и корзина у вас всегда будет существовать на странице, потому что шапка остается всегда одной и той же.
2) Я вижу что у вас используется скорее всего какой то готовый шаблон интернет магазина, взятый с бескрайних просторов интернета, а значит переверстывать никто не будет. Тогда действительно придется иметь два разных чанка для шапки, в каждом полноценно вызывать [[!msMiniCart?&tpl=`miniCart`]], а не подгружать по клику, НО решать какой из чанков показать вам нужно еще на уровне обработки запроса на сервере. Помоему для modx даже была какой-то сниппет типа MobileDetect или как то так, который позволяет определить с какого устройства пришел запрос.
29 мая 2022, 07:38
+1
Юрий, вы всегда можете посмотреть, что содержит в себе та или иная переменная в феном, распечатав ее при помощи модификатора print {$delivery|print}
Наверняка там содержится и поле id и вы можете сделать как написал выше Артур.
Синтаксис шаблонизатора феном можно посмотреть тут github.com/fenom-template/fenom/tree/master/docs/ru
29 мая 2022, 07:26
0
Вы хотите чтобы ваш сниппет оперировал информацией, которую получает с формы.
Формы могут отправлять данные используя два метода http запросов — POST и GET
Следовательно вам нужно разместить на одной странице и форму и ваш сниппет.
Далее псевдо код, который не рассматривает вопросы безопасности.
<form method=post action=this page>
<input name=id>
<button>
</form>

[[snippet]]
if $_POST[id] {
sql = SELECT * FROM table WHERE id=$_POST[id]
get data by sql;
}
28 мая 2022, 15:13
0
Вам нужно просто поручить это сделать тому человеку, который разбирается.
Потому что даже подсказывать вам опасно, вы ведь сделаете по примеру и не подумаете о безопасности, о том, что давать возможность пользователю напрямую передавать данные из формы в sql запрос это очень опасно.
28 мая 2022, 10:43
0
по нескольким урлам надо открывать один и от же ресурс?
я лично уже запутался, о чем спрашивал автор статьи и на что мы ищем ответ.
Автор говорит
Ситуация — часть товаров выводятся в разных категориях.
насколько я понимаю, речь идет о том, что один товар minishop создан в одной категории, а в другие расставлен при помощи галочек. Но в таком случае, урл товара всегда одинаков ведь, разве нет? Не важно откуда мы на него перейдем, из основной категории или из виртуальной, урд товара будет один и тот же.
20 мая 2022, 10:56
0
Я хочу создать простой отчет с фильтром в менеджере
Что это значит? Вы хотите внутри человека менеджера запихнуть фильтр и бумажный отчет? Это жестоко.
Но если без иронии, то тоже не понятно. Что в вашем понимании «отчет». Отчет чего или кого. Причем тут фильтр?

А ответ Артура следует понимать так — создать что либо в админ панели довольно сложно, вам нужно как минимум хорошо знать сам modx и фреймворк extjs который отвечает за отрисовку интерфейса. Поэтому гораздо проще создать в админке просто ресурс, но снять галочку — опубликован. Внутри этого ресурса, вставляйте какие угодно самописные (или нет) сниппеты, которые создадут нужную вам логику. Такую страницу можно открыть по урлу как любую другую, но изза того, что она неопубликована, видите ее только вы, предварительно авторизовавшись в админке.
17 мая 2022, 16:07
+1
мне кажется, раз вы предварительно уточняли у разработчика компонента seofilter и купили его — вам нужно ему и писать в техподдержку.
уверен, что тот код который у вас приведен выше, вам не пригодится больше для вывода товаров.
ну и в целом, фильтровать что то у вас будет или невозможно или очень сложно.
Ваши значения заполняются вручную, в одном поле храниться как величина (10) так и единица измерения (кг), менеджер может в одном месте написать 3.4, а в другом 3,4 и так далее.
Мой совет — переделайте сайт используя минишоп и избавьтесь от характеристик на migx/
Это будет быстрее и правильнее.
16 мая 2022, 08:50
0
время ответа сервера не идеально, но не критично.
Я использую такую блочную систему только если руководство требует ручного управления блоками на странице. Это нужно далеко не везде, чаще всего макеты страниц статичны.
15 мая 2022, 12:51
0
внутрь чанка пробрасывается информация о блоке. чтобы уже внутри чанка можно было разобраться, откуда грузить данные.
15 мая 2022, 12:49
0
<?php
$fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true);
$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true);
if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) {
    $pdoFetch = new $pdoClass($modx, $scriptProperties);
} else {
    return false;
}


$blockList = $modx->resource->getTVValue("blockList");
$blockList = json_decode($blockList ,true);

$html = "";
foreach ($blockList as $key => $block){
    if (empty($block['chunkName']) or $block['isActive'] != 'Да')
        continue;

    $chunk = '@FILE blocks/'.$block['chunkName'];

    $html .= $pdoFetch->getChunk($chunk, $block);
}

return $html;
примерно так.
15 мая 2022, 12:05
+2
Опишу вкратце, как организовывал подобный функционал я, может кому то будет интересно.
Кода не будет, будут только общие концепции.
1) Есть конфигурация migx которая содержит
— название блока. Это для того чтобы менеджеру было сразу понятно, о чем этот блок. Никакой другой цели не несет.
— скриншот. Хранит скриншот того, как этот блок выглядит на странице. Тоже чтобы менеджеру было удобно.
— заголовок блока. Это текст, который может быть в блоке а может и нет. Например на одной странице нам нужно вывести иконки и написать вверху над ними — наши преимущества. А где то нужно обойтись только иконками.
— чекбокс Активен блок или нет.
— название чанка, хранящего верстку блока.
— описание. Для удобства менеджера, если управление блоком не очевидно и требует каких то комментариев.
— откуда брать данные для блока. Выпадающий список с такими вариантами. — брать с текущей страницы — брать с общих настроек. Детальнее что это опишу ниже.
2) На основании этой конфигурации создаем ТВ поле блок. Привязываем к нужным нам шаблонам.
3) Для удобства менеджера облегчим ему жизнь. Создадим несколько служебных ресурсов. Назовем их
— общие настройки
— категория товара
-товар
— инфостраница
Называем примерно так, чтобы была визуальна видна связь с шаблонам. Зачем нужны эти ресурсы. Они будут являться образцами. К примеру мы идем в служебный ресурс Товар и создаем там блоки (имеются ввиду ТВ поля типа migx).
Настраиваем их, располагаем в нужном нам порядке, так как хотим чтобы выглядела страница товара.
4) При создании любого ресурса срабатывает наш плагин (важно. именно при создании нового а не при обновлении) который понимает какой именно ресурс хотят создать (анализируя шаблон или анализируя родителя, внутри которого его хотят создать). К примеру плагин понял что хотят создать товар. Он идет в служебный ресурс товар и копирует оттуда все блоки, которые заранее настроил менеджер. Если плагину не удалось точно понять, какой ресурс хотят создать, он скопирует блоки с служебного ресурса — общие настройки.
5) мы сохранили новый ресурс и он уже заполнен блоками в нужном нам порядке. Но если менеджер хочет что то изменить, он может редактировать блоки уже принадлежащие этому ресурсу. Сделать эту страницу чем то отличающуюся от стандартного шаблона.
6) как это все работает и почему блоки отображаются на странице. А шаблонах не содержится верстки, кроме основного скелета html. На странице вызывается самописный сниппет buildpage задача которого получить значение migx tv с блоками на этой странице, получить инфу активен ли блок (нужно ли его вообще отображать на странице) и если активен — вызвать нужный чанк (имя которого тоже лежит в блоке). Очередность блоков задается менеджером путем перетаскивания строк в админке.
7) последнее время чанки, которые формируют внешний вид блока начал делать по типу компонентов vue. Имеется ввиду лишь идея, в чанке прописан как блок со стилями, так и html так и javascript относящийся к блоку. Соответственно если блок не активен, то нет и лишних стилей и скриптов.
8) осталось рассказать только об одном — о данных. Сами блоки — это лишь внешний вид, им нужно откуда то брать данные, причем эти данные могут быть разными для блока, в зависимости от того на какой странице он вызван. Данные для блоков храню так же в migx tv полях. Возьму для примера тот же блок — наши преимущества (не знаю как у вас но наши сеошники аж трясутся над этим блоком и пихают его чуть ли не по 10 штук на страницу). Так вот. Создаю конфигурацию migx задача которой хранить изображения. Создаю ТВ поле — блок наши преимущества, которые построен на этой конфигурации. Это ТВ поле есть как у служебных ресурсов, так и у реальных ресурсов, создаваемых менеджером. Настройка в блоке, с именем «Откуда брать данные» как раз и отвечает за это. Менеджер может заполнить один раз данные для блока преимущества (загрузить иконки, возможно написать текст) в служебном ресурсе Общие настройки. Активируя блок «наши преимущества» на любой странице сайта менеджер просто выбирает — брать данные из общих настроек. Если нужно для этой страницы задать индивидуальные данные, то нужно всего лишь перезаполнить соответствующее ТВ поле уже этого ресурса и выставить у блока — «брать данные с этой страницы».
В общем то и все.
14 мая 2022, 08:49
0
а вот еще хотелось бы мне подискутировать на затронутую мной же тему jwt токенов.
Кто скажет, почему 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 минут.
13 мая 2022, 19:49
0
nginx у нас это прокси сервер, nitro это веб сервер. Причем я почитал документацию, он умеет отдавать и статику тоже.
Зачем использовать nginx, почему не настроить nitro на 80 порт и слушать запросы напрямую на нем?
13 мая 2022, 19:34
0
А Nuxt и прочее Node.js это уже для серьёзных специалистов.
с этим наверное не соглашусь. Наоборот, современная разработка становится все более высокоуровневой, мы оперируем сплошными абстракциями, все дальше уходя от компьютера как железа. Программировать становится все проще, синтаксис все сахарнее. Скоро доживем до того, что программирование будет типа
const site = new Site();
site->getWonderfullShop('no cart please');
Поэтому не соглашусь, что nodejs это для специалистов. Синтаксис там простой, библиотек море.
Вот ассемблер — это для специалистов.
13 мая 2022, 19:29
0
с этим почти согласен. Ну разве что php-fpm не является серверов, это процесс демон интерпретатора php.
13 мая 2022, 14:08
0
гугл умеет хорошо индексировать без ssr, а вот яндекс, вы правы, не хочет.
13 мая 2022, 12:33
0
я не подскажу, к сожалению. Плохо вообще понимаю что такое nuxt и зачем это существует. Очень слабо понимаю, зачем для работы js фрейворков требуется аж два одновременно работающих вебсервера — свой и nginx (пусть даже последний выполняет роль прокси сервера). Это все равно если бы мы писали программу на php, переносили ее на продакшен, так запускали локальный веб сервер php
php -S localhost:8080 -t public
естественно что так до нашей программы нельзя достучаться из браузера, поэтому мы запускаем еще и nginx который настраиваем на проксирование всех запросов с порта 80 на порт 8080 и оно даже будет работать, но вопрос — зачем.
Но вам чтобы увидеть приветственную страницу именно так и нужно сделать. Установить nginx, настроить его дефолтный конфигурационный файл на слушанье 80 порта и тупое проксирование всех запросов на тот порт, на котором запустился ваш nuxt