Я пытаюсь создать мастера форм в Кохане и немного учусь на ходу. Одна из вещей, которые я изучил, могла бы работать лучше всего - это использовать шаблон состояния в моей структуре классов для управления различными шагами, которые пользователь может выполнять во время процесса формы.
После некоторых исследований я подумал, что наилучшим подходом может быть использование интерфейса и выполнение всех шагов в качестве состояний, реализующих интерфейс. После проверки состояния оно изменит переменную сеанса на следующий шаг, который можно прочитать при начальной загрузке интерфейса и вызвать правильное состояние для использования.
Имеет ли этот подход смысл? Если да, то как, черт возьми, я это делаю (как мне лучше структурировать файловую систему?)
Вот грубое начало, над которым я работал:
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Project_Builder @state
* Step_One @state
* Step_Two @state
**/
interface Project_Builder
{
public function do_this_first();
public function validate();
public function do_this_after();
}
class Step_One implements Project_Builder {
public function __construct
{
parent::__construct();
// Do validation and set a partial variable if valid
}
public function do_this_first()
{
echo 'First thing done';
// This should be used to set the session step variable, validate and add project data, and return the new view body.
$session->set('step', '2');
}
public function do_this_after()
{
throw new LogicException('Have to do the other thing first!');
}
}
class Step_Two implements Project_Builder {
public function do_this_first()
{
throw new LogicException('Already did this first!');
}
public function do_this_after()
{
echo 'Did this after the first!';
return $this;
}
}
class Project implements Project_Builder {
protected $state;
protected $user_step;
protected $project_data
public function __construct()
{
// Check the SESSION for a "step" entry. If it does not find one, it creates it, and sets it to "1".
$session = Session::instance('database');
if ( ! $session->get('step'))
{
$session->set('step', '1');
}
// Get the step that was requested by the client.
$this->user_step = $this->request->param('param1');
// Validate that the step is authorized by the session.
if ($session->get('step') !== $this->user_step)
{
throw new HTTP_Exception_404('You cannot skip a step!');
}
// Check if there is user data posted, and if so, clean it.
if (HTTP_Request::POST == $this->request->method())
{
foreach ($this->request->post() as $name => $value)
{
$this->project_data["$name"] = HTML::chars($value);
}
}
// Trigger the proper state to use based on the authorized session step (should I do this?)
$this->state = new Step_One;
}
public function doThisFirst()
{
$this->state = $this->state->do_this_first();
}
public function doThisAfter()
{
$this->state = $this->state->do_this_after();
}
}
$project = new Project;
try
{
$project->do_this_after(); //throws exception
}
catch(LogicException $e)
{
echo $e->getMessage();
}
$project = new Project;
$project->do_this_first();
$project->validate();
$project->do_this_after();
//$project->update();