phplibrary/src/Controller/Model.php

520 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Переименовать контроллер !! (StubController, CrudController, PageController, BaseController) ModelController
* Возможно нужен еще класс с мета действиями как для actionIndex <= metaActionIndex либо с классам для этих действий
* Есть класс для управлениями действиями а есть сами действия в виде классов или функций !!
*
* @class Controller_Model в котором определены основные действия для редактирования, вывода списка, сохранения, поиска и т.д
* В модуле определяется только способ отображения этих данных
*/
class Controller_Model extends Controller_Action
{
public /*.array.*/$schema = array();
public /*.array.*/$schemaSearch = array();
/**
* FIXME: Лучше $this->table->setHeader
*/
public $tableSchema = null;
public /*.array.*/$formSchema = array();
public $menu;
public $table;
protected /*.string.*/$useModel;
protected /*.string.*/$itemModel;
public function __construct()
{
parent::__construct();
$this->menu = new Widgets_PageMenu();
$this->table = new Widgets_ReactListTable();
}
/**
*/
function setUp() {
parent::setUp();
$this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'btn-danger', 'remove');
}
function saveParameters(HttpRequest $args, $list) {
foreach ($list as $item) {
$args->session()->set(array($this, $item), $args->get($item));
}
}
protected function getJSONList(/*.Model_Mapper.*/ $model, HttpRequest $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);
}
protected function getCSV(Model_Mapper $model, HttpRequest $request, $title) {
$ref = $request->get('ref');
$list = $model->findAll($request, $request->get('ref'));
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$title.'.csv');
echo "\xEF\xBB\xBF"; //UTF-8 BOM.
$output = fopen('php://output', 'w');
if (is_resource($output)) {
foreach ($list as $row) {
fputcsv($output, (array)$row,';');
}
}
}
/**
* Удаление строк из таблицы
*/
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);
return json_encode(array('result' => 'ok'));
}
/**
* Ответ на запрос по поиску
*/
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);
if ($request->get('filter')) {
$data = new Collection();
$data->import($request->get('filter'));
$model->addFilter($model->requestToSQL($data, $this->formSchema));
}
return $this->getJSONList($model, $request);
}
public function actionCSV(HttpRequest $request)
{
$model = $this->getModel($this->useModel);
$title = $request->get("title");
if(!$title){
$title = "noname";
}
return $this->getCSV($model, $request, $title);
}
private function setFormSchema()
{
$model = $this->getModel($this->useModel);
$ui = new Model_UIMapper($model);
$this->formSchema = $ui->getFormSchema();
}
/**
* Сохранение формы
*/
function beforeSave(/*Model*/ $item, HttpRequest $request)
{
if (empty($this->formSchema)) {
$this->setFormSchema();
}
// Сделать отображение Формы в обьект и обратно
foreach ($this->formSchema as $key => $conv) {
list($value, $type) = $conv;
$item->$value = call_user_func(array('Primitive', 'to_' . $type), $request->get($key)); // Здесь нужно преобразовывать тип значения
}
}
/**
* Обновление формы
*/
function formUpdate(Form_Form $form, HttpRequest $request) {
$form->setValues($request);
}
/**
* Загрузка формы
*/
function beforeLoad(/*.Model_Model.*/$item, Form_Form $form)
{
if (empty($this->formSchema)) {
$this->setFormSchema();
}
// Вставка значений из данных в форму
// Отображение обьекта в поля формы
$form->fill($item, $this->formSchema);
}
function beforeFirstLoad(Form_Form $form)
{
}
// Проверка ввода
protected function validate(Validator_Validator $validator, Collection $request)
{
}
/**
* Действие для проверки формы
*/
public function actionValidate($request)
{
$validator = new Validator_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_Form $form, $id = null, $ref = null)
{
if (empty($this->schema)) {
$model = $this->getModel($this->useModel);
$ui = new Model_UIMapper($model);
$schema = $ui->getEditSchema();
$form->addFieldList($schema);
} else {
$form->addFieldList($this->schema);
}
}
/**
* Добавление
*/
public function actionAdd(HttpRequest $request)
{
// {{{ тоже может быть один ref или несколько
$ref = $request->get('ref');
$this->addParameter('ref', $ref); // Добавляет параметр в url
/// }}}
// Проверка
$validator = new Validator_Validator();
$validator->addRuleList($this->schema);
// Действия до проверки формы
$this->validate($validator, $request); // <--|
$validator->validate($request); // --|
// Проверка формы
if (!$validator->isValid()) {
return json_encode(array('result'=>'fail','errors'=>$validator->getErrorMsg()));
}
// Нужен тест для формы
$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 ??? или выход или новая форма для создания новости
$id = $model->saveDB($item, $request);
// Для страницы со списком id -> идентификатор родительской таблицы !!??
// $request->set('id', $request->get('ref'));
if ($request->get('apply')) {
$request->setAction('form');
return (string) $this->forward('actionForm', $request);
}
//$request->setAction('index');
$result = array('result'=>'ok');
if($id){
$result['action'] = forceUrl($this->nUrl('add', array('id' => $id, 'ref' => $request->get('ref'))));
}
return json_encode($result);
}
/**
* Заголовок
*/
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 Form_Form(); // Показываем форму
$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);
}else{//Создание нового элемента
$this->beforeFirstLoad($form);
}
return json_encode($tpl);
}
/**
*/
function tableSetup(Widgets_ListTable $table, $id = null, $ref = null)
{
// FIXME: После замены везде $tableSchema -> table->setHeader удалить!
if ($this->tableSchema) {
$table->setHeader($this->tableSchema);
} else {
// Настройка таблицы отображения по схеме данных
$model = $this->getModel($this->useModel);
$ui = new Model_UIMapper($model);
$ui->hidden = $table->hidden;
$schema = $ui->getTableSchema();
$schema[0]['action'] = forceUrl($table->getFirstItem());
$table->setHeader($schema);
}
}
/**
*/
public function actionDefault(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 = new stdClass();
// Помощники действий
$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);
if (!$this->table->getData('module')) {
$this->table->setData('module', strtolower($this->useModel));
}
$tpl->menu_path = $this->path->getItems();
$this->table->makeData();
$tpl->table = array('data' => $this->table->data);
$tpl->menu = $this->menu->menu->getItems();
$tpl->path = $this->path->getItems();
return json_encode($tpl);
}
/**
*/
public function actionSetup(HttpRequest $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), 'page' => 1, 'size' => 0, 'desc' => 'asc', 'key' => false));
return $this->forward('actionIndex', $request);
}
/**
*/
protected function formPage($form, $request, $template = 'form') {
$view = new stdClass();//$this->getView($template);
$view->form = $form;
$form->action = forceUrl($this->nUrl('add', array('page' => $this->getPageId($request)))); // Действие для формы
$view->path = $this->path->getItems();
$view->back = $this->path->getPrev();
return $view;
}
function _getActionPath() {
return new Controller_State('index');
}
// Тоже убрать в метод Controller_Model
function getActionPath(HttpRequest $request, $action = null) {
$this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
}
function parse_params($expression) {
$expression = htmlspecialchars_decode($expression);
$offset = strpos($expression, '?');
$url = parse_url($expression);
$arguments = array();
if ($offset === false) {
$path = $expression;
} else if (is_int($offset)) {
$path = substr($expression, 0, $offset);
$query = substr($expression, $offset+1);
parse_str($query, $arguments);
}
return $arguments;
}
public function actionFormPage(HttpRequest $request) {
//$tpl = $this->getView('formpage', 'View_Top');
$view = $this->getView('formpage', 'View_Top');
$params = $this->parse_params($request->get('params'));
// $model = $this->getModel($this->useModel);
$form = new Form_Form(); // Показываем форму
$form->header = 'Редактирование записи';
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
/*
$ui = new Model_UIMapper($model);
$schema = $ui->getEditSchema();
$form->addFieldList($schema);
*/
$list = $request->get('table_item');
$id = ($list[0]) ? $list[0] : $request->get('id');
// $tpl = $this->formPage($form, $request);
$view->setView('form', $form);
$view->action = forceUrl($this->nUrl('addpage', array('ref' => $params['id']))); // Действие для формы
// $view->menu_path = $this->path->getItems();
$view->back = '';
return $view;
// return $tpl;
}
/* Для поддержки редактрования на сайте */
public function actionAddPage(HttpRequest $request)
{
// {{{ тоже может быть один ref или несколько
$ref = $request->get('ref');
$this->addParameter('ref', $ref); // Добавляет параметр в url
/// }}}
$validator = new Validator_Validator();
$validator->addRuleList($this->schema);
// Действия до проверки формы
$this->validate($validator, $request); // <--|
$validator->validate($request); // --|
// Проверка формы
if (!$validator->isValid()) {
return $validator;
}
// Нужен тест для формы
$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); // Сюдаже и истрия переходов
$model->saveDB($item, $request);
return null;
}
}