Всего 125 692 комментария

Артур Шевченко
17 мая 2021, 13:00
0
Люди предупреждены. А за ревью спасибо.
Павел Бигель
17 мая 2021, 12:29
+6
Мне как раз все понятно.
{if $_modx->user.id > 0}           
    <a href="[[~13]]">  <!-- 13 это id ресурса с формой оформления заказа -->
         <button type="submit" class="knopka2">
             Оформить заказ
       </button>
    </a>          
{else}
    <button type="button" data-toggle="modal" data-target="#modalSMSAuth" class="knopka2">
        Оформить заказ
    </button>
{/if}
Помесь стандартного и fenom синтаксиса это дурной тон.

{'!AjaxForm' | snippet:[
                'snippet' =>'custConfirm',
                'form' =>'@FILE chunks/forms/confirmForm.html',
                'validate'=>'phone:required'
            ]} 
            {'!AjaxForm' | snippet:[
                'snippet' =>'custCheckCode',
                'customValidators' => 'validateCode'
                'form' =>'@FILE chunks/forms/checkcodeForm.html',
                'validate'=>'phone:required,code:validateCode',
                'redirectTo' => 13 
            ]}
Два некешированных вызова AjaxForm. А че ж не 5? Эту задачу можно решить одним вызовом сниппета.

<?php
$file = MODX_CORE_PATH . 'components/codesender/smsc_api.php';
if(!file_exists($file)){
    $modx->log(1, 'FILE NOT FOUND');
}
include_once $file;

if(!isset($translit)){
    $translit = 1; // по умолчанию отправляем транслит, там можно впихнуть больше текста
}
$send = send_sms($number, $message, $translit);

return $send;
Такого рода задачи решаются не сниппетами. Сниппеты это вообще про другое.
Более того, ты же ниже создаешь пакет, какая проблема примутить к нему класс-контроллер?

Тут вы вероятно заметили, что есть сниппет genPassword, изнутри он выглядит так
Опять же а) Не решаются такие задачи сниппетами б) mt_rand не является безопасным для задач уровня генерации паролей. Ты бы это знал, если бы писал это сам.

Итак, выходим на финишную прямую. Сниппет custCheckCode отвечает за проверку кода, авторизацию и регистрацию пользователей
Снова, такие задачи не решаются сниппетами.

// если ошибок нет
    if($_POST['phone']){
        $username = preg_replace('/[^0-9]/', '', trim($_POST['phone']));
        $params = array('username' => $username, 'password' => $_POST['code'], 'group' => 2, 'active' => true, 'blocked' => false);
        $params = array_merge($_POST, $params);
        $user = $modx->getObject('modUser', array('username' => $username));
        if(!$user){
            $modx->log(1, 'Регистрация');
            $user = $modx->runSnippet('Registration', array('params' => $params));
        }
        $user->set('password', $_POST['code']);
        $user->save();
        $response = $modx->runSnippet('Authorization', array('params' => $params));
        if(!$response['success']){
            return  $AjaxForm->error($response['message'],  array());
        }
        $redirectId= $scriptProperties['redirectTo'] ?: 1; // при вызове сниппета мы передаём id ресурса, на который нужно сделать редирект, если не передаем, то редирект будет на главную.
        $redirectUrl = $modx->makeUrl($redirectId , 'web', '', 'full'); 
        return $AjaxForm->success($response['message'], array('redirectTo' => $redirectUrl)); 
    }
}
Из поста данные не валидируются. Пахнет безопасностью! Либо впадлу, либо не знаешь что это такое.
Тут кстати гораздо логичнее была бы проверка на false.

Кастомный валидатор validateCode содержит такой код:
Опять никакой валидации. Еще и сырой запрос (вызов которого не оправдан ничем)

Регистрацию я сделал так (Registration)
Ни единой проверки на то что модель не сохранилась. Неверное сохранение аггеративных моделей.

Итого: куски сомнительного кода не несущие абсолютно никакой ценности.
Я бы ни слова ни сказал, даже плюсик бы залепил если бы тут было хоть какое-то объяснение происходящего.
Почему так, а не иначе, почему это лучше, а это хуже.

Итого ты не учишь, а даешь людям копировать плохие практики.
Абсолютно заслуженный минус
Павел Бигель
17 мая 2021, 10:48
+1
Простыня кода, три строчки текста, никаких объяснений, нулевая информативность.
Alexey
17 мая 2021, 09:25
0
В плагине после строки

case 'OnWebPagePrerender':
добавить строку

if($modx->resource->id == 8) return;

где 8 — id нужного ресурса, меняем на нужный.
Georg
17 мая 2021, 09:09
0
Я так понимаю можно и на ID ресурса проверку сделать? AMP без шаблона делаю. Может есть где-то образец как реализовать? Порылся в интернете не нашел, а плагины и сниппеты, это прям не про меня если честно.
Наумов Алексей
17 мая 2021, 08:33
0
Один из простых вариантов — это создать пользователя Гость (Покупатель) и заказы плагином вешать на него. Но у данного лица есть поле email, а у заказа нет такого поля) вот тут будут проблемы, если вам при оформлении заказа нужна почта.
Артур Шевченко
17 мая 2021, 07:53
0
Спасибо за комментарий, но причина появления сниппета genPassword не в длине пароля, а в его составе, в своём сниппите я могу генерировать числовой код, а если использовать стандартный механизм там будут разные символы, а не только числа. Людям удобнее вводить числа, как показала практика и надёжность пароля им не важна. Ещё я думаю, что наверное после авторизации надо менять пароль ещё раз на более сложный, чтоб никто другой войти не смог. Хотя возможно это излишняя предосторожность.
Евгений Генералов
17 мая 2021, 07:41
0
Хорошая статья.
От себя могу добавить, сниппет genPassword можно не писать. У класса modUser есть метод generatePassword. В который тоже можно передать длину пароля
Lori
17 мая 2021, 06:08
0
у меня контекст один. Идея была такая же, только проблема в реализации — я свой первый сниппет буквально два 3 назад написал)
Valeria
16 мая 2021, 22:47
0
Изменить стили хочу на странице категории товаров.
Отображаю при помощи pdoPage:
[[!pdoPage? 
        &element=`msProducts`
        &tpl=`products_row`
        &includeTVs=`prod-img`
        &limit=`400`
]]
Содержимое products_row:
<tr>
	<td class="prod-name">{$pagetitle}</td>
	<td class="prod-size">[[!msOptions? &options=`size` &tpl=`tpl.msOptions-sizes` &product=`[[+id]]`]]</td>
	<td class="prod-sost">[[!msOptions? &options=`sost` &tpl=`tpl.msOptions-sizes` &product=`[[+id]]`]]</td>
	<td class="prod-nalichie">{$weight} кг</td>
	<td class="prod-price">{$price | replace:" ":""} руб.</td>
	<td class="prod-primechanie">[[!msOptions? &options=`prim` &tpl=`tpl.msOptions-sizes` &product=`[[+id]]`]]</td>
	<td>[[+prod-img]]</td>
</tr>
Добавляю код, предложенный Евгением, задала стили классу, поставила галочку — ничего не изменилось.
Александр Мельник
16 мая 2021, 19:10
0
представьте насколько проще было бы вам помочь, если бы вы показали, куда и что вставляете.
Начнем с того, где вы хотите «изменить стили»? На странице категории товаров (где идет вывод списка товаров) или на посадочной конечной странице товара?
Если в категории товаров, то как вы их отображаете, при помощи сниппета msProducts?
Если да, то вы в нем указываете имя tpl чанка, который отвечает за отображение одного товара в списке, ведь так? В этом чанке будет работать код, указанный Евгением — тоесть проверка на то что в переменной $favorite лежит что-то что может быть приведено к true. Ставите у товара галочку — особый и в эту переменную попадает 1.

Если вы хотите иметь доступ к переменной $favorite на странице товара, то используйте такой вызов
{ if $_modx->resource.favorite}my_class_for_favorite{/if}
Евгений Шеронов
16 мая 2021, 16:22
0
Тут человек AjaxForm путает с AjaxSnippet, поэтому твой совет не поможет (но комментарий привлёк меня, так что косвенно ты тоже помогаешь :))
Там нет никакой формы и вообще ничто никуда не отправится.

