-- 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__);
?>