Preliminary support for shared upload directory. This is primarily intended
authorErik Moeller <erik@users.mediawiki.org>
Thu, 21 Oct 2004 05:04:14 +0000 (05:04 +0000)
committerErik Moeller <erik@users.mediawiki.org>
Thu, 21 Oct 2004 05:04:14 +0000 (05:04 +0000)
for the Wikimedia Commons. If $wgUseSharedUploads is set, MediaWiki will try
to locate an image file in the shared upload directory if it is not found
locally. Thumbnails for shared images will also be generated in the
shared directory.

Note: I changed
                $text = $this->replaceInternalLinks ( $text );
                $text = $this->replaceExternalLinks( $text );
to
                $text = $this->replaceExternalLinks( $text );
                $text = $this->replaceInternalLinks ( $text );

in Parser.php. Otherwise [[Media:Bla.jpg]] to an absolute URL would be
incorrectly parsed as external links. The header of
replaceExternalLinks says:

        Note: we have to do external links before the internal ones

So the old order was not consistent with the documentation. I did some
tests and nothing seems to be broken, but I have some problems executing
parserTests.php so I couldn't test it systematically.

includes/DefaultSettings.php
includes/Image.php
includes/ImagePage.php
includes/Parser.php
includes/Skin.php
languages/Language.php
skins/common/common.css
skins/monobook/main.css

index 4d239e5..825f5ec 100644 (file)
@@ -119,6 +119,30 @@ $wgTmpDirectory     = "{$wgUploadDirectory}/tmp";
 $wgUploadBaseUrl    = "";
 /**#@-*/
 
+# If you operate multiple wikis, you can define a shared upload
+# path here. Uploads to this wiki will NOT be put there - they
+# will be put into $wgUploadDirectory.
+#
+# If $wgUseSharedUploads is set, the wiki will look in the
+# shared repository if no file of the given name is found in
+# the local repository (for [[Image:..]], [[Media:..]] links).
+# Thumbnails will also be looked for and generated in this
+# directory.
+#
+$wgUseSharedUploads = false;
+# Leave this blank if it is the same server. NO FINAL SLASH -
+# it is concatenated with $wgSharedUploadPath.
+# Example: "http://commons.wikimedia.org"
+$wgSharedUploadBaseUrl = "";
+# Path on the web server where shared uploads can be found
+$wgSharedUploadPath = "/shared/images";
+# Path on the file system where shared uploads can be found
+$wgSharedUploadDirectory = "/var/www/wiki3/images";
+# Set this to false especially if you have a set of files that need to be
+# accessible by all wikis, and you do not want to use the hash (path/a/aa/)
+# directory layout.
+$wgHashedSharedUploadDirectory = true;
+
 
 # Email settings
 #
index abc4d08..6d5f369 100644 (file)
@@ -21,6 +21,7 @@ class Image
                $url,           # Image URL
                $title,         # Title object for this image. Initialized when needed.
                $fileExists,    # does the image file exist on disk?
+               $fromSharedDirectory, # load this image from $wgSharedUploadDirectory
                $historyLine,   # Number of line to return by nextHistoryLine()
                $historyRes,    # result of the query for the image's history
                $width,         # \
