Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Moodle

Глава 13 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: Moodle
Автор: Tim Hunt
Перевод: А.Панин

13.1. Обзор принципа работы приложения Moodle

Установка приложения Moodle состоит из трех составных частей:
  1. Код, обычно расположенный в такой директории, как /var/www/moodle или ~/htdocs/moodle. Доступ на запись в эту директорию не должен предоставляться веб-серверу.
  2. База данных, управляемая одной из поддерживаемых систем управления реляционными базами данных (relational database management system - RDMS). На самом деле, приложение Moodle добавляет префикс ко всем именам таблиц, поэтому оно может делить базу данных с другими приложениями в случае необходимости.
  3. Директория moodledata. Это директория, в которой приложение Moodle хранит загружаемые и генерируемые файлы, поэтому данная директория должна быть доступна для записи со стороны веб-сервера. В целях безопасности эта директория должна находиться вне корневой директории веб-сервера.

Все три части могут быть расположены на одном сервере. В качестве альтернативы при работе в окружении с системой балансировки нагрузки может использоваться множество копий кода, по одной на каждом из веб-серверов, но должна использоваться только одна разделяемая копия базы данных и одна директория moodledata, возможно на других серверах.

Конфигурационная информация для всех трех составных частей хранится в файле с названием config.php в корневой директории установки приложения Moodle с именем moodle.

Передача запросов

Moodle является веб-приложением, поэтому пользователи взаимодействуют с ним посредством своих веб-браузеров. С точки зрения приложения Moodle, процесс взаимодействия заключается в отправке ответов на HTTP-запросы. Следовательно, важным аспектом архитектуры Moodle является пространство имен URL и способ доставки данных URL различным сценариям.

Приложение Moodle в данном случае использует стандартный подход языка PHP. Строка URL для просмотра главной страницы курса будет иметь следующий вид: .../course/view.php?id=123, где 123 является уникальным идентификатором курса в базе данных. Строка URL для просмотра дискуссии форума будет выглядеть аналогично .../mod/forum/discuss.php?id=456789. То есть, эти сценарии course/view.php или mod/forum/discuss.php будут обрабатывать эти запросы.

Так проще для разработчика. Для понимания того, как приложение Moodle обрабатывает определенный запрос, следует рассмотреть строку URL и начать читать код в ней. Это неудачное решение с точки зрения пользователя. Эти строки URL, однако, постоянны. Строки URL не изменяются в случае переименования курса или в том случае, когда модератор перемещает дискуссию в другой форум. (Это свойство строк URL является полезным и описано в статье Tim Berners-Lee с названием "Cool URIs don't change".)

Альтернативным подходом, который может показаться полезным, является единая точка входа .../index.php/[дополнительная-информация-для-превращения-запроса-в-уникальный]. После этого отдельный сценарий index.php будет предавать запросы каким-либо образом. Этот подход добавляет уровень абстракции, что всегда любят делать разработчики программного обеспечения. Отсутствие этого уровня абстракции не кажется вредным для приложения Moodle.

Расширения

Как и множество успешных проектов с открытым исходным кодом, проект Moodle построен на основе большого количества работающих совместно с ядром системы расширений. Этот подход удачен, так как он позволяет пользователям изменять и расширять возможности приложения Moodle различными способами. Важным преимуществом системы с открытым исходным кодом является тот факт, что вы можете адаптировать ее к вашим определенным потребностям. Выполнение значительных изменений кода может, однако, привести к большим проблемам при наступлении времени обновления, даже в случае использования удобной системы контроля версий. Позволяя производить так много изменений и добавлять столько новых функций, сколько возможно при условии их реализации в рамках самостоятельных расширений, взаимодействующих с ядром приложения Moodle с помощью описанного API, можно облегчить задачу по изменению возможностей Moodle пользователями в соответствии с их потребностями, а также по распространению внесенных изменений, при этом сохраняя возможность обновления ядра системы Moodle.

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

Когда я я говорю о строго типизированных расширениях, я имею в виду то, что вам придется разрабатывать различные типы расширений и использовать различные API в зависимости от того, какой тип функций вы хотите реализовать. Например, новое расширение в виде модуля действий будет значительно отличаться от расширения аутентификации или нового расширения типа вопроса. (Существует полный список типов расширений приложения Moodle.) Этот подход противоположен используемому в архитектуре, где все расширения используют в основном один и тот же API а затем, возможно, соединяются с необходимым им подмножеством точек вызова функций или событий.

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

