00001 <?php
00002 require_once dirname(__FILE__) . '/commandbase.cls.php';
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 class CommandComposite extends CommandBase {
00015 protected $commands = array();
00016
00017
00018
00019
00020 public function append($command) {
00021 if ($command instanceof ICommand) {
00022 $this->commands[] = $command;
00023 }
00024 }
00025
00026
00027
00028
00029 public function append_array($commands) {
00030 if (is_array($commands)) {
00031 foreach($commands as $command) {
00032 $this->append($command);
00033 }
00034 }
00035 }
00036
00037
00038
00039
00040 public function can_execute($user) {
00041 $ret = $this->do_can_execute($user);
00042 if ($ret) {
00043 foreach($this->commands as $command) {
00044 if (!$command->can_execute($user)) {
00045 return false;
00046 }
00047 }
00048 }
00049 return $ret;
00050 }
00051
00052
00053
00054
00055 public function execute() {
00056 $ret = new Status();
00057 $arr_executed = array();
00058 DB::start_trans();
00059 try {
00060 $ret = $this->do_execute();
00061 if ($ret->is_ok()) {
00062 foreach($this->commands as $command) {
00063 $ret->merge($command->execute());
00064 if ($ret->is_error()) {
00065
00066 break;
00067 }
00068 $arr_executed[] = $command;
00069 }
00070 }
00071 }
00072 catch (Exception $ex) {
00073 $ret->merge($ex);
00074 }
00075
00076 if ($ret->is_error()) {
00077 $this->undo_on_chain($arr_executed);
00078 $this->undo();
00079 }
00080 DB::end_trans($ret);
00081 return $ret;
00082 }
00083
00084
00085
00086
00087 public function undo() {
00088 $this->do_undo();
00089 $this->undo_on_chain($this->commands);
00090 }
00091
00092
00093
00094
00095 protected function undo_on_chain($commands) {
00096
00097 $cnt = count($commands);
00098 for ($i = $cnt - 1; $i >= 0; $i--) {
00099 $commands[$i]->undo();
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108 protected function do_can_execute($user) {
00109 return parent::can_execute($user);
00110 }
00111
00112
00113
00114
00115
00116
00117 protected function do_execute() {
00118 return parent::execute();
00119 }
00120
00121
00122
00123
00124 protected function do_undo() {
00125 parent::undo();
00126 }
00127 }