Index: trunk/phase3/index.php |
— | — | @@ -108,6 +108,22 @@ |
109 | 109 | case "print": |
110 | 110 | $wgArticle->view(); |
111 | 111 | break; |
| 112 | + case "dublincore": |
| 113 | + if (!$wgEnableDublinCoreRdf) { |
| 114 | + wfHttpError(403, "Forbidden", wfMsg("nodublincore")); |
| 115 | + } else { |
| 116 | + include_once("Metadata.php"); |
| 117 | + wfDublinCoreRdf($wgArticle); |
| 118 | + } |
| 119 | + break; |
| 120 | + case "creativecommons": |
| 121 | + if (!$wgEnableCreativeCommonsRdf) { |
| 122 | + wfHttpError(403, "Forbidden", wfMsg("nocreativecommons")); |
| 123 | + } else { |
| 124 | + include_once("Metadata.php"); |
| 125 | + wfCreativeCommonsRdf($wgArticle); |
| 126 | + } |
| 127 | + break; |
112 | 128 | case "edit": |
113 | 129 | case "submit": |
114 | 130 | if( !$wgCommandLineMode && !$wgRequest->checkSessionCookie() ) { |
Index: trunk/phase3/includes/GlobalFunctions.php |
— | — | @@ -845,4 +845,101 @@ |
846 | 846 | } |
847 | 847 | } |
848 | 848 | |
| 849 | +/* Provide a simple HTTP error. */ |
| 850 | + |
| 851 | +function wfHttpError($code, $label, $desc) { |
| 852 | + |
| 853 | + global $wgOut; |
| 854 | + $wgOut->disable(); |
| 855 | + header("HTTP/1.0 $code $label"); |
| 856 | + header("Status: $code $label"); |
| 857 | + $wgOut->sendCacheControl(); |
| 858 | + |
| 859 | + /* Don't send content if it's a HEAD request. */ |
| 860 | + |
| 861 | + if (strcmp($HTTP_SERVER_VARS['REQUEST_METHOD'],'HEAD') != 0) { |
| 862 | + header("Content-type: text/plain"); |
| 863 | + print "$desc\n"; |
| 864 | + } |
| 865 | +} |
| 866 | + |
| 867 | +# Converts an Accept-* header into an array mapping string values to quality factors |
| 868 | + |
| 869 | +function wfAcceptToPrefs($accept, $def = "*/*") { |
| 870 | + # No arg means accept anything (per HTTP spec) |
| 871 | + if (!$accept) { |
| 872 | + return array($def => 1); |
| 873 | + } |
| 874 | + |
| 875 | + $prefs = array(); |
| 876 | + |
| 877 | + $parts = explode(",", $accept); |
| 878 | + |
| 879 | + foreach ($parts as $part) { |
| 880 | + #FIXME: doesn't deal with params like 'text/html; level=1' |
| 881 | + list($value, $qpart) = explode(";", $part); |
| 882 | + if (!isset($qpart)) { |
| 883 | + $prefs[$value] = 1; |
| 884 | + } else if (preg_match('/q\s*=\s*(\d*\.\d+)/', $qpart, $match)) { |
| 885 | + $prefs[$value] = $match[1]; |
| 886 | + } |
| 887 | + } |
| 888 | + |
| 889 | + return $prefs; |
| 890 | +} |
| 891 | + |
| 892 | +/* private */ function mimeTypeMatch($type, $avail) { |
| 893 | + if (array_key_exists($type, $avail)) { |
| 894 | + return $type; |
| 895 | + } else { |
| 896 | + $parts = explode('/', $type); |
| 897 | + if (array_key_exists($parts[0] . '/*', $avail)) { |
| 898 | + return $parts[0] . '/*'; |
| 899 | + } else if (array_key_exists('*/*', $avail)) { |
| 900 | + return '*/*'; |
| 901 | + } else { |
| 902 | + return NULL; |
| 903 | + } |
| 904 | + } |
| 905 | +} |
| 906 | + |
| 907 | +#FIXME: doesn't handle params like 'text/plain; charset=UTF-8' |
| 908 | +#XXX: generalize to negotiate other stuff |
| 909 | + |
| 910 | +function wfNegotiateType($cprefs, $sprefs) { |
| 911 | + $combine = array(); |
| 912 | + |
| 913 | + foreach (array_keys($sprefs) as $type) { |
| 914 | + $parts = explode('/', $type); |
| 915 | + if ($parts[1] != '*') { |
| 916 | + $ckey = mimeTypeMatch($type, $cprefs); |
| 917 | + if ($ckey) { |
| 918 | + $combine[$type] = $sprefs[$type] * $cprefs[$ckey]; |
| 919 | + } |
| 920 | + } |
| 921 | + } |
| 922 | + |
| 923 | + foreach (array_keys($cprefs) as $type) { |
| 924 | + $parts = explode('/', $type); |
| 925 | + if ($parts[1] != '*' && !array_key_exists($type, $sprefs)) { |
| 926 | + $skey = mimeTypeMatch($type, $sprefs); |
| 927 | + if ($skey) { |
| 928 | + $combine[$type] = $sprefs[$skey] * $cprefs[$type]; |
| 929 | + } |
| 930 | + } |
| 931 | + } |
| 932 | + |
| 933 | + $bestq = 0; |
| 934 | + $besttype = NULL; |
| 935 | + |
| 936 | + foreach (array_keys($combine) as $type) { |
| 937 | + if ($combine[$type] > $bestq) { |
| 938 | + $besttype = $type; |
| 939 | + $bestq = $combine[$type]; |
| 940 | + } |
| 941 | + } |
| 942 | + |
| 943 | + return $besttype; |
| 944 | +} |
| 945 | + |
849 | 946 | ?> |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -292,5 +292,17 @@ |
293 | 293 | } |
294 | 294 | |
295 | 295 | # Show seconds in Recent Changes |
296 | | -$wgRCSeconds = false |
| 296 | +$wgRCSeconds = false; |
| 297 | + |
| 298 | + |
| 299 | +# RDF metadata toggles |
| 300 | + |
| 301 | +$wgEnableDublinCoreRdf = false; |
| 302 | +$wgEnableCreativeCommonsRdf = false; |
| 303 | + |
| 304 | +# Override for copyright metadata. |
| 305 | + |
| 306 | +$wgRightsPage = NULL; |
| 307 | +$wgRightsUrl = NULL; |
| 308 | +$wgRightsText = NULL; |
297 | 309 | ?> |
Index: trunk/phase3/includes/Skin.php |
— | — | @@ -95,15 +95,30 @@ |
96 | 96 | |
97 | 97 | function initPage( &$out ) |
98 | 98 | { |
99 | | - global $wgStyleSheetPath; |
100 | 99 | $fname = "Skin::initPage"; |
101 | 100 | wfProfileIn( $fname ); |
102 | 101 | |
103 | 102 | $out->addLink( "shortcut icon", "", "/favicon.ico" ); |
104 | | - |
| 103 | + |
| 104 | + $this->addMetadataLinks($out); |
| 105 | + |
105 | 106 | wfProfileOut( $fname ); |
106 | 107 | } |
107 | 108 | |
| 109 | + function addMetadataLinks( &$out ) { |
| 110 | + global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action; |
| 111 | + |
| 112 | + if ($action == 'view') { |
| 113 | + # note: buggy CC software only reads first "meta" link |
| 114 | + if ($wgEnableCreativeCommonsRdf) { |
| 115 | + $out->addMetadataLink('application/rdf+xml', wfLocalUrl($wgTitle->getPrefixedURL(), "action=creativecommons")); |
| 116 | + } |
| 117 | + if ($wgEnableDublinCoreRdf) { |
| 118 | + $out->addMetadataLink('application/rdf+xml', wfLocalUrl($wgTitle->getPrefixedURL(), "action=dublincore")); |
| 119 | + } |
| 120 | + } |
| 121 | + } |
| 122 | + |
108 | 123 | function outputPage( &$out ) { |
109 | 124 | global $wgDebugComments; |
110 | 125 | |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -46,6 +46,12 @@ |
47 | 47 | function addKeyword( $text ) { array_push( $this->mKeywords, $text ); } |
48 | 48 | function addLink( $rel, $rev, $target, $type="", $media="" ) { array_push( $this->mLinktags, array( $rel, $rev, $target, $type, $media ) ); } |
49 | 49 | |
| 50 | + function addMetadataLink( $type, $target ) { |
| 51 | + static $haveMeta = false; |
| 52 | + $this->addLink(($haveMeta) ? "alternate meta" : "meta", "", $target, $type); |
| 53 | + $haveMeta = true; |
| 54 | + } |
| 55 | + |
50 | 56 | # checkLastModified tells the client to use the client-cached page if |
51 | 57 | # possible. If sucessful, the OutputPage is disabled so that |
52 | 58 | # any future call to OutputPage->output() have no effect. The method |
Index: trunk/phase3/languages/Language.php |
— | — | @@ -1548,6 +1548,15 @@ |
1549 | 1549 | 'tooltip-specialpages' => 'List of all special pages', |
1550 | 1550 | 'tooltip-upload' => 'Upload images or media files [alt-u]', |
1551 | 1551 | 'tooltip-specialpage' => 'This is a special page, you can\'t edit the page itself.', |
| 1552 | + |
| 1553 | +# Metadata |
| 1554 | +"nodublincore" => "Dublin Core RDF metadata disabled for this server.", |
| 1555 | +"nocreativecommons" => "Creative Commons RDF metadata disabled for this server.", |
| 1556 | +"notacceptable" => "The wiki server can't provide data in a format your client can read.", |
| 1557 | + |
| 1558 | +# Attribution |
| 1559 | + |
| 1560 | +"anonymous" => "Anonymous user(s) of $wgSitename" |
1552 | 1561 | ); |
1553 | 1562 | |
1554 | 1563 | #-------------------------------------------------------------------------- |