Basic integrated audio/video support, with Ogg implementation.
* JavaScript video player based loosely on Greg Maxwell's player * Image page text snippet customisation * Abstraction of transform parameters in the parser. Introduced Linker::makeImageLink2(). * Made canRender(), mustRender() depend on file, not just on handler. Moved width=0, height=0 checking to ImageHandler::canRender(), since audio streams have width=height=0 but should be rendered. Also: * Automatic upgrade for oldimage rows on image page view, allows media handler selection based on oi_*_mime * oi_*_mime unconditionally referenced, REQUIRES SCHEMA UPGRADE * Don't destroy file info for missing files on upgrade * Simple, centralised extension message file handling * Made MessageCache::loadAllMessages non-static, optimised for repeated-call case due to abuse in User.php * Support for lightweight parser output hooks, with callback whitelist for security * Moved Linker::formatSize() to Language, to join the new formatTimePeriod() and formatBitrate() * Introduced MagicWordArray, regex capture trick requires that magic word IDs DO NOT CONTAIN HYPHENS.
This commit is contained in:
parent
baa6cfc46b
commit
164bb322f2
31 changed files with 824 additions and 279 deletions
|
|
@ -173,6 +173,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
|
|||
* (bug 10872) Fall back to sane defaults when generating protection selector
|
||||
labels for custom restriction levels
|
||||
* Show edit count in user preferences
|
||||
* Improved support for audio/video extensions
|
||||
|
||||
== Bugfixes since 1.10 ==
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ function __autoload($className) {
|
|||
'LogPage' => 'includes/LogPage.php',
|
||||
'MacBinary' => 'includes/MacBinary.php',
|
||||
'MagicWord' => 'includes/MagicWord.php',
|
||||
'MagicWordArray' => 'includes/MagicWord.php',
|
||||
'MathRenderer' => 'includes/Math.php',
|
||||
'MediaTransformOutput' => 'includes/MediaTransformOutput.php',
|
||||
'ThumbnailImage' => 'includes/MediaTransformOutput.php',
|
||||
|
|
@ -385,3 +386,4 @@ function wfLoadAllExtensions() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1916,6 +1916,28 @@ $wgExtensionFunctions = array();
|
|||
*/
|
||||
$wgSkinExtensionFunctions = array();
|
||||
|
||||
/**
|
||||
* Extension messages files
|
||||
* Associative array mapping extension name to the filename where messages can be found.
|
||||
* The file must create a variable called $messages.
|
||||
* When the messages are needed, the extension should call wfLoadMessagesFile()
|
||||
*/
|
||||
$wgExtensionMessagesFiles = array();
|
||||
|
||||
/**
|
||||
* Parser output hooks.
|
||||
* This is an associative array where the key is an extension-defined tag
|
||||
* (typically the extension name), and the value is a PHP callback.
|
||||
* These will be called as an OutputPageParserOutput hook, if the relevant
|
||||
* tag has been registered with the parser output object.
|
||||
*
|
||||
* Registration is done with $pout->addOutputHook( $tag, $data ).
|
||||
*
|
||||
* The callback has the form:
|
||||
* function outputHook( $outputPage, $parserOutput, $data ) { ... }
|
||||
*/
|
||||
$wgParserOutputHooks = array();
|
||||
|
||||
/**
|
||||
* List of valid skin names.
|
||||
* The key should be the name in all lower case, the value should be a display name.
|
||||
|
|
|
|||
|
|
@ -2297,3 +2297,17 @@ function wfScript( $script = 'index' ) {
|
|||
function wfBoolToStr( $value ) {
|
||||
return $value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an extension messages file
|
||||
*/
|
||||
function wfLoadExtensionMessages( $extensionName ) {
|
||||
global $wgExtensionMessagesFiles, $wgMessageCache;
|
||||
if ( !empty( $wgExtensionMessagesFiles[$extensionName] ) ) {
|
||||
$wgMessageCache->loadMessagesFile( $wgExtensionMessagesFiles[$extensionName] );
|
||||
// Prevent double-loading
|
||||
$wgExtensionMessagesFiles[$extensionName] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ if( !defined( 'MEDIAWIKI' ) )
|
|||
class ImagePage extends Article {
|
||||
|
||||
/* private */ var $img; // Image object this page is shown for
|
||||
/* private */ var $repo;
|
||||
var $mExtraDescription = false;
|
||||
|
||||
function __construct( $title ) {
|
||||
|
|
@ -24,6 +25,7 @@ class ImagePage extends Article {
|
|||
if ( !$this->img ) {
|
||||
$this->img = wfLocalFile( $this->mTitle );
|
||||
}
|
||||
$this->repo = $this->img->repo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -46,6 +48,7 @@ class ImagePage extends Article {
|
|||
return Article::view();
|
||||
|
||||
if ($wgShowEXIF && $this->img->exists()) {
|
||||
// FIXME: bad interface, see note on MediaHandler::formatMetadata().
|
||||
$formattedMetadata = $this->img->formatMetadata();
|
||||
$showmeta = $formattedMetadata !== false;
|
||||
} else {
|
||||
|
|
@ -115,6 +118,8 @@ class ImagePage extends Article {
|
|||
/**
|
||||
* Make a table with metadata to be shown in the output page.
|
||||
*
|
||||
* FIXME: bad interface, see note on MediaHandler::formatMetadata().
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array $exif The array containing the EXIF data
|
||||
|
|
@ -188,14 +193,15 @@ class ImagePage extends Article {
|
|||
$mime = $this->img->getMimeType();
|
||||
$showLink = false;
|
||||
$linkAttribs = array( 'href' => $full_url );
|
||||
$longDesc = $this->img->getLongDesc();
|
||||
|
||||
wfRunHooks( 'ImageOpenShowImageInlineBefore', array( &$this , &$wgOut ) ) ;
|
||||
wfRunHooks( 'ImageOpenShowImageInlineBefore', array( &$this , &$wgOut ) ) ;
|
||||
|
||||
if ( $this->img->allowInlineDisplay() and $width and $height) {
|
||||
if ( $this->img->allowInlineDisplay() ) {
|
||||
# image
|
||||
|
||||
# "Download high res version" link below the image
|
||||
$msgsize = wfMsgHtml('file-info-size', $width_orig, $height_orig, $sk->formatSize( $this->img->getSize() ), $mime );
|
||||
#$msgsize = wfMsgHtml('file-info-size', $width_orig, $height_orig, $sk->formatSize( $this->img->getSize() ), $mime );
|
||||
# We'll show a thumbnail of this image
|
||||
if ( $width > $maxWidth || $height > $maxHeight ) {
|
||||
# Calculate the thumbnail size.
|
||||
|
|
@ -229,7 +235,7 @@ class ImagePage extends Article {
|
|||
} else {
|
||||
$anchorclose .=
|
||||
$msgsmall .
|
||||
'<br />' . Xml::tags( 'a', $linkAttribs, $msgbig ) . ' ' . $msgsize;
|
||||
'<br />' . Xml::tags( 'a', $linkAttribs, $msgbig ) . ' ' . $longDesc;
|
||||
}
|
||||
|
||||
if ( $this->img->isMultipage() ) {
|
||||
|
|
@ -301,26 +307,17 @@ class ImagePage extends Article {
|
|||
|
||||
|
||||
if ($showLink) {
|
||||
// Workaround for incorrect MIME type on SVGs uploaded in previous versions
|
||||
if ($mime == 'image/svg') $mime = 'image/svg+xml';
|
||||
|
||||
$filename = wfEscapeWikiText( $this->img->getName() );
|
||||
$info = wfMsg( 'file-info', $sk->formatSize( $this->img->getSize() ), $mime );
|
||||
$infores = '';
|
||||
|
||||
// Check for MIME type. Other types may have more information in the future.
|
||||
if (substr($mime,0,9) == 'image/svg' ) {
|
||||
$infores = wfMsg('file-svg', $width_orig, $height_orig ) . '<br />';
|
||||
}
|
||||
|
||||
global $wgContLang;
|
||||
$dirmark = $wgContLang->getDirMark();
|
||||
if (!$this->img->isSafeFile()) {
|
||||
$warning = wfMsg( 'mediawarning' );
|
||||
$wgOut->addWikiText( <<<EOT
|
||||
<div class="fullMedia">$infores
|
||||
<div class="fullMedia">
|
||||
<span class="dangerousLink">[[Media:$filename|$filename]]</span>$dirmark
|
||||
<span class="fileInfo"> $info</span>
|
||||
<span class="fileInfo"> $longDesc</span>
|
||||
</div>
|
||||
|
||||
<div class="mediaWarning">$warning</div>
|
||||
|
|
@ -328,8 +325,8 @@ EOT
|
|||
);
|
||||
} else {
|
||||
$wgOut->addWikiText( <<<EOT
|
||||
<div class="fullMedia">$infores
|
||||
[[Media:$filename|$filename]]$dirmark <span class="fileInfo"> $info</span>
|
||||
<div class="fullMedia">
|
||||
[[Media:$filename|$filename]]$dirmark <span class="fileInfo"> $longDesc</span>
|
||||
</div>
|
||||
EOT
|
||||
);
|
||||
|
|
@ -421,18 +418,22 @@ EOT
|
|||
|
||||
if ( $line ) {
|
||||
$list = new ImageHistoryList( $sk, $this->img );
|
||||
$file = $this->repo->newFileFromRow( $line );
|
||||
$dims = $file->getDimensionsString();
|
||||
$s = $list->beginImageHistoryList() .
|
||||
$list->imageHistoryLine( true, wfTimestamp(TS_MW, $line->img_timestamp),
|
||||
$this->mTitle->getDBkey(), $line->img_user,
|
||||
$line->img_user_text, $line->img_size, $line->img_description,
|
||||
$line->img_width, $line->img_height
|
||||
$dims
|
||||
);
|
||||
|
||||
while ( $line = $this->img->nextHistoryLine() ) {
|
||||
$s .= $list->imageHistoryLine( false, $line->img_timestamp,
|
||||
$line->oi_archive_name, $line->img_user,
|
||||
$line->img_user_text, $line->img_size, $line->img_description,
|
||||
$line->img_width, $line->img_height
|
||||
$file = $this->repo->newFileFromRow( $line );
|
||||
$dims = $file->getDimensionsString();
|
||||
$s .= $list->imageHistoryLine( false, $line->oi_timestamp,
|
||||
$line->oi_archive_name, $line->oi_user,
|
||||
$line->oi_user_text, $line->oi_size, $line->oi_description,
|
||||
$dims
|
||||
);
|
||||
}
|
||||
$s .= $list->endImageHistoryList();
|
||||
|
|
@ -655,7 +656,7 @@ EOT
|
|||
*/
|
||||
class ImageHistoryList {
|
||||
|
||||
protected $img, $skin, $title;
|
||||
protected $img, $skin, $title, $repo;
|
||||
|
||||
public function __construct( $skin, $img ) {
|
||||
$this->skin = $skin;
|
||||
|
|
@ -682,7 +683,7 @@ class ImageHistoryList {
|
|||
return "</table>\n";
|
||||
}
|
||||
|
||||
public function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $width, $height ) {
|
||||
public function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $dims ) {
|
||||
global $wgUser, $wgLang, $wgTitle, $wgContLang;
|
||||
$local = $this->img->isLocal();
|
||||
$row = '';
|
||||
|
|
@ -740,10 +741,7 @@ class ImageHistoryList {
|
|||
$row .= '</td>';
|
||||
|
||||
// Image dimensions
|
||||
// FIXME: It would be nice to show the duration (sound files) or
|
||||
// width/height/duration (video files) here, but this needs some
|
||||
// additional media handler work
|
||||
$row .= '<td>' . wfMsgHtml( 'widthheight', $width, $height ) . '</td>';
|
||||
$row .= '<td>' . htmlspecialchars( $dims ) . '</td>';
|
||||
|
||||
// File size
|
||||
$row .= '<td class="mw-imagepage-filesize">' . $this->skin->formatSize( $size ) . '</td>';
|
||||
|
|
@ -754,4 +752,4 @@ class ImageHistoryList {
|
|||
return "<tr>{$row}</tr>\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -433,42 +433,96 @@ class Linker {
|
|||
return $s;
|
||||
}
|
||||
|
||||
/** Creates the HTML source for images
|
||||
* @param object $nt
|
||||
* @param string $label label text
|
||||
* @param string $alt alt text
|
||||
* @param string $align horizontal alignment: none, left, center, right)
|
||||
* @param array $params some format keywords: width, height, page, upright, upright_factor, frameless, border
|
||||
* @param boolean $framed shows image in original size in a frame
|
||||
* @param boolean $thumb shows image as thumbnail in a frame
|
||||
* @param string $manual_thumb image name for the manual thumbnail
|
||||
* @param string $valign vertical alignment: baseline, sub, super, top, text-top, middle, bottom, text-bottom
|
||||
* @return string
|
||||
*/
|
||||
function makeImageLinkObj( $nt, $label, $alt, $align = '', $params = array(), $framed = false,
|
||||
$thumb = false, $manual_thumb = '', $valign = '', $time = false )
|
||||
/**
|
||||
* Creates the HTML source for images
|
||||
* @deprecated use makeImageLink2
|
||||
*
|
||||
* @param object $title
|
||||
* @param string $label label text
|
||||
* @param string $alt alt text
|
||||
* @param string $align horizontal alignment: none, left, center, right)
|
||||
* @param array $handlerParams Parameters to be passed to the media handler
|
||||
* @param boolean $framed shows image in original size in a frame
|
||||
* @param boolean $thumb shows image as thumbnail in a frame
|
||||
* @param string $manualthumb image name for the manual thumbnail
|
||||
* @param string $valign vertical alignment: baseline, sub, super, top, text-top, middle, bottom, text-bottom
|
||||
* @return string
|
||||
*/
|
||||
function makeImageLinkObj( $title, $label, $alt, $align = '', $handlerParams = array(), $framed = false,
|
||||
$thumb = false, $manualthumb = '', $valign = '', $time = false )
|
||||
{
|
||||
$frameParams = array( 'alt' => $alt, 'caption' => $label );
|
||||
if ( $align ) {
|
||||
$frameParams['align'] = $align;
|
||||
}
|
||||
if ( $framed ) {
|
||||
$frameParams['framed'] = true;
|
||||
}
|
||||
if ( $thumb ) {
|
||||
$frameParams['thumb'] = true;
|
||||
}
|
||||
if ( $manualthumb ) {
|
||||
$frameParams['manualthumb'] = $manualthumb;
|
||||
}
|
||||
if ( $valign ) {
|
||||
$frameParams['valign'] = $valign;
|
||||
}
|
||||
$file = wfFindFile( $title, $time );
|
||||
return $this->makeImageLink2( $title, $file, $label, $alt, $frameParams, $handlerParams );
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an image link
|
||||
* @param Title $title Title object
|
||||
* @param File $file File object, or false if it doesn't exist
|
||||
*
|
||||
* @param array $frameParams Associative array of parameters external to the media handler.
|
||||
* Boolean parameters are indicated by presence or absence, the value is arbitrary and
|
||||
* will often be false.
|
||||
* thumbnail If present, downscale and frame
|
||||
* manualthumb Image name to use as a thumbnail, instead of automatic scaling
|
||||
* framed Shows image in original size in a frame
|
||||
* frameless Downscale but don't frame
|
||||
* upright If present, tweak default sizes for portrait orientation
|
||||
* upright_factor Fudge factor for "upright" tweak (default 0.75)
|
||||
* border If present, show a border around the image
|
||||
* align Horizontal alignment (left, right, center, none)
|
||||
* valign Vertical alignment (baseline, sub, super, top, text-top, middle,
|
||||
* bottom, text-bottom)
|
||||
* alt Alternate text for image (i.e. alt attribute). Plain text.
|
||||
* caption HTML for image caption.
|
||||
*
|
||||
* @param array $handlerParams Associative array of media handler parameters, to be passed
|
||||
* to transform(). Typical keys are "width" and "page".
|
||||
*/
|
||||
function makeImageLink2( Title $title, $file, $frameParams = array(), $handlerParams = array() ) {
|
||||
global $wgContLang, $wgUser, $wgThumbLimits, $wgThumbUpright;
|
||||
|
||||
$img = wfFindFile( $nt, $time );
|
||||
|
||||
if ( $img && !$img->allowInlineDisplay() ) {
|
||||
wfDebug( __METHOD__.': '.$nt->getPrefixedDBkey()." does not allow inline display\n" );
|
||||
return $this->makeKnownLinkObj( $nt );
|
||||
if ( $file && !$file->allowInlineDisplay() ) {
|
||||
wfDebug( __METHOD__.': '.$title->getPrefixedDBkey()." does not allow inline display\n" );
|
||||
return $this->makeKnownLinkObj( $title );
|
||||
}
|
||||
|
||||
$error = $prefix = $postfix = '';
|
||||
$page = isset( $params['page'] ) ? $params['page'] : false;
|
||||
// Shortcuts
|
||||
$fp =& $frameParams;
|
||||
$hp =& $handlerParams;
|
||||
|
||||
if ( 'center' == $align )
|
||||
// Clean up parameters
|
||||
$page = isset( $hp['page'] ) ? $hp['page'] : false;
|
||||
if ( !isset( $fp['align'] ) ) $fp['align'] = '';
|
||||
if ( !isset( $fp['alt'] ) ) $fp['alt'] = '';
|
||||
|
||||
$prefix = $postfix = '';
|
||||
|
||||
if ( 'center' == $fp['align'] )
|
||||
{
|
||||
$prefix = '<div class="center">';
|
||||
$postfix = '</div>';
|
||||
$align = 'none';
|
||||
$fp['align'] = 'none';
|
||||
}
|
||||
if ( $img && !isset( $params['width'] ) ) {
|
||||
$params['width'] = $img->getWidth( $page );
|
||||
if( $thumb || $framed || isset( $params['frameless'] ) ) {
|
||||
if ( $file && !isset( $hp['width'] ) ) {
|
||||
$hp['width'] = $file->getWidth( $page );
|
||||
|
||||
if( isset( $fp['thumbnail'] ) || isset( $fp['framed'] ) || isset( $fp['frameless'] ) || !$hp['width'] ) {
|
||||
$wopt = $wgUser->getOption( 'thumbsize' );
|
||||
|
||||
if( !isset( $wgThumbLimits[$wopt] ) ) {
|
||||
|
|
@ -476,16 +530,21 @@ class Linker {
|
|||
}
|
||||
|
||||
// Reduce width for upright images when parameter 'upright' is used
|
||||
if ( !isset( $params['upright_factor'] ) || $params['upright_factor'] == 0 ) {
|
||||
$params['upright_factor'] = $wgThumbUpright;
|
||||
if ( !isset( $fp['upright_factor'] ) || $fp['upright_factor'] == 0 ) {
|
||||
$fp['upright_factor'] = $wgThumbUpright;
|
||||
}
|
||||
// Use width which is smaller: real image width or user preference width
|
||||
// For caching health: If width scaled down due to upright parameter, round to full __0 pixel to avoid the creation of a lot of odd thumbs
|
||||
$params['width'] = min( $params['width'], isset( $params['upright'] ) ? round( $wgThumbLimits[$wopt] * $params['upright_factor'], -1 ) : $wgThumbLimits[$wopt] );
|
||||
$prefWidth = isset( $fp['upright'] ) ?
|
||||
round( $wgThumbLimits[$wopt] * $fp['upright_factor'], -1 ) :
|
||||
$wgThumbLimits[$wopt];
|
||||
if ( $hp['width'] <= 0 || $prefWidth < $hp['width'] ) {
|
||||
$hp['width'] = $prefWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $thumb || $framed ) {
|
||||
if ( isset( $fp['thumbnail'] ) || isset( $fp['framed'] ) ) {
|
||||
|
||||
# Create a thumbnail. Alignment depends on language
|
||||
# writing direction, # right aligned for left-to-right-
|
||||
|
|
@ -494,15 +553,15 @@ class Linker {
|
|||
#
|
||||
# If thumbnail width has not been provided, it is set
|
||||
# to the default user option as specified in Language*.php
|
||||
if ( $align == '' ) {
|
||||
$align = $wgContLang->isRTL() ? 'left' : 'right';
|
||||
if ( $fp['align'] == '' ) {
|
||||
$fp['align'] = $wgContLang->isRTL() ? 'left' : 'right';
|
||||
}
|
||||
return $prefix.$this->makeThumbLinkObj( $nt, $img, $label, $alt, $align, $params, $framed, $manual_thumb ).$postfix;
|
||||
return $prefix.$this->makeThumbLink2( $title, $file, $fp, $hp ).$postfix;
|
||||
}
|
||||
|
||||
if ( $img && $params['width'] ) {
|
||||
if ( $file && $hp['width'] ) {
|
||||
# Create a resized image, without the additional thumbnail features
|
||||
$thumb = $img->transform( $params );
|
||||
$thumb = $file->transform( $hp );
|
||||
} else {
|
||||
$thumb = false;
|
||||
}
|
||||
|
|
@ -512,58 +571,76 @@ class Linker {
|
|||
} else {
|
||||
$query = '';
|
||||
}
|
||||
$u = $nt->getLocalURL( $query );
|
||||
$url = $title->getLocalURL( $query );
|
||||
$imgAttribs = array(
|
||||
'alt' => $alt,
|
||||
'longdesc' => $u
|
||||
'alt' => $fp['alt'],
|
||||
'longdesc' => $url
|
||||
);
|
||||
|
||||
if ( $valign ) {
|
||||
$imgAttribs['style'] = "vertical-align: $valign";
|
||||
if ( isset( $fp['valign'] ) ) {
|
||||
$imgAttribs['style'] = "vertical-align: {$fp['valign']}";
|
||||
}
|
||||
if ( isset( $params['border'] ) ) {
|
||||
if ( isset( $fp['border'] ) ) {
|
||||
$imgAttribs['class'] = "thumbborder";
|
||||
}
|
||||
$linkAttribs = array(
|
||||
'href' => $u,
|
||||
'href' => $url,
|
||||
'class' => 'image',
|
||||
'title' => $alt
|
||||
'title' => $fp['alt']
|
||||
);
|
||||
|
||||
if ( !$thumb ) {
|
||||
$s = $this->makeBrokenImageLinkObj( $nt );
|
||||
$s = $this->makeBrokenImageLinkObj( $title );
|
||||
} else {
|
||||
$s = $thumb->toHtml( $imgAttribs, $linkAttribs );
|
||||
}
|
||||
if ( '' != $align ) {
|
||||
$s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
|
||||
if ( '' != $fp['align'] ) {
|
||||
$s = "<div class=\"float{$fp['align']}\"><span>{$s}</span></div>";
|
||||
}
|
||||
return str_replace("\n", ' ',$prefix.$s.$postfix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make HTML for a thumbnail including image, border and caption
|
||||
* @param Title $nt
|
||||
* @param Image $img Image object or false if it doesn't exist
|
||||
* @param Title $title
|
||||
* @param File $file File object or false if it doesn't exist
|
||||
*/
|
||||
function makeThumbLinkObj( Title $nt, $img, $label = '', $alt, $align = 'right', $params = array(), $framed=false , $manual_thumb = "" ) {
|
||||
function makeThumbLinkObj( Title $title, $file, $label = '', $alt, $align = 'right', $params = array(), $framed=false , $manualthumb = "" ) {
|
||||
$frameParams = array(
|
||||
'alt' => $alt,
|
||||
'caption' => $label,
|
||||
'align' => $align
|
||||
);
|
||||
if ( $framed ) $frameParams['framed'] = true;
|
||||
if ( $manualthumb ) $frameParams['manualthumb'] = $manualthumb;
|
||||
return $this->makeThumbLink2( $title, $file, $frameParams, $handlerParams );
|
||||
}
|
||||
|
||||
function makeThumbLink2( Title $title, $file, $frameParams = array(), $handlerParams = array() ) {
|
||||
global $wgStylePath, $wgContLang;
|
||||
$exists = $img && $img->exists();
|
||||
$exists = $file && $file->exists();
|
||||
|
||||
$page = isset( $params['page'] ) ? $params['page'] : false;
|
||||
# Shortcuts
|
||||
$fp =& $frameParams;
|
||||
$hp =& $handlerParams;
|
||||
|
||||
if ( empty( $params['width'] ) ) {
|
||||
$page = isset( $hp['page'] ) ? $hp['page'] : false;
|
||||
if ( !isset( $fp['align'] ) ) $fp['align'] = 'right';
|
||||
if ( !isset( $fp['alt'] ) ) $fp['alt'] = '';
|
||||
if ( !isset( $fp['caption'] ) ) $fp['caption'] = '';
|
||||
|
||||
if ( empty( $hp['width'] ) ) {
|
||||
// Reduce width for upright images when parameter 'upright' is used
|
||||
$params['width'] = isset( $params['upright'] ) ? 130 : 180;
|
||||
$hp['width'] = isset( $fp['upright'] ) ? 130 : 180;
|
||||
}
|
||||
$thumb = false;
|
||||
|
||||
if ( !$exists ) {
|
||||
$outerWidth = $params['width'] + 2;
|
||||
$outerWidth = $hp['width'] + 2;
|
||||
} else {
|
||||
if ( $manual_thumb != '' ) {
|
||||
if ( isset( $fp['manualthumb'] ) ) {
|
||||
# Use manually specified thumbnail
|
||||
$manual_title = Title::makeTitleSafe( NS_IMAGE, $manual_thumb );
|
||||
$manual_title = Title::makeTitleSafe( NS_IMAGE, $fp['manualthumb'] );
|
||||
if( $manual_title ) {
|
||||
$manual_img = wfFindFile( $manual_title );
|
||||
if ( $manual_img ) {
|
||||
|
|
@ -572,63 +649,63 @@ class Linker {
|
|||
$exists = false;
|
||||
}
|
||||
}
|
||||
} elseif ( $framed ) {
|
||||
} elseif ( isset( $fp['framed'] ) ) {
|
||||
// Use image dimensions, don't scale
|
||||
$thumb = $img->getUnscaledThumb( $page );
|
||||
$thumb = $file->getUnscaledThumb( $page );
|
||||
} else {
|
||||
# Do not present an image bigger than the source, for bitmap-style images
|
||||
# This is a hack to maintain compatibility with arbitrary pre-1.10 behaviour
|
||||
$srcWidth = $img->getWidth( $page );
|
||||
if ( $srcWidth && !$img->mustRender() && $params['width'] > $srcWidth ) {
|
||||
$params['width'] = $srcWidth;
|
||||
$srcWidth = $file->getWidth( $page );
|
||||
if ( $srcWidth && !$file->mustRender() && $hp['width'] > $srcWidth ) {
|
||||
$hp['width'] = $srcWidth;
|
||||
}
|
||||
$thumb = $img->transform( $params );
|
||||
$thumb = $file->transform( $hp );
|
||||
}
|
||||
|
||||
if ( $thumb ) {
|
||||
$outerWidth = $thumb->getWidth() + 2;
|
||||
} else {
|
||||
$outerWidth = $params['width'] + 2;
|
||||
$outerWidth = $hp['width'] + 2;
|
||||
}
|
||||
}
|
||||
|
||||
$query = $page ? 'page=' . urlencode( $page ) : '';
|
||||
$u = $nt->getLocalURL( $query );
|
||||
$url = $title->getLocalURL( $query );
|
||||
|
||||
$more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
|
||||
$magnifyalign = $wgContLang->isRTL() ? 'left' : 'right';
|
||||
$textalign = $wgContLang->isRTL() ? ' style="text-align:right"' : '';
|
||||
|
||||
$s = "<div class=\"thumb t{$align}\"><div class=\"thumbinner\" style=\"width:{$outerWidth}px;\">";
|
||||
$s = "<div class=\"thumb t{$fp['align']}\"><div class=\"thumbinner\" style=\"width:{$outerWidth}px;\">";
|
||||
if( !$exists ) {
|
||||
$s .= $this->makeBrokenImageLinkObj( $nt );
|
||||
$s .= $this->makeBrokenImageLinkObj( $title );
|
||||
$zoomicon = '';
|
||||
} elseif ( !$thumb ) {
|
||||
$s .= htmlspecialchars( wfMsg( 'thumbnail_error', '' ) );
|
||||
$zoomicon = '';
|
||||
} else {
|
||||
$imgAttribs = array(
|
||||
'alt' => $alt,
|
||||
'longdesc' => $u,
|
||||
'alt' => $fp['alt'],
|
||||
'longdesc' => $url,
|
||||
'class' => 'thumbimage'
|
||||
);
|
||||
$linkAttribs = array(
|
||||
'href' => $u,
|
||||
'href' => $url,
|
||||
'class' => 'internal',
|
||||
'title' => $alt
|
||||
'title' => $fp['alt']
|
||||
);
|
||||
|
||||
|
||||
$s .= $thumb->toHtml( $imgAttribs, $linkAttribs );
|
||||
if ( $framed ) {
|
||||
if ( isset( $fp['framed'] ) ) {
|
||||
$zoomicon="";
|
||||
} else {
|
||||
$zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
|
||||
'<a href="'.$u.'" class="internal" title="'.$more.'">'.
|
||||
'<a href="'.$url.'" class="internal" title="'.$more.'">'.
|
||||
'<img src="'.$wgStylePath.'/common/images/magnify-clip.png" ' .
|
||||
'width="15" height="11" alt="" /></a></div>';
|
||||
}
|
||||
}
|
||||
$s .= ' <div class="thumbcaption"'.$textalign.'>'.$zoomicon.$label."</div></div></div>";
|
||||
$s .= ' <div class="thumbcaption"'.$textalign.'>'.$zoomicon.$fp['caption']."</div></div></div>";
|
||||
return str_replace("\n", ' ', $s);
|
||||
}
|
||||
|
||||
|
|
@ -1269,28 +1346,7 @@ class Linker {
|
|||
*/
|
||||
public function formatSize( $size ) {
|
||||
global $wgLang;
|
||||
// For small sizes no decimal places necessary
|
||||
$round = 0;
|
||||
if( $size > 1024 ) {
|
||||
$size = $size / 1024;
|
||||
if( $size > 1024 ) {
|
||||
$size = $size / 1024;
|
||||
// For MB and bigger two decimal places are smarter
|
||||
$round = 2;
|
||||
if( $size > 1024 ) {
|
||||
$size = $size / 1024;
|
||||
$msg = 'size-gigabytes';
|
||||
} else {
|
||||
$msg = 'size-megabytes';
|
||||
}
|
||||
} else {
|
||||
$msg = 'size-kilobytes';
|
||||
}
|
||||
} else {
|
||||
$msg = 'size-bytes';
|
||||
}
|
||||
$size = round( $size, $round );
|
||||
return wfMsgHtml( $msg, $wgLang->formatNum( $size ) );
|
||||
return htmlspecialchars( $wgLang->formatSize( $size ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1346,3 +1402,4 @@ class Linker {
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -386,6 +386,181 @@ class MagicWord {
|
|||
function isCaseSensitive() {
|
||||
return $this->mCaseSensitive;
|
||||
}
|
||||
|
||||
function getId() {
|
||||
return $this->mId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for handling an array of magic words
|
||||
*/
|
||||
class MagicWordArray {
|
||||
var $names = array();
|
||||
var $hash;
|
||||
var $baseRegex, $regex;
|
||||
|
||||
function __construct( $names = array() ) {
|
||||
$this->names = $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a magic word by name
|
||||
*/
|
||||
public function add( $name ) {
|
||||
global $wgContLang;
|
||||
$this->names[] = $name;
|
||||
$this->hash = $this->baseRegex = $this->regex = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number of magic words by name
|
||||
*/
|
||||
public function addArray( $names ) {
|
||||
$this->names = array_merge( $this->names, array_values( $names ) );
|
||||
$this->hash = $this->baseRegex = $this->regex = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a 2-d hashtable for this array
|
||||
*/
|
||||
function getHash() {
|
||||
if ( is_null( $this->hash ) ) {
|
||||
global $wgContLang;
|
||||
$this->hash = array( 0 => array(), 1 => array() );
|
||||
foreach ( $this->names as $name ) {
|
||||
$magic = MagicWord::get( $name );
|
||||
$case = intval( $magic->isCaseSensitive() );
|
||||
foreach ( $magic->getSynonyms() as $syn ) {
|
||||
if ( !$case ) {
|
||||
$syn = $wgContLang->lc( $syn );
|
||||
}
|
||||
$this->hash[$case][$syn] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base regex
|
||||
*/
|
||||
function getBaseRegex() {
|
||||
if ( is_null( $this->baseRegex ) ) {
|
||||
$this->baseRegex = array( 0 => '', 1 => '' );
|
||||
foreach ( $this->names as $name ) {
|
||||
$magic = MagicWord::get( $name );
|
||||
$case = intval( $magic->isCaseSensitive() );
|
||||
foreach ( $magic->getSynonyms() as $i => $syn ) {
|
||||
$group = "(?P<{$i}_{$name}>" . preg_quote( $syn, '/' ) . ')';
|
||||
if ( $this->baseRegex[$case] === '' ) {
|
||||
$this->baseRegex[$case] = $group;
|
||||
} else {
|
||||
$this->baseRegex[$case] .= '|' . $group;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->baseRegex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an unanchored regex
|
||||
*/
|
||||
function getRegex() {
|
||||
if ( is_null( $this->regex ) ) {
|
||||
$base = $this->getBaseRegex();
|
||||
$this->regex = array( '', '' );
|
||||
if ( $this->baseRegex[0] !== '' ) {
|
||||
$this->regex[0] = "/{$base[0]}/iuS";
|
||||
}
|
||||
if ( $this->baseRegex[1] !== '' ) {
|
||||
$this->regex[1] = "/{$base[1]}/S";
|
||||
}
|
||||
}
|
||||
return $this->regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a regex for matching variables
|
||||
*/
|
||||
function getVariableRegex() {
|
||||
return str_replace( "\\$1", "(.*?)", $this->getRegex() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an anchored regex for matching variables
|
||||
*/
|
||||
function getVariableStartToEndRegex() {
|
||||
$base = $this->getBaseRegex();
|
||||
$newRegex = array( '', '' );
|
||||
if ( $base[0] !== '' ) {
|
||||
$newRegex[0] = str_replace( "\\$1", "(.*?)", "/^(?:{$base[0]})$/iuS" );
|
||||
}
|
||||
if ( $base[1] !== '' ) {
|
||||
$newRegex[1] = str_replace( "\\$1", "(.*?)", "/^(?:{$base[1]})$/S" );
|
||||
}
|
||||
return $newRegex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a match array from preg_match
|
||||
*/
|
||||
function parseMatch( $m ) {
|
||||
reset( $m );
|
||||
while ( list( $key, $value ) = each( $m ) ) {
|
||||
if ( $key === 0 || $value === '' ) {
|
||||
continue;
|
||||
}
|
||||
$parts = explode( '_', $key, 2 );
|
||||
if ( count( $parts ) != 2 ) {
|
||||
// This shouldn't happen
|
||||
// continue;
|
||||
throw new MWException( __METHOD__ . ': bad parameter name' );
|
||||
}
|
||||
list( $synIndex, $magicName ) = $parts;
|
||||
$paramValue = next( $m );
|
||||
return array( $magicName, $paramValue );
|
||||
}
|
||||
// This shouldn't happen either
|
||||
throw new MWException( __METHOD__.': parameter not found' );
|
||||
return array( false, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Match some text, with parameter capture
|
||||
* Returns an array with the magic word name in the first element and the
|
||||
* parameter in the second element.
|
||||
* Both elements are false if there was no match.
|
||||
*/
|
||||
public function matchVariableStartToEnd( $text ) {
|
||||
global $wgContLang;
|
||||
$regexes = $this->getVariableStartToEndRegex();
|
||||
foreach ( $regexes as $case => $regex ) {
|
||||
if ( $regex !== '' ) {
|
||||
$m = false;
|
||||
if ( preg_match( $regex, $text, $m ) ) {
|
||||
return $this->parseMatch( $m );
|
||||
}
|
||||
}
|
||||
}
|
||||
return array( false, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Match some text, without parameter capture
|
||||
* Returns the magic word name, or false if there was no capture
|
||||
*/
|
||||
public function matchStartToEnd( $text ) {
|
||||
$hash = $this->getHash();
|
||||
if ( isset( $hash[1][$text] ) ) {
|
||||
return $hash[1][$text];
|
||||
}
|
||||
global $wgContLang;
|
||||
$lc = $wgContLang->lc( $text );
|
||||
if ( isset( $hash[0][$lc] ) ) {
|
||||
return $hash[0][$lc];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class MessageCache {
|
|||
var $mExtensionMessages = array();
|
||||
var $mInitialised = false;
|
||||
var $mDeferred = true;
|
||||
var $mAllMessagesLoaded;
|
||||
|
||||
function __construct( &$memCached, $useDB, $expiry, $memcPrefix) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
|
@ -669,12 +670,33 @@ class MessageCache {
|
|||
}
|
||||
}
|
||||
|
||||
static function loadAllMessages() {
|
||||
function loadAllMessages() {
|
||||
global $wgExtensionMessagesFiles;
|
||||
if ( $this->mAllMessagesLoaded ) {
|
||||
return;
|
||||
}
|
||||
$this->mAllMessagesLoaded = true;
|
||||
|
||||
# Some extensions will load their messages when you load their class file
|
||||
wfLoadAllExtensions();
|
||||
# Others will respond to this hook
|
||||
wfRunHooks( 'LoadAllMessages' );
|
||||
# Some register their messages in $wgExtensionMessagesFiles
|
||||
foreach ( $wgExtensionMessagesFiles as $name => $file ) {
|
||||
if ( $file ) {
|
||||
$this->loadMessagesFile( $file );
|
||||
$wgExtensionMessagesFiles[$name] = false;
|
||||
}
|
||||
}
|
||||
# Still others will respond to neither, they are EVIL. We sometimes need to know!
|
||||
}
|
||||
|
||||
/**
|
||||
* Load messages from a given file
|
||||
*/
|
||||
function loadMessagesFile( $filename ) {
|
||||
require( $filename );
|
||||
$this->addMessagesByLang( $messages );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -374,7 +374,9 @@ class MimeMagic {
|
|||
$mime = $this->detectMimeType( $file, $ext );
|
||||
|
||||
// Read a chunk of the file
|
||||
wfSuppressWarnings();
|
||||
$f = fopen( $file, "rt" );
|
||||
wfRestoreWarnings();
|
||||
if( !$f ) return "unknown/unknown";
|
||||
$head = fread( $f, 1024 );
|
||||
fclose( $f );
|
||||
|
|
|
|||
|
|
@ -109,6 +109,10 @@ class OutputPage {
|
|||
$this->mHeadItems[$name] = $value;
|
||||
}
|
||||
|
||||
function hasHeadItem( $name ) {
|
||||
return isset( $this->mHeadItems[$name] );
|
||||
}
|
||||
|
||||
function setETag($tag) { $this->mETag = $tag; }
|
||||
function setArticleBodyOnly($only) { $this->mArticleBodyOnly = $only; }
|
||||
function getArticleBodyOnly($only) { return $this->mArticleBodyOnly; }
|
||||
|
|
@ -377,7 +381,16 @@ class OutputPage {
|
|||
# Display title
|
||||
if( ( $dt = $parserOutput->getDisplayTitle() ) !== false )
|
||||
$this->setPageTitle( $dt );
|
||||
|
||||
|
||||
# Hooks registered in the object
|
||||
global $wgParserOutputHooks;
|
||||
foreach ( $parserOutput->getOutputHooks() as $hookInfo ) {
|
||||
list( $hookName, $data ) = $hookInfo;
|
||||
if ( isset( $wgParserOutputHooks[$hookName] ) ) {
|
||||
call_user_func( $wgParserOutputHooks[$hookName], $this, $parserOutput, $data );
|
||||
}
|
||||
}
|
||||
|
||||
wfRunHooks( 'OutputPageParserOutput', array( &$this, $parserOutput ) );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ class Parser
|
|||
* @private
|
||||
*/
|
||||
# Persistent:
|
||||
var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables;
|
||||
var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables,
|
||||
$mImageParams, $mImageParamsMagicArray;
|
||||
|
||||
# Cleared with clearState():
|
||||
var $mOutput, $mAutonumber, $mDTopen, $mStripState;
|
||||
|
|
@ -4473,10 +4474,50 @@ class Parser
|
|||
return $ig->toHTML();
|
||||
}
|
||||
|
||||
function getImageParams( $handler ) {
|
||||
if ( $handler ) {
|
||||
$handlerClass = get_class( $handler );
|
||||
} else {
|
||||
$handlerClass = '';
|
||||
}
|
||||
if ( !isset( $this->mImageParams[$handlerClass] ) ) {
|
||||
// Initialise static lists
|
||||
static $internalParamNames = array(
|
||||
'horizAlign' => array( 'left', 'right', 'center', 'none' ),
|
||||
'vertAlign' => array( 'baseline', 'sub', 'super', 'top', 'text-top', 'middle',
|
||||
'bottom', 'text-bottom' ),
|
||||
'frame' => array( 'thumbnail', 'manualthumb', 'framed', 'frameless',
|
||||
'upright', 'border' ),
|
||||
);
|
||||
static $internalParamMap;
|
||||
if ( !$internalParamMap ) {
|
||||
$internalParamMap = array();
|
||||
foreach ( $internalParamNames as $type => $names ) {
|
||||
foreach ( $names as $name ) {
|
||||
$magicName = str_replace( '-', '_', "img_$name" );
|
||||
$internalParamMap[$magicName] = array( $type, $name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add handler params
|
||||
$paramMap = $internalParamMap;
|
||||
if ( $handler ) {
|
||||
$handlerParamMap = $handler->getParamMap();
|
||||
foreach ( $handlerParamMap as $magic => $paramName ) {
|
||||
$paramMap[$magic] = array( 'handler', $paramName );
|
||||
}
|
||||
}
|
||||
$this->mImageParams[$handlerClass] = $paramMap;
|
||||
$this->mImageParamsMagicArray[$handlerClass] = new MagicWordArray( array_keys( $paramMap ) );
|
||||
}
|
||||
return array( $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse image options text and use it to make an image
|
||||
*/
|
||||
function makeImage( $nt, $options ) {
|
||||
function makeImage( $title, $options ) {
|
||||
# @TODO: let the MediaHandler specify its transform parameters
|
||||
#
|
||||
# Check if the options text is of the form "options|alt text"
|
||||
|
|
@ -4500,77 +4541,55 @@ class Parser
|
|||
# * middle
|
||||
# * bottom
|
||||
# * text-bottom
|
||||
|
||||
|
||||
$part = array_map( 'trim', explode( '|', $options) );
|
||||
|
||||
$mwAlign = array();
|
||||
$alignments = array( 'left', 'right', 'center', 'none', 'baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom' );
|
||||
foreach ( $alignments as $alignment ) {
|
||||
$mwAlign[$alignment] =& MagicWord::get( 'img_'.$alignment );
|
||||
}
|
||||
$mwThumb =& MagicWord::get( 'img_thumbnail' );
|
||||
$mwManualThumb =& MagicWord::get( 'img_manualthumb' );
|
||||
$mwWidth =& MagicWord::get( 'img_width' );
|
||||
$mwFramed =& MagicWord::get( 'img_framed' );
|
||||
$mwFrameless =& MagicWord::get( 'img_frameless' );
|
||||
$mwUpright =& MagicWord::get( 'img_upright' );
|
||||
$mwBorder =& MagicWord::get( 'img_border' );
|
||||
$mwPage =& MagicWord::get( 'img_page' );
|
||||
$caption = '';
|
||||
|
||||
$params = array();
|
||||
$framed = $thumb = false;
|
||||
$manual_thumb = '' ;
|
||||
$align = $valign = '';
|
||||
|
||||
$parts = array_map( 'trim', explode( '|', $options) );
|
||||
$sk = $this->mOptions->getSkin();
|
||||
|
||||
foreach( $part as $val ) {
|
||||
if ( !is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
|
||||
$thumb=true;
|
||||
} elseif ( !is_null( $match = $mwUpright->matchVariableStartToEnd( $val ) ) ) {
|
||||
$params['upright'] = true;
|
||||
$params['upright_factor'] = floatval( $match );
|
||||
} elseif ( !is_null( $match = $mwFrameless->matchVariableStartToEnd( $val ) ) ) {
|
||||
$params['frameless'] = true;
|
||||
} elseif ( !is_null( $mwBorder->matchVariableStartToEnd( $val ) ) ) {
|
||||
$params['border'] = true;
|
||||
} elseif ( ! is_null( $match = $mwManualThumb->matchVariableStartToEnd($val) ) ) {
|
||||
# use manually specified thumbnail
|
||||
$thumb=true;
|
||||
$manual_thumb = $match;
|
||||
# Give extensions a chance to select the file revision for us
|
||||
$skip = $time = false;
|
||||
wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$title, &$skip, &$time ) );
|
||||
|
||||
if ( $skip ) {
|
||||
return $sk->makeLinkObj( $title );
|
||||
}
|
||||
|
||||
# Get parameter map
|
||||
$file = wfFindFile( $title, $time );
|
||||
$handler = $file ? $file->getHandler() : false;
|
||||
|
||||
list( $paramMap, $mwArray ) = $this->getImageParams( $handler );
|
||||
|
||||
# Process the input parameters
|
||||
$caption = '';
|
||||
$params = array( 'frame' => array(), 'handler' => array(),
|
||||
'horizAlign' => array(), 'vertAlign' => array() );
|
||||
foreach( $parts as $part ) {
|
||||
list( $magicName, $value ) = $mwArray->matchVariableStartToEnd( $part );
|
||||
if ( isset( $paramMap[$magicName] ) ) {
|
||||
list( $type, $paramName ) = $paramMap[$magicName];
|
||||
$params[$type][$paramName] = $value;
|
||||
} else {
|
||||
foreach( $alignments as $alignment ) {
|
||||
if ( ! is_null( $mwAlign[$alignment]->matchVariableStartToEnd($val) ) ) {
|
||||
switch ( $alignment ) {
|
||||
case 'left': case 'right': case 'center': case 'none':
|
||||
$align = $alignment; break;
|
||||
default:
|
||||
$valign = $alignment;
|
||||
}
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
if ( ! is_null( $match = $mwPage->matchVariableStartToEnd($val) ) ) {
|
||||
# Select a page in a multipage document
|
||||
$params['page'] = $match;
|
||||
} elseif ( !isset( $params['width'] ) && ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
|
||||
wfDebug( "img_width match: $match\n" );
|
||||
# $match is the image width in pixels
|
||||
$m = array();
|
||||
if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
|
||||
$params['width'] = intval( $m[1] );
|
||||
$params['height'] = intval( $m[2] );
|
||||
} else {
|
||||
$params['width'] = intval($match);
|
||||
}
|
||||
} elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
|
||||
$framed=true;
|
||||
} else {
|
||||
$caption = $val;
|
||||
$caption = $part;
|
||||
}
|
||||
}
|
||||
|
||||
# Process alignment parameters
|
||||
if ( $params['horizAlign'] ) {
|
||||
$params['frame']['align'] = key( $params['horizAlign'] );
|
||||
}
|
||||
if ( $params['vertAlign'] ) {
|
||||
$params['frame']['valign'] = key( $params['vertAlign'] );
|
||||
}
|
||||
|
||||
# Validate the handler parameters
|
||||
if ( $handler ) {
|
||||
foreach ( $params['handler'] as $name => $value ) {
|
||||
if ( !$handler->validateParam( $name, $value ) ) {
|
||||
unset( $params['handler'][$name] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Strip bad stuff out of the alt text
|
||||
$alt = $this->replaceLinkHoldersText( $caption );
|
||||
|
||||
|
|
@ -4580,18 +4599,18 @@ class Parser
|
|||
$alt = $this->mStripState->unstripBoth( $alt );
|
||||
$alt = Sanitizer::stripAllTags( $alt );
|
||||
|
||||
# Give extensions a chance to select the file revision for us
|
||||
$skip = $time = false;
|
||||
wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$nt, &$skip, &$time ) );
|
||||
$params['frame']['alt'] = $alt;
|
||||
$params['frame']['caption'] = $caption;
|
||||
|
||||
# Linker does the rest
|
||||
if( $skip ) {
|
||||
$link = $sk->makeLinkObj( $nt );
|
||||
} else {
|
||||
$link = $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $params, $framed, $thumb, $manual_thumb, $valign, $time );
|
||||
$ret = $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'] );
|
||||
|
||||
# Give the handler a chance to modify the parser object
|
||||
if ( $handler ) {
|
||||
$handler->parserTransformHook( $this, $file );
|
||||
}
|
||||
|
||||
return $link;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ class ParserOutput
|
|||
$mExternalLinks, # External link URLs, in the key only
|
||||
$mNewSection, # Show a new section link?
|
||||
$mNoGallery, # No gallery on category page? (__NOGALLERY__)
|
||||
$mHeadItems; # Items to put in the <head> section
|
||||
$mHeadItems, # Items to put in the <head> section
|
||||
$mOutputHooks; # Hook tags as per $wgParserOutputHooks
|
||||
|
||||
/**
|
||||
* Overridden title for display
|
||||
|
|
@ -44,6 +45,7 @@ class ParserOutput
|
|||
$this->mNoGallery = false;
|
||||
$this->mHeadItems = array();
|
||||
$this->mTemplateIds = array();
|
||||
$this->mOutputHooks = array();
|
||||
}
|
||||
|
||||
function getText() { return $this->mText; }
|
||||
|
|
@ -58,6 +60,7 @@ class ParserOutput
|
|||
function &getExternalLinks() { return $this->mExternalLinks; }
|
||||
function getNoGallery() { return $this->mNoGallery; }
|
||||
function getSubtitle() { return $this->mSubtitle; }
|
||||
function getOutputHooks() { return $this->mOutputHooks; }
|
||||
|
||||
function containsOldMagic() { return $this->mContainsOldMagic; }
|
||||
function setText( $text ) { return wfSetVar( $this->mText, $text ); }
|
||||
|
|
@ -71,6 +74,10 @@ class ParserOutput
|
|||
function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; }
|
||||
function addExternalLink( $url ) { $this->mExternalLinks[$url] = 1; }
|
||||
|
||||
function addOutputHook( $hook, $data = false ) {
|
||||
$this->mOutputHooks[] = array( $hook, $data );
|
||||
}
|
||||
|
||||
function setNewSection( $value ) {
|
||||
$this->mNewSection = (bool)$value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ function wfSpecialAllmessages() {
|
|||
$navText = wfMsg( 'allmessagestext' );
|
||||
|
||||
# Make sure all extension messages are available
|
||||
MessageCache::loadAllMessages();
|
||||
|
||||
$wgMessageCache->loadAllMessages();
|
||||
|
||||
$sortedArray = array_merge( Language::getMessagesFor( 'en' ), $wgMessageCache->getExtensionMessagesFor( 'en' ) );
|
||||
ksort( $sortedArray );
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
*
|
||||
*/
|
||||
function wfSpecialSpecialpages() {
|
||||
global $wgOut, $wgUser;
|
||||
global $wgOut, $wgUser, $wgMessageCache;
|
||||
|
||||
MessageCache::loadAllMessages();
|
||||
$wgMessageCache->loadAllMessages();
|
||||
|
||||
$wgOut->setRobotpolicy( 'index,nofollow' );
|
||||
$sk = $wgUser->getSkin();
|
||||
|
|
|
|||
|
|
@ -2527,7 +2527,8 @@ class User {
|
|||
* @static
|
||||
*/
|
||||
static function getGroupName( $group ) {
|
||||
MessageCache::loadAllMessages();
|
||||
global $wgMessageCache;
|
||||
$wgMessageCache->loadAllMessages();
|
||||
$key = "group-$group";
|
||||
$name = wfMsg( $key );
|
||||
return $name == '' || wfEmptyMsg( $key, $name )
|
||||
|
|
@ -2541,7 +2542,8 @@ class User {
|
|||
* @static
|
||||
*/
|
||||
static function getGroupMember( $group ) {
|
||||
MessageCache::loadAllMessages();
|
||||
global $wgMessageCache;
|
||||
$wgMessageCache->loadAllMessages();
|
||||
$key = "group-$group-member";
|
||||
$name = wfMsg( $key );
|
||||
return $name == '' || wfEmptyMsg( $key, $name )
|
||||
|
|
@ -2586,7 +2588,8 @@ class User {
|
|||
* @return mixed
|
||||
*/
|
||||
static function getGroupPage( $group ) {
|
||||
MessageCache::loadAllMessages();
|
||||
global $wgMessageCache;
|
||||
$wgMessageCache->loadAllMessages();
|
||||
$page = wfMsgForContent( 'grouppage-' . $group );
|
||||
if( !wfEmptyMsg( 'grouppage-' . $group, $page ) ) {
|
||||
$title = Title::newFromText( $page );
|
||||
|
|
|
|||
|
|
@ -209,6 +209,18 @@ abstract class File {
|
|||
*/
|
||||
public function getHeight( $page = 1 ) { return false; }
|
||||
|
||||
/**
|
||||
* Get the duration of a media file in seconds
|
||||
*/
|
||||
public function getLength() {
|
||||
$handler = $this->getHandler();
|
||||
if ( $handler ) {
|
||||
return $handler->getLength( $this );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get handler-specific metadata
|
||||
* Overridden by LocalFile, UnregisteredLocalFile
|
||||
|
|
@ -239,7 +251,9 @@ abstract class File {
|
|||
function getMediaType() { return MEDIATYPE_UNKNOWN; }
|
||||
|
||||
/**
|
||||
* Checks if the file can be presented to the browser as a bitmap.
|
||||
* Checks if the output of transform() for this file is likely
|
||||
* to be valid. If this is false, various user elements will
|
||||
* display a placeholder instead.
|
||||
*
|
||||
* Currently, this checks if the file is an image format
|
||||
* that can be converted to a format
|
||||
|
|
@ -248,7 +262,7 @@ abstract class File {
|
|||
*/
|
||||
function canRender() {
|
||||
if ( !isset( $this->canRender ) ) {
|
||||
$this->canRender = $this->getHandler() && $this->handler->canRender();
|
||||
$this->canRender = $this->getHandler() && $this->handler->canRender( $this );
|
||||
}
|
||||
return $this->canRender;
|
||||
}
|
||||
|
|
@ -271,16 +285,11 @@ abstract class File {
|
|||
* @return bool
|
||||
*/
|
||||
function mustRender() {
|
||||
return $this->getHandler() && $this->handler->mustRender();
|
||||
return $this->getHandler() && $this->handler->mustRender( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this media file may be shown inline on a page.
|
||||
*
|
||||
* This is currently synonymous to canRender(), but this could be
|
||||
* extended to also allow inline display of other media,
|
||||
* like flash animations or videos. If you do so, please keep in mind that
|
||||
* that could be a security risk.
|
||||
* Alias for canRender()
|
||||
*/
|
||||
function allowInlineDisplay() {
|
||||
return $this->canRender();
|
||||
|
|
@ -470,7 +479,7 @@ abstract class File {
|
|||
|
||||
wfProfileIn( __METHOD__ );
|
||||
do {
|
||||
if ( !$this->getHandler() || !$this->handler->canRender() ) {
|
||||
if ( !$this->canRender() ) {
|
||||
// not a bitmap or renderable image, don't try.
|
||||
$thumb = $this->iconThumb();
|
||||
break;
|
||||
|
|
@ -906,7 +915,7 @@ abstract class File {
|
|||
* @return Bool
|
||||
*/
|
||||
function isMultipage() {
|
||||
return $this->getHandler() && $this->handler->isMultiPage();
|
||||
return $this->getHandler() && $this->handler->isMultiPage( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -915,7 +924,7 @@ abstract class File {
|
|||
*/
|
||||
function pageCount() {
|
||||
if ( !isset( $this->pageCount ) ) {
|
||||
if ( $this->getHandler() && $this->handler->isMultiPage() ) {
|
||||
if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
|
||||
$this->pageCount = $this->handler->pageCount( $this );
|
||||
} else {
|
||||
$this->pageCount = false;
|
||||
|
|
@ -1014,7 +1023,9 @@ abstract class File {
|
|||
static function getPropsFromPath( $path, $ext = true ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
wfDebug( __METHOD__.": Getting file info for $path\n" );
|
||||
$info = array( 'fileExists' => file_exists( $path ) );
|
||||
$info = array(
|
||||
'fileExists' => file_exists( $path ) && !is_dir( $path )
|
||||
);
|
||||
$gis = false;
|
||||
if ( $info['fileExists'] ) {
|
||||
$magic = MimeMagic::singleton();
|
||||
|
|
@ -1030,8 +1041,8 @@ abstract class File {
|
|||
$handler = MediaHandler::getHandler( $info['mime'] );
|
||||
if ( $handler ) {
|
||||
$tempImage = (object)array();
|
||||
$gis = $handler->getImageSize( $tempImage, $path );
|
||||
$info['metadata'] = $handler->getMetadata( $tempImage, $path );
|
||||
$gis = $handler->getImageSize( $tempImage, $path, $info['metadata'] );
|
||||
} else {
|
||||
$gis = false;
|
||||
$info['metadata'] = '';
|
||||
|
|
@ -1074,13 +1085,42 @@ abstract class File {
|
|||
* Returns false on failure
|
||||
*/
|
||||
static function sha1Base36( $path ) {
|
||||
wfSuppressWarnings();
|
||||
$hash = sha1_file( $path );
|
||||
wfRestoreWarnings();
|
||||
if ( $hash === false ) {
|
||||
return false;
|
||||
} else {
|
||||
return wfBaseConvert( $hash, 16, 36, 31 );
|
||||
}
|
||||
}
|
||||
|
||||
function getLongDesc() {
|
||||
$handler = $this->getHandler();
|
||||
if ( $handler ) {
|
||||
return $handler->getLongDesc( $this );
|
||||
} else {
|
||||
return MediaHandler::getLongDesc( $this );
|
||||
}
|
||||
}
|
||||
|
||||
function getShortDesc() {
|
||||
$handler = $this->getHandler();
|
||||
if ( $handler ) {
|
||||
return $handler->getShortDesc( $this );
|
||||
} else {
|
||||
return MediaHandler::getShortDesc( $this );
|
||||
}
|
||||
}
|
||||
|
||||
function getDimensionsString() {
|
||||
$handler = $this->getHandler();
|
||||
if ( $handler ) {
|
||||
return $handler->getDimensionsString( $this );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Aliases for backwards compatibility with 1.6
|
||||
|
|
@ -1090,3 +1130,4 @@ define( 'MW_IMG_DELETED_COMMENT', File::DELETED_COMMENT );
|
|||
define( 'MW_IMG_DELETED_USER', File::DELETED_USER );
|
||||
define( 'MW_IMG_DELETED_RESTRICTED', File::DELETED_RESTRICTED );
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class LocalFile extends File
|
|||
$media_type, # MEDIATYPE_xxx (bitmap, drawing, audio...)
|
||||
$mime, # MIME type, determined by MimeMagic::guessMimeType
|
||||
$major_mime, # Major mime type
|
||||
$minor_mine, # Minor mime type
|
||||
$minor_mime, # Minor mime type
|
||||
$size, # Size in bytes (loadFromXxx)
|
||||
$metadata, # Handler-specific metadata
|
||||
$timestamp, # Upload timestamp
|
||||
|
|
@ -231,6 +231,7 @@ class LocalFile extends File
|
|||
* Load file metadata from a DB result row
|
||||
*/
|
||||
function loadFromRow( $row, $prefix = 'img_' ) {
|
||||
$this->dataLoaded = true;
|
||||
$array = $this->decodeRow( $row, $prefix );
|
||||
foreach ( $array as $name => $value ) {
|
||||
$this->$name = $value;
|
||||
|
|
@ -287,6 +288,11 @@ class LocalFile extends File
|
|||
|
||||
$this->loadFromFile();
|
||||
|
||||
# Don't destroy file info of missing files
|
||||
if ( !$this->fileExists ) {
|
||||
wfDebug( __METHOD__.": file does not exist, aborting\n" );
|
||||
return;
|
||||
}
|
||||
$dbw = $this->repo->getMasterDB();
|
||||
list( $major, $minor ) = self::splitMime( $this->mime );
|
||||
|
||||
|
|
@ -318,6 +324,12 @@ class LocalFile extends File
|
|||
$this->$field = $info[$field];
|
||||
}
|
||||
}
|
||||
// Fix up mime fields
|
||||
if ( isset( $info['major_mime'] ) ) {
|
||||
$this->mime = "{$info['major_mime']}/{$info['minor_mime']}";
|
||||
} elseif ( isset( $info['mime'] ) ) {
|
||||
list( $this->major_mime, $this->minor_mime ) = self::splitMime( $this->mime );
|
||||
}
|
||||
}
|
||||
|
||||
/** splitMime inherited */
|
||||
|
|
@ -560,14 +572,9 @@ class LocalFile extends File
|
|||
$dbr = $this->repo->getSlaveDB();
|
||||
|
||||
if ( $this->historyLine == 0 ) {// called for the first time, return line from cur
|
||||
$this->historyRes = $dbr->select( 'image',
|
||||
$this->historyRes = $dbr->select( 'image',
|
||||
array(
|
||||
'img_size',
|
||||
'img_description',
|
||||
'img_user','img_user_text',
|
||||
'img_timestamp',
|
||||
'img_width',
|
||||
'img_height',
|
||||
'*',
|
||||
"'' AS oi_archive_name"
|
||||
),
|
||||
array( 'img_name' => $this->title->getDBkey() ),
|
||||
|
|
@ -580,17 +587,7 @@ class LocalFile extends File
|
|||
}
|
||||
} else if ( $this->historyLine == 1 ) {
|
||||
$dbr->freeResult($this->historyRes);
|
||||
$this->historyRes = $dbr->select( 'oldimage',
|
||||
array(
|
||||
'oi_size AS img_size',
|
||||
'oi_description AS img_description',
|
||||
'oi_user AS img_user',
|
||||
'oi_user_text AS img_user_text',
|
||||
'oi_timestamp AS img_timestamp',
|
||||
'oi_width as img_width',
|
||||
'oi_height as img_height',
|
||||
'oi_archive_name'
|
||||
),
|
||||
$this->historyRes = $dbr->select( 'oldimage', '*',
|
||||
array( 'oi_name' => $this->title->getDBkey() ),
|
||||
__METHOD__,
|
||||
array( 'ORDER BY' => 'oi_timestamp DESC' )
|
||||
|
|
|
|||
|
|
@ -118,7 +118,10 @@ class OldLocalFile extends LocalFile {
|
|||
}
|
||||
|
||||
function saveToCache() {
|
||||
// Cache the entire history of the image (up to MAX_CACHE_ROWS).
|
||||
// If a timestamp was specified, cache the entire history of the image (up to MAX_CACHE_ROWS).
|
||||
if ( is_null( $this->requestedTime ) ) {
|
||||
return;
|
||||
}
|
||||
// This is expensive, so we only do it if $wgMemc is real
|
||||
global $wgMemc;
|
||||
if ( $wgMemc instanceof FakeMemcachedClient ) {
|
||||
|
|
@ -155,6 +158,7 @@ class OldLocalFile extends LocalFile {
|
|||
|
||||
function loadFromDB() {
|
||||
wfProfileIn( __METHOD__ );
|
||||
$this->dataLoaded = true;
|
||||
$dbr = $this->repo->getSlaveDB();
|
||||
$conds = array( 'oi_name' => $this->getName() );
|
||||
if ( is_null( $this->requestedTime ) ) {
|
||||
|
|
@ -169,7 +173,6 @@ class OldLocalFile extends LocalFile {
|
|||
} else {
|
||||
$this->fileExists = false;
|
||||
}
|
||||
$this->dataLoaded = true;
|
||||
wfProfileOut( __METHOD__ );
|
||||
}
|
||||
|
||||
|
|
@ -178,8 +181,8 @@ class OldLocalFile extends LocalFile {
|
|||
$fields[] = $prefix . 'archive_name';
|
||||
|
||||
// XXX: Temporary hack before schema update
|
||||
$fields = array_diff( $fields, array(
|
||||
'oi_media_type', 'oi_major_mime', 'oi_minor_mime', 'oi_metadata' ) );
|
||||
//$fields = array_diff( $fields, array(
|
||||
// 'oi_media_type', 'oi_major_mime', 'oi_minor_mime', 'oi_metadata' ) );
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
|
@ -193,11 +196,18 @@ class OldLocalFile extends LocalFile {
|
|||
|
||||
function upgradeRow() {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
$this->loadFromFile();
|
||||
|
||||
# Don't destroy file info of missing files
|
||||
if ( !$this->fileExists ) {
|
||||
wfDebug( __METHOD__.": file does not exist, aborting\n" );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return;
|
||||
}
|
||||
|
||||
$dbw = $this->repo->getMasterDB();
|
||||
list( $major, $minor ) = self::splitMime( $this->mime );
|
||||
$mime = $this->mime;
|
||||
|
||||
wfDebug(__METHOD__.': upgrading '.$this->archive_name." to the current schema\n");
|
||||
$dbw->update( 'oldimage',
|
||||
|
|
@ -205,10 +215,10 @@ class OldLocalFile extends LocalFile {
|
|||
'oi_width' => $this->width,
|
||||
'oi_height' => $this->height,
|
||||
'oi_bits' => $this->bits,
|
||||
#'oi_media_type' => $this->media_type,
|
||||
#'oi_major_mime' => $major,
|
||||
#'oi_minor_mime' => $minor,
|
||||
#'oi_metadata' => $this->metadata,
|
||||
'oi_media_type' => $this->media_type,
|
||||
'oi_major_mime' => $major,
|
||||
'oi_minor_mime' => $minor,
|
||||
'oi_metadata' => $this->metadata,
|
||||
'oi_sha1' => $this->sha1,
|
||||
), array(
|
||||
'oi_name' => $this->getName(),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@ class DjVuHandler extends ImageHandler {
|
|||
function mustRender() { return true; }
|
||||
function isMultiPage() { return true; }
|
||||
|
||||
function getParamMap() {
|
||||
return array(
|
||||
'img_width' => 'width',
|
||||
'img_page' => 'page',
|
||||
);
|
||||
}
|
||||
|
||||
function validateParam( $name, $value ) {
|
||||
if ( in_array( $name, array( 'width', 'height', 'page' ) ) ) {
|
||||
if ( $value <= 0 ) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ abstract class MediaHandler {
|
|||
return self::$handlers[$class];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an associative array mapping magic word IDs to parameter names.
|
||||
* Will be used by the parser to identify parameters.
|
||||
*/
|
||||
abstract function getParamMap();
|
||||
|
||||
/*
|
||||
* Validate a thumbnail parameter at parse time.
|
||||
* Return true to accept the parameter, and false to reject it.
|
||||
|
|
@ -126,20 +132,20 @@ abstract class MediaHandler {
|
|||
/**
|
||||
* True if the handled types can be transformed
|
||||
*/
|
||||
function canRender() { return true; }
|
||||
function canRender( $file ) { return true; }
|
||||
/**
|
||||
* True if handled types cannot be displayed directly in a browser
|
||||
* but can be rendered
|
||||
*/
|
||||
function mustRender() { return false; }
|
||||
function mustRender( $file ) { return false; }
|
||||
/**
|
||||
* True if the type has multi-page capabilities
|
||||
*/
|
||||
function isMultiPage() { return false; }
|
||||
function isMultiPage( $file ) { return false; }
|
||||
/**
|
||||
* Page count for a multi-page document, false if unsupported or unknown
|
||||
*/
|
||||
function pageCount() { return false; }
|
||||
function pageCount( $file ) { return false; }
|
||||
/**
|
||||
* False if the handler is disabled for all files
|
||||
*/
|
||||
|
|
@ -177,10 +183,18 @@ abstract class MediaHandler {
|
|||
*
|
||||
* The function should return false if there is no metadata to display.
|
||||
*/
|
||||
|
||||
/**
|
||||
* FIXME: I don't really like this interface, it's not very flexible
|
||||
* I think the media handler should generate HTML instead. It can do
|
||||
* all the formatting according to some standard. That makes it possible
|
||||
* to do things like visual indication of grouped and chained streams
|
||||
* in ogg container files.
|
||||
*/
|
||||
function formatMetadata( $image, $metadata ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected static function addMeta( &$array, $visibility, $type, $id, $value, $param = false ) {
|
||||
$array[$visibility][] = array(
|
||||
'id' => "$type-$id",
|
||||
|
|
@ -189,6 +203,26 @@ abstract class MediaHandler {
|
|||
);
|
||||
}
|
||||
|
||||
function getShortDesc( $file ) {
|
||||
global $wgLang;
|
||||
$nbytes = '(' . wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ),
|
||||
$wgLang->formatNum( $file->getSize() ) ) . ')';
|
||||
}
|
||||
|
||||
function getLongDesc( $file ) {
|
||||
global $wgUser;
|
||||
$sk = $wgUser->getSkin();
|
||||
return wfMsg( 'file-info', $sk->formatSize( $file->getSize() ), $file->getMimeType() );
|
||||
}
|
||||
|
||||
function getDimensionsString() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the parser object post-transform
|
||||
*/
|
||||
function parserTransformHook( $parser, $file ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -197,6 +231,18 @@ abstract class MediaHandler {
|
|||
* @addtogroup Media
|
||||
*/
|
||||
abstract class ImageHandler extends MediaHandler {
|
||||
function canRender( $file ) {
|
||||
if ( $file->getWidth() && $file->getHeight() ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getParamMap() {
|
||||
return array( 'img_width' => 'width' );
|
||||
}
|
||||
|
||||
function validateParam( $name, $value ) {
|
||||
if ( in_array( $name, array( 'width', 'height' ) ) ) {
|
||||
if ( $value <= 0 ) {
|
||||
|
|
@ -325,6 +371,31 @@ abstract class ImageHandler extends MediaHandler {
|
|||
wfRestoreWarnings();
|
||||
return $gis;
|
||||
}
|
||||
|
||||
function getShortDesc( $file ) {
|
||||
global $wgLang;
|
||||
$nbytes = '(' . wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ),
|
||||
$wgLang->formatNum( $file->getSize() ) ) . ')';
|
||||
$widthheight = wfMsgHtml( 'widthheight', $file->getWidth(), $file->getHeight() );
|
||||
|
||||
return "$widthheight ($nbytes)";
|
||||
}
|
||||
|
||||
function getLongDesc( $file ) {
|
||||
global $wgLang;
|
||||
return wfMsgHtml('file-info-size', $file->getWidth(), $file->getHeight(),
|
||||
$wgLang->formatSize( $file->getSize() ), $file->getMimeType() );
|
||||
}
|
||||
|
||||
function getDimensionsString( $file ) {
|
||||
$pages = $file->pageCount();
|
||||
if ( $pages > 1 ) {
|
||||
return wfMsg( 'widthheightpage', $file->getWidth(), $file->getHeight(), $pages );
|
||||
} else {
|
||||
return wfMsg( 'widthheight', $file->getWidth(), $file->getHeight() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class SvgHandler extends ImageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
function mustRender() {
|
||||
function mustRender( $file ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -91,5 +91,12 @@ class SvgHandler extends ImageHandler {
|
|||
function getThumbType( $ext, $mime ) {
|
||||
return array( 'png', 'image/png' );
|
||||
}
|
||||
|
||||
function getLongDesc( $file ) {
|
||||
global $wgLang;
|
||||
return wfMsg( 'svg-long-desc', $file->getWidth(), $file->getHeight(),
|
||||
$wgLang->formatSize( $file->getSize() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,73 @@ class Language {
|
|||
wfProfileOut( __METHOD__ );
|
||||
return array( $wikiUpperChars, $wikiLowerChars );
|
||||
}
|
||||
|
||||
function formatTimePeriod( $seconds ) {
|
||||
if ( $seconds < 10 ) {
|
||||
return $this->formatNum( sprintf( "%.1f", $seconds ) ) . wfMsg( 'seconds-abbrev' );
|
||||
} elseif ( $seconds < 60 ) {
|
||||
return $this->formatNum( round( $seconds ) ) . wfMsg( 'seconds-abbrev' );
|
||||
} elseif ( $seconds < 3600 ) {
|
||||
return $this->formatNum( floor( $seconds / 60 ) ) . wfMsg( 'minutes-abbrev' ) .
|
||||
$this->formatNum( round( fmod( $seconds, 60 ) ) ) . wfMsg( 'seconds-abbrev' );
|
||||
} else {
|
||||
$hours = floor( $seconds / 3600 );
|
||||
$minutes = floor( ( $seconds - $hours * 3600 ) / 60 );
|
||||
$secondsPart = round( $seconds - $hours * 3600 - $minutes * 60 );
|
||||
return $this->formatNum( $hours ) . wfMsg( 'hours-abbrev' ) .
|
||||
$this->formatNum( $minutes ) . wfMsg( 'minutes-abbrev' ) .
|
||||
$this->formatNum( $secondsPart ) . wfMsg( 'seconds-abbrev' );
|
||||
}
|
||||
}
|
||||
|
||||
function formatBitrate( $bps ) {
|
||||
$units = array( 'bps', 'kbps', 'Mbps', 'Gbps' );
|
||||
if ( $bps <= 0 ) {
|
||||
return $this->formatNum( $bps ) . $units[0];
|
||||
}
|
||||
$unitIndex = floor( log10( $bps ) / 3 );
|
||||
$mantissa = $bps / pow( 1000, $unitIndex );
|
||||
if ( $mantissa < 10 ) {
|
||||
$mantissa = round( $mantissa, 1 );
|
||||
} else {
|
||||
$mantissa = round( $mantissa );
|
||||
}
|
||||
return $this->formatNum( $mantissa ) . $units[$unitIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a size in bytes for output, using an appropriate
|
||||
* unit (B, KB, MB or GB) according to the magnitude in question
|
||||
*
|
||||
* @param $size Size to format
|
||||
* @return string Plain text (not HTML)
|
||||
*/
|
||||
function formatSize( $size ) {
|
||||
// For small sizes no decimal places necessary
|
||||
$round = 0;
|
||||
if( $size > 1024 ) {
|
||||
$size = $size / 1024;
|
||||
if( $size > 1024 ) {
|
||||
$size = $size / 1024;
|
||||
// For MB and bigger two decimal places are smarter
|
||||
$round = 2;
|
||||
if( $size > 1024 ) {
|
||||
$size = $size / 1024;
|
||||
$msg = 'size-gigabytes';
|
||||
} else {
|
||||
$msg = 'size-megabytes';
|
||||
}
|
||||
} else {
|
||||
$msg = 'size-kilobytes';
|
||||
}
|
||||
} else {
|
||||
$msg = 'size-bytes';
|
||||
}
|
||||
$size = round( $size, $round );
|
||||
$text = $this->getMessageFromDB( $msg );
|
||||
return str_replace( '$1', $this->formatNum( $size ), $text );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -156,10 +156,10 @@ $magicWords = array(
|
|||
'img_page' => array( 1, "صفحة=$1", "صفحة $1", "page=$1", "page $1" ),
|
||||
'img_border' => array( 1, "حد", "حدود", "border" ),
|
||||
'img_top' => array( 1, "أعلى", "top" ),
|
||||
'img_text-top' => array( 1, "نص_أعلى", "text-top" ),
|
||||
'img_text_top' => array( 1, "نص_أعلى", "text-top" ),
|
||||
'img_middle' => array( 1, "وسط", "middle" ),
|
||||
'img_bottom' => array( 1, "أسفل", "bottom" ),
|
||||
'img_text-bottom' => array( 1, "نص_أسفل", "text-bottom" ),
|
||||
'img_text_bottom' => array( 1, "نص_أسفل", "text-bottom" ),
|
||||
'int' => array( 0, "محتوى:", "INT:" ),
|
||||
'sitename' => array( 1, "اسم_الموقع", "اسم_موقع", "SITENAME" ),
|
||||
'ns' => array( 0, "نط:", "NS:" ),
|
||||
|
|
|
|||
|
|
@ -114,10 +114,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'sub' ),
|
||||
'img_super' => array( 1, 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'top' ),
|
||||
'img_text-top' => array( 1, 'text-top' ),
|
||||
'img_text_top' => array( 1, 'text-top' ),
|
||||
'img_middle' => array( 1, 'middle' ),
|
||||
'img_bottom' => array( 1, 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'text-bottom' ),
|
||||
'int' => array( 0, 'INT:', 'ВЪТР:'),
|
||||
'sitename' => array( 1, 'SITENAME', 'ИМЕНАСАЙТА'),
|
||||
'ns' => array( 0, 'NS:', 'ИП:' ),
|
||||
|
|
|
|||
|
|
@ -133,10 +133,10 @@ $bookstoreList = array(
|
|||
'img_sub' => array( 1, 'sub' ),
|
||||
'img_super' => array( 1, 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'top' ),
|
||||
'img_text-top' => array( 1, 'text-top' ),
|
||||
'img_text_top' => array( 1, 'text-top' ),
|
||||
'img_middle' => array( 1, 'middle' ),
|
||||
'img_bottom' => array( 1, 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'text-bottom' ),
|
||||
'int' => array( 0, 'INT:' ),
|
||||
'sitename' => array( 1, 'SITENAME', 'NÁZEVSERVERU' ),
|
||||
'ns' => array( 0, 'NS:' ),
|
||||
|
|
|
|||
|
|
@ -209,7 +209,9 @@ $bookstoreList = array(
|
|||
|
||||
/**
|
||||
* Magic words
|
||||
* Customisable syntax for wikitext and elsewhere
|
||||
* Customisable syntax for wikitext and elsewhere.
|
||||
*
|
||||
* IDs must be valid identifiers, they can't contain hyphens.
|
||||
*
|
||||
* Note to translators:
|
||||
* Please include the English words as synonyms. This allows people
|
||||
|
|
@ -287,10 +289,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'sub' ),
|
||||
'img_super' => array( 1, 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'top' ),
|
||||
'img_text-top' => array( 1, 'text-top' ),
|
||||
'img_text_top' => array( 1, 'text-top' ),
|
||||
'img_middle' => array( 1, 'middle' ),
|
||||
'img_bottom' => array( 1, 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'text-bottom' ),
|
||||
'int' => array( 0, 'INT:' ),
|
||||
'sitename' => array( 1, 'SITENAME' ),
|
||||
'ns' => array( 0, 'NS:' ),
|
||||
|
|
@ -2422,10 +2424,11 @@ All transwiki import actions are logged at the [[Special:Log/import|import log]]
|
|||
'imagemaxsize' => 'Limit images on image description pages to:',
|
||||
'thumbsize' => 'Thumbnail size:',
|
||||
'widthheight' => '$1×$2', # only translate this message to other languages if you have to change it
|
||||
'widthheightpage' => '$1×$2, $3 pages',
|
||||
'file-info' => '(file size: $1, MIME type: $2)',
|
||||
'file-info-size' => '($1 × $2 pixel, file size: $3, MIME type: $4)',
|
||||
'file-nohires' => '<small>No higher resolution available.</small>',
|
||||
'file-svg' => '<small>This is a lossless scalable vector image. Base size: $1 × $2 pixels.</small>',
|
||||
'svg-long-desc' => '(SVG file, nominally $1 × $2 pixels, file size: $3)',
|
||||
'show-big-image' => 'Full resolution',
|
||||
'show-big-image-thumb' => '<small>Size of this preview: $1 × $2 pixels</small>',
|
||||
|
||||
|
|
@ -2434,6 +2437,12 @@ All transwiki import actions are logged at the [[Special:Log/import|import log]]
|
|||
'showhidebots' => '($1 bots)',
|
||||
'noimages' => 'Nothing to see.',
|
||||
|
||||
'video-dims' => '$1, $2×$3',
|
||||
# Used by Language::formatTimePeriod() to format lengths in the above messages
|
||||
'seconds-abbrev' => 's',
|
||||
'minutes-abbrev' => 'm',
|
||||
'hours-abbrev' => 'h',
|
||||
|
||||
# Bad image list
|
||||
'bad_image_list' => 'The format is as follows:
|
||||
|
||||
|
|
|
|||
|
|
@ -147,10 +147,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'sub' ),
|
||||
'img_super' => array( 1, 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'atas', 'top' ),
|
||||
'img_text-top' => array( 1, 'atas-teks', 'text-top' ),
|
||||
'img_text_top' => array( 1, 'atas-teks', 'text-top' ),
|
||||
'img_middle' => array( 1, 'tengah', 'middle' ),
|
||||
'img_bottom' => array( 1, 'bawah', 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'bawah-teks', 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'bawah-teks', 'text-bottom' ),
|
||||
'int' => array( 0, 'INT:' ),
|
||||
'sitename' => array( 1, 'NAMASITUS', 'SITENAME' ),
|
||||
'ns' => array( 0, 'RN:', 'NS:' ),
|
||||
|
|
|
|||
|
|
@ -223,10 +223,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'استىلىعى', 'است', 'sub'),
|
||||
'img_super' => array( 1, 'ٷستٸلٸگٸ', 'ٷست', 'sup', 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'ٷستٸنە', 'top' ),
|
||||
'img_text-top' => array( 1, 'مٵتٸن-ٷستٸندە', 'text-top' ),
|
||||
'img_text_top' => array( 1, 'مٵتٸن-ٷستٸندە', 'text-top' ),
|
||||
'img_middle' => array( 1, 'ارالىعىنا', 'middle' ),
|
||||
'img_bottom' => array( 1, 'استىنا', 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'مٵتٸن-استىندا', 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'مٵتٸن-استىندا', 'text-bottom' ),
|
||||
'int' => array( 0, 'ٸشكٸ:', 'INT:' ),
|
||||
'sitename' => array( 1, 'توراپاتاۋى', 'SITENAME' ),
|
||||
'ns' => array( 0, 'ەا:', 'ەسٸمايا:', 'NS:' ),
|
||||
|
|
|
|||
|
|
@ -215,10 +215,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'астылығы', 'аст', 'sub'),
|
||||
'img_super' => array( 1, 'үстілігі', 'үст', 'sup', 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'үстіне', 'top' ),
|
||||
'img_text-top' => array( 1, 'мәтін-үстінде', 'text-top' ),
|
||||
'img_text_top' => array( 1, 'мәтін-үстінде', 'text-top' ),
|
||||
'img_middle' => array( 1, 'аралығына', 'middle' ),
|
||||
'img_bottom' => array( 1, 'астына', 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'мәтін-астында', 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'мәтін-астында', 'text-bottom' ),
|
||||
'int' => array( 0, 'ІШКІ:', 'INT:' ),
|
||||
'sitename' => array( 1, 'ТОРАПАТАУЫ', 'SITENAME' ),
|
||||
'ns' => array( 0, 'ЕА:', 'ЕСІМАЯ:', 'NS:' ),
|
||||
|
|
|
|||
|
|
@ -216,10 +216,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'astılığı', 'ast', 'sub'),
|
||||
'img_super' => array( 1, 'üstiligi', 'üst', 'sup', 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'üstine', 'top' ),
|
||||
'img_text-top' => array( 1, 'mätin-üstinde', 'text-top' ),
|
||||
'img_text_top' => array( 1, 'mätin-üstinde', 'text-top' ),
|
||||
'img_middle' => array( 1, 'aralığına', 'middle' ),
|
||||
'img_bottom' => array( 1, 'astına', 'bottom' ),
|
||||
'img_text-bottom' => array( 1, 'mätin-astında', 'text-bottom' ),
|
||||
'img_text_bottom' => array( 1, 'mätin-astında', 'text-bottom' ),
|
||||
'int' => array( 0, 'İŞKİ:', 'INT:' ),
|
||||
'sitename' => array( 1, 'TORAPATAWI', 'SITENAME' ),
|
||||
'ns' => array( 0, 'EA:', 'ESİMAYA:', 'NS:' ),
|
||||
|
|
|
|||
|
|
@ -165,10 +165,10 @@ $magicWords = array(
|
|||
'img_sub' => array( 1, 'sub' ),
|
||||
'img_super' => array( 1, 'super', 'sup' ),
|
||||
'img_top' => array( 1, 'top', 'boven' ),
|
||||
'img_text-top' => array( 1, 'text-top', 'tekst-boven' ),
|
||||
'img_text_top' => array( 1, 'text-top', 'tekst-boven' ),
|
||||
'img_middle' => array( 1, 'middle', 'midden' ),
|
||||
'img_bottom' => array( 1, 'bottom', 'beneden' ),
|
||||
'img_text-bottom' => array( 1, 'text-bottom', 'tekst-beneden' ),
|
||||
'img_text_bottom' => array( 1, 'text-bottom', 'tekst-beneden' ),
|
||||
'int' => array( 0, 'INT:' ),
|
||||
'sitename' => array( 1, 'SITENAME', 'SITENAAM' ),
|
||||
'ns' => array( 0, 'NS:', 'NR:' ),
|
||||
|
|
|
|||
Loading…
Reference in a new issue