Расширение приложения Moodle представлено в форме директории, содержащей файлы. Расширение имеет тип и название, которые совместно формируют составное название расширения, известное, как "Frankenstyle". (Слово "Frankenstayle" появилось в ходе дискуссии на Jabber-канале разработчиков, при этом оно очень понравилось всем и его начали использовать.) Тип расширения и его название задают путь к директории расширения. Тип расширения задает префикс, а имя директории является названием расширения. Ниже приведено несколько примеров:

Тип расширения Название расширения Frankenstyle Директория
mod (модуль действия) forum mod_forum mod/forum
mod (модуль действия) quiz mod_quiz mod/quiz
block (блок боковой панели) navigation block_navigation blocks_navigation
qtype (тип вопроса) shortanswer qtype_shortanswer question/type/shortanswer
quiz (отчет о тестировании) statistics quiz_statistics mod/quiz/report/statistics

Последний пример иллюстрирует то, что каждый модуль действия может объявлять типы подмодулей. На данный момент только модули действий могут делать это по двум причинам. Если бы всем расширениям было позволено иметь подрасширения, могли бы возникнуть проблемы с производительностью. Модули действий реализуют основные обучающие возможности приложения Moodle и поэтому являются самым важным типом расширений, следовательно, они имеют особые привилегии.

Пример расширения

Я смогу объяснить множество подробностей реализации архитектуры приложения Moodle, рассмотрев пример специального расширения. По традиции я решил реализовать расширение, которое будет выводить фразу "Hello world".

Это расширение на самом деле полностью не соответствует ни одному из стандартных типов расширений приложения Moodle. Это просто сценарий, не связанный с чем-либо еще, поэтому я решил остановить свой выбор на реализации "локального" ("local") расширения. Этот тип расширения является обобщенным типом для реализации разнообразных функций, которые не могут быть корректно отнесены к какому-либо из-других типов. Я назову свое расширение greet для формирования названия Frankenstyle local_greet и пути к директории local/greet. (Исходный код расширения может быть загружен.)

Каждое расширение должно содержать файл с названием version.php, который содержит некоторые основные метаданные, относящиеся к расширению. Этот файл используется системой установки расширений приложения Moodle для установки и обновления расширения. Например, файл local/greet/version.php содержит строки:
<?php
$plugin->component    = 'local_greet';
$plugin->version      = 2011102900;
$plugin->requires     = 2011102700;
$plugin->maturity     = MATURITY_STABLE;

Включение названия компонента в файл может показаться избыточным, так как оно может быть извлечено из пути к директории, но установщик использует его для проверки того, что расширение установлено в предназначенном для него месте. Поле версии содержит версию расширения. Поле maturity содержит указание на альфа-версию (ALPHA), бета-версию (BETA), релиз-кандидат (RC, release candidate) или стабильную версию (STABLE). Поле requires указывает на минимальную версию приложения Moodle, с которой совместимо данное расширение. Если это необходимо, есть возможность указать другие расширения, от которых зависит данное расширение.

Ниже приведен код главного сценария для этого простого расширения (расположенный в файле local/greet/index.php):

Строка 1: Начальная загрузка приложения Moodle

require_once(dirname(__FILE__) . '/../../config.php');        // 1
Единственной строкой этого сценария, выполняющей большую часть работы, является первая строка. Выше я упоминал о том, что файл config.php содержит данные, которые требуются приложению Moodle для соединения с базой данных и поиска директории с данными приложения Moodle. Этот файл, однако, заканчивается строкой require_once('lib/setup.php'). При использовании этого файла:
  1. загружаются все стандартные библиотеки приложения Moodle с помощью функции require_once;
  2. инициируется запуск системы обработки сессий;
  3. осуществляется соединение с базой данных; и
  4. устанавливаются значения большого количества глобальных переменных, с которыми мы столкнемся позднее.

Строка 2: Установление факта входа пользователя в систему

require_login();                                              // 2

Эта строка вынуждает приложение Moodle проверить, осуществил ли текущий пользователь вход в систему, используя любое из расширений аутентификации, настроенных администратором. Если пользователь не осуществил вход, он будет перемещен на страницу с формой ввода данных для входа в систему и эта функция никогда не вернет управление.

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


Далее: Система ролей и разрешений приложения Moodle