...

вторник, 8 июля 2014 г.

Когда нужно что-то почти готовое

image

Доброго времени суток, хабражитель!


Чуть более года назад столкнулся с ситуацией когда нужно было реализовать веб-приложение (как обычно в очень сжатые сроки) с богатым функционалом:



  1. Управление учетными записями пользователей с различными ролями

  2. Назначение задач на пользователей и отслеживание дальнейшей жизнедеятельности этих задач

  3. Планирование работы пользователей (на день, месяц)

  4. Работа с результатами работы сотрудников (регистрация времени и типов работ)

  5. Формирование различных отчетов, статистических срезов информации и тп




И это только десятая часть того что нужно было сделать еще “вчера”. Сразу оговорюсь: я — не веб-разработчик, поэтому нужно было решение, на котором можно было бы построить веб-приложение как можно быстрее без глубокого погружения в мир PHP, JS, Java, Ruby, и тп.



Я умышленно пропущу анализ и выбор средств реализации и сразу перейду к самому интересному: в качестве платформы был выбран Koala Framework — гремучая смесь из Zend Framework и ExtJS. В основу этого фреймворка легла модель MVC (model-view-controller). Но настоящей его силой являются автогенерируемые формы и таблицы (AutoForm и AutoGrid).

Смысл авто-форм и авто-таблиц в том, что разработчику нужно описать модель (таблицу БД) и связать поля/свойста модели с колонками таблицы и полями формы. Например:


допустим у нас есть таблица в MySQL:



CREATE TABLE IF NOT EXISTS `tasks` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userId` int NOT NULL,
`title` varchar(300) COLLATE utf8_unicode_ci,
`description` varchar(1000) COLLATE utf8_unicode_ci,
`startDate` date,
`endDate` date,
`status` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `userId` (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


Модель будет иметь вид:



<?php
class Tasks extends Kwf_Model_Db
{
protected $_table = 'tasks';
}


Чтобы отобразить список задач необходимо создать контроллер (точнее AutoGrid Controller):



<?php
class TasksController extends Kwf_Controller_Action_Auto_Grid
{
protected $_modelName = 'Tasks';
protected $_defaultOrder = array('field' => 'id', 'direction' => 'DESC');
protected $_paging = 30;
protected $_buttons = array('add');

public function indexAction()
{
$this->view->ext('Tasks');
}

protected function _initColumns()
{
$this->_columns->add(new Kwf_Grid_Column('title', trl('Title'), 200));

$this->_columns->add(new Kwf_Grid_Column_Date('endDate', trl('End Date'), 100))->setRenderer('checkDate');
}
}


Здесь свойства класса описывают поведение: количество элементов на странице (да, постраничный вывод поддерживается из коробки!), модель данных, сортировку выборки (опиционально) и возможные действия. Из действий здесь указано только добавление задач, но доступны еще и удаление, сохранение и экспорт в Excel/PDF.


Теперь нужно загрузить задачи только для конкретного залогиненого пользователя. Для этого во фреймворке есть глобальные переменные. Теперь легко задаем условия для выборки задач в контроллере:



protected function _getWhere()
{
$users = Kwf_Registry::get('userModel');

$ret = parent::_getWhere();

$ret['status = ?'] = 0;
$ret['userId = ?'] = $users->getAuthedUserId();
return $ret;
}


Отлично, теперь пользователь видит только свои активные задачи!


Так, осталось добавить создание и изменение задач. Для этого нужен уже другой контроллер (AutoForm Controller):



<?php
class TaskController extends Kwf_Controller_Action_Auto_Form
{
protected $_modelName = 'Tasks';
protected $_permissions = array('save', 'add');
protected $_buttons = array('save');

protected function _initFields()
{
$this->_form->add(new Kwf_Form_Field_TextField('title', trl('Title')))
->setWidth(400)
->setAllowBlank(false);

$this->_form->add(new Kwf_Form_Field_DateField('startDate', trl('Start Date')));
$this->_form->add(new Kwf_Form_Field_DateField('endDate', trl('End Date')));

$this->_form->add(new Kwf_Form_Field_TextArea('description', trl('Description')))
->setHeight(70)
->setWidth(400);

$this->_form->add(new Kwf_Form_Field_Checkbox('status', trl('Done')));
}
}


Свойства класса описывают поведение формы, причем связи данных с полями задаются в функции initFields(). Но есть маленькая проблема: поле userId никак не связано с текущим пользователем и не привязано к полям формы. Пока… Чтобы освободить пользователя от работы по выбору самого себя в качестве владельца задачи нужно добавить триггер — функцию, срабатывающую во время создания новой записи:



protected function _beforeInsert(Kwf_Model_Row_Interface $row)
{
$users = Kwf_Registry::get('userModel');

if ($row->startDate == NULL)
{
$row->startDate = new DateTime ();
}
$row->userId = $users->getAuthedUserId();
$row->status = 0;
}


В KWF также доступны и другие триггеры: на изменение и удаление данных.


Теперь как-то нужно связать оба этих контроллера между собой. Код обоих контроллеров генерирует ExtJS формы. Следовательно и связывать мы их будем в JS коде:



var Tasks = Ext.extend(Ext.Panel,
{
initComponent : function(test)
{
var form = new Kwf.Auto.FormPanel({
controllerUrl : '/task',
region : 'center'
});

var grid = new Kwf.Auto.GridPanel({
controllerUrl : '/tasks',
region : 'west',
width : 400,
resizable : true,
split : true,
collapsible : true,
title : trl('Tasks'),
bindings: [{
queryParam: 'id',
item: form
}]
});
this.layout = 'border';
this.items = [grid, {
layout: 'border',
region: 'center',
items: [form]
}];
Tasks.superclass.initComponent.call(this);
}
});


Всем, кто уже работал с ExtJS, этот код наверно покажется очень знакомым =)


Осталось только определить точку доступа (входа) к этим контроллерам. Для этого в KWF есть отдельный предопределенный класс Kwf_Acl:



<?php
class Acl extends Kwf_Acl
{
public function __construct()
{
parent::__construct();
$this->remove('default_index');

$this->addResource(new Kwf_Acl_Resource_MenuUrl('default_tasks', array('text'=>trl('Tasks'), 'icon'=>'time.png'), '/tasks'));

$this->addResource(new Zend_Acl_Resource('default_task'), ‘default_tasks');

$this->addRole(new Zend_Acl_Role(‘user'));

$this->allow('user', 'default_tasks');
$this->allow('admin', 'default_tasks');
$this->allow('admin', 'default_index');
}
}


Вот и все! Очередной TO-DO список готов! В добавок он многопользовательский и при необходимости задачи типа экспорт списка в Excel / PDF, фильтрации и сортировки списков добавляются максимум минут за 5!



Полный код приложения доступен тут: http://ift.tt/1r4wRk5


Давайте создавать побольше полезных и удобных инструментов! =)


От себя еще хочу добавить что сейчас веб-приложение на KFW успешно разработано и внедрено в крупной Российской компании. Отзывы пользователей исключительно положительные.


PS: В команду ищутся разработчики PHP, ExtJS, MySQL, желающие поближе познакомиться с Koala Framework и готовые помочь (не бесплатно конечно) в развитии отечественной специализированной КИС. На все вопросы могу ответить в комментариях или в личке.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий