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