# CommandChain.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2006-2007 by Konstantin V. Arkhipov                     *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    00009  *                                                                         *
    00010  ***************************************************************************/
    00011
    00015     final class CommandChain implements EditorCommand
    00016     {
    00017         private $chain = array();
    00018
    00022         public static function create()
    00023         {
    00024             return new self;
    00025         }
    00026
    00030         public function add(EditorCommand $command)
    00031         {
    00032             $this->chain[] = $command;
    00033
    00034             return $this;
    00035         }
    00036
    00041         public function run(Prototyped $subject, Form $form, HttpRequest $request)
    00042         {
    00043             Assert::isTrue(
    00044                 ($size = count($this->chain)) > 0,
    00045
    00046                 'command chain is empty'
    00047             );
    00048
    00049             for ($i = 0; $i < $size; ++$i) {
    00050                 $command = &$this->chain[$i];
    00051
    00052                 try {
    00053                     $mav = $command->run($subject, $form, $request);
    00054
    00055                     if ($mav->getView() == EditorController::COMMAND_FAILED) {
    00056                         $this->rollback($i);
    00057                         return $mav;
    00058                     }
    00059                 } catch (BaseException $e) {
    00060                     $this->rollback($i);
    00061                     throw $e;
    00062                 }
    00063             }
    00064
    00065             return $mav;
    00066         }
    00067
    00071         private function rollback($position)
    00072         {
    00073             for ($i = $position; $i > -1; --$i) {
    00074                 if ($this->chain[$i] instanceof CarefulCommand) {
    00075                     try {
    00076                         $this->chain[$i]->rollback();
    00077                     } catch (BaseException $e) {
    00078                         // silently ignore, since no one
    00079                         // allowed to interrupt this proccess
    00080                     }
    00081                 }
    00082             }
    00083
    00084             return $this;
    00085         }
    00086
    00090         private function commit()
    00091         {
    00092             for ($size = count($this->chain), $i = 0; $i < $size; --$i) {
    00093                 if ($this->chain[$i] instanceof CarefulCommand)
    00094                     $this->chain[$i]->commit();
    00095             }
    00096
    00097             return $this;
    00098         }
    00099     }
    00100 ?>