Разработка:Стандарт кодирования — различия между версиями
Yumeneco (обсуждение | вклад) |
Konovalov (обсуждение | вклад) (→Использование JavaScript) |
||
(не показано 70 промежуточных версий 7 участников) | |||
Строка 1: | Строка 1: | ||
== Правила оформления кода в проекте «Электронный деканат». == | == Правила оформления кода в проекте «Электронный деканат». == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | === Стиль кодирования === | |
+ | ==== Формат файлов ==== | ||
+ | # Все файлы с кодом должны иметь расширение .php | ||
+ | # Все html-шаблоны должны иметь расширение .html | ||
+ | # Весь текст, включая исходный код, должен быть в кодировке utf-8 с оконачаниями строк в формет Unix | ||
+ | # Окончания строк в формате Unix (LF - 0x0A) | ||
+ | # Все php-теги должны быть полными <?php ... ?>. Краткие теки <? ?> не допускаются | ||
+ | # Все отступы – 4 пробела. Не использовать TAB. | ||
+ | # Длинна строки в коде не должна быть больше 80 символов. В некоторых случаях допускается 120, если это упростит читаемость кода. | ||
+ | # Пробелы можно использовать свободно. Не надо бояться растягивать код для улучшения читабельности. | ||
+ | ==== Имена ==== | ||
+ | # Имена файлов должны состоять только из латинских символов, знака подчеркивания и точки. Имя файла обязательно должно иметь расширение. Рекомендуется использовать для именования файлов слова на английском языке. | ||
+ | # Имена классов должны состоять из строчных латинских символов и знака подчеркивания. Рекомендуется использовать английские слова разделенных символом подчеркивания. Имя класса в плагине должно начинаться с префикса, соответствующего плагину. Если требуется, имя класса может включать преффикс и суффикс. | ||
+ | # Имена функций и методов должны состоять из строчных латинских символов и знака подчеркивания. Имя функции в плагине должно начинаться с префикса, соответствующего имени модуля (dof_) и плагину, в котором объявлена (типплагина_кодплагина). Затем идет часть имени, описывающая выполняемое действие. Последняя часть - это существительное, обозначающее сущность, над которой это действие производится либо набор сущностей. Не должно быть пробелов между именем функции и скобками. Это относится и к объявлению функции, и к ее использованию. Параметры всегда должны иметь разумные значения по умолчанию, если это возможно. Пример: modname_get_string($identifier, $pluginname = NULL). Между ключевым словом function и именем функции должен быть только один пробел. | ||
+ | # Имена параметров функций именуются по тем же правилам, что и переменные. Имя параметра должно быть кратким и информативным для сторонних программистов. Если параметр может быть не задан, используйте по умолчанию значение null, для отличия этой ситуации от передачи параметра false, 0 или '' если это требуется). | ||
+ | # Имена переменных - всегда легкие для чтения осмысленные слова английского языка, набранные в нижнем регистре. Несколько слов пишутся слитно. Но они должны быть как можно короче. Используйте имена во множественном числе для массивов объектов. Например: $courseid, $studentsgrades | ||
+ | # Имена глобальных переменных, должны состоять полностью из заглавных букв. Пример: $CFG | ||
+ | # Имена констант должны состоять из латинских символов в верхнем регистре и знака подчеркивания. Всегда начинаются с имени модуля (DOF). Если константа объявлена в плагине, она получает дополнительный префикс ТИППЛАГИНА_КОДПЛАГИНА. Слова в названии разделены символом подчеркивания. Пример: SITE_ID | ||
+ | # true, false и null должны быть набраны в нижнем регистре | ||
+ | # AND, OR, XOR должны быть набраны в верхнем регистре, не используйте сокращенные синонимы. | ||
+ | ==== Строки ==== | ||
+ | # Используйте одинарные кавычки, если в строке отсутствуют макроподстановки и эскейп-последовательности, а так же если в строке присутствует много двойных кавычек. | ||
+ | # При макроподстановках в двойных кавычках заключайте переменные в фигурные скобки. | ||
+ | # Объединение строк выполняется через оператор "точка" (.) | ||
+ | ==== Массивы ==== | ||
+ | # Не используйте отрицательных чисел для нумерации массивов (кроме случаев, когда это прямо требуется логикой программы). | ||
+ | # Индексация массива может начинаться с любого положительного числа, обычно с 0. | ||
+ | # При объявлении массива через функцию array() ставьте пробел после запятой при перечислении параметров. Длинные объявления можно переносить по строкам. При объявлении ассоциативных массивов помещайте на одну строку одну пару ключ-значение. | ||
+ | ==== Классы ==== | ||
+ | # Свойства класса должны объявляться до его методов. | ||
+ | # Фигурная скобка пишется на следующей строчке после объявления имени класса, на одном уровне с ключевым словом class. | ||
+ | # Объявление любого класса должно быть документировано по стандарту PHPDocumentor | ||
+ | # Весь код внутри класса должен быть сдвинут на 4 пробела от уровня его объявления. | ||
+ | # Объявление класса должно быть отделено от остального коду двумя пустыми строками. | ||
+ | # Свойства класса должны объявляться напрямую при объявлении класса с указанием модификатора доступа (private (доступ извне запрещен), protected (разрешен доступ из наследников) или public) | ||
+ | ==== Функции и методы ==== | ||
+ | # Объявление функций и методов должно сопровождаться комментарием по стандарту PHPDocumentor | ||
+ | # Все объявления методов должны содержать модификатор доступа (private (доступ извне запрещен), protected (разрешен доступ из наследников) или public) | ||
+ | # Фигурная скобка должна располагаться на следующей строке после объявления имени функции или метода на одном с ним уровнем. | ||
+ | # Тело функции должно быть сдвинуто на 4 пробела вправо. | ||
+ | # Между именем функции и круглой скобкой не должно быть пробела. | ||
+ | # Если функция не возвращает значений, то true обозначает успех, false - не успех. Если функция возвращает массив, в случае успешного выполнения, но отсутствия элементов в результате, функция должна возвращать пустой массив. | ||
− | ···· $c = $a; | + | ==== Управляющие конструкции ==== |
+ | Ставьте один пробел между скобками и синтаксическими конструкциями. Это не относится к функциям и их параметрам. Пример: | ||
+ | <code php> | ||
+ | if ( $a >= max($key) ) | ||
+ | { | ||
+ | |||
+ | ···· $c = $a; | ||
+ | |||
+ | } | ||
+ | </code> | ||
− | + | Блоки всегда ограничиваются фигурными скобками. При этом используется [http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B8%D0%BB%D1%8C_%D0%BE%D1%82%D1%81%D1%82%D1%83%D0%BF%D0%BE%D0%B2#.D0.A1.D1.82.D0.B8.D0.BB.D1.8C_.D0.9E.D0.BB.D0.BC.D0.B0.D0.BD.D0.B0 стиль Олмана]: | |
− | + | <code php> | |
− | + | if (<cond>) | |
− | + | { | |
− | Блоки всегда ограничиваются фигурными скобками. При этом используется стиль Олмана: | + | ····<body> |
+ | } | ||
+ | </code> | ||
− | + | ==== Комментарии и документация ==== | |
+ | # Комментарии должны быть подробными и содержательными. Объяснять каждое объявление классов, функций и переменных. Каждый цикл и каждая ветвь условия должны быть пояснены содержательным смыслом выполняемых действий, например: "перебираем список товаров", "если пользователь не заполнил поле имя..." | ||
+ | # Комментарии к функциям и классам оформляются в формате [http://manual.phpdoc.org/HTMLframesConverter/default/ PHPDoc] | ||
+ | # Комментарии в строках должны быть в стиле '''//'''. Они должны быть понятными и располагаться над строкой комментируемого кода. | ||
+ | # Файлы, содержащие PHP-код должны начинаться с комментария, предусмотренного лицензией GNU GPL. | ||
− | + | ==== Дата и время ==== | |
− | + | #Все даты и время в базе данных хранятся в [http://ru.wikipedia.org/wiki/Unix_timestamp Unix Timestamp] по [http://ru.wikipedia.org/wiki/UTC UTC] без учета летнего времени и пересчитываются в местное время при отображении (это стандартный функционал time() - Time Stamp не зависит от часовых поясов). | |
− | + | # В зависимости от услових (и техзадания) применяется либо часовой пояс подразделения (например, в периоде и днях), либо часовой пояс пользователя. | |
− | + | # Если определена только дата, то время устанавливается 12:00 по полудню по применяемому часовому поясу. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ==== Исключения ==== | |
− | - | + | # Рекомендуется использование исключений для сообщения об ошибках. |
− | + | # Любые необработанные исключения должны заканчиваться вызовом $DOF->print_error() для вывода сообщения об ошибке. | |
− | ---- | + | # Не используйте исключения для обработки штатных ситуаций, только в ошибочных и аварийных ситуаций. |
− | При копировании объектов используйте PHP5-функцию копирования объектов. В MOODLE есть функция clone(), которая совместима и с PHP4 тоже. | + | # Для вывода исключений можно использовать следующие классы: |
− | + | ## dof_exception - базовый класс исключения | |
− | Если вы копируете переменную, которая может содержать объект, то используйте функцию MOODLE fullclone(). | + | ## dof_exception_coding - ошибка разработчика |
− | + | ## dof_exception_ddl - ошибка определения структуры СУБД | |
− | + | ## dof_exception_dml - ошибка манипуляции с СУБД | |
− | + | ## dof_exception_file - ошибка работы с файлами | |
− | Все переменные перед первым использованием необходимо инициализировать. | + | |
− | + | ==== Прочее ==== | |
− | Имя модуля может включать только строчные латинские буквы и содержать не более 20 символов. | + | # При копировании объектов используйте PHP5-функцию копирования объектов. В MOODLE есть функция clone(), которая совместима и с PHP4 тоже. |
− | + | # Если вы копируете переменную, которая может содержать объект, то используйте функцию MOODLE fullclone(). | |
− | + | # Все переменные перед первым использованием необходимо инициализировать. | |
− | + | # Имя модуля может включать только строчные латинские буквы и содержать не более 20 символов. | |
− | + | # Следует избегать использования глобальных переменных. | |
− | + | # Обращения к объектом Free Dean's Office выполняется через объект [[Разработка:lib/dof.php|$DOF]]. При объявлении плагина он должен сохранить ссылка на объект $DOF в собственном свойстве dof и во всех собственных методов использовать для обращения '''$this->dof''' | |
− | Следует избегать использования глобальных переменных. | + | # Не должно быть никакого SQL-кода за пределом справочников ([[Разработка:Структура#Справочники|плагинов storage]]) |
− | + | # Из справочников (storage) нельзя обращаться к плагинам интерфейса (im) | |
− | Обращения к объектом Free Dean's Office выполняется через объект $DOF. При объявлении плагина он должен сохранить ссылка на объект $DOF в собственном свойстве dof и во всех собственных методов использовать для обращения $this->dof | + | # Кроме [[Разработка:Структура#Интерфейс пользователя|плагинов im]] никакие другие плагины не должны принимать запросы по http. Исключение могут составлять плагины [[Разработка:Структура#Синхронизации|sync]], которые могут принимать входящие soap-запросы и т.п. (но и они не должны реализовывать веб-интерфейс). При этом все плагины должны быть безопасны на случай, если злоумышленик попытается обратиться по прямой ссылке к одному из их файлов (следует предотвращать запуск файла по прямой ссылке, если это может нанести урон безопасности). |
− | + | # В методах обращения к базе, подразумевающих формирование своего SQL запроса, например get_records_sql(), необходимо максимально задействовать входные параметры, вместо формирования одного единственного $sql. Например limitfrom и limitnum необходимо передавать дополнительными параметрами, а не добавлять их в параметр $sql. | |
− | Не должно быть никакого SQL-кода за пределом справочников (плагинов storage) | + | |
− | + | ==== Исключения из правил ==== | |
− | Кроме плагинов im | + | # При использовании сторонних библиотек возможно отступление от некоторых пунктов. Это связано с экономией времени на переработку оформления библиотеки и сохранением стиля сопутствующего кода. Пример: class SomeCustomClass {function classMethod(){...}} |
− | ---- | + | |
− | Все | + | === Структура базы данных === |
− | Если | + | # Имена таблиц, принадлежащих справочникам, должны быть вида "block_dof_s_кодсправочника" |
+ | # Имена колонок БД, содержащих ключ по другой колонке в БД Free Dean's Office должны заканчиваться на "id" | ||
+ | # Имена колонок в БД, содержащих ключ объекта в собственной БД Moodle должны начинаться на "mdl" (но не должны заканчиваться на "id") | ||
+ | # Имя колонки status рекомендуется использовать только для статусов рабочих процессов (workflow) | ||
+ | # Если в таблице есть поле "code" то это поле должно быть уникальнам в рамках всей таблицы (как будто это второй первичный ключ) | ||
+ | # При именовании колонок рекомендуется придерживаться следующего правила: колонка именуется простым словом (name,type,price) если ее содержимое относится ко всей записи (например, для колонки "курсы" name - название курса, type - тип курса "очный", "дистанционный" и т.п. price - цена курса), а для остальных полей имя лучше уточнять (controltype - тип итогового контроля, ownerid - "владелец" курса, markprice - цена оценки :-)))) | ||
+ | |||
+ | === Безопасность === | ||
+ | # Все переменные должны содержать только безопасные данные (текстовые строки должны быть обработаны addslashes()). | ||
+ | # При получении данных через optional_param(), require_param(), dof_modlib_widgets_form (moodleform), а так же через стандартные методы справочников - все данные передаются в уже обработанном виде. | ||
+ | # При отображении данных на веб-странице и прочих операциях, где строки не должны быть экранированы, программист должен самостоятельно обработать данные stripslashes() непосредственно перед операцией, далее эти данные в программе использоваться не должны, либо их необходимо преобразовать обратно. Во всех остальных случаях, включая задание текстовых констант непосредственно в коде программы, программист обязан позаботится о безопасности данных (addslashes()). | ||
+ | |||
+ | Типы ожидаемых данных для функций optional_param() и require_param() можно посмотреть в статье [Разработка:Константы_Moodle#Константы типов данных|константы типов данных]]. | ||
+ | |||
+ | ==== Работа с правами доступа ==== | ||
+ | Правила работы с правами доступа описаны в разделе "[[Разработка:Управление_доступом#.D0.9F.D1.80.D0.B0.D0.B2.D0.B8.D0.BB.D0.B0_.D1.80.D0.B0.D0.B1.D0.BE.D1.82.D1.8B_.D1.81_.D0.BF.D1.80.D0.B0.D0.B2.D0.B0.D0.BC.D0.B8_.D0.B4.D0.BE.D1.81.D1.82.D1.83.D0.BF.D0.B0|Управление доступом]]" | ||
+ | |||
+ | === Использование JavaScript === | ||
+ | В качестве основной js-библиотеки проекта используется [https://docs.moodle.org/dev/YUI YUI]. Сама библиотека подключена как modlib-плагин: [[Разработка:modlibs/yui]]. | ||
+ | Помимо неё в проекте используется [http://jquery.com/ jQuery]: [[Разработка:modlibs/jquery]]. | ||
+ | |||
+ | Все скрипты (и стили), рекомендуется располагать в отдельный файлах. | ||
+ | |||
+ | JavaScript располагается в файлах с раширением .js, стили - .css. | ||
+ | |||
+ | Для того чтобы подключить скрипты YUI необходимо: | ||
+ | |||
+ | 1) Создать папку в директории dof/yui/modulename | ||
+ | |||
+ | 2) Создать скрипт с таким же названием (modulename.js), как и папка | ||
+ | |||
+ | 3) Воспользоваться функцией YUI.add() для добавления нужного функционала, например, таким образом: | ||
+ | |||
+ | <pre> | ||
+ | YUI.add('moodle-block_dof-modulename', function (Y) { | ||
+ | var MODULENAME = 'block_dof_modulename'; | ||
+ | var MODULE = function () { | ||
+ | MODULE.superclass.constructor.apply(this, arguments); | ||
+ | }; | ||
+ | |||
+ | MODULE.prototype = { | ||
+ | initializer: function (params) { | ||
+ | /* Инициализация происходит здесь */ | ||
+ | } | ||
+ | } | ||
+ | Y.extend(MODULE, Y.Base, MODULE.prototype, { | ||
+ | NAME: MODULENAME, | ||
+ | /* Можно передать эти параметры через функцию yui_module() */ | ||
+ | ATTRS: { | ||
+ | params: [], | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | M.block_dof = M.block_dof || {}; | ||
+ | M.block_dof.init_modulename = function (params) { | ||
+ | return new MODULE(params); | ||
+ | } | ||
+ | |||
+ | }, '@VERSION@', { | ||
+ | /* Модули для подключения необходимого фукнционала */ | ||
+ | requires: ['anim', 'array-extras', 'base', 'dd-constrain', 'dd-delegate', 'dd-drop', | ||
+ | 'dd-proxy', 'event-resize', 'io', 'json-parse', 'json', 'node', 'panel'] | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | 4) В коде вызвать подключение модуля: | ||
+ | |||
+ | <pre> | ||
+ | $DOF->modlib('yui')->yui_module('moodle-block_dof-modulename', 'M.block_dof.init_modulename', | ||
+ | array(array('submitparams' => $submitparams))); | ||
+ | </pre> | ||
+ | |||
+ | Для того чтобы подключить скрипты jQuery можно воспользоваться двумя способами: | ||
+ | |||
+ | 1) Если нужно просто подключить отдельный файл - то нужно воспользоваться функцией [[Разработка:modlibs/nvg#add_scripts()|add_scripts()]] в плагине nvg. | ||
+ | |||
+ | 2) Если нужно подключить библиотеку - то надо воспользоваться функцией [[Разработка:modlibs/widgets#js_init()|js_init()]] в плагине widgets. | ||
+ | |||
+ | Если вы пишете виджет, который использует javascript, то он сам должен подключать все нужные файлы. Файлы виджетов всегда прописываются в функции [[Разработка:modlibs/widgets#js_init()|js_init()]]. | ||
+ | |||
+ | === Работа с библиотеками Moodle === | ||
+ | Все обращения к библиотекам moodle можно производить только в модуле ama. Модуль ama можно вызывать только из модуля sync. | ||
+ | |||
+ | === Другие правила === | ||
+ | ==== Работа с сессиями ==== | ||
+ | Для каждого плагина, чтобы избежать пересечения по именам переменных, выделено персональное пространство в массиве сессии: | ||
+ | $_SESSION['dof'][plugintype][plugincode], | ||
+ | plugintype записывается так, как он указан, как его возвращает метод type(). | ||
+ | |||
+ | == Работа со стандартными библиотеками moodle == | ||
+ | Этот раздел будет содержать справку по работе со стандартными пакетами moodle | ||
+ | |||
+ | === Работа с moodleQuickForm === | ||
+ | ''Основная статья:'' [[Разработка:moodleQuickForm]]. | ||
+ | |||
+ | В этом разделе содержаться только основные правила работы с moodleQuickForm, которых следует придерживаться при написании форм. Подробные инструкции по работе с формами содержатся в основной статье. | ||
+ | ==== Создание класса ==== | ||
+ | Все создаваемые классы форм должны наследоваться только от класса ''dof_modlib_widgets_form''. Для того чтобы подключить этот класс, нужно воспользоваться функцией '''webform'''() из библиотеки [[Разработка:modlibs/widgets#API|widgets]]. | ||
+ | |||
+ | Пример кода: | ||
+ | ''// Подключаем библиотеку форм'' | ||
+ | $DOF->modlib('widgets')->'''webform'''(); | ||
+ | |||
+ | ''// создаем класс формы при помощи наследования'' | ||
+ | class my_form extends '''dof_modlib_widgets_form''' | ||
+ | { | ||
+ | .... | ||
+ | } | ||
+ | Наследование от класса ''moodleform'' или от ''HTMLQuickForm'' напрямую '''не допускается''' из-за проблем с совместимостью. | ||
+ | |||
+ | Во всех внутренних методах формы разрешается использовать обращение к глобальной переменной [[Разработка:lib/dof.php|$DOF]]. | ||
+ | |||
+ | При создании формы для добавления любых текстовых строк на русском языке следует пользоваться функцией $DOF->get_string(). | ||
+ | |||
+ | ==== Получение данных ==== | ||
+ | Получение данных из формы производится только при помощи специального метода [[Разработка:moodleQuickForm#get_data($slashed) | get_data()]]. | ||
+ | |||
+ | Проверка того, отправлены ли данные из формы производится при помощи метода [[Разработка:moodleQuickForm#is_submitted() | is_submitted()]]. | ||
+ | |||
+ | Пример кода: | ||
+ | // создаем объект данных | ||
+ | $form = new my_form(); | ||
+ | ''// проверяем, отправлены ли данные из формы'' | ||
+ | if ( $form->'''is_submitted'''() ) | ||
+ | { | ||
+ | ''// получаем данные'' | ||
+ | $data = $form->'''get_data'''(); | ||
+ | |||
+ | ... | ||
+ | |||
+ | } | ||
+ | |||
+ | ==== Проверка данных ==== | ||
+ | Пожалуйста не забывайте о том, что данные всегда могут быть посланы в обход формы, поэтому проверяя какие-либо данные на стороне клиента проверяйте их повторно на стороне сервера. | ||
+ | |||
+ | При создании формы, в полях, которые получают данные всегда указывайте тип данных, который вы ожидаете получить при помощи функции [[Разработка:moodleQuickForm#setType($elementname, $paramtype) | setType()]] | ||
+ | |||
+ | Для всех дополнительных проверок на стороне сервера должен использоваться внутренний метод [[Разработка:moodleQuickForm#validation($data, $files) | validation()]]. | ||
+ | |||
+ | === Работа с moodleExcelWorkbook === | ||
+ | |||
+ | === Работа с XMLDB === | ||
+ | ''Основная статья:'' [[Разработка:XMLDB]] | ||
+ | |||
+ | Если при создании нового плагина storage вам потребуется создать новую таблицу в базе данных, то следует воспользоваться установкой таблиц через XMLDB-скрипты. | ||
+ | |||
+ | Основные правила создания таблиц: | ||
+ | * Собственные таблицы могут иметь только плагины типа storage | ||
+ | * Файл С XML-кодом таблицы должен называться install.xml и лежать внутри плагина, в папке "db". | ||
+ | * Одному плагину storage должна соответствовать только одна таблица в базе данных. | ||
+ | * При обновлении таблицы не надо править ее xml-файл, вся информация об обновлении таблиц дается только в скриптах. | ||
+ | * При составлении скриптов для обновления структуры таблицы настоятельно рекомендуется пользоваться встроенным XMLDB-редактором Moodle. | ||
+ | |||
+ | [[Категория:Разработка]] |
Текущая версия на 11:36, 2 февраля 2015
Содержание
Правила оформления кода в проекте «Электронный деканат».
Стиль кодирования
Формат файлов
- Все файлы с кодом должны иметь расширение .php
- Все html-шаблоны должны иметь расширение .html
- Весь текст, включая исходный код, должен быть в кодировке utf-8 с оконачаниями строк в формет Unix
- Окончания строк в формате Unix (LF - 0x0A)
- Все php-теги должны быть полными <?php ... ?>. Краткие теки <? ?> не допускаются
- Все отступы – 4 пробела. Не использовать TAB.
- Длинна строки в коде не должна быть больше 80 символов. В некоторых случаях допускается 120, если это упростит читаемость кода.
- Пробелы можно использовать свободно. Не надо бояться растягивать код для улучшения читабельности.
Имена
- Имена файлов должны состоять только из латинских символов, знака подчеркивания и точки. Имя файла обязательно должно иметь расширение. Рекомендуется использовать для именования файлов слова на английском языке.
- Имена классов должны состоять из строчных латинских символов и знака подчеркивания. Рекомендуется использовать английские слова разделенных символом подчеркивания. Имя класса в плагине должно начинаться с префикса, соответствующего плагину. Если требуется, имя класса может включать преффикс и суффикс.
- Имена функций и методов должны состоять из строчных латинских символов и знака подчеркивания. Имя функции в плагине должно начинаться с префикса, соответствующего имени модуля (dof_) и плагину, в котором объявлена (типплагина_кодплагина). Затем идет часть имени, описывающая выполняемое действие. Последняя часть - это существительное, обозначающее сущность, над которой это действие производится либо набор сущностей. Не должно быть пробелов между именем функции и скобками. Это относится и к объявлению функции, и к ее использованию. Параметры всегда должны иметь разумные значения по умолчанию, если это возможно. Пример: modname_get_string($identifier, $pluginname = NULL). Между ключевым словом function и именем функции должен быть только один пробел.
- Имена параметров функций именуются по тем же правилам, что и переменные. Имя параметра должно быть кратким и информативным для сторонних программистов. Если параметр может быть не задан, используйте по умолчанию значение null, для отличия этой ситуации от передачи параметра false, 0 или если это требуется).
- Имена переменных - всегда легкие для чтения осмысленные слова английского языка, набранные в нижнем регистре. Несколько слов пишутся слитно. Но они должны быть как можно короче. Используйте имена во множественном числе для массивов объектов. Например: $courseid, $studentsgrades
- Имена глобальных переменных, должны состоять полностью из заглавных букв. Пример: $CFG
- Имена констант должны состоять из латинских символов в верхнем регистре и знака подчеркивания. Всегда начинаются с имени модуля (DOF). Если константа объявлена в плагине, она получает дополнительный префикс ТИППЛАГИНА_КОДПЛАГИНА. Слова в названии разделены символом подчеркивания. Пример: SITE_ID
- true, false и null должны быть набраны в нижнем регистре
- AND, OR, XOR должны быть набраны в верхнем регистре, не используйте сокращенные синонимы.
Строки
- Используйте одинарные кавычки, если в строке отсутствуют макроподстановки и эскейп-последовательности, а так же если в строке присутствует много двойных кавычек.
- При макроподстановках в двойных кавычках заключайте переменные в фигурные скобки.
- Объединение строк выполняется через оператор "точка" (.)
Массивы
- Не используйте отрицательных чисел для нумерации массивов (кроме случаев, когда это прямо требуется логикой программы).
- Индексация массива может начинаться с любого положительного числа, обычно с 0.
- При объявлении массива через функцию array() ставьте пробел после запятой при перечислении параметров. Длинные объявления можно переносить по строкам. При объявлении ассоциативных массивов помещайте на одну строку одну пару ключ-значение.
Классы
- Свойства класса должны объявляться до его методов.
- Фигурная скобка пишется на следующей строчке после объявления имени класса, на одном уровне с ключевым словом class.
- Объявление любого класса должно быть документировано по стандарту PHPDocumentor
- Весь код внутри класса должен быть сдвинут на 4 пробела от уровня его объявления.
- Объявление класса должно быть отделено от остального коду двумя пустыми строками.
- Свойства класса должны объявляться напрямую при объявлении класса с указанием модификатора доступа (private (доступ извне запрещен), protected (разрешен доступ из наследников) или public)
Функции и методы
- Объявление функций и методов должно сопровождаться комментарием по стандарту PHPDocumentor
- Все объявления методов должны содержать модификатор доступа (private (доступ извне запрещен), protected (разрешен доступ из наследников) или public)
- Фигурная скобка должна располагаться на следующей строке после объявления имени функции или метода на одном с ним уровнем.
- Тело функции должно быть сдвинуто на 4 пробела вправо.
- Между именем функции и круглой скобкой не должно быть пробела.
- Если функция не возвращает значений, то true обозначает успех, false - не успех. Если функция возвращает массив, в случае успешного выполнения, но отсутствия элементов в результате, функция должна возвращать пустой массив.
Управляющие конструкции
Ставьте один пробел между скобками и синтаксическими конструкциями. Это не относится к функциям и их параметрам. Пример:
if ( $a >= max($key) ) { ···· $c = $a; }
Блоки всегда ограничиваются фигурными скобками. При этом используется стиль Олмана:
if (<cond>) { ····<body> }
Комментарии и документация
- Комментарии должны быть подробными и содержательными. Объяснять каждое объявление классов, функций и переменных. Каждый цикл и каждая ветвь условия должны быть пояснены содержательным смыслом выполняемых действий, например: "перебираем список товаров", "если пользователь не заполнил поле имя..."
- Комментарии к функциям и классам оформляются в формате PHPDoc
- Комментарии в строках должны быть в стиле //. Они должны быть понятными и располагаться над строкой комментируемого кода.
- Файлы, содержащие PHP-код должны начинаться с комментария, предусмотренного лицензией GNU GPL.
Дата и время
- Все даты и время в базе данных хранятся в Unix Timestamp по UTC без учета летнего времени и пересчитываются в местное время при отображении (это стандартный функционал time() - Time Stamp не зависит от часовых поясов).
- В зависимости от услових (и техзадания) применяется либо часовой пояс подразделения (например, в периоде и днях), либо часовой пояс пользователя.
- Если определена только дата, то время устанавливается 12:00 по полудню по применяемому часовому поясу.
Исключения
- Рекомендуется использование исключений для сообщения об ошибках.
- Любые необработанные исключения должны заканчиваться вызовом $DOF->print_error() для вывода сообщения об ошибке.
- Не используйте исключения для обработки штатных ситуаций, только в ошибочных и аварийных ситуаций.
- Для вывода исключений можно использовать следующие классы:
- dof_exception - базовый класс исключения
- dof_exception_coding - ошибка разработчика
- dof_exception_ddl - ошибка определения структуры СУБД
- dof_exception_dml - ошибка манипуляции с СУБД
- dof_exception_file - ошибка работы с файлами
Прочее
- При копировании объектов используйте PHP5-функцию копирования объектов. В MOODLE есть функция clone(), которая совместима и с PHP4 тоже.
- Если вы копируете переменную, которая может содержать объект, то используйте функцию MOODLE fullclone().
- Все переменные перед первым использованием необходимо инициализировать.
- Имя модуля может включать только строчные латинские буквы и содержать не более 20 символов.
- Следует избегать использования глобальных переменных.
- Обращения к объектом Free Dean's Office выполняется через объект $DOF. При объявлении плагина он должен сохранить ссылка на объект $DOF в собственном свойстве dof и во всех собственных методов использовать для обращения $this->dof
- Не должно быть никакого SQL-кода за пределом справочников (плагинов storage)
- Из справочников (storage) нельзя обращаться к плагинам интерфейса (im)
- Кроме плагинов im никакие другие плагины не должны принимать запросы по http. Исключение могут составлять плагины sync, которые могут принимать входящие soap-запросы и т.п. (но и они не должны реализовывать веб-интерфейс). При этом все плагины должны быть безопасны на случай, если злоумышленик попытается обратиться по прямой ссылке к одному из их файлов (следует предотвращать запуск файла по прямой ссылке, если это может нанести урон безопасности).
- В методах обращения к базе, подразумевающих формирование своего SQL запроса, например get_records_sql(), необходимо максимально задействовать входные параметры, вместо формирования одного единственного $sql. Например limitfrom и limitnum необходимо передавать дополнительными параметрами, а не добавлять их в параметр $sql.
Исключения из правил
- При использовании сторонних библиотек возможно отступление от некоторых пунктов. Это связано с экономией времени на переработку оформления библиотеки и сохранением стиля сопутствующего кода. Пример: class SomeCustomClass {function classMethod(){...}}
Структура базы данных
- Имена таблиц, принадлежащих справочникам, должны быть вида "block_dof_s_кодсправочника"
- Имена колонок БД, содержащих ключ по другой колонке в БД Free Dean's Office должны заканчиваться на "id"
- Имена колонок в БД, содержащих ключ объекта в собственной БД Moodle должны начинаться на "mdl" (но не должны заканчиваться на "id")
- Имя колонки status рекомендуется использовать только для статусов рабочих процессов (workflow)
- Если в таблице есть поле "code" то это поле должно быть уникальнам в рамках всей таблицы (как будто это второй первичный ключ)
- При именовании колонок рекомендуется придерживаться следующего правила: колонка именуется простым словом (name,type,price) если ее содержимое относится ко всей записи (например, для колонки "курсы" name - название курса, type - тип курса "очный", "дистанционный" и т.п. price - цена курса), а для остальных полей имя лучше уточнять (controltype - тип итогового контроля, ownerid - "владелец" курса, markprice - цена оценки :-))))
Безопасность
- Все переменные должны содержать только безопасные данные (текстовые строки должны быть обработаны addslashes()).
- При получении данных через optional_param(), require_param(), dof_modlib_widgets_form (moodleform), а так же через стандартные методы справочников - все данные передаются в уже обработанном виде.
- При отображении данных на веб-странице и прочих операциях, где строки не должны быть экранированы, программист должен самостоятельно обработать данные stripslashes() непосредственно перед операцией, далее эти данные в программе использоваться не должны, либо их необходимо преобразовать обратно. Во всех остальных случаях, включая задание текстовых констант непосредственно в коде программы, программист обязан позаботится о безопасности данных (addslashes()).
Типы ожидаемых данных для функций optional_param() и require_param() можно посмотреть в статье [Разработка:Константы_Moodle#Константы типов данных|константы типов данных]].
Работа с правами доступа
Правила работы с правами доступа описаны в разделе "Управление доступом"
Использование JavaScript
В качестве основной js-библиотеки проекта используется YUI. Сама библиотека подключена как modlib-плагин: Разработка:modlibs/yui. Помимо неё в проекте используется jQuery: Разработка:modlibs/jquery.
Все скрипты (и стили), рекомендуется располагать в отдельный файлах.
JavaScript располагается в файлах с раширением .js, стили - .css.
Для того чтобы подключить скрипты YUI необходимо:
1) Создать папку в директории dof/yui/modulename
2) Создать скрипт с таким же названием (modulename.js), как и папка
3) Воспользоваться функцией YUI.add() для добавления нужного функционала, например, таким образом:
YUI.add('moodle-block_dof-modulename', function (Y) { var MODULENAME = 'block_dof_modulename'; var MODULE = function () { MODULE.superclass.constructor.apply(this, arguments); }; MODULE.prototype = { initializer: function (params) { /* Инициализация происходит здесь */ } } Y.extend(MODULE, Y.Base, MODULE.prototype, { NAME: MODULENAME, /* Можно передать эти параметры через функцию yui_module() */ ATTRS: { params: [], } }); M.block_dof = M.block_dof || {}; M.block_dof.init_modulename = function (params) { return new MODULE(params); } }, '@VERSION@', { /* Модули для подключения необходимого фукнционала */ requires: ['anim', 'array-extras', 'base', 'dd-constrain', 'dd-delegate', 'dd-drop', 'dd-proxy', 'event-resize', 'io', 'json-parse', 'json', 'node', 'panel'] });
4) В коде вызвать подключение модуля:
$DOF->modlib('yui')->yui_module('moodle-block_dof-modulename', 'M.block_dof.init_modulename', array(array('submitparams' => $submitparams)));
Для того чтобы подключить скрипты jQuery можно воспользоваться двумя способами:
1) Если нужно просто подключить отдельный файл - то нужно воспользоваться функцией add_scripts() в плагине nvg.
2) Если нужно подключить библиотеку - то надо воспользоваться функцией js_init() в плагине widgets.
Если вы пишете виджет, который использует javascript, то он сам должен подключать все нужные файлы. Файлы виджетов всегда прописываются в функции js_init().
Работа с библиотеками Moodle
Все обращения к библиотекам moodle можно производить только в модуле ama. Модуль ama можно вызывать только из модуля sync.
Другие правила
Работа с сессиями
Для каждого плагина, чтобы избежать пересечения по именам переменных, выделено персональное пространство в массиве сессии: $_SESSION['dof'][plugintype][plugincode], plugintype записывается так, как он указан, как его возвращает метод type().
Работа со стандартными библиотеками moodle
Этот раздел будет содержать справку по работе со стандартными пакетами moodle
Работа с moodleQuickForm
Основная статья: Разработка:moodleQuickForm.
В этом разделе содержаться только основные правила работы с moodleQuickForm, которых следует придерживаться при написании форм. Подробные инструкции по работе с формами содержатся в основной статье.
Создание класса
Все создаваемые классы форм должны наследоваться только от класса dof_modlib_widgets_form. Для того чтобы подключить этот класс, нужно воспользоваться функцией webform() из библиотеки widgets.
Пример кода:
// Подключаем библиотеку форм $DOF->modlib('widgets')->webform(); // создаем класс формы при помощи наследования class my_form extends dof_modlib_widgets_form { .... }
Наследование от класса moodleform или от HTMLQuickForm напрямую не допускается из-за проблем с совместимостью.
Во всех внутренних методах формы разрешается использовать обращение к глобальной переменной $DOF.
При создании формы для добавления любых текстовых строк на русском языке следует пользоваться функцией $DOF->get_string().
Получение данных
Получение данных из формы производится только при помощи специального метода get_data().
Проверка того, отправлены ли данные из формы производится при помощи метода is_submitted().
Пример кода:
// создаем объект данных $form = new my_form(); // проверяем, отправлены ли данные из формы if ( $form->is_submitted() ) { // получаем данные $data = $form->get_data(); ... }
Проверка данных
Пожалуйста не забывайте о том, что данные всегда могут быть посланы в обход формы, поэтому проверяя какие-либо данные на стороне клиента проверяйте их повторно на стороне сервера.
При создании формы, в полях, которые получают данные всегда указывайте тип данных, который вы ожидаете получить при помощи функции setType()
Для всех дополнительных проверок на стороне сервера должен использоваться внутренний метод validation().
Работа с moodleExcelWorkbook
Работа с XMLDB
Основная статья: Разработка:XMLDB
Если при создании нового плагина storage вам потребуется создать новую таблицу в базе данных, то следует воспользоваться установкой таблиц через XMLDB-скрипты.
Основные правила создания таблиц:
- Собственные таблицы могут иметь только плагины типа storage
- Файл С XML-кодом таблицы должен называться install.xml и лежать внутри плагина, в папке "db".
- Одному плагину storage должна соответствовать только одна таблица в базе данных.
- При обновлении таблицы не надо править ее xml-файл, вся информация об обновлении таблиц дается только в скриптах.
- При составлении скриптов для обновления структуры таблицы настоятельно рекомендуется пользоваться встроенным XMLDB-редактором Moodle.