Всего 123 786 комментариев

vit
vit
31 марта 2024, 21:15
0
Не знаю на FetchIt перешел. Он работает
Dmitrii
31 марта 2024, 16:15
0
Здравствуйте! Обновление не планируете? Необходимо адаптировать к php 8+
Арман
31 марта 2024, 12:05
0
А сейчас работает?
vit
vit
31 марта 2024, 09:24
0
У меня на MODX3 с php 8.1 тоже не работал месяц назад
Герман
31 марта 2024, 01:42
0
Оказалось, что если вернуть просто айдишники нужных статей, а затем сделать фильтр по полю resources, то все работает. Но тем не менее хотелось бы знать почему было такое поведение
vit
vit
30 марта 2024, 18:07
0
Так же как и Products с помощью foreach можно
Артур Шевченко
30 марта 2024, 14:50
0
Оставил только один товар на главной, можете смотреть.
Владимир
30 марта 2024, 13:26
0
что-то здесь modifications.art-sites.ru/ так и не нашел примера работы ( можете подсказать где там это посмотреть?
Алексей Смирнов
29 марта 2024, 21:20
0
Странное поведение, но вы проверьте плагины. (Поочередно поотключайте подозрительные.) может там есть плагинчик на корректировки и он не корректно обрабатывает что-то.
Матвей
29 марта 2024, 20:59
0
Ответ оказался прост…

!!! Надо изучать мануалы!!!
Чтение — решение всех проблем!

Если добавляем id ресурса, то фильтруем по нему
&where=`{"id":"[[*id]]"}`
Или фильтруем по полю

&where=`{"name":"[[*pagetitle]]"}`
Дима Касаткин
29 марта 2024, 16:38
0
И всё для того, чтобы пользователи не начинали развиваться.
Василий, прекращай пожалуйста путать развитие разработчика (программиста, ИТ-гика, кодера, PHP-шника и т.п.) с развитием например маркетолога, который собирает сайты на MODX CMS (вместо Wordpress и Битрикс и etc) чтобы иногда пригласить разработчика на сложные задачи.

Дружелюбность системы, баланс её простоты и функционала, скорость развёртывания позволят её развиваться и привлекать новых пользователей.

Развитие!=Усложнение. Часто бывает наоборот, у гиков реже. Но для гиков уже есть фреймворки с их усложнениями на любую глубину погружения, а MODX крут тем, что сохранял баланс простоты.

Или сделать проще слишком сложно ?)) (Вот он и вызов!)
vit
vit
29 марта 2024, 15:53
0
Да я сейчас сразу все в migxDB делаю просто попался проект где уже сделано все в обычном migx. А переносить они не хотят. Поэтому ищу варианты. Спасибо за ответ)
Алексей Смирнов
29 марта 2024, 10:58
+1
100 ограничивает 1 поле.
те если 2 ТВ, то у каждого по 100.
Это ограничение можно увеличить, но не нужно.
Потому что если у вас планируется более 100 записей делайте, как вам Денис посоветовал, лучше пройти по ссылке и сделать отдельную БД для этих записей.
Потому что иначе вы можете столкнуться с уничтожением или не корректностью данных в данном поле, а так же с различными глюками и неприятностями.
Валерий
28 марта 2024, 22:34
0
5. Настроил компонент Login.
6. И в раздел «Редактирование данных» у уже авторизованного пользователя вывел следующий сниппет:

<?php
$modx->initialize('web');
// Проверяем, авторизован ли пользователь
if ($modx->user->isAuthenticated('web')) {
    // Получаем имя пользователя (username) из текущей сессии
    $FUusername = $modx->user->get('username');
    // ID категории, где находятся ресурсы
    $FUcategoryId = 162;
    // Получаем все ресурсы из категории с ID 162
    $resources = $modx->getCollection('modResource', array('parent' => $FUcategoryId));
    // Переменная для хранения найденного ресурса
    $foundResourceId = null;

    // Проходим по каждому ресурсу
    foreach ($resources as $resource) {
        // Получаем значение TV-поля "mentor_email" для текущего ресурса
        $mentorEmail = strtolower($resource->getTVValue('mentor_email'));

        // Сравниваем значение TV-поля "mentor_email" с именем пользователя
        if ($mentorEmail == $FUusername) {
            // Если значение TV-поля "mentor_email" совпадает с именем пользователя, сохраняем ID этого ресурса
            $foundResourceId = $resource->get('id');
            break; // Прекращаем цикл, так как уже нашли нужный ресурс
        }
    }

    // Проверяем, был ли найден ресурс с TV-полем "mentor_email" равным имени пользователя
    if ($foundResourceId) {
        $_SESSION['current_resource_id'] = $foundResourceId;
        // Если форма была отправлена
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            // Получаем значение TV-поля "mentor_test" из отправленной формы
            $mentorTestValue = $_POST['mentor_test'] ?? '';
            $workingBusyValue = $_POST['workingBusy'] ?? '';
            $workingPersonFormatValue = $_POST['workingPersonFormat'] ?? '';

            // Получаем объект ресурса
            $resource = $modx->getObject('modResource', $foundResourceId);

            // Проверяем, был ли найден ресурс
            if ($resource) {
                // Сохраняем значение TV-поля "mentor_test"
                $resource->setTVValue('mentor_test', $mentorTestValue);
                $resource->setTVValue('workingBusy', $workingBusyValue);
                $resource->setTVValue('workingPersonFormat', $workingPersonFormatValue);
                $resource->save();
                
                // Перенаправляем пользователя на текущую страницу для предотвращения повторной отправки формы
                header('Location: ' . $_SERVER['REQUEST_URI']);
                exit();
            }
        }

        // Получаем данные ресурса
        $resource = $modx->getObject('modResource', $foundResourceId);

        // Проверяем, был ли найден ресурс
        if ($resource) {
            // Получаем значение TV-поля "mentor_test"
            $mentorTest = $resource->getTVValue('mentor_test');
            $workingBusy = $resource->getTVValue('workingBusy');
            $workingPersonFormat = $resource->getTVValue('workingPersonFormat');
            
            // Выводим значения переменных для отладки
            echo '<pre>';
            echo 'mentor_test: ' . $mentorTest . PHP_EOL;
            echo 'workingBusy: ' . $workingBusy . PHP_EOL;
            echo 'workingPersonFormat: ' . $workingPersonFormat . PHP_EOL;
            echo '</pre>';
            // Передаем данные в чанк "edit_profile_chunk" для заполнения формы
            $output = $modx->getChunk('edit_profile_chunk', array(
                'mentor_test' => $mentorTest,
                'workingBusy' => $workingBusy,
                'workingPersonFormat' => $workingPersonFormat,
                // Другие данные для заполнения формы
            ));
        } else {
            // Если ресурс не найден, выводим сообщение об ошибке
            $output = 'Ресурс не найден';
        }
    } else {
        // Если не найден ресурс с TV-полем "mentor_email" равным имени пользователя
        $output = 'Не найдено ресурсов с TV-полем ' . $FUusername .', равным имени пользователя';
    }
} else {
    // Если пользователь не авторизован, возвращаем сообщение об ошибке или что-то другое
    $output = 'Пользователь не авторизован';
}

return $output;
7. Ну и чанк, в который передаются данные и из которого формируется сама страница:

<form action="[[~[[*id]]]]" method="post" class="form-edit" id="editProfileForm">
    <div class="form-edit__input">
        <label for="mentorTest">Тестовое поле:</label>
        <span class="form-edit__note">Немного слов.</span>
        <input type="text" id="mentorTest" name="mentor_test" value="[[+mentor_test]]">
    </div>
    <div class="form-edit__select">
        <label for="workingBus">Есть свободные слоты:</label>
        <span class="form-edit__note">Поставить значение «нет» в том случае, когда у вас нет свободных мест для работы с студентами.</span>
        <select id="workingBusy" name="workingBusy">
            <option value="0" [[!If? &subject=`[[+workingBusy]]` &operator=`=` &operand=`0` &then=`selected`]]>Да</option>
            <option value="1" [[!If? &subject=`[[+workingBusy]]` &operator=`=` &operand=`1` &then=`selected`]]>Нет</option>
        </select>
    </div>
    <div class="form-edit__select">
        <label for="workingBus">Доступный формат приема:</label>
        <span class="form-edit__note">Внимание! Указывать формат, который вам разрешен для проведения сертификационных сессий.</span>
        <select id="workingPersonFormat" name="workingPersonFormat">
            <option value="0" [[!If? &subject=`[[+workingPersonFormat]]` &operator=`=` &operand=`0` &then=`selected`]]>Очно</option>
            <option value="1" [[!If? &subject=`[[+workingPersonFormat]]` &operator=`=` &operand=`1` &then=`selected`]]>Онлайн</option>
            <option value="2" [[!If? &subject=`[[+workingPersonFormat]]` &operator=`=` &operand=`2` &then=`selected`]]>Оба варианта</option>
        </select>
    </div>
    <!-- Другие поля для редактирования -->
    
    <!-- Кнопка для отправки формы -->
    <button type="submit" class="btn btn_green btn_forSave">Сохранить</button>
</form>
<script>
    // JavaScript для предотвращения множественных отправок формы
    document.getElementById('editProfileForm').addEventListener('submit', function(event) {
        // Проверяем, была ли форма отправлена ранее
        if (this.getAttribute('data-submitted') === 'true') {
            // Если форма уже была отправлена, предотвращаем повторную отправку
            event.preventDefault();
            return;
        }

        // Отмечаем форму как отправленную
        this.setAttribute('data-submitted', 'true');

        // Отключаем кнопку "Сохранить"
        document.getElementById('saveButton').disabled = true;

        // Отправляем форму асинхронным запросом
        var formData = new FormData(this);
        var xhr = new XMLHttpRequest();
        xhr.open('POST', this.action);
        xhr.onload = function() {
            if (xhr.status === 200) {
                // Если запрос выполнен успешно, перезагружаем страницу
                location.reload();
            } else {
                // Если произошла ошибка, разрешаем повторную отправку формы
                document.getElementById('editProfileForm').removeAttribute('data-submitted');
                document.getElementById('saveButton').disabled = false;
            }
        };
        xhr.send(formData);
    });
