Index: branches/FileBackend/phase3/img_auth.php |
— | — | @@ -74,9 +74,6 @@ |
75 | 75 | |
76 | 76 | // Get the local file repository |
77 | 77 | $repo = RepoGroup::singleton()->getRepo( 'local' ); |
78 | | - if ( !$repo ) { |
79 | | - return; // wtf? |
80 | | - } |
81 | 78 | |
82 | 79 | // Get the full file storage path and extract the source file name. |
83 | 80 | // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png). |
Index: branches/FileBackend/phase3/tests/phpunit/includes/parser/NewParserTest.php |
— | — | @@ -119,6 +119,7 @@ |
120 | 120 | } |
121 | 121 | |
122 | 122 | function addDBData() { |
| 123 | + $this->tablesUsed[] = 'image'; |
123 | 124 | # Hack: insert a few Wikipedia in-project interwiki prefixes, |
124 | 125 | # for testing inter-language links |
125 | 126 | $this->db->insert( 'interwiki', array( |
Index: branches/FileBackend/phase3/tests/phpunit/includes/media/GIFTest.php |
— | — | @@ -2,12 +2,22 @@ |
3 | 3 | class GIFHandlerTest extends MediaWikiTestCase { |
4 | 4 | |
5 | 5 | public function setUp() { |
6 | | - $this->filePath = dirname( __FILE__ ) . '/../../data/media/'; |
| 6 | + $this->filePath = dirname( __FILE__ ) . '/../../data/media'; |
| 7 | + $this->backend = new FSFileBackend( array( |
| 8 | + 'name' => 'localtesting', |
| 9 | + 'lockManager' => 'nullLockManager', |
| 10 | + 'containerPaths' => array( 'data' => $this->filePath ) |
| 11 | + ) ); |
| 12 | + $this->repo = new FSRepo( array( |
| 13 | + 'name' => 'temp', |
| 14 | + 'url' => 'http://localhost/thumbtest', |
| 15 | + 'backend' => $this->backend |
| 16 | + ) ); |
7 | 17 | $this->handler = new GIFHandler(); |
8 | 18 | } |
9 | 19 | |
10 | 20 | public function testInvalidFile() { |
11 | | - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); |
| 21 | + $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); |
12 | 22 | $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); |
13 | 23 | } |
14 | 24 | /** |
— | — | @@ -16,8 +26,7 @@ |
17 | 27 | * @dataProvider dataIsAnimated |
18 | 28 | */ |
19 | 29 | public function testIsAnimanted( $filename, $expected ) { |
20 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, |
21 | | - 'image/gif' ); |
| 30 | + $file = $this->dataFile( $filename, 'image/gif' ); |
22 | 31 | $actual = $this->handler->isAnimatedImage( $file ); |
23 | 32 | $this->assertEquals( $expected, $actual ); |
24 | 33 | } |
— | — | @@ -34,8 +43,7 @@ |
35 | 44 | * @dataProvider dataGetImageArea |
36 | 45 | */ |
37 | 46 | public function testGetImageArea( $filename, $expected ) { |
38 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, |
39 | | - 'image/gif' ); |
| 47 | + $file = $this->dataFile( $filename, 'image/gif' ); |
40 | 48 | $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); |
41 | 49 | $this->assertEquals( $expected, $actual ); |
42 | 50 | } |
— | — | @@ -71,15 +79,20 @@ |
72 | 80 | * @dataProvider dataGetMetadata |
73 | 81 | */ |
74 | 82 | public function testGetMetadata( $filename, $expected ) { |
75 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, |
76 | | - 'image/gif' ); |
77 | | - $actual = $this->handler->getMetadata( $file, $this->filePath . $filename ); |
| 83 | + $file = $this->dataFile( $filename, 'image/gif' ); |
| 84 | + $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); |
78 | 85 | $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); |
79 | 86 | } |
| 87 | + |
80 | 88 | public function dataGetMetadata() { |
81 | 89 | return array( |
82 | 90 | array( 'nonanimated.gif', 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}' ), |
83 | 91 | array( 'animated-xmp.gif', 'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}' ), |
84 | 92 | ); |
85 | 93 | } |
| 94 | + |
| 95 | + private function dataFile( $name, $type ) { |
| 96 | + return new UnregisteredLocalFile( false, $this->repo, |
| 97 | + "mwstore://localtesting/data/$name", $type ); |
| 98 | + } |
86 | 99 | } |
Index: branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php |
— | — | @@ -7,13 +7,19 @@ |
8 | 8 | |
9 | 9 | function setUp() { |
10 | 10 | parent::setUp(); |
11 | | - $this->filePath = dirname( __FILE__ ) . '/../../data/media/'; |
12 | 11 | $this->handler = new BitmapHandler(); |
13 | | - $this->repo = new FSRepo(array( |
14 | | - 'name' => 'temp', |
15 | | - 'directory' => wfTempDir() . '/exif-test-' . time() . '-' . mt_rand(), |
16 | | - 'url' => 'http://localhost/thumbtest' |
17 | | - )); |
| 12 | + $filePath = dirname( __FILE__ ) . '/../../data/media'; |
| 13 | + $tmpDir = wfTempDir() . '/exif-test-' . time() . '-' . mt_rand(); |
| 14 | + $this->backend = new FSFileBackend( array( |
| 15 | + 'name' => 'localtesting', |
| 16 | + 'lockManager' => 'nullLockManager', |
| 17 | + 'containerPaths' => array( 'images-thumb' => $tmpDir, 'data' => $filePath ) |
| 18 | + ) ); |
| 19 | + $this->repo = new FSRepo( array( |
| 20 | + 'name' => 'temp', |
| 21 | + 'url' => 'http://localhost/thumbtest', |
| 22 | + 'backend' => $this->backend |
| 23 | + ) ); |
18 | 24 | if ( !wfDl( 'exif' ) ) { |
19 | 25 | $this->markTestSkipped( "This test needs the exif extension." ); |
20 | 26 | } |
— | — | @@ -39,7 +45,7 @@ |
40 | 46 | if ( !BitmapHandler::canRotate() ) { |
41 | 47 | $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); |
42 | 48 | } |
43 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $name, $type ); |
| 49 | + $file = $this->dataFile( $name, $type ); |
44 | 50 | $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); |
45 | 51 | $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); |
46 | 52 | } |
— | — | @@ -66,13 +72,13 @@ |
67 | 73 | throw new MWException('bogus test data format ' . $size); |
68 | 74 | } |
69 | 75 | |
70 | | - $file = $this->localFile( $name, $type ); |
| 76 | + $file = $this->dataFile( $name, $type ); |
71 | 77 | $thumb = $file->transform( $params, File::RENDER_NOW ); |
72 | 78 | |
73 | 79 | $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); |
74 | 80 | $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); |
75 | 81 | |
76 | | - $gis = getimagesize( $thumb->getPath() ); |
| 82 | + $gis = getimagesize( $thumb->getLocalCopyPath() ); |
77 | 83 | if ($out[0] > $info['width']) { |
78 | 84 | // Physical image won't be scaled bigger than the original. |
79 | 85 | $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size"); |
— | — | @@ -84,8 +90,9 @@ |
85 | 91 | } |
86 | 92 | } |
87 | 93 | |
88 | | - private function localFile( $name, $type ) { |
89 | | - return new UnregisteredLocalFile( false, $this->repo, $this->filePath . $name, $type ); |
| 94 | + private function dataFile( $name, $type ) { |
| 95 | + return new UnregisteredLocalFile( false, $this->repo, |
| 96 | + "mwstore://localtesting/data/$name", $type ); |
90 | 97 | } |
91 | 98 | |
92 | 99 | function providerFiles() { |
— | — | @@ -129,7 +136,7 @@ |
130 | 137 | global $wgEnableAutoRotation; |
131 | 138 | $wgEnableAutoRotation = false; |
132 | 139 | |
133 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $name, $type ); |
| 140 | + $file = $this->dataFile( $name, $type ); |
134 | 141 | $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); |
135 | 142 | $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); |
136 | 143 | |
— | — | @@ -158,13 +165,13 @@ |
159 | 166 | throw new MWException('bogus test data format ' . $size); |
160 | 167 | } |
161 | 168 | |
162 | | - $file = $this->localFile( $name, $type ); |
| 169 | + $file = $this->dataFile( $name, $type ); |
163 | 170 | $thumb = $file->transform( $params, File::RENDER_NOW ); |
164 | 171 | |
165 | 172 | $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); |
166 | 173 | $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); |
167 | 174 | |
168 | | - $gis = getimagesize( $thumb->getPath() ); |
| 175 | + $gis = getimagesize( $thumb->getLocalCopyPath() ); |
169 | 176 | if ($out[0] > $info['width']) { |
170 | 177 | // Physical image won't be scaled bigger than the original. |
171 | 178 | $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size"); |
— | — | @@ -242,7 +249,7 @@ |
243 | 250 | array( |
244 | 251 | 270, |
245 | 252 | array( self::TEST_HEIGHT, self::TEST_WIDTH ) |
246 | | - ), |
| 253 | + ), |
247 | 254 | ); |
248 | 255 | } |
249 | 256 | } |
Index: branches/FileBackend/phase3/tests/phpunit/includes/media/PNGTest.php |
— | — | @@ -2,12 +2,22 @@ |
3 | 3 | class PNGHandlerTest extends MediaWikiTestCase { |
4 | 4 | |
5 | 5 | public function setUp() { |
6 | | - $this->filePath = dirname( __FILE__ ) . '/../../data/media/'; |
| 6 | + $this->filePath = dirname( __FILE__ ) . '/../../data/media'; |
| 7 | + $this->backend = new FSFileBackend( array( |
| 8 | + 'name' => 'localtesting', |
| 9 | + 'lockManager' => 'nullLockManager', |
| 10 | + 'containerPaths' => array( 'data' => $this->filePath ) |
| 11 | + ) ); |
| 12 | + $this->repo = new FSRepo( array( |
| 13 | + 'name' => 'temp', |
| 14 | + 'url' => 'http://localhost/thumbtest', |
| 15 | + 'backend' => $this->backend |
| 16 | + ) ); |
7 | 17 | $this->handler = new PNGHandler(); |
8 | 18 | } |
9 | 19 | |
10 | 20 | public function testInvalidFile() { |
11 | | - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); |
| 21 | + $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); |
12 | 22 | $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); |
13 | 23 | } |
14 | 24 | /** |
— | — | @@ -16,8 +26,7 @@ |
17 | 27 | * @dataProvider dataIsAnimated |
18 | 28 | */ |
19 | 29 | public function testIsAnimanted( $filename, $expected ) { |
20 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, |
21 | | - 'image/png' ); |
| 30 | + $file = $this->dataFile( $filename, 'image/png' ); |
22 | 31 | $actual = $this->handler->isAnimatedImage( $file ); |
23 | 32 | $this->assertEquals( $expected, $actual ); |
24 | 33 | } |
— | — | @@ -34,8 +43,7 @@ |
35 | 44 | * @dataProvider dataGetImageArea |
36 | 45 | */ |
37 | 46 | public function testGetImageArea( $filename, $expected ) { |
38 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, |
39 | | - 'image/png' ); |
| 47 | + $file = $this->dataFile($filename, 'image/png' ); |
40 | 48 | $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); |
41 | 49 | $this->assertEquals( $expected, $actual ); |
42 | 50 | } |
— | — | @@ -73,9 +81,8 @@ |
74 | 82 | * @dataProvider dataGetMetadata |
75 | 83 | */ |
76 | 84 | public function testGetMetadata( $filename, $expected ) { |
77 | | - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, |
78 | | - 'image/png' ); |
79 | | - $actual = $this->handler->getMetadata( $file, $this->filePath . $filename ); |
| 85 | + $file = $this->dataFile( $filename, 'image/png' ); |
| 86 | + $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); |
80 | 87 | // $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); |
81 | 88 | $this->assertEquals( ( $expected ), ( $actual ) ); |
82 | 89 | } |
— | — | @@ -85,4 +92,9 @@ |
86 | 93 | array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), |
87 | 94 | ); |
88 | 95 | } |
| 96 | + |
| 97 | + private function dataFile( $name, $type ) { |
| 98 | + return new UnregisteredLocalFile( false, $this->repo, |
| 99 | + "mwstore://localtesting/data/$name", $type ); |
| 100 | + } |
89 | 101 | } |
Index: branches/FileBackend/phase3/tests/phpunit/includes/media/FormatMetadataTest.php |
— | — | @@ -4,6 +4,17 @@ |
5 | 5 | if ( !wfDl( 'exif' ) ) { |
6 | 6 | $this->markTestSkipped( "This test needs the exif extension." ); |
7 | 7 | } |
| 8 | + $filePath = dirname( __FILE__ ) . '/../../data/media'; |
| 9 | + $this->backend = new FSFileBackend( array( |
| 10 | + 'name' => 'localtesting', |
| 11 | + 'lockManager' => 'nullLockManager', |
| 12 | + 'containerPaths' => array( 'data' => $filePath ) |
| 13 | + ) ); |
| 14 | + $this->repo = new FSRepo( array( |
| 15 | + 'name' => 'temp', |
| 16 | + 'url' => 'http://localhost/thumbtest', |
| 17 | + 'backend' => $this->backend |
| 18 | + ) ); |
8 | 19 | global $wgShowEXIF; |
9 | 20 | $this->show = $wgShowEXIF; |
10 | 21 | $wgShowEXIF = true; |
— | — | @@ -14,8 +25,7 @@ |
15 | 26 | } |
16 | 27 | |
17 | 28 | public function testInvalidDate() { |
18 | | - $file = UnregisteredLocalFile::newFromPath( dirname( __FILE__ ) . |
19 | | - '/../../data/media/broken_exif_date.jpg', 'image/jpeg' ); |
| 29 | + $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' ); |
20 | 30 | |
21 | 31 | // Throws an error if bug hit |
22 | 32 | $meta = $file->formatMetadata(); |
— | — | @@ -34,4 +44,9 @@ |
35 | 45 | $meta['visible'][$dateIndex]['value'], |
36 | 46 | 'File with invalid date metadata (bug 29471)' ); |
37 | 47 | } |
| 48 | + |
| 49 | + private function dataFile( $name, $type ) { |
| 50 | + return new UnregisteredLocalFile( false, $this->repo, |
| 51 | + "mwstore://localtesting/data/$name", $type ); |
| 52 | + } |
38 | 53 | } |
Index: branches/FileBackend/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php |
— | — | @@ -287,7 +287,7 @@ |
288 | 288 | } |
289 | 289 | |
290 | 290 | /** |
291 | | - * @dataProvider provider_testConcatenate |
| 291 | + * @dataProvider provider_testCreate |
292 | 292 | */ |
293 | 293 | public function provider_testCreate() { |
294 | 294 | $cases = array(); |
— | — | @@ -324,47 +324,17 @@ |
325 | 325 | return $cases; |
326 | 326 | } |
327 | 327 | |
328 | | - /** |
329 | | - * @dataProvider provider_testConcatenate |
330 | | - */ |
331 | | - public function testConcatenate() { |
332 | | - |
333 | | - } |
| 328 | + // @TODO: testConcatenate |
334 | 329 | |
335 | | - /** |
336 | | - * @dataProvider provider_testPrepare |
337 | | - */ |
338 | | - public function testPrepare() { |
339 | | - |
340 | | - } |
| 330 | + // @TODO: testPrepare |
341 | 331 | |
342 | | - /** |
343 | | - * @dataProvider provider_testSecure |
344 | | - */ |
345 | | - public function testSecure() { |
346 | | - |
347 | | - } |
| 332 | + // @TODO: testSecure |
348 | 333 | |
349 | | - /** |
350 | | - * @dataProvider provider_testClean |
351 | | - */ |
352 | | - public function testClean() { |
353 | | - |
354 | | - } |
| 334 | + // @TODO: testClean |
355 | 335 | |
356 | | - /** |
357 | | - * @dataProvider provider_testGetLocalCopy |
358 | | - */ |
359 | | - public function testGetLocalCopy() { |
360 | | - |
361 | | - } |
| 336 | + // @TODO: testGetLocalCopy |
362 | 337 | |
363 | | - /** |
364 | | - * @dataProvider provider_testDoOperations |
365 | | - */ |
366 | | - public function testDoOperations() { |
367 | | - |
368 | | - } |
| 338 | + // @TODO: testDoOperations |
369 | 339 | |
370 | 340 | public function testGetFileList() { |
371 | 341 | $base = $this->singleBasePath(); |
Index: branches/FileBackend/phase3/includes/AutoLoader.php |
— | — | @@ -499,6 +499,7 @@ |
500 | 500 | 'LockManager' => 'includes/filerepo/backend/LockManager.php', |
501 | 501 | 'FSLockManager' => 'includes/filerepo/backend/LockManager.php', |
502 | 502 | 'DBLockManager' => 'includes/filerepo/backend/LockManager.php', |
| 503 | + 'NullLockManager' => 'includes/filerepo/backend/LockManager.php', |
503 | 504 | 'FileOp' => 'includes/filerepo/backend/FileOp.php', |
504 | 505 | 'StoreFileOp' => 'includes/filerepo/backend/FileOp.php', |
505 | 506 | 'CopyFileOp' => 'includes/filerepo/backend/FileOp.php', |
Index: branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php |
— | — | @@ -260,6 +260,7 @@ |
261 | 261 | * All lock requests for a resource, identified by a hash string, will |
262 | 262 | * map to one bucket. Each bucket maps to one or several peer DB servers, |
263 | 263 | * each having a `file_locks` table with row-level locking. |
| 264 | + * This does not use GET_LOCK() per http://bugs.mysql.com/bug.php?id=1118. |
264 | 265 | * |
265 | 266 | * A majority of peer servers must agree for a lock to be acquired. |
266 | 267 | * As long as one peer server is up, lock requests will not be blocked |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -289,9 +289,7 @@ |
290 | 290 | * @param $params Array |
291 | 291 | * @return FSFile|null Returns null on failure |
292 | 292 | */ |
293 | | - public function getLocalReference( array $params ) { |
294 | | - return $this->getLocalCopy( $params ); |
295 | | - } |
| 293 | + abstract public function getLocalReference( array $params ); |
296 | 294 | |
297 | 295 | /** |
298 | 296 | * Get a local copy on disk of the file at a storage path in the backend. |
— | — | @@ -477,6 +475,10 @@ |
478 | 476 | return 'internal'; |
479 | 477 | } |
480 | 478 | |
| 479 | + public function getLocalReference( array $params ) { |
| 480 | + return $this->getLocalCopy( $params ); |
| 481 | + } |
| 482 | + |
481 | 483 | function streamFile( array $params ) { |
482 | 484 | $status = Status::newGood(); |
483 | 485 | |
— | — | @@ -736,7 +738,7 @@ |
737 | 739 | // This accounts for Swift and S3 restrictions. Also note |
738 | 740 | // that these urlencode to the same string, which is useful |
739 | 741 | // since the Swift size limit is *after* URL encoding. |
740 | | - return preg_match( '/^[a-zA-Z._-]{1,256}$/u', $container ); |
| 742 | + return preg_match( '/^[a-zA-Z0-9._-]{1,256}$/u', $container ); |
741 | 743 | } |
742 | 744 | |
743 | 745 | /** |
Index: branches/FileBackend/phase3/includes/filerepo/FileRepo.php |
— | — | @@ -44,7 +44,11 @@ |
45 | 45 | $this->url = isset( $info['url'] ) |
46 | 46 | ? $info['url'] |
47 | 47 | : false; // a subclass will need to set the URL (e.g. ForeignAPIRepo) |
48 | | - $this->backend = FileBackendGroup::singleton()->get( $info['backend'] ); |
| 48 | + if ( $info['backend'] instanceof FileBackendBase ) { |
| 49 | + $this->backend = $info['backend']; // useful for testing |
| 50 | + } else { |
| 51 | + $this->backend = FileBackendGroup::singleton()->get( $info['backend'] ); |
| 52 | + } |
49 | 53 | |
50 | 54 | // Optional settings that can have no value |
51 | 55 | $optionalSettings = array( |
— | — | @@ -94,7 +98,7 @@ |
95 | 99 | } |
96 | 100 | |
97 | 101 | /** |
98 | | - * Get the file backend |
| 102 | + * Get the file backend instance |
99 | 103 | * |
100 | 104 | * @return FileBackendBase |
101 | 105 | */ |
Index: branches/FileBackend/phase3/includes/media/MediaTransformOutput.php |
— | — | @@ -78,8 +78,8 @@ |
79 | 79 | * @return Bool |
80 | 80 | */ |
81 | 81 | public function hasFile() { |
82 | | - // If TRANSFORM_LATER, a 0-byte temp file be at the path (not purged yet) |
83 | | - return ( !$this->isError() && $this->path && filesize( $this->path ) ); |
| 82 | + // If TRANSFORM_LATER, $this->path will be false |
| 83 | + return ( !$this->isError() && $this->path ); |
84 | 84 | } |
85 | 85 | |
86 | 86 | /** |
— | — | @@ -93,6 +93,15 @@ |
94 | 94 | } |
95 | 95 | |
96 | 96 | /** |
| 97 | + * Get the path of a file system copy of the thumbnail |
| 98 | + * |
| 99 | + * @return string|false Returns false if there isn't one |
| 100 | + */ |
| 101 | + public function getLocalCopyPath() { |
| 102 | + return $this->path; |
| 103 | + } |
| 104 | + |
| 105 | + /** |
97 | 106 | * Stream the file if there were no errors |
98 | 107 | * |
99 | 108 | * @param $headers Array Additional HTTP headers to send on success |
Index: branches/FileBackend/phase3/includes/media/Generic.php |
— | — | @@ -216,7 +216,7 @@ |
217 | 217 | $out = $this->doFSTransform( $image, $tmpDest, $dstUrl, $params, $flags ); |
218 | 218 | // Copy any thumbnail from FS into storage at $dstpath |
219 | 219 | // Note: no file is created if it's to be rendered client-side. |
220 | | - if ( !$out->isError() && $out->hasFile() ) { |
| 220 | + if ( !$out->isError() && $out->hasFile() && !$out->fileIsSource() ) { |
221 | 221 | $op = array( 'op' => 'store', |
222 | 222 | 'src' => $tmpDest, 'dst' => $dstPath, 'overwriteDest' => true ); |
223 | 223 | if ( !$image->getRepo()->getBackend()->doOperation( $op )->isOK() ) { |