Разработка:Стандарт кодирования — различия между версиями

Материал из DOF
Перейти к: навигация, поиск
(Правила оформления кода в проекте «Электронный деканат».)
(Использование JavaScript)
 
(не показано 59 промежуточных версий 6 участников)
Строка 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 - не успех. Если функция возвращает массив, в случае успешного выполнения, но отсутствия элементов в результате, функция должна возвращать пустой массив.
  
 
+
==== Управляющие конструкции ====
 
+
Ставьте один пробел между скобками и синтаксическими конструкциями. Это не относится к функциям и их параметрам. Пример:
 
+
<code php>
 
 
== Правила оформления кода в проекте «Электронный деканат». ==
 
*Все отступы – 4 пробела. Не использовать TAB.
 
*Имена переменных - всегда легкие для чтения осмысленные слова английского языка, набранные в нижнем регистре. Несколько слов пишутся слитно. Но они должны быть как можно короче. Используйте имена во множественном числе для массивов. $courseid, $studentsgrades
 
*Константы всегда в верхнем регистре, всегда начинаются с имени модуля. Слова в названии разделены символом подчеркивания. SITE_ID
 
*Имена глобальных переменных, состоят полностью из заглавных букв. $CFG
 
*Функции называются словами английского языка в нижнем регистре, разделенные символом подчеркивания. Начинаются с имени модуля. Затем идет часть имени, описывающая выполняемое действие. Последняя часть - это существительное, обозначающее сущность, над которой это действие производится либо набор сущностей. Не должно быть пробелов между именем функции и скобками. Это относится и к объявлению функции, и к ее использованию. Параметры всегда должны иметь разумные значения по умолчанию, если это возможно. Пример:
 
    modname_get_string($identifier, $pluginname = NULL)
 
*Ставьте один пробел между скобками и синтаксическими конструкциями. Это не относится к функциям и их параметрам. Пример:
 
 
     if ( $a >= max($key) )
 
     if ( $a >= max($key) )
 
     {
 
     {
Строка 21: Строка 55:
 
      
 
      
 
     }
 
     }
 +
</code>
  
*При использовании сторонних библиотек возможно отступление от пунктов 4, 5, 6. (см. пример). Это связано с экономией времени на переработку оформления библиотеки и сохранением стиля сопутствующего кода. Пример:
+
Блоки всегда ограничиваются фигурными скобками. При этом используется [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 стиль Олмана]:
    class SomeCustomClass {function classMethod(){...}}
+
<code php>
*Блоки всегда ограничиваются фигурными скобками. При этом используется стиль Олмана:
 
 
     if (<cond>)
 
     if (<cond>)
 
     {
 
     {
 
     ····<body>
 
     ····<body>
 
     }
 
     }
*Строки должны заключаться, если это возможно, одинарными кавычками.
+
</code>
*Двойные кавычки должны использоваться если:
+
 
**строка содержит интерпретируемые переменные;
+
==== Комментарии и документация ====
**внутри строки должны использоваться кавычки (их можно заэкранировать слешем, но это немного снизит читаемость кода).
+
# Комментарии должны быть подробными и содержательными. Объяснять каждое объявление классов, функций и переменных. Каждый цикл и каждая ветвь условия должны быть пояснены содержательным смыслом выполняемых действий, например: "перебираем список товаров", "если пользователь не заполнил поле имя..."
*Комментарии должны быть подробными и содержательными. Объяснять каждое объявление классов, функций и переменных. Каждый цикл и каждая ветвь условия должны быть пояснены содержательным смыслом выполняемых действий, например: "перебираем список товаров", "если пользователь не заполнил поле имя..."
+
# Комментарии к функциям и классам оформляются в формате [http://manual.phpdoc.org/HTMLframesConverter/default/ PHPDoc]
*Комментарии к функциям и классам оформляются в формате PHPDocs
+
# Комментарии в строках должны быть в стиле '''//'''. Они должны быть понятными и располагаться над строкой комментируемого кода.
*Комментарии в строках должны быть в стиле '''//'''. Они должны быть понятными и располагаться над строкой комментируемого кода.
+
# Файлы, содержащие PHP-код должны начинаться с комментария, предусмотренного лицензией GNU GPL.
*Пробелы можно использовать свободно. Не надо бояться растягивать код для улучшения читабельности.
+
 
