2004-12-18 06:29:23 +00:00
|
|
|
<?php
|
2012-05-12 20:33:02 +00:00
|
|
|
/**
|
|
|
|
|
* Methods to make links and related items.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
|
*
|
|
|
|
|
* @file
|
|
|
|
|
*/
|
|
|
|
|
|
2004-12-18 06:29:23 +00:00
|
|
|
/**
|
2011-04-03 11:44:11 +00:00
|
|
|
* Some internal bits split of from Skin.php. These functions are used
|
2008-07-01 00:40:53 +00:00
|
|
|
* for primarily page content: links, embedded images, table of contents. Links
|
2011-04-03 11:44:11 +00:00
|
|
|
* are also used in the skin.
|
2004-12-18 06:29:23 +00:00
|
|
|
*
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @ingroup Skins
|
2004-12-18 06:29:23 +00:00
|
|
|
*/
|
|
|
|
|
class Linker {
|
2007-08-06 07:09:59 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Flags for userToolLinks()
|
|
|
|
|
*/
|
|
|
|
|
const TOOL_LINKS_NOBLOCK = 1;
|
2013-02-03 20:05:24 +00:00
|
|
|
const TOOL_LINKS_EMAIL = 2;
|
2007-08-06 07:09:59 +00:00
|
|
|
|
2008-07-01 00:57:39 +00:00
|
|
|
/**
|
2013-03-13 07:42:41 +00:00
|
|
|
* Get the appropriate HTML attributes to add to the "a" element of an
|
|
|
|
|
* external link, as created by [wikisyntax].
|
2008-07-01 00:57:39 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $class the contents of the class attribute; if an empty
|
2008-07-01 00:57:39 +00:00
|
|
|
* string is passed, which is the default value, defaults to 'external'.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2011-05-06 20:59:58 +00:00
|
|
|
* @deprecated since 1.18 Just pass the external class directly to something using Html::expandAttributes
|
2008-07-01 00:57:39 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function getExternalLinkAttributes( $class = 'external' ) {
|
2011-12-13 05:19:05 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.18' );
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::getLinkAttributesInternal( '', $class );
|
2006-03-17 01:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-01 00:57:39 +00:00
|
|
|
/**
|
2013-03-13 07:42:41 +00:00
|
|
|
* Get the appropriate HTML attributes to add to the "a" element of an interwiki link.
|
2008-07-01 00:57:39 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $title the title text for the link, URL-encoded (???) but
|
2008-07-01 00:57:39 +00:00
|
|
|
* not HTML-escaped
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $unused unused
|
|
|
|
|
* @param string $class the contents of the class attribute; if an empty
|
2008-07-01 00:57:39 +00:00
|
|
|
* string is passed, which is the default value, defaults to 'external'.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2008-07-01 00:57:39 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function getInterwikiLinkAttributes( $title, $unused = null, $class = 'external' ) {
|
2006-03-17 01:02:14 +00:00
|
|
|
global $wgContLang;
|
|
|
|
|
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: We have a whole bunch of handling here that doesn't happen in
|
2008-07-01 00:57:39 +00:00
|
|
|
# getExternalLinkAttributes, why?
|
|
|
|
|
$title = urldecode( $title );
|
|
|
|
|
$title = $wgContLang->checkTitleEncoding( $title );
|
|
|
|
|
$title = preg_replace( '/[\\x00-\\x1f]/', ' ', $title );
|
2004-12-18 06:29:23 +00:00
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::getLinkAttributesInternal( $title, $class );
|
2008-07-01 01:17:39 +00:00
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
|
2008-07-01 01:17:39 +00:00
|
|
|
/**
|
2013-03-13 07:42:41 +00:00
|
|
|
* Get the appropriate HTML attributes to add to the "a" element of an internal link.
|
2008-07-01 01:17:39 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $title the title text for the link, URL-encoded (???) but
|
2008-07-01 01:17:39 +00:00
|
|
|
* not HTML-escaped
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $unused unused
|
|
|
|
|
* @param string $class the contents of the class attribute, default none
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2008-07-01 01:17:39 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function getInternalLinkAttributes( $title, $unused = null, $class = '' ) {
|
2008-07-01 01:17:39 +00:00
|
|
|
$title = urldecode( $title );
|
|
|
|
|
$title = str_replace( '_', ' ', $title );
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::getLinkAttributesInternal( $title, $class );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-01 01:17:39 +00:00
|
|
|
/**
|
2013-03-13 07:42:41 +00:00
|
|
|
* Get the appropriate HTML attributes to add to the "a" element of an internal
|
|
|
|
|
* link, given the Title object for the page we want to link to.
|
2008-07-01 01:17:39 +00:00
|
|
|
*
|
2011-03-02 10:57:55 +00:00
|
|
|
* @param $nt Title
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $unused unused
|
|
|
|
|
* @param string $class the contents of the class attribute, default none
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $title Mixed: optional (unescaped) string to use in the title
|
2008-07-01 01:17:39 +00:00
|
|
|
* attribute; if false, default to the name of the page we're linking to
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2008-07-01 01:17:39 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function getInternalLinkAttributesObj( $nt, $unused = null, $class = '', $title = false ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $title === false ) {
|
2008-07-01 01:17:39 +00:00
|
|
|
$title = $nt->getPrefixedText();
|
|
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::getLinkAttributesInternal( $title, $class );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-07-01 01:17:39 +00:00
|
|
|
* Common code for getLinkAttributesX functions
|
2011-05-28 18:59:42 +00:00
|
|
|
*
|
|
|
|
|
* @param $title string
|
|
|
|
|
* @param $class string
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
2004-12-18 06:29:23 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
private static function getLinkAttributesInternal( $title, $class ) {
|
2008-07-01 01:17:39 +00:00
|
|
|
$title = htmlspecialchars( $title );
|
|
|
|
|
$class = htmlspecialchars( $class );
|
|
|
|
|
$r = '';
|
2009-07-11 04:47:12 +00:00
|
|
|
if ( $class != '' ) {
|
2008-07-01 01:17:39 +00:00
|
|
|
$r .= " class=\"$class\"";
|
2008-02-21 09:32:59 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $title != '' ) {
|
2009-07-11 04:47:12 +00:00
|
|
|
$r .= " title=\"$title\"";
|
|
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-22 15:54:18 +00:00
|
|
|
/**
|
|
|
|
|
* Return the CSS colour of a known link
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $t Title object
|
|
|
|
|
* @param $threshold Integer: user defined threshold
|
|
|
|
|
* @return String: CSS class
|
2007-11-22 15:54:18 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function getLinkColour( $t, $threshold ) {
|
2008-02-12 18:01:42 +00:00
|
|
|
$colour = '';
|
2008-04-08 20:34:09 +00:00
|
|
|
if ( $t->isRedirect() ) {
|
2008-02-12 18:01:42 +00:00
|
|
|
# Page is a redirect
|
|
|
|
|
$colour = 'mw-redirect';
|
2012-07-24 12:44:27 +00:00
|
|
|
} elseif ( $threshold > 0 && $t->isContentPage() &&
|
|
|
|
|
$t->exists() && $t->getLength() < $threshold
|
|
|
|
|
) {
|
2008-02-12 18:01:42 +00:00
|
|
|
# Page is a stub
|
|
|
|
|
$colour = 'stub';
|
2007-11-22 15:54:18 +00:00
|
|
|
}
|
|
|
|
|
return $colour;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-30 21:02:28 +00:00
|
|
|
/**
|
2008-07-30 21:11:17 +00:00
|
|
|
* This function returns an HTML link to the given target. It serves a few
|
|
|
|
|
* purposes:
|
|
|
|
|
* 1) If $target is a Title, the correct URL to link to will be figured
|
|
|
|
|
* out automatically.
|
|
|
|
|
* 2) It automatically adds the usual classes for various types of link
|
|
|
|
|
* targets: "new" for red links, "stub" for short articles, etc.
|
2008-07-30 21:02:28 +00:00
|
|
|
* 3) It escapes all attribute values safely so there's no risk of XSS.
|
2008-07-30 21:11:17 +00:00
|
|
|
* 4) It provides a default tooltip if the target is a Title (the page
|
|
|
|
|
* name of the target).
|
|
|
|
|
* link() replaces the old functions in the makeLink() family.
|
2008-07-30 21:02:28 +00:00
|
|
|
*
|
2011-12-13 20:45:35 +00:00
|
|
|
* @since 1.18 Method exists since 1.16 as non-static, made static in 1.18.
|
|
|
|
|
* You can call it using this if you want to keep compat with these:
|
|
|
|
|
* $linker = class_exists( 'DummyLinker' ) ? new DummyLinker() : new Linker();
|
|
|
|
|
* $linker->link( ... );
|
2011-12-13 05:25:06 +00:00
|
|
|
*
|
2008-07-30 21:11:17 +00:00
|
|
|
* @param $target Title Can currently only be a Title, but this may
|
|
|
|
|
* change to support Images, literal URLs, etc.
|
2011-09-03 13:46:56 +00:00
|
|
|
* @param $html string The HTML contents of the <a> element, i.e.,
|
2008-08-01 14:33:14 +00:00
|
|
|
* the link text. This is raw HTML and will not be escaped. If null,
|
2008-08-01 01:37:07 +00:00
|
|
|
* defaults to the prefixed text of the Title; or if the Title is just a
|
|
|
|
|
* fragment, the contents of the fragment.
|
2013-03-13 07:42:41 +00:00
|
|
|
* @param array $customAttribs A key => value array of extra HTML attributes,
|
|
|
|
|
* such as title and class. (href is ignored.) Classes will be
|
2008-07-30 21:11:17 +00:00
|
|
|
* merged with the default classes, while other attributes will replace
|
|
|
|
|
* default attributes. All passed attribute values will be HTML-escaped.
|
|
|
|
|
* A false attribute value means to suppress that attribute.
|
2008-08-06 11:41:51 +00:00
|
|
|
* @param $query array The query string to append to the URL
|
|
|
|
|
* you're linking to, in key => value array form. Query keys and values
|
|
|
|
|
* will be URL-encoded.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string|array $options String or array of strings:
|
2012-01-03 21:20:35 +00:00
|
|
|
* 'known': Page is known to exist, so don't check if it does.
|
|
|
|
|
* 'broken': Page is known not to exist, so don't check if it does.
|
|
|
|
|
* 'noclasses': Don't add any classes automatically (includes "new",
|
2008-08-01 15:02:46 +00:00
|
|
|
* "stub", "mw-redirect", "extiw"). Only use the class attribute
|
|
|
|
|
* provided, if any, so you get a simple blue link with no funny i-
|
|
|
|
|
* cons.
|
2012-01-03 21:20:35 +00:00
|
|
|
* 'forcearticlepath': Use the article path always, even with a querystring.
|
2008-10-02 22:52:42 +00:00
|
|
|
* Has compatibility issues on some setups, so avoid wherever possible.
|
2012-09-27 17:47:42 +00:00
|
|
|
* 'http': Force a full URL with http:// as the scheme.
|
|
|
|
|
* 'https': Force a full URL with https:// as the scheme.
|
2008-07-30 21:02:28 +00:00
|
|
|
* @return string HTML <a> attribute
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function link(
|
2011-05-08 00:10:31 +00:00
|
|
|
$target, $html = null, $customAttribs = array(), $query = array(), $options = array()
|
2011-03-21 16:15:56 +00:00
|
|
|
) {
|
2008-07-30 21:02:28 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( !$target instanceof Title ) {
|
2011-01-11 22:20:56 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2011-05-08 00:10:31 +00:00
|
|
|
return "<!-- ERROR -->$html";
|
2008-09-14 00:49:52 +00:00
|
|
|
}
|
2012-07-05 13:58:42 +00:00
|
|
|
|
|
|
|
|
if( is_string( $query ) ) {
|
|
|
|
|
// some functions withing core using this still hand over query strings
|
|
|
|
|
wfDeprecated( __METHOD__ . ' with parameter $query as string (should be array)', '1.20' );
|
2012-08-14 09:51:26 +00:00
|
|
|
$query = wfCgiToArray( $query );
|
2012-07-05 13:58:42 +00:00
|
|
|
}
|
2008-09-14 00:49:52 +00:00
|
|
|
$options = (array)$options;
|
|
|
|
|
|
2011-04-03 12:04:04 +00:00
|
|
|
$dummy = new DummyLinker; // dummy linker instance for bc on the hooks
|
2011-04-03 11:44:11 +00:00
|
|
|
|
2008-08-05 17:05:59 +00:00
|
|
|
$ret = null;
|
2011-05-08 00:10:31 +00:00
|
|
|
if ( !wfRunHooks( 'LinkBegin', array( $dummy, $target, &$html,
|
2008-08-05 17:05:59 +00:00
|
|
|
&$customAttribs, &$query, &$options, &$ret ) ) ) {
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-30 21:02:28 +00:00
|
|
|
# Normalize the Title if it's a special page
|
2011-04-03 11:44:11 +00:00
|
|
|
$target = self::normaliseSpecialPage( $target );
|
2008-07-30 21:02:28 +00:00
|
|
|
|
|
|
|
|
# If we don't know whether the page exists, let's find out.
|
2008-08-01 15:13:14 +00:00
|
|
|
wfProfileIn( __METHOD__ . '-checkPageExistence' );
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( !in_array( 'known', $options ) and !in_array( 'broken', $options ) ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $target->isKnown() ) {
|
|
|
|
|
$options[] = 'known';
|
2008-07-30 21:02:28 +00:00
|
|
|
} else {
|
2010-08-26 19:40:29 +00:00
|
|
|
$options[] = 'broken';
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-08-01 15:13:14 +00:00
|
|
|
wfProfileOut( __METHOD__ . '-checkPageExistence' );
|
2008-07-30 21:02:28 +00:00
|
|
|
|
2008-10-02 21:04:36 +00:00
|
|
|
$oldquery = array();
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( in_array( "forcearticlepath", $options ) && $query ) {
|
2008-10-02 21:04:36 +00:00
|
|
|
$oldquery = $query;
|
|
|
|
|
$query = array();
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-30 21:02:28 +00:00
|
|
|
# Note: we want the href attribute first, for prettiness.
|
2011-04-03 11:44:11 +00:00
|
|
|
$attribs = array( 'href' => self::linkUrl( $target, $query, $options ) );
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( in_array( 'forcearticlepath', $options ) && $oldquery ) {
|
2008-10-02 21:04:36 +00:00
|
|
|
$attribs['href'] = wfAppendQuery( $attribs['href'], wfArrayToCgi( $oldquery ) );
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-30 21:02:28 +00:00
|
|
|
$attribs = array_merge(
|
|
|
|
|
$attribs,
|
2011-04-27 19:13:34 +00:00
|
|
|
self::linkAttribs( $target, $customAttribs, $options )
|
2008-07-30 21:02:28 +00:00
|
|
|
);
|
2011-05-08 00:10:31 +00:00
|
|
|
if ( is_null( $html ) ) {
|
|
|
|
|
$html = self::linkText( $target );
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-05 17:05:59 +00:00
|
|
|
$ret = null;
|
2011-05-08 00:10:31 +00:00
|
|
|
if ( wfRunHooks( 'LinkEnd', array( $dummy, $target, $options, &$html, &$attribs, &$ret ) ) ) {
|
|
|
|
|
$ret = Html::rawElement( 'a', $attribs, $html );
|
2008-08-05 17:05:59 +00:00
|
|
|
}
|
2008-07-30 21:02:28 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-29 16:02:16 +00:00
|
|
|
/**
|
|
|
|
|
* Identical to link(), except $options defaults to 'known'.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-03-29 16:02:16 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function linkKnown(
|
2011-09-03 13:46:56 +00:00
|
|
|
$target, $html = null, $customAttribs = array(),
|
2011-03-21 16:15:56 +00:00
|
|
|
$query = array(), $options = array( 'known', 'noclasses' ) )
|
|
|
|
|
{
|
2011-09-03 13:46:56 +00:00
|
|
|
return self::link( $target, $html, $customAttribs, $query, $options );
|
2009-03-29 16:02:16 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-26 14:25:48 +00:00
|
|
|
/**
|
|
|
|
|
* Returns the Url used to link to a Title
|
2011-03-02 10:57:55 +00:00
|
|
|
*
|
|
|
|
|
* @param $target Title
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $query query parameters
|
2012-02-01 20:53:38 +00:00
|
|
|
* @param $options Array
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return String
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
private static function linkUrl( $target, $query, $options ) {
|
2008-08-01 15:13:14 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2008-08-05 17:05:59 +00:00
|
|
|
# We don't want to include fragments for broken links, because they
|
|
|
|
|
# generally make no sense.
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( in_array( 'broken', $options ) && $target->mFragment !== '' ) {
|
2008-08-05 17:05:59 +00:00
|
|
|
$target = clone $target;
|
|
|
|
|
$target->mFragment = '';
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-01 15:02:46 +00:00
|
|
|
# If it's a broken link, add the appropriate query pieces, unless
|
2008-08-03 16:52:55 +00:00
|
|
|
# there's already an action specified, or unless 'edit' makes no sense
|
|
|
|
|
# (i.e., for a nonexistent special page).
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( in_array( 'broken', $options ) && empty( $query['action'] )
|
2011-11-02 20:55:08 +00:00
|
|
|
&& !$target->isSpecialPage() ) {
|
2008-07-30 21:02:28 +00:00
|
|
|
$query['action'] = 'edit';
|
|
|
|
|
$query['redlink'] = '1';
|
|
|
|
|
}
|
2012-09-27 17:47:42 +00:00
|
|
|
|
|
|
|
|
if ( in_array( 'http', $options ) ) {
|
|
|
|
|
$proto = PROTO_HTTP;
|
|
|
|
|
} elseif ( in_array( 'https', $options ) ) {
|
|
|
|
|
$proto = PROTO_HTTPS;
|
|
|
|
|
} else {
|
|
|
|
|
$proto = PROTO_RELATIVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$ret = $target->getLinkURL( $query, false, $proto );
|
2008-08-01 15:13:14 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-26 14:25:48 +00:00
|
|
|
/**
|
|
|
|
|
* Returns the array of attributes used when linking to the Title $target
|
2011-03-02 10:57:55 +00:00
|
|
|
*
|
|
|
|
|
* @param $target Title
|
2011-05-29 14:01:47 +00:00
|
|
|
* @param $attribs
|
|
|
|
|
* @param $options
|
2011-06-17 16:03:52 +00:00
|
|
|
*
|
2011-05-29 14:01:47 +00:00
|
|
|
* @return array
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-04-27 19:13:34 +00:00
|
|
|
private static function linkAttribs( $target, $attribs, $options ) {
|
2012-01-01 14:01:49 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2012-01-03 21:20:35 +00:00
|
|
|
global $wgUser;
|
2008-07-30 21:02:28 +00:00
|
|
|
$defaults = array();
|
|
|
|
|
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( !in_array( 'noclasses', $options ) ) {
|
2008-08-03 16:52:55 +00:00
|
|
|
wfProfileIn( __METHOD__ . '-getClasses' );
|
2008-08-05 17:05:59 +00:00
|
|
|
# Now build the classes.
|
2008-07-30 21:02:28 +00:00
|
|
|
$classes = array();
|
|
|
|
|
|
2012-01-03 21:20:35 +00:00
|
|
|
if ( in_array( 'broken', $options ) ) {
|
|
|
|
|
$classes[] = 'new';
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $target->isExternal() ) {
|
2008-08-01 15:02:46 +00:00
|
|
|
$classes[] = 'extiw';
|
2012-01-03 21:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !in_array( 'broken', $options ) ) { # Avoid useless calls to LinkCache (see r50387)
|
2011-04-03 11:44:11 +00:00
|
|
|
$colour = self::getLinkColour( $target, $wgUser->getStubThreshold() );
|
2010-08-02 15:53:22 +00:00
|
|
|
if ( $colour !== '' ) {
|
|
|
|
|
$classes[] = $colour; # mw-redirect or stub
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $classes != array() ) {
|
2008-07-30 21:02:28 +00:00
|
|
|
$defaults['class'] = implode( ' ', $classes );
|
|
|
|
|
}
|
2008-08-03 16:52:55 +00:00
|
|
|
wfProfileOut( __METHOD__ . '-getClasses' );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Get a default title attribute.
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $target->getPrefixedText() == '' ) {
|
2009-03-31 14:26:40 +00:00
|
|
|
# A link like [[#Foo]]. This used to mean an empty title
|
|
|
|
|
# attribute, but that's silly. Just don't output a title.
|
2012-01-03 21:20:35 +00:00
|
|
|
} elseif ( in_array( 'known', $options ) ) {
|
2008-08-03 16:52:55 +00:00
|
|
|
$defaults['title'] = $target->getPrefixedText();
|
2011-04-27 19:13:34 +00:00
|
|
|
} else {
|
2012-08-19 20:44:29 +00:00
|
|
|
$defaults['title'] = wfMessage( 'red-link-title', $target->getPrefixedText() )->text();
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Finally, merge the custom attribs with the default ones, and iterate
|
|
|
|
|
# over that, deleting all "false" attributes.
|
|
|
|
|
$ret = array();
|
2008-07-30 22:02:23 +00:00
|
|
|
$merged = Sanitizer::mergeAttributes( $defaults, $attribs );
|
2010-08-26 19:40:29 +00:00
|
|
|
foreach ( $merged as $key => $val ) {
|
2008-07-30 21:11:17 +00:00
|
|
|
# A false value suppresses the attribute, and we don't want the
|
|
|
|
|
# href attribute to be overridden.
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $key != 'href' and $val !== false ) {
|
2008-07-30 21:02:28 +00:00
|
|
|
$ret[$key] = $val;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-08-01 15:13:14 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2008-07-30 21:02:28 +00:00
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-26 14:25:48 +00:00
|
|
|
/**
|
|
|
|
|
* Default text of the links to the Title $target
|
2011-03-02 10:57:55 +00:00
|
|
|
*
|
|
|
|
|
* @param $target Title
|
2011-05-06 22:53:59 +00:00
|
|
|
*
|
|
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
private static function linkText( $target ) {
|
2013-03-13 07:42:41 +00:00
|
|
|
// We might be passed a non-Title by make*LinkObj(). Fail gracefully.
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( !$target instanceof Title ) {
|
2008-09-08 22:53:44 +00:00
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 07:42:41 +00:00
|
|
|
// If the target is just a fragment, with no title, we return the fragment
|
|
|
|
|
// text. Otherwise, we return the title text itself.
|
2011-03-02 10:57:55 +00:00
|
|
|
if ( $target->getPrefixedText() === '' && $target->getFragment() !== '' ) {
|
2008-08-01 14:33:14 +00:00
|
|
|
return htmlspecialchars( $target->getFragment() );
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
2008-08-01 14:33:14 +00:00
|
|
|
return htmlspecialchars( $target->getPrefixedText() );
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
2005-06-01 10:29:34 +00:00
|
|
|
/**
|
|
|
|
|
* Generate either a normal exists-style link or a stub link, depending
|
|
|
|
|
* on the given page size.
|
2006-11-08 07:12:03 +00:00
|
|
|
*
|
2010-11-05 19:06:12 +00:00
|
|
|
* @param $size Integer
|
|
|
|
|
* @param $nt Title object.
|
|
|
|
|
* @param $text String
|
|
|
|
|
* @param $query String
|
|
|
|
|
* @param $trail String
|
|
|
|
|
* @param $prefix String
|
|
|
|
|
* @return string HTML of link
|
2011-03-12 18:14:33 +00:00
|
|
|
* @deprecated since 1.17
|
2005-06-01 10:29:34 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function makeSizeLinkObj( $size, $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
|
2005-06-01 10:29:34 +00:00
|
|
|
global $wgUser;
|
2011-12-13 05:19:05 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.17' );
|
2010-08-26 19:40:29 +00:00
|
|
|
|
2010-08-03 22:32:09 +00:00
|
|
|
$threshold = $wgUser->getStubThreshold();
|
2007-11-22 15:54:18 +00:00
|
|
|
$colour = ( $size < $threshold ) ? 'stub' : '';
|
2011-05-17 22:03:20 +00:00
|
|
|
// @todo FIXME: Replace deprecated makeColouredLinkObj by link()
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::makeColouredLinkObj( $nt, $colour, $text, $query, $trail, $prefix );
|
2005-06-01 10:29:34 +00:00
|
|
|
}
|
|
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
/**
|
2006-02-01 04:34:47 +00:00
|
|
|
* Make appropriate markup for a link to the current article. This is currently rendered
|
2011-04-03 12:04:04 +00:00
|
|
|
* as the bold link text. The calling sequence is the same as the other make*LinkObj static functions,
|
2006-02-01 04:34:47 +00:00
|
|
|
* despite $query not being used.
|
2011-03-02 10:57:55 +00:00
|
|
|
*
|
2011-03-02 10:59:30 +00:00
|
|
|
* @param $nt Title
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $html [optional]
|
|
|
|
|
* @param string $query [optional]
|
|
|
|
|
* @param string $trail [optional]
|
|
|
|
|
* @param string $prefix [optional]
|
2012-07-10 14:58:52 +00:00
|
|
|
*
|
2011-05-06 22:53:59 +00:00
|
|
|
*
|
|
|
|
|
* @return string
|
2006-02-01 04:34:47 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function makeSelfLinkObj( $nt, $html = '', $query = '', $trail = '', $prefix = '' ) {
|
2011-09-03 13:46:56 +00:00
|
|
|
if ( $html == '' ) {
|
|
|
|
|
$html = htmlspecialchars( $nt->getPrefixedText() );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
list( $inside, $trail ) = self::splitTrail( $trail );
|
2011-09-03 13:46:56 +00:00
|
|
|
return "<strong class=\"selflink\">{$prefix}{$html}{$inside}</strong>{$trail}";
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-10 09:28:48 +00:00
|
|
|
/**
|
|
|
|
|
* Get a message saying that an invalid title was encountered.
|
|
|
|
|
* This should be called after a method like Title::makeTitleSafe() returned
|
|
|
|
|
* a value indicating that the title object is invalid.
|
|
|
|
|
*
|
|
|
|
|
* @param $context IContextSource context to use to get the messages
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param int $namespace Namespace number
|
|
|
|
|
* @param string $title Text of the title, without the namespace part
|
2012-10-07 23:35:26 +00:00
|
|
|
* @return string
|
2012-04-10 09:28:48 +00:00
|
|
|
*/
|
|
|
|
|
public static function getInvalidTitleDescription( IContextSource $context, $namespace, $title ) {
|
|
|
|
|
global $wgContLang;
|
|
|
|
|
|
|
|
|
|
// First we check whether the namespace exists or not.
|
|
|
|
|
if ( MWNamespace::exists( $namespace ) ) {
|
|
|
|
|
if ( $namespace == NS_MAIN ) {
|
|
|
|
|
$name = $context->msg( 'blanknamespace' )->text();
|
|
|
|
|
} else {
|
|
|
|
|
$name = $wgContLang->getFormattedNsText( $namespace );
|
|
|
|
|
}
|
|
|
|
|
return $context->msg( 'invalidtitle-knownnamespace', $namespace, $name, $title )->text();
|
|
|
|
|
} else {
|
|
|
|
|
return $context->msg( 'invalidtitle-unknownnamespace', $namespace, $title )->text();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-06 22:53:59 +00:00
|
|
|
/**
|
|
|
|
|
* @param $title Title
|
|
|
|
|
* @return Title
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function normaliseSpecialPage( Title $title ) {
|
2011-11-02 20:55:08 +00:00
|
|
|
if ( $title->isSpecialPage() ) {
|
2011-04-17 11:31:11 +00:00
|
|
|
list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
|
2010-08-19 11:21:14 +00:00
|
|
|
if ( !$name ) {
|
|
|
|
|
return $title;
|
|
|
|
|
}
|
2008-08-01 22:44:11 +00:00
|
|
|
$ret = SpecialPage::getTitleFor( $name, $subpage );
|
|
|
|
|
$ret->mFragment = $title->getFragment();
|
|
|
|
|
return $ret;
|
2008-06-17 08:08:59 +00:00
|
|
|
} else {
|
|
|
|
|
return $title;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-07 09:32:09 +00:00
|
|
|
/**
|
2009-10-26 14:25:48 +00:00
|
|
|
* Returns the filename part of an url.
|
|
|
|
|
* Used as alternative text for external images.
|
2011-05-06 22:53:59 +00:00
|
|
|
*
|
|
|
|
|
* @param $url string
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
private static function fnamePart( $url ) {
|
2004-12-18 06:29:23 +00:00
|
|
|
$basename = strrchr( $url, '/' );
|
|
|
|
|
if ( false === $basename ) {
|
|
|
|
|
$basename = $url;
|
|
|
|
|
} else {
|
|
|
|
|
$basename = substr( $basename, 1 );
|
|
|
|
|
}
|
2008-07-02 01:19:00 +00:00
|
|
|
return $basename;
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2010-01-07 09:32:09 +00:00
|
|
|
/**
|
2009-10-26 14:25:48 +00:00
|
|
|
* Return the code for images which were added via external links,
|
|
|
|
|
* via Parser::maybeMakeExternalImage().
|
2011-05-06 22:53:59 +00:00
|
|
|
*
|
|
|
|
|
* @param $url
|
|
|
|
|
* @param $alt
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function makeExternalImage( $url, $alt = '' ) {
|
2010-01-06 19:59:42 +00:00
|
|
|
if ( $alt == '' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$alt = self::fnamePart( $url );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2008-06-24 14:32:49 +00:00
|
|
|
$img = '';
|
2010-08-26 19:40:29 +00:00
|
|
|
$success = wfRunHooks( 'LinkerMakeExternalImage', array( &$url, &$alt, &$img ) );
|
|
|
|
|
if ( !$success ) {
|
|
|
|
|
wfDebug( "Hook LinkerMakeExternalImage changed the output of external image with url {$url} and alt text {$alt} to {$img}\n", true );
|
2008-06-24 14:32:49 +00:00
|
|
|
return $img;
|
|
|
|
|
}
|
2009-08-21 20:39:35 +00:00
|
|
|
return Html::element( 'img',
|
2008-07-02 01:19:00 +00:00
|
|
|
array(
|
|
|
|
|
'src' => $url,
|
|
|
|
|
'alt' => $alt ) );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
/**
|
2009-06-08 22:33:37 +00:00
|
|
|
* Given parameters derived from [[Image:Foo|options...]], generate the
|
|
|
|
|
* HTML that that syntax inserts in the page.
|
2008-02-26 17:20:39 +00:00
|
|
|
*
|
2012-08-01 03:34:32 +00:00
|
|
|
* @param $parser Parser object
|
|
|
|
|
* @param $title Title object of the file (not the currently viewed page)
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $file File object, or false if it doesn't exist
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $frameParams associative array of parameters external to the media handler.
|
2008-04-14 07:45:50 +00:00
|
|
|
* Boolean parameters are indicated by presence or absence, the value is arbitrary and
|
2008-01-03 19:28:50 +00:00
|
|
|
* 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)
|
2008-04-14 07:45:50 +00:00
|
|
|
* valign Vertical alignment (baseline, sub, super, top, text-top, middle,
|
2008-01-03 19:28:50 +00:00
|
|
|
* bottom, text-bottom)
|
|
|
|
|
* alt Alternate text for image (i.e. alt attribute). Plain text.
|
2012-08-20 10:12:47 +00:00
|
|
|
* class HTML for image classes. Plain text.
|
2008-01-03 19:28:50 +00:00
|
|
|
* caption HTML for image caption.
|
2008-10-07 00:31:26 +00:00
|
|
|
* link-url URL to link to
|
|
|
|
|
* link-title Title object to link to
|
2013-03-13 07:42:41 +00:00
|
|
|
* link-target Value for the target attribute, only with link-url
|
2008-10-06 05:55:27 +00:00
|
|
|
* no-link Boolean, suppress description link
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $handlerParams associative array of media handler parameters, to be passed
|
2008-04-14 07:45:50 +00:00
|
|
|
* to transform(). Typical keys are "width" and "page".
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $time timestamp of the file, set as false for current
|
|
|
|
|
* @param string $query query params for desc url
|
2010-10-31 21:53:29 +00:00
|
|
|
* @param $widthOption: Used by the parser to remember the user preference thumbnailsize
|
2012-08-01 03:34:32 +00:00
|
|
|
* @since 1.20
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML for an image, with links, wrappers, etc.
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
*/
|
2012-08-01 03:34:32 +00:00
|
|
|
public static function makeImageLink( /*Parser*/ $parser, Title $title, $file, $frameParams = array(),
|
2011-03-21 16:15:56 +00:00
|
|
|
$handlerParams = array(), $time = false, $query = "", $widthOption = null )
|
|
|
|
|
{
|
2008-02-26 17:20:39 +00:00
|
|
|
$res = null;
|
2011-04-03 12:04:04 +00:00
|
|
|
$dummy = new DummyLinker;
|
2011-04-03 11:44:11 +00:00
|
|
|
if ( !wfRunHooks( 'ImageBeforeProduceHTML', array( &$dummy, &$title,
|
2011-03-02 10:57:55 +00:00
|
|
|
&$file, &$frameParams, &$handlerParams, &$time, &$res ) ) ) {
|
2008-02-26 17:20:39 +00:00
|
|
|
return $res;
|
|
|
|
|
}
|
|
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
if ( $file && !$file->allowInlineDisplay() ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
wfDebug( __METHOD__ . ': ' . $title->getPrefixedDBkey() . " does not allow inline display\n" );
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::link( $title );
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
// Shortcuts
|
|
|
|
|
$fp =& $frameParams;
|
|
|
|
|
$hp =& $handlerParams;
|
2006-08-13 17:34:48 +00:00
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
// Clean up parameters
|
|
|
|
|
$page = isset( $hp['page'] ) ? $hp['page'] : false;
|
2011-03-02 10:57:55 +00:00
|
|
|
if ( !isset( $fp['align'] ) ) {
|
|
|
|
|
$fp['align'] = '';
|
|
|
|
|
}
|
|
|
|
|
if ( !isset( $fp['alt'] ) ) {
|
|
|
|
|
$fp['alt'] = '';
|
|
|
|
|
}
|
|
|
|
|
if ( !isset( $fp['title'] ) ) {
|
|
|
|
|
$fp['title'] = '';
|
|
|
|
|
}
|
2012-08-20 10:12:47 +00:00
|
|
|
if ( !isset( $fp['class'] ) ) {
|
|
|
|
|
$fp['class'] = '';
|
|
|
|
|
}
|
2006-01-03 00:51:57 +00:00
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$prefix = $postfix = '';
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-10-08 16:33:36 +00:00
|
|
|
if ( 'center' == $fp['align'] ) {
|
2013-02-03 20:05:24 +00:00
|
|
|
$prefix = '<div class="center">';
|
2004-12-18 06:29:23 +00:00
|
|
|
$postfix = '</div>';
|
2013-02-03 20:05:24 +00:00
|
|
|
$fp['align'] = 'none';
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
if ( $file && !isset( $hp['width'] ) ) {
|
2011-05-14 23:48:59 +00:00
|
|
|
if ( isset( $hp['height'] ) && $file->isVectorized() ) {
|
|
|
|
|
// If its a vector image, and user only specifies height
|
|
|
|
|
// we don't want it to be limited by its "normal" width.
|
|
|
|
|
global $wgSVGMaxSize;
|
|
|
|
|
$hp['width'] = $wgSVGMaxSize;
|
2011-06-17 16:03:52 +00:00
|
|
|
} else {
|
2011-05-14 23:48:59 +00:00
|
|
|
$hp['width'] = $file->getWidth( $page );
|
|
|
|
|
}
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( isset( $fp['thumbnail'] ) || isset( $fp['framed'] ) || isset( $fp['frameless'] ) || !$hp['width'] ) {
|
2010-10-31 21:53:29 +00:00
|
|
|
global $wgThumbLimits, $wgThumbUpright;
|
2013-03-10 15:23:46 +00:00
|
|
|
if ( $widthOption === null || !isset( $wgThumbLimits[$widthOption] ) ) {
|
2010-10-31 21:53:29 +00:00
|
|
|
$widthOption = User::getDefaultOption( 'thumbsize' );
|
2007-04-20 19:24:53 +00:00
|
|
|
}
|
2007-04-20 12:31:36 +00:00
|
|
|
|
2007-05-21 18:56:03 +00:00
|
|
|
// Reduce width for upright images when parameter 'upright' is used
|
2007-08-27 11:24:53 +00:00
|
|
|
if ( isset( $fp['upright'] ) && $fp['upright'] == 0 ) {
|
|
|
|
|
$fp['upright'] = $wgThumbUpright;
|
2007-05-21 18:56:03 +00:00
|
|
|
}
|
|
|
|
|
// 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
|
2008-04-14 07:45:50 +00:00
|
|
|
$prefWidth = isset( $fp['upright'] ) ?
|
2010-08-07 22:35:23 +00:00
|
|
|
round( $wgThumbLimits[$widthOption] * $fp['upright'], -1 ) :
|
|
|
|
|
$wgThumbLimits[$widthOption];
|
2010-10-31 21:53:29 +00:00
|
|
|
|
|
|
|
|
// Use width which is smaller: real image width or user preference width
|
|
|
|
|
// Unless image is scalable vector.
|
|
|
|
|
if ( !isset( $hp['height'] ) && ( $hp['width'] <= 0 ||
|
|
|
|
|
$prefWidth < $hp['width'] || $file->isVectorized() ) ) {
|
|
|
|
|
$hp['width'] = $prefWidth;
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
}
|
2007-04-20 19:24:53 +00:00
|
|
|
}
|
2007-04-20 12:31:36 +00:00
|
|
|
}
|
|
|
|
|
|
2010-11-01 19:36:29 +00:00
|
|
|
if ( isset( $fp['thumbnail'] ) || isset( $fp['manualthumb'] ) || isset( $fp['framed'] ) ) {
|
2012-08-01 03:34:32 +00:00
|
|
|
# Create a thumbnail. Alignment depends on the writing direction of
|
|
|
|
|
# the page content language (right-aligned for LTR languages,
|
|
|
|
|
# left-aligned for RTL languages)
|
2004-12-18 06:29:23 +00:00
|
|
|
#
|
2012-08-01 03:34:32 +00:00
|
|
|
# If a thumbnail width has not been provided, it is set
|
2005-04-12 00:37:45 +00:00
|
|
|
# to the default user option as specified in Language*.php
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
if ( $fp['align'] == '' ) {
|
2012-08-01 03:34:32 +00:00
|
|
|
if( $parser instanceof Parser ) {
|
|
|
|
|
$fp['align'] = $parser->getTargetLanguage()->alignEnd();
|
|
|
|
|
} else {
|
|
|
|
|
# backwards compatibility, remove with makeImageLink2()
|
|
|
|
|
global $wgContLang;
|
|
|
|
|
$fp['align'] = $wgContLang->alignEnd();
|
|
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
return $prefix . self::makeThumbLink2( $title, $file, $fp, $hp, $time, $query ) . $postfix;
|
2005-08-16 13:27:00 +00:00
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
|
2007-11-20 12:11:05 +00:00
|
|
|
if ( $file && isset( $fp['frameless'] ) ) {
|
|
|
|
|
$srcWidth = $file->getWidth( $page );
|
|
|
|
|
# For "frameless" option: do not present an image bigger than the source (for bitmap-style images)
|
2013-03-04 08:44:38 +00:00
|
|
|
# This is the same behavior as the "thumb" option does it already.
|
2007-11-20 12:11:05 +00:00
|
|
|
if ( $srcWidth && !$file->mustRender() && $hp['width'] > $srcWidth ) {
|
|
|
|
|
$hp['width'] = $srcWidth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-31 21:53:29 +00:00
|
|
|
if ( $file && isset( $hp['width'] ) ) {
|
2007-04-20 12:31:36 +00:00
|
|
|
# Create a resized image, without the additional thumbnail features
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$thumb = $file->transform( $hp );
|
2005-07-04 19:20:53 +00:00
|
|
|
} else {
|
2007-04-20 12:31:36 +00:00
|
|
|
$thumb = false;
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2007-04-20 12:31:36 +00:00
|
|
|
if ( !$thumb ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$s = self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
|
2004-12-18 06:29:23 +00:00
|
|
|
} else {
|
Initial stab at responsive images for screen densities.
* adds $wgResponsiveImages setting, defaulting to true, to enable the feature
* adds 'srcset' attribute with 1.5x and 2x URLs to image links and image thumbs
* adds jquery.hidpi plugin to check pixel density and implement partial 'srcset' polyfill
** $.devicePixelRatio() returns window.devicePixelRatio, with compat fallback for IE 10
** $().hidpi() performs a 'srcset' polyfill for browsers with no native 'srcset' support
* adds mediawiki.hidpi RL script to trigger hidpi loads after main images load
Note that this is a work in progress. There will be places where this doesn't yet work which output their imgs differently. If moving from a low to high-DPI screen on a MacBook Pro Retina display, you won't see images load until you reload.
Confirmed basic images and thumbs in wikitext appear to work in Safari 6, Chrome 21, Firefox 18 nightly on MacBook Pro Retina display, and IE 10 in Windows 8 at 150% zoom, 200% zoom, and 140% and 180%-ratio Metro tablet sizes.
Internally this is still a bit of a hack; Linker::makeImageLink and Linker::makeThumbLink explicitly ask for 1.5x and 2x scaled versions and insert their URLs, if different, into the original thumbnail object which (in default handler) outputs the srcset. This means that a number of places that handle images differently won't see the higher-resolution versions, such as <gallery> and the large thumbnail on the File: description page.
At some point we may wish to redo some of how the MediaHandler stuff works so that requesting a single thumbnail automatically produces the extra sizes in all circumstances. We might also consider outputting a 'srcset' or multiple src sizes in 'imageinfo' API requests, which would make ApiForeignRepo/InstantCommons more efficient. (Currently it has to make three requests for each image to get the three sizes.)
Change-Id: Id80ebd07a1a9f401a2c2bfeb21aae987e5aa863b
2012-09-18 07:18:50 +00:00
|
|
|
self::processResponsiveImages( $file, $thumb, $hp );
|
2008-10-06 05:55:27 +00:00
|
|
|
$params = array(
|
2007-08-31 02:51:23 +00:00
|
|
|
'alt' => $fp['alt'],
|
2008-10-08 16:33:36 +00:00
|
|
|
'title' => $fp['title'],
|
2012-08-20 10:12:47 +00:00
|
|
|
'valign' => isset( $fp['valign'] ) ? $fp['valign'] : false,
|
|
|
|
|
'img-class' => $fp['class'] );
|
|
|
|
|
if ( isset( $fp['border'] ) ) {
|
2013-03-13 07:42:41 +00:00
|
|
|
// TODO: BUG? Both values are identical
|
2012-08-20 10:12:47 +00:00
|
|
|
$params['img-class'] .= ( $params['img-class'] !== '' ) ? ' thumbborder' : 'thumbborder';
|
|
|
|
|
}
|
2012-08-06 17:04:07 +00:00
|
|
|
$params = self::getImageLinkMTOParams( $fp, $query, $parser ) + $params;
|
2008-10-06 05:55:27 +00:00
|
|
|
|
|
|
|
|
$s = $thumb->toHtml( $params );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2010-01-06 19:59:42 +00:00
|
|
|
if ( $fp['align'] != '' ) {
|
2008-10-06 04:22:19 +00:00
|
|
|
$s = "<div class=\"float{$fp['align']}\">{$s}</div>";
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
return str_replace( "\n", ' ', $prefix . $s . $postfix );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2012-08-01 03:34:32 +00:00
|
|
|
/**
|
|
|
|
|
* See makeImageLink()
|
|
|
|
|
* When this function is removed, remove if( $parser instanceof Parser ) check there too
|
|
|
|
|
* @deprecated since 1.20
|
|
|
|
|
*/
|
|
|
|
|
public static function makeImageLink2( Title $title, $file, $frameParams = array(),
|
|
|
|
|
$handlerParams = array(), $time = false, $query = "", $widthOption = null ) {
|
|
|
|
|
return self::makeImageLink( null, $title, $file, $frameParams,
|
|
|
|
|
$handlerParams, $time, $query, $widthOption );
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-20 10:28:00 +00:00
|
|
|
/**
|
2010-08-26 19:40:29 +00:00
|
|
|
* Get the link parameters for MediaTransformOutput::toHtml() from given
|
2010-07-20 10:28:00 +00:00
|
|
|
* frame parameters supplied by the Parser.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $frameParams The frame parameters
|
|
|
|
|
* @param string $query An optional query string to add to description page links
|
2012-02-09 19:29:36 +00:00
|
|
|
* @return array
|
2010-07-20 10:28:00 +00:00
|
|
|
*/
|
2012-08-06 17:04:07 +00:00
|
|
|
private static function getImageLinkMTOParams( $frameParams, $query = '', $parser = null ) {
|
2010-07-20 10:28:00 +00:00
|
|
|
$mtoParams = array();
|
|
|
|
|
if ( isset( $frameParams['link-url'] ) && $frameParams['link-url'] !== '' ) {
|
|
|
|
|
$mtoParams['custom-url-link'] = $frameParams['link-url'];
|
2010-11-09 12:25:57 +00:00
|
|
|
if ( isset( $frameParams['link-target'] ) ) {
|
|
|
|
|
$mtoParams['custom-target-link'] = $frameParams['link-target'];
|
|
|
|
|
}
|
2012-08-06 17:04:07 +00:00
|
|
|
if ( $parser ) {
|
|
|
|
|
$extLinkAttrs = $parser->getExternalLinkAttribs( $frameParams['link-url'] );
|
|
|
|
|
foreach ( $extLinkAttrs as $name => $val ) {
|
|
|
|
|
// Currently could include 'rel' and 'target'
|
2013-02-03 20:05:24 +00:00
|
|
|
$mtoParams['parser-extlink-' . $name] = $val;
|
2012-08-06 17:04:07 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-07-20 10:28:00 +00:00
|
|
|
} elseif ( isset( $frameParams['link-title'] ) && $frameParams['link-title'] !== '' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$mtoParams['custom-title-link'] = self::normaliseSpecialPage( $frameParams['link-title'] );
|
2010-07-20 10:28:00 +00:00
|
|
|
} elseif ( !empty( $frameParams['no-link'] ) ) {
|
|
|
|
|
// No link
|
|
|
|
|
} else {
|
|
|
|
|
$mtoParams['desc-link'] = true;
|
|
|
|
|
$mtoParams['desc-query'] = $query;
|
|
|
|
|
}
|
|
|
|
|
return $mtoParams;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-18 06:29:23 +00:00
|
|
|
/**
|
|
|
|
|
* Make HTML for a thumbnail including image, border and caption
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $title Title object
|
|
|
|
|
* @param $file File object or false if it doesn't exist
|
|
|
|
|
* @param $label String
|
|
|
|
|
* @param $alt String
|
|
|
|
|
* @param $align String
|
|
|
|
|
* @param $params Array
|
|
|
|
|
* @param $framed Boolean
|
|
|
|
|
* @param $manualthumb String
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return mixed
|
2004-12-18 06:29:23 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function makeThumbLinkObj( Title $title, $file, $label = '', $alt,
|
2013-02-03 20:05:24 +00:00
|
|
|
$align = 'right', $params = array(), $framed = false, $manualthumb = "" )
|
2011-03-21 16:15:56 +00:00
|
|
|
{
|
2008-04-14 07:45:50 +00:00
|
|
|
$frameParams = array(
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
'alt' => $alt,
|
|
|
|
|
'caption' => $label,
|
|
|
|
|
'align' => $align
|
|
|
|
|
);
|
2011-03-02 10:57:55 +00:00
|
|
|
if ( $framed ) {
|
|
|
|
|
$frameParams['framed'] = true;
|
|
|
|
|
}
|
|
|
|
|
if ( $manualthumb ) {
|
|
|
|
|
$frameParams['manualthumb'] = $manualthumb;
|
|
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::makeThumbLink2( $title, $file, $frameParams, $params );
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-02 10:57:55 +00:00
|
|
|
/**
|
|
|
|
|
* @param $title Title
|
|
|
|
|
* @param $file File
|
|
|
|
|
* @param array $frameParams
|
|
|
|
|
* @param array $handlerParams
|
|
|
|
|
* @param bool $time
|
|
|
|
|
* @param string $query
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function makeThumbLink2( Title $title, $file, $frameParams = array(),
|
2011-03-21 16:15:56 +00:00
|
|
|
$handlerParams = array(), $time = false, $query = "" )
|
|
|
|
|
{
|
2011-04-30 12:04:00 +00:00
|
|
|
global $wgStylePath, $wgContLang;
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$exists = $file && $file->exists();
|
2004-12-18 06:29:23 +00:00
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
# Shortcuts
|
|
|
|
|
$fp =& $frameParams;
|
|
|
|
|
$hp =& $handlerParams;
|
2007-04-20 12:31:36 +00:00
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$page = isset( $hp['page'] ) ? $hp['page'] : false;
|
|
|
|
|
if ( !isset( $fp['align'] ) ) $fp['align'] = 'right';
|
|
|
|
|
if ( !isset( $fp['alt'] ) ) $fp['alt'] = '';
|
2009-07-03 05:13:58 +00:00
|
|
|
if ( !isset( $fp['title'] ) ) $fp['title'] = '';
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
if ( !isset( $fp['caption'] ) ) $fp['caption'] = '';
|
|
|
|
|
|
|
|
|
|
if ( empty( $hp['width'] ) ) {
|
2008-04-14 07:45:50 +00:00
|
|
|
// Reduce width for upright images when parameter 'upright' is used
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$hp['width'] = isset( $fp['upright'] ) ? 130 : 180;
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2007-04-20 12:31:36 +00:00
|
|
|
$thumb = false;
|
Initial stab at responsive images for screen densities.
* adds $wgResponsiveImages setting, defaulting to true, to enable the feature
* adds 'srcset' attribute with 1.5x and 2x URLs to image links and image thumbs
* adds jquery.hidpi plugin to check pixel density and implement partial 'srcset' polyfill
** $.devicePixelRatio() returns window.devicePixelRatio, with compat fallback for IE 10
** $().hidpi() performs a 'srcset' polyfill for browsers with no native 'srcset' support
* adds mediawiki.hidpi RL script to trigger hidpi loads after main images load
Note that this is a work in progress. There will be places where this doesn't yet work which output their imgs differently. If moving from a low to high-DPI screen on a MacBook Pro Retina display, you won't see images load until you reload.
Confirmed basic images and thumbs in wikitext appear to work in Safari 6, Chrome 21, Firefox 18 nightly on MacBook Pro Retina display, and IE 10 in Windows 8 at 150% zoom, 200% zoom, and 140% and 180%-ratio Metro tablet sizes.
Internally this is still a bit of a hack; Linker::makeImageLink and Linker::makeThumbLink explicitly ask for 1.5x and 2x scaled versions and insert their URLs, if different, into the original thumbnail object which (in default handler) outputs the srcset. This means that a number of places that handle images differently won't see the higher-resolution versions, such as <gallery> and the large thumbnail on the File: description page.
At some point we may wish to redo some of how the MediaHandler stuff works so that requesting a single thumbnail automatically produces the extra sizes in all circumstances. We might also consider outputting a 'srcset' or multiple src sizes in 'imageinfo' API requests, which would make ApiForeignRepo/InstantCommons more efficient. (Currently it has to make three requests for each image to get the three sizes.)
Change-Id: Id80ebd07a1a9f401a2c2bfeb21aae987e5aa863b
2012-09-18 07:18:50 +00:00
|
|
|
$noscale = false;
|
2007-05-30 21:02:32 +00:00
|
|
|
|
|
|
|
|
if ( !$exists ) {
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$outerWidth = $hp['width'] + 2;
|
2004-12-18 06:29:23 +00:00
|
|
|
} else {
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
if ( isset( $fp['manualthumb'] ) ) {
|
2007-05-30 21:02:32 +00:00
|
|
|
# Use manually specified thumbnail
|
2008-12-01 17:14:30 +00:00
|
|
|
$manual_title = Title::makeTitleSafe( NS_FILE, $fp['manualthumb'] );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $manual_title ) {
|
2007-05-30 21:02:32 +00:00
|
|
|
$manual_img = wfFindFile( $manual_title );
|
|
|
|
|
if ( $manual_img ) {
|
2010-05-19 00:40:48 +00:00
|
|
|
$thumb = $manual_img->getUnscaledThumb( $hp );
|
2007-05-30 21:02:32 +00:00
|
|
|
} else {
|
|
|
|
|
$exists = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
} elseif ( isset( $fp['framed'] ) ) {
|
2007-05-30 21:02:32 +00:00
|
|
|
// Use image dimensions, don't scale
|
2010-05-19 00:40:48 +00:00
|
|
|
$thumb = $file->getUnscaledThumb( $hp );
|
Initial stab at responsive images for screen densities.
* adds $wgResponsiveImages setting, defaulting to true, to enable the feature
* adds 'srcset' attribute with 1.5x and 2x URLs to image links and image thumbs
* adds jquery.hidpi plugin to check pixel density and implement partial 'srcset' polyfill
** $.devicePixelRatio() returns window.devicePixelRatio, with compat fallback for IE 10
** $().hidpi() performs a 'srcset' polyfill for browsers with no native 'srcset' support
* adds mediawiki.hidpi RL script to trigger hidpi loads after main images load
Note that this is a work in progress. There will be places where this doesn't yet work which output their imgs differently. If moving from a low to high-DPI screen on a MacBook Pro Retina display, you won't see images load until you reload.
Confirmed basic images and thumbs in wikitext appear to work in Safari 6, Chrome 21, Firefox 18 nightly on MacBook Pro Retina display, and IE 10 in Windows 8 at 150% zoom, 200% zoom, and 140% and 180%-ratio Metro tablet sizes.
Internally this is still a bit of a hack; Linker::makeImageLink and Linker::makeThumbLink explicitly ask for 1.5x and 2x scaled versions and insert their URLs, if different, into the original thumbnail object which (in default handler) outputs the srcset. This means that a number of places that handle images differently won't see the higher-resolution versions, such as <gallery> and the large thumbnail on the File: description page.
At some point we may wish to redo some of how the MediaHandler stuff works so that requesting a single thumbnail automatically produces the extra sizes in all circumstances. We might also consider outputting a 'srcset' or multiple src sizes in 'imageinfo' API requests, which would make ApiForeignRepo/InstantCommons more efficient. (Currently it has to make three requests for each image to get the three sizes.)
Change-Id: Id80ebd07a1a9f401a2c2bfeb21aae987e5aa863b
2012-09-18 07:18:50 +00:00
|
|
|
$noscale = true;
|
2007-05-30 21:02:32 +00:00
|
|
|
} else {
|
2007-09-18 14:30:40 +00:00
|
|
|
# Do not present an image bigger than the source, for bitmap-style images
|
2013-03-04 08:44:38 +00:00
|
|
|
# This is a hack to maintain compatibility with arbitrary pre-1.10 behavior
|
2007-09-18 14:30:40 +00:00
|
|
|
$srcWidth = $file->getWidth( $page );
|
|
|
|
|
if ( $srcWidth && !$file->mustRender() && $hp['width'] > $srcWidth ) {
|
|
|
|
|
$hp['width'] = $srcWidth;
|
|
|
|
|
}
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$thumb = $file->transform( $hp );
|
2007-05-01 21:30:46 +00:00
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
|
2007-05-30 21:02:32 +00:00
|
|
|
if ( $thumb ) {
|
|
|
|
|
$outerWidth = $thumb->getWidth() + 2;
|
|
|
|
|
} else {
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$outerWidth = $hp['width'] + 2;
|
2007-05-30 21:02:32 +00:00
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2009-03-13 15:02:28 +00:00
|
|
|
# ThumbnailImage::toHtml() already adds page= onto the end of DjVu URLs
|
|
|
|
|
# So we don't need to pass it here in $query. However, the URL for the
|
|
|
|
|
# zoom icon still needs it, so we make a unique query for it. See bug 14771
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$url = $title->getLocalURL( $query );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $page ) {
|
2009-03-13 15:02:28 +00:00
|
|
|
$url = wfAppendQuery( $url, 'page=' . urlencode( $page ) );
|
|
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
$s = "<div class=\"thumb t{$fp['align']}\"><div class=\"thumbinner\" style=\"width:{$outerWidth}px;\">";
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( !$exists ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$s .= self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
|
2010-07-20 10:28:00 +00:00
|
|
|
$zoomIcon = '';
|
2007-05-30 21:02:32 +00:00
|
|
|
} elseif ( !$thumb ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$s .= wfMessage( 'thumbnail_error', '' )->escaped();
|
2010-07-20 10:28:00 +00:00
|
|
|
$zoomIcon = '';
|
2004-12-18 06:29:23 +00:00
|
|
|
} else {
|
Initial stab at responsive images for screen densities.
* adds $wgResponsiveImages setting, defaulting to true, to enable the feature
* adds 'srcset' attribute with 1.5x and 2x URLs to image links and image thumbs
* adds jquery.hidpi plugin to check pixel density and implement partial 'srcset' polyfill
** $.devicePixelRatio() returns window.devicePixelRatio, with compat fallback for IE 10
** $().hidpi() performs a 'srcset' polyfill for browsers with no native 'srcset' support
* adds mediawiki.hidpi RL script to trigger hidpi loads after main images load
Note that this is a work in progress. There will be places where this doesn't yet work which output their imgs differently. If moving from a low to high-DPI screen on a MacBook Pro Retina display, you won't see images load until you reload.
Confirmed basic images and thumbs in wikitext appear to work in Safari 6, Chrome 21, Firefox 18 nightly on MacBook Pro Retina display, and IE 10 in Windows 8 at 150% zoom, 200% zoom, and 140% and 180%-ratio Metro tablet sizes.
Internally this is still a bit of a hack; Linker::makeImageLink and Linker::makeThumbLink explicitly ask for 1.5x and 2x scaled versions and insert their URLs, if different, into the original thumbnail object which (in default handler) outputs the srcset. This means that a number of places that handle images differently won't see the higher-resolution versions, such as <gallery> and the large thumbnail on the File: description page.
At some point we may wish to redo some of how the MediaHandler stuff works so that requesting a single thumbnail automatically produces the extra sizes in all circumstances. We might also consider outputting a 'srcset' or multiple src sizes in 'imageinfo' API requests, which would make ApiForeignRepo/InstantCommons more efficient. (Currently it has to make three requests for each image to get the three sizes.)
Change-Id: Id80ebd07a1a9f401a2c2bfeb21aae987e5aa863b
2012-09-18 07:18:50 +00:00
|
|
|
if ( !$noscale ) {
|
|
|
|
|
self::processResponsiveImages( $file, $thumb, $hp );
|
|
|
|
|
}
|
2010-07-20 10:28:00 +00:00
|
|
|
$params = array(
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
'alt' => $fp['alt'],
|
2008-10-08 16:33:36 +00:00
|
|
|
'title' => $fp['title'],
|
2012-08-20 10:12:47 +00:00
|
|
|
'img-class' => ( isset( $fp['class'] ) && $fp['class'] !== '' ) ? $fp['class'] . ' thumbimage' : 'thumbimage'
|
|
|
|
|
);
|
2011-04-03 11:44:11 +00:00
|
|
|
$params = self::getImageLinkMTOParams( $fp, $query ) + $params;
|
2010-07-20 10:28:00 +00:00
|
|
|
$s .= $thumb->toHtml( $params );
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
if ( isset( $fp['framed'] ) ) {
|
2010-07-20 10:28:00 +00:00
|
|
|
$zoomIcon = "";
|
2004-12-18 06:29:23 +00:00
|
|
|
} else {
|
2011-04-30 12:04:00 +00:00
|
|
|
$zoomIcon = Html::rawElement( 'div', array( 'class' => 'magnify' ),
|
|
|
|
|
Html::rawElement( 'a', array(
|
|
|
|
|
'href' => $url,
|
|
|
|
|
'class' => 'internal',
|
2012-08-19 20:44:29 +00:00
|
|
|
'title' => wfMessage( 'thumbnail-more' )->text() ),
|
2011-04-30 12:04:00 +00:00
|
|
|
Html::element( 'img', array(
|
|
|
|
|
'src' => $wgStylePath . '/common/images/magnify-clip' . ( $wgContLang->isRTL() ? '-rtl' : '' ) . '.png',
|
|
|
|
|
'width' => 15,
|
|
|
|
|
'height' => 11,
|
|
|
|
|
'alt' => "" ) ) ) );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-07-20 10:28:00 +00:00
|
|
|
$s .= ' <div class="thumbcaption">' . $zoomIcon . $fp['caption'] . "</div></div></div>";
|
2010-08-26 19:40:29 +00:00
|
|
|
return str_replace( "\n", ' ', $s );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
Initial stab at responsive images for screen densities.
* adds $wgResponsiveImages setting, defaulting to true, to enable the feature
* adds 'srcset' attribute with 1.5x and 2x URLs to image links and image thumbs
* adds jquery.hidpi plugin to check pixel density and implement partial 'srcset' polyfill
** $.devicePixelRatio() returns window.devicePixelRatio, with compat fallback for IE 10
** $().hidpi() performs a 'srcset' polyfill for browsers with no native 'srcset' support
* adds mediawiki.hidpi RL script to trigger hidpi loads after main images load
Note that this is a work in progress. There will be places where this doesn't yet work which output their imgs differently. If moving from a low to high-DPI screen on a MacBook Pro Retina display, you won't see images load until you reload.
Confirmed basic images and thumbs in wikitext appear to work in Safari 6, Chrome 21, Firefox 18 nightly on MacBook Pro Retina display, and IE 10 in Windows 8 at 150% zoom, 200% zoom, and 140% and 180%-ratio Metro tablet sizes.
Internally this is still a bit of a hack; Linker::makeImageLink and Linker::makeThumbLink explicitly ask for 1.5x and 2x scaled versions and insert their URLs, if different, into the original thumbnail object which (in default handler) outputs the srcset. This means that a number of places that handle images differently won't see the higher-resolution versions, such as <gallery> and the large thumbnail on the File: description page.
At some point we may wish to redo some of how the MediaHandler stuff works so that requesting a single thumbnail automatically produces the extra sizes in all circumstances. We might also consider outputting a 'srcset' or multiple src sizes in 'imageinfo' API requests, which would make ApiForeignRepo/InstantCommons more efficient. (Currently it has to make three requests for each image to get the three sizes.)
Change-Id: Id80ebd07a1a9f401a2c2bfeb21aae987e5aa863b
2012-09-18 07:18:50 +00:00
|
|
|
/**
|
|
|
|
|
* Process responsive images: add 1.5x and 2x subimages to the thumbnail, where
|
|
|
|
|
* applicable.
|
|
|
|
|
*
|
|
|
|
|
* @param File $file
|
|
|
|
|
* @param MediaOutput $thumb
|
|
|
|
|
* @param array $hp image parameters
|
|
|
|
|
*/
|
|
|
|
|
protected static function processResponsiveImages( $file, $thumb, $hp ) {
|
|
|
|
|
global $wgResponsiveImages;
|
|
|
|
|
if ( $wgResponsiveImages ) {
|
|
|
|
|
$hp15 = $hp;
|
|
|
|
|
$hp15['width'] = round( $hp['width'] * 1.5 );
|
|
|
|
|
$hp20 = $hp;
|
|
|
|
|
$hp20['width'] = $hp['width'] * 2;
|
|
|
|
|
if ( isset( $hp['height'] ) ) {
|
|
|
|
|
$hp15['height'] = round( $hp['height'] * 1.5 );
|
|
|
|
|
$hp20['height'] = $hp['height'] * 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$thumb15 = $file->transform( $hp15 );
|
|
|
|
|
$thumb20 = $file->transform( $hp20 );
|
|
|
|
|
if ( $thumb15->url !== $thumb->url ) {
|
|
|
|
|
$thumb->responsiveUrls['1.5'] = $thumb15->url;
|
|
|
|
|
}
|
|
|
|
|
if ( $thumb20->url !== $thumb->url ) {
|
|
|
|
|
$thumb->responsiveUrls['2'] = $thumb20->url;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-17 08:30:15 +00:00
|
|
|
/**
|
2007-06-09 16:19:38 +00:00
|
|
|
* Make a "broken" link to an image
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $title Title object
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $label link label (plain text)
|
|
|
|
|
* @param string $query query string
|
2012-08-31 03:40:19 +00:00
|
|
|
* @param $unused1 Unused parameter kept for b/c
|
|
|
|
|
* @param $unused2 Unused parameter kept for b/c
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $time Boolean: a file of a certain timestamp was requested
|
|
|
|
|
* @return String
|
2005-04-17 08:30:15 +00:00
|
|
|
*/
|
2012-08-31 03:40:19 +00:00
|
|
|
public static function makeBrokenImageLinkObj( $title, $label = '', $query = '', $unused1 = '', $unused2 = '', $time = false ) {
|
2011-07-19 23:09:55 +00:00
|
|
|
global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
|
2011-05-15 12:34:00 +00:00
|
|
|
if ( ! $title instanceof Title ) {
|
2012-08-31 03:40:19 +00:00
|
|
|
return "<!-- ERROR -->" . htmlspecialchars( $label );
|
2011-05-15 12:34:00 +00:00
|
|
|
}
|
|
|
|
|
wfProfileIn( __METHOD__ );
|
2012-08-31 03:40:19 +00:00
|
|
|
if ( $label == '' ) {
|
|
|
|
|
$label = $title->getPrefixedText();
|
|
|
|
|
}
|
|
|
|
|
$encLabel = htmlspecialchars( $label );
|
2011-05-15 12:34:00 +00:00
|
|
|
$currentExists = $time ? ( wfFindFile( $title ) != false ) : false;
|
2010-09-04 22:25:59 +00:00
|
|
|
|
2011-07-19 23:09:55 +00:00
|
|
|
if ( ( $wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads ) && !$currentExists ) {
|
2011-05-15 12:34:00 +00:00
|
|
|
$redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect( $title );
|
2010-01-03 22:45:34 +00:00
|
|
|
|
2011-05-15 12:34:00 +00:00
|
|
|
if ( $redir ) {
|
2007-06-09 16:19:38 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2012-08-31 03:40:19 +00:00
|
|
|
return self::linkKnown( $title, $encLabel, array(), wfCgiToArray( $query ) );
|
2007-06-09 16:19:38 +00:00
|
|
|
}
|
2011-05-15 12:34:00 +00:00
|
|
|
|
|
|
|
|
$href = self::getUploadUrl( $title, $query );
|
|
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return '<a href="' . htmlspecialchars( $href ) . '" class="new" title="' .
|
|
|
|
|
htmlspecialchars( $title->getPrefixedText(), ENT_QUOTES ) . '">' .
|
2012-08-31 03:40:19 +00:00
|
|
|
$encLabel . '</a>';
|
2005-04-17 08:30:15 +00:00
|
|
|
}
|
2013-01-09 13:25:49 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return self::linkKnown( $title, $encLabel, array(), wfCgiToArray( $query ) );
|
2005-04-17 08:30:15 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
|
2010-01-12 19:43:03 +00:00
|
|
|
/**
|
|
|
|
|
* Get the URL to upload a certain file
|
2010-08-26 19:40:29 +00:00
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $destFile Title object of the file to upload
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $query urlencoded query string to prepend
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: urlencoded URL
|
2010-01-12 19:43:03 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
protected static function getUploadUrl( $destFile, $query = '' ) {
|
2011-07-19 23:09:55 +00:00
|
|
|
global $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
|
2013-03-22 07:39:02 +00:00
|
|
|
$q = 'wpDestFile=' . $destFile->getPartialURL();
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $query != '' )
|
2010-01-12 19:43:03 +00:00
|
|
|
$q .= '&' . $query;
|
|
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $wgUploadMissingFileUrl ) {
|
2010-07-27 10:31:30 +00:00
|
|
|
return wfAppendQuery( $wgUploadMissingFileUrl, $q );
|
2011-07-19 23:09:55 +00:00
|
|
|
} elseif( $wgUploadNavigationUrl ) {
|
|
|
|
|
return wfAppendQuery( $wgUploadNavigationUrl, $q );
|
2010-01-12 19:43:03 +00:00
|
|
|
} else {
|
|
|
|
|
$upload = SpecialPage::getTitleFor( 'Upload' );
|
|
|
|
|
return $upload->getLocalUrl( $q );
|
2010-08-26 19:40:29 +00:00
|
|
|
}
|
2010-01-12 19:43:03 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-02-21 01:56:50 +00:00
|
|
|
/**
|
|
|
|
|
* Create a direct link to a given uploaded file.
|
2006-11-08 07:12:03 +00:00
|
|
|
*
|
|
|
|
|
* @param $title Title object.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $html pre-sanitized HTML
|
|
|
|
|
* @param string $time MW timestamp of file creation time
|
2011-03-23 03:13:37 +00:00
|
|
|
* @return String: HTML
|
|
|
|
|
*/
|
2011-09-03 13:46:56 +00:00
|
|
|
public static function makeMediaLinkObj( $title, $html = '', $time = false ) {
|
2011-03-23 03:13:37 +00:00
|
|
|
$img = wfFindFile( $title, array( 'time' => $time ) );
|
2011-09-03 13:46:56 +00:00
|
|
|
return self::makeMediaLinkFile( $title, $img, $html );
|
2011-03-23 03:13:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a direct link to a given uploaded file.
|
|
|
|
|
* This will make a broken link if $file is false.
|
|
|
|
|
*
|
|
|
|
|
* @param $title Title object.
|
2012-02-09 18:01:10 +00:00
|
|
|
* @param $file File|bool mixed File object or false
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $html pre-sanitized HTML
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML
|
2006-11-08 07:12:03 +00:00
|
|
|
*
|
2005-02-21 01:56:50 +00:00
|
|
|
* @todo Handle invalid or missing images better.
|
|
|
|
|
*/
|
2011-09-03 13:46:56 +00:00
|
|
|
public static function makeMediaLinkFile( Title $title, $file, $html = '' ) {
|
2011-03-23 03:13:37 +00:00
|
|
|
if ( $file && $file->exists() ) {
|
|
|
|
|
$url = $file->getURL();
|
|
|
|
|
$class = 'internal';
|
2004-12-18 06:29:23 +00:00
|
|
|
} else {
|
2011-04-03 11:44:11 +00:00
|
|
|
$url = self::getUploadUrl( $title );
|
2011-03-23 03:13:37 +00:00
|
|
|
$class = 'new';
|
|
|
|
|
}
|
|
|
|
|
$alt = htmlspecialchars( $title->getText(), ENT_QUOTES );
|
2011-09-03 13:46:56 +00:00
|
|
|
if ( $html == '' ) {
|
|
|
|
|
$html = $alt;
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2011-03-23 03:13:37 +00:00
|
|
|
$u = htmlspecialchars( $url );
|
2011-09-03 13:46:56 +00:00
|
|
|
return "<a href=\"{$u}\" class=\"$class\" title=\"{$alt}\">{$html}</a>";
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2010-01-07 09:32:09 +00:00
|
|
|
/**
|
2011-05-29 14:01:47 +00:00
|
|
|
* Make a link to a special page given its name and, optionally,
|
2010-01-07 09:32:09 +00:00
|
|
|
* a message key from the link text.
|
2011-10-11 13:00:17 +00:00
|
|
|
* Usage example: Linker::specialLink( 'Recentchanges' )
|
2011-05-29 14:01:47 +00:00
|
|
|
*
|
2011-07-23 20:58:18 +00:00
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function specialLink( $name, $key = '' ) {
|
2011-05-29 14:01:47 +00:00
|
|
|
if ( $key == '' ) {
|
|
|
|
|
$key = strtolower( $name );
|
|
|
|
|
}
|
2010-09-03 21:53:02 +00:00
|
|
|
|
2013-02-03 20:05:24 +00:00
|
|
|
return self::linkKnown( SpecialPage::getTitleFor( $name ), wfMessage( $key )->text() );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2009-03-09 15:53:08 +00:00
|
|
|
/**
|
|
|
|
|
* Make an external link
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $url URL to link to
|
|
|
|
|
* @param string $text text of link
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $escape Boolean: do we escape the link text?
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $linktype type of external link. Gets added to the classes
|
|
|
|
|
* @param array $attribs of extra attributes to <a>
|
2012-12-05 20:09:14 +00:00
|
|
|
* @param $title Title|null Title object used for title specific link attributes
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-03-09 15:53:08 +00:00
|
|
|
*/
|
2012-12-05 20:09:14 +00:00
|
|
|
public static function makeExternalLink( $url, $text, $escape = true, $linktype = '', $attribs = array(), $title = null ) {
|
|
|
|
|
global $wgTitle;
|
2011-02-05 23:06:36 +00:00
|
|
|
$class = "external";
|
2011-09-19 18:38:38 +00:00
|
|
|
if ( $linktype ) {
|
2011-02-05 23:06:36 +00:00
|
|
|
$class .= " $linktype";
|
2010-08-26 19:40:29 +00:00
|
|
|
}
|
2011-09-19 18:38:38 +00:00
|
|
|
if ( isset( $attribs['class'] ) && $attribs['class'] ) {
|
2011-02-05 23:06:36 +00:00
|
|
|
$class .= " {$attribs['class']}";
|
|
|
|
|
}
|
|
|
|
|
$attribs['class'] = $class;
|
2011-05-25 15:39:47 +00:00
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $escape ) {
|
2004-12-18 06:29:23 +00:00
|
|
|
$text = htmlspecialchars( $text );
|
|
|
|
|
}
|
2012-12-05 20:09:14 +00:00
|
|
|
|
|
|
|
|
if ( !$title ) {
|
|
|
|
|
$title = $wgTitle;
|
|
|
|
|
}
|
|
|
|
|
$attribs['rel'] = Parser::getExternalLinkRel( $url, $title );
|
2008-06-08 21:45:05 +00:00
|
|
|
$link = '';
|
2011-03-21 16:15:56 +00:00
|
|
|
$success = wfRunHooks( 'LinkerMakeExternalLink',
|
|
|
|
|
array( &$url, &$text, &$link, &$attribs, $linktype ) );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( !$success ) {
|
|
|
|
|
wfDebug( "Hook LinkerMakeExternalLink changed the output of link with url {$url} and text {$text} to {$link}\n", true );
|
2008-06-08 21:45:05 +00:00
|
|
|
return $link;
|
|
|
|
|
}
|
2011-02-05 23:06:36 +00:00
|
|
|
$attribs['href'] = $url;
|
|
|
|
|
return Html::rawElement( 'a', $attribs, $text );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
|
|
|
|
* Make user link (or user contributions for unregistered users)
|
2006-11-08 07:12:03 +00:00
|
|
|
* @param $userId Integer: user id in database.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $userName user name in database.
|
|
|
|
|
* @param string $altUserName text to display instead of the user name (optional)
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML fragment
|
2012-07-04 09:38:56 +00:00
|
|
|
* @since 1.19 Method exists for a long time. $altUserName was added in 1.19.
|
2006-03-16 19:04:25 +00:00
|
|
|
*/
|
2012-01-05 09:33:46 +00:00
|
|
|
public static function userLink( $userId, $userName, $altUserName = false ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $userId == 0 ) {
|
2012-01-05 09:33:46 +00:00
|
|
|
$page = SpecialPage::getTitleFor( 'Contributions', $userName );
|
2012-05-22 23:30:07 +00:00
|
|
|
if ( $altUserName === false ) {
|
|
|
|
|
$altUserName = IP::prettifyIP( $userName );
|
|
|
|
|
}
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
2012-01-05 09:33:46 +00:00
|
|
|
$page = Title::makeTitle( NS_USER, $userName );
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
2012-01-05 09:33:46 +00:00
|
|
|
|
|
|
|
|
return self::link(
|
|
|
|
|
$page,
|
|
|
|
|
htmlspecialchars( $altUserName !== false ? $altUserName : $userName ),
|
|
|
|
|
array( 'class' => 'mw-userlink' )
|
|
|
|
|
);
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2007-08-06 07:09:59 +00:00
|
|
|
* Generate standard user tool links (talk, contributions, block link, etc.)
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $userId Integer: user identifier
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $userText user name or IP address
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $redContribsWhenNoEdits Boolean: should the contributions link be
|
|
|
|
|
* red if the user has no edits?
|
2011-09-07 12:12:24 +00:00
|
|
|
* @param $flags Integer: customisation flags (e.g. Linker::TOOL_LINKS_NOBLOCK and Linker::TOOL_LINKS_EMAIL)
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $edits Integer: user edit count (optional, for performance)
|
|
|
|
|
* @return String: HTML fragment
|
2006-03-16 19:04:25 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function userToolLinks(
|
2011-03-21 16:15:56 +00:00
|
|
|
$userId, $userText, $redContribsWhenNoEdits = false, $flags = 0, $edits = null
|
|
|
|
|
) {
|
2011-03-12 12:13:22 +00:00
|
|
|
global $wgUser, $wgDisableAnonTalk, $wgLang;
|
2006-03-16 19:04:25 +00:00
|
|
|
$talkable = !( $wgDisableAnonTalk && 0 == $userId );
|
2011-09-11 08:14:46 +00:00
|
|
|
$blockable = !( $flags & self::TOOL_LINKS_NOBLOCK );
|
|
|
|
|
$addEmailLink = $flags & self::TOOL_LINKS_EMAIL && $userId;
|
2006-03-16 19:04:25 +00:00
|
|
|
|
|
|
|
|
$items = array();
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $talkable ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$items[] = self::userTalkLink( $userId, $userText );
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $userId ) {
|
2007-01-23 19:56:01 +00:00
|
|
|
// check if the user has an edit
|
2008-07-30 21:02:28 +00:00
|
|
|
$attribs = array();
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $redContribsWhenNoEdits ) {
|
2012-10-03 15:22:40 +00:00
|
|
|
if ( intval( $edits ) === 0 && $edits !== 0 ) {
|
|
|
|
|
$user = User::newFromId( $userId );
|
|
|
|
|
$edits = $user->getEditCount();
|
|
|
|
|
}
|
|
|
|
|
if ( $edits === 0 ) {
|
2008-07-30 21:02:28 +00:00
|
|
|
$attribs['class'] = 'new';
|
|
|
|
|
}
|
2007-01-23 19:56:01 +00:00
|
|
|
}
|
2006-12-02 08:52:54 +00:00
|
|
|
$contribsPage = SpecialPage::getTitleFor( 'Contributions', $userText );
|
2007-01-23 19:56:01 +00:00
|
|
|
|
2012-08-19 20:44:29 +00:00
|
|
|
$items[] = self::link( $contribsPage, wfMessage( 'contribslink' )->escaped(), $attribs );
|
2006-03-16 21:17:32 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $blockable && $wgUser->isAllowed( 'block' ) ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$items[] = self::blockLink( $userId, $userText );
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
2011-09-07 12:12:24 +00:00
|
|
|
if ( $addEmailLink && $wgUser->canSendEmail() ) {
|
|
|
|
|
$items[] = self::emailLink( $userId, $userText );
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-20 15:16:54 +00:00
|
|
|
wfRunHooks( 'UserToolLinksEdit', array( $userId, $userText, &$items ) );
|
|
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $items ) {
|
2012-05-29 08:28:07 +00:00
|
|
|
return wfMessage( 'word-separator' )->plain()
|
|
|
|
|
. '<span class="mw-usertoollinks">'
|
|
|
|
|
. wfMessage( 'parentheses' )->rawParams( $wgLang->pipeList( $items ) )->escaped()
|
|
|
|
|
. '</span>';
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-23 19:56:01 +00:00
|
|
|
/**
|
|
|
|
|
* Alias for userToolLinks( $userId, $userText, true );
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $userId Integer: user identifier
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $userText user name or IP address
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $edits Integer: user edit count (optional, for performance)
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return String
|
2007-01-23 19:56:01 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function userToolLinksRedContribs( $userId, $userText, $edits = null ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::userToolLinks( $userId, $userText, true, 0, $edits );
|
2007-01-23 19:56:01 +00:00
|
|
|
}
|
|
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
2006-11-08 07:12:03 +00:00
|
|
|
* @param $userId Integer: user id in database.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $userText user name in database.
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML fragment with user talk link
|
2006-03-16 19:04:25 +00:00
|
|
|
*/
|
2011-09-07 17:00:46 +00:00
|
|
|
public static function userTalkLink( $userId, $userText ) {
|
2006-03-16 19:04:25 +00:00
|
|
|
$userTalkPage = Title::makeTitle( NS_USER_TALK, $userText );
|
2012-08-19 20:44:29 +00:00
|
|
|
$userTalkLink = self::link( $userTalkPage, wfMessage( 'talkpagelinktext' )->escaped() );
|
2006-03-16 19:04:25 +00:00
|
|
|
return $userTalkLink;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2006-11-08 07:12:03 +00:00
|
|
|
* @param $userId Integer: userid
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $userText user name in database.
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML fragment with block link
|
2006-03-16 19:04:25 +00:00
|
|
|
*/
|
2011-09-07 17:00:46 +00:00
|
|
|
public static function blockLink( $userId, $userText ) {
|
2011-03-12 23:22:34 +00:00
|
|
|
$blockPage = SpecialPage::getTitleFor( 'Block', $userText );
|
2012-08-19 20:44:29 +00:00
|
|
|
$blockLink = self::link( $blockPage, wfMessage( 'blocklink' )->escaped() );
|
2006-03-16 19:04:25 +00:00
|
|
|
return $blockLink;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2011-09-07 12:12:24 +00:00
|
|
|
/**
|
|
|
|
|
* @param $userId Integer: userid
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $userText user name in database.
|
2011-09-07 12:12:24 +00:00
|
|
|
* @return String: HTML fragment with e-mail user link
|
|
|
|
|
*/
|
2011-09-07 17:00:46 +00:00
|
|
|
public static function emailLink( $userId, $userText ) {
|
2011-09-07 13:35:01 +00:00
|
|
|
$emailPage = SpecialPage::getTitleFor( 'Emailuser', $userText );
|
2012-08-19 20:44:29 +00:00
|
|
|
$emailLink = self::link( $emailPage, wfMessage( 'emaillink' )->escaped() );
|
2011-09-07 12:12:24 +00:00
|
|
|
return $emailLink;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
|
|
|
|
* Generate a user link if the current user is allowed to view it
|
2006-11-08 07:12:03 +00:00
|
|
|
* @param $rev Revision object.
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $isPublic Boolean: show only if all users can see it
|
|
|
|
|
* @return String: HTML fragment
|
2006-03-16 19:04:25 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function revUserLink( $rev, $isPublic = false ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$link = wfMessage( 'rev-deleted-user' )->escaped();
|
2011-06-17 16:03:52 +00:00
|
|
|
} elseif ( $rev->userCan( Revision::DELETED_USER ) ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$link = self::userLink( $rev->getUser( Revision::FOR_THIS_USER ),
|
2008-09-24 09:44:45 +00:00
|
|
|
$rev->getUserText( Revision::FOR_THIS_USER ) );
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
2012-08-19 20:44:29 +00:00
|
|
|
$link = wfMessage( 'rev-deleted-user' )->escaped();
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
|
2006-03-16 19:04:25 +00:00
|
|
|
return '<span class="history-deleted">' . $link . '</span>';
|
|
|
|
|
}
|
|
|
|
|
return $link;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate a user tool link cluster if the current user is allowed to view it
|
2006-11-08 07:12:03 +00:00
|
|
|
* @param $rev Revision object.
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $isPublic Boolean: show only if all users can see it
|
2006-03-16 19:04:25 +00:00
|
|
|
* @return string HTML
|
|
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function revUserTools( $rev, $isPublic = false ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$link = wfMessage( 'rev-deleted-user' )->escaped();
|
2011-06-17 16:03:52 +00:00
|
|
|
} elseif ( $rev->userCan( Revision::DELETED_USER ) ) {
|
2008-09-24 09:44:45 +00:00
|
|
|
$userId = $rev->getUser( Revision::FOR_THIS_USER );
|
2010-01-07 09:32:09 +00:00
|
|
|
$userText = $rev->getUserText( Revision::FOR_THIS_USER );
|
2012-05-29 08:28:07 +00:00
|
|
|
$link = self::userLink( $userId, $userText )
|
|
|
|
|
. wfMessage( 'word-separator' )->plain()
|
|
|
|
|
. self::userToolLinks( $userId, $userText );
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
2012-08-19 20:44:29 +00:00
|
|
|
$link = wfMessage( 'rev-deleted-user' )->escaped();
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
|
2008-03-09 02:25:04 +00:00
|
|
|
return ' <span class="history-deleted">' . $link . '</span>';
|
2007-03-14 15:50:06 +00:00
|
|
|
}
|
|
|
|
|
return $link;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2004-12-18 06:29:23 +00:00
|
|
|
/**
|
|
|
|
|
* This function is called by all recent changes variants, by the page history,
|
|
|
|
|
* and by the user contributions list. It is responsible for formatting edit
|
2012-12-19 22:20:54 +00:00
|
|
|
* summaries. It escapes any HTML in the summary, but adds some CSS to format
|
2004-12-18 06:29:23 +00:00
|
|
|
* auto-generated comments (from section editing) and formats [[wikilinks]].
|
2006-11-08 07:12:03 +00:00
|
|
|
*
|
2004-12-18 06:29:23 +00:00
|
|
|
* @author Erik Moeller <moeller@scireview.de>
|
2006-11-08 07:12:03 +00:00
|
|
|
*
|
2004-12-18 06:29:23 +00:00
|
|
|
* Note: there's not always a title to pass to this function.
|
|
|
|
|
* Since you can't set a default parameter for a reference, I've turned it
|
|
|
|
|
* temporarily to a value pass. Should be adjusted further. --brion
|
2006-11-17 03:59:32 +00:00
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $comment String
|
|
|
|
|
* @param $title Mixed: Title object (to generate link to the section in autocomment) or null
|
|
|
|
|
* @param $local Boolean: whether section links should refer to local page
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return mixed|String
|
2004-12-18 06:29:23 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function formatComment( $comment, $title = null, $local = false ) {
|
2006-11-17 03:59:32 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2007-05-09 20:05:08 +00:00
|
|
|
# Sanitize text a bit:
|
2005-04-06 00:00:03 +00:00
|
|
|
$comment = str_replace( "\n", " ", $comment );
|
2008-08-18 18:15:47 +00:00
|
|
|
# Allow HTML entities (for bug 13815)
|
|
|
|
|
$comment = Sanitizer::escapeHtmlAllowEntities( $comment );
|
2004-12-18 06:29:23 +00:00
|
|
|
|
2007-05-09 20:05:08 +00:00
|
|
|
# Render autocomments and make links:
|
2011-04-03 11:44:11 +00:00
|
|
|
$comment = self::formatAutocomments( $comment, $title, $local );
|
|
|
|
|
$comment = self::formatLinksInComment( $comment, $title, $local );
|
2007-05-09 20:05:08 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $comment;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-28 14:52:55 +00:00
|
|
|
/**
|
|
|
|
|
* @var Title
|
|
|
|
|
*/
|
2011-04-03 11:44:11 +00:00
|
|
|
static $autocommentTitle;
|
|
|
|
|
static $autocommentLocal;
|
|
|
|
|
|
2007-05-09 20:05:08 +00:00
|
|
|
/**
|
2012-12-19 22:20:54 +00:00
|
|
|
* Converts autogenerated comments in edit summaries into section links.
|
2007-05-09 20:05:08 +00:00
|
|
|
* The pattern for autogen comments is / * foo * /, which makes for
|
|
|
|
|
* some nasty regex.
|
|
|
|
|
* We look for all comments, match any text before and after the comment,
|
|
|
|
|
* add a separator where needed and format the comment itself with CSS
|
|
|
|
|
* Called by Linker::formatComment.
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $comment comment text
|
2012-02-09 19:29:36 +00:00
|
|
|
* @param $title Title|null An optional title object used to links to sections
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $local Boolean: whether section links should refer to local page
|
|
|
|
|
* @return String: formatted comment
|
2007-05-09 20:05:08 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
private static function formatAutocomments( $comment, $title = null, $local = false ) {
|
2008-08-14 23:33:02 +00:00
|
|
|
// Bah!
|
2011-04-03 11:44:11 +00:00
|
|
|
self::$autocommentTitle = $title;
|
|
|
|
|
self::$autocommentLocal = $local;
|
2008-08-14 23:33:02 +00:00
|
|
|
$comment = preg_replace_callback(
|
2008-08-18 17:22:12 +00:00
|
|
|
'!(.*)/\*\s*(.*?)\s*\*/(.*)!',
|
2011-04-03 11:44:11 +00:00
|
|
|
array( 'Linker', 'formatAutocommentsCallback' ),
|
2008-08-14 23:33:02 +00:00
|
|
|
$comment );
|
2011-04-03 11:44:11 +00:00
|
|
|
self::$autocommentTitle = null;
|
|
|
|
|
self::$autocommentLocal = null;
|
2008-08-14 23:33:02 +00:00
|
|
|
return $comment;
|
|
|
|
|
}
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2011-05-29 14:01:47 +00:00
|
|
|
/**
|
2012-12-19 22:20:54 +00:00
|
|
|
* Helper function for Linker::formatAutocomments
|
2011-05-29 14:01:47 +00:00
|
|
|
* @param $match
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
private static function formatAutocommentsCallback( $match ) {
|
2011-12-12 06:40:40 +00:00
|
|
|
global $wgLang;
|
2011-04-03 11:44:11 +00:00
|
|
|
$title = self::$autocommentTitle;
|
|
|
|
|
$local = self::$autocommentLocal;
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2010-02-08 20:05:06 +00:00
|
|
|
$pre = $match[1];
|
|
|
|
|
$auto = $match[2];
|
|
|
|
|
$post = $match[3];
|
2012-06-15 09:40:40 +00:00
|
|
|
$comment = null;
|
|
|
|
|
wfRunHooks( 'FormatAutocomments', array( &$comment, $pre, $auto, $post, $title, $local ) );
|
|
|
|
|
if ( $comment === null ) {
|
|
|
|
|
$link = '';
|
|
|
|
|
if ( $title ) {
|
|
|
|
|
$section = $auto;
|
|
|
|
|
|
|
|
|
|
# Remove links that a user may have manually put in the autosummary
|
|
|
|
|
# This could be improved by copying as much of Parser::stripSectionName as desired.
|
|
|
|
|
$section = str_replace( '[[:', '', $section );
|
|
|
|
|
$section = str_replace( '[[', '', $section );
|
|
|
|
|
$section = str_replace( ']]', '', $section );
|
|
|
|
|
|
|
|
|
|
$section = Sanitizer::normalizeSectionNameWhitespace( $section ); # bug 22784
|
|
|
|
|
if ( $local ) {
|
|
|
|
|
$sectionTitle = Title::newFromText( '#' . $section );
|
|
|
|
|
} else {
|
|
|
|
|
$sectionTitle = Title::makeTitleSafe( $title->getNamespace(),
|
|
|
|
|
$title->getDBkey(), $section );
|
|
|
|
|
}
|
|
|
|
|
if ( $sectionTitle ) {
|
|
|
|
|
$link = self::link( $sectionTitle,
|
|
|
|
|
$wgLang->getArrow(), array(), array(),
|
|
|
|
|
'noclasses' );
|
|
|
|
|
} else {
|
|
|
|
|
$link = '';
|
|
|
|
|
}
|
2008-02-06 11:45:38 +00:00
|
|
|
}
|
2012-06-15 09:40:40 +00:00
|
|
|
if ( $pre ) {
|
|
|
|
|
# written summary $presep autocomment (summary /* section */)
|
2012-08-19 20:44:29 +00:00
|
|
|
$pre .= wfMessage( 'autocomment-prefix' )->inContentLanguage()->escaped();
|
2008-08-28 23:12:57 +00:00
|
|
|
}
|
2012-06-15 09:40:40 +00:00
|
|
|
if ( $post ) {
|
|
|
|
|
# autocomment $postsep written summary (/* section */ summary)
|
2012-08-19 20:44:29 +00:00
|
|
|
$auto .= wfMessage( 'colon-separator' )->inContentLanguage()->escaped();
|
2012-06-15 09:40:40 +00:00
|
|
|
}
|
|
|
|
|
$auto = '<span class="autocomment">' . $auto . '</span>';
|
|
|
|
|
$comment = $pre . $link . $wgLang->getDirMark() . '<span dir="auto">' . $auto . $post . '</span>';
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2007-05-09 20:05:08 +00:00
|
|
|
return $comment;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-29 14:01:47 +00:00
|
|
|
/**
|
|
|
|
|
* @var Title
|
|
|
|
|
*/
|
2011-04-03 11:44:11 +00:00
|
|
|
static $commentContextTitle;
|
|
|
|
|
static $commentLocal;
|
|
|
|
|
|
2007-05-09 20:05:08 +00:00
|
|
|
/**
|
2007-06-07 22:16:19 +00:00
|
|
|
* Formats wiki links and media links in text; all other wiki formatting
|
|
|
|
|
* is ignored
|
|
|
|
|
*
|
2011-05-17 22:03:20 +00:00
|
|
|
* @todo FIXME: Doesn't handle sub-links as in image thumb texts like the main parser
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $comment text to format links in
|
2012-02-09 19:29:36 +00:00
|
|
|
* @param $title Title|null An optional title object used to links to sections
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $local Boolean: whether section links should refer to local page
|
|
|
|
|
* @return String
|
2007-05-09 20:05:08 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function formatLinksInComment( $comment, $title = null, $local = false ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
self::$commentContextTitle = $title;
|
|
|
|
|
self::$commentLocal = $local;
|
2009-08-27 22:27:42 +00:00
|
|
|
$html = preg_replace_callback(
|
2012-10-30 01:49:15 +00:00
|
|
|
'/
|
|
|
|
|
\[\[
|
|
|
|
|
:? # ignore optional leading colon
|
|
|
|
|
([^\]|]+) # 1. link target; page names cannot include ] or |
|
|
|
|
|
(?:\|
|
|
|
|
|
# 2. a pipe-separated substring; only the last is captured
|
|
|
|
|
# Stop matching at | and ]] without relying on backtracking.
|
|
|
|
|
((?:]?[^\]|])*+)
|
|
|
|
|
)*
|
|
|
|
|
\]\]
|
|
|
|
|
([^[]*) # 3. link trail (the text up until the next link)
|
|
|
|
|
/x',
|
2011-04-03 11:44:11 +00:00
|
|
|
array( 'Linker', 'formatLinksInCommentCallback' ),
|
2009-08-27 22:27:42 +00:00
|
|
|
$comment );
|
2011-04-03 11:44:11 +00:00
|
|
|
self::$commentContextTitle = null;
|
|
|
|
|
self::$commentLocal = null;
|
2009-07-20 02:07:56 +00:00
|
|
|
return $html;
|
2007-10-04 18:59:50 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2011-05-29 14:01:47 +00:00
|
|
|
/**
|
|
|
|
|
* @param $match
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
protected static function formatLinksInCommentCallback( $match ) {
|
2007-05-09 20:05:08 +00:00
|
|
|
global $wgContLang;
|
|
|
|
|
|
2008-03-21 23:13:34 +00:00
|
|
|
$medians = '(?:' . preg_quote( MWNamespace::getCanonicalName( NS_MEDIA ), '/' ) . '|';
|
2006-12-03 04:09:48 +00:00
|
|
|
$medians .= preg_quote( $wgContLang->getNsText( NS_MEDIA ), '/' ) . '):';
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-10-04 18:59:50 +00:00
|
|
|
$comment = $match[0];
|
2007-05-09 20:05:08 +00:00
|
|
|
|
2008-05-22 20:02:03 +00:00
|
|
|
# fix up urlencoded title texts (copied from Parser::replaceInternalLinks)
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( strpos( $match[1], '%' ) !== false ) {
|
2010-12-24 09:53:08 +00:00
|
|
|
$match[1] = str_replace( array( '<', '>' ), array( '<', '>' ), rawurldecode( $match[1] ) );
|
2008-05-22 20:02:03 +00:00
|
|
|
}
|
|
|
|
|
|
2007-10-04 18:59:50 +00:00
|
|
|
# Handle link renaming [[foo|text]] will show link as "text"
|
2012-10-25 13:54:52 +00:00
|
|
|
if ( $match[2] != "" ) {
|
|
|
|
|
$text = $match[2];
|
2007-10-04 18:59:50 +00:00
|
|
|
} else {
|
|
|
|
|
$text = $match[1];
|
|
|
|
|
}
|
|
|
|
|
$submatch = array();
|
2009-07-21 17:07:56 +00:00
|
|
|
$thelink = null;
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
|
2007-10-04 18:59:50 +00:00
|
|
|
# Media link; trail not supported.
|
2009-08-27 22:27:42 +00:00
|
|
|
$linkRegexp = '/\[\[(.*?)\]\]/';
|
2009-06-13 13:41:48 +00:00
|
|
|
$title = Title::makeTitleSafe( NS_FILE, $submatch[1] );
|
2011-09-22 15:08:32 +00:00
|
|
|
if ( $title ) {
|
|
|
|
|
$thelink = self::makeMediaLinkObj( $title, $text );
|
|
|
|
|
}
|
2007-10-04 18:59:50 +00:00
|
|
|
} else {
|
|
|
|
|
# Other kind of link
|
2012-10-25 13:54:52 +00:00
|
|
|
if ( preg_match( $wgContLang->linkTrail(), $match[3], $submatch ) ) {
|
2007-10-04 18:59:50 +00:00
|
|
|
$trail = $submatch[1];
|
2004-12-18 06:29:23 +00:00
|
|
|
} else {
|
2007-10-04 18:59:50 +00:00
|
|
|
$trail = "";
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2009-08-27 22:27:42 +00:00
|
|
|
$linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( isset( $match[1][0] ) && $match[1][0] == ':' )
|
|
|
|
|
$match[1] = substr( $match[1], 1 );
|
2011-04-03 11:44:11 +00:00
|
|
|
list( $inside, $trail ) = self::splitTrail( $trail );
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2009-07-20 02:07:56 +00:00
|
|
|
$linkText = $text;
|
2011-04-03 11:44:11 +00:00
|
|
|
$linkTarget = self::normalizeSubpageLink( self::$commentContextTitle,
|
2009-07-20 02:07:56 +00:00
|
|
|
$match[1], $linkText );
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2009-07-20 02:26:37 +00:00
|
|
|
$target = Title::newFromText( $linkTarget );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $target ) {
|
|
|
|
|
if ( $target->getText() == '' && $target->getInterwiki() === ''
|
2011-04-03 11:44:11 +00:00
|
|
|
&& !self::$commentLocal && self::$commentContextTitle )
|
2010-04-27 18:09:37 +00:00
|
|
|
{
|
2011-04-03 11:44:11 +00:00
|
|
|
$newTarget = clone ( self::$commentContextTitle );
|
2009-07-20 02:26:37 +00:00
|
|
|
$newTarget->setFragment( '#' . $target->getFragment() );
|
|
|
|
|
$target = $newTarget;
|
|
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
$thelink = self::link(
|
2009-07-20 02:26:37 +00:00
|
|
|
$target,
|
|
|
|
|
$linkText . $inside
|
|
|
|
|
) . $trail;
|
|
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $thelink ) {
|
2009-07-21 17:07:56 +00:00
|
|
|
// If the link is still valid, go ahead and replace it in!
|
|
|
|
|
$comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 );
|
|
|
|
|
}
|
2007-05-09 20:05:08 +00:00
|
|
|
|
2004-12-18 06:29:23 +00:00
|
|
|
return $comment;
|
|
|
|
|
}
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2011-03-02 10:57:55 +00:00
|
|
|
/**
|
|
|
|
|
* @param $contextTitle Title
|
|
|
|
|
* @param $target
|
|
|
|
|
* @param $text
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function normalizeSubpageLink( $contextTitle, $target, &$text ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
# Valid link forms:
|
|
|
|
|
# Foobar -- normal
|
|
|
|
|
# :Foobar -- override special treatment of prefix (images, language links)
|
|
|
|
|
# /Foobar -- convert to CurrentPage/Foobar
|
|
|
|
|
# /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
|
|
|
|
|
# ../ -- convert to CurrentPage, from CurrentPage/CurrentSubPage
|
|
|
|
|
# ../Foobar -- convert to CurrentPage/Foobar, from CurrentPage/CurrentSubPage
|
|
|
|
|
|
|
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
$ret = $target; # default return value is no change
|
|
|
|
|
|
|
|
|
|
# Some namespaces don't allow subpages,
|
|
|
|
|
# so only perform processing if subpages are allowed
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $contextTitle && MWNamespace::hasSubpages( $contextTitle->getNamespace() ) ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
$hash = strpos( $target, '#' );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $hash !== false ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
$suffix = substr( $target, $hash );
|
|
|
|
|
$target = substr( $target, 0, $hash );
|
|
|
|
|
} else {
|
|
|
|
|
$suffix = '';
|
|
|
|
|
}
|
|
|
|
|
# bug 7425
|
|
|
|
|
$target = trim( $target );
|
|
|
|
|
# Look at the first character
|
2011-09-22 14:57:08 +00:00
|
|
|
if ( $target != '' && $target[0] === '/' ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
# / at end means we don't want the slash to be shown
|
|
|
|
|
$m = array();
|
|
|
|
|
$trailingSlashes = preg_match_all( '%(/+)$%', $target, $m );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $trailingSlashes ) {
|
|
|
|
|
$noslash = $target = substr( $target, 1, -strlen( $m[0][0] ) );
|
2009-07-20 02:07:56 +00:00
|
|
|
} else {
|
|
|
|
|
$noslash = substr( $target, 1 );
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
$ret = $contextTitle->getPrefixedText() . '/' . trim( $noslash ) . $suffix;
|
|
|
|
|
if ( $text === '' ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
$text = $target . $suffix;
|
|
|
|
|
} # this might be changed for ugliness reasons
|
|
|
|
|
} else {
|
|
|
|
|
# check for .. subpage backlinks
|
|
|
|
|
$dotdotcount = 0;
|
|
|
|
|
$nodotdot = $target;
|
2010-08-26 19:40:29 +00:00
|
|
|
while ( strncmp( $nodotdot, "../", 3 ) == 0 ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
++$dotdotcount;
|
|
|
|
|
$nodotdot = substr( $nodotdot, 3 );
|
|
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $dotdotcount > 0 ) {
|
2013-03-22 07:39:02 +00:00
|
|
|
$exploded = explode( '/', $contextTitle->getPrefixedText() );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( count( $exploded ) > $dotdotcount ) { # not allowed to go below top level page
|
2009-07-20 02:07:56 +00:00
|
|
|
$ret = implode( '/', array_slice( $exploded, 0, -$dotdotcount ) );
|
|
|
|
|
# / at the end means don't show full path
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( substr( $nodotdot, -1, 1 ) === '/' ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
$nodotdot = substr( $nodotdot, 0, -1 );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $text === '' ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
$text = $nodotdot . $suffix;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$nodotdot = trim( $nodotdot );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $nodotdot != '' ) {
|
2009-07-20 02:07:56 +00:00
|
|
|
$ret .= '/' . $nodotdot;
|
|
|
|
|
}
|
|
|
|
|
$ret .= $suffix;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-02-21 12:23:52 +00:00
|
|
|
/**
|
|
|
|
|
* Wrap a comment in standard punctuation and formatting if
|
|
|
|
|
* it's non-empty, otherwise return empty string.
|
2006-11-08 07:12:03 +00:00
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $comment String
|
|
|
|
|
* @param $title Mixed: Title object (to generate link to section in autocomment) or null
|
|
|
|
|
* @param $local Boolean: whether section links should refer to local page
|
2011-06-14 23:50:40 +00:00
|
|
|
*
|
2006-11-08 07:12:03 +00:00
|
|
|
* @return string
|
2005-02-21 12:23:52 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function commentBlock( $comment, $title = null, $local = false ) {
|
2005-12-08 20:19:33 +00:00
|
|
|
// '*' used to be the comment inserted by the software way back
|
|
|
|
|
// in antiquity in case none was provided, here for backwards
|
2013-03-13 07:42:41 +00:00
|
|
|
// compatibility, acc. to brion -ævar
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $comment == '' || $comment == '*' ) {
|
2005-02-21 12:23:52 +00:00
|
|
|
return '';
|
|
|
|
|
} else {
|
2011-04-03 11:44:11 +00:00
|
|
|
$formatted = self::formatComment( $comment, $title, $local );
|
2012-02-26 12:11:35 +00:00
|
|
|
$formatted = wfMessage( 'parentheses' )->rawParams( $formatted )->escaped();
|
2012-02-25 20:53:54 +00:00
|
|
|
return " <span class=\"comment\">$formatted</span>";
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-05-09 20:05:08 +00:00
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
|
|
|
|
* Wrap and format the given revision's comment block, if the current
|
|
|
|
|
* user is allowed to view it.
|
2006-11-17 03:59:32 +00:00
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $rev Revision object
|
|
|
|
|
* @param $local Boolean: whether section links should refer to local page
|
|
|
|
|
* @param $isPublic Boolean: show only if all users can see it
|
|
|
|
|
* @return String: HTML fragment
|
2006-03-16 19:04:25 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function revComment( Revision $rev, $local = false, $isPublic = false ) {
|
2011-03-02 10:57:55 +00:00
|
|
|
if ( $rev->getRawComment() == "" ) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $rev->isDeleted( Revision::DELETED_COMMENT ) && $isPublic ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
|
2011-06-17 16:03:52 +00:00
|
|
|
} elseif ( $rev->userCan( Revision::DELETED_COMMENT ) ) {
|
2011-06-14 23:50:40 +00:00
|
|
|
$block = self::commentBlock( $rev->getComment( Revision::FOR_THIS_USER ),
|
2008-09-24 09:44:45 +00:00
|
|
|
$rev->getTitle(), $local );
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
2012-08-19 20:44:29 +00:00
|
|
|
$block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
|
2006-03-16 19:04:25 +00:00
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
|
2006-06-12 05:33:48 +00:00
|
|
|
return " <span class=\"history-deleted\">$block</span>";
|
2005-02-21 12:23:52 +00:00
|
|
|
}
|
2006-03-16 19:04:25 +00:00
|
|
|
return $block;
|
2005-02-21 12:23:52 +00:00
|
|
|
}
|
2005-01-27 19:51:47 +00:00
|
|
|
|
2011-05-29 14:01:47 +00:00
|
|
|
/**
|
|
|
|
|
* @param $size
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function formatRevisionSize( $size ) {
|
2008-07-14 19:10:47 +00:00
|
|
|
if ( $size == 0 ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$stxt = wfMessage( 'historyempty' )->escaped();
|
2008-07-14 19:10:47 +00:00
|
|
|
} else {
|
2012-08-19 20:44:29 +00:00
|
|
|
$stxt = wfMessage( 'nbytes' )->numParams( $size )->escaped();
|
2012-02-26 12:11:35 +00:00
|
|
|
$stxt = wfMessage( 'parentheses' )->rawParams( $stxt )->escaped();
|
2008-07-14 19:10:47 +00:00
|
|
|
}
|
|
|
|
|
return "<span class=\"history-size\">$stxt</span>";
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-26 14:25:48 +00:00
|
|
|
/**
|
|
|
|
|
* Add another level to the Table of Contents
|
2011-05-29 14:01:47 +00:00
|
|
|
*
|
|
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function tocIndent() {
|
2005-01-15 23:21:52 +00:00
|
|
|
return "\n<ul>";
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-26 14:25:48 +00:00
|
|
|
/**
|
|
|
|
|
* Finish one or more sublevels on the Table of Contents
|
2011-05-29 14:01:47 +00:00
|
|
|
*
|
|
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function tocUnindent( $level ) {
|
2010-08-26 19:40:29 +00:00
|
|
|
return "</li>\n" . str_repeat( "</ul>\n</li>\n", $level > 0 ? $level : 0 );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* parameter level defines if we are on an indentation level
|
2011-05-29 14:01:47 +00:00
|
|
|
*
|
|
|
|
|
* @return string
|
2004-12-18 06:29:23 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function tocLine( $anchor, $tocline, $tocnumber, $level, $sectionIndex = false ) {
|
2009-06-20 21:47:10 +00:00
|
|
|
$classes = "toclevel-$level";
|
2011-05-29 14:01:47 +00:00
|
|
|
if ( $sectionIndex !== false ) {
|
2009-06-20 21:47:10 +00:00
|
|
|
$classes .= " tocsection-$sectionIndex";
|
2011-05-29 14:01:47 +00:00
|
|
|
}
|
2009-06-20 21:47:10 +00:00
|
|
|
return "\n<li class=\"$classes\"><a href=\"#" .
|
2005-02-21 01:56:50 +00:00
|
|
|
$anchor . '"><span class="tocnumber">' .
|
|
|
|
|
$tocnumber . '</span> <span class="toctext">' .
|
|
|
|
|
$tocline . '</span></a>';
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-26 14:25:48 +00:00
|
|
|
/**
|
|
|
|
|
* End a Table Of Contents line.
|
2010-01-07 09:32:09 +00:00
|
|
|
* tocUnindent() will be used instead if we're ending a line below
|
2009-10-26 14:25:48 +00:00
|
|
|
* the new level.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function tocLineEnd() {
|
2005-01-15 23:21:52 +00:00
|
|
|
return "</li>\n";
|
2010-11-05 19:06:12 +00:00
|
|
|
}
|
2005-01-15 23:21:52 +00:00
|
|
|
|
2010-01-07 09:32:09 +00:00
|
|
|
/**
|
2009-10-26 14:25:48 +00:00
|
|
|
* Wraps the TOC in a table and provides the hide/collapse javascript.
|
2010-05-20 20:36:12 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $toc html of the Table Of Contents
|
2012-08-22 19:49:39 +00:00
|
|
|
* @param $lang String|Language|false: Language for the toc title, defaults to user language
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: full html of the TOC
|
2009-10-26 14:25:48 +00:00
|
|
|
*/
|
2011-09-12 09:25:00 +00:00
|
|
|
public static function tocList( $toc, $lang = false ) {
|
2012-08-22 19:29:18 +00:00
|
|
|
$lang = wfGetLangObj( $lang );
|
|
|
|
|
$title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
|
|
|
|
|
|
2013-02-03 20:05:24 +00:00
|
|
|
return '<table id="toc" class="toc"><tr><td>'
|
|
|
|
|
. '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
|
|
|
|
|
. $toc
|
|
|
|
|
. "</ul>\n</td></tr></table>\n";
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2009-06-25 11:05:22 +00:00
|
|
|
/**
|
|
|
|
|
* Generate a table of contents from a section tree
|
2009-10-26 14:25:48 +00:00
|
|
|
* Currently unused.
|
2010-05-20 20:36:12 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $tree Return value of ParserOutput::getSections()
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML fragment
|
2009-06-25 11:05:22 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function generateTOC( $tree ) {
|
2009-06-25 11:05:22 +00:00
|
|
|
$toc = '';
|
|
|
|
|
$lastLevel = 0;
|
|
|
|
|
foreach ( $tree as $section ) {
|
|
|
|
|
if ( $section['toclevel'] > $lastLevel )
|
2011-04-03 11:44:11 +00:00
|
|
|
$toc .= self::tocIndent();
|
2011-06-17 16:03:52 +00:00
|
|
|
elseif ( $section['toclevel'] < $lastLevel )
|
2011-04-03 11:44:11 +00:00
|
|
|
$toc .= self::tocUnindent(
|
2009-06-25 11:05:22 +00:00
|
|
|
$lastLevel - $section['toclevel'] );
|
|
|
|
|
else
|
2011-04-03 11:44:11 +00:00
|
|
|
$toc .= self::tocLineEnd();
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
$toc .= self::tocLine( $section['anchor'],
|
2009-06-25 11:05:22 +00:00
|
|
|
$section['line'], $section['number'],
|
|
|
|
|
$section['toclevel'], $section['index'] );
|
|
|
|
|
$lastLevel = $section['toclevel'];
|
|
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
$toc .= self::tocLineEnd();
|
|
|
|
|
return self::tocList( $toc );
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2005-04-27 07:48:14 +00:00
|
|
|
|
2007-01-08 02:11:45 +00:00
|
|
|
/**
|
|
|
|
|
* Create a headline for content
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $level Integer: the level of the headline (1-6)
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $attribs any attributes for the headline, starting with
|
2010-05-20 20:36:12 +00:00
|
|
|
* a space and ending with '>'
|
|
|
|
|
* This *must* be at least '>' for no attribs
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $anchor the anchor to give the headline (the bit after the #)
|
|
|
|
|
* @param string $html html for the text of the header
|
|
|
|
|
* @param string $link HTML to add for the section edit link
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $legacyAnchor Mixed: a second, optional anchor to give for
|
2009-01-05 15:59:46 +00:00
|
|
|
* backward compatibility (false to omit)
|
2007-01-08 02:11:45 +00:00
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML headline
|
2007-01-08 02:11:45 +00:00
|
|
|
*/
|
2011-09-03 13:46:56 +00:00
|
|
|
public static function makeHeadline( $level, $attribs, $anchor, $html, $link, $legacyAnchor = false ) {
|
2011-07-27 19:24:43 +00:00
|
|
|
$ret = "<h$level$attribs"
|
|
|
|
|
. $link
|
2011-09-03 13:46:56 +00:00
|
|
|
. " <span class=\"mw-headline\" id=\"$anchor\">$html</span>"
|
2011-07-27 19:24:43 +00:00
|
|
|
. "</h$level>";
|
2009-01-05 15:59:46 +00:00
|
|
|
if ( $legacyAnchor !== false ) {
|
2010-08-17 21:55:21 +00:00
|
|
|
$ret = "<div id=\"$legacyAnchor\"></div>$ret";
|
2009-01-05 15:59:46 +00:00
|
|
|
}
|
|
|
|
|
return $ret;
|
2007-01-08 02:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-07 13:09:30 +00:00
|
|
|
/**
|
2005-04-27 07:48:14 +00:00
|
|
|
* Split a link trail, return the "inside" portion and the remainder of the trail
|
|
|
|
|
* as a two-element array
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return array
|
2005-04-27 07:48:14 +00:00
|
|
|
*/
|
2006-11-08 07:12:03 +00:00
|
|
|
static function splitTrail( $trail ) {
|
2011-04-06 21:11:49 +00:00
|
|
|
global $wgContLang;
|
|
|
|
|
$regex = $wgContLang->linkTrail();
|
2005-04-27 07:48:14 +00:00
|
|
|
$inside = '';
|
2010-05-28 14:16:46 +00:00
|
|
|
if ( $trail !== '' ) {
|
2006-11-23 08:25:56 +00:00
|
|
|
$m = array();
|
2005-04-27 07:48:14 +00:00
|
|
|
if ( preg_match( $regex, $trail, $m ) ) {
|
|
|
|
|
$inside = $m[1];
|
|
|
|
|
$trail = $m[2];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return array( $inside, $trail );
|
|
|
|
|
}
|
2006-11-08 07:12:03 +00:00
|
|
|
|
2006-11-16 22:53:01 +00:00
|
|
|
/**
|
|
|
|
|
* Generate a rollback link for a given revision. Currently it's the
|
|
|
|
|
* caller's responsibility to ensure that the revision is the top one. If
|
|
|
|
|
* it's not, of course, the user will get an error message.
|
|
|
|
|
*
|
|
|
|
|
* If the calling page is called with the parameter &bot=1, all rollback
|
|
|
|
|
* links also get that parameter. It causes the edit itself and the rollback
|
|
|
|
|
* to be marked as "bot" edits. Bot edits are hidden by default from recent
|
|
|
|
|
* changes, so this allows sysops to combat a busy vandal without bothering
|
|
|
|
|
* other users.
|
|
|
|
|
*
|
2012-11-01 20:04:12 +00:00
|
|
|
* If the option verify is set this function will return the link only in case the
|
|
|
|
|
* revision can be reverted. Please note that due to performance limitations
|
|
|
|
|
* it might be assumed that a user isn't the only contributor of a page while
|
|
|
|
|
* (s)he is, which will lead to useless rollback links. Furthermore this wont
|
|
|
|
|
* work if $wgShowRollbackEditCount is disabled, so this can only function
|
|
|
|
|
* as an additional check.
|
|
|
|
|
*
|
|
|
|
|
* If the option noBrackets is set the rollback link wont be enclosed in []
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $rev Revision object
|
2012-07-05 21:07:58 +00:00
|
|
|
* @param $context IContextSource context to use or null for the main context.
|
2012-11-01 20:04:12 +00:00
|
|
|
* @param $options array
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2006-11-16 22:53:01 +00:00
|
|
|
*/
|
2012-11-01 20:04:12 +00:00
|
|
|
public static function generateRollback( $rev, IContextSource $context = null, $options = array( 'verify' ) ) {
|
2012-07-05 21:07:58 +00:00
|
|
|
if ( $context === null ) {
|
|
|
|
|
$context = RequestContext::getMain();
|
|
|
|
|
}
|
2012-11-01 20:04:12 +00:00
|
|
|
$editCount = false;
|
|
|
|
|
if ( in_array( 'verify', $options ) ) {
|
|
|
|
|
$editCount = self::getRollbackEditCount( $rev, true );
|
|
|
|
|
if ( $editCount === false ) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$inner = self::buildRollbackLink( $rev, $context, $editCount );
|
|
|
|
|
|
|
|
|
|
if ( !in_array( 'noBrackets', $options ) ) {
|
|
|
|
|
$inner = $context->msg( 'brackets' )->rawParams( $inner )->plain();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return '<span class="mw-rollback-link">' . $inner . '</span>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This function will return the number of revisions which a rollback
|
|
|
|
|
* would revert and, if $verify is set it will verify that a revision
|
|
|
|
|
* can be reverted (that the user isn't the only contributor and the
|
|
|
|
|
* revision we might rollback to isn't deleted). These checks can only
|
|
|
|
|
* function as an additional check as this function only checks against
|
|
|
|
|
* the last $wgShowRollbackEditCount edits.
|
|
|
|
|
*
|
|
|
|
|
* Returns null if $wgShowRollbackEditCount is disabled or false if $verify
|
|
|
|
|
* is set and the user is the only contributor of the page.
|
|
|
|
|
*
|
|
|
|
|
* @param $rev Revision object
|
2013-03-13 07:42:41 +00:00
|
|
|
* @param bool $verify Try to verify that this revision can really be rolled back
|
2012-11-01 20:04:12 +00:00
|
|
|
* @return integer|bool|null
|
|
|
|
|
*/
|
|
|
|
|
public static function getRollbackEditCount( $rev, $verify ) {
|
|
|
|
|
global $wgShowRollbackEditCount;
|
|
|
|
|
if ( !is_int( $wgShowRollbackEditCount ) || !$wgShowRollbackEditCount > 0 ) {
|
|
|
|
|
// Nothing has happened, indicate this by returning 'null'
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
|
|
|
|
|
// Up to the value of $wgShowRollbackEditCount revisions are counted
|
|
|
|
|
$res = $dbr->select(
|
|
|
|
|
'revision',
|
|
|
|
|
array( 'rev_user_text', 'rev_deleted' ),
|
|
|
|
|
// $rev->getPage() returns null sometimes
|
|
|
|
|
array( 'rev_page' => $rev->getTitle()->getArticleID() ),
|
|
|
|
|
__METHOD__,
|
|
|
|
|
array(
|
|
|
|
|
'USE INDEX' => array( 'revision' => 'page_timestamp' ),
|
|
|
|
|
'ORDER BY' => 'rev_timestamp DESC',
|
|
|
|
|
'LIMIT' => $wgShowRollbackEditCount + 1
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$editCount = 0;
|
|
|
|
|
$moreRevs = false;
|
|
|
|
|
foreach ( $res as $row ) {
|
|
|
|
|
if ( $rev->getRawUserText() != $row->rev_user_text ) {
|
|
|
|
|
if ( $verify && ( $row->rev_deleted & Revision::DELETED_TEXT || $row->rev_deleted & Revision::DELETED_USER ) ) {
|
|
|
|
|
// If the user or the text of the revision we might rollback to is deleted in some way we can't rollback
|
|
|
|
|
// Similar to the sanity checks in WikiPage::commitRollback
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$moreRevs = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
$editCount++;
|
|
|
|
|
}
|
2012-07-05 21:07:58 +00:00
|
|
|
|
2012-11-01 20:04:12 +00:00
|
|
|
if ( $verify && $editCount <= $wgShowRollbackEditCount && !$moreRevs ) {
|
|
|
|
|
// We didn't find at least $wgShowRollbackEditCount revisions made by the current user
|
|
|
|
|
// and there weren't any other revisions. That means that the current user is the only
|
|
|
|
|
// editor, so we can't rollback
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return $editCount;
|
2007-07-07 00:17:51 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-07-07 00:17:51 +00:00
|
|
|
/**
|
|
|
|
|
* Build a raw rollback link, useful for collections of "tool" links
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $rev Revision object
|
2012-07-05 21:07:58 +00:00
|
|
|
* @param $context IContextSource context to use or null for the main context.
|
2012-11-01 20:04:12 +00:00
|
|
|
* @param $editCount integer Number of edits that would be reverted
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML fragment
|
2007-07-07 00:17:51 +00:00
|
|
|
*/
|
2012-11-01 20:04:12 +00:00
|
|
|
public static function buildRollbackLink( $rev, IContextSource $context = null, $editCount = false ) {
|
2012-08-01 16:52:30 +00:00
|
|
|
global $wgShowRollbackEditCount, $wgMiserMode;
|
2012-10-19 20:03:05 +00:00
|
|
|
|
2012-08-01 16:52:30 +00:00
|
|
|
// To config which pages are effected by miser mode
|
|
|
|
|
$disableRollbackEditCountSpecialPage = array( 'Recentchanges', 'Watchlist' );
|
2012-07-29 16:57:11 +00:00
|
|
|
|
2012-07-05 21:07:58 +00:00
|
|
|
if ( $context === null ) {
|
|
|
|
|
$context = RequestContext::getMain();
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-16 22:53:01 +00:00
|
|
|
$title = $rev->getTitle();
|
2008-08-01 00:54:08 +00:00
|
|
|
$query = array(
|
|
|
|
|
'action' => 'rollback',
|
2010-12-18 23:07:30 +00:00
|
|
|
'from' => $rev->getUserText(),
|
2012-07-05 21:07:58 +00:00
|
|
|
'token' => $context->getUser()->getEditToken( array( $title->getPrefixedText(), $rev->getUserText() ) ),
|
2008-08-01 00:54:08 +00:00
|
|
|
);
|
2012-07-05 21:07:58 +00:00
|
|
|
if ( $context->getRequest()->getBool( 'bot' ) ) {
|
2008-07-30 21:02:28 +00:00
|
|
|
$query['bot'] = '1';
|
2009-01-03 05:39:13 +00:00
|
|
|
$query['hidediff'] = '1'; // bug 15999
|
2008-07-30 21:02:28 +00:00
|
|
|
}
|
2012-07-29 16:57:11 +00:00
|
|
|
|
2012-08-01 16:52:30 +00:00
|
|
|
$disableRollbackEditCount = false;
|
|
|
|
|
if( $wgMiserMode ) {
|
|
|
|
|
foreach( $disableRollbackEditCountSpecialPage as $specialPage ) {
|
|
|
|
|
if( $context->getTitle()->isSpecial( $specialPage ) ) {
|
|
|
|
|
$disableRollbackEditCount = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !$disableRollbackEditCount && is_int( $wgShowRollbackEditCount ) && $wgShowRollbackEditCount > 0 ) {
|
2012-11-01 20:04:12 +00:00
|
|
|
if ( !is_numeric( $editCount ) ) {
|
|
|
|
|
$editCount = self::getRollbackEditCount( $rev, false );
|
2012-07-29 16:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( $editCount > $wgShowRollbackEditCount ) {
|
|
|
|
|
$editCount_output = $context->msg( 'rollbacklinkcount-morethan' )->numParams( $wgShowRollbackEditCount )->parse();
|
|
|
|
|
} else {
|
|
|
|
|
$editCount_output = $context->msg( 'rollbacklinkcount' )->numParams( $editCount )->parse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return self::link(
|
|
|
|
|
$title,
|
|
|
|
|
$editCount_output,
|
|
|
|
|
array( 'title' => $context->msg( 'tooltip-rollback' )->text() ),
|
|
|
|
|
$query,
|
|
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return self::link(
|
|
|
|
|
$title,
|
|
|
|
|
$context->msg( 'rollbacklink' )->escaped(),
|
|
|
|
|
array( 'title' => $context->msg( 'tooltip-rollback' )->text() ),
|
|
|
|
|
$query,
|
|
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
|
|
|
|
}
|
2006-11-16 22:53:01 +00:00
|
|
|
}
|
2006-11-17 03:42:23 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns HTML for the "templates used on this page" list.
|
|
|
|
|
*
|
2012-11-02 20:15:37 +00:00
|
|
|
* Make an HTML list of templates, and then add a "More..." link at
|
|
|
|
|
* the bottom. If $more is null, do not add a "More..." link. If $more
|
|
|
|
|
* is a Title, make a link to that title and use it. If $more is a string,
|
2013-01-15 20:35:41 +00:00
|
|
|
* directly paste it in as the link (escaping needs to be done manually).
|
|
|
|
|
* Finally, if $more is a Message, call toString().
|
2012-11-02 20:15:37 +00:00
|
|
|
*
|
2013-01-15 20:35:41 +00:00
|
|
|
* @param array $templates Array of templates from Article::getUsedTemplate or similar
|
2012-11-02 20:15:37 +00:00
|
|
|
* @param bool $preview Whether this is for a preview
|
|
|
|
|
* @param bool $section Whether this is for a section edit
|
2013-01-15 20:35:41 +00:00
|
|
|
* @param Title|Message|string|null $more An escaped link for "More..." of the templates
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML output
|
2006-11-17 03:42:23 +00:00
|
|
|
*/
|
2012-11-02 20:15:37 +00:00
|
|
|
public static function formatTemplates( $templates, $preview = false, $section = false, $more = null ) {
|
2006-11-17 03:42:23 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
|
|
|
|
|
$outText = '';
|
|
|
|
|
if ( count( $templates ) > 0 ) {
|
|
|
|
|
# Do a batch existence check
|
|
|
|
|
$batch = new LinkBatch;
|
2010-08-26 19:40:29 +00:00
|
|
|
foreach ( $templates as $title ) {
|
2006-11-17 03:42:23 +00:00
|
|
|
$batch->addObj( $title );
|
|
|
|
|
}
|
|
|
|
|
$batch->execute();
|
|
|
|
|
|
|
|
|
|
# Construct the HTML
|
2006-11-21 03:22:18 +00:00
|
|
|
$outText = '<div class="mw-templatesUsedExplanation">';
|
2006-12-31 01:35:26 +00:00
|
|
|
if ( $preview ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$outText .= wfMessage( 'templatesusedpreview' )->numParams( count( $templates ) )
|
|
|
|
|
->parseAsBlock();
|
2006-12-31 01:35:26 +00:00
|
|
|
} elseif ( $section ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$outText .= wfMessage( 'templatesusedsection' )->numParams( count( $templates ) )
|
|
|
|
|
->parseAsBlock();
|
2006-12-31 01:35:26 +00:00
|
|
|
} else {
|
2012-08-19 20:44:29 +00:00
|
|
|
$outText .= wfMessage( 'templatesused' )->numParams( count( $templates ) )
|
|
|
|
|
->parseAsBlock();
|
2006-12-31 01:35:26 +00:00
|
|
|
}
|
2008-12-28 16:46:05 +00:00
|
|
|
$outText .= "</div><ul>\n";
|
2006-12-31 01:35:26 +00:00
|
|
|
|
2012-07-08 09:40:50 +00:00
|
|
|
usort( $templates, 'Title::compare' );
|
2006-11-17 03:42:23 +00:00
|
|
|
foreach ( $templates as $titleObj ) {
|
2006-12-31 01:35:26 +00:00
|
|
|
$r = $titleObj->getRestrictions( 'edit' );
|
2008-04-14 07:45:50 +00:00
|
|
|
if ( in_array( 'sysop', $r ) ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$protected = wfMessage( 'template-protected' )->parse();
|
2006-12-31 01:35:26 +00:00
|
|
|
} elseif ( in_array( 'autoconfirmed', $r ) ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$protected = wfMessage( 'template-semiprotected' )->parse();
|
2006-12-31 01:35:26 +00:00
|
|
|
} else {
|
|
|
|
|
$protected = '';
|
|
|
|
|
}
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $titleObj->quickUserCan( 'edit' ) ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$editLink = self::link(
|
2009-06-06 15:45:43 +00:00
|
|
|
$titleObj,
|
2012-08-19 20:44:29 +00:00
|
|
|
wfMessage( 'editlink' )->text(),
|
2009-06-06 15:45:43 +00:00
|
|
|
array(),
|
|
|
|
|
array( 'action' => 'edit' )
|
|
|
|
|
);
|
2008-10-08 02:29:23 +00:00
|
|
|
} else {
|
2011-04-03 11:44:11 +00:00
|
|
|
$editLink = self::link(
|
2009-06-06 15:45:43 +00:00
|
|
|
$titleObj,
|
2012-08-19 20:44:29 +00:00
|
|
|
wfMessage( 'viewsourcelink' )->text(),
|
2009-06-06 15:45:43 +00:00
|
|
|
array(),
|
|
|
|
|
array( 'action' => 'edit' )
|
|
|
|
|
);
|
2008-10-08 02:29:23 +00:00
|
|
|
}
|
2012-10-23 11:50:05 +00:00
|
|
|
$outText .= '<li>' . self::link( $titleObj )
|
|
|
|
|
. wfMessage( 'word-separator' )->escaped()
|
|
|
|
|
. wfMessage( 'parentheses' )->rawParams( $editLink )->escaped()
|
|
|
|
|
. wfMessage( 'word-separator' )->escaped()
|
|
|
|
|
. $protected . '</li>';
|
2006-11-17 03:42:23 +00:00
|
|
|
}
|
2012-11-02 20:15:37 +00:00
|
|
|
|
|
|
|
|
if ( $more instanceof Title ) {
|
|
|
|
|
$outText .= '<li>' . self::link( $more, wfMessage( 'moredotdotdot' ) ) . '</li>';
|
|
|
|
|
} elseif ( $more ) {
|
|
|
|
|
$outText .= "<li>$more</li>";
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-17 03:42:23 +00:00
|
|
|
$outText .= '</ul>';
|
|
|
|
|
}
|
2013-01-06 18:23:10 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2006-11-17 03:42:23 +00:00
|
|
|
return $outText;
|
|
|
|
|
}
|
2008-02-25 13:38:21 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns HTML for the "hidden categories on this page" list.
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $hiddencats of hidden categories from Article::getHiddenCategories
|
2008-02-25 13:38:21 +00:00
|
|
|
* or similar
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: HTML output
|
2008-02-25 13:38:21 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function formatHiddenCategories( $hiddencats ) {
|
2008-02-25 13:38:21 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
|
|
|
|
|
$outText = '';
|
|
|
|
|
if ( count( $hiddencats ) > 0 ) {
|
|
|
|
|
# Construct the HTML
|
|
|
|
|
$outText = '<div class="mw-hiddenCategoriesExplanation">';
|
2012-08-19 20:44:29 +00:00
|
|
|
$outText .= wfMessage( 'hiddencategories' )->numParams( count( $hiddencats ) )->parseAsBlock();
|
2008-12-28 16:46:05 +00:00
|
|
|
$outText .= "</div><ul>\n";
|
2008-02-25 13:38:21 +00:00
|
|
|
|
|
|
|
|
foreach ( $hiddencats as $titleObj ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$outText .= '<li>' . self::link( $titleObj, null, array(), array(), 'known' ) . "</li>\n"; # If it's hidden, it must exist - no need to check with a LinkBatch
|
2008-02-25 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
$outText .= '</ul>';
|
|
|
|
|
}
|
2013-01-06 18:23:10 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2008-02-25 13:38:21 +00:00
|
|
|
return $outText;
|
|
|
|
|
}
|
2008-02-25 19:09:25 +00:00
|
|
|
|
2006-12-23 13:13:13 +00:00
|
|
|
/**
|
|
|
|
|
* Format a size in bytes for output, using an appropriate
|
|
|
|
|
* unit (B, KB, MB or GB) according to the magnitude in question
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param int $size Size to format
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String
|
2006-12-23 13:13:13 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function formatSize( $size ) {
|
2006-12-23 13:13:13 +00:00
|
|
|
global $wgLang;
|
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.
2007-08-15 10:50:09 +00:00
|
|
|
return htmlspecialchars( $wgLang->formatSize( $size ) );
|
2006-12-23 13:13:13 +00:00
|
|
|
}
|
2007-01-10 05:18:30 +00:00
|
|
|
|
2007-01-10 06:03:14 +00:00
|
|
|
/**
|
2007-01-11 00:57:30 +00:00
|
|
|
* Given the id of an interface element, constructs the appropriate title
|
|
|
|
|
* attribute from the system messages. (Note, this is usually the id but
|
|
|
|
|
* isn't always, because sometimes the accesskey needs to go on a different
|
|
|
|
|
* element than the id, for reverse-compatibility, etc.)
|
2007-01-10 06:03:14 +00:00
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $name id of the element, minus prefixes.
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $options Mixed: null or the string 'withaccess' to add an access-
|
2008-08-13 15:11:36 +00:00
|
|
|
* key hint
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: contents of the title attribute (which you must HTML-
|
2008-10-27 23:58:00 +00:00
|
|
|
* escape), or false for no title attribute
|
2007-01-10 06:03:14 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function titleAttrib( $name, $options = null ) {
|
2008-08-13 14:52:40 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2007-01-10 06:03:14 +00:00
|
|
|
|
2010-12-25 12:33:17 +00:00
|
|
|
$message = wfMessage( "tooltip-$name" );
|
|
|
|
|
|
|
|
|
|
if ( !$message->exists() ) {
|
2008-10-27 23:58:00 +00:00
|
|
|
$tooltip = false;
|
2010-08-05 16:22:42 +00:00
|
|
|
} else {
|
2010-12-25 12:33:17 +00:00
|
|
|
$tooltip = $message->text();
|
2010-08-05 16:22:42 +00:00
|
|
|
# Compatibility: formerly some tooltips had [alt-.] hardcoded
|
|
|
|
|
$tooltip = preg_replace( "/ ?\[alt-.\]$/", '', $tooltip );
|
|
|
|
|
# Message equal to '-' means suppress it.
|
2013-02-03 20:05:24 +00:00
|
|
|
if ( $tooltip == '-' ) {
|
2010-08-05 16:22:42 +00:00
|
|
|
$tooltip = false;
|
|
|
|
|
}
|
2008-08-13 15:11:36 +00:00
|
|
|
}
|
|
|
|
|
|
2008-10-27 23:58:00 +00:00
|
|
|
if ( $options == 'withaccess' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$accesskey = self::accesskey( $name );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $accesskey !== false ) {
|
2008-10-27 23:58:00 +00:00
|
|
|
if ( $tooltip === false || $tooltip === '' ) {
|
|
|
|
|
$tooltip = "[$accesskey]";
|
|
|
|
|
} else {
|
|
|
|
|
$tooltip .= " [$accesskey]";
|
|
|
|
|
}
|
2008-08-13 15:11:36 +00:00
|
|
|
}
|
2007-01-10 06:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-13 14:52:40 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2008-10-27 23:58:00 +00:00
|
|
|
return $tooltip;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
static $accesskeycache;
|
|
|
|
|
|
2008-10-27 23:58:00 +00:00
|
|
|
/**
|
|
|
|
|
* Given the id of an interface element, constructs the appropriate
|
|
|
|
|
* accesskey attribute from the system messages. (Note, this is usually
|
|
|
|
|
* the id but isn't always, because sometimes the accesskey needs to go on
|
|
|
|
|
* a different element than the id, for reverse-compatibility, etc.)
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $name id of the element, minus prefixes.
|
2010-05-20 20:36:12 +00:00
|
|
|
* @return String: contents of the accesskey attribute (which you must HTML-
|
2008-10-27 23:58:00 +00:00
|
|
|
* escape), or false for no accesskey attribute
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function accesskey( $name ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
if ( isset( self::$accesskeycache[$name] ) ) {
|
|
|
|
|
return self::$accesskeycache[$name];
|
2010-12-25 12:24:18 +00:00
|
|
|
}
|
2011-02-10 16:08:44 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-12-25 12:24:18 +00:00
|
|
|
|
|
|
|
|
$message = wfMessage( "accesskey-$name" );
|
|
|
|
|
|
|
|
|
|
if ( !$message->exists() ) {
|
2010-08-05 16:22:42 +00:00
|
|
|
$accesskey = false;
|
|
|
|
|
} else {
|
2010-12-25 12:24:18 +00:00
|
|
|
$accesskey = $message->plain();
|
2010-08-05 16:22:42 +00:00
|
|
|
if ( $accesskey === '' || $accesskey === '-' ) {
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: Per standard MW behavior, a value of '-' means to suppress the
|
2010-08-05 16:22:42 +00:00
|
|
|
# attribute, but this is broken for accesskey: that might be a useful
|
|
|
|
|
# value.
|
|
|
|
|
$accesskey = false;
|
|
|
|
|
}
|
2008-10-27 23:58:00 +00:00
|
|
|
}
|
2008-10-28 00:23:26 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::$accesskeycache[$name] = $accesskey;
|
2007-01-10 06:03:14 +00:00
|
|
|
}
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2011-08-03 22:37:20 +00:00
|
|
|
/**
|
|
|
|
|
* Get a revision-deletion link, or disabled link, or nothing, depending
|
|
|
|
|
* on user permissions & the settings on the revision.
|
|
|
|
|
*
|
|
|
|
|
* Will use forward-compatible revision ID in the Special:RevDelete link
|
|
|
|
|
* if possible, otherwise the timestamp-based ID which may break after
|
|
|
|
|
* undeletion.
|
|
|
|
|
*
|
|
|
|
|
* @param User $user
|
|
|
|
|
* @param Revision $rev
|
|
|
|
|
* @param Revision $title
|
|
|
|
|
* @return string HTML fragment
|
|
|
|
|
*/
|
|
|
|
|
public static function getRevDeleteLink( User $user, Revision $rev, Title $title ) {
|
|
|
|
|
$canHide = $user->isAllowed( 'deleterevision' );
|
2011-12-28 18:41:36 +00:00
|
|
|
if ( !$canHide && !( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) ) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
|
|
|
|
|
return Linker::revDeleteLinkDisabled( $canHide ); // revision was hidden from sysops
|
|
|
|
|
} else {
|
|
|
|
|
if ( $rev->getId() ) {
|
|
|
|
|
// RevDelete links using revision ID are stable across
|
|
|
|
|
// page deletion and undeletion; use when possible.
|
|
|
|
|
$query = array(
|
2013-02-03 20:05:24 +00:00
|
|
|
'type' => 'revision',
|
2011-12-28 18:41:36 +00:00
|
|
|
'target' => $title->getPrefixedDBkey(),
|
2013-02-03 20:05:24 +00:00
|
|
|
'ids' => $rev->getId()
|
2011-12-28 18:41:36 +00:00
|
|
|
);
|
2011-08-03 22:37:20 +00:00
|
|
|
} else {
|
2011-12-28 18:41:36 +00:00
|
|
|
// Older deleted entries didn't save a revision ID.
|
|
|
|
|
// We have to refer to these by timestamp, ick!
|
|
|
|
|
$query = array(
|
2013-02-03 20:05:24 +00:00
|
|
|
'type' => 'archive',
|
2011-12-28 18:41:36 +00:00
|
|
|
'target' => $title->getPrefixedDBkey(),
|
2013-02-03 20:05:24 +00:00
|
|
|
'ids' => $rev->getTimestamp()
|
2011-12-28 18:41:36 +00:00
|
|
|
);
|
2011-08-03 22:37:20 +00:00
|
|
|
}
|
2011-12-28 18:41:36 +00:00
|
|
|
return Linker::revDeleteLink( $query,
|
|
|
|
|
$rev->isDeleted( Revision::DELETED_RESTRICTED ), $canHide );
|
2011-08-03 22:37:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-18 21:07:09 +00:00
|
|
|
/**
|
|
|
|
|
* Creates a (show/hide) link for deleting revisions/log entries
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param array $query query parameters to be passed to link()
|
2012-07-10 14:58:52 +00:00
|
|
|
* @param $restricted Boolean: set to true to use a "<strong>" instead of a "<span>"
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $delete Boolean: set to true to use (show/hide) rather than (show)
|
2009-01-18 21:07:09 +00:00
|
|
|
*
|
2012-07-10 14:58:52 +00:00
|
|
|
* @return String: HTML "<a>" link to Special:Revisiondelete, wrapped in a
|
2009-01-18 21:07:09 +00:00
|
|
|
* span to allow for customization of appearance with CSS
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function revDeleteLink( $query = array(), $restricted = false, $delete = true ) {
|
2009-01-18 21:07:09 +00:00
|
|
|
$sp = SpecialPage::getTitleFor( 'Revisiondelete' );
|
2012-08-19 20:44:29 +00:00
|
|
|
$msgKey = $delete ? 'rev-delundel' : 'rev-showdeleted';
|
|
|
|
|
$html = wfMessage( $msgKey )->escaped();
|
2009-02-22 14:35:29 +00:00
|
|
|
$tag = $restricted ? 'strong' : 'span';
|
2011-09-03 13:46:56 +00:00
|
|
|
$link = self::link( $sp, $html, array(), $query, array( 'known', 'noclasses' ) );
|
2012-02-26 12:11:35 +00:00
|
|
|
return Xml::tags( $tag, array( 'class' => 'mw-revdelundel-link' ), wfMessage( 'parentheses' )->rawParams( $link )->escaped() );
|
2009-01-18 21:07:09 +00:00
|
|
|
}
|
2010-01-07 09:32:09 +00:00
|
|
|
|
2009-10-30 02:14:22 +00:00
|
|
|
/**
|
|
|
|
|
* Creates a dead (show/hide) link for deleting revisions/log entries
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $delete Boolean: set to true to use (show/hide) rather than (show)
|
2009-10-30 02:14:22 +00:00
|
|
|
*
|
|
|
|
|
* @return string HTML text wrapped in a span to allow for customization
|
|
|
|
|
* of appearance with CSS
|
|
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function revDeleteLinkDisabled( $delete = true ) {
|
2012-08-19 20:44:29 +00:00
|
|
|
$msgKey = $delete ? 'rev-delundel' : 'rev-showdeleted';
|
|
|
|
|
$html = wfMessage( $msgKey )->escaped();
|
|
|
|
|
$htmlParentheses = wfMessage( 'parentheses' )->rawParams( $html )->escaped();
|
|
|
|
|
return Xml::tags( 'span', array( 'class' => 'mw-revdelundel-link' ), $htmlParentheses );
|
2009-10-30 02:14:22 +00:00
|
|
|
}
|
2009-06-08 22:33:37 +00:00
|
|
|
|
|
|
|
|
/* Deprecated methods */
|
|
|
|
|
|
|
|
|
|
/**
|
2011-03-12 18:14:33 +00:00
|
|
|
* @deprecated since 1.16 Use link()
|
2009-06-08 22:33:37 +00:00
|
|
|
*
|
|
|
|
|
* This function is a shortcut to makeBrokenLinkObj(Title::newFromText($title),...). Do not call
|
|
|
|
|
* it if you already have a title object handy. See makeBrokenLinkObj for further documentation.
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $title The text of the title
|
|
|
|
|
* @param string $text Link text
|
|
|
|
|
* @param string $query Optional query part
|
|
|
|
|
* @param string $trail Optional trail. Alphabetic characters at the start of this string will
|
2010-05-20 20:36:12 +00:00
|
|
|
* be included in the link text. Other characters will be appended after
|
|
|
|
|
* the end of the link.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-06-08 22:33:37 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
|
2011-12-13 05:19:05 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.16' );
|
2012-10-19 20:03:05 +00:00
|
|
|
|
2009-06-08 22:33:37 +00:00
|
|
|
$nt = Title::newFromText( $title );
|
|
|
|
|
if ( $nt instanceof Title ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::makeBrokenLinkObj( $nt, $text, $query, $trail );
|
2009-06-08 22:33:37 +00:00
|
|
|
} else {
|
2011-04-03 11:44:11 +00:00
|
|
|
wfDebug( 'Invalid title passed to self::makeBrokenLink(): "' . $title . "\"\n" );
|
2009-06-08 22:33:37 +00:00
|
|
|
return $text == '' ? $title : $text;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2012-10-05 18:20:19 +00:00
|
|
|
* @deprecated since 1.16 Use link(); warnings since 1.21
|
2009-06-08 22:33:37 +00:00
|
|
|
*
|
|
|
|
|
* Make a link for a title which may or may not be in the database. If you need to
|
|
|
|
|
* call this lots of times, pre-fill the link cache with a LinkBatch, otherwise each
|
|
|
|
|
* call to this will result in a DB query.
|
|
|
|
|
*
|
|
|
|
|
* @param $nt Title: the title object to make the link from, e.g. from
|
|
|
|
|
* Title::newFromText.
|
|
|
|
|
* @param $text String: link text
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $query optional query part
|
|
|
|
|
* @param string $trail optional trail. Alphabetic characters at the start of this string will
|
2009-06-08 22:33:37 +00:00
|
|
|
* be included in the link text. Other characters will be appended after
|
|
|
|
|
* the end of the link.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $prefix optional prefix. As trail, only before instead of after.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-06-08 22:33:37 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function makeLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
|
2012-10-05 18:20:19 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.21' );
|
2012-10-19 20:03:05 +00:00
|
|
|
|
2009-06-08 22:33:37 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
$query = wfCgiToArray( $query );
|
2011-04-03 11:44:11 +00:00
|
|
|
list( $inside, $trail ) = self::splitTrail( $trail );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $text === '' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$text = self::linkText( $nt );
|
2009-06-08 22:33:37 +00:00
|
|
|
}
|
|
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
$ret = self::link( $nt, "$prefix$text$inside", array(), $query ) . $trail;
|
2009-06-08 22:33:37 +00:00
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2012-10-05 18:20:19 +00:00
|
|
|
* @deprecated since 1.16 Use link(); warnings since 1.21
|
2009-06-08 22:33:37 +00:00
|
|
|
*
|
|
|
|
|
* Make a link for a title which definitely exists. This is faster than makeLinkObj because
|
|
|
|
|
* it doesn't have to do a database query. It's also valid for interwiki titles and special
|
|
|
|
|
* pages.
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $title Title object of target page
|
2009-06-08 22:33:37 +00:00
|
|
|
* @param $text String: text to replace the title
|
|
|
|
|
* @param $query String: link target
|
|
|
|
|
* @param $trail String: text after link
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $prefix text before link text
|
|
|
|
|
* @param string $aprops extra attributes to the a-element
|
2009-06-08 22:33:37 +00:00
|
|
|
* @param $style String: style to apply - if empty, use getInternalLinkAttributesObj instead
|
2012-02-09 19:29:36 +00:00
|
|
|
* @return string the a-element
|
2009-06-08 22:33:37 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function makeKnownLinkObj(
|
2013-02-03 20:05:24 +00:00
|
|
|
$title, $text = '', $query = '', $trail = '', $prefix = '', $aprops = '', $style = ''
|
2011-03-21 16:15:56 +00:00
|
|
|
) {
|
2012-10-05 18:20:19 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.21' );
|
2012-10-19 20:03:05 +00:00
|
|
|
|
2009-06-08 22:33:37 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
|
|
|
|
|
if ( $text == '' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$text = self::linkText( $title );
|
2009-06-08 22:33:37 +00:00
|
|
|
}
|
|
|
|
|
$attribs = Sanitizer::mergeAttributes(
|
|
|
|
|
Sanitizer::decodeTagAttributes( $aprops ),
|
|
|
|
|
Sanitizer::decodeTagAttributes( $style )
|
|
|
|
|
);
|
|
|
|
|
$query = wfCgiToArray( $query );
|
2011-04-03 11:44:11 +00:00
|
|
|
list( $inside, $trail ) = self::splitTrail( $trail );
|
2009-06-08 22:33:37 +00:00
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
$ret = self::link( $title, "$prefix$text$inside", $attribs, $query,
|
2009-06-08 22:33:37 +00:00
|
|
|
array( 'known', 'noclasses' ) ) . $trail;
|
|
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2011-03-12 18:14:33 +00:00
|
|
|
* @deprecated since 1.16 Use link()
|
2009-06-08 22:33:37 +00:00
|
|
|
*
|
|
|
|
|
* Make a red link to the edit page of a given title.
|
|
|
|
|
*
|
2010-05-20 20:36:12 +00:00
|
|
|
* @param $title Title object of the target page
|
2009-06-08 22:33:37 +00:00
|
|
|
* @param $text String: Link text
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $query Optional query part
|
|
|
|
|
* @param string $trail Optional trail. Alphabetic characters at the start of this string will
|
2009-06-08 22:33:37 +00:00
|
|
|
* be included in the link text. Other characters will be appended after
|
|
|
|
|
* the end of the link.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $prefix Optional prefix
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-06-08 22:33:37 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function makeBrokenLinkObj( $title, $text = '', $query = '', $trail = '', $prefix = '' ) {
|
2011-12-13 05:19:05 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.16' );
|
2012-10-19 20:03:05 +00:00
|
|
|
|
2009-06-08 22:33:37 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
list( $inside, $trail ) = self::splitTrail( $trail );
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $text === '' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$text = self::linkText( $title );
|
2009-06-08 22:33:37 +00:00
|
|
|
}
|
|
|
|
|
|
2011-04-03 11:44:11 +00:00
|
|
|
$ret = self::link( $title, "$prefix$text$inside", array(),
|
2009-06-08 22:33:37 +00:00
|
|
|
wfCgiToArray( $query ), 'broken' ) . $trail;
|
|
|
|
|
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2011-03-12 18:14:33 +00:00
|
|
|
* @deprecated since 1.16 Use link()
|
2009-06-08 22:33:37 +00:00
|
|
|
*
|
|
|
|
|
* Make a coloured link.
|
|
|
|
|
*
|
|
|
|
|
* @param $nt Title object of the target page
|
|
|
|
|
* @param $colour Integer: colour of the link
|
|
|
|
|
* @param $text String: link text
|
|
|
|
|
* @param $query String: optional query part
|
|
|
|
|
* @param $trail String: optional trail. Alphabetic characters at the start of this string will
|
|
|
|
|
* be included in the link text. Other characters will be appended after
|
|
|
|
|
* the end of the link.
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $prefix Optional prefix
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return string
|
2009-06-08 22:33:37 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
static function makeColouredLinkObj( $nt, $colour, $text = '', $query = '', $trail = '', $prefix = '' ) {
|
2011-12-13 05:19:05 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.16' );
|
2012-10-19 20:03:05 +00:00
|
|
|
|
2010-08-26 19:40:29 +00:00
|
|
|
if ( $colour != '' ) {
|
2011-04-03 11:44:11 +00:00
|
|
|
$style = self::getInternalLinkAttributesObj( $nt, $text, $colour );
|
2011-03-02 10:57:55 +00:00
|
|
|
} else {
|
|
|
|
|
$style = '';
|
|
|
|
|
}
|
2011-04-03 11:44:11 +00:00
|
|
|
return self::makeKnownLinkObj( $nt, $text, $query, $trail, $prefix, '', $style );
|
2009-06-08 22:33:37 +00:00
|
|
|
}
|
2009-06-13 13:41:48 +00:00
|
|
|
|
2009-06-08 22:33:37 +00:00
|
|
|
/**
|
2010-08-05 16:22:42 +00:00
|
|
|
* Returns the attributes for the tooltip and access key.
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return array
|
2009-06-08 22:33:37 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function tooltipAndAccesskeyAttribs( $name ) {
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: If Sanitizer::expandAttributes() treated "false" as "output
|
2009-06-08 22:33:37 +00:00
|
|
|
# no attribute" instead of "output '' as value for attribute", this
|
|
|
|
|
# would be three lines.
|
|
|
|
|
$attribs = array(
|
2011-04-03 11:44:11 +00:00
|
|
|
'title' => self::titleAttrib( $name, 'withaccess' ),
|
|
|
|
|
'accesskey' => self::accesskey( $name )
|
2009-06-08 22:33:37 +00:00
|
|
|
);
|
|
|
|
|
if ( $attribs['title'] === false ) {
|
|
|
|
|
unset( $attribs['title'] );
|
|
|
|
|
}
|
|
|
|
|
if ( $attribs['accesskey'] === false ) {
|
|
|
|
|
unset( $attribs['accesskey'] );
|
|
|
|
|
}
|
2009-10-18 19:29:35 +00:00
|
|
|
return $attribs;
|
|
|
|
|
}
|
2011-01-06 18:53:53 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns raw bits of HTML, use titleAttrib()
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return null|string
|
2011-01-06 18:53:53 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
public static function tooltip( $name, $options = null ) {
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: If Sanitizer::expandAttributes() treated "false" as "output
|
2009-06-08 22:33:37 +00:00
|
|
|
# no attribute" instead of "output '' as value for attribute", this
|
|
|
|
|
# would be two lines.
|
2011-04-03 11:44:11 +00:00
|
|
|
$tooltip = self::titleAttrib( $name, $options );
|
2009-06-08 22:33:37 +00:00
|
|
|
if ( $tooltip === false ) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
return Xml::expandAttributes( array(
|
2011-05-06 23:07:20 +00:00
|
|
|
'title' => $tooltip
|
2009-06-08 22:33:37 +00:00
|
|
|
) );
|
|
|
|
|
}
|
2004-12-18 06:29:23 +00:00
|
|
|
}
|
2011-04-03 12:04:04 +00:00
|
|
|
|
2011-06-02 14:38:14 +00:00
|
|
|
/**
|
2011-07-18 23:01:08 +00:00
|
|
|
* @since 1.18
|
2011-06-02 14:38:14 +00:00
|
|
|
*/
|
2011-04-03 12:04:04 +00:00
|
|
|
class DummyLinker {
|
2011-05-25 15:39:47 +00:00
|
|
|
|
2011-04-03 12:04:04 +00:00
|
|
|
/**
|
|
|
|
|
* Use PHP's magic __call handler to transform instance calls to a dummy instance
|
|
|
|
|
* into static calls to the new Linker for backwards compatibility.
|
|
|
|
|
*
|
2013-03-11 17:15:01 +00:00
|
|
|
* @param string $fname Name of called method
|
|
|
|
|
* @param array $args Arguments to the method
|
2012-02-09 21:35:05 +00:00
|
|
|
* @return mixed
|
2011-04-03 12:04:04 +00:00
|
|
|
*/
|
2011-06-30 18:38:32 +00:00
|
|
|
public function __call( $fname, $args ) {
|
2011-04-03 12:04:04 +00:00
|
|
|
return call_user_func_array( array( 'Linker', $fname ), $args );
|
|
|
|
|
}
|
|
|
|
|
}
|