Index: branches/FileBackend/phase3/includes/filerepo/FileBackend.php |
— | — | @@ -69,34 +69,75 @@ |
70 | 70 | * @param Array $ops - Array of arrays containing N operations to execute IN ORDER |
71 | 71 | * @return Status |
72 | 72 | */ |
73 | | - public function doOps($ops) { |
| 73 | + public function doOps( $ops, $reversed = 0 ) { |
74 | 74 | if(!is_array($ops)) { |
75 | 75 | throw new MWException(__METHOD__ . " not provided with an operations array"); |
76 | 76 | } |
77 | 77 | |
78 | 78 | $statusObject = ''; // some sort of status object that can hold other status objects |
79 | 79 | |
80 | | - foreach($ops AS $op) { |
81 | | - switch ($op['operation']) { |
| 80 | + foreach( $ops AS $i => $op ) { |
| 81 | + switch ( $op['operation'] ) { |
82 | 82 | case 'move': |
83 | | - $statusObject->append($this->commonCaller('move', $op)); |
| 83 | + $st = $this->commonCaller('move', $op); |
84 | 84 | break; |
85 | 85 | case 'delete': |
86 | | - $statusObject->append($this->commonCaller('delete', $op)); |
| 86 | + $st = $this->commonCaller('delete', $op); |
87 | 87 | break; |
88 | 88 | case 'copy': |
89 | | - $statusObject->append($this->copy()); |
| 89 | + $st = $this->copy(); |
90 | 90 | break; |
91 | 91 | case 'getFileProps': |
92 | 92 | $tmpFile = $this->getLocalCopy(); |
93 | | - $statusObject->append($this->getFileProps($tmpFile)); |
| 93 | + $st = $this->getFileProps( $tmpFile ); |
94 | 94 | default: |
95 | | - $statusObject->append('Unknown data store operation ' . $op['operation']); |
96 | | - |
| 95 | + $st = 'Unknown data store operation ' . $op['operation']); |
97 | 96 | } |
98 | | - } |
| 97 | + $statusObject->append( $st ); |
| 98 | + if ( $st && $reversed) { |
| 99 | + // oh noes! Something went wrong AGAIN. |
| 100 | + // pray to gods. |
| 101 | + return 'STATUS OBJECT'; |
| 102 | + elseif ( $st ) { |
| 103 | + // oh crap, something went wrong. Try to unwind. |
| 104 | + return $this->doOps( $this->unwind( $ops, $i ), 1); |
| 105 | + } |
| 106 | + } |
99 | 107 | |
100 | | - return 'STATUS OBJECT'; |
| 108 | + return 'STATUS OBJECT'; |
| 109 | + } |
| 110 | + |
| 111 | + /** |
| 112 | + * Unwinds an array of operations, attempting to reverse their action. |
| 113 | + * @param Array $ops - Array of arrays containing N operations to execute IN ORDER |
| 114 | + * @param Integer $i - index of first operation that failed. |
| 115 | + * @return Array |
| 116 | + */ |
| 117 | + protected function unwind( $ops, $i ) { |
| 118 | + $outops = array(); |
| 119 | + |
| 120 | + foreach( $ops AS $k => $op ) { |
| 121 | + $newop = null; |
| 122 | + switch ( $op['operation'] ) { |
| 123 | + case 'move': |
| 124 | + $newop = $op; |
| 125 | + $newop['source'] = $op['source']; |
| 126 | + $newop['dest'] = $op['dest']; |
| 127 | + break; |
| 128 | + case 'delete': |
| 129 | + // sigh. |
| 130 | + break; |
| 131 | + case 'copy': |
| 132 | + $newop = $op; |
| 133 | + $newop['operation'] = 'delete'; |
| 134 | + $newop['source'] = $op['dest']; |
| 135 | + break; |
| 136 | + } |
| 137 | + if ($newop) { |
| 138 | + array_unshift($outops, $newop); |
| 139 | + } |
| 140 | + } |
| 141 | + return $outops; |
101 | 142 | } |
102 | 143 | |
103 | 144 | /** |
— | — | @@ -219,7 +260,7 @@ |
220 | 261 | // * Please overload this class inside your storage module |
221 | 262 | // * |
222 | 263 | // * @param String $file - Name of file to retreive thumbnail listing for |
223 | | -// * @retrun Array |
| 264 | +// * @return Array |
224 | 265 | // */ |
225 | 266 | // abstract function getThumbnailList( $file ); |
226 | 267 | // |
— | — | @@ -229,4 +270,44 @@ |
230 | 271 | // public function concatenateChunks() { throw new MWException( __METHOD__ . ' not yet implemented.' ); } |
231 | 272 | |
232 | 273 | |
233 | | -} // end class |
\ No newline at end of file |
| 274 | +} // end class |
| 275 | + |
| 276 | + |
| 277 | +/** |
| 278 | + * A helper class for FileBackend. Some filestores won't have files in the filesystem, |
| 279 | + * so we can't count on being able to hand out the filename. Instead, we hand out an |
| 280 | + * instance of this class, which will DTRT for all filestores. |
| 281 | + */ |
| 282 | +class TempLocalFile { |
| 283 | + |
| 284 | + /** |
| 285 | + * @param String $file - mwrepo:// url for the file to hand out. |
| 286 | + */ |
| 287 | + public function __construct( $file ) { |
| 288 | + $this->tempPath = $file; |
| 289 | + } |
| 290 | + |
| 291 | + /** |
| 292 | + * Returns a file path pointing to our file or a copy thereof. |
| 293 | + * @return String |
| 294 | + */ |
| 295 | + public function path() { |
| 296 | + return $this->tempPath; |
| 297 | + } |
| 298 | + |
| 299 | + /** |
| 300 | + * we don't have a close() method. Just let the instance go out of scope. |
| 301 | + */ |
| 302 | + |
| 303 | + /** |
| 304 | + * if we need to delete the file, do so now. |
| 305 | + */ |
| 306 | + public function __destruct() { |
| 307 | + if ( $this->tempPath ) { |
| 308 | + // Clean up temporary data. |
| 309 | + // Only if we actually made a local copy!! unlink( $this->tempPath ); |
| 310 | + $this->tempPath = null; |
| 311 | + } |
| 312 | + } |
| 313 | + |
| 314 | +} // end class |