*При копировании объектов используйте PHP5-функцию копирования объектов. В MOODLE есть функция clone(), которая совместима и с PHP4 тоже.
+
==== Дата и время ====
*Если вы копируете переменную, которая может содержать объект, то используйте функцию MOODLE fullclone().
+
#Все даты и время в базе данных хранятся в [http://ru.wikipedia.org/wiki/Unix_timestamp Unix Timestamp] по [http://ru.wikipedia.org/wiki/UTC UTC] без учета летнего времени и пересчитываются в местное время при отображении (это стандартный функционал time() - Time Stamp не зависит от часовых поясов).
*Если функция не возвращает значений, то true обозначает успех, false - не успех. Если функция возвращает массив, в случае успешного выполнения, но отсутствия элементов в результате, функция должна возвращать пустой массив.
+
# В зависимости от услових (и техзадания) применяется либо часовой пояс подразделения (например, в периоде и днях), либо часовой пояс пользователя.
*Все переменные перед первым использованием необходимо инициализировать.
+
# Если определена только дата, то время устанавливается 12:00 по полудню по применяемому часовому поясу.
*Имя модуля может включать только строчные латинские буквы и содержать не более 20 символов.
+
 
*Имена колонок БД, содержащих ключ по другой колонке в БД Free Dean's Office должны заканчиваться на id
+
==== Исключения ====
*Имена колонок в БД, содержащих ключ объекта в собственной БД Moodle должны начинаться на mdl (но не должны заканчиваться на id)
+
# Рекомендуется использование исключений для сообщения об ошибках.
*Следует избегать использования глобальных переменных.
+
# Любые необработанные исключения должны заканчиваться вызовом $DOF->print_error() для вывода сообщения об ошибке.
*Обращения к объектом Free Dean's Office выполняется через объект $DOF. При объявлении плагина он должен сохранить ссылка на объект $DOF в собственном свойстве dof и во всех собственных методов использовать для обращения $this->dof
+
# Не используйте исключения для обработки штатных ситуаций, только в ошибочных и аварийных ситуаций.
*Не должно быть никакого SQL-кода за пределом справочников (плагинов storage)
+
# Для вывода исключений можно использовать следующие классы:
*Кроме плагинов im/ никакие другие плагины не должны принимать запросы по http. Исключение могут составлять плагины sync, которые могут принимать входящие soap-запросы и т.п. (но и они не должны реализовывать веб-интерфейс). При этом все плагины должны быть безопасны на случай, если злоумышленик попытается обратиться по прямой ссылке к одному из их файлов (следует предотвращать запуск файла по прямой ссылке, если это может нанести урон безопасности).
+
## dof_exception - базовый класс исключения
*Все даты и время в базе данных хранятся в Unix Timestamp по UTC без учета летнего времени и пересчитываются в местное время при отображении.
+
## dof_exception_coding - ошибка разработчика
Если определена только дата, то время устанавливается 12:00 по полудню.
+
## dof_exception_ddl - ошибка определения структуры СУБД
 +
## dof_exception_dml - ошибка манипуляции с СУБД
 +
## dof_exception_file - ошибка работы с файлами
 +
 
 +
==== Прочее ====
 +
# При копировании объектов используйте PHP5-функцию копирования объектов. В MOODLE есть функция clone(), которая совместима и с PHP4 тоже.
 +
# Если вы копируете переменную, которая может содержать объект, то используйте функцию MOODLE fullclone().
 +
# Все переменные перед первым использованием необходимо инициализировать.
 +
# Имя модуля может включать только строчные латинские буквы и содержать не более 20 символов.
 +
# Следует избегать использования глобальных переменных.
 +
