Дисклеймер: система дистанционного обучения (СДО) в настоящее время введена в эксплуатацию (продакшн), апробирована, протестирована и успешно работает. Система бесплатна, имеет открытый исходный код и выложена в репозитории GitHub. С точки зрения стека технологий она построена на фреймворке Laravel 8.0 (PHP 7.4) с использованием библиотек и иных пакетов (программ): React (redux+router), SocketIo, Docker, NodeJs, Rest API, WebRTC, Leaflet и т.д.

В серии статей я расскажу, как устроена система, через что пришлось пройти при ее разработке и какие проблемы пришлось решать.

К уникальным особенностям системы можно отнести:

  1. Внутренний антиплагиат. В процессе проведения занятий мы столкнулись с проблемой копирования студентами решений заданий друг у друга. В ручном режиме достаточно сложно отслеживать степень совпадения решений, в связи с чем разработана система, показывающая процент «похожести» ответов.

  2. Выявление технических методов повышения уникальности текста. Для повышения эффективности проверки работ и обнаружения попыток использования различных методов повышения уникальности разработана система выявления признаков подозрительного вмешательства в текст.

  3. Помимо стандартных алгоритмов проверки (тесты, проверка документов, чаты и т.д.) были реализованы:

    a.      Квест. Визуальный конструктор квестов позволяет реализовать практически любые виды заданий в виде игры.

    b.     Диалоговая система. В режиме конструктора создается дерево вопросов и ответов, которые позволяют нелинейно решать отдельные задачи (беседа, допрос, алгоритм действий и т.д.)

    c.      Портфолио. Для учета дополнительной работы созданы дополнительные категории оценки (наука, творчество, макет, иное).

  4. Анализ текста ответов. Автоматическая проверка текстов и процессуальных документов позволяет экономить время преподавателя и выявлять некачественные ответы.

  5. Внутренняя самопроверка. Пользователи могут сами создавать задания и перекрестно проверять задания друг друга. Собственный алгоритм сопоставления решений студентов с целью исключения повторов (дублирования) ответов. Можно назвать это собственным внутренним антиплагиатом.

  6. Виртуальная доска. Для демонстрации документов, презентаций, текста и фотографий всем участникам, а также для проведения блиц-опроса по теме была создана доска, позволяющая организатору в онлайн режиме видеть и автоматически проверять ответы на задания, а также разрешать/запрещать видимость правильность ответа пользователями, видимость ответа других участников.

  7. Онлайн поддержка. Мониторинг открытых пользователями страниц в режиме реального времени позволяет осуществлять более эффективную поддержку.

  8. GPS. Для реализации творческих идей создана интерактивная карта, на которой отмечаются пользователи в режиме реального времени и их перемещение на местности.

  9. Видеосвязь. Для дистанционного взаимодействия используется система видеосвязи, позволяющая демонстрировать звук и изображение с web-камеры, либо экран организатора.

  10. Telegram Bot. Бот в телеграме автоматически уведомит о поступивших сообщениях.

Предыстория

Имея высшее юридическое образование и проработав несколько лет практикующим специалистом жизнь сложилась так, что я стал работать преподавателем в образовательной организации на кафедре юридического профиля. О собственной системе дистанционного обучения ранее задумываться не приходилось – вполне хватало времени на очных занятиях. Однако, по прошествии времени (около 5 лет) оказалось, что знаний, которые бы хотелось передавать обучающимся гораздо больше, чем позволяет это сделать учебный план.

Пришло понимание, что необходимо давать больший объем заданий на самоподготовку, а проверять возросший объем работы было сложнее, поэтому было принято решение автоматизировать процесс проверки решений с использованием web технологий. Поискав в Интернете готовые решения, я остановился на тестировании, реализованном на JavaScript. Я купил домен и хостинг и загрузил html страницы с тестами, прописанными в самом коде. Информация о решенных заданиях отправлялась с помощью встроенной функции mail PHP приходила на адрес email. Насколько я помню и как это ни странно это работало и письма приходили. Страниц оказалось много и было неудобно редактировать тесты, создавать новые, а настоящий кошмар наступал, когда приходилось что-то поменять в функционале страниц (добавить меню, информацию). Отчасти решая эти проблемы путем использования include, быстро пришло понимание, что я изобретаю велосипед и наверняка уже есть что-то готовое.

Обзор существующих и наиболее распространённых CMS типа WordPress и Joomla показал, что они решают немного иные задачи и из коробки не имеют нужного мне функционала. Установка нужных плагинов, пакетов и расширений в тот момент казалась невыполнимой задачей с точки зрения понимания работы этого всего в комплексе и расширения собственного функционала.

От установки и использования Moodle также отказался по причине сложности в понимании на тот момент ее установки, использования и громоздкости, даже готовые виртуальные машины не рассматривались. Хотелось сделать что-то своё, чтобы оно работало быстро с полным пониманием принципов работы и дальнейшего совершенствования.

Было принято решение создавать свою систему с нуля. Первая версия системы была написана на PHP и JQuery с использованием интерфейса MySql для доступа к базе данных, весь материал был найден на просторах интернета и путем копирования кода по фрагментам была сделана система, позволяющая уже хоть как-то ее поддерживать и расширять функционал.