@@ -40,11 +41,14 @@ class Image
         */
        function Image( $name )
        {
-               global $wgUploadDirectory,$wgHashedUploadDirectory;
+               global $wgUploadDirectory,$wgHashedUploadDirectory,
+                      $wgUseSharedUploads, $wgSharedUploadDirectory, 
+                      $wgHashedSharedUploadDirectory;
 
                $this->name      = $name;
                $this->title     = Title::makeTitleSafe( NS_IMAGE, $this->name );
-               //$this->imagePath = wfImagePath( $name );
+               $this->fromSharedDirectory = false;             
+               
                if ($wgHashedUploadDirectory) {
                        $hash            = md5( $this->title->getDBkey() );
                        $this->imagePath = $wgUploadDirectory . '/' . $hash{0} . '/' .
@@ -52,13 +56,34 @@ class Image
                } else {
                        $this->imagePath = $wgUploadDirectory . '/' . $name;
                }
-
-               $this->url       = $this->wfImageUrl( $name );
+               $this->fileExists = file_exists( $this->imagePath);             
+               
+               # If the file is not found, and a shared upload directory 
+               # like the Wikimedia Commons is used, look for it there.
+               if (!$this->fileExists && $wgUseSharedUploads) {
+                       
+                       if($wgHashedSharedUploadDirectory) {                            
+                               $hash = md5( $this->title->getDBkey() );
+                               $this->imagePath = $wgSharedUploadDirectory . '/' . $hash{0} . '/' .
+                                       substr( $hash, 0, 2 ) . "/{$name}";
+                       } else {
+                               $this->imagePath = $wgSharedUploadDirectory . '/' . $name;
+                       }
+                       $this->fileExists = file_exists( $this->imagePath);
+                       $this->fromSharedDirectory = true;
+                       #wfDebug ("File from shared directory: ".$this->imagePath."\n");
+               }               
+               if($this->fileExists) {
+                       $this->url       = $this->wfImageUrl( $name, $this->fromSharedDirectory );
+               } else {
+                       $this->url='';
+               }
                
                $n = strrpos( $name, '.' );
                $this->extension = strtolower( $n ? substr( $name, $n + 1 ) : '' );
+                               
 
-               if ( $this->fileExists = file_exists( $this->imagePath ) ) // Sic!, "=" is intended
+               if ( $this->fileExists )
                {
                        if( $this->extension == 'svg' ) {
                                @$gis = getSVGsize( $this->imagePath );
@@ -77,7 +102,7 @@ class Image
                                }
                        }
                }
-               $this->historyLine = 0;
+               $this->historyLine = 0;                         
        }
 
        /**
@@ -207,18 +232,30 @@ class Image
        /**
         * Return the URL of an image, provided its name.
         *
-        * @param string $name  Name of the image, without the leading Image:
+        * @param string $name  Name of the image, without the leading "Image:"
+        * @param boolean $fromSharedDirectory  Should this be in $wgSharedUploadPath?   
         * @access public
         */
