Index: branches/new-upload/phase3/includes/filerepo/FSRepo.php |
— | — | @@ -213,17 +213,28 @@ |
214 | 214 | } |
215 | 215 | function append( $srcPath, $toAppendPath ){ |
216 | 216 | $status = $this->newGood(); |
| 217 | + |
| 218 | + //resolve the virtual url: |
| 219 | + if ( self::isVirtualUrl( $srcPath ) ) { |
| 220 | + $srcPath = $this->resolveVirtualUrl( $srcPath ); |
| 221 | + } |
217 | 222 | //make sure files are there: |
218 | 223 | if ( !is_file( $srcPath ) ) |
219 | | - $status->fatal( 'filenotfound', $srcPath ); |
| 224 | + $status->fatal( 'append-src-filenotfound', $srcPath ); |
220 | 225 | |
221 | 226 | if ( !is_file( $toAppendPath ) ) |
222 | | - $status->fatal( 'filenotfound', $toAppendPath ); |
| 227 | + $status->fatal( 'append-toappend-filenotfound', $toAppendPath ); |
223 | 228 | |
224 | 229 | //do the append: |
225 | | - if( ! file_put_contents( $srcPath, file_get_contents( $toAppendPath ), FILE_APPEND ) ) |
| 230 | + if( file_put_contents( $srcPath, file_get_contents( $toAppendPath ), FILE_APPEND ) ){ |
| 231 | + $status->value = $srcPath; |
| 232 | + }else{ |
226 | 233 | $status->fatal( 'fileappenderror', $toAppendPath, $srcPath); |
227 | | - |
| 234 | + } |
| 235 | + |
| 236 | + //either way remove the append chunk as we have no use for it now: |
| 237 | + unlink($toAppendPath); |
| 238 | + |
228 | 239 | return $status; |
229 | 240 | } |
230 | 241 | /** |
— | — | @@ -257,12 +268,6 @@ |
258 | 269 | $result->value = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; |
259 | 270 | return $result; |
260 | 271 | } |
261 | | - /*append to a temporary file (used in chunks uploads) */ |
262 | | - function appendToTemp( $srcPath, $appendDataPath ) { |
263 | | - //append to the "shared" temporary file |
264 | | - $result = $this->append( $srcPath, $appendDataPath ); |
265 | | - return $result; |
266 | | - } |
267 | 272 | |
268 | 273 | /** |
269 | 274 | * Remove a temporary file or mark it for garbage collection |
Index: branches/new-upload/phase3/includes/UploadBase.php |
— | — | @@ -101,7 +101,7 @@ |
102 | 102 | return self::OK; |
103 | 103 | } |
104 | 104 | //return the file size |
105 | | - function isEmptyFile(){ |
| 105 | + function isEmptyFile(){ |
106 | 106 | return empty( $this->mFileSize); |
107 | 107 | } |
108 | 108 | /** |
— | — | @@ -161,13 +161,14 @@ |
162 | 162 | /** |
163 | 163 | * Verifies that it's ok to include the uploaded file |
164 | 164 | * |
| 165 | + * this function seems to intermixes tmpfile and $this->mTempPath .. no idea why this is |
| 166 | + * |
165 | 167 | * @param string $tmpfile the full path of the temporary file to verify |
166 | 168 | * @return mixed true of the file is verified, a string or array otherwise. |
167 | 169 | */ |
168 | 170 | protected function verifyFile( $tmpfile ) { |
169 | | - $this->mFileProps = File::getPropsFromPath( $this->mTempPath, |
170 | | - $this->mFinalExtension ); |
171 | | - $this->checkMacBinary(); |
| 171 | + $this->mFileProps = File::getPropsFromPath( $this->mTempPath, $this->mFinalExtension ); |
| 172 | + $this->checkMacBinary( ); |
172 | 173 | |
173 | 174 | #magically determine mime type |
174 | 175 | $magic = MimeMagic::singleton(); |
— | — | @@ -209,8 +210,7 @@ |
210 | 211 | $virus = $this->detectVirus($tmpfile); |
211 | 212 | if ( $virus ) { |
212 | 213 | return array( 'uploadvirus', $virus ); |
213 | | - } |
214 | | - |
| 214 | + } |
215 | 215 | wfDebug( __METHOD__.": all clear; passing.\n" ); |
216 | 216 | return true; |
217 | 217 | } |
Index: branches/new-upload/phase3/includes/api/ApiUpload.php |
— | — | @@ -121,8 +121,7 @@ |
122 | 122 | $result['result'] = 'Failure'; |
123 | 123 | $result['error'] = 'permission-denied'; |
124 | 124 | return $result; |
125 | | - } |
126 | | - |
| 125 | + } |
127 | 126 | $verification = $this->mUpload->verifyUpload( $resultDetails ); |
128 | 127 | if( $verification != UploadBase::OK ) { |
129 | 128 | $result['result'] = 'Failure'; |
— | — | @@ -167,7 +166,7 @@ |
168 | 167 | break; |
169 | 168 | } |
170 | 169 | return $result; |
171 | | - } |
| 170 | + } |
172 | 171 | if( !$this->mParams['ignorewarnings'] ) { |
173 | 172 | $warnings = $this->mUpload->checkWarnings(); |
174 | 173 | if( $warnings ) { |
— | — | @@ -183,7 +182,7 @@ |
184 | 183 | $result['sessionkey'] = $sessionKey; |
185 | 184 | return $result; |
186 | 185 | } |
187 | | - } |
| 186 | + } |
188 | 187 | //do the upload |
189 | 188 | $status = $this->mUpload->performUpload( $this->mParams['comment'], |
190 | 189 | $this->mParams['comment'], $this->mParams['watch'], $wgUser ); |
Index: branches/new-upload/phase3/includes/UploadFromChunks.php |
— | — | @@ -26,18 +26,20 @@ |
27 | 27 | $this->chunk_mode = UploadFromChunks::INIT; |
28 | 28 | $this->mDesiredDestName = $param['filename']; |
29 | 29 | |
30 | | - }else if( $this->mSessionKey && !$param['done']){ |
| 30 | + }else if( $this->mSessionKey && !$param['done']){ |
31 | 31 | //this is a chunk piece |
32 | | - $this->chunk_mode = UploadFromChunks::CHUNK; |
33 | | - |
34 | | - //set chunk related vars: |
35 | | - $this->mTempPath = $request->getFileTempName( 'chunk' ); |
36 | | - $this->mFileSize = $request->getFileSize( 'chunk' ); |
37 | | - |
38 | | - }else if( $this->mSessionKey && $param['done']){ |
| 32 | + $this->chunk_mode = UploadFromChunks::CHUNK; |
| 33 | + }else if( $this->mSessionKey && $param['done']){ |
39 | 34 | //this is the last chunk |
40 | | - $this->chunk_mode = UploadFromChunks::DONE; |
| 35 | + $this->chunk_mode = UploadFromChunks::DONE; |
41 | 36 | } |
| 37 | + if( $this->chunk_mode == UploadFromChunks::CHUNK || |
| 38 | + $this->chunk_mode == UploadFromChunks::DONE ){ |
| 39 | + //set chunk related vars: |
| 40 | + $this->mTempPath = $request->getFileTempName( 'chunk' ); |
| 41 | + $this->mFileSize = $request->getFileSize( 'chunk' ); |
| 42 | + } |
| 43 | + |
42 | 44 | return $this->status; |
43 | 45 | } |
44 | 46 | |
— | — | @@ -97,15 +99,29 @@ |
98 | 100 | } |
99 | 101 | //only run verifyFile on completed uploaded chunks |
100 | 102 | function verifyFile( $tmpFile ){ |
101 | | - if( $this->chunk_mode == UploadFromChunks::DONE){ |
102 | | - return parent::verifyFile($tmpFile); |
| 103 | + if( $this->chunk_mode == UploadFromChunks::DONE ){ |
| 104 | + //first append last chunk (so we can do a real verifyFile check... (check file type etc) |
| 105 | + $status = $this->doChunkAppend(); |
| 106 | + if( $status->isOK() ){ |
| 107 | + $this->mTempPath = $this->getRealPath( $this->mTempAppendPath ); |
| 108 | + //verify the completed merged chunks as if it was the file that got uploaded: |
| 109 | + return parent::verifyFile( $this->mTempPath ) ; |
| 110 | + }else{ |
| 111 | + //conflict of status returns (have to return the error ary) ... why we don't consistantly use a status object is beyond me.. |
| 112 | + return $status->getErrorsArray(); |
| 113 | + } |
103 | 114 | }else{ |
104 | 115 | return true; |
105 | 116 | } |
| 117 | + } |
| 118 | + function getRealPath($srcPath){ |
| 119 | + $repo = RepoGroup::singleton()->getLocalRepo(); |
| 120 | + if ( $repo->isVirtualUrl( $srcPath) ) { |
| 121 | + return $repo->resolveVirtualUrl( $srcPath ); |
| 122 | + } |
106 | 123 | } |
107 | 124 | function setupChunkSession( $comment, $watch ) { |
108 | | - $this->mSessionKey = $this->getSessionKey(); |
109 | | - |
| 125 | + $this->mSessionKey = $this->getSessionKey(); |
110 | 126 | $_SESSION['wsUploadData'][ $this->mSessionKey ] = array( |
111 | 127 | 'mComment' => $comment, |
112 | 128 | 'mWatch' => $watch, |
— | — | @@ -114,10 +130,8 @@ |
115 | 131 | 'mDesiredDestName' => $this->mDesiredDestName, |
116 | 132 | 'version' => self::SESSION_VERSION, |
117 | 133 | ); |
118 | | - |
119 | 134 | return $this->mSessionKey; |
120 | | - } |
121 | | - |
| 135 | + } |
122 | 136 | //lets us return an api result (as flow for chunk uploads is kind of different than others. |
123 | 137 | function performUpload($summary='', $comment='', $watch='', $user){ |
124 | 138 | global $wgServer, $wgScriptPath; |
— | — | @@ -145,7 +159,11 @@ |
146 | 160 | //firefogg expects a specific result per: |
147 | 161 | //http://www.firefogg.org/dev/chunk_post.html |
148 | 162 | ob_clean(); |
149 | | - echo ApiFormatJson::getJsonEncode( array("result"=>1) ); |
| 163 | + echo ApiFormatJson::getJsonEncode( array( |
| 164 | + "result"=>1, |
| 165 | + "filesize"=> filesize( $this->getRealPath( $this->mTempAppendPath ) ) |
| 166 | + ) |
| 167 | + ); |
150 | 168 | exit(0); |
151 | 169 | /*return array( |
152 | 170 | 'result' => 1 |
— | — | @@ -153,14 +171,23 @@ |
154 | 172 | }else{ |
155 | 173 | return $status; |
156 | 174 | } |
157 | | - }else if( $this->chunk_mode == UploadFromChunks::DONE ){ |
158 | | - //append the last chunk: |
159 | | - if( $this->doChunkAppend() ){ |
160 | | - //validate the uploaded file |
161 | | - |
162 | | - //process the upload normally: |
163 | | - return Status::newGood('chunk upload done'); |
164 | | - } |
| 175 | + }else if( $this->chunk_mode == UploadFromChunks::DONE ){ |
| 176 | + $status = parent::performUpload($summary='', $comment='',$watch='', $user ); |
| 177 | + if( !$status->isGood() ) { |
| 178 | + return $status; |
| 179 | + } |
| 180 | + $file = $this->getLocalFile(); |
| 181 | + //firefogg expects a specific result per: |
| 182 | + //http://www.firefogg.org/dev/chunk_post.html |
| 183 | + ob_clean(); |
| 184 | + echo ApiFormatJson::getJsonEncode( array( |
| 185 | + "result"=>1, |
| 186 | + "done"=>1, |
| 187 | + "resultUrl"=> $file->getDescriptionUrl() |
| 188 | + ) |
| 189 | + ); |
| 190 | + exit(0); |
| 191 | + |
165 | 192 | } |
166 | 193 | } |
167 | 194 | //append the given chunk to the temporary uploaded file. (if no temporary uploaded file exists created it. |
— | — | @@ -178,14 +205,12 @@ |
179 | 206 | } |
180 | 207 | return $status; |
181 | 208 | }else{ |
182 | | - //make sure the file exists: |
183 | | - if( is_file( $this->mTempAppendPath ) ){ |
184 | | - print "append: " . $this->mTempPath . ' to ' . $this->mTempAppendPath . "\n"; |
185 | | - $status = $this->appendToUploadFile( $this->mTempAppendPath, $this->mTempPath ); |
186 | | - return $status; |
| 209 | + if( is_file( $this->getRealPath( $this->mTempAppendPath ) ) ){ |
| 210 | + $status = $this->appendToUploadFile( $this->mTempAppendPath, $this->mTempPath ); |
187 | 211 | }else{ |
188 | | - return Status::newFatal('chunk-file-append-missing'); |
| 212 | + $status->fatal( 'filenotfound', $this->mTempAppendPath ); |
189 | 213 | } |
| 214 | + return $status; |
190 | 215 | } |
191 | 216 | } |
192 | 217 | } |