# Обращения к объектом Free Dean's Office выполняется через объект [[Разработка:lib/dof.php|$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#Константы типов данных|константы типов данных]].
 +
 
 +
==== Работа с правами доступа ====
 +
Правила работы с правами доступа описаны в разделе "[[Разработка:Управление_доступом#.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 ==
 
Этот раздел будет содержать справку по работе со стандартными пакетами moodle
 
Этот раздел будет содержать справку по работе со стандартными пакетами moodle
  
== Работа с moodleQuickForm ==
+
=== Работа с 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]]
  
== Работа с moodleExcelWorkbook ==
+
Если при создании нового плагина storage вам потребуется создать новую таблицу в базе данных, то следует воспользоваться установкой таблиц через XMLDB-скрипты.
  
 +
Основные правила создания таблиц:
 +
* Собственные таблицы могут иметь только плагины типа storage
 +
* Файл С XML-кодом таблицы должен называться install.xml и лежать внутри плагина, в папке "db".
 +
* Одному плагину storage должна соответствовать только одна таблица в базе данных.
 +
* При обновлении таблицы не надо править ее xml-файл, вся информация об обновлении таблиц дается только в скриптах.
 +
* При составлении скриптов для обновления структуры таблицы настоятельно рекомендуется пользоваться встроенным XMLDB-редактором Moodle.
  
== Работа с XMLDB ==
+
[[Категория:Разработка]]

Текущая версия на 11:36, 2 февраля 2015

Правила оформления кода в проекте «Электронный деканат».

Стиль кодирования

Формат файлов

  1. Все файлы с кодом должны иметь расширение .php
  2. Все html-шаблоны должны иметь расширение .html
  3. Весь текст, включая исходный код, должен быть в кодировке utf-8 с оконачаниями строк в формет Unix
  4. Окончания строк в формате Unix (LF - 0x0A)
  5. Все php-теги должны быть полными <?php ... ?>. Краткие теки <? ?> не допускаются
  6. Все отступы – 4 пробела. Не использовать TAB.
  7. Длинна строки в коде не должна быть больше 80 символов. В некоторых случаях допускается 120, если это упростит читаемость кода.
  8. Пробелы можно использовать свободно. Не надо бояться растягивать код для улучшения читабельности.

Имена

  1. Имена файлов должны состоять только из латинских символов, знака подчеркивания и точки. Имя файла обязательно должно иметь расширение. Рекомендуется использовать для именования файлов слова на английском языке.
  2. Имена классов должны состоять из строчных латинских символов и знака подчеркивания. Рекомендуется использовать английские слова разделенных символом подчеркивания. Имя класса в плагине должно начинаться с префикса, соответствующего плагину. Если требуется, имя класса может включать преффикс и суффикс.
  3. Имена функций и методов должны состоять из строчных латинских символов и знака подчеркивания. Имя функции в плагине должно начинаться с префикса, соответствующего имени модуля (dof_) и плагину, в котором объявлена (типплагина_кодплагина). Затем идет часть имени, описывающая выполняемое действие. Последняя часть - это существительное, обозначающее сущность, над которой это действие производится либо набор сущностей. Не должно быть пробелов между именем функции и скобками. Это относится и к объявлению функции, и к ее использованию. Параметры всегда должны иметь разумные значения по умолчанию, если это возможно. Пример: modname_get_string($identifier, $pluginname = NULL). Между ключевым словом function и именем функции должен быть только один пробел.
  4. Имена параметров функций именуются по тем же правилам, что и переменные. Имя параметра должно быть кратким и информативным для сторонних программистов. Если параметр может быть не задан, используйте по умолчанию значение null, для отличия этой ситуации от передачи параметра false, 0 или если это требуется).
  5. Имена переменных - всегда легкие для чтения осмысленные слова английского языка, набранные в нижнем регистре. Несколько слов пишутся слитно. Но они должны быть как можно короче. Используйте имена во множественном числе для массивов объектов. Например: $courseid, $studentsgrades
  6. Имена глобальных переменных, должны состоять полностью из заглавных букв. Пример: $CFG
  7. Имена констант должны состоять из латинских символов в верхнем регистре и знака подчеркивания. Всегда начинаются с имени модуля (DOF). Если константа объявлена в плагине, она получает дополнительный префикс ТИППЛАГИНА_КОДПЛАГИНА. Слова в названии разделены символом подчеркивания. Пример: SITE_ID
  8. true, false и null должны быть набраны в нижнем регистре
  9. AND, OR, XOR должны быть набраны в верхнем регистре, не используйте сокращенные синонимы.