Недостатки такого похода были обнаружены довольно быстро, начинания от простейших SQL инъекций типа “1=1”, которые были использованы для удаления базы и пришедшем осознании, что работа с процедурным кодом таит в себе множество проблем в виде плохой поддержки, запутанности и дублирования кода.

Решив, что надо изучить современные паттерны и шаблоны проектирования, остановился на задаче создания собственной CMS с использованием шаблона проектирования MVC и ООП. Маршрутизация была сделана очень примитивно: обрабатывался URI адрес с использованием регулярных выражений, вручную (собственным autoload) вызывался соответствующий класс контроллера, который в свою очередь вызывал классы настроек, модели и шаблона. Система стала более структурированной и современной. Стал использоваться интерфейс PDO для доступа к MySql. Класс каждой модели наследовался от базового класса, который в конструкторе подключался к базе и использованием шаблона singleton и возвращал сведения в ассоциативном массиве (флаг \PDO::FETCH_ASSOC). В базовом классе были созданы методы, отдаленно напоминающие попытку реализации собственной ORM в виде CRUD. Структура самой базы была очень непродуманной: в таблице tasks (задания) хранилась избыточная информация о теме, самом задании, авторе и т.д.

Запросы к базе выглядели довольно плохо. Пример запроса на выбор решений:

$decisions = $model->findBySql("SELECT *, d.id as did, t.login as tlogin, d.login as login  FROM decisions as d, tasks as t WHERE ((d.id_task = 0 and t.number_razdel = d.number_razdel and t.number_task = d.number_task) or (t.id=d.id_task)) and t." . $route['discipline'] . " = 1 and d.login IN ('" . implode("','", $arr_users) . "')", []);

$decisions = $model->findBySql("SELECT *, d.id as did, t.login as tlogin, d.login as login  FROM decisions as d, tasks as t WHERE ((d.id_task = 0 and t.number_razdel = d.number_razdel and t.number_task = d.number_task) or (t.id=d.id_task)) and t." . $route['discipline'] . " = 1 and d.login IN ('" . implode("','", $arr_users) . "')", []);

Дальнейшем совершенствованием системы стало внедрение composer, создание продвинутого автолоадера и пространства имен. Также был осуществлен переход на PhpStorm (преподавательская лицензия) и OpenServer.

Активно развивался и frontend. Изначально вся логика построения html строилась c использованием в качестве шаблонизатора самого PHP, лишь в отдельных частях кода использовался jQuery для анимации и визуальных эффектов. Позднее были подключены сторонние библиотеки TinyMCE (визуальный редактор для редактирования контента), ResponsiveFilemanager (для работы с файловой системой), Bootstrap. Функционал работы системы осуществлялся с помощью классических POST и GET запросов с параметрами (никаких систем шифрования, токенов не использовалось), впоследствии я пришел к повсеместному внедрению ajax, fetch, axios, но это было позже.

В связи с желанием создать свою систему диалогов и обучающих квестов как видов заданий я пришел к пониманию, что PHP не подходит для эффективного решения такого рода задач и стал искать готовые решения для реализации задумок. Самым простым мне показалось решение перевода презентации pptx (Microsoft Office), слайды которой имеют перекрестные гиперссылки друг на друга в web режим. Для целей перевода презентации в html документ использовалось программное решение ISpring, которое в принципе со своей задачей справлялось. Выходной документ представлял из себя html страницу с подключенными скриптами JavaScript, отвечающими за функционал. Файл запускался в iFrame основного сайта и позволял проходить квесты (о них более подробно далее), но возникла сложность внесения изменений в файл скриптов js – они для меня были непонятны от слова «вообще», так как код был минимизирован. Также не совсем было понятно, как послать сигнал основному window, что квест пройден. Решение на тот момент было таким: финальный слайд квеста, загруженного в iFrame содержал ключевое слово, а весь документ раз в 1 секунду анализировался с помощью JS и в случае совпадения заполнял соответствующие поля формы.

Довольно быстро я от этой идеи отказался, в первую очередь, по указанной выше причине, а также по причине сложности создания проектов другими пользователями, необходимости повторного преобразования презентации в квест при малейших исправлениях, отсутствии нормальной обратной связи с iframe через основное окно и т.д.

Решив, что JavaScript в технологиях дистанционного обучения это «наше всё», я начал экспериментировать с возможностями JS в плане интерактивности реализации single page application SPA на 1 странице сайта. Пришлось разбираться со структурами данных в JS (в первую очередь, потому что мне понравилась коллекция MAP), прототипы, промисы, анонимные и асинхронные функции, контексты вызова, замыкания, колбэки, изучать особенности ECMAScript 6 с его деструктуризацией (на самом деле очень удобно), новые типы переменных (let, const) и т.д.

В итоге получилась, как мне казалось, неплохое приложение, которое подключалось include на страницу сайта и даже работало как мне надо. Скриншоты первой версии прилагаю. Несомненным плюсом являлась возможность не использовать сборщики типа Webpack, а простое редактирование кода прямо на сервере.

