Index: trunk/extensions/NSFileRepo/NSFileRepo_body.php |
— | — | @@ -0,0 +1,429 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Class definitions for NSFileRepo |
| 6 | + */ |
| 7 | + |
| 8 | +class NSLocalRepo extends LocalRepo { |
| 9 | + var $fileFactory = array( 'NSLocalFile', 'newFromTitle' ); |
| 10 | + var $oldFileFactory = array( 'NSOldLocalFile', 'newFromTitle' ); |
| 11 | + var $fileFromRowFactory = array( 'NSLocalFile', 'newFromRow' ); |
| 12 | + var $oldFileFromRowFactory = array( 'NSOldLocalFile', 'newFromRow' ); |
| 13 | + |
| 14 | + static function getHashPathForLevel( $name, $levels ) { |
| 15 | + global $wgContLang; |
| 16 | + $bits = explode( ':',$name ); |
| 17 | + $filename = $bits[ count( $bits ) - 1 ]; |
| 18 | + $path = parent::getHashPathForLevel( $filename, $levels ); |
| 19 | + return count( $bits ) > 1 ? |
| 20 | + $wgContLang->getNsIndex( $bits[0] ) .'/'. $path : $path; |
| 21 | + } |
| 22 | + |
| 23 | + /** |
| 24 | + * Get a relative path including trailing slash, e.g. f/fa/ |
| 25 | + * If the repo is not hashed, returns an empty string |
| 26 | + * This is needed because self:: will call parent if not included - exact same as in FSRepo |
| 27 | + */ |
| 28 | + function getHashPath( $name ) { |
| 29 | + return self::getHashPathForLevel( $name, $this->hashLevels ); |
| 30 | + } |
| 31 | + |
| 32 | + /** |
| 33 | + * Pick a random name in the temp zone and store a file to it. |
| 34 | + * @param string $originalName The base name of the file as specified |
| 35 | + * by the user. The file extension will be maintained. |
| 36 | + * @param string $srcPath The current location of the file. |
| 37 | + * @return FileRepoStatus object with the URL in the value. |
| 38 | + */ |
| 39 | + function storeTemp( $originalName, $srcPath ) { |
| 40 | + $date = gmdate( "YmdHis" ); |
| 41 | + $hashPath = $this->getHashPath( $originalName ); |
| 42 | + $filename = $this->getFileNameStripped( $originalName ); |
| 43 | + $dstRel = "$hashPath$date!$filename"; |
| 44 | + $dstUrlRel = $hashPath . $date . '!' . rawurlencode( $filename ); |
| 45 | + $result = $this->store( $srcPath, 'temp', $dstRel ); |
| 46 | + $result->value = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; |
| 47 | + return $result; |
| 48 | + } |
| 49 | + |
| 50 | + function getFileNameStripped($suffix) { |
| 51 | + return(NSLocalFile::getFileNameStripped($suffix)); |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +class NSLocalFile extends LocalFile { |
| 56 | + /** |
| 57 | + * Get the path of the file relative to the public zone root |
| 58 | + */ |
| 59 | + function getRel() { |
| 60 | + return $this->getHashPath() . $this->getFileNameStripped( $this->getName() ); |
| 61 | + } |
| 62 | + |
| 63 | + /** |
| 64 | + * Get urlencoded relative path of the file |
| 65 | + */ |
| 66 | + function getUrlRel() { |
| 67 | + return $this->getHashPath() . |
| 68 | + rawurlencode( $this->getFileNameStripped( $this->getName() ) ); |
| 69 | + } |
| 70 | + |
| 71 | + /** Get the URL of the thumbnail directory, or a particular file if $suffix is specified */ |
| 72 | + function getThumbUrl( $suffix = false ) { |
| 73 | + $path = $this->repo->getZoneUrl('thumb') . '/' . $this->getUrlRel(); |
| 74 | + if ( $suffix !== false ) { |
| 75 | + $path .= '/' . rawurlencode( $this->getFileNameStripped( $suffix ) ); |
| 76 | + } |
| 77 | + return $path; |
| 78 | + } |
| 79 | + |
| 80 | + |
| 81 | + /** Return the file name of a thumbnail with the specified parameters */ |
| 82 | + function thumbName( $params ) { |
| 83 | + if ( !$this->getHandler() ) { |
| 84 | + return null; |
| 85 | + } |
| 86 | + $extension = $this->getExtension(); |
| 87 | + list( $thumbExt, $thumbMime ) = $this->handler->getThumbType( $extension, $this->getMimeType() ); |
| 88 | +/* This is the part that changed from LocalFile */ |
| 89 | + $thumbName = $this->handler->makeParamString( $params ) . '-' . $this->getFileNameStripped( $this->getName() ); |
| 90 | +/* End of changes */ |
| 91 | + if ( $thumbExt != $extension ) { |
| 92 | + $thumbName .= ".$thumbExt"; |
| 93 | + } |
| 94 | + $bits = explode( ':',$this->getName() ); |
| 95 | + if ( count($bits) > 1 ) $thumbName = $bits[0] . ":" . $thumbName; |
| 96 | + return $thumbName; |
| 97 | + } |
| 98 | + |
| 99 | + |
| 100 | + /** Get the path of the thumbnail directory, or a particular file if $suffix is specified */ |
| 101 | + function getThumbPath( $suffix = false ) { |
| 102 | + $path = $this->repo->getZonePath('thumb') . '/' . $this->getRel(); |
| 103 | + if ( $suffix !== false ) { |
| 104 | + $path .= '/' . $this->getFileNameStripped( $suffix ); |
| 105 | + } |
| 106 | + return $path; |
| 107 | + } |
| 108 | + |
| 109 | + /** Get the relative path for an archive file */ |
| 110 | + function getArchiveRel( $suffix = false ) { |
| 111 | + $path = 'archive/' . $this->getHashPath(); |
| 112 | + if ( $suffix === false ) { |
| 113 | + $path = substr( $path, 0, -1 ); |
| 114 | + } else { |
| 115 | + $path .= $this->getFileNameStripped( $suffix ); |
| 116 | + } |
| 117 | + return $path; |
| 118 | + } |
| 119 | + |
| 120 | + /** Get the URL of the archive directory, or a particular file if $suffix is specified */ |
| 121 | + function getArchiveUrl( $suffix = false ) { |
| 122 | + $path = $this->repo->getZoneUrl( 'public' ) . '/archive/' . $this->getHashPath(); |
| 123 | + if ( $suffix === false ) { |
| 124 | + $path = substr( $path, 0, -1 ); |
| 125 | + } else { |
| 126 | + $path .= rawurlencode( $this->getFileNameStripped( $suffix ) ); |
| 127 | + } |
| 128 | + return $path; |
| 129 | + } |
| 130 | + |
| 131 | + /** Get the virtual URL for an archive file or directory */ |
| 132 | + function getArchiveVirtualUrl( $suffix = false ) { |
| 133 | + $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath(); |
| 134 | + if ( $suffix === false ) { |
| 135 | + $path = substr( $path, 0, -1 ); |
| 136 | + } else { |
| 137 | + $path .= rawurlencode( $this->getFileNameStripped( $suffix ) ); |
| 138 | + } |
| 139 | + return $path; |
| 140 | + } |
| 141 | + |
| 142 | + /** Get the virtual URL for a thumbnail file or directory */ |
| 143 | + function getThumbVirtualUrl( $suffix = false ) { |
| 144 | + $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel(); |
| 145 | + if ( $suffix !== false ) { |
| 146 | + $path .= '/' . rawurlencode( $this->getFileNameStripped( $suffix ) ); |
| 147 | + } |
| 148 | + return $path; |
| 149 | + } |
| 150 | + |
| 151 | + /** Get the virtual URL for the file itself */ |
| 152 | + function getVirtualUrl( $suffix = false ) { |
| 153 | + $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel(); |
| 154 | + if ( $suffix !== false ) { |
| 155 | + $path .= '/' . rawurlencode( $this->getFileNameStripped( $suffix ) ); |
| 156 | + } |
| 157 | + return $path; |
| 158 | + } |
| 159 | + |
| 160 | + /** Strip namespace (if any) from file name */ |
| 161 | + function getFileNameStripped($suffix) { |
| 162 | + $bits = explode( ':', $suffix ); |
| 163 | + return $bits[ count( $bits ) -1 ]; |
| 164 | + } |
| 165 | + |
| 166 | + /** |
| 167 | + * This function overrides the LocalFile because the archive name should not contain the namespace in the |
| 168 | + * filename. Otherwise the function would have worked. This only affects reuploads |
| 169 | + * |
| 170 | + * Move or copy a file to its public location. If a file exists at the |
| 171 | + * destination, move it to an archive. Returns the archive name on success |
| 172 | + * or an empty string if it was a new file, and a wikitext-formatted |
| 173 | + * WikiError object on failure. |
| 174 | + * |
| 175 | + * The archive name should be passed through to recordUpload for database |
| 176 | + * registration. |
| 177 | + * |
| 178 | + * @param string $sourcePath Local filesystem path to the source image |
| 179 | + * @param integer $flags A bitwise combination of: |
| 180 | + * File::DELETE_SOURCE Delete the source file, i.e. move |
| 181 | + * rather than copy |
| 182 | + * @return FileRepoStatus object. On success, the value member contains the |
| 183 | + * archive name, or an empty string if it was a new file. |
| 184 | + */ |
| 185 | + function publish( $srcPath, $flags = 0 ) { |
| 186 | + $this->lock(); |
| 187 | + $dstRel = $this->getRel(); |
| 188 | + /* This is the part that changed from LocalFile */ |
| 189 | + $archiveName = gmdate( 'YmdHis' ) . '!' . |
| 190 | + $this->getFileNameStripped( $this->getName() ); |
| 191 | + /* End of changes */ |
| 192 | + $archiveRel = 'archive/' . $this->getHashPath() . $archiveName; |
| 193 | + $flags = $flags & File::DELETE_SOURCE ? LocalRepo::DELETE_SOURCE : 0; |
| 194 | + $status = $this->repo->publish( $srcPath, $dstRel, $archiveRel, $flags ); |
| 195 | + if ( $status->value == 'new' ) { |
| 196 | + $status->value = ''; |
| 197 | + } else { |
| 198 | + $status->value = $archiveName; |
| 199 | + } |
| 200 | + $this->unlock(); |
| 201 | + return $status; |
| 202 | + } |
| 203 | + |
| 204 | + /** |
| 205 | + * The only thing changed here is that the array needs to strip the NS from the file name for the has (oldname is already fixed) |
| 206 | + * Add the old versions of the image to the batch |
| 207 | + */ |
| 208 | + function addOlds() { |
| 209 | + $archiveBase = 'archive'; |
| 210 | + $this->olds = array(); |
| 211 | + $this->oldCount = 0; |
| 212 | + |
| 213 | + $result = $this->db->select( 'oldimage', |
| 214 | + array( 'oi_archive_name', 'oi_deleted' ), |
| 215 | + array( 'oi_name' => $this->oldName ), |
| 216 | + __METHOD__ |
| 217 | + ); |
| 218 | + foreach( $result as $row ) { |
| 219 | + $oldName = $row->oi_archive_name; |
| 220 | + $bits = explode( '!', $oldName, 2 ); |
| 221 | + if( count( $bits ) != 2 ) { |
| 222 | + wfDebug( "Invalid old file name: $oldName \n" ); |
| 223 | + continue; |
| 224 | + } |
| 225 | + list( $timestamp, $filename ) = $bits; |
| 226 | + if( $this->oldName != $filename ) { |
| 227 | + wfDebug( "Invalid old file name: $oldName \n" ); |
| 228 | + continue; |
| 229 | + } |
| 230 | + $this->oldCount++; |
| 231 | + // Do we want to add those to oldCount? |
| 232 | + if( $row->oi_deleted & File::DELETED_FILE ) { |
| 233 | + continue; |
| 234 | + } |
| 235 | + $this->olds[] = array( |
| 236 | + "{$archiveBase}/{$this->oldHash}{$oldName}", |
| 237 | + /* This is the part that changed from LocalFile */ |
| 238 | + "{$archiveBase}/{$this->newHash}{$timestamp}!" . |
| 239 | + $this->getFileNameStripped( $this->newName ) |
| 240 | + /* End of changes */ |
| 241 | + ); |
| 242 | + } |
| 243 | + $this->db->freeResult( $result ); |
| 244 | + } |
| 245 | + |
| 246 | + /** |
| 247 | + * The only thing changed here is to strip NS from the file name |
| 248 | + * Delete cached transformed files |
| 249 | + */ |
| 250 | + function purgeThumbnails() { |
| 251 | + global $wgUseSquid; |
| 252 | + // Delete thumbnails |
| 253 | + $files = $this->getThumbnails(); |
| 254 | + $dir = $this->getThumbPath(); |
| 255 | + $urls = array(); |
| 256 | + foreach ( $files as $file ) { |
| 257 | + # Check that the base file name is part of the thumb name |
| 258 | + # This is a basic sanity check to avoid erasing unrelated directories |
| 259 | + |
| 260 | + /* This is the part that changed from LocalFile */ |
| 261 | + if ( strpos( $file, $this->getFileNameStripped($this->getName()) ) !== false ) { |
| 262 | + /* End of changes */ |
| 263 | + $url = $this->getThumbUrl( $file ); |
| 264 | + $urls[] = $url; |
| 265 | + wfSuppressWarnings(); |
| 266 | + unlink( "$dir/$file" ); |
| 267 | + wfRestoreWarnings(); |
| 268 | + } |
| 269 | + } |
| 270 | + |
| 271 | + // Purge the squid |
| 272 | + if ( $wgUseSquid ) { |
| 273 | + SquidUpdate::purge( $urls ); |
| 274 | + } |
| 275 | + } |
| 276 | + |
| 277 | + /** |
| 278 | + * Replaces hard coded OldLocalFile::newFromRow to use $this->repo->oldFileFromRowFactory configuration |
| 279 | + * This may not be necessary in the future if LocalFile is patched to allow configuration |
| 280 | + */ |
| 281 | + |
| 282 | + function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
| 283 | + $dbr = $this->repo->getSlaveDB(); |
| 284 | + $tables = array( 'oldimage' ); |
| 285 | + $fields = OldLocalFile::selectFields(); |
| 286 | + $conds = $opts = $join_conds = array(); |
| 287 | + $eq = $inc ? '=' : ''; |
| 288 | + $conds[] = "oi_name = " . $dbr->addQuotes( $this->title->getDBkey() ); |
| 289 | + if( $start ) { |
| 290 | + $conds[] = "oi_timestamp <$eq " . $dbr->addQuotes( $dbr->timestamp( $start ) ); |
| 291 | + } |
| 292 | + if( $end ) { |
| 293 | + $conds[] = "oi_timestamp >$eq " . $dbr->addQuotes( $dbr->timestamp( $end ) ); |
| 294 | + } |
| 295 | + if( $limit ) { |
| 296 | + $opts['LIMIT'] = $limit; |
| 297 | + } |
| 298 | + // Search backwards for time > x queries |
| 299 | + $order = ( !$start && $end !== null ) ? 'ASC' : 'DESC'; |
| 300 | + $opts['ORDER BY'] = "oi_timestamp $order"; |
| 301 | + $opts['USE INDEX'] = array( 'oldimage' => 'oi_name_timestamp' ); |
| 302 | + |
| 303 | + wfRunHooks( 'LocalFile::getHistory', array( &$this, &$tables, &$fields, |
| 304 | + &$conds, &$opts, &$join_conds ) ); |
| 305 | + |
| 306 | + $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $opts, $join_conds ); |
| 307 | + $r = array(); |
| 308 | + foreach( $res as $row ) { |
| 309 | + /* This is the part that changed from LocalFile */ |
| 310 | + if ( $this->repo->oldFileFromRowFactory ) { |
| 311 | + $r[] = call_user_func( $this->repo->oldFileFromRowFactory, $row, $this->repo ); |
| 312 | + } else { |
| 313 | + $r[] = OldLocalFile::newFromRow( $row, $this->repo ); |
| 314 | + } |
| 315 | + /* End of changes */ |
| 316 | + } |
| 317 | + if( $order == 'ASC' ) { |
| 318 | + $r = array_reverse( $r ); // make sure it ends up descending |
| 319 | + } |
| 320 | + return $r; |
| 321 | + } |
| 322 | + |
| 323 | + |
| 324 | + |
| 325 | + /** Instantiating this class using "self" |
| 326 | + * If you're reading this, you're problably wondering why on earth are the following static functions, which are copied |
| 327 | + * verbatim from the original extended class "LocalFIle" included here? |
| 328 | + * The answer is that "self", will instantiate the class the code is physically in, not the class extended from it. |
| 329 | + * Without the inclusion of these methods in "NSLocalFile, "self" would instantiate a "LocalFile" class, not the |
| 330 | + * "NSLocalFile" class we want it to. Since there are only two methods within the "LocalFile" class that use "self", |
| 331 | + * I just copied that code into the new "NSLocalFile" extended class, and the copied code will instantiate the "NSLocalFIle" |
| 332 | + * class instead of the "LocalFile" class (at least in PHP 5.2.4) |
| 333 | + */ |
| 334 | + |
| 335 | + /** |
| 336 | + * Create a NSLocalFile from a title |
| 337 | + * Do not call this except from inside a repo class. |
| 338 | + * |
| 339 | + * Note: $unused param is only here to avoid an E_STRICT |
| 340 | + */ |
| 341 | + static function newFromTitle( $title, $repo, $unused = null ) { |
| 342 | + return new self( $title, $repo ); |
| 343 | + } |
| 344 | + /** |
| 345 | + * Create a NSLocalFile from a title |
| 346 | + * Do not call this except from inside a repo class. |
| 347 | + */ |
| 348 | + |
| 349 | + static function newFromRow( $row, $repo ) { |
| 350 | + $title = Title::makeTitle( NS_FILE, $row->img_name ); |
| 351 | + $file = new self( $title, $repo ); |
| 352 | + $file->loadFromRow( $row ); |
| 353 | + return $file; |
| 354 | + } |
| 355 | +} |
| 356 | + |
| 357 | +class NSOldLocalFile extends OldLocalFile { |
| 358 | + |
| 359 | + function getRel() { |
| 360 | + return 'archive/' . $this->getHashPath() . |
| 361 | + $this->getFileNameStripped( $this->getArchiveName() ); |
| 362 | + } |
| 363 | + function getUrlRel() { |
| 364 | + return 'archive/' . $this->getHashPath() . |
| 365 | + urlencode( $this->getFileNameStripped( $this->getArchiveName() ) ); |
| 366 | + } |
| 367 | + function publish( $srcPath, $flags = 0 ) { |
| 368 | + return NSLocalFile::publish( $srcPath, $flags ); |
| 369 | + } |
| 370 | + function getThumbUrl( $suffix = false ) { |
| 371 | + return NSLocalFile::getThumbUrl( $suffix ); |
| 372 | + } |
| 373 | + function thumbName( $params ) { |
| 374 | + return NSLocalFile::thumbName( $params ); |
| 375 | + } |
| 376 | + function getThumbPath( $suffix = false ) { |
| 377 | + return NSLocalFile::getThumbPath( $suffix ); |
| 378 | + } |
| 379 | + function getArchiveRel( $suffix = false ) { |
| 380 | + return NSLocalFile::getArchiveRel( $suffix ); |
| 381 | + } |
| 382 | + function getArchiveUrl( $suffix = false ) { |
| 383 | + return NSLocalFile::getArchiveUrl( $suffix ); |
| 384 | + } |
| 385 | + function getArchiveVirtualUrl( $suffix = false ) { |
| 386 | + return NSLocalFile::getArchiveVirtualUrl( $suffix ); |
| 387 | + } |
| 388 | + function getThumbVirtualUrl( $suffix = false ) { |
| 389 | + return NSLocalFile::getArchiveVirtualUrl( $suffix ); |
| 390 | + } |
| 391 | + function getVirtualUrl( $suffix = false ) { |
| 392 | + return NSLocalFile::getVirtualUrl( $suffix ); |
| 393 | + } |
| 394 | + function getFileNameStripped($suffix) { |
| 395 | + return NSLocalFile::getFileNameStripped( $suffix ); |
| 396 | + } |
| 397 | + function addOlds() { |
| 398 | + return NSLocalFile::addOlds(); |
| 399 | + } |
| 400 | + function purgeThumbnails() { |
| 401 | + return NSLocalFile::purgeThumbnails(); |
| 402 | + } |
| 403 | + /** |
| 404 | + * Replaces hard coded OldLocalFile::newFromRow to use $this->repo->oldFileFromRowFactory configuration |
| 405 | + * This may not be necessary in the future if LocalFile is patched to allow configuration |
| 406 | + */ |
| 407 | + function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
| 408 | + return NSLocalFile::getHistory( $limit, $start , $end, $inc ); |
| 409 | + } |
| 410 | + |
| 411 | + /** See comment above about Instantiating this class using "self" */ |
| 412 | + |
| 413 | + static function newFromTitle( $title, $repo, $time = null ) { |
| 414 | + # The null default value is only here to avoid an E_STRICT |
| 415 | + if( $time === null ) |
| 416 | + throw new MWException( __METHOD__.' got null for $time parameter' ); |
| 417 | + return new self( $title, $repo, $time, null ); |
| 418 | + } |
| 419 | + |
| 420 | + static function newFromArchiveName( $title, $repo, $archiveName ) { |
| 421 | + return new self( $title, $repo, null, $archiveName ); |
| 422 | + } |
| 423 | + |
| 424 | + static function newFromRow( $row, $repo ) { |
| 425 | + $title = Title::makeTitle( NS_FILE, $row->oi_name ); |
| 426 | + $file = new self( $title, $repo, null, $row->oi_archive_name ); |
| 427 | + $file->loadFromRow( $row, 'oi_' ); |
| 428 | + return $file; |
| 429 | + } |
| 430 | +} |
Property changes on: trunk/extensions/NSFileRepo/NSFileRepo_body.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 431 | + native |
Index: trunk/extensions/NSFileRepo/NSFileRepo.php |
— | — | @@ -21,16 +21,18 @@ |
22 | 22 | * It must be included(required) after Lockdown! Also, $wgHashedUploadDirectory must be true and cannot be changed once repository has files in it |
23 | 23 | */ |
24 | 24 | |
25 | | -if (!defined('MEDIAWIKI')) die('Not an entry point.'); |
| 25 | +if ( !defined( 'MEDIAWIKI' ) ) die( 'Not an entry point.' ); |
26 | 26 | if (!function_exists('lockdownUserCan')) die('You MUST load Extension Lockdown before NSFileRepo (http://www.mediawiki.org/wiki/Extension:Lockdown).'); |
27 | 27 | |
28 | 28 | $wgImgAuthPublicTest = false; // Must be set to false if you want to use more restrictive than general ['*']['read'] |
29 | 29 | $wgIllegalFileChars = isset($wgIllegalFileChars) ? $wgIllegalFileChars : ""; // For MW Versions <1.16 |
30 | 30 | $wgIllegalFileChars = str_replace(":","",$wgIllegalFileChars); // Remove the default illegal char ':' - need it to determine NS |
31 | 31 | |
| 32 | +$dir = dirname( __FILE__ ) . '/'; |
| 33 | + |
32 | 34 | # Internationalisation file |
33 | | -$wgExtensionMessagesFiles['NSFileRepo'] = dirname(__FILE__) .'/NSFileRepo.i18n.php'; |
34 | | -$wgExtensionMessagesFiles['img_auth'] = dirname(__FILE__) .'/img_auth.i18n.php'; |
| 35 | +$wgExtensionMessagesFiles['NSFileRepo'] = $dir . 'NSFileRepo.i18n.php'; |
| 36 | +$wgExtensionMessagesFiles['img_auth'] = $dir . 'img_auth.i18n.php'; |
35 | 37 | |
36 | 38 | $wgExtensionFunctions[] = 'NSFileRepoSetup'; |
37 | 39 | $wgExtensionCredits['media'][] = array( |
— | — | @@ -43,483 +45,80 @@ |
44 | 46 | ); |
45 | 47 | |
46 | 48 | /** |
47 | | - * Set up hooks for NSFileRepo |
| 49 | + * Classes |
48 | 50 | */ |
| 51 | +$wgAutoloadClasses['NSLocalRepo'] = $dir . 'NSFileRepo_body.php'; |
| 52 | +$wgAutoloadClasses['NSLocalFile'] = $dir . 'NSFileRepo_body.php'; |
| 53 | +$wgAutoloadClasses['NSOldLocalFile'] = $dir . 'NSFileRepo_body.php'; |
49 | 54 | |
50 | | -$wgHooks['UploadForm:BeforeProcessing'][] = 'NSFileRepoNSCheck'; |
51 | 55 | /** |
52 | | -Note, this must be AFTER lockdown has been included - thus assuming that the user has access to files in general + files at this particular namespace. |
53 | | -*/ |
| 56 | + * Set up hooks for NSFileRepo |
| 57 | + */ |
| 58 | +$wgHooks['UploadForm:BeforeProcessing'][] = 'NSFileRepoNSCheck'; |
| 59 | +// Note, this must be AFTER lockdown has been included - thus assuming that the |
| 60 | +// user has access to files in general + files at this particular namespace. |
54 | 61 | $wgHooks['userCan'][] = 'NSFileRepolockdownUserCan'; |
55 | 62 | $wgHooks['ImgAuthBeforeStream'][] = 'NSFileRepoImgAuthCheck'; |
56 | 63 | |
57 | | -class NSLocalRepo extends LocalRepo { |
58 | | - var $fileFactory = array( 'NSLocalFile', 'newFromTitle' ); |
59 | | - var $oldFileFactory = array( 'NSOldLocalFile', 'newFromTitle' ); |
60 | | - var $fileFromRowFactory = array( 'NSLocalFile', 'newFromRow' ); |
61 | | - var $oldFileFromRowFactory = array( 'NSOldLocalFile', 'newFromRow' ); |
62 | | - |
63 | | - static function getHashPathForLevel( $name, $levels ) { |
64 | | - global $wgContLang; |
65 | | - $bits=explode(':',$name); |
66 | | - $filename = $bits[count($bits)-1]; |
67 | | - $path = parent::getHashPathForLevel( $filename, $levels ); |
68 | | - return ((count($bits) > 1) ? $wgContLang->getNsIndex($bits[0]).'/'.$path : $path); |
69 | | - } |
70 | | - /** |
71 | | - * Get a relative path including trailing slash, e.g. f/fa/ |
72 | | - * If the repo is not hashed, returns an empty string |
73 | | - * This is needed because self:: will call parent if not included - exact same as in FSRepo |
74 | | - */ |
75 | | - function getHashPath( $name ) { |
76 | | - return self::getHashPathForLevel( $name, $this->hashLevels ); |
77 | | - } |
78 | | - /** |
79 | | - * Pick a random name in the temp zone and store a file to it. |
80 | | - * @param string $originalName The base name of the file as specified |
81 | | - * by the user. The file extension will be maintained. |
82 | | - * @param string $srcPath The current location of the file. |
83 | | - * @return FileRepoStatus object with the URL in the value. |
84 | | - */ |
85 | | - function storeTemp( $originalName, $srcPath ) { |
86 | | - $date = gmdate( "YmdHis" ); |
87 | | - $hashPath = $this->getHashPath( $originalName ); |
88 | | - $filename = $this->getFileNameStripped($originalName); |
89 | | - $dstRel = "$hashPath$date!$filename"; |
90 | | - $dstUrlRel = $hashPath . $date . '!' . rawurlencode( $filename ); |
91 | | - $result = $this->store( $srcPath, 'temp', $dstRel ); |
92 | | - $result->value = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; |
93 | | - return $result; |
94 | | - } |
95 | | - function getFileNameStripped($suffix) { |
96 | | - return(NSLocalFile::getFileNameStripped($suffix)); |
97 | | - } |
98 | | -} |
99 | | - |
100 | | -class NSLocalFile extends LocalFile |
101 | | -{ |
102 | | - /** |
103 | | - * Get the path of the file relative to the public zone root |
104 | | - */ |
105 | | - function getRel() { |
106 | | - return $this->getHashPath() . $this->getFileNameStripped($this->getName()); |
107 | | - } |
108 | | - |
109 | | - /** |
110 | | - * Get urlencoded relative path of the file |
111 | | - */ |
112 | | - function getUrlRel() { |
113 | | - return $this->getHashPath() . rawurlencode( $this->getFileNameStripped($this->getName())); |
114 | | - } |
115 | | - |
116 | | - /** Get the URL of the thumbnail directory, or a particular file if $suffix is specified */ |
117 | | - function getThumbUrl( $suffix = false ) { |
118 | | - $path = $this->repo->getZoneUrl('thumb') . '/' . $this->getUrlRel(); |
119 | | - if ( $suffix !== false ) { |
120 | | - $path .= '/' . rawurlencode( $this->getFileNameStripped($suffix) ); |
121 | | - } |
122 | | - return $path; |
123 | | - } |
124 | | - |
125 | | - |
126 | | - /** Return the file name of a thumbnail with the specified parameters */ |
127 | | - function thumbName( $params ) { |
128 | | - if ( !$this->getHandler() ) { |
129 | | - return null; |
130 | | - } |
131 | | - $extension = $this->getExtension(); |
132 | | - list( $thumbExt, $thumbMime ) = $this->handler->getThumbType( $extension, $this->getMimeType() ); |
133 | | -/* This is the part that changed from LocalFile */ |
134 | | - $thumbName = $this->handler->makeParamString( $params ) . '-' . $this->getFileNameStripped($this->getName()); |
135 | | -/* End of changes */ |
136 | | - if ( $thumbExt != $extension ) { |
137 | | - $thumbName .= ".$thumbExt"; |
138 | | - } |
139 | | - $bits=explode(':',$this->getName()); |
140 | | - if (count($bits) > 1) $thumbName = $bits[0].":".$thumbName; |
141 | | - return $thumbName; |
142 | | - } |
143 | | - |
144 | | - |
145 | | - /** Get the path of the thumbnail directory, or a particular file if $suffix is specified */ |
146 | | - function getThumbPath( $suffix = false ) { |
147 | | - $path = $this->repo->getZonePath('thumb') . '/' . $this->getRel(); |
148 | | - if ( $suffix !== false ) { |
149 | | - $path .= '/' . $this->getFileNameStripped($suffix); |
150 | | - } |
151 | | - return $path; |
152 | | - } |
153 | | - |
154 | | - /** Get the relative path for an archive file */ |
155 | | - function getArchiveRel( $suffix = false ) { |
156 | | - $path = 'archive/' . $this->getHashPath(); |
157 | | - if ( $suffix === false ) { |
158 | | - $path = substr( $path, 0, -1 ); |
159 | | - } else { |
160 | | - $path .= $this->getFileNameStripped($suffix); |
161 | | - } |
162 | | - return $path; |
163 | | - } |
164 | | - |
165 | | - /** Get the URL of the archive directory, or a particular file if $suffix is specified */ |
166 | | - function getArchiveUrl( $suffix = false ) { |
167 | | - $path = $this->repo->getZoneUrl('public') . '/archive/' . $this->getHashPath(); |
168 | | - if ( $suffix === false ) { |
169 | | - $path = substr( $path, 0, -1 ); |
170 | | - } else { |
171 | | - $path .= rawurlencode( $this->getFileNameStripped($suffix) ); |
172 | | - } |
173 | | - return $path; |
174 | | - } |
175 | | - |
176 | | - /** Get the virtual URL for an archive file or directory */ |
177 | | - function getArchiveVirtualUrl( $suffix = false ) { |
178 | | - $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath(); |
179 | | - if ( $suffix === false ) { |
180 | | - $path = substr( $path, 0, -1 ); |
181 | | - } else { |
182 | | - $path .= rawurlencode( $this->getFileNameStripped($suffix) ); |
183 | | - } |
184 | | - return $path; |
185 | | - } |
186 | | - |
187 | | - /** Get the virtual URL for a thumbnail file or directory */ |
188 | | - function getThumbVirtualUrl( $suffix = false ) { |
189 | | - $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel(); |
190 | | - if ( $suffix !== false ) { |
191 | | - $path .= '/' . rawurlencode( $this->getFileNameStripped($suffix) ); |
192 | | - } |
193 | | - return $path; |
194 | | - } |
195 | | - |
196 | | - /** Get the virtual URL for the file itself */ |
197 | | - function getVirtualUrl( $suffix = false ) { |
198 | | - $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel(); |
199 | | - if ( $suffix !== false ) { |
200 | | - $path .= '/' . rawurlencode( $this->getFileNameStripped($suffix) ); |
201 | | - } |
202 | | - return $path; |
203 | | - } |
204 | | - |
205 | | - /** Strip namespace (if any) from file name */ |
206 | | - function getFileNameStripped($suffix) { |
207 | | - $bits=explode(':',$suffix); |
208 | | - return $bits[count($bits)-1]; |
209 | | - } |
210 | | - |
211 | | - /** |
212 | | - * This function overrides the LocalFile because the archive name should not contain the namespace in the |
213 | | - * filename. Otherwise the function would have worked. This only affects reuploads |
214 | | - * |
215 | | - * Move or copy a file to its public location. If a file exists at the |
216 | | - * destination, move it to an archive. Returns the archive name on success |
217 | | - * or an empty string if it was a new file, and a wikitext-formatted |
218 | | - * WikiError object on failure. |
219 | | - * |
220 | | - * The archive name should be passed through to recordUpload for database |
221 | | - * registration. |
222 | | - * |
223 | | - * @param string $sourcePath Local filesystem path to the source image |
224 | | - * @param integer $flags A bitwise combination of: |
225 | | - * File::DELETE_SOURCE Delete the source file, i.e. move |
226 | | - * rather than copy |
227 | | - * @return FileRepoStatus object. On success, the value member contains the |
228 | | - * archive name, or an empty string if it was a new file. |
229 | | - */ |
230 | | - function publish( $srcPath, $flags = 0 ) { |
231 | | - $this->lock(); |
232 | | - $dstRel = $this->getRel(); |
233 | | -/* This is the part that changed from LocalFile */ |
234 | | - $archiveName = gmdate( 'YmdHis' ) . '!'.$this->getFileNameStripped($this->getName()); |
235 | | -/* End of changes */ |
236 | | - $archiveRel = 'archive/' . $this->getHashPath() . $archiveName; |
237 | | - $flags = $flags & File::DELETE_SOURCE ? LocalRepo::DELETE_SOURCE : 0; |
238 | | - $status = $this->repo->publish( $srcPath, $dstRel, $archiveRel, $flags ); |
239 | | - if ( $status->value == 'new' ) { |
240 | | - $status->value = ''; |
241 | | - } else { |
242 | | - $status->value = $archiveName; |
243 | | - } |
244 | | - $this->unlock(); |
245 | | - return $status; |
246 | | - } |
247 | | - |
248 | | - /** |
249 | | - * The only thing changed here is that the array needs to strip the NS from the file name for the has (oldname is already fixed) |
250 | | - * Add the old versions of the image to the batch |
251 | | - */ |
252 | | - function addOlds() { |
253 | | - $archiveBase = 'archive'; |
254 | | - $this->olds = array(); |
255 | | - $this->oldCount = 0; |
256 | | - |
257 | | - $result = $this->db->select( 'oldimage', |
258 | | - array( 'oi_archive_name', 'oi_deleted' ), |
259 | | - array( 'oi_name' => $this->oldName ), |
260 | | - __METHOD__ |
261 | | - ); |
262 | | - while( $row = $this->db->fetchObject( $result ) ) { |
263 | | - $oldName = $row->oi_archive_name; |
264 | | - $bits = explode( '!', $oldName, 2 ); |
265 | | - if( count( $bits ) != 2 ) { |
266 | | - wfDebug( "Invalid old file name: $oldName \n" ); |
267 | | - continue; |
268 | | - } |
269 | | - list( $timestamp, $filename ) = $bits; |
270 | | - if( $this->oldName != $filename ) { |
271 | | - wfDebug( "Invalid old file name: $oldName \n" ); |
272 | | - continue; |
273 | | - } |
274 | | - $this->oldCount++; |
275 | | - // Do we want to add those to oldCount? |
276 | | - if( $row->oi_deleted & File::DELETED_FILE ) { |
277 | | - continue; |
278 | | - } |
279 | | - $this->olds[] = array( |
280 | | - "{$archiveBase}/{$this->oldHash}{$oldName}", |
281 | | -/* This is the part that changed from LocalFile */ |
282 | | - "{$archiveBase}/{$this->newHash}{$timestamp}!".$this->getFileNameStripped($this->newName) |
283 | | -/* End of changes */ |
284 | | - ); |
285 | | - } |
286 | | - $this->db->freeResult( $result ); |
287 | | - } |
288 | | - |
289 | | - /** |
290 | | - * The only thing changed here is to strip NS from the file name |
291 | | - * Delete cached transformed files |
292 | | - */ |
293 | | - |
294 | | - function purgeThumbnails() { |
295 | | - global $wgUseSquid; |
296 | | - // Delete thumbnails |
297 | | - $files = $this->getThumbnails(); |
298 | | - $dir = $this->getThumbPath(); |
299 | | - $urls = array(); |
300 | | - foreach ( $files as $file ) { |
301 | | - # Check that the base file name is part of the thumb name |
302 | | - # This is a basic sanity check to avoid erasing unrelated directories |
303 | | - |
304 | | -/* This is the part that changed from LocalFile */ |
305 | | - if ( strpos( $file, $this->getFileNameStripped($this->getName()) ) !== false ) { |
306 | | -/* End of changes */ |
307 | | - $url = $this->getThumbUrl( $file ); |
308 | | - $urls[] = $url; |
309 | | - @unlink( "$dir/$file" ); |
310 | | - } |
311 | | - } |
312 | | - |
313 | | - // Purge the squid |
314 | | - if ( $wgUseSquid ) { |
315 | | - SquidUpdate::purge( $urls ); |
316 | | - } |
317 | | - } |
318 | | - |
319 | | - /** |
320 | | - * Replaces hard coded OldLocalFile::newFromRow to use $this->repo->oldFileFromRowFactory configuration |
321 | | - * This may not be necessary in the future if LocalFile is patched to allow configuration |
322 | | - */ |
323 | | - |
324 | | - function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
325 | | - $dbr = $this->repo->getSlaveDB(); |
326 | | - $tables = array( 'oldimage' ); |
327 | | - $fields = OldLocalFile::selectFields(); |
328 | | - $conds = $opts = $join_conds = array(); |
329 | | - $eq = $inc ? '=' : ''; |
330 | | - $conds[] = "oi_name = " . $dbr->addQuotes( $this->title->getDBkey() ); |
331 | | - if( $start ) { |
332 | | - $conds[] = "oi_timestamp <$eq " . $dbr->addQuotes( $dbr->timestamp( $start ) ); |
333 | | - } |
334 | | - if( $end ) { |
335 | | - $conds[] = "oi_timestamp >$eq " . $dbr->addQuotes( $dbr->timestamp( $end ) ); |
336 | | - } |
337 | | - if( $limit ) { |
338 | | - $opts['LIMIT'] = $limit; |
339 | | - } |
340 | | - // Search backwards for time > x queries |
341 | | - $order = ( !$start && $end !== null ) ? 'ASC' : 'DESC'; |
342 | | - $opts['ORDER BY'] = "oi_timestamp $order"; |
343 | | - $opts['USE INDEX'] = array( 'oldimage' => 'oi_name_timestamp' ); |
344 | | - |
345 | | - wfRunHooks( 'LocalFile::getHistory', array( &$this, &$tables, &$fields, |
346 | | - &$conds, &$opts, &$join_conds ) ); |
347 | | - |
348 | | - $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $opts, $join_conds ); |
349 | | - $r = array(); |
350 | | - while( $row = $dbr->fetchObject( $res ) ) { |
351 | | -/* This is the part that changed from LocalFile */ |
352 | | - if ( $this->repo->oldFileFromRowFactory ) { |
353 | | - $r[] = call_user_func( $this->repo->oldFileFromRowFactory, $row, $this->repo ); |
354 | | - } else { |
355 | | - $r[] = OldLocalFile::newFromRow( $row, $this->repo ); |
356 | | - } |
357 | | -/* End of changes */ |
358 | | - } |
359 | | - if( $order == 'ASC' ) { |
360 | | - $r = array_reverse( $r ); // make sure it ends up descending |
361 | | - } |
362 | | - return $r; |
363 | | - } |
364 | | - |
365 | | - |
366 | | - |
367 | | - /** Instantiating this class using "self" |
368 | | - * If you're reading this, you're problably wondering why on earth are the following static functions, which are copied |
369 | | - * verbatim from the original extended class "LocalFIle" included here? |
370 | | - * The answer is that "self", will instantiate the class the code is physically in, not the class extended from it. |
371 | | - * Without the inclusion of these methods in "NSLocalFile, "self" would instantiate a "LocalFile" class, not the |
372 | | - * "NSLocalFile" class we want it to. Since there are only two methods within the "LocalFile" class that use "self", |
373 | | - * I just copied that code into the new "NSLocalFile" extended class, and the copied code will instantiate the "NSLocalFIle" |
374 | | - * class instead of the "LocalFile" class (at least in PHP 5.2.4) |
375 | | - */ |
376 | | - |
377 | | - /** |
378 | | - * Create a NSLocalFile from a title |
379 | | - * Do not call this except from inside a repo class. |
380 | | - * |
381 | | - * Note: $unused param is only here to avoid an E_STRICT |
382 | | - */ |
383 | | - static function newFromTitle( $title, $repo, $unused = null ) { |
384 | | - return new self( $title, $repo ); |
385 | | - } |
386 | | - /** |
387 | | - * Create a NSLocalFile from a title |
388 | | - * Do not call this except from inside a repo class. |
389 | | - */ |
390 | | - |
391 | | - static function newFromRow( $row, $repo ) { |
392 | | - $title = Title::makeTitle( NS_IMAGE, $row->img_name ); |
393 | | - $file = new self( $title, $repo ); |
394 | | - $file->loadFromRow( $row ); |
395 | | - return $file; |
396 | | - } |
397 | | -} |
398 | | -class NSOldLocalFile extends OldLocalFile |
399 | | -{ |
400 | | - |
401 | | - function getRel() { |
402 | | - return 'archive/' . $this->getHashPath() . $this->getFileNameStripped($this->getArchiveName()); |
403 | | - } |
404 | | - function getUrlRel() { |
405 | | - return 'archive/' . $this->getHashPath() . urlencode( $this->getFileNameStripped($this->getArchiveName()) ); |
406 | | - } |
407 | | - function publish( $srcPath, $flags = 0 ) { |
408 | | - return NSLocalFile::publish( $srcPath, $flags ); |
409 | | - } |
410 | | - function getThumbUrl( $suffix = false ) { |
411 | | - return(NSLocalFile::getThumbUrl( $suffix ) ); |
412 | | - } |
413 | | - function thumbName( $params ) { |
414 | | - return(NSLocalFile::thumbName( $params )); |
415 | | - } |
416 | | - function getThumbPath( $suffix = false ) { |
417 | | - return(NSLocalFile::getThumbPath( $suffix )); |
418 | | - } |
419 | | - function getArchiveRel( $suffix = false ) { |
420 | | - return(NSLocalFile::getArchiveRel( $suffix )); |
421 | | - } |
422 | | - function getArchiveUrl( $suffix = false ) { |
423 | | - return(NSLocalFile::getArchiveUrl( $suffix )); |
424 | | - } |
425 | | - function getArchiveVirtualUrl( $suffix = false ) { |
426 | | - return(NSLocalFile::getArchiveVirtualUrl( $suffix )); |
427 | | - } |
428 | | - function getThumbVirtualUrl( $suffix = false ) { |
429 | | - return(NSLocalFile::getArchiveVirtualUrl( $suffix )); |
430 | | - } |
431 | | - function getVirtualUrl( $suffix = false ) { |
432 | | - return(NSLocalFile::getVirtualUrl( $suffix )); |
433 | | - } |
434 | | - function getFileNameStripped($suffix) { |
435 | | - return(NSLocalFile::getFileNameStripped($suffix)); |
436 | | - } |
437 | | - function addOlds() { |
438 | | - return(NSLocalFile::addOlds()); |
439 | | - } |
440 | | - function purgeThumbnails() { |
441 | | - return(NSLocalFile::purgeThumbnails()); |
442 | | - } |
443 | | - /** |
444 | | - * Replaces hard coded OldLocalFile::newFromRow to use $this->repo->oldFileFromRowFactory configuration |
445 | | - * This may not be necessary in the future if LocalFile is patched to allow configuration |
446 | | - */ |
447 | | - function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
448 | | - return(NSLocalFile::getHistory( $limit, $start , $end, $inc) ); |
449 | | - } |
450 | | - |
451 | | - /** See comment above about Instantiating this class using "self" */ |
452 | | - |
453 | | - static function newFromTitle( $title, $repo, $time = null ) { |
454 | | - # The null default value is only here to avoid an E_STRICT |
455 | | - if( $time === null ) |
456 | | - throw new MWException( __METHOD__.' got null for $time parameter' ); |
457 | | - return new self( $title, $repo, $time, null ); |
458 | | - } |
459 | | - |
460 | | - static function newFromArchiveName( $title, $repo, $archiveName ) { |
461 | | - return new self( $title, $repo, null, $archiveName ); |
462 | | - } |
463 | | - |
464 | | - static function newFromRow( $row, $repo ) { |
465 | | - $title = Title::makeTitle( NS_IMAGE, $row->oi_name ); |
466 | | - $file = new self( $title, $repo, null, $row->oi_archive_name ); |
467 | | - $file->loadFromRow( $row, 'oi_' ); |
468 | | - return $file; |
469 | | - } |
470 | | -} |
471 | | - |
472 | 64 | /** |
473 | 65 | * Initial setup, add .i18n. messages from $IP/extensions/DiscussionThreading/DiscussionThreading.i18n.php |
474 | 66 | */ |
475 | 67 | function NSFileRepoSetup() { |
476 | | - global $wgLocalFileRepo,$wgVersion; |
477 | | - $xversion = explode(".",$wgVersion); |
478 | | - if ($xversion[0] <= "1" && $xversion[1] < "16") wfLoadExtensionMessages( 'img_auth' ); // loads img_auth messages for versions <1.16 |
| 68 | + global $wgLocalFileRepo, $wgVersion; |
| 69 | + // loads img_auth messages for versions <1.16 |
| 70 | + if( version_compare( $wgVersion, '1.16' ) ) { |
| 71 | + wfLoadExtensionMessages( 'img_auth' ); |
| 72 | + } |
479 | 73 | wfLoadExtensionMessages( 'NSFileRepo' ); |
480 | 74 | $wgLocalFileRepo['class'] = "NSLocalRepo"; |
481 | 75 | RepoGroup::destroySingleton(); |
482 | 76 | } |
| 77 | + |
483 | 78 | /* |
484 | 79 | * Check for Namespace in Title Line |
485 | 80 | */ |
486 | | -function NSFileRepoNSCheck($UploadForm) { |
487 | | - $title = Title::newFromText($UploadForm->mDesiredDestName); |
488 | | - if ($title->mNamespace < 100) { |
489 | | - $UploadForm->mDesiredDestName = preg_replace ( "/:/", '-', $UploadForm->mDesiredDestName); |
| 81 | +function NSFileRepoNSCheck( $uploadForm ) { |
| 82 | + $title = Title::newFromText($uploadForm->mDesiredDestName); |
| 83 | + if ( $title->getNamespace() < 100 ) { |
| 84 | + $uploadForm->mDesiredDestName = preg_replace( "/:/", '-', $uploadForm->mDesiredDestName ); |
490 | 85 | } else { |
491 | | - $bits=explode(':',$UploadForm->mDesiredDestName); |
492 | | - $ns = array_shift($bits); |
493 | | - $UploadForm->mDesiredDestName = $ns.":".implode("-",$bits); |
| 86 | + $bits = explode( ':', $uploadForm->mDesiredDestName ); |
| 87 | + $ns = array_shift( $bits ); |
| 88 | + $uploadForm->mDesiredDestName = $ns.":" . implode( "-", $bits ); |
494 | 89 | } |
495 | | - return (true); |
| 90 | + return true; |
496 | 91 | } |
497 | 92 | |
498 | | -// If Extension:Lockdown has been activated (recommend), check individual namespace protection |
499 | | - |
500 | | -function NSFileRepolockdownUserCan($title, $user, $action, &$result) { |
| 93 | +/** |
| 94 | + * If Extension:Lockdown has been activated (recommend), check individual namespace protection |
| 95 | + */ |
| 96 | +function NSFileRepolockdownUserCan( $title, $user, $action, &$result) { |
501 | 97 | global $wgWhitelistRead; |
502 | | - if (in_array($title->getPrefixedText(), $wgWhitelistRead)) return true; |
503 | | - if (function_exists('lockdownUserCan')){ |
504 | | - if($title->getNamespace() == NS_IMAGE) { |
505 | | - $ntitle = Title::newFromText($title->mDbkeyform); |
506 | | - return ($ntitle->mNamespace < 100) ? true : lockdownUserCan($ntitle, $user, $action, $result); |
| 98 | + if ( in_array( $title->getPrefixedText(), $wgWhitelistRead ) ) { |
| 99 | + return true; |
| 100 | + } elseif( function_exists( 'lockdownUserCan' ) ) { |
| 101 | + if( $title->getNamespace() == NS_FILE ) { |
| 102 | + $ntitle = Title::newFromText( $title->mDbkeyform ); |
| 103 | + return ( $ntitle->getNamespace() < 100 ) ? |
| 104 | + true : lockdownUserCan( $ntitle, $user, $action, $result ); |
507 | 105 | } |
508 | 106 | } |
509 | 107 | return true; |
510 | 108 | } |
511 | 109 | |
512 | | -function NSFileRepoImgAuthCheck($title, $path, $name, $result) { |
| 110 | +function NSFileRepoImgAuthCheck( $title, $path, $name, $result ) { |
513 | 111 | global $wgContLang; |
514 | 112 | |
515 | | -# See if stored in a NS path |
516 | | - |
| 113 | + # See if stored in a NS path |
517 | 114 | $subdirs = explode('/',$path); |
518 | 115 | $x = (!is_numeric($subdirs[1]) && ($subdirs[1] == "archive" || $subdirs[1] == "deleted" || $subdirs[1] == "thumb")) ? 2 : 1; |
519 | 116 | $x = ($x == 2 && $subdirs[1] == "thumb" && $subdirs[2] == "archive") ? 3 : $x; |
520 | | - if (strlen($subdirs[$x]) >= 3 && is_numeric($subdirs[$x]) && $subdirs[$x] >= 100) { |
521 | | - $title = Title::makeTitleSafe( NS_IMAGE, $wgContLang->getNsText($subdirs[$x]).":".$name ); |
| 117 | + if ( strlen( $subdirs[$x] ) >= 3 && is_numeric( $subdirs[$x] ) |
| 118 | + && $subdirs[$x] >= 100 ) |
| 119 | + { |
| 120 | + $title = Title::makeTitleSafe( NS_FILE, $wgContLang->getNsText( $subdirs[$x] ) . ":" . $name ); |
522 | 121 | if( !$title instanceof Title ) { |
523 | | - $result = array('img-auth-accessdenied','img-auth-badtitle',$name); |
| 122 | + $result = array( 'img-auth-accessdenied', 'img-auth-badtitle', $name ); |
524 | 123 | return false; |
525 | 124 | } |
526 | 125 | } |