Строки

  1. Используйте одинарные кавычки, если в строке отсутствуют макроподстановки и эскейп-последовательности, а так же если в строке присутствует много двойных кавычек.
  2. При макроподстановках в двойных кавычках заключайте переменные в фигурные скобки.
  3. Объединение строк выполняется через оператор "точка" (.)

Массивы

  1. Не используйте отрицательных чисел для нумерации массивов (кроме случаев, когда это прямо требуется логикой программы).
  2. Индексация массива может начинаться с любого положительного числа, обычно с 0.
  3. При объявлении массива через функцию array() ставьте пробел после запятой при перечислении параметров. Длинные объявления можно переносить по строкам. При объявлении ассоциативных массивов помещайте на одну строку одну пару ключ-значение.

Классы

  1. Свойства класса должны объявляться до его методов.
  2. Фигурная скобка пишется на следующей строчке после объявления имени класса, на одном уровне с ключевым словом class.
  3. Объявление любого класса должно быть документировано по стандарту PHPDocumentor
  4. Весь код внутри класса должен быть сдвинут на 4 пробела от уровня его объявления.
  5. Объявление класса должно быть отделено от остального коду двумя пустыми строками.
  6. Свойства класса должны объявляться напрямую при объявлении класса с указанием модификатора доступа (private (доступ извне запрещен), protected (разрешен доступ из наследников) или public)

Функции и методы

  1. Объявление функций и методов должно сопровождаться комментарием по стандарту PHPDocumentor
  2. Все объявления методов должны содержать модификатор доступа (private (доступ извне запрещен), protected (разрешен доступ из наследников) или public)
  3. Фигурная скобка должна располагаться на следующей строке после объявления имени функции или метода на одном с ним уровнем.
  4. Тело функции должно быть сдвинуто на 4 пробела вправо.
  5. Между именем функции и круглой скобкой не должно быть пробела.
  6. Если функция не возвращает значений, то true обозначает успех, false - не успех. Если функция возвращает массив, в случае успешного выполнения, но отсутствия элементов в результате, функция должна возвращать пустой массив.

Управляющие конструкции

Ставьте один пробел между скобками и синтаксическими конструкциями. Это не относится к функциям и их параметрам. Пример:

   if ( $a >= max($key) )
   {
   
   ···· $c = $a;
   
   }

Блоки всегда ограничиваются фигурными скобками. При этом используется стиль Олмана:

   if (<cond>)
   {
   ····<body>
   }

Комментарии и документация

  1. Комментарии должны быть подробными и содержательными. Объяснять каждое объявление классов, функций и переменных. Каждый цикл и каждая ветвь условия должны быть пояснены содержательным смыслом выполняемых действий, например: "перебираем список товаров", "если пользователь не заполнил поле имя..."
  2. Комментарии к функциям и классам оформляются в формате PHPDoc
  3. Комментарии в строках должны быть в стиле //. Они должны быть понятными и располагаться над строкой комментируемого кода.
  4. Файлы, содержащие PHP-код должны начинаться с комментария, предусмотренного лицензией GNU GPL.

Дата и время

  1. Все даты и время в базе данных хранятся в Unix Timestamp по UTC без учета летнего времени и пересчитываются в местное время при отображении (это стандартный функционал time() - Time Stamp не зависит от часовых поясов).
  2. В зависимости от услових (и техзадания) применяется либо часовой пояс подразделения (например, в периоде и днях), либо часовой пояс пользователя.
  3. Если определена только дата, то время устанавливается 12:00 по полудню по применяемому часовому поясу.

