From fbc65f8972fc08a410acd13cb7e3d39059cadcaf Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Fri, 19 Aug 2011 11:23:17 +0000 Subject: [PATCH] Per CR on r44412 and my promise in the commit summary of r94990, stop abusing $wgInternalServer (intended for Squid URLs) for IRC/e-mail URLs and introduce $wgCanonicalServer for these purposes instead. This revision introduces two new hooks for WMF hacks, in exchange for making the core code saner. * Introduce $wgCanonicalServer, which should typically be a fully qualified version of $wgServer but in practice can be anything that you'd like to be used in IRC/e-mail notifs ** Default value is $wgServer, expanded to http:// if protocol-relative ** This means you can easily set HTTPS as the 'default' protocol to use in IRC and e-mail notifs by setting $wgCanonicalServer to https://example.com * Introduce Title::getCanonicalURL(). Similar to getInternalURL(), including a hook for WMF usage (which will be needed as long as secure.wikimedia.org is used) ** Also add escapeCanonicalURL(). Due to some ridiculous accident of history, the other escapeFooURL() functions don't have a $variant parameter; I decided not to follow that bad example * Reinstate the spirit of r44406 and r44412: instead of calling getInternalURL() (or getCanonicalURL()) and regexing the title parameter out, obtain the path to index.php using $wgCanonicalServer . $wgScript and append params to that. Sadly, we need to add a hook here to support the secure server hack for WMF, but that's the price of saner code in this case * Introduce the {{canonicalurl:}} and {{canonicalurle:}} parser functions, which work just like {{fullurl:}} and {{fullurle:}} except that they use getCanonicalURL() instead of getFullURL() * Use {{canonicalurl:}} in the enotif_body message, fixing bug 29993 (protocol-relative URLs appear in e-mail notifications) --- includes/DefaultSettings.php | 17 +++++++++++++++-- includes/RecentChange.php | 18 +++++++++--------- includes/Setup.php | 5 +++++ includes/Title.php | 23 +++++++++++++++++++++++ includes/parser/CoreParserFunctions.php | 4 ++++ languages/messages/MessagesEn.php | 8 +++++--- 6 files changed, 61 insertions(+), 14 deletions(-) diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index b5d6701023..4ca6b43835 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -39,19 +39,31 @@ $wgVersion = '1.19alpha'; $wgSitename = 'MediaWiki'; /** - * URL of the server. It will be automatically built including https mode. + * URL of the server. * * Example: * - * $wgServer = http://example.com + * $wgServer = 'http://example.com'; * * * This is usually detected correctly by MediaWiki. If MediaWiki detects the * wrong server, it will redirect incorrectly after you save a page. In that * case, set this variable to fix it. + * + * If you want to use protocol-relative URLs on your wiki, set this to a + * protocol-relative URL like '//example.com' and set $wgCanonicalServer + * to a fully qualified URL. */ $wgServer = WebRequest::detectServer(); +/** + * Canonical URL of the server, to use in IRC feeds and notification e-mails. + * Must be fully qualified, even if $wgServer is protocol-relative. + * + * Defaults to $wgServer, expanded to a fully qualified http:// URL if needed. + */ +$wgCanonicalServer = false; + /************************************************************************//** * @name Script path settings * @{ @@ -120,6 +132,7 @@ $wgRedirectScript = false; */ $wgLoadScript = false; + /**@}*/ /************************************************************************//** diff --git a/includes/RecentChange.php b/includes/RecentChange.php index b01368c7c2..a3a42e656e 100644 --- a/includes/RecentChange.php +++ b/includes/RecentChange.php @@ -682,7 +682,8 @@ class RecentChange { } public function getIRCLine() { - global $wgUseRCPatrol, $wgUseNPPatrol, $wgRC2UDPInterwikiPrefix, $wgLocalInterwiki; + global $wgUseRCPatrol, $wgUseNPPatrol, $wgRC2UDPInterwikiPrefix, $wgLocalInterwiki, + $wgCanonicalServer, $wgScript; if( $this->mAttribs['rc_type'] == RC_LOG ) { $titleObj = Title::newFromText( 'Log/' . $this->mAttribs['rc_log_type'], NS_SPECIAL ); @@ -695,19 +696,18 @@ class RecentChange { if( $this->mAttribs['rc_type'] == RC_LOG ) { $url = ''; } else { + $url = $wgCanonicalServer . $wgScript; if( $this->mAttribs['rc_type'] == RC_NEW ) { - $url = 'oldid=' . $this->mAttribs['rc_this_oldid']; + $query = '?oldid=' . $this->mAttribs['rc_this_oldid']; } else { - $url = 'diff=' . $this->mAttribs['rc_this_oldid'] . '&oldid=' . $this->mAttribs['rc_last_oldid']; + $query = '?diff=' . $this->mAttribs['rc_this_oldid'] . '&oldid=' . $this->mAttribs['rc_last_oldid']; } if ( $wgUseRCPatrol || ( $this->mAttribs['rc_type'] == RC_NEW && $wgUseNPPatrol ) ) { - $url .= '&rcid=' . $this->mAttribs['rc_id']; + $query .= '&rcid=' . $this->mAttribs['rc_id']; } - // XXX: *HACK* this should use getFullURL(), hacked for SSL madness --brion 2005-12-26 - // XXX: *HACK^2* the preg_replace() undoes much of what getInternalURL() does, but we - // XXX: need to call it so that URL paths on the Wikimedia secure server can be fixed - // XXX: by a custom GetInternalURL hook --vyznev 2008-12-10 - $url = preg_replace( '/title=[^&]*&/', '', $titleObj->getInternalURL( $url ) ); + // HACK: We need this hook for WMF's secure server setup + wfRunHooks( 'IRCLineURL', array( &$url, &$query ) ); + $url .= $query; } if( isset( $this->mExtra['oldSize'] ) && isset( $this->mExtra['newSize'] ) ) { diff --git a/includes/Setup.php b/includes/Setup.php index 82bf4424ca..fa7cf170f3 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -343,6 +343,11 @@ if ( !defined( 'MW_COMPILED' ) ) { wfProfileOut( $fname . '-includes' ); } +# Now that GlobalFunctions is loaded, set the default for $wgCanonicalServer +if ( $wgCanonicalServer === false ) { + $wgCanonicalServer = wfExpandUrl( $wgServer, PROTO_HTTP ); +} + wfProfileIn( $fname . '-misc1' ); # Raise the memory limit if it's too low diff --git a/includes/Title.php b/includes/Title.php index fab3b5bea9..4f61897f0a 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -987,6 +987,13 @@ class Title { public function escapeFullURL( $query = '' ) { return htmlspecialchars( $this->getFullURL( $query ) ); } + + /** + * HTML-escaped version of getCanonicalURL() + */ + public function escapeCanonicalURL( $query = '', $variant = false ) { + return htmlspecialchars( $this->getCanonicalURL( $query, $variant ) ); + } /** * Get the URL form for an internal link. @@ -1009,6 +1016,22 @@ class Title { return $url; } + /** + * Get the URL for a canonical link, for use in things like IRC and + * e-mail notifications. Uses $wgCanonicalServer and the + * GetCanonicalURL hook. + * + * @param $query string An optional query string + * @param $variant string Language variant of URL (for sr, zh, ...) + * @return string The URL + */ + public function getCanonicalURL( $query = '', $variant = false ) { + global $wgCanonicalServer; + $url = $wgCanonicalServer . $this->getLocalURL( $query, $variant ); + wfRunHooks( 'GetCanonicalURL', array( &$this, &$url, $query ) ); + return $url; + } + /** * Get the edit URL for this Title * diff --git a/includes/parser/CoreParserFunctions.php b/includes/parser/CoreParserFunctions.php index eda577dc47..750587601a 100644 --- a/includes/parser/CoreParserFunctions.php +++ b/includes/parser/CoreParserFunctions.php @@ -35,6 +35,8 @@ class CoreParserFunctions { $parser->setFunctionHook( 'localurle', array( __CLASS__, 'localurle' ), SFH_NO_HASH ); $parser->setFunctionHook( 'fullurl', array( __CLASS__, 'fullurl' ), SFH_NO_HASH ); $parser->setFunctionHook( 'fullurle', array( __CLASS__, 'fullurle' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'canonicalurl', array( __CLASS__, 'canonicalurl' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'canonicalurle', array( __CLASS__, 'canonicalurle' ), SFH_NO_HASH ); $parser->setFunctionHook( 'formatnum', array( __CLASS__, 'formatnum' ), SFH_NO_HASH ); $parser->setFunctionHook( 'grammar', array( __CLASS__, 'grammar' ), SFH_NO_HASH ); $parser->setFunctionHook( 'gender', array( __CLASS__, 'gender' ), SFH_NO_HASH ); @@ -218,6 +220,8 @@ class CoreParserFunctions { static function localurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeLocalURL', $s, $arg ); } static function fullurl( $parser, $s = '', $arg = null ) { return self::urlFunction( 'getFullURL', $s, $arg ); } static function fullurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeFullURL', $s, $arg ); } + static function canonicalurl( $parser, $s = '', $arg = null ) { return self::urlFunction( 'getCanonicalURL', $s, $arg ); } + static function canonicalurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeCanonicalURL', $s, $arg ); } static function urlFunction( $func, $s = '', $arg = null ) { $title = Title::newFromText( $s ); diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index f976ed3e94..9880f3e361 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -310,6 +310,8 @@ $magicWords = array( 'plural' => array( 0, 'PLURAL:' ), 'fullurl' => array( 0, 'FULLURL:' ), 'fullurle' => array( 0, 'FULLURLE:' ), + 'canonicalurl' => array( 0, 'CANONICALURL:' ), + 'canonicalurle' => array( 0, 'CANONICALURLE:' ), 'lcfirst' => array( 0, 'LCFIRST:' ), 'ucfirst' => array( 0, 'UCFIRST:' ), 'lc' => array( 0, 'LC:' ), @@ -2772,16 +2774,16 @@ You could also reset the notification flags for all your watched pages on your w -- To change your email notification settings, visit -{{fullurl:{{#special:Preferences}}}} +{{canonicalurl:{{#special:Preferences}}}} To change your watchlist settings, visit -{{fullurl:{{#special:EditWatchlist}}}} +{{canonicalurl:{{#special:EditWatchlist}}}} To delete the page from your watchlist, visit $UNWATCHURL Feedback and further assistance: -{{fullurl:{{MediaWiki:Helppage}}}}', +{{canonicalurl:{{MediaWiki:Helppage}}}}', # Delete 'deletepage' => 'Delete page', -- 2.20.1