mediawiki logo instead of the wikipedia one
[mediawiki.git] / includes / Metadata.php
blobb435284d051f3134cc39c5e5425d42fabeb02552
1 <?php
2 /* Metadata.php -- provides DublinCore and CreativeCommons metadata
3 * Copyright 2004, Evan Prodromou <evan@wikitravel.org>.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 define(RDF_TYPE_PREFS, "application/rdf+xml,text/xml;q=0.7,application/xml;q=0.5,text/rdf;q=0.1");
22 function wfDublinCoreRdf($article) {
24 $url = dcReallyFullUrl($article->mTitle);
26 if (rdfSetup()) {
27 dcPrologue($url);
28 dcBasics($article);
29 dcEpilogue();
33 function wfCreativeCommonsRdf($article) {
35 if (rdfSetup()) {
36 global $wgRightsUrl;
38 $url = dcReallyFullUrl($article->mTitle);
40 ccPrologue();
41 ccSubPrologue('Work', $url);
42 dcBasics($article);
43 if (isset($wgRightsUrl)) {
44 print " <cc:license rdf:resource=\"$wgRightsUrl\" />\n";
47 ccSubEpilogue('Work');
49 if (isset($wgRightsUrl)) {
50 $terms = ccGetTerms($wgRightsUrl);
51 if ($terms) {
52 ccSubPrologue('License', $wgRightsUrl);
53 ccLicense($terms);
54 ccSubEpilogue('License');
59 ccEpilogue();
62 /* private */ function rdfSetup() {
63 global $wgOut, $wgRdfMimeType, $_SERVER;
65 $rdftype = wfNegotiateType(wfAcceptToPrefs($_SERVER['HTTP_ACCEPT']), wfAcceptToPrefs(RDF_TYPE_PREFS));
67 if (!$rdftype) {
68 wfHttpError(406, "Not Acceptable", wfMsg("notacceptable"));
69 return false;
70 } else {
71 $wgOut->disable();
72 header( "Content-type: {$rdftype}" );
73 $wgOut->sendCacheControl();
74 return true;
78 /* private */ function dcPrologue($url) {
79 global $wgOutputEncoding;
81 print "<?xml version=\"1.0\" encoding=\"{$wgOutputEncoding}\" ?>
83 <!DOCTYPE rdf:RDF PUBLIC \"-//DUBLIN CORE//DCMES DTD 2002/07/31//EN\" \"http://dublincore.org/documents/2002/07/31/dcmes-xml/dcmes-xml-dtd.dtd\">
85 <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
86 xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
87 <rdf:Description rdf:about=\"$url\">
91 /* private */ function dcEpilogue() {
92 print "
93 </rdf:Description>
94 </rdf:RDF>
98 /* private */ function dcBasics($article) {
99 global $wgLanguageCode, $wgSitename;
101 dcElement('title', $article->mTitle->getText());
102 dcPageOrString('publisher', wfMsg('aboutpage'), $wgSitename);
103 dcElement('language', $wgLanguageCode);
104 dcElement('type', 'Text');
105 dcElement('format', 'text/html');
106 dcElement('identifier', dcReallyFullUrl($article->mTitle));
107 dcElement('date', dcDate($article->getTimestamp()));
108 dcPerson('creator', $article->getUser());
110 $contributors = dcContributors($article->mTitle);
112 foreach ($contributors as $cid) {
113 dcPerson('contributor', $cid);
116 dcRights($article);
119 /* private */ function ccPrologue() {
120 global $wgOutputEncoding;
122 echo "<?xml version='1.0' encoding='{$wgOutputEncoding}' ?>
124 <rdf:RDF xmlns:cc=\"http://web.resource.org/cc/\"
125 xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
126 xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">
130 /* private */ function ccSubPrologue($type, $url) {
131 echo " <cc:{$type} rdf:about=\"{$url}\">\n";
134 /* private */ function ccSubEpilogue($type) {
135 echo " </cc:{$type}>\n";
138 /* private */ function ccLicense($terms) {
140 foreach ($terms as $term) {
141 switch ($term) {
142 case 're':
143 ccTerm('permits', "Reproduction"); break;
144 case 'di':
145 ccTerm('permits', "Distribution"); break;
146 case 'de':
147 ccTerm('permits', "DerivativeWorks"); break;
148 case 'nc':
149 ccTerm('prohibits', "CommercialUse"); break;
150 case 'no':
151 ccTerm('requires', "Notice"); break;
152 case 'by':
153 ccTerm('requires', "Attribution"); break;
154 case 'sa':
155 ccTerm('requires', "ShareAlike"); break;
156 case 'sc':
157 ccTerm('requires', "SourceCode"); break;
162 /* private */ function ccTerm($term, $name) {
163 print " <cc:{$term} rdf:resource=\"http://web.resource.org/cc/{$name}\" />\n";
166 /* private */ function ccEpilogue() {
167 echo "</rdf:RDF>\n";
170 /* private */ function dcElement($name, $value) {
171 print " <dc:{$name}>{$value}</dc:{$name}>\n";
174 /* private */ function dcDate($timestamp) {
175 return substr($timestamp, 0, 4) . "-"
176 . substr($timestamp, 4, 2) . "-"
177 . substr($timestamp, 6, 2);
180 /* private */ function dcReallyFullUrl($title) {
181 $title->getFullURL();
184 /* private */ function dcPageOrString($name, $page, $str) {
185 $nt = Title::newFromText($page);
187 if (!$nt || $nt->getArticleID() == 0) {
188 dcElement($name, $str);
189 } else {
190 dcPage($name, $nt);
194 /* private */ function dcPage($name, $title) {
195 dcUrl($name, dcReallyFullUrl($title));
198 /* private */ function dcUrl($name, $url) {
199 print " <dc:{$name} rdf:resource=\"{$url}\" />\n";
202 /* private */ function dcPerson($name, $id) {
203 global $wgLang;
205 if ($id == 0) {
206 dcElement($name, wfMsg("anonymous"));
207 } else {
208 $user_name = User::whoIs($id);
209 dcPageOrString($name, $wgLang->getNsText(NS_USER) . ":" . $user_name, $user_name);
213 /* private */ function dcContributors($title) {
215 $contribs = array();
217 $res = wfQuery("SELECT DISTINCT old_user" .
218 " FROM old " .
219 " WHERE old_namespace = " . $title->getNamespace() .
220 " AND old_title = '" . $title->getDBkey() . "'", DB_READ);
222 while ( $line = wfFetchObject( $res ) ) {
223 $contribs[] = $line->old_user;
226 return $contribs;
229 /* Takes an arg, for future enhancement with different rights for
230 different pages. */
232 /* private */ function dcRights($article) {
234 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
236 if (isset($wgRightsPage) &&
237 ($nt = Title::newFromText($wgRightsPage))
238 && ($nt->getArticleID() != 0)) {
239 dcPage('rights', $nt);
240 } else if (isset($wgRightsUrl)) {
241 dcUrl('rights', $wgRightsUrl);
242 } else if (isset($wgRightsText)) {
243 dcElement('rights', $wgRightsText);
247 /* private */ function ccGetTerms($url) {
248 global $wgLicenseTerms;
250 if (isset($wgLicenseTerms)) {
251 return $wgLicenseTerms;
252 } else {
253 $known = getKnownLicenses();
254 return $known[$url];
258 /* private */ function getKnownLicenses() {
260 $ccLicenses = array('by', 'by-nd', 'by-nd-nc', 'by-nc',
261 'by-nc-sa', 'by-sa', 'nd', 'nd-nc',
262 'nc', 'nc-sa', 'sa');
264 $knownLicenses = array();
266 foreach ($ccLicenses as $license) {
267 $lurl = "http://creativecommons.org/licenses/{$license}/1.0/";
268 $knownLicenses[$lurl] = explode('-', $license);
269 $knownLicenses[$lurl][] = 're';
270 $knownLicenses[$lurl][] = 'di';
271 $knownLicenses[$lurl][] = 'no';
272 if (!in_array('nd', $knownLicenses[$lurl])) {
273 $knownLicenses[$lurl][] = 'de';
277 /* Handle the GPL and LGPL, too. */
279 $knownLicenses["http://creativecommons.org/licenses/GPL/2.0/"] =
280 array('de', 're', 'di', 'no', 'sa', 'sc');
281 $knownLicenses["http://creativecommons.org/licenses/LGPL/2.1/"] =
282 array('de', 're', 'di', 'no', 'sa', 'sc');
283 $knownLicenses["http://www.gnu.org/copyleft/fdl.html"] =
284 array('de', 're', 'di', 'no', 'sa', 'sc');
286 return $knownLicenses;