433 lines
15 KiB
PHP
433 lines
15 KiB
PHP
<?php
|
||
/**
|
||
*
|
||
* @package Core
|
||
*/
|
||
require_once 'core/json.php';
|
||
require_once 'core/form/form.php';
|
||
require_once 'core/controller/controller.php';
|
||
|
||
require_once 'core/widgets/pagemenu.php';
|
||
require_once 'core/widgets/menu.php';
|
||
require_once 'core/widgets/search.php';
|
||
require_once 'core/widgets/setup.php';
|
||
require_once 'core/widgets/listtable.php';
|
||
|
||
/**
|
||
* Переименовать контроллер !! (StubController, CrudController, PageController, BaseController) ModelController
|
||
* Возможно нужен еще класс с мета действиями как для actionIndex <= metaActionIndex либо с классам для этих действий
|
||
* Есть класс для управлениями действиями а есть сами действия в виде классов или функций !!
|
||
*/
|
||
class Controller_Model extends Controller_Action
|
||
{
|
||
public $schema = array();
|
||
public $schemaSearch = array();
|
||
|
||
/**
|
||
* FIXME: Лучше $this->table->setHeader
|
||
*/
|
||
public $tableSchema = null;
|
||
public $formSchema = array();
|
||
|
||
public $menu;
|
||
public $path;
|
||
public $table;
|
||
|
||
public function __construct()
|
||
{
|
||
$this->path = new PathMenu();
|
||
$this->menu = new PageMenu();
|
||
$this->table = new ListTable();
|
||
}
|
||
|
||
/**
|
||
*/
|
||
function setUp()
|
||
{
|
||
$this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'warning');
|
||
//$this->table->addMenuItem($this->nUrl('form'), 'редактировать', 'edit-24.png');
|
||
}
|
||
|
||
function saveParameters($args, $list)
|
||
{
|
||
foreach ($list as $item) {
|
||
$args->session()->set(array($this, $item), $args->get($item));
|
||
}
|
||
}
|
||
|
||
protected function getJSONList(/*Mapper*/ $model, Collection $request)
|
||
{
|
||
$result = array();
|
||
$this->saveParameters($request, array('size','page','desc', 'key'));
|
||
|
||
$result['list'] = $model->findAll($request, $request->get('ref'));
|
||
$result['size'] = $model->getCount($request, $request->get('ref'));
|
||
return json::encode($result);
|
||
}
|
||
|
||
/**
|
||
* Удаление сторк из таблицы
|
||
*/
|
||
public function actionDelete(HttpRequest $request)
|
||
{
|
||
$model = $this->getModel($this->useModel);
|
||
// Почему table_item ???
|
||
$list = ($request->get('table_item')) ? $request->get('table_item'): $request->get('id');
|
||
$model->deleteList($list);
|
||
|
||
return $this->getJSONList($model, $request);
|
||
}
|
||
|
||
/**
|
||
* Ответ на запрос по поиску
|
||
*/
|
||
public function actionSearch(HttpRequest $request)
|
||
{
|
||
$model = $this->getModel($this->useModel);
|
||
$model->addFilter($model->requestToSQL($request, $this->formSchema));
|
||
|
||
return $this->getJSONList($model, $request);
|
||
}
|
||
|
||
/**
|
||
* Список элементов
|
||
*/
|
||
public function actionList(HttpRequest $request)
|
||
{
|
||
$model = $this->getModel($this->useModel);
|
||
return $this->getJSONList($model, $request);
|
||
}
|
||
|
||
|
||
private function setFormSchema()
|
||
{
|
||
require_once 'core/mapper/uimapper.php';
|
||
|
||
$model = $this->getModel($this->useModel);
|
||
$ui = new UIMapper($model);
|
||
|
||
$this->formSchema = $ui->getFormSchema();
|
||
}
|
||
|
||
/**
|
||
* Сохранение формы
|
||
*/
|
||
function beforeSave(/*Model*/ $item, Collection $request)
|
||
{
|
||
if (empty($this->formSchema)) {
|
||
$this->setFormSchema();
|
||
}
|
||
// Сделать отображение Формы в обьект и обратно <-- Убрать в beforeSave
|
||
foreach ($this->formSchema as $key => $conv) {
|
||
list($value, $type) = $conv;
|
||
$item->$value = call_user_func(array('Cast', 'to_' . $type), $request->get($key)); // Здесть нужно преобразовывать тип значения
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Обновление формы
|
||
*/
|
||
function formUpdate(TForm $form, Collection $request)
|
||
{
|
||
}
|
||
|
||
/**
|
||
* Загрузка формы
|
||
*/
|
||
function beforeLoad(/*Model*/ $item, TForm $form)
|
||
{
|
||
if (empty($this->formSchema)) {
|
||
$this->setFormSchema();
|
||
}
|
||
// Вставка значений из данных в форму
|
||
// Отображение обьекта в поля формы
|
||
$form->fill($item, $this->formSchema);
|
||
}
|
||
|
||
// Проверка ввода
|
||
protected function validate($validator, $request)
|
||
{
|
||
}
|
||
|
||
/**
|
||
* Действие для проверки формы
|
||
*/
|
||
public function actionValidate($request)
|
||
{
|
||
require_once "core/validator/validator.php";
|
||
$validator = new Validator();
|
||
$validator->addRuleList($this->schema);
|
||
|
||
// Действия до проверки формы
|
||
$this->validate($validator, $request); // <--|
|
||
$validator->validate($request); // --|
|
||
// Проверка формы
|
||
if (!$validator->isValid()) {
|
||
return json::encode($validator->getErrorMsg());
|
||
}
|
||
return json::encode(true);
|
||
}
|
||
|
||
/**
|
||
* Инициализация формы
|
||
*/
|
||
protected function formSetup($form, $id = null, $ref = null)
|
||
{
|
||
if (empty($this->schema)) {
|
||
$model = $this->getModel($this->useModel);
|
||
$ui = new UIMapper($model);
|
||
$schema = $ui->getEditSchema();
|
||
|
||
$form->addFieldList($schema);
|
||
} else {
|
||
$form->addFieldList($this->schema);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Добавление пользователя
|
||
*/
|
||
public function actionAdd(HttpRequest $request)
|
||
{
|
||
require_once "core/validator/validator.php";
|
||
// {{{ тоже может быть один ref или несколько
|
||
$ref = $request->get('ref');
|
||
$this->addParameter('ref', $ref); // Добавляет параметр в url
|
||
/// }}}
|
||
|
||
if ($this->checkPageId($request, $request->get('page'))) {
|
||
// Проверка
|
||
$validator = new Validator();
|
||
$validator->addRuleList($this->schema);
|
||
|
||
// Действия до проверки формы
|
||
$this->validate($validator, $request); // <--|
|
||
$validator->validate($request); // --|
|
||
// Проверка формы
|
||
if (!$validator->isValid()) {
|
||
$request->setAction('form');
|
||
$this->getActionPath($request);
|
||
|
||
$form = new TForm();
|
||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
||
|
||
$form->setValues($request); // <-- Убрать в formUpdate
|
||
$this->formUpdate($form, $request);
|
||
|
||
$form->setError($validator); // Установка ошибок для формы
|
||
|
||
$tpl = $this->formPage($form, $request);
|
||
$id = $request->get('id');
|
||
if ($id) { // Редактирование
|
||
$tpl->action = forceUrl($this->nUrl('add', array('id' => $id, 'page' => $this->getPageId($request)))); // action Совйство формы
|
||
}
|
||
return $tpl /*->execute()*/;
|
||
}
|
||
|
||
// Нужен тест для формы
|
||
$model = $this->getModel($this->useModel);
|
||
$className = $model->className;
|
||
$item = new $className();
|
||
|
||
// Сохраняем значение в базе данных
|
||
$item->id = $request->get('id');
|
||
// Если таблица связана с другой таблицей
|
||
if ($request->get('ref') && $model->reference[1]) {
|
||
$ref_id = $model->reference[1];
|
||
$item->$ref_id = $request->get('ref');
|
||
}
|
||
|
||
// Подготовка к сохранению
|
||
$this->beforeSave($item, $request); // Сюдаже и истрия переходов
|
||
// nextId ??? или выход или новая форма для создания новости
|
||
$model->saveDB($item, $request);
|
||
}
|
||
|
||
// Для страницы со списком id -> идентефикатор родительской таблицы !!??
|
||
// $request->set('id', $request->get('ref'));
|
||
if ($request->get('apply')) {
|
||
$request->setAction('form');
|
||
return $this->forward('actionForm', $request);
|
||
}
|
||
return $this->forward('actionIndex', $request);
|
||
}
|
||
|
||
/**
|
||
* Заголовок
|
||
*/
|
||
private function setTitlePath($ref)
|
||
{
|
||
if ($ref) {
|
||
$model = $this->getModel($this->useModel);
|
||
if (is_array($model->reference) && $model->reference[0]) {
|
||
$refmodel = $this->getModel($model->reference[0]);
|
||
try {
|
||
$parent = $refmodel->findById($ref);
|
||
$this->path->addTitle($parent->getTitle()); // Заголовок к подписям путей
|
||
} catch (Exception $e) {
|
||
// Не найден заголовок потому что неправильно определен родительский элемент
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Форма для редактирования
|
||
*/
|
||
public function actionForm(HttpRequest $request)
|
||
{
|
||
$this->getActionPath($request);
|
||
$ref = $request->get('ref');
|
||
$this->addParameter('ref', $ref); // Добавляет параметр в url
|
||
$this->setTitlePath($ref);
|
||
|
||
$model = $this->getModel($this->useModel);
|
||
$form = new TForm(); // Показываем форму
|
||
$form->header = 'Редактирование записи';
|
||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
||
|
||
$list = $request->get('table_item');
|
||
$id = ($list[0]) ? $list[0] : $request->get('id');
|
||
|
||
$tpl = $this->formPage ($form, $request);
|
||
if ($id) { // Редактирование
|
||
$form->action = forceUrl($this->nUrl('add', array('id' => $id, 'page' => $this->getPageId($request)))); // action Свойство формы
|
||
$item = $model->findById($id);
|
||
// Загрузка формы
|
||
$this->beforeLoad($item, $form);
|
||
///
|
||
}
|
||
return $tpl;
|
||
}
|
||
|
||
/**
|
||
*/
|
||
function tableSetup($table, $id = null, $ref = null)
|
||
{
|
||
// FIXME: После замены везде $tableSchema -> table->setHeader удалить!
|
||
if ($this->tableSchema) {
|
||
$table->setHeader($this->tableSchema);
|
||
} else {
|
||
// Настройка таблицы отображения по схеме данных
|
||
require_once 'core/mapper/uimapper.php';
|
||
$model = $this->getModel($this->useModel);
|
||
$ui = new UIMapper($model);
|
||
$schema = $ui->getTableSchema();
|
||
$schema[0]['action'] = $table->getFirstItem();
|
||
|
||
$table->setHeader($schema);
|
||
}
|
||
}
|
||
|
||
/**
|
||
*/
|
||
public function actionIndex(HttpRequest $request)
|
||
{
|
||
$this->getActionPath($request, 'index');
|
||
// Такое мета действие наверное можно вынести в отдельный класс
|
||
return $this->metaActionIndex($request, array($this, 'tableSetup'), $this->aUrl('list'));
|
||
}
|
||
|
||
/**
|
||
* Страница по умолчанию
|
||
*/
|
||
public function metaActionIndex(HttpRequest $request, $setup, $list)
|
||
{
|
||
// может быть одно ref или несколько
|
||
// {{{ история переходов
|
||
$ref = null;
|
||
if ($request->get('ref')) {
|
||
$ref = $request->get('ref');
|
||
} else if ($request->session()->get('ref')) {
|
||
$ref = $request->session()->get('ref');
|
||
}
|
||
|
||
$request->session->set('ref', $ref);
|
||
$this->addParameter('ref', $ref);
|
||
// }}}
|
||
$this->setTitlePath($ref);
|
||
|
||
$tpl = $this->getView('list');
|
||
|
||
// Помошники действий
|
||
$this->callHelpers($request);
|
||
// Таблица
|
||
if ($request->session()->get(strtolower(get_class($this)))) {
|
||
$session = $request->session()->get(strtolower(get_class($this)));
|
||
if (isset($session['view'])) {
|
||
$this->table->setView($session['view']);
|
||
}
|
||
$this->table->setData('state', array(
|
||
'page' => $session['page'],
|
||
'size' => $session['size'],
|
||
'desc' => $session['desc']));
|
||
|
||
$this->table->setData('sorter', $session['key']);
|
||
if (isset($session['desc'])) {
|
||
$this->table->setData('desc', $session['desc']);
|
||
}
|
||
}
|
||
|
||
call_user_func($setup, $this->table, $request->get('id'), $ref);// --> Эквивалент formSetup
|
||
$this->table->setAction($list);
|
||
//
|
||
$tpl->menu_path = $this->path->getItems();
|
||
|
||
// Поиск
|
||
$search = new SearchDialog();
|
||
$search->setTitle('Поиск');
|
||
$search->setAction($this->aUrl('search'));
|
||
$search->setFriend($this->table);
|
||
$search->addFields($this->schemaSearch);
|
||
|
||
// Настройки
|
||
$setup = new SetupDialog();
|
||
$setup->setTitle('Настройки');
|
||
$setup->setAction($this->nUrl('setup'));
|
||
$setup->setFriend($this->table);
|
||
|
||
// Меню
|
||
$this->menu->addMenuItem('?menu=toggle&id=' . $search->getName(), 'поиск', 'actions/system-search'); // Стандартный размер для иконок 22-24px
|
||
$this->menu->addMenuItem('?menu=toggle&id=' . $setup->getName(), 'настройки', 'categories/applications-system');
|
||
// Добавление компонентов
|
||
$this->addChild('menu', $this->menu);
|
||
$this->addChild('search', $search);
|
||
$this->addChild('setup', $setup);
|
||
$this->addChild('table', $this->table);
|
||
//
|
||
return $tpl;
|
||
}
|
||
|
||
/**
|
||
*/
|
||
public function actionSetup($request)
|
||
{
|
||
$left = explode(",", $request->get('left'));
|
||
$right = explode(",", $request->get('right'));
|
||
|
||
$$request->session()->set(strtolower(get_class($this)),
|
||
array('view' => array('left' => $left, 'right' => $right)));
|
||
|
||
return $this->forward('actionIndex', $request);
|
||
}
|
||
|
||
/**
|
||
*/
|
||
private function formPage($form, $request)
|
||
{
|
||
$view = $this->getView('form');
|
||
$view->setView('form', $form);
|
||
$view->action = forceUrl($this->nUrl('add', array('page' => $this->getPageId($request)))); // Действие для формы
|
||
|
||
$view->menu_path = $this->path->getItems();
|
||
$view->back = $this->path->getPrev();
|
||
return $view;
|
||
}
|
||
|
||
// Тоже убрать в метод Controller_Model
|
||
function getActionPath(HttpRequest $request/*, $action = false*/)
|
||
{
|
||
require_once 'state.php';
|
||
$this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
|
||
}
|
||
}
|