При этом сниппет addfavorites ведёт себя как хук для FormIt (хотя вполне себе можно без него, просто оперируя POST данными).

Следовательно вызов в таблице должен быть таким:
(чтобы не мешать синтаксис, ведь люди старались сделать всё изначально на Fenom)
{$_modx->runSnippet('!AjaxForm', [
    'snippet' => 'FormIt',
    'form' => 'tpl.Favorite',
    'hooks' =>  'addfavorite',
    'fi.name' => $service.name,
    'fi.id_service' => $service.id_service,
    'fi.cost' => $service.cost,
    'fi.address' => $service.address
])}
Параметры fi.name и т.д. нужны, чтобы прокинуть данные в форму. См. modx.pro/components/3342

А чанк tpl.Favorite переделать хотя бы так:
<form action="" method="post" class="ajax_form">
    <input type="hidden" name="name" value="[[+fi.name]]">
    <input type="hidden" name="id_service" value="[[+fi.id_service]]">
    <input type="hidden" name="cost" value="[[+fi.cost]]">
    <input type="hidden" name="address" value="[[+fi.address]]">
    <button type="submit" class="center">В избранное</button>
</form>
Это, конечно, не отменяет множество проблем в коде автора.
Например строка $id_user = $modx->user->get('id'); будет работать только для авторизованных пользователей (для админа когда он проверяет). А на пользователях-гостях вполне себе будет падать.

Ну и какой-то странный формат HTML вёрстки с запятой и разными кавычками)
<td class='service' id="cost", value="{$service.price}">Стоимость: {$service.price} ₽</td>

Мне немного страшно и интересно, как же будет выглядеть запрос, который положит данные в базу.
Valeria
16 мая 2021, 15:59
0
я, похоже, как обычно куда-то не туда вставляю, потому что у меня ничего не получается(
Николай Савин
16 мая 2021, 13:34
0
Отлавливайте клик средствами JS. Передайте куда нибудь в data атрибут идентификатор товара.
После того как поймаете клик по нужному товару — сформируйте ajax запрос на сайт.
Ловите запрос через плагин на событие onHandleRequest и далее уже средствами php как-нибудь запоминайте этот товар как избранный
Alexey
16 мая 2021, 12:24
0
Помню, несколько лет назад реализовывал функционал избранного, но не через сессии, а через куки.

То есть, при добавлении в избранное, идет проверка, авторизован ли пользователь на фронтенде. Если да, то id товара пишется в extended пользователя, если нет, то сажаем ему куку в браузер. Список айдишников просто через запятую, при добавлении, есесно, проверяем наличие этого айдишника в избранном, если есть, то удаляем из избранного и наоборот.

Плюс этого варианта в отсутствии необходимости добавлять отдельную таблицу. Но какие-то подводные камни были… Вроде бы, связанные с разными контекстами
Николай Савин
16 мая 2021, 11:54
0
Вообще если честно судя по списку ваших вопросов я вам вряд ли смогу помочь подобными алгоритмами.
Больно уж много знать нужно о MODX
Николай Савин
16 мая 2021, 11:52
+1
Суть будет примерно такая.

1. Нужно создать таблицу в базе данных. Поля user_id — число, session_id — строка, product_id — число
2. Создать модель для этой таблицы, чтобы modx знал о ее существовании.
3. Создать класс управления таблицей. Основные методы add(), remove(), getList(), может быть getCount()
4. В каждом методе написать обращение к таблице и ее чтение, добавление записи, удаление записи.
5. При записи в таблицу если пользователь авторизован — записывать его Id как идентификатор, если нет — то записывать session_id
6. Подготовить js файл который по клику будет определять чего хочет пользователь и слать запрос на корневой адрес сайта
7. Подготовить плагин на событие OnHandleRequest который будет слушать обращения JS файла и вызывать класс компонента и соответствующий метод.
Амина
16 мая 2021, 11:42
0
Подскажите, пожалуйста