Финансовая поддержка VPS, бесплатные дополнения и docs Донаты оплачивают сервер и двигают бесплатные дополнения MODX и документацию. Поддержать

Всего 126 117 комментариев

Александр Туниеков
Александр Туниеков
Кстати GRUD в getTables реализован и можно его использовать для подобной задачи :-). У пользователей MODX 2 таблицы и не так просто. Но можно попробовать.

На странице на которую ограничен доступ пишем сниппет:
{'!getTable' | snippet : [
    'table'=>[
        'event'=>1,
        'class'=>'modUser',
        'actions'=>[
            'create'=>[],
            'update'=>[],
            'remove'=>[],
            'export_excel'=>[],
        ],
        'pdoTools'=>[
            'class'=>'modUser',
            'leftJoin'=>[
                'modUserProfile'=>[
                    'class'=>'modUserProfile',
                    'on'=>'modUserProfile.internalKey = modUser.id'
                ]
            ],
            'select'=>[
                'modUser'=>'modUser.id',
                'modUserProfile'=>'modUserProfile.fullname,modUserProfile.email,modUserProfile.phone',
            ],
            'sortby'=>[
                'modUser.id'=>'DESC'
            ]
        ],
        'row'=>[
            'id'=>['filter'=>1],
            'password'=>[
                'edit'=>['type'=>'hidden'],
                'default'=>'Не секретный пароль'
            ],
            'fullname'=>[
                'class'=>'modUserProfile',
                'label'=>'ФИО',
                'edit'=>['type'=>'text','search_fields'=>['internalKey'=>'id'],],
                'filter'=>1,
            ],
            'email'=>[
                'class'=>'modUserProfile',
                'label'=>'email',
                'edit'=>['type'=>'text','search_fields'=>['internalKey'=>'id'],],
                'filter'=>1,
            ],
            'phone'=>[
                'class'=>'modUserProfile',
                'label'=>'Телефон',
                'edit'=>['type'=>'text','search_fields'=>['internalKey'=>'id'],],
                'filter'=>1,
            ],
        ]
    ]
]}
Пишем плагин на событие getTablesAfterUpdateCreate. Для работы плагина в сниппете должно быть указано 'event'=>1, как выше.
<?php
switch ($modx->event->name) {
    case 'getTablesAfterUpdateCreate':
        // $modx->log(1,'getTablesAfterUpdateCreate '.print_r($data,1));
        if($data['table_name'] == 'modUser' and $data['gts_action'] == 'getTable/create'){
            if($modUser = $modx->getObject('modUser',(int)$data['id'])){
                $modUser->set('username',$data['email']);
                $modUser->set('password',md5(date('d.m.Y H:i:s')));
                $modUser->joinGroup(2);
                $modUser->save();
            }
        }
    break;
}
И все работает :-).


