Extend wfParseUrl() to handle protocol-relative URLs. parse_url() doesn't handle...
authorRoan Kattouw <catrope@users.mediawiki.org>
Tue, 12 Jul 2011 23:52:43 +0000 (23:52 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Tue, 12 Jul 2011 23:52:43 +0000 (23:52 +0000)
includes/GlobalFunctions.php

index 63b621f..12b1309 100644 (file)
@@ -478,14 +478,21 @@ function wfUrlProtocols() {
  * parse_url() work-alike, but non-broken.  Differences:
  *
  * 1) Does not raise warnings on bad URLs (just returns false)
- * 2) Handles protocols that don't use :// (e.g., mailto: and news:) correctly
- * 3) Adds a "delimiter" element to the array, either '://' or ':' (see (2))
+ * 2) Handles protocols that don't use :// (e.g., mailto: and news: , as well as protocol-relative URLs) correctly
+ * 3) Adds a "delimiter" element to the array, either '://', ':' or '//' (see (2))
  *
  * @param $url String: a URL to parse
  * @return Array: bits of the URL in an associative array, per PHP docs
  */
 function wfParseUrl( $url ) {
        global $wgUrlProtocols; // Allow all protocols defined in DefaultSettings/LocalSettings.php
+       
+       // Protocol-relative URLs are handled really badly by parse_url(). It's so bad that the easiest
+       // way to handle them is to just prepend 'http:' and strip the protocol out later
+       $wasRelative = substr( $url, 0, 2 ) == '//';
+       if ( $wasRelative ) {
+               $url = "http:$url";
+       }
        wfSuppressWarnings();
        $bits = parse_url( $url );
        wfRestoreWarnings();
@@ -517,6 +524,12 @@ function wfParseUrl( $url ) {
                        $bits['path'] = '/' . $bits['path'];
                }
        }
+       
+       // If the URL was protocol-relative, fix scheme and delimiter
+       if ( $wasRelative ) {
+               $bits['scheme'] = '';
+               $bits['delimiter'] = '//';
+       }
        return $bits;
 }