Логика работы фреймворка опирается на некоторые соглашения об именовании файлов, PHP-классов и таблиц базы данных, которые нужно обязательно соблюдать для правильной работы приложений, плагинов, виджетов и тем дизайна.
База данных #
Таблицы приложений в базе данных
Требование: названия всех таблиц приложения должны начинаться с идентификатора приложения (app_id), отделенного символом подчеркивания.
Рекомендация: таблицы сущностей, например, для хранения сообщений в гостевой книге, записей, файлов и т. д. рекомендуется называть в единственном числе.
Примеры
guestbook_message
— таблица хранения сообщений в приложении guestbookblog_post
— таблица хранения записей в приложении blogfiles_file
— таблица хранения файлов в приложении file
Рекомендация: таблицы связей и дополнительных данных рекомендуется именовать по следующему правилу: название таблицы формируется из двух слов (в дополнение к обязательному префиксу с ID приложения), разделенных символом подчеркивания: название основной сущности в единственном числе и название второстепенной сущности во множественном числе.
Пример
Таблица для хранения email-ов контактов: wa_contact_emails
— связь одного (контаката) ко многим (email-адресам).
Таблицы плагинов в базе данных
Требование: названия таблиц плагина должны формироваться по шаблону вида [app_id]_[plugin_id]_name
, где вместо [app_id]
и [plugin_id]
нужно использовать идентификаторы приложения и плагина, а вместо name
— произвольное долполнение к имени таблицы.
Поля таблиц базы данных
Рекомендация: собственные поля таблицы рекомендуется называть без дополнительных префиксов. Под собственными понимаются поля, не являющиеся внешними ключами к записям в других таблицах.
Примеры
id
name
create_datetime
Если несколько полей схожи по названию, рекомендуется добавлять префикс, уточняющий смысл поля исходя из логики и здравого смысла. Например, поля с различными датами:
create_datetime
edit_datetime
Рекомендация: поля внешних ключей рекомендуется именовать следующим образом: название таблицы (без префикса) на которую ссылается поле, далее символ подчёркивания и название соответствующего поля в этой таблице.
Примеры
contact_id
— ссылка на поле id в таблице контактов (wa_contact.id);order_id
— id заказа.
Для большей наглядности можно добавлять к такому имени поля смысловой префикс.
Примеры
actor_contact_id
— id контакта, совершившего действие;assigned_contact_id
— id контакта, назначенного на выполнение задания и т. д.
Классы, методы и переменные PHP #
Именование классов и методов
Требование: имена всех классов приложения должны начинаться с идентификатора приложения (app_id). Это нужно для того, чтобы не возникало конфликтов имён между классами разных приложений.
Требование: для именования классов и методов нужно использовать «горбатый стиль»: слова в названии пишутся слитно (без символа-разделителя), первое слово (app_id) — с маленькой буквы, остальные — с большой.
Пример
<?php class filesFile { public function getInfo() { ... } ... }
Именование PHP-файлов классов
Классы PHP подгружаются фреймворком с помощью механизма Autoload. Для того чтобы механизм подгрузки смог найти нужный PHP-файл, нужно придерживаться определённых правил именования файлов классов.
Требование: все файлы классов должны находиться внутри
директории lib/
в каталоге приложения, плагина или виджета.
Требование: название файла класса должно иметь следующий формат: {ИМЯ_КЛАССА}.class.php
. Например, если класс называется contactsCollection
, то его файл должен называться contactsCollection.class.php
.
Требование: для файлов экшенов, контроллеров и моделей существует дополнительный формат именования, который рекомендуется использовать: если в имени класса содержится суффикс Actions
, Action
, Controller
или Model
,
то название файла класса должно иметь следующий формат: [НАЗВАНИЕ_КЛАССА_БЕЗ_СУФФИКСА].[суффикс].php
([суффикс]
пишется строчными буквами).
Примеры
- Класс
contactsGroupsSaveAction
— файлcontactsGroupsSave.action.php
- Класс
contactsGroupsActions
— файлcontactsGroups.actions.php
- Класс
contactsGroupsController
— файлcontactsGroups.controller.php
- Класс
contactsRightsModel
— файлcontactsRights.model.php
Именование классов и методов PHP-контроллеров и экшенов #
Логика приложения в слое контроллеров организована в двухуровневую иерархию «модуль/действие« (MODULE/ACTION). Действующие правила маршрутизации задают соответствие между URL запроса и парой модуль+действие. Т. е. каждый запрос запускает выполнение определённого действия внутри определённого модуля.
Механизм маршрутизации определяет названия модуля и действия (действие может быть не указано, в этом случае система запустит действие по умолчанию). Для того чтобы система смогла определить, какой метод какого класса необходимо вызвать для обработки поступившего запроса, нужно придерживаться правил именования классов и методов контроллеров.
Требование: имя класса и метода для обработки запроса должны соответствовать правилам, по которым система ищет класс и метод для его обработки. Поиск выполняется в следующем порядке (конкатенация строк при построении названия класса производится в «горбатом« стиле без разделителей):
Первым ищется класс с названием
[app_id][Module][Action]Controller
или, если не был указан [Action],[app_id][Module]Controller
. Если такой класс найден, то создаётся экземпляр этого класса и вызывается его методexecute
— это стартовая точка контроллера для данной страницы.Если класс найден не был, то ищется класс с названием, построенным по другому правилу:
[app_id][Module]Actions
. Если такой класс найден, то создаётся его экземпляр и вызывается метод[action]Action
, либо методDefaulAction
, если [action] не был указан.Если второй вариант класса не был найден, ищется третий вариант с именем вида
[app_id][Module][Action]Action
или, если не указан [action],[app_id][Module]Action
. Если такой класс найден, то создаётся его экзепляр и вызывается методexecute
.Если ни один из этих классов не был найден, то отдаётся ошибка с кодом 404 («Не найдено»).
Примеры
Приложение myblog, модуль mail, действие не указано:
myblogMailController->execute()
myblogMailActions->defaultAction()
myblogMailAction->execute()
Приложение myblog, модуль mail, действие test:
myblogMailTestController->execute()
myblogMailActions->testAction()
myblogMailTestAction->execute()
Подробнее система маршрутизации описана в разделах «Маршрутизация в бекенде» и «Маршрутизация во фронтенде».
Имена классов и файлов плагинов
В плагинах используются аналогичные правила за тем исключением, что после идентификатора приложения нужно добавить идентификатор плагина и слово Plugin.
Примеры
- Имя класса:
shopSuperPluginBackendListAction
, имя файла:shopSuperPluginBackendList.action.php
. - Имя класса:
blogSocialPluginItemsModel
, имя файла:blogSocialPluginItems.model.php
.
Именование файлов шаблонов #
Каждый шаблон привязан к конкретному действию конкретного модуля. Механизм определения шаблона для рендеринга опирается на названия модуля и действия.
Требование: файл шаблона ищется по следующему пути внутри файловой структуры: templates/actions/[Module]/[Module][Action].html
. Например, для модуля mail и действия test фреймворк будет искать в качестве шаблона файл templates/actions/mail/MailTest.html
Требование: для случаев, когда [Action] не был указан, правила именования шаблона зависят от типа класса экшена:
- Для экшенов, реализуемых методом
defaultAction
, файл шаблона должен называться [Module]Default.html - Для экшенов, реализуемых методом
execute
, файл шаблона должен называться [Module].html
Подробнее о типах классов экшенов см. раздел «Экшены и контроллеры».
Именование глобально доступных идентификаторов (JavaScript, CSS, сессии, cookie) #
Глобально доступные идентификаторы (переменные и функции JavaScript, CSS-классы, параметры запросов, обрабатываемые классом waRequest
, переменные пользовательских сессий и cookie) нужно именовать таким образом, чтобы они не приводили к конфликтам с любыми другими программными продуктами, которые могут использоваться в бекенде и фронтенде. Для этого в именах таких идентификаторов используйте ID вашего плагина или приложения.
Примеры
// JavaScript var myplugin_var; //если нет другой возможности, добавьте ID плагина в имя глобальной переменной // обычно лучше оформить такой JavaScript-код с использованием замыканий и не добавлять лишний идентификатор в имя переменной // CSS .myplugin-settings .fields .field .name //например, оберните поля настроек в элемент с собственным CSS-классом и переопределяйте стили полей с использованием префикса // PHP-сессии wa()->getStorage()->set('shop_myplugin_custom_var', $data); // Параметры запросов waRequest::setParam('myplugin_custom_param', $data);
Рекомендация: при написании JavaScript-кода желательно не использовать глобальные идентификаторы и оформлять код плагина с использованием замыканий.
Пример
// Нежелательно var myplugin_global_var = '...'; //пусть и с собственным префиксом, эта переменная будет доступна в коде других плагинов и самого приложения if (myplugin_global_var) { ... } //Лучше (function () { var global_var = '...'; //эта переменная доступна только в коде плагина и с другими плагинами конфликтовать не будет if (global_var) { ... } })();
Рекомендации по стилю форматирования PHP-кода #
Рекомендация: при разработке приложений (особенно при командной разработке), рекомендуется придерживаться единого стиля форматирования кода. Мы рекомендуем придерживаться стиля, применяемого в коде фреймворка и приложений Webasyst:
<?php //использовать только такой открывающий тег и никакой другой /** * @desc Всегда оставлять комментарии к своим классам в формате PhpDOC */ class CodingStyle //классы называть по правилу «верблюжьего горба» { //открывающую фигурную скобку в начале класса ставить с НОВОЙ строки //табуляция заменяется 4 пробелами //кодировка - UTF-8 //переносы строк UNIX, то есть \n, а не \r\n /** * @desc формат названий переменных должен отличаться от формата названий методов * в названиях переменных использовать только маленькие буквы и разделять слова подчеркиванием */ public $is_right; /** * @desc К методам и функциям писать комментарии * @param $code int - описывать входные данные * @return boolean - описывать выходные данные */ public function doIWriteValidCode($code) //методы называть по принципу «верблюжьего горба» { //открывающую фигурную скобку в начале метода ставить с НОВОЙ строки //внутри методов и функций писать комментарии ТОЛЬКО в таком виде и не использовать //многострочное оформление даже если комментарии на несколько строк $this->is_right = false; //символы +-=*/{} и пр. обязательно отделять пробелами if (! $code) { //любую открывающую скобку внутри методов ставить на ТОЙ ЖЕ строке //нет кода - нет проблемы. $this->is_right = true; //использовать скобки, ДАЖЕ если оператор в конструкции один } else { //else/elseif писать на ТОЙ ЖЕ строке, что и закрывающая скобка оператора if $this->is_right = $this->checkMyCode($code); } return $this->is_right; } /** * @desc Составлять описание, даже если название метода говорит само за себя */ public function checkMyCode($code) { return false; //Закон природы - мы всегда найдем к чему придраться, какой бы код ни был } } //в конце файла закрывающий тег не нужен