</script>
Собственно все. Подозреваю, что с выводом TV полей уже для редактирования можно было бы как-то лучше разобраться, но пока такой формат работает и нагрузки лишней нет. Есть проблемы с мультиполями, с ними еще работаю.
Валерий
28 марта 2024, 22:31
0
В итоге сделал, все работает корректно. Но пошел по пути написания сниппета и небольшого «одноразового» сниппета для регистрации пользователей. Оставлю тут, может кому пригодится.
Конечно, код далек от идеального, я так и не добрался до php в чистом виде, только наверстываю. Может кто-то укажет на явные косяки и чрезмерность (стартовый каркас писал с помощью ChatGPT, потом уже все в рабочий вид превращал).

1. Вначале отсортировал в JSON файл всех сотрудников, у которых есть почты (было решено опираться на соответствие почты в карточках и у пользователя).
2. Вывел JSON с параметрами email и name (на самом деле больше параметров, но нужны для конкретной цели только эти два).
3. Создал группу для пользователей с нужными мне настройками доступа (работа ВНЕ админки).
4. Написал сниппет:
<?php
$usersJsonPath = 'https://migip-reg.ru/tehnicheskie-stranicy/fullstuff-list.json'; // Укажите путь к вашему JSON файлу

// Функция для создания случайного пароля
function generateRandomPassword($length = 8) {
    $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $password = '';
    for ($i = 0; $i < $length; $i++) {
        $password .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $password;
}

// Получение данных из JSON файла
$jsonData = file_get_contents($usersJsonPath);
if ($jsonData === false) {
    // Выводим сообщение об ошибке, если не удалось получить данные из JSON
    echo 'Не удалось получить данные из JSON файла';
} else {
    // Данные из JSON получены успешно, декодируем их
    $usersData = json_decode($jsonData, true);
    
    // Проверяем, произошла ли ошибка при декодировании JSON
    if (json_last_error() !== JSON_ERROR_NONE) {
        echo 'Ошибка при декодировании JSON: ' . json_last_error_msg();
    } else {
        // Данные из JSON успешно декодированы, выводим их для отладки
        echo '<pre>';
        print_r($usersData);
        echo '</pre>';
        
        // Проходим по каждому пользователю и создаем его в MODX
        foreach ($usersData as $userData) {
            $email = strtolower($userData['email']);
            $fullName = $userData['name'];

            // Проверка на существование пользователя с таким email
            if (!$modx->getObject('modUser', array('email' => $email))) {
                // Пользователя с таким email не существует, создаем нового
                $user = $modx->newObject('modUser');
                $user->set('username', $email); // Используем email в качестве имени пользователя
                $user->set('email', $email);
                $user->set('password', generateRandomPassword()); // Генерируем случайный пароль
                $user->set('active', 1); // Устанавливаем пользователя активным
                
                // Создаем профиль пользователя
                $profile = $modx->newObject('modUserProfile');
                $profile->set('internalKey', $user->get('id')); // Устанавливаем внутренний ключ профиля равным ID пользователя
                $profile->set('fullname', $fullName); // Устанавливаем полное имя
                $profile->set('email', $email); // Устанавливаем адрес электронной почты

                // Присоединяем профиль к пользователю
                $user->addOne($profile);

                // Сохраняем пользователя
                $user->save();

                // Добавляем пользователя в группу "Stuff"
                $user->joinGroup('Stuff');
                $user->save();
            }
        }
    }
}
Таким образом были созданы все пользователи с именем пользователя и почтой = почты в карточках специалистов, и полным именем из карточек специалистов.
Сергей Карпович
28 марта 2024, 18:07
0
Файл изображения — название файла с расширением
Путь к файлу — путь где файл находится

На мой взгляд для манагера это сложно. Проще иметь возможность выбрать файл из источника

Тем более что манагеру часто закрыт доступ напрямую в файловый менеджер
Prihod
28 марта 2024, 17:54
0
Подскажите в чем разница полей Файл изображения и Путь к файлу изображения?
Файл изображения — название файла с расширением
Путь к файлу — путь где файл находится

Не хватает функции копирования разделов и пунктов меню, полезно, когда нужно сделать несколько похожим меню
в новой версии добавлю
Сергей Карпович
28 марта 2024, 17:37
0
Не хватает функции копирования разделов и пунктов меню, полезно, когда нужно сделать несколько похожим меню
Сергей Карпович
28 марта 2024, 17:24
0
Подскажите в чем разница полей Файл изображения и Путь к файлу изображения?
Как менеджеру вставить в них картинку, как будто не хватает привязки источника файлов и кнопки выбора файла из этого источника
Скрин: Путь к файлу изображения: disk.yandex.ru/d/EHA36Ksv0vftIA

Также очень не удобно, что ресурс можно выбрать только из списка, ввод ID в ручную не сохраняется