-- FileCopyCommand::EXECUTE --
Warning: copy(test) [function.copy]: failed to open stream: No such file or directory in /kunden/145289_55118/code/php/zend/patterns/history.php on line 85
-- FileCopyCommand::UNDO --
Warning: unlink(test.tmp) [function.unlink]: No such file or directory in /kunden/145289_55118/code/php/zend/patterns/history.php on line 73
SUCCESS: Undo, -- FileCopyCommand::REDO --
-- FileCopyCommand::EXECUTE --
Warning: copy(test) [function.copy]: failed to open stream: No such file or directory in /kunden/145289_55118/code/php/zend/patterns/history.php on line 85
<?php
/*
draft and caseStudy history class
Alternatives:
http://c2.com/cgi/wiki?MementoPattern
visitor pattern
credit: "do, undo, redo pattern"
http://www.michaelmcgrady.com/do_undo.jsp
*/
define ('NEW_LINE', '<br/>');
//------------------------------------------------------------
// Command Pattern
//------------------------------------------------------------
class Command
{
function add($cmd)
{
$this->_commands[] = $cmd;
}
function undo()
{
$this->history->undoCommand();
}
function redo()
{
$this->history->redoCommand();
}
function run()
{
// history executes and adds Command to History
foreach ($this->_commands as $cmd) {
$this->history->inVoke($cmd);
}
}
function Command($history)
{
$this->history = $history;
}
};
//------------------------------------------------------------
/*
interface ICommand {
function execute () {}
function undoCommand () {}
function redoCommand () {}
};
*/
class FileCopyCommand // implements ICommand
{
var $src = 'test';
var $target = 'test.tmp';
function undoCommand()
{
echo '-- FileCopyCommand::UNDO --'.NEW_LINE;
unlink($this->target);
}
function redoCommand()
{
echo '-- FileCopyCommand::REDO --'.NEW_LINE;
$this->execute();
}
function execute ()
{
echo '-- FileCopyCommand::EXECUTE --'.NEW_LINE;
copy($this->src, $this->target);
}
};
//------------------------------------------------------------
// History Pattern
//------------------------------------------------------------
class History
{
var $maxHistory = 2;
var $redoList = array();
var $undoList = array();
function inVoke($cmd)
{
$cmd->execute();
$this->addToHistory($cmd);
}
function undoCommand()
{
if (sizeof($this->undoList) > 0) {
// echo '--UNDO--';
$undoCommand = $this->removeFirst($this->undoList);
$undoCommand->undoCommand();
$this->addFirst($undoCommand, $this->redoList);
}
}
function redoCommand()
{
if (sizeof($this->redoList) > 0) {
// echo '--REDO--';
$redoCommand = $this->removeFirst($this->redoList);
$redoCommand->redoCommand();
$this->addToHistory($redoCommand);
}
}
function addToRedoList($cmd)
{
$this->addFirst($cmd, $this->redoList);
if (sizeof($this->history) > $this->maxHistory) {
$this->removeLast($this->redoList);
}
}
function addToHistory($cmd)
{
$this->addFirst($cmd, $this->undoList);
if (sizeof($this->undoList) > $this->maxHistory) {
$this->removeLast($this->undoList);
}
}
function addFirst($cmd, &$history)
{
array_unshift($history, $cmd);
// var_dump($this->undoList);
}
function removeLast(&$history)
{
array_pop($history);
}
function removeFirst(&$history)
{
$cmd = array_shift($history);
return $cmd;
}
};
//------------------------------------------------------------
// Test
//------------------------------------------------------------
// command need to know history
$history = new History();
$cmd = new Command($history);
$cmd->add(new FileCopyCommand);
//------------------------------------------------------------
$cmd->run();
if (file_exists('test.tmp')) {
echo 'SUCCESS: Command, ';
}
//------------------------------------------------------------
// $history->undoCommand();
$cmd->undo();
if (!file_exists('test.tmp')) {
echo 'SUCCESS: Undo, ';
}
//------------------------------------------------------------
$cmd->redo();
if (file_exists('test.tmp')) {
echo 'SUCCESS: Redo. :-) ';
}
//------------------------------------------------------------
show_source(__FILE__);
?>