* (bug 10365) Localization of Special:Version
[lhc/web/wiklou.git] / includes / SpecialVersion.php
1 <?php
2 /**#@+
3 * Give information about the version of MediaWiki, PHP, the DB and extensions
4 *
5 * @addtogroup SpecialPage
6 *
7 * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
8 * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
9 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
10 */
11
12 /**
13 * constructor
14 */
15 function wfSpecialVersion() {
16 $version = new SpecialVersion;
17 $version->execute();
18 }
19
20 class SpecialVersion {
21 private $firstExtOpened = true;
22
23 /**
24 * main()
25 */
26 function execute() {
27 global $wgOut;
28
29 $wgOut->addWikiText(
30 $this->MediaWikiCredits() .
31 $this->systemInformation() .
32 $this->extensionCredits() .
33 $this->wgHooks()
34 );
35 $wgOut->addHTML( $this->IPInfo() );
36 }
37
38 /**#@+
39 * @private
40 */
41
42 /**
43 * Return wiki text showing the licence information and third party
44 * software versions (apache, php, mysql).
45 * @static
46 */
47 function MediaWikiCredits() {
48 $ret = "<h2>" . wfMsgExt( 'version-licence', array( 'parseinline' ) ) . "</h2>\n";
49
50 $ret .=
51 "__NOTOC__
52 <div dir='ltr'>
53 This wiki is powered by '''[http://www.mediawiki.org/ MediaWiki]''',
54 copyright (C) 2001-2007 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
55 Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason,
56 Niklas Laxström, Domas Mituzas, Rob Church and others.
57
58 MediaWiki is free software; you can redistribute it and/or modify
59 it under the terms of the GNU General Public License as published by
60 the Free Software Foundation; either version 2 of the License, or
61 (at your option) any later version.
62
63 MediaWiki is distributed in the hope that it will be useful,
64 but WITHOUT ANY WARRANTY; without even the implied warranty of
65 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66 GNU General Public License for more details.
67
68 You should have received [{{SERVER}}{{SCRIPTPATH}}/COPYING a copy of the GNU General Public License]
69 along with this program; if not, write to the Free Software
70 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
71 or [http://www.gnu.org/copyleft/gpl.html read it online]
72 </div>";
73
74 $translation = wfMsgExt( 'version-licence-text', array( 'parseline' ) );
75 if( !( wfEmptyMsg( 'version-licence-text', $translation ) || $translation == '-' || $translation == '' ) ) {
76 $ret .= "<h3>" . wfMsgExt( 'version-licence-header', array( 'parseinline' ) ) . "</h3>\n";
77 $ret .= $translation;
78 }
79 return str_replace( "\t\t", '', $ret ) . "\n";
80 }
81
82 /** Return a string of the MediaWiki version with SVN revision if available */
83 public static function getVersion() {
84 global $wgVersion, $IP;
85 $svn = self::getSvnRevision( $IP );
86 return $svn ? "$wgVersion (r$svn)" : $wgVersion;
87 }
88
89 /** Generate wikitext showing extensions name, URL, author and description */
90 function extensionCredits() {
91 global $wgExtensionCredits, $wgExtensionFunctions, $wgParser, $wgSkinExtensionFunction;
92
93 if ( ! count( $wgExtensionCredits ) && ! count( $wgExtensionFunctions ) && ! count( $wgSkinExtensionFunction ) )
94 return '';
95
96 $extensionTypes = array(
97 'specialpage' => wfMsgExt( 'version-specialpages', array( 'parseinline' ) ),
98 'parserhook' => wfMsgExt( 'version-parserhooks', array( 'parseinline' ) ),
99 'variable' => wfMsgExt( 'version-variables', array( 'parseinline' ) ),
100 'other' => wfMsgExt( 'version-other', array( 'parseinline' ) ),
101 );
102 wfRunHooks( 'SpecialVersionExtensionTypes', array( &$this, &$extensionTypes ) );
103
104 $out = "<h2>" . wfMsgExt( 'version-extensions', array( 'parseinline' ) ) . "</h2>\n";
105 $out .= Xml::openElement( 'table', array('id' => 'sv-ext', 'dir' => 'ltr' ) );
106
107 foreach ( $extensionTypes as $type => $text ) {
108 if ( isset ( $wgExtensionCredits[$type] ) && count ( $wgExtensionCredits[$type] ) ) {
109 $out .= $this->openExtType( $text );
110
111 usort( $wgExtensionCredits[$type], array( $this, 'compare' ) );
112
113 foreach ( $wgExtensionCredits[$type] as $extension ) {
114 $out .= $this->formatCredits(
115 isset ( $extension['name'] ) ? $extension['name'] : '',
116 isset ( $extension['version'] ) ? $extension['version'] : null,
117 isset ( $extension['author'] ) ? $extension['author'] : '',
118 isset ( $extension['url'] ) ? $extension['url'] : null,
119 isset ( $extension['description'] ) ? $extension['description'] : ''
120 );
121 }
122 }
123 }
124
125 if ( count( $wgExtensionFunctions ) ) {
126 $out .= $this->openExtType( wfMsgExt( 'version-extension-functions', array( 'parseinline' ) ) );
127 $out .= '<tr><td colspan="3">' . $this->listToText( $wgExtensionFunctions ) . "</td></tr>\n";
128 }
129
130 if ( $cnt = count( $tags = $wgParser->getTags() ) ) {
131 for ( $i = 0; $i < $cnt; ++$i )
132 $tags[$i] = "&lt;{$tags[$i]}&gt;";
133 $out .= $this->openExtType( wfMsgExt( 'version-parser-extensiontags', array( 'parseinline' ) ) );
134 $out .= '<tr><td colspan="3">' . $this->listToText( $tags ). "</td></tr>\n";
135 }
136
137 if( $cnt = count( $fhooks = $wgParser->getFunctionHooks() ) ) {
138 $out .= $this->openExtType( wfMsgExt( 'version-parser-function-hooks', array( 'parseinline' ) ) );
139 $out .= '<tr><td colspan="3">' . $this->listToText( $fhooks ) . "</td></tr>\n";
140 }
141
142 if ( count( $wgSkinExtensionFunction ) ) {
143 $out .= $this->openExtType( wfMsgExt( 'version-skin-extension-functions', array( 'parseinline' ) ) );
144 $out .= '<tr><td colspan="3">' . $this->listToText( $wgSkinExtensionFunction ) . "</td></tr>\n";
145 }
146 $out .= Xml::closeElement( 'table' );
147 return $out;
148 }
149
150 /** Callback to sort extensions by type */
151 function compare( $a, $b ) {
152 if ( $a['name'] === $b['name'] )
153 return 0;
154 else
155 return Language::lc( $a['name'] ) > Language::lc( $b['name'] ) ? 1 : -1;
156 }
157
158 function formatCredits( $name, $version = null, $author = null, $url = null, $description = null) {
159 $ret = '<tr><td>';
160 if ( isset( $url ) )
161 $ret .= "[$url ";
162 $ret .= "''$name";
163 if ( isset( $version ) )
164 $ret .= " (version $version)";
165 $ret .= "''";
166 if ( isset( $url ) )
167 $ret .= ']';
168 $ret .= '</td>';
169 $ret .= "<td>$description</td>";
170 $ret .= "<td>" . $this->listToText( (array)$author ) . "</td>";
171 $ret .= '</tr>';
172 return "$ret\n";
173 }
174
175 /**
176 * @return string
177 */
178 function wgHooks() {
179 global $wgHooks;
180
181 if ( count( $wgHooks ) ) {
182 $myWgHooks = $wgHooks;
183 ksort( $myWgHooks );
184
185 $ret = "<h2>" . wfMsgExt( 'version-hooks', array( 'parseinline' ) ) . "</h2>\n";
186 $ret .= Xml::openElement( 'table', array( 'id' => 'sv-hooks', 'dir' => 'ltr' ) );
187 $ret .= "<tr>
188 <th>" . wfMsgExt( 'version-hook-name', array( 'parseinline' ) ) . "</th>
189 <th>" . wfMsgExt( 'version-hook-subscribedby', array( 'parseinline' ) ) . "</th>
190 </tr>\n";
191
192 foreach ($myWgHooks as $hook => $hooks)
193 $ret .= "<tr>
194 <td>$hook</td>
195 <td>" . $this->listToText( $hooks ) . "</td>
196 </tr>\n";
197
198 $ret .= Xml::closeElement( 'table' );
199 return $ret;
200 } else
201 return '';
202 }
203
204 function systemInformation() {
205 $version = self::getVersion();
206 $dbr = wfGetDB( DB_SLAVE );
207
208 $ret = "<h2>" . wfMsgExt( 'version-system', array( 'parseinline' ) ) . "</h2>\n";
209 $ret .= Xml::openElement( 'table', array( 'id' => 'sv-software', 'dir' => 'ltr' ) );
210 $ret .= "<tr>
211 <th>" . wfMsgExt( 'version-software', array( 'parseinline' ) ) . "</th>
212 <th>" . wfMsgExt( 'version-version', array( 'parseinline' ) ) . "</th>
213 </tr>
214 <tr>
215 <td>[http://www.mediawiki.org/ MediaWiki]:</td>
216 <td>$version</td>
217 </tr>
218 <tr>
219 <td>[http://www.php.net/ PHP]:</td>
220 <td>" . phpversion() . " (" . php_sapi_name() . ")</td>
221 </tr>
222 <tr>
223 <td>" . $dbr->getSoftwareLink() . ":</td>
224 <td>" . $dbr->getServerVersion() . "</td>
225 </tr>\n";
226 $ret .= Xml::closeElement( 'table' );
227
228 return $ret;
229 }
230
231 private function openExtType($text, $name = null) {
232 $opt = array( 'colspan' => 3 );
233 $out = '';
234
235 if(!$this->firstExtOpened) {
236 // Insert a spacing line
237 $out .= '<tr class="sv-space">' . Xml::tags( 'td', $opt, '' ) . "</tr>\n";
238 }
239 $this->firstExtOpened = false;
240
241 if($name) { $opt['id'] = "sv-$name"; }
242
243 $out .= "<tr>" . Xml::tags( 'th', $opt, $text) . "</tr>\n";
244 return $out;
245 }
246
247 /**
248 * @static
249 *
250 * @return string
251 */
252 function IPInfo() {
253 $ip = str_replace( '--', ' - ', htmlspecialchars( wfGetIP() ) );
254 return "<!-- visited from $ip -->\n" .
255 "<span style='display:none'>visited from $ip</span>";
256 }
257
258 /**
259 * @param array $list
260 * @return string
261 */
262 function listToText( $list ) {
263
264 if ( count( $list ) ) {
265 sort( $list );
266 return implode( ', ', $list );
267 } else {
268 return '';
269 }
270 }
271
272 /**
273 * Retrieve the revision number of a Subversion working directory.
274 *
275 * @param string $dir
276 * @return mixed revision number as int, or false if not a SVN checkout
277 */
278 public static function getSvnRevision( $dir ) {
279 // http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html
280 $entries = $dir . '/.svn/entries';
281
282 if( !file_exists( $entries ) ) {
283 return false;
284 }
285
286 $content = file( $entries );
287
288 // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
289 if( preg_match( '/^<\?xml/', $content[0] ) ) {
290 // subversion is release <= 1.3
291 if( !function_exists( 'simplexml_load_file' ) ) {
292 // We could fall back to expat... YUCK
293 return false;
294 }
295
296 // SimpleXml whines about the xmlns...
297 wfSuppressWarnings();
298 $xml = simplexml_load_file( $entries );
299 wfRestoreWarnings();
300
301 if( $xml ) {
302 foreach( $xml->entry as $entry ) {
303 if( $xml->entry[0]['name'] == '' ) {
304 // The directory entry should always have a revision marker.
305 if( $entry['revision'] ) {
306 return intval( $entry['revision'] );
307 }
308 }
309 }
310 }
311 return false;
312 } else {
313 // subversion is release 1.4
314 return intval( $content[3] );
315 }
316 }
317
318 /**#@-*/
319 }
320
321 /**#@-*/
322 ?>