В тот момент я практически не использовал библиотеки npm или composer, поэтому писал код как дома, так и на работе, а обменивался файлами с использованием YandexDisk. Никакого дискомфорта это не доставляло. Знал, что есть гит, но не знал зачем он мне.

К проблемам работы SPA приложения без использования библиотек можно отнести загроможденность DOM дерева, так как все данные хранились в data-атрибутах, сложность читаемости кода, в базе данных все хранилось в сериализованном JSON формате, множество промисов, реализованных в async await функциях, которые не всегда работали как мне было надо, практически полностью отсутствовал механизм обработки ошибок и исключений. Но все вроде работало и задачи выполняло.

Конец 1 части.

Планируются публикации (указанное ниже работает в действующей системе):

Часть 2. Создание аналога Moodle. Реализация API для прототипа SPA. Межсайтовые запросы. Первые проблемы архитектуры

Часть 3. Выявление технических методов повышения уникальности текста с помощью PHP (в рамках создания собственной СДО)

Часть 4. Выбор фреймворка и переход на Laravel в рамках создания собственной СДО

Часть 5. Переход на ReactJs, внедрение flux, SOLID и интеграция в Laravel.

Часть 6. Внедрение нейронных сетей в работу СДО.

Комментарии (11)


  1. habrjeka
    22.11.2021 11:12
    +2

    Юрист, преподаватель, который разобрался в PHP, React, Docker, GitHub, OSM, нейронках, парсингах ... Да Вы молодец!


  1. kiloper
    22.11.2021 11:14
    +1

    Главный вопрос зачем? Из-за того, что не было понимания как работает Moodle?

    Не быстрее ли было приобрести эти понимания чем изобретать велосипед. Код Moodle очень расширяем, система раз в неделю обновляется, там большой уклон сделан на bigdata

    Я всегда поддерживаю начинания, не обижайтесь, но дизайн аля 90е.

    Если хотите получить фидбеки сделайте контейнер для быстрого развертывания вашего СДО и аппробации.


    1. pavel_smagin Автор
      22.11.2021 11:18

      Спасибо за вопрос. Да, Moodle в настоящее время достаточно сильно преобразился, однако, как отмечалось ранее, он не решает всех необходимых задач, а установка плагинов и расширений позволит все задуманное реализовать. К примеру, нет в Moodle конструктора квестов, а такая возможность была мне необходима.

      В планах есть контейнеризация.


      1. kiloper
        22.11.2021 11:20

        Все что вы описали делается путем плагинов, вы рассматриваете Moodle как СДО

        Я же говорю использовать Moodle как фреймворк для написания своего СДО


      1. kiloper
        22.11.2021 11:31

        Напишите пожалуйста мне в телеграмм kiloper

        https://t.me/kiloper


    1. Crocodylus
      22.11.2021 12:18

      Если готовое решение нуждается в сильной кастомизации - часто проще реализовать альтернативное, "с полным пониманием принципов работы и дальнейшего совершенствования". Глубокую кастомизацию сложно обновлять и сложно поддерживать. А вопрос дизайна "аля 90е" как раз самый легкорешаемый вопрос, но судя по тому, что решение уже применяется в продакшене, особых проблем с дизайном у пользователей нет.


      1. pavel_smagin Автор
        22.11.2021 12:58

        Да, решалось несколько задач:

        - создание системы для удовлетворения своих, иногда весьма специфических, потребностей;

        - изучение мира Web разработки (признаться, получил много удовольствия от создания собственных работающих функций);

        - удобная масштабируемость системы на популярных библиотеках и фреймворках.


  1. Marcucci
    22.11.2021 11:14

    Павел, спасибо за интересную статью. Замечу, что, что готовящийся релиз moodle 4 обещает снять ряд проблем, которые Вы затронули, в том числе громозкость. Да, как любое универсальное решение оно стало эдаким "бегемотом"; но по опыту 5 лет сопровождения этого решения для одного из ВУЗов задачи СДО и автоматизации проверок решает неплохо. И после часового инструктажа в этом инструменте разбираются даже, условно, "девочки-гуманитарии". Но этому предшествует большая работа по конфигурированию moodle.
    С нетерпением жду информации о применении нейросетей, интересно, какие задачи Вы ими решали.


  1. boronnikov
    22.11.2021 15:44

    Спасибо за статью, понимаю вашу мотивацию сделать свою LMS.
    В Moodle действительно много всего и сходу сложно разобраться. По опыту чаще сталкиваются с тем, что функционала сильно больше, чем нужно. Но бывают и исключения. По квестам есть интересное решение через вставку в курс H5P содержимого. В частности можно видео-ролик сделать интерактивным, с паузами и опросами о материалу. И в зависимости от ответа дальше могут быть различные сценарии, в том числе, конечно, и с продолжением просмотра.

    Но очень интересно будет проследить за вашей разработкой.


  1. domix32
    23.11.2021 11:05

    А ссылка на гитхаб будет?


    1. pavel_smagin Автор
      23.11.2021 11:41

      Да, ссылку дам немного позднее.