Index: trunk/extensions/NSFileRepo/NSFileRepo.php |
— | — | @@ -10,6 +10,8 @@ |
11 | 11 | * @url http://www.mediawiki.org/wiki/Manual:Extension:NSFileRepo |
12 | 12 | * @licence GNU General Public Licence 2.0 or later |
13 | 13 | * |
| 14 | + * Version 1.4 - Several thumbnail fixes and updates for FileRepo enhancements |
| 15 | + * |
14 | 16 | * Version 1.3 - Allows namespace protected files to be whitelisted |
15 | 17 | * |
16 | 18 | * Version 1.2 - Fixes reupload error and adds lockdown security to archives, deleted, thumbs |
— | — | @@ -29,18 +31,16 @@ |
30 | 32 | $wgExtensionMessagesFiles['NSFileRepo'] = dirname(__FILE__) .'/NSFileRepo.i18n.php'; |
31 | 33 | $wgExtensionMessagesFiles['img_auth'] = dirname(__FILE__) .'/img_auth.i18n.php'; |
32 | 34 | |
33 | | - |
34 | 35 | $wgExtensionFunctions[] = 'NSFileRepoSetup'; |
35 | 36 | $wgExtensionCredits['media'][] = array( |
36 | 37 | 'path' => __FILE__, |
37 | 38 | 'name' => 'NSFileRepo', |
38 | 39 | 'author' => 'Jack D. Pond', |
39 | | - 'version' => '1.4alpha', |
| 40 | + 'version' => '1.4', |
40 | 41 | 'url' => 'http://www.mediawiki.org/wiki/Extension:NSFileRepo', |
41 | 42 | 'descriptionmsg' => 'nsfilerepo-desc' |
42 | 43 | ); |
43 | 44 | |
44 | | - |
45 | 45 | /** |
46 | 46 | * Set up hooks for NSFileRepo |
47 | 47 | */ |
— | — | @@ -52,7 +52,6 @@ |
53 | 53 | $wgHooks['userCan'][] = 'NSFileRepolockdownUserCan'; |
54 | 54 | $wgHooks['ImgAuthBeforeStream'][] = 'NSFileRepoImgAuthCheck'; |
55 | 55 | |
56 | | - |
57 | 56 | class NSLocalRepo extends LocalRepo { |
58 | 57 | var $fileFactory = array( 'NSLocalFile', 'newFromTitle' ); |
59 | 58 | var $oldFileFactory = array( 'NSOldLocalFile', 'newFromTitle' ); |
— | — | @@ -84,8 +83,7 @@ |
85 | 84 | function storeTemp( $originalName, $srcPath ) { |
86 | 85 | $date = gmdate( "YmdHis" ); |
87 | 86 | $hashPath = $this->getHashPath( $originalName ); |
88 | | - $bits=explode(':',$originalName); |
89 | | - $filename = $bits[count($bits)-1]; |
| 87 | + $filename = $this->getFileNameStripped($originalName); |
90 | 88 | $dstRel = "$hashPath$date!$filename"; |
91 | 89 | $dstUrlRel = $hashPath . $date . '!' . rawurlencode( $filename ); |
92 | 90 | $result = $this->store( $srcPath, 'temp', $dstRel ); |
— | — | @@ -100,18 +98,14 @@ |
101 | 99 | * Get the path of the file relative to the public zone root |
102 | 100 | */ |
103 | 101 | function getRel() { |
104 | | - $bits=explode(':',$this->getName()); |
105 | | - $filename = $bits[count($bits)-1]; |
106 | | - return $this->getHashPath() . $filename; |
| 102 | + return $this->getHashPath() . $this->getFileNameStripped($this->getName()); |
107 | 103 | } |
108 | 104 | |
109 | 105 | /** |
110 | 106 | * Get urlencoded relative path of the file |
111 | 107 | */ |
112 | 108 | function getUrlRel() { |
113 | | - $bits=explode(':',$this->getName()); |
114 | | - $filename = $bits[count($bits)-1]; |
115 | | - return $this->getHashPath() . rawurlencode( $filename ); |
| 109 | + return $this->getHashPath() . rawurlencode( $this->getFileNameStripped($this->getName())); |
116 | 110 | } |
117 | 111 | |
118 | 112 | /** Get the URL of the thumbnail directory, or a particular file if $suffix is specified */ |
— | — | @@ -123,6 +117,26 @@ |
124 | 118 | return $path; |
125 | 119 | } |
126 | 120 | |
| 121 | + |
| 122 | + /** Return the file name of a thumbnail with the specified parameters */ |
| 123 | + function thumbName( $params ) { |
| 124 | + if ( !$this->getHandler() ) { |
| 125 | + return null; |
| 126 | + } |
| 127 | + $extension = $this->getExtension(); |
| 128 | + list( $thumbExt, $thumbMime ) = $this->handler->getThumbType( $extension, $this->getMimeType() ); |
| 129 | +/* This is the part that changed from LocalFile */ |
| 130 | + $thumbName = $this->handler->makeParamString( $params ) . '-' . $this->getFileNameStripped($this->getName()); |
| 131 | +/* End of changes */ |
| 132 | + if ( $thumbExt != $extension ) { |
| 133 | + $thumbName .= ".$thumbExt"; |
| 134 | + } |
| 135 | + $bits=explode(':',$this->getName()); |
| 136 | + if (count($bits) > 1) $thumbName = $bits[0].":".$thumbName; |
| 137 | + return $thumbName; |
| 138 | + } |
| 139 | + |
| 140 | + |
127 | 141 | /** Get the path of the thumbnail directory, or a particular file if $suffix is specified */ |
128 | 142 | function getThumbPath( $suffix = false ) { |
129 | 143 | $path = $this->repo->getZonePath('thumb') . '/' . $this->getRel(); |
— | — | @@ -186,13 +200,9 @@ |
187 | 201 | /** Strip namespace (if any) from file name */ |
188 | 202 | function getFileNameStripped($suffix) { |
189 | 203 | $bits=explode(':',$suffix); |
190 | | - $filename = $bits[count($bits)-1]; |
191 | | - $pxpos = strpos($suffix,"px-"); |
192 | | - if (count($bits) > 1 && $pxpos) $filename= substr($suffix,0,$pxpos+3).$filename; |
193 | | - return $filename; |
| 204 | + return $bits[count($bits)-1]; |
194 | 205 | } |
195 | 206 | |
196 | | - |
197 | 207 | /** |
198 | 208 | * This function overrides the LocalFile because the archive name should not contain the namespace in the |
199 | 209 | * filename. Otherwise the function would have worked. This only affects reuploads |
— | — | @@ -263,13 +273,92 @@ |
264 | 274 | } |
265 | 275 | $this->olds[] = array( |
266 | 276 | "{$archiveBase}/{$this->oldHash}{$oldName}", |
| 277 | +/* This is the part that changed from LocalFile */ |
267 | 278 | "{$archiveBase}/{$this->newHash}{$timestamp}!".$this->getFileNameStripped($this->newName) |
| 279 | +/* End of changes */ |
268 | 280 | ); |
269 | 281 | } |
270 | 282 | $this->db->freeResult( $result ); |
271 | 283 | } |
272 | 284 | |
| 285 | + /** |
| 286 | + * The only thing changed here is to strip NS from the file name |
| 287 | + * Delete cached transformed files |
| 288 | + */ |
273 | 289 | |
| 290 | + function purgeThumbnails() { |
| 291 | + global $wgUseSquid; |
| 292 | + // Delete thumbnails |
| 293 | + $files = $this->getThumbnails(); |
| 294 | + $dir = $this->getThumbPath(); |
| 295 | + $urls = array(); |
| 296 | + foreach ( $files as $file ) { |
| 297 | + # Check that the base file name is part of the thumb name |
| 298 | + # This is a basic sanity check to avoid erasing unrelated directories |
| 299 | + |
| 300 | +/* This is the part that changed from LocalFile */ |
| 301 | + if ( strpos( $file, $this->getFileNameStripped($this->getName()) ) !== false ) { |
| 302 | +/* End of changes */ |
| 303 | + $url = $this->getThumbUrl( $file ); |
| 304 | + $urls[] = $url; |
| 305 | + @unlink( "$dir/$file" ); |
| 306 | + } |
| 307 | + } |
| 308 | + |
| 309 | + // Purge the squid |
| 310 | + if ( $wgUseSquid ) { |
| 311 | + SquidUpdate::purge( $urls ); |
| 312 | + } |
| 313 | + } |
| 314 | + |
| 315 | + /** |
| 316 | + * Replaces hard coded OldLocalFile::newFromRow to use $this->repo->oldFileFromRowFactory configuration |
| 317 | + * This may not be necessary in the future if LocalFile is patched to allow configuration |
| 318 | + */ |
| 319 | + |
| 320 | + function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
| 321 | + $dbr = $this->repo->getSlaveDB(); |
| 322 | + $tables = array( 'oldimage' ); |
| 323 | + $fields = OldLocalFile::selectFields(); |
| 324 | + $conds = $opts = $join_conds = array(); |
| 325 | + $eq = $inc ? '=' : ''; |
| 326 | + $conds[] = "oi_name = " . $dbr->addQuotes( $this->title->getDBkey() ); |
| 327 | + if( $start ) { |
| 328 | + $conds[] = "oi_timestamp <$eq " . $dbr->addQuotes( $dbr->timestamp( $start ) ); |
| 329 | + } |
| 330 | + if( $end ) { |
| 331 | + $conds[] = "oi_timestamp >$eq " . $dbr->addQuotes( $dbr->timestamp( $end ) ); |
| 332 | + } |
| 333 | + if( $limit ) { |
| 334 | + $opts['LIMIT'] = $limit; |
| 335 | + } |
| 336 | + // Search backwards for time > x queries |
| 337 | + $order = ( !$start && $end !== null ) ? 'ASC' : 'DESC'; |
| 338 | + $opts['ORDER BY'] = "oi_timestamp $order"; |
| 339 | + $opts['USE INDEX'] = array( 'oldimage' => 'oi_name_timestamp' ); |
| 340 | + |
| 341 | + wfRunHooks( 'LocalFile::getHistory', array( &$this, &$tables, &$fields, |
| 342 | + &$conds, &$opts, &$join_conds ) ); |
| 343 | + |
| 344 | + $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $opts, $join_conds ); |
| 345 | + $r = array(); |
| 346 | + while( $row = $dbr->fetchObject( $res ) ) { |
| 347 | +/* This is the part that changed from LocalFile */ |
| 348 | + if ( $this->repo->oldFileFromRowFactory ) { |
| 349 | + $r[] = call_user_func( $this->repo->oldFileFromRowFactory, $row, $this->repo ); |
| 350 | + } else { |
| 351 | + $r[] = OldLocalFile::newFromRow( $row, $this->repo ); |
| 352 | + } |
| 353 | +/* End of changes */ |
| 354 | + } |
| 355 | + if( $order == 'ASC' ) { |
| 356 | + $r = array_reverse( $r ); // make sure it ends up descending |
| 357 | + } |
| 358 | + return $r; |
| 359 | + } |
| 360 | + |
| 361 | + |
| 362 | + |
274 | 363 | /** Instantiating this class using "self" |
275 | 364 | * If you're reading this, you're problably wondering why on earth are the following static functions, which are copied |
276 | 365 | * verbatim from the original extended class "LocalFIle" included here? |
— | — | @@ -303,11 +392,12 @@ |
304 | 393 | } |
305 | 394 | class NSOldLocalFile extends OldLocalFile |
306 | 395 | { |
307 | | - function getRel( $name, $levels) { |
308 | | - return(NSLocalFile::getRel( $name, $levels )); |
| 396 | + |
| 397 | + function getRel() { |
| 398 | + return 'archive/' . $this->getHashPath() . $this->getFileNameStripped($this->getArchiveName()); |
309 | 399 | } |
310 | | - function getUrlRel( $name, $levels ) { |
311 | | - return(NSLocalFile::getUrlRel( $name, $levels )); |
| 400 | + function getUrlRel() { |
| 401 | + return 'archive/' . $this->getHashPath() . urlencode( $this->getFileNameStripped($this->getArchiveName()) ); |
312 | 402 | } |
313 | 403 | function publish( $srcPath, $flags = 0 ) { |
314 | 404 | return NSLocalFile::publish( $srcPath, $flags ); |
— | — | @@ -315,6 +405,9 @@ |
316 | 406 | function getThumbUrl( $suffix = false ) { |
317 | 407 | return(NSLocalFile::getThumbUrl( $suffix ) ); |
318 | 408 | } |
| 409 | + function thumbName( $params ) { |
| 410 | + return(NSLocalFile::thumbName( $params )); |
| 411 | + } |
319 | 412 | function getThumbPath( $suffix = false ) { |
320 | 413 | return(NSLocalFile::getThumbPath( $suffix )); |
321 | 414 | } |
— | — | @@ -336,11 +429,24 @@ |
337 | 430 | function getThumbStripped($suffix) { |
338 | 431 | return(NSLocalFile::getThumbStripped($suffix)); |
339 | 432 | } |
| 433 | + function getFileNameStripped($suffix) { |
| 434 | + return(NSLocalFile::getFileNameStripped($suffix)); |
| 435 | + } |
340 | 436 | function addOlds() { |
341 | 437 | return(NSLocalFile::addOlds()); |
342 | 438 | } |
| 439 | + function purgeThumbnails() { |
| 440 | + return(NSLocalFile::purgeThumbnails()); |
| 441 | + } |
| 442 | + /** |
| 443 | + * Replaces hard coded OldLocalFile::newFromRow to use $this->repo->oldFileFromRowFactory configuration |
| 444 | + * This may not be necessary in the future if LocalFile is patched to allow configuration |
| 445 | + */ |
| 446 | + function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
| 447 | + return(NSLocalFile::getHistory( $limit, $start , $end, $inc) ); |
| 448 | + } |
343 | 449 | |
344 | | - /** See comment about Instantiating this class using "self", above */ |
| 450 | + /** See comment above about Instantiating this class using "self" */ |
345 | 451 | |
346 | 452 | static function newFromTitle( $title, $repo, $time = null ) { |
347 | 453 | # The null default value is only here to avoid an E_STRICT |
— | — | @@ -361,7 +467,6 @@ |
362 | 468 | } |
363 | 469 | } |
364 | 470 | |
365 | | - |
366 | 471 | /** |
367 | 472 | * Initial setup, add .i18n. messages from $IP/extensions/DiscussionThreading/DiscussionThreading.i18n.php |
368 | 473 | */ |
— | — | @@ -388,7 +493,6 @@ |
389 | 494 | return (true); |
390 | 495 | } |
391 | 496 | |
392 | | - |
393 | 497 | // If Extension:Lockdown has been activated (recommend), check individual namespace protection |
394 | 498 | |
395 | 499 | function NSFileRepolockdownUserCan($title, $user, $action, &$result) { |
Index: trunk/extensions/NSFileRepo/README |
— | — | @@ -12,8 +12,8 @@ |
13 | 13 | |description = implements per-namespace group permissions for image and file rights protection |
14 | 14 | |image = |
15 | 15 | |version = 1.3 |
16 | | -|update = 2010-1-27 |
17 | | -|mediawiki = 1.13, 1.14, 1.15, 1.16 |
| 16 | +|update = 2010-4-23 |
| 17 | +|mediawiki = 1.13, 1.14, 1.15, 1.16, 1.17-SVN |
18 | 18 | |license = GNU General Public Licence 2.0 |
19 | 19 | |download = {{WikimediaDownload|NSFileRepo}} |
20 | 20 | |readme = [http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions/NSFileRepo/README README] |
— | — | @@ -72,12 +72,24 @@ |
73 | 73 | == Announcements == |
74 | 74 | |
75 | 75 | * Starting with version 1.16.0, this extension will require no patching. Updates were made to make more efficient and easier to use. |
76 | | -* The first version of this (Rel 0.0) was released 2009-07-11. The following activities are underway to make this extension easier to install and use, including: |
77 | | -** Modifying and updating the standard version of img_auth.php to include localization and a hook necessary for this extension. Will hopefully be approved for version 1.16 |
78 | | -** Discussing ways to allow modification of wfStripIllegalFilenameChars so that future patching will not be needed. |
| 76 | +* The first version of this (Rel 0.0) was released 2009-07-11. The following activities were completed to make this extension easier to install and use, including: |
| 77 | +** 1.16.0 - img_auth.php was rewritten which has the required hook and global messages for image authorization failures and this extension. |
| 78 | +** 1.16.0+ - has global variable [[Manual:$wgIllegalFileChars | $wgIllegalFileChars]]. By default this extension modifies it to allow ":" for namespaces. |
79 | 79 | |
| 80 | + |
80 | 81 | == Release Notes == |
| 82 | +=== NSFileRepo 1.4 === |
81 | 83 | |
| 84 | +=== NSFileRepo 1.4 (Planned) === |
| 85 | + |
| 86 | +* Bug Fixes - Thumbnails did not display properly in History (and even in uploads of past files). The problem is fixed with 1.16 (and the current trunk version of NSFileRepo), but in versions of MW before 1.16, archived thumbnails still break because LocalFile.php uses hard-coded class of OldLocalFile instead of <nowiki>$repo->oldFileFactory</nowiki> which would instantiate the correct NSLocalFile class. |
| 87 | + |
| 88 | +* Works with all namespaces > 1000 (used to only work with NS >=11 and <1000 |
| 89 | + |
| 90 | +* Use NS_IMAGE instead of NS_FILE for backward compatibility |
| 91 | + |
| 92 | +* Upgrades - Now works completely with >1.16. Changes were made for 100% backward compatibility. Even though it can be used all the way back to 1.13, the thumbnails probably will not display correctly because of issues with FileRepo before 1.16. This is a cosmetic versus a functional issue - if it bothers you, just disable thumbnails. If you're not using automatically generated thumbnails, you wouldn't notice the difference. |
| 93 | + |
82 | 94 | === NSFileRepo 1.3 === |
83 | 95 | |
84 | 96 | * Allow files with namespace protection (e.g. File:ns:yourfile.txt) to be whitelisted using standard [[Manual:$wgWhitelistRead | $wgWhitelistRead]] in localsettings. |
— | — | @@ -98,8 +110,8 @@ |
99 | 111 | This Extension and the necessary patch/files may be downloaded from one of the following (SVN preferred). The distribution is the same for all versions of MW, 1.13.0 through Current. |
100 | 112 | |
101 | 113 | |
102 | | -* [http://wiki.montcopa.org/PublicDownloads/NSFileRepo_REL_1_1.tar Download tar] (May require eol conversion) |
103 | | -* [http://wiki.montcopa.org/PublicDownloads/NSFileRepo_REL_1_1.zip Download zip] |
| 114 | +* [http://wiki.montcopa.org/PublicDownloads/NSFileRepo_REL_1_4.tar Download tar] (May require eol conversion) |
| 115 | +* [http://wiki.montcopa.org/PublicDownloads/NSFileRepo_REL_1_4.zip Download zip] |
104 | 116 | * [http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions/NSFileRepo SVN] |
105 | 117 | |
106 | 118 | Copy all files and directories into directory: |
— | — | @@ -140,7 +152,7 @@ |
141 | 153 | |
142 | 154 | The user rights and configuration requiremements are are the same as described in [[Extension:Lockdown#Configuration | Extension Lockdown]]. |
143 | 155 | |
144 | | -==Patch GlobalFunctions.php== |
| 156 | +==Patch GlobalFunctions.php (only MW versions between 1.13.0 and 1.16) == |
145 | 157 | |
146 | 158 | In version 1_13_0, a new function wfStripIllegalFilenameChars was added to <nowiki>includes/GlobalFunctions.php</nowiki>. This prevents the extension from determining the namespace associated with the file/image. For this extension to work in versions 1_13_0 through 1_15_1, you will need to make a minor patch to includes/GlobalFunctions.php as follows: |
147 | 159 | |