-       function wfImageUrl( $name )
+       function wfImageUrl( $name, $fromSharedDirectory = false )
        {
-               global $wgUploadPath,$wgUploadBaseUrl,$wgHashedUploadDirectory;
-               if ($wgHashedUploadDirectory) {
+               global $wgUploadPath,$wgUploadBaseUrl,$wgHashedUploadDirectory,
+                      $wgHashedSharedUploadDirectory,$wgSharedUploadBaseUrl,
+                      $wgSharedUploadPath;
+               if($fromSharedDirectory) {
+                       $hash = $wgHashedSharedUploadDirectory;
+                       $base = $wgSharedUploadBaseUrl;
+                       $path = $wgSharedUploadPath;
+               } else {
+                       $hash = $wgHashedUploadDirectory;
+                       $base = $wgUploadBaseUrl;
+                       $path = $wgUploadPath;
+               }                       
+               if ( $hash ) {
                        $hash = md5( $name );
-                       $url = "{$wgUploadBaseUrl}{$wgUploadPath}/" . $hash{0} . "/" .
+                       $url = "{$base}{$path}/" . $hash{0} . "/" .
                        substr( $hash, 0, 2 ) . "/{$name}";
                } else {
-                       $url = "{$wgUploadBaseUrl}{$wgUploadPath}/{$name}";
+                       $url = "{$base}{$path}/{$name}";
                }
                return wfUrlencode( $url );
        }
@@ -237,15 +274,26 @@ class Image
         *
         * @access private
         */
-       function thumbUrl( $width, $subdir='thumb' ) {
-               global $wgUploadPath,$wgHashedUploadDirectory;
+       function thumbUrl( $width, $subdir='thumb') {
+               global $wgUploadPath,$wgHashedUploadDirectory, $wgUploadBaseUrl,
+                      $wgSharedUploadPath,$wgSharedUploadDirectory,
+                      $wgHashedSharedUploadDirectory, $wgSharedUploadBaseUrl;
                $name = $this->thumbName( $width );
-               if ($wgHashedUploadDirectory) {
+               if($this->fromSharedDirectory) {
+                       $hashdir = $wgHashedSharedUploadDirectory;
+                       $base = $wgSharedUploadBaseUrl;
+                       $path = $wgSharedUploadPath;
+               } else {
+                       $hashdir = $wgHashedUploadDirectory;
+                       $base = $wgUploadBaseUrl;
+                       $path = $wgUploadPath;
+               }
+               if ($hashdir) {
                        $hash = md5( $name );
-                       $url = "{$wgUploadPath}/{$subdir}/" . $hash{0} . "/" . 
+                       $url = "{$base}{$path}/{$subdir}/" . $hash{0} . "/" . 
                                substr( $hash, 0, 2 ) . "/{$name}";
                } else {
-                       $url = "{$wgUploadPath}/{$subdir}/{$name}";
+                       $url = "{$base}{$path}/{$subdir}/{$name}";
                }
 
                return wfUrlencode($url);
@@ -311,7 +359,6 @@ class Image
         * @access private
         */
        function /* private */ renderThumb( $width ) {
-               global $wgUploadDirectory;
                global $wgImageMagickConvertCommand;
                global $wgUseImageMagick;
                global $wgUseSquid, $wgInternalServer;
@@ -319,9 +366,9 @@ class Image
                $width = IntVal( $width );
 
                $thumbName = $this->thumbName( $width );
-               $thumbPath = wfImageThumbDir( $thumbName ).'/'.$thumbName;
+               $thumbPath = wfImageThumbDir( $thumbName, 'thumb', $this->fromSharedDirectory ).'/'.$thumbName;
                $thumbUrl  = $this->thumbUrl( $width );
-
+               #wfDebug ( "Render name: $thumbName path: $thumbPath url: $thumbUrl\n");
                if ( ! $this->exists() )
                {
                        # If there is no image, there will be no thumbnail
@@ -362,7 +409,7 @@ class Image
                                $cmd  =  $wgImageMagickConvertCommand .
                                        " -quality 85 -background white -geometry {$width} ".
                                        escapeshellarg($this->imagePath) . " " .
-                                       escapeshellarg($thumbPath);
+                                       escapeshellarg($thumbPath);                             
                                $conv = shell_exec( $cmd );
                        } else {
                                # Use PHP's builtin GD library functions.
@@ -537,11 +584,12 @@ function wfImageDir( $fname )
  * 
  * @param string $fname                file name of the thumbnail file, including file size prefix
  * @param string $subdir       (optional) subdirectory of the image upload directory that should be used for storing the thumbnail. Default is 'thumb'
+ * @param boolean $shared      (optional) use the shared upload directory
  * @access public
  */
-function wfImageThumbDir( $fname , $subdir='thumb')
+function wfImageThumbDir( $fname , $subdir='thumb', $shared=false)
 {
-       return wfImageArchiveDir( $fname, $subdir );
+       return wfImageArchiveDir( $fname, $subdir, $shared );
 }
 
 /**
@@ -551,20 +599,22 @@ function wfImageThumbDir( $fname , $subdir='thumb')
  * 
  * @param string $fname                file name of the thumbnail file, including file size prefix
  * @param string $subdir       (optional) subdirectory of the image upload directory that should be used for storing the old version. Default is 'archive'
+ * @param boolean $shared      (optional) use the shared upload directory (only relevant for other functions which call this one)
  * @access public
  */
-function wfImageArchiveDir( $fname , $subdir='archive')
+function wfImageArchiveDir( $fname , $subdir='archive', $shared=false )
 {
-       global $wgUploadDirectory, $wgHashedUploadDirectory;
-
-       if (!$wgHashedUploadDirectory) { return $wgUploadDirectory.'/'.$subdir; }
+       global $wgUploadDirectory, $wgHashedUploadDirectory,
+              $wgSharedUploadDirectory, $wgHashedSharedUploadDirectory;
+       $dir = $shared ? $wgSharedUploadDirectory : $wgUploadDirectory;
+       $hashdir = $shared ? $wgHashedSharedUploadDirectory : $wgHashedUploadDirectory;
+       if (!$hashdir) { return $dir.'/'.$subdir; }
 
        $hash = md5( $fname );
        $oldumask = umask(0);
-
        # Suppress warning messages here; if the file itself can't
        # be written we'll worry about it then.
-       $archive = $wgUploadDirectory.'/'.$subdir;
+       $archive = $dir.'/'.$subdir;
        if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
        $archive .= '/' . $hash{0};
        if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
index 6eda491..5c9f342 100644 (file)
@@ -80,6 +80,9 @@ class ImagePage extends Article {
                        } else {
                                $s = "<div class=\"fullMedia\">".$sk->makeMediaLink($this->img->getName(),"")."</div>";
                        }
+                       if($this->img->fromSharedDirectory) {
+                               $s.="<div class=\"sharedUploadNotice\">".wfMsg("sharedupload")."</div>";
+                       }
                        $wgOut->addHTML( $s );
                }
        }
index d09c72c..beffc7a 100644 (file)
@@ -377,7 +377,7 @@ class Parser
        }
 
        /**
-        * restores pre, math, and heiro removed by strip()
+        * restores pre, math, and hiero removed by strip()
         *
         * always call unstripNoWiki() after this one
         * @access private
@@ -679,8 +679,8 @@ class Parser
                        $text = $wgDateFormatter->reformat( $this->mOptions->getDateFormat(), $text );
                }
                $text = $this->doAllQuotes( $text );
+               $text = $this->replaceExternalLinks( $text );           
                $text = $this->replaceInternalLinks ( $text );
-               $text = $this->replaceExternalLinks( $text );
                $text = $this->doMagicLinks( $text );
                $text = $this->doTableStuff( $text );
                $text = $this->formatHeadings( $text, $isMain );
index 482513c..90ad7f5 100644 (file)
@@ -1656,7 +1656,6 @@ class Skin {
 
        function makeImage( $url, $alt = '' ) {
                global $wgOut;
-
                if ( '' == $alt ) {
                        $alt = $this->fnamePart( $url );
                }
@@ -1778,7 +1777,7 @@ class Skin {
                $alt = str_replace( array('<', '>', '"'), array('&lt;', '&gt;', '&quot;'), $alt );
 
                $u = $nt->escapeLocalURL();
-               $uf = $nt->escapeFullURL();
+               $uf = $nt->escapeFullURL();             
                if ( $url == '' )
                {
                        $s = wfMsg( 'missingimage', $img->getName() );
@@ -1885,24 +1884,24 @@ class Skin {
        }
 
        function makeMediaLink( $name, $url, $alt = '' ) {
-               $nt = Title::makeTitleSafe( Namespace::getMedia(), $name );
+               $nt = Title::makeTitleSafe( NS_IMAGE, $name );
                return $this->makeMediaLinkObj( $nt, $alt );
        }
 
-       function makeMediaLinkObj( $nt, $alt = '' ) {
+       function makeMediaLinkObj( $nt, $alt = '' ) {           
                if ( ! isset( $nt ) )
                {
                        ### HOTFIX. Instead of breaking, return empty string.
                        $s = $alt;
                } else {
-                       $name = $nt->getDBKey();
-                       $url = Image::wfImageUrl( $name );
+                       $name = $nt->getDBKey();        
+                       $img   = Image::newFromTitle( $nt );
+                       $url = $img->getURL();
                        if ( empty( $alt ) ) {
                                $alt = preg_replace( '/\.(.+?)^/', '', $name );
                        }
-
                        $u = htmlspecialchars( $url );
-                       $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
+                       $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";                   
                }
                return $s;
        }
index 3c14530..e916f04 100644 (file)
@@ -939,7 +939,7 @@ agrees to license it under the terms of the $1.",
 'emptyfile'            => 'The file you uploaded seems to be empty. This might be due to a typo in the file name. Please check whether you really want to upload this file.',
 'fileexists'           => 'A file with this name exists already, please check $1 if you are not sure if you want to change it.',
 'successfulupload' => 'Successful upload',
-'fileuploaded' => "File uploaded successfully.
+'fileuploaded' => "File $1 uploaded successfully.
 Please follow this link: $2 to the description page and fill
 in information about the file, such as where it came from, when it was
 created and by whom, and anything else you may know about it. If this is an image, you can insert it like this: <tt><nowiki>[[Image:$1|thumb|Description]]</nowiki></tt>",
@@ -974,6 +974,7 @@ this old version, (rev) = revert to this old version.
 'imagelinks'   => 'Image links',
 'linkstoimage' => 'The following pages link to this image:',
 'nolinkstoimage' => 'There are no pages that link to this image.',
+'sharedupload' => 'This file is a shared upload and may be used by other projects.',
 
 # Statistics
 #
index 4e8bc08..fa8d816 100644 (file)
@@ -204,3 +204,7 @@ div.townBox dl dd {
        color: red;
        font-weight: bold;
 }
+
+.sharedUploadNotice {
+       font-style: italic;
+}
\ No newline at end of file
index 8101aaf..b79cb73 100644 (file)
@@ -920,3 +920,6 @@ span.newpage, span.minor, span.searchmatch {
 span.searchmatch {
        color: red;
 }
+.sharedUploadNotice {
+        font-style: italic;
+}
\ No newline at end of file