Статьи

Openbiz Cubi: надежная платформа PHP-приложений, часть 2

В первой части этой серии мы говорили о проблемах развития, с которыми мы сталкиваемся, и о том, как 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 ?

  1. index.php вызывает _forward.php для анализа URL. Он понимает, что / customer / customer_list указывает на cubi/modules/customer/view/CustomerListView.xml в соответствии с соглашением об именах URL-адресов Кубы.
  2. Метод визуализации представления вызывается.
  3. Метод render вызывает метод render включенной формы ( cubi/modules/customer/form/CustomerListForm.xml ).
  4. Метод render формы вызывает методы запроса данных своего объекта данных.
  5. Методы запроса подготавливают SQL и выполняют его в отношении базы данных.
  6. Форма использует возвращенный набор данных из DO для генерации HTML со своим шаблоном.
  7. Представление использует выходные данные форм для генерации HTML со своим шаблоном.
  8. Сервер отправляет вывод HTML в браузер.

Как только представление загружается в браузер, большинство взаимодействий с пользователем происходит в формах через Ajax (без перезагрузки страницы). Диаграмма ниже показывает, как работает вызов Ajax:

Cubi-2-1

Вывод

Из этой серии мы узнали, как установить Cubi, настроить систему и создать модуль. Вы также можете обнаружить, что файл метаданных XML легче изучать и поддерживать, чем программный код. Я надеюсь, что вам понравился этот сериал, и желаю вам удачи в ваших собственных бизнес-приложениях на Openbiz Cubi.

Изображение через Fotolia