Исключения

  1. Рекомендуется использование исключений для сообщения об ошибках.
  2. Любые необработанные исключения должны заканчиваться вызовом $DOF->print_error() для вывода сообщения об ошибке.
  3. Не используйте исключения для обработки штатных ситуаций, только в ошибочных и аварийных ситуаций.
  4. Для вывода исключений можно использовать следующие классы:
    1. dof_exception - базовый класс исключения
    2. dof_exception_coding - ошибка разработчика
    3. dof_exception_ddl - ошибка определения структуры СУБД
    4. dof_exception_dml - ошибка манипуляции с СУБД
    5. dof_exception_file - ошибка работы с файлами

Прочее

  1. При копировании объектов используйте PHP5-функцию копирования объектов. В MOODLE есть функция clone(), которая совместима и с PHP4 тоже.
  2. Если вы копируете переменную, которая может содержать объект, то используйте функцию MOODLE fullclone().
  3. Все переменные перед первым использованием необходимо инициализировать.
  4. Имя модуля может включать только строчные латинские буквы и содержать не более 20 символов.
  5. Следует избегать использования глобальных переменных.
  6. Обращения к объектом Free Dean's Office выполняется через объект $DOF. При объявлении плагина он должен сохранить ссылка на объект $DOF в собственном свойстве dof и во всех собственных методов использовать для обращения $this->dof
  7. Не должно быть никакого SQL-кода за пределом справочников (плагинов storage)
  8. Из справочников (storage) нельзя обращаться к плагинам интерфейса (im)
  9. Кроме плагинов im никакие другие плагины не должны принимать запросы по http. Исключение могут составлять плагины sync, которые могут принимать входящие soap-запросы и т.п. (но и они не должны реализовывать веб-интерфейс). При этом все плагины должны быть безопасны на случай, если злоумышленик попытается обратиться по прямой ссылке к одному из их файлов (следует предотвращать запуск файла по прямой ссылке, если это может нанести урон безопасности).
  10. В методах обращения к базе, подразумевающих формирование своего SQL запроса, например get_records_sql(), необходимо максимально задействовать входные параметры, вместо формирования одного единственного $sql. Например limitfrom и limitnum необходимо передавать дополнительными параметрами, а не добавлять их в параметр $sql.

Исключения из правил

  1. При использовании сторонних библиотек возможно отступление от некоторых пунктов. Это связано с экономией времени на переработку оформления библиотеки и сохранением стиля сопутствующего кода. Пример: class SomeCustomClass {function classMethod(){...}}

Структура базы данных

  1. Имена таблиц, принадлежащих справочникам, должны быть вида "block_dof_s_кодсправочника"
  2. Имена колонок БД, содержащих ключ по другой колонке в БД Free Dean's Office должны заканчиваться на "id"
  3. Имена колонок в БД, содержащих ключ объекта в собственной БД Moodle должны начинаться на "mdl" (но не должны заканчиваться на "id")
  4. Имя колонки status рекомендуется использовать только для статусов рабочих процессов (workflow)
  5. Если в таблице есть поле "code" то это поле должно быть уникальнам в рамках всей таблицы (как будто это второй первичный ключ)
  6. При именовании колонок рекомендуется придерживаться следующего правила: колонка именуется простым словом (name,type,price) если ее содержимое относится ко всей записи (например, для колонки "курсы" name - название курса, type - тип курса "очный", "дистанционный" и т.п. price - цена курса), а для остальных полей имя лучше уточнять (controltype - тип итогового контроля, ownerid - "владелец" курса, markprice - цена оценки :-))))

Безопасность

  1. Все переменные должны содержать только безопасные данные (текстовые строки должны быть обработаны addslashes()).
  2. При получении данных через optional_param(), require_param(), dof_modlib_widgets_form (moodleform), а так же через стандартные методы справочников - все данные передаются в уже обработанном виде.
  3. При отображении данных на веб-странице и прочих операциях, где строки не должны быть экранированы, программист должен самостоятельно обработать данные 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.