Так же можно это же сделать с PVTables, но этот компонент я еще не добрался опубликовать :-(. И писать в 2 таблицы сразу там не сделанно. И события не все прописал :-(.

Безопасность обеспечивается хеш-кодом. Страница на которой опубликован сниппет должна быть доступна только нужным пользователям. Использовать getTables, для подобных задач, думаю, проше и быстрее чем писать контроллеры для sendIt.
Александр Туниеков
Александр Туниеков
Какая версия MySQL? На MySQL 8 возникала проблема. Он почему-то не воспринимает двойную сортировку.
sort by pagetitle ASC, createon DESC
И MySQL 8 возвращает ошибку. В коде от Ильи двойная сортировка используется и нужна. Когда с этой ошибкой столкнулся не было времени ее решать, но на всякий случай сейчас MySQL 8 не ставлю.
Александр Туниеков
Александр Туниеков
Тоже интересно что с безопасностью. В коде на гитхабе никаких проверок на доступ. Возможно безопасность обеспечивает SendIt, но автор вообще не указал как SendIt подключается и используется. Наверно в SendIt подключаются прессеты??? В общем, для человека не знакомого с SendIt, как мне, статья вообще не понятная.

Безопасность может быть реализованна таким образом. Сниппет, типа AjaxForm, при обработки страницы, записывает в сессию хеш-код. js в браузере отправляет с формой этот хеш-код. Обработчик ajax запросов на сервере смотрит есть ли в сесии этот хеш-код и если его нет, то возращяет ошибку.
Таким образом, если сниппет не был вызван при обработке страницы, то все ajax запросы завершаться ошибкой. Будут приняты только те запросы с правильным хеш-кодом.
А на ресурс MODX можно поставить ограничения и показывать его только разрешенным пользователям. Соответственно на странице на запрещенном ресурсе сниппет не отработал, хеш-код в сессию не записался и ajax запросы не срабатывают.

В общем не знаю, как безопасность реализованна в SendIt, но наверно что-то подобное. Надеюсь
@Артур Шевченко просветит нас :-)
Ivan K.
Ivan K.
Сегодня столкнулся с подобной проблемой.
MODX3 + php8.1

Выяснил, что причина в слеше в начале твшки с картинкой.
Решил топорным методом.
[[pthumb? &input=`[[+tv.foto:replace=`/assets/files/==assets/files/`]]` &options=`w=250&h=180&zc=1`]]
Вдруг кому пригодится.
Pavel
Pavel
Спасибо большое за решение, я думаю попробовать его для аренды техники — тоже посуточно.
Правда появились вопросы — везде теперь написано «аренда номера» и надо это как-то мне выпиливать.
И второе — подключается bootstrap и jq которые у меня уже подключены и хотелось бы иметь возможность их отключить ((
Благодарю
Ivan K.
Ivan K.
Здравствуйте.
Отличное и нужное решение. Обязательно воспользуюсь.
Но хотел уточнить не возникнет ли проблем при использовании MODX3 + php8.1?
И в плане безопасности можно ли использовать в «личном кабинете пользователя» (простые юзеры, которые залогинены в контексте web) данное решение? хотел кастомную таблицу подключить, чтобы юзеры меняли в ней данные.
Сергей
Сергей
Володя, подскажи пожалуйста на какое событие нужно создать скрипт, что бы при фильтрации через msearch2 выбиралась нужная опция. Сейчас работает только при повторном обновлении страницы в дефолтным классом. И почему у кастомного msopfilters.class.php нет выбора нужной опции при фильтрации. И почему то при добавлении зависимостей, очень медленно работает. Речь о фильтрации и выводе в каталоге.
Сергей Шлоков
Сергей Шлоков
Как по мне, чересчур громоздко. Логика с date и start/end не очевидна. Да и в коде слишком много лишней логики. Я бы предложил вариант с датой и длительностью (просто в целях разминки полушарий)
$date = $modx->getOption('date', $scriptProperties, '');
$duration = $modx->getOption('duration', $scriptProperties, '1');
$chunk = $modx->getOption('tpl', $scriptProperties, '');

if (empty($date) || empty($chunk)) {
  return '';
}

[$day, $month, $year] = sscanf($date, "%d.%d.%d");
$year ??= date('Y');
$date = "$day.$month.$year";

$currentTimestamp = time();
$startTimestamp = strtotime($date);
$endTimestamp = strtotime($date . " + $duration days");

if ($currentTimestamp >= $startTimestamp && $currentTimestamp < $endTimestamp) {
  $pdoTools = $modx->getService('pdoTools');
  return $pdoTools->getChunk($chunk);
}
Указал год — сработает только для него. Не указал, ежегодно. Если длительность не указана, то она равна 1 дню.
Артур Шевченко
Артур Шевченко
Немного сократил и добавил поддержку файловых чанков.
<?php
$start = $modx->getOption('start', $scriptProperties, '');
$end = $modx->getOption('end', $scriptProperties, '');
$chunk = $modx->getOption('tpl', $scriptProperties, '');

// определяем в каких случаях мы ничего не будем делать, нам важно не перетрудиться.
if((!$start && !$end) || !$chunk){
    return '';
}
// завозим поддержку файловых чанков
if(!$parser = $modx->getService('pdoTools')){
    $parser = $modx;
}

$now = strtotime('d.m.Y');
$currentYear = date('Y');
// предполагается что дада передаётся строкой вида "d.m"
$startTime = strtotime($start . '.' . $currentYear);

// если задана только дата начала, считае, что оформление будет активно только в эту дату
if(!$end){
    if($now === $startTime){
        return $parser->getChunk($chunk);
    }
}

$startParts = explode('.', $start);
$endParts = explode('.', $end);

// проверяем больше месяц даты начала месяца даты окончания
if((int)$startParts[1] > (int)$endParts[1]){
    $endTime = strtotime($end . '.' . ($currentYear + 1));
}else{
    $endTime = strtotime($end . '.' . $currentYear);
}

if ($now < $startTime || $now > $endTime) {
   return '';
}
return $parser->getChunk($chunk);
Дима Касаткин
Дима Касаткин
Вообще чем-то похоже на работу пакета BannerY получилось кстати. Только опять же, со срабатыванием каждый год. На самом деле для ежегодных праздников твой вариант подходит конечно идеально!
Дима Касаткин
Дима Касаткин
Пользуюсь похожей конструкцией, чтобы редактировать TV-шки с фронта. Отличный пример допиливания полезного функционала под проект, спасибо!

P.S. Поправь плиз отступы в форматировании кода во 3 и 4 блоках, а то я shift+tab чуть не нажал машинально, когда читал :)