В первой части этой серии мы говорили о проблемах развития, с которыми мы сталкиваемся, и о том, как Openbiz Cubi может помочь, предоставив надежную, готовую к использованию среду веб-приложений. В этой части мы увидим, как создать наш собственный модуль и немного углубиться в основную архитектуру фреймворка.
Сборка первого модуля
Давайте перейдем к захватывающей части — созданию модуля; мы начнем с простой страницы редактирования клиента. На этой странице пользователи могут создавать, обновлять и удалять клиентов.
Сначала давайте сделаем таблицу базы данных customer
. SQL для создания таблицы:
CREATE TABLE customer ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(64) NOT NULL, description VARCHAR(255) DEFAULT NULL, address VARCHAR(255) DEFAULT NULL, phone VARCHAR(20) DEFAULT NULL, fax VARCHAR(20) DEFAULT NULL, status INTEGER DEFAULT NULL, create_by INTEGER DEFAULT '1', create_time DATETIME DEFAULT NULL, update_by INTEGER DEFAULT '1', update_time DATETIME DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB
Следующим шагом в создании модуля является создание файлов метаданных XML для страницы редактирования клиента. Здесь мы используем gen_meta
, команду генерации метаданных в gen_meta
cubi/bin/tools
.
/ dev / cubi / bin / tools $ php gen_meta.php Клиент по умолчанию
Вы можете просто нажать клавишу Enter, чтобы завершить работу мастера. После выполнения команды генерируются следующие файлы:
Файл конфигурации модуля
-
modules/customer/mod.xml
Модуль DO файл
-
modules/customer/do/CustomerDO.xml
Файл формы модуля
-
modules/customer/form/CustomerListForm.xml
-
modules/customer/form/CustomerDetailForm.xml
-
modules/customer/form/CustomerEditForm.xml
-
modules/customer/form/CustomerNewForm.xml
-
modules/customer/form/CustomerCopyForm.xml
Модуль Просмотр файла
-
modules/customer/view/CustomerListView.xml
Файлы виджетов модуля
-
modules/customer/widget/DashboardForm.xml
-
modules/customer/widget/LeftMenu.xml
Файлы шаблонов модулей
-
modules/customer/template/detail.tpl
-
modules/customer/template/detail_elementset.tpl
-
modules/customer/template/grid.tpl
-
modules/customer/template/view.tpl
Затем мы загружаем только что созданный модуль командой load_module
.
/ dev / cubi / bin / tools / php $ load_module.php customer Начать загрузку клиентского модуля ... -------------------------------------------------- ------ [2013-01-26T17: 57: 16 + 08: 00] Загрузка модуля заказчика [2013-01-26T17: 57: 16 + 08: 00] Установить модуль заказчика [2013-01-26T17: 57: 16 + 08: 00] Установите ACL модуля. [2013-01-26T17: 57: 16 + 08: 00] Установить меню модуля. [2013-01-26T17: 57: 16 + 08: 00] Установить виджет модуля. [2013-01-26T17: 57: 16 + 08: 00] Установить ресурс модуля. [2013-01-26T17: 57: 16 + 08: 00] Установить журналы изменений модуля. [2013-01-26T17: 57: 16 + 08: 00] Скопируйте файлы ресурсов в папку / cubi / resources. [2013-01-26T17: 57: 16 + 08: 00] клиент загружен. Предоставить администратору доступ ко всем действиям модуля «клиент» -------------------------------------------------- ------ Клиентский модуль с конечной загрузкой
Давайте проверим модуль. Если вы уже вошли в Cubi, выйдите и войдите снова. Вы должны увидеть новую вкладку с именем «Клиент», появившуюся в разделе заголовка. Перейдите на вкладку, чтобы перейти на страницу «Панель управления клиентами», затем нажмите ссылку «Управление клиентами», чтобы перейти на страницу управления клиентами. Теперь мы можем создавать, обновлять, искать и удалять клиентов.
Под капотом
Вы можете задаться вопросом без какого-либо программирования, как Openbiz Cubi заставляет все работать? На предыдущих шагах gen_meta
создавала XML-файлы в папке клиентского модуля. Куби тогда знает, как интерпретировать эти файлы. Давайте сначала mod.xml
файл описания модуля mod.xml
.
Файл описания модуля
Мы создали модуль customer с mod.xml
modules/customer
.
<?xml version="1.0" standalone="no"?> <Module Name="customer" Description="customer module" Version="0.1.0" OpenbizVersion="3.0"> <ACL> <Resource Name="customer"> <Action Name="Access" Description="Access Customer Module Dashboard"/> </Resource> <Resource Name="customer"> <Action Name="Access" Description="Access Customer"/> <Action Name="Manage" Description="Manage Customer"/> </Resource> </ACL> <Menu> <MenuItem Name="CustomerTop" Title="Customer" Description="Customer Description" URL="/customer/dashboard" Parent="" Order="10"> <MenuItem Name="Customer" Title="Customer" Description="Customer description" URL="" Order="10"> <MenuItem Name="Customer.List" Title="Customer Manage" Description="" URL="/customer/customer_list" Order="10"/> </MenuItem> </MenuItem> </Menu> <Dependency> <Module Name="system"/> </Dependency> </Module>
mod.xml
содержит 3 раздела:
- Контроль доступа — раздел
ACL
определяет ресурсы и их действия. Эти определения используются для управления разрешениями для определенных ролей. - Меню — раздел «
Menu
» определяет ссылки на страницы в навигационной системе (вкладки приложений, хлебные крошки и меню). - Зависимости — раздел
Dependency
определяет модули, от которых зависит текущий модуль. Зависимые модули должны быть установлены в первую очередь.
Обычно каждый модуль включает в себя свои собственные модели данных и XML-файлы презентации. Каркас имеет механизм метаданных, который может понимать XML и загружать данные и объекты пользовательского интерфейса на лету. Фреймворк в основном работает с двумя типами объектов метаданных:
- Объекты данных — Cubi отображает физические хранилища данных (например, таблицу базы данных) на логические объекты.
- Объекты формы и представления. Объекты формы описывают, как представлять данные объектов данных в блоке на странице, а объекты представления определяют контейнер объектов формы. В браузере представление совпадает с веб-страницей.
Объект данных
Теперь давайте посмотрим на объект данных XML в modules/customer/do/CustomerDO.xml
:
<?xml version="1.0" standalone="no"?> <BizDataObj Name="CustomerDO" Description="" Class="BizDataObj" DBName="Default" Table="customer" SearchRule="" SortRule="" OtherSQLRule="" Uniqueness="" Stateless="N" IdGeneration="Identity" CacheLifeTime="0" CreateCondition="customer.Manage" UpdateCondition="customer.Manage" DeleteCondition="customer.Manage"> <BizFieldList> <BizField Name="Id" Column="id" Type="Number"/> <BizField Name="name" Column="name" Length="64" Required="Y" Type="Text"/> <BizField Name="description" Column="description" Length="255" Required="N" Type="Text"/> <BizField Name="address" Column="address" Length="255" Required="N" Type="Text"/> <BizField Name="phone" Column="phone" Length="20" Required="N" Type="Text"/> <BizField Name="fax" Column="fax" Length="20" Required="N" Type="Text"/> <BizField Name="status" Column="status" Required="N" Type="Number"/> <BizField Name="create_by" Column="create_by" Type="Number" ValueOnCreate="{@profile:Id}"/> <BizField Name="create_time" Column="create_time" Type="Datetime" ValueOnCreate="{date('Ymd H:i:s')}"/> <BizField Name="update_by" Column="update_by" Type="Number" ValueOnCreate="{@profile:Id}" ValueOnUpdate="{@profile:Id}"/> <BizField Name="update_time" Column="update_time" Type="Datetime" ValueOnCreate="{date('Ymd H:i:s')}" ValueOnUpdate="{date('Ymd H:i:s')}"/> </BizFieldList> <TableJoins> </TableJoins> <ObjReferences> </ObjReferences> </BizDataObj>
XML определяет отображение между таблицей customer
и объектом CustomerDO
. Он также определяет определенные правила для объектов, а также проверку, тип и значение каждого поля.
Форма объекта
Давайте также посмотрим на объект формы XML в modules/customer/form/CustomerListForm.xml
.
<?xml version="1.0" encoding="UTF-8"?> <EasyForm Name="CustomerListForm" Class="EasyForm" FormType="List" jsClass="jbForm" Title="Customer Management" Description="" BizDataObj="customer.do.CustomerDO" PageSize="10" DefaultForm="Y" TemplateEngine="Smarty" TemplateFile="grid.tpl" Access="customer.Access"> <DataPanel> <Element Name="row_selections" Class="RowCheckbox" Label="" FieldName="Id"/> <Element Name="fld_Id" Class="ColumnText" FieldName="Id" Label="Id" Sortable="Y"/> <Element Name="fld_name" Class="ColumnText" FieldName="name" Label="Name" DefaultValue="New Customer" Sortable="Y" Link="javascript:"> <EventHandler Name="fld_name_onclick" Event="onclick" Function="SwitchForm(customer.form.CustomerDetailForm,{@:Elem[fld_Id].Value})" /> </Element> <Element Name="fld_description" Class="ColumnText" FieldName="description" Label="Description" Sortable="Y"/> <Element Name="fld_address" Class="ColumnText" FieldName="address" Label="Address" Sortable="Y"/> <Element Name="fld_phone" Class="ColumnText" FieldName="phone" Label="Phone" Sortable="Y"/> <Element Name="fld_fax" Class="ColumnText" FieldName="fax" Label="Fax" Sortable="Y"/> <Element Name="fld_status" Class="ColumnText" FieldName="status" Label="Status" Sortable="Y"/> </DataPanel> <ActionPanel> ... <Element Name="btn_delete" Class="Button" Text="Delete" CssClass="button_gray_m" Access="customer.Manage"> <EventHandler Name="del_onclick" Event="onclick" EventLogMsg="" Function="DeleteRecord()" ShortcutKey="Ctrl+Delete" ContextMenu="Delete"/> </Element> ... </ActionPanel> <NavPane> ... </NavPanel> <SearchPane> ... </SearchPanel> </EasyForm>
XML отображает поля из объектов данных в элементы пользовательского интерфейса. Он также определяет панели для логического расположения элементов. Для каждого элемента пользовательского интерфейса поведение взаимодействия может быть описано в его разделе EventHandler
.
Настроить объекты
Каждый элемент Metadata
поставляется с атрибутом Class
. В метаданных, сгенерированных gen_meta
, для атрибута задан базовый класс платформы ( BizDataObj
для объектов данных, EasyForm
для объектов формы). Разработчики могут просто заменить это для реализации специальной бизнес-логики. Например, чтобы добавить специальную логику для удаления записи клиента, вы можете создать файл /modules/customer/form/CustomerForm.php
и установить для него атрибут Class
элемента Metadata
. Класс PHP может выглядеть так:
<?php class CustomerForm extends EasyForm { public function deleteRecord($id = null) { // add your logic here Parent::deleteRecord($id); // call parent deleteRecord method } }
Кубический поток казни
Так что же происходит, когда в браузере вызывается http: //host/cubi/index.php/customer/customer_list ?
-
index.php
вызывает_forward.php
для анализа URL. Он понимает, что / customer / customer_list указывает наcubi/modules/customer/view/CustomerListView.xml
в соответствии с соглашением об именах URL-адресов Кубы. - Метод визуализации представления вызывается.
- Метод render вызывает метод render включенной формы (
cubi/modules/customer/form/CustomerListForm.xml
). - Метод render формы вызывает методы запроса данных своего объекта данных.
- Методы запроса подготавливают SQL и выполняют его в отношении базы данных.
- Форма использует возвращенный набор данных из DO для генерации HTML со своим шаблоном.
- Представление использует выходные данные форм для генерации HTML со своим шаблоном.
- Сервер отправляет вывод HTML в браузер.
Как только представление загружается в браузер, большинство взаимодействий с пользователем происходит в формах через Ajax (без перезагрузки страницы). Диаграмма ниже показывает, как работает вызов Ajax:
Вывод
Из этой серии мы узнали, как установить Cubi, настроить систему и создать модуль. Вы также можете обнаружить, что файл метаданных XML легче изучать и поддерживать, чем программный код. Я надеюсь, что вам понравился этот сериал, и желаю вам удачи в ваших собственных бизнес-приложениях на Openbiz Cubi.
Изображение через Fotolia