Законы создания IT команд и следствия законов для IT проектов «на пальцах»
LMS Moodle с точки зрения программиста
1. с точки зрения программиста
12th Central and Eastern
European Software
Engineering Conference in
Russia – CEE-SECR 2016October 28-30, 2016
$meta = array(
‘author’ => ‘Igor Sazonov’
,’position’ => ‘programmer’
,’company’ => ‘LMSTech’
,’website’ => ‘https://lmstech.ru’
,’city’ => ‘St. Petersburg’
);
https://www.facebook.com/groups/elearning.spb/
2. с точки зрения программистаOctober 28-30, 2016
Как всегда – Introduction
Moodle — система управления курсами (электронное обучение), также
известная как система управления обучением или виртуальная
обучающая среда (англ.). Является аббревиатурой от англ. Modular
Object-Oriented Dynamic Learning Environment (модульная
объектно-ориентированная динамическая обучающая среда).
Представляет собой свободное (распространяющееся по лицензии
GNU GPL) веб-приложение, предоставляющее возможность создавать
сайты для онлайн-обучения.
3. с точки зрения программистаOctober 28-30, 2016
Как всегда – Introduction
Официальный сайт https://moodle.org/
Год основания 2003
Текущая версия 3.1.2 (28.10.2016)
Язык программирования PHP
База данных Реляционная: MySQL, PostgreSQL, MSSQL, Oracle
Основатель Martin Dougiamas
Лицензия GNU GPL v2
4. с точки зрения программистаOctober 28-30, 2016
Забегая вперед…
Какие навыки нужны Moodle-разработчику
Владение ООП PHP
Хорошее владение SQL
Умение тестировать код
Терпение
5. с точки зрения программистаOctober 28-30, 2016
Архитектура. Абстракция
Классическая трехслойная архитектура
Model (DB)-Library-View (index.php)
6. с точки зрения программистаOctober 28-30, 2016
Архитектура. Абстракция
moodledata – папка для хранения динамических файлов Moodle
(картинки, кеши, загруженные файлы итп)
Разработчик вправе строить свои слои,
подключать свои библиотеки, г*вн*кодить итд.
Нет строгой
архитектуры
зависимостей и связок
* разработчик только изучивший PHP * профессиональный (ленивый) разработчик
7. с точки зрения программистаOctober 28-30, 2016
Архитектура. Модули в ядре
М – модульность
Все кроме шаблонов (тем) и админки в ядре
Moodle – это модули
• Moodle – это главный модуль
• Тест – модуль
• Авторизация – модуль
• Блок с информацией – модуль
• Отчеты – модуль
• итд
* модули в папке /mod – это часть модулей, просто они официально называются «Модули»
8. с точки зрения программистаOctober 28-30, 2016
Архитектура. Типы модулей
Дополнительные модули (плагины) делятся по типам (модульность). Каждый тип модуля имеет
свою папку «точку входа» (могут отличаться) и набор обязательных файлов и папок
https://docs.moodle.org/dev/Plugin_types
* входная точка модуля – (как правило) конструктор класса, имеющего родительский класс
9. с точки зрения программистаOctober 28-30, 2016
Дополнительные модули
Алгоритм разработки дополнительного модуля (плагина)
Выбор типа плагина согласно задаче
Продумывание архитектуры кода (опционально – только для больших плагинов), изучение
базового класса
Заполнение базовой (необходимой) структуры модуля (version.php, lang/en, «точка входа»),
наименования
Заход в «точку входа»
Программирование
for ($i=1;$i<={уверенность в качестве кода и отладке};$i++) {
Тестирование
Отладка
}
«Причесывание» кода
Production
10. с точки зрения программистаOctober 28-30, 2016
Дополнительные модули. Пример. Блок (Block) feedback
/blocks/feedback/db
/blocks/feedback
/blocks/feedback/lang/en
11. с точки зрения программистаOctober 28-30, 2016
Дополнительные модули. Пример. Блок (Block) feedback. Код
Документация: https://docs.moodle.org/dev/Blocks
version.php (обязательный файл)
$plugin->version = 2016022800;
$plugin->requires = 2013111805; // Requires Moodle 2.6.5 or later
$plugin->cron = 1; //optional
$plugin->release = '1.0.0 (Build: 2016022800)'; //optional
$plugin->maturity = MATURITY_STABLE; //optional
$plugin->component = ‘block_feedback';
12. с точки зрения программистаOctober 28-30, 2016
Дополнительные модули. Пример. Блок (Block) feedback. Код
Документация: https://docs.moodle.org/dev/Blocks
db/install.php (необязательно)
function xmldb_block_feedback_install() {
//your magic
}
db/uninstall.php (необязательно)
function xmldb_block_feedback_uninstall() {
//your magic
}
Подробнее: https://docs.moodle.org/dev/Upgrade_API#Other_things_that_can_be_in_the_db_folder
13. с точки зрения программистаOctober 28-30, 2016
Дополнительные модули. Пример. Блок (Block) feedback.
Локализация
lang/en/block_feedback.php (обязательно хотя бы en)
$string['pluginname'] = 'Feedback';
$string[‘feedback_title'] = 'Feedback block title';
* совет: если хотите переводить плагин, не переводите на другие языки, пока полностью не закончите
разработку и отладку
Документация: https://docs.moodle.org/dev/Blocks
14. с точки зрения программистаOctober 28-30, 2016
Дополнительные модули. Пример. Блок (Block) feedback.
Локализация
block_feedback.php («входная» точка, обязательно для блоков)
class block_feedback extends block_list { //родительский класс block_base или block_list
public function init() {
$this->title = get_string(‘feedback_title’, ‘block_feedback’); //заголовок
}
public function get_content() {
$this->content = ‘I am block!’;
return $this->content;
}
}
Документация: https://docs.moodle.org/dev/Blocks
15. с точки зрения программистаOctober 28-30, 2016
Подведем итог по дополнительным модулям и архитектуре
Недостатки
Нет единой архитектуры разных модулей. «Входные точки» могут
отличаться принципиально
Модули очень сильно изолированы в рамках своих задач
Нет «перехватчиков» данных или «крючков» (аналогия с add_filter()
и add_action() в WordPress)
Нет первоначальной автозагрузки
Много проблем с обслуживанием локализации
16. с точки зрения программистаOctober 28-30, 2016
Подведем итог по дополнительным модулям и архитектуре
Преимущества
Единая архитектура обязательных файлов и логики в
них
ООП (в рамках модуля)
Много примеров в core-модулях
17. с точки зрения программистаOctober 28-30, 2016
База данных
Поддерживаемые драйверы MySQL, PostgreSQL, MSSQL, Oracle
Количество таблиц БД в ядре ~320
Количество активно используемых таблиц 20- 40
Документация по Data API https://docs.moodle.org/dev/Data_manipulatio
n_API
18. с точки зрения программистаOctober 28-30, 2016
База данных. Moodle Data API
Глобальный объект $DB
Документация: https://docs.moodle.org/dev/Data_manipulation_API
global $DB; //подгружаем объект
Получение единственной записи. Будет возвращен ОБЪЕКТ типа stdClass! Префикс от таблицы Moodle не нужен!
$user = $DB->get_record('user', array('firstname'=>'Martin',
'lastname'=>'Dougiamas')); //выборка по полям из одной таблицы mdl_user
$user = $DB->get_record_sql('SELECT * FROM {user} WHERE id =
?', array(1)); //выборка по нативному SQL-запросу
19. с точки зрения программистаOctober 28-30, 2016
База данных. Moodle Data API
Глобальный объект $DB
Документация: https://docs.moodle.org/dev/Data_manipulation_API
Получение нескольких записей. Будет возвращен массив ОБЪЕКТов типа stdClass!
get_records($table, array $conditions=null, $sort='',
$fields='*', $limitfrom=0, $limitnum=0)
get_records_sql($sql, array $params=null, $limitfrom=0,
$limitnum=0)
20. с точки зрения программистаOctober 28-30, 2016
База данных. Moodle Data API
Глобальный объект $DB
Документация: https://docs.moodle.org/dev/Data_manipulation_API
global $DB;
Получение единственной записи. Будет возвращен ОБЪЕКТ типа stdClass! Префикс от таблицы Moodle не нужен!
$user = $DB->get_record('user', array('firstname'=>'Martin',
'lastname'=>'Dougiamas')); //выборка по полям из одной таблицы mdl_user
$user = $DB->get_record_sql('SELECT * FROM {user} WHERE id =
?', array(1)); //выборка по нативному SQL-запросу
21. с точки зрения программистаOctober 28-30, 2016
База данных. Moodle Data API
Глобальный объект $DB
Документация: https://docs.moodle.org/dev/Data_manipulation_API
Получение нескольких записей. Будет возвращен массив ОБЪЕКТов типа stdClass!
get_records($table, array $conditions=null, $sort='',
$fields='*', $limitfrom=0, $limitnum=0)
get_records_sql($sql, array $params=null, $limitfrom=0,
$limitnum=0)
22. с точки зрения программистаOctober 28-30, 2016
База данных. Moodle Data API. Тонкости
Советы, тонкости, кейсы
Если Вы используете нативные запросы (а Вы из будете использовать =), тестируйте их еще
хотя бы на одном драйвере, например MySQL + PostgreSQL
ВАЖНО. При выборке нескольких записей (из нескольких таблиц с помощью JOIN) и
нативном запросе (например методом get_records_sql) возвращается массив с ключами
первого поля выборки, поэтому необходимо обеспечить уникальность первого ключа и явно
указывать нужные поля выборки (вместо SELECT *)
При insert-запросах пользоваться транзакциями
Слабая поддержка большого количества insert-запросов (настройка MySQL не помогает,
отрабатывает не более 50 insert-запросов в цикле)
$DB->insert_record($table, $dataobject, $returnid=true, $bulk=false)
$bulk не участвует в жизни метода (MySQL)
Документация: https://docs.moodle.org/dev/Data_manipulation_API
23. с точки зрения программистаOctober 28-30, 2016
Локализация. String API
Обязательная папка lang в модуле содержит подпапки локализаций
/lang
/en – английский язык
/ru – русский язык
/es – испанский язык
итд, список всех кодов:
https://github.com/moodle/moodle/blob/master/lang/en/countries.php
Документация: https://docs.moodle.org/dev/String_API
Совет. Только после полного завершения
работ по модулю приступайте к полной
локализации
24. с точки зрения программистаOctober 28-30, 2016
Локализация. String API
Внутри папок – php-файл локализации (массив $string) с названием модуля,
например block_feedback.php
$string[‘denegnet’] = ‘Вы держитесь! Хорошего настроения!’;
//в коде
echo get_string(‘denegnet’, ‘block_feedback’) === print_string(‘denegnet’,
‘block_feedback’)
Документация: https://docs.moodle.org/dev/String_API
25. с точки зрения программистаOctober 28-30, 2016
Объект $CFG
Объект $CFG содержит в себе конфигурационные данные и
данные из БД
Вызов: global $CFG;
HTTP(s) адрес текущего Moodle: $CFG->wwwroot
Серверный адрес текущего Moodle: $CFG->dirroot
Серверный адрес к папке moodledata: $CFG->dataroot
Полный список ключей и значений объекта: print_r($CFG);
26. с точки зрения программистаOctober 28-30, 2016
FrontEnd (JavaScript)
Базовый JS-фреймворк – YUI (Yahoo User Interface). http://yuilibrary.com/ RIP since 2014.
Документация - https://docs.moodle.org/dev/YUI
С версии 2.9 (май 2015) в Moodle внедрена поддержка jQuery из ядра, НО! через AMD-
модули, подключаемые через RequireJS: http://requirejs.org/. Все подключаемые из вне
скрипты/библиотеки должны поддерживать AMD. Поддержка в Moodle – папка amd с
подпапками build (production) и src (development)
require(['jquery', ‘block_feedback/timer'], function(jQuery, timer) {…});
Документация: https://docs.moodle.org/dev/Javascript_Modules
Доступ к информационным объектам через javascript-переменную-объект M, например к
данным из $CFG данные можно получить через строку M.cfg.wwwroot
27. с точки зрения программистаOctober 28-30, 2016
Безопасность
Защищаем входные данные от XSS-атак
Функция clean_param($param, $type). $param – входные данные, $type – ожидаемый
тип данных
Возможные типы данных: http://xref-diff.mukudu-
dev.net/moodle26/lib/moodlelib.php.source.html#l765
Совет. Если не знаете точно ожидаемый тип данных – используйте PARAM_CLEAN
Проверка Session Key. В сессию записывается хешированная строка в зависимости от ID
текущего пользователя
confirm_sesskey( $sesskey = NULL ) – проверка $sesskey из параметра или из
$_POST[‘sesskey’]
require_sesskey() – блокирует все вызовы, если confirm_sesskey() выдала false
В javascript – M.cfg.sesskey
Система контекстов - https://docs.moodle.org/dev/Access_APIс