Всего 123 792 комментария

Валерий
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 в ручную не сохраняется
Кровельный
28 марта 2024, 16:49
0
Добрый день, прикрутите возможность поиска товаров по ТВ/значению
Роман
28 марта 2024, 13:32
0
Может можно реализовать как-то через «цепочки» внутри самого easyComm…
Дмитрий
28 марта 2024, 11:20
0
Добрый день!
Скачал ваш модуль YandexMarket2 все нравиться вроде, но есть минус и как его исправить у меня картинки выходит через TV.image выбираешь
favoritceramica.ru/uploads/gallery/
а должен путь полный
favoritceramica.ru/image/uploads/gallery/
Как это добавить!?

И не где на форумах и сайтах нету информации кто столкнулся с такой проблемой!
Дмитрий
28 марта 2024, 11:13
0
Добрый день!
Скачал ваш модуль YandexMarket2 все нравиться вроде, но есть минус и как его исправить у меня картинки выходит через TV.image выбираешь
favoritceramica.ru/uploads/gallery/
а должен путь полный
favoritceramica.ru/image/uploads/
Как это добавить!?

И не где на форумах и сайтах нету информации кто столкнулся с такой проблемой!
Артур Шевченко
28 марта 2024, 10:19
+1
Потому что phpthumb обновили и он не работает с php 7.4. Эту тему много и часто обсуждали. В телеге в группе закреп есть с решением.
Вячеслав Варов
28 марта 2024, 09:42
0
Просто сейчас почему-то после переезда на 7.4 отлетели картинки в панели управления, вместо картинок вижу 500 ошибку
/connectors/system/phpthumb.php?w=400&h=400&aoe=0&far=0&f=png&src=products/uzcard_unionpay.jpg&source=3&version=41a17f4b
В файломов менеджере тоже превью не загружаются
Артур Шевченко
28 марта 2024, 09:40
0
Это может быть связано с тем, что компоненты для второй версии modx никогда не писались под php 8.x
Вячеслав Варов
28 марта 2024, 09:27
0
На php 7.4 запустилось, но хотелось бы разобраться и запустить на 8 версии
alex.shabun
27 марта 2024, 22:38
0
Если используете сниппет для отправки формы без перезагрузки страницы, то js компонента FetchIt вставляет текст ошибок внутри тега с атрибутом data-error:
<input id="c-name" type="text" name="name" value="">
<span data-error="name"></span>
если я отправлю форму с незаполненным обязательным полем, то код на странице станет таким:
<input class="is-invalid" id="c-name" type="text" name="name" value="" aria-invalid="true">
<span data-error="name">
    <span class="error">Это поле обязательно для заполнения.</span>
</span>
Если нужно что-либо самому сделать, то поможет инфа из раздела JS API. В частности FetchIt.Message
Артур Шевченко
27 марта 2024, 22:01
0
Если посмотреть за последние годы, сколько здесь было заметок о дополнениях, которые сделали не наши ребята?
Это сайт русскоязычноого сообщества, тут просто нет забугорных пользователей)) А так-то у них, наверное, тоже есть те, кто пишут допы.