r86403 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r86402‎ | r86403 | r86404 >
Date:15:20, 19 April 2011
Author:maxsem
Status:deferred
Tags:
Comment:
Splited to separate files, created GadgetsView. Export was removed as it's not going to be used in its present form
Modified paths:
  • /branches/Gadgets3.0/Gadgets.php (modified) (history)
  • /branches/Gadgets3.0/backend/Gadget.php (added) (history)
  • /branches/Gadgets3.0/backend/GadgetHooks.php (added) (history)
  • /branches/Gadgets3.0/backend/Gadgets_body.php (deleted) (history)
  • /branches/Gadgets3.0/ui/ExportGadgetsView.php (added) (history)
  • /branches/Gadgets3.0/ui/GadgetsView.php (added) (history)
  • /branches/Gadgets3.0/ui/MainGadgetsView.php (added) (history)
  • /branches/Gadgets3.0/ui/SpecialGadgets.php (modified) (history)

Diff [purge]

Index: branches/Gadgets3.0/Gadgets.php
@@ -17,8 +17,8 @@
1818 die( 1 );
1919 }
2020
21 -if ( version_compare( $wgVersion, '1.17alpha', '<' ) ) {
22 - die( "This version of Extension:Gadgets requires MediaWiki 1.17+\n" );
 21+if ( version_compare( $wgVersion, '1.18alpha', '<' ) ) {
 22+ die( "This version of Extension:Gadgets requires MediaWiki 1.18+\n" );
2323 }
2424
2525 $wgExtensionCredits['other'][] = array(
@@ -39,12 +39,17 @@
4040 $wgExtensionMessagesFiles['Gadgets'] = $dir . 'Gadgets.i18n.php';
4141 $wgExtensionAliasesFiles['Gadgets'] = $dir . 'Gadgets.alias.php';
4242
 43+$wgAutoloadClasses['Gadget'] = $dir . 'backend/Gadget.php';
 44+$wgAutoloadClasses['GadgetHooks'] = $dir . 'backend/GadgetHooks.php';
 45+$wgAutoloadClasses['GadgetResourceLoaderModule'] = $dir . 'backend/GadgetResourceLoaderModule.php';
 46+
4347 $wgAutoloadClasses['ApiQueryGadgetCategories'] = $dir . 'api/ApiQueryGadgetCategories.php';
4448 $wgAutoloadClasses['ApiQueryGadgets'] = $dir . 'api/ApiQueryGadgets.php';
45 -$wgAutoloadClasses['Gadget'] = $dir . 'backend/Gadgets_body.php';
46 -$wgAutoloadClasses['GadgetHooks'] = $dir . 'backend/Gadgets_body.php';
47 -$wgAutoloadClasses['GadgetResourceLoaderModule'] = $dir . 'backend/Gadgets_body.php';
 49+
 50+
4851 $wgAutoloadClasses['SpecialGadgets'] = $dir . 'ui/SpecialGadgets.php';
 52+$wgAutoloadClasses['GadgetsView'] = $dir . 'ui/GadgetsView.php';
 53+$wgAutoloadClasses['MainGadgetsView'] = $dir . 'ui/MainGadgetsView.php';
4954
5055 $wgSpecialPages['Gadgets'] = 'SpecialGadgets';
5156 $wgSpecialPageGroups['Gadgets'] = 'wiki';
Index: branches/Gadgets3.0/backend/Gadgets_body.php
@@ -1,567 +0,0 @@
2 -<?php
3 -/**
4 - * Gadgets extension - lets users select custom javascript gadgets
5 - *
6 - *
7 - * For more info see http://mediawiki.org/wiki/Extension:Gadgets
8 - *
9 - * @file
10 - * @ingroup Extensions
11 - * @author Daniel Kinzler, brightbyte.de
12 - * @copyright © 2007 Daniel Kinzler
13 - * @license GNU General Public Licence 2.0 or later
14 - */
15 -
16 -class GadgetHooks {
17 -
18 - /**
19 - * ArticleSaveComplete hook handler.
20 - *
21 - * @param $article Article
22 - * @param $user User
23 - * @param $text String: New page text
24 - */
25 - public static function articleSaveComplete( $article, $user, $text ) {
26 - //update cache if MediaWiki:Gadgets-definition was edited
27 - $title = $article->mTitle;
28 - if( $title->getNamespace() == NS_MEDIAWIKI && $title->getText() == 'Gadgets-definition' ) {
29 - Gadget::loadStructuredList( $text );
30 - }
31 - return true;
32 - }
33 -
34 - /**
35 - * GetPreferences hook handler.
36 - * @param $user User
37 - * @param $preferences Array: Preference descriptions
38 - */
39 - public static function getPreferences( $user, &$preferences ) {
40 - $gadgets = Gadget::loadStructuredList();
41 - if (!$gadgets) return true;
42 -
43 - $options = array();
44 - $default = array();
45 - foreach( $gadgets as $section => $thisSection ) {
46 - $available = array();
47 - foreach( $thisSection as $gadget ) {
48 - if ( $gadget->isAllowed( $user ) ) {
49 - $gname = $gadget->getName();
50 - $available[$gadget->getDescription()] = $gname;
51 - if ( $gadget->isEnabled( $user ) ) {
52 - $default[] = $gname;
53 - }
54 - }
55 - }
56 - if ( $section !== '' ) {
57 - $section = wfMsgExt( "gadget-section-$section", 'parseinline' );
58 - if ( count ( $available ) ) {
59 - $options[$section] = $available;
60 - }
61 - } else {
62 - $options = array_merge( $options, $available );
63 - }
64 - }
65 -
66 - $preferences['gadgets-intro'] =
67 - array(
68 - 'type' => 'info',
69 - 'label' => '&#160;',
70 - 'default' => Xml::tags( 'tr', array(),
71 - Xml::tags( 'td', array( 'colspan' => 2 ),
72 - wfMsgExt( 'gadgets-prefstext', 'parse' ) ) ),
73 - 'section' => 'gadgets',
74 - 'raw' => 1,
75 - 'rawrow' => 1,
76 - );
77 -
78 - $preferences['gadgets'] =
79 - array(
80 - 'type' => 'multiselect',
81 - 'options' => $options,
82 - 'section' => 'gadgets',
83 - 'label' => '&#160;',
84 - 'prefix' => 'gadget-',
85 - 'default' => $default,
86 - );
87 -
88 - return true;
89 - }
90 -
91 - /**
92 - * ResourceLoaderRegisterModules hook handler.
93 - * @param $resourceLoader ResourceLoader
94 - */
95 - public static function registerModules( &$resourceLoader ) {
96 - $gadgets = Gadget::loadList();
97 - if ( !$gadgets ) {
98 - return true;
99 - }
100 - foreach ( $gadgets as $g ) {
101 - $module = $g->getModule();
102 - if ( $module ) {
103 - $resourceLoader->register( $g->getModuleName(), $module );
104 - }
105 - }
106 - return true;
107 - }
108 -
109 - /**
110 - * BeforePageDisplay hook handler.
111 - * @param $out OutputPage
112 - */
113 - public static function beforePageDisplay( $out ) {
114 - global $wgUser;
115 -
116 - wfProfileIn( __METHOD__ );
117 -
118 - $gadgets = Gadget::loadList();
119 - if ( !$gadgets ) {
120 - wfProfileOut( __METHOD__ );
121 - return true;
122 - }
123 -
124 - $lb = new LinkBatch();
125 - $lb->setCaller( __METHOD__ );
126 - $pages = array();
127 -
128 - foreach ( $gadgets as $gadget ) {
129 - if ( $gadget->isEnabled( $wgUser ) && $gadget->isAllowed( $wgUser ) ) {
130 - if ( $gadget->hasModule() ) {
131 - $out->addModules( $gadget->getModuleName() );
132 - }
133 - foreach ( $gadget->getLegacyScripts() as $page ) {
134 - $lb->add( NS_MEDIAWIKI, $page );
135 - $pages[] = $page;
136 - }
137 - }
138 - }
139 -
140 - $lb->execute( __METHOD__ );
141 -
142 - $done = array();
143 - foreach ( $pages as $page ) {
144 - if ( isset( $done[$page] ) ) continue;
145 - $done[$page] = true;
146 - self::applyScript( $page, $out );
147 - }
148 - wfProfileOut( __METHOD__ );
149 -
150 - return true;
151 - }
152 -
153 - /**
154 - * Adds one legacy script to output.
155 - *
156 - * @param $page String: Unprefixed page title
157 - * @param $out OutputPage
158 - */
159 - private static function applyScript( $page, $out ) {
160 - global $wgJsMimeType;
161 -
162 - # bug 22929: disable gadgets on sensitive pages. Scripts loaded through the
163 - # ResourceLoader handle this in OutputPage::getModules()
164 - # TODO: make this extension load everything via RL, then we don't need to worry
165 - # about any of this.
166 - if( $out->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS ) < ResourceLoaderModule::ORIGIN_USER_SITEWIDE ){
167 - return;
168 - }
169 -
170 - $t = Title::makeTitleSafe( NS_MEDIAWIKI, $page );
171 - if ( !$t ) return;
172 -
173 - $u = $t->getLocalURL( 'action=raw&ctype=' . $wgJsMimeType );
174 - $out->addScriptFile( $u, $t->getLatestRevID() );
175 - }
176 -
177 - /**
178 - * UnitTestsList hook handler
179 - * @param $files Array: List of extension test files
180 - */
181 - public static function unitTestsList( $files ) {
182 - $files[] = dirname( __FILE__ ) . '/Gadgets_tests.php';
183 - return true;
184 - }
185 -}
186 -
187 -/**
188 - * Wrapper for one gadget.
189 - */
190 -class Gadget {
191 - /**
192 - * Increment this when changing class structure
193 - */
194 - const GADGET_CLASS_VERSION = 5;
195 -
196 - private $version = self::GADGET_CLASS_VERSION,
197 - $scripts = array(),
198 - $styles = array(),
199 - $dependencies = array(),
200 - $name,
201 - $definition,
202 - $resourceLoaded = false,
203 - $requiredRights = array(),
204 - $onByDefault = false,
205 - $category;
206 -
207 - /**
208 - * Creates an instance of this class from definition in MediaWiki:Gadgets-definition
209 - * @param $definition String: Gadget definition
210 - * @return Mixed: Instance of Gadget class or false if $definition is invalid
211 - */
212 - public static function newFromDefinition( $definition ) {
213 - $m = array();
214 - if ( !preg_match( '/^\*+ *([a-zA-Z](?:[-_:.\w\d ]*[a-zA-Z0-9])?)(\s*\[.*?\])?\s*((\|[^|]*)+)\s*$/', $definition, $m ) ) {
215 - return false;
216 - }
217 - //NOTE: the gadget name is used as part of the name of a form field,
218 - // and must follow the rules defined in http://www.w3.org/TR/html4/types.html#type-cdata
219 - // Also, title-normalization applies.
220 - $gadget = new Gadget();
221 - $gadget->name = trim( str_replace(' ', '_', $m[1] ) );
222 - $gadget->definition = $definition;
223 - $options = trim( $m[2], ' []' );
224 - foreach ( preg_split( '/\s*\|\s*/', $options, -1, PREG_SPLIT_NO_EMPTY ) as $option ) {
225 - $arr = preg_split( '/\s*=\s*/', $option, 2 );
226 - $option = $arr[0];
227 - if ( isset( $arr[1] ) ) {
228 - $params = explode( ',', $arr[1] );
229 - $params = array_map( 'trim', $params );
230 - } else {
231 - $params = array();
232 - }
233 - switch ( $option ) {
234 - case 'ResourceLoader':
235 - $gadget->resourceLoaded = true;
236 - break;
237 - case 'dependencies':
238 - $gadget->dependencies = $params;
239 - break;
240 - case 'rights':
241 - $gadget->requiredRights = $params;
242 - break;
243 - case 'default':
244 - $gadget->onByDefault = true;
245 - break;
246 - }
247 - }
248 - foreach ( preg_split( '/\s*\|\s*/', $m[3], -1, PREG_SPLIT_NO_EMPTY ) as $page ) {
249 - $page = "Gadget-$page";
250 - if ( preg_match( '/\.js/', $page ) ) {
251 - $gadget->scripts[] = $page;
252 - } elseif ( preg_match( '/\.css/', $page ) ) {
253 - $gadget->styles[] = $page;
254 - }
255 - }
256 - return $gadget;
257 - }
258 -
259 - /**
260 - * @return String: Gadget name
261 - */
262 - public function getName() {
263 - return $this->name;
264 - }
265 -
266 - /**
267 - * @return String: Gadget description parsed into HTML
268 - */
269 - public function getDescription() {
270 - return wfMessage( "gadget-{$this->getName()}" )->parse();
271 - }
272 -
273 - /**
274 - * @return String: Wikitext of gadget description
275 - */
276 - public function getRawDescription() {
277 - return wfMessage( "gadget-{$this->getName()}" )->plain();
278 - }
279 -
280 - /**
281 - * @return String: Name of category (aka section) our gadget belongs to. Empty string if none.
282 - */
283 - public function getCategory() {
284 - return $this->category;
285 - }
286 -
287 - /**
288 - * @return String: Name of ResourceLoader module for this gadget
289 - */
290 - public function getModuleName() {
291 - return "ext.gadget.{$this->name}";
292 - }
293 -
294 - /**
295 - * Checks whether this is an instance of an older version of this class deserialized from cache
296 - * @return Boolean
297 - */
298 - public function isOutdated() {
299 - return $this->version != self::GADGET_CLASS_VERSION;
300 - }
301 -
302 - /**
303 - * Checks whether this gadget is enabled for given user
304 - *
305 - * @param $user User: user to check against
306 - * @return Boolean
307 - */
308 - public function isEnabled( $user ) {
309 - return (bool)$user->getOption( "gadget-{$this->name}", $this->onByDefault );
310 - }
311 -
312 - /**
313 - * Checks whether given user has permissions to use this gadget
314 - *
315 - * @param $user User: user to check against
316 - * @return Boolean
317 - */
318 - public function isAllowed( $user ) {
319 - return count( array_intersect( $this->requiredRights, $user->getRights() ) ) == count( $this->requiredRights );
320 - }
321 -
322 - /**
323 - * @return Boolean: Whether this gadget is on by default for everyone (but can be disabled in preferences)
324 - */
325 - public function isOnByDefault() {
326 - return $this->onByDefault;
327 - }
328 -
329 - /**
330 - * @return Boolean: Whether all of this gadget's JS components support ResourceLoader
331 - */
332 - public function supportsResourceLoader() {
333 - return $this->resourceLoaded;
334 - }
335 -
336 - /**
337 - * @return Boolean: Whether this gadget has resources that can be loaded via ResourceLoader
338 - */
339 - public function hasModule() {
340 - return count( $this->styles )
341 - + ( $this->supportsResourceLoader() ? count( $this->scripts ) : 0 )
342 - > 0;
343 - }
344 -
345 - /**
346 - * @return String: Definition for this gadget from MediaWiki:gadgets-definition
347 - */
348 - public function getDefinition() {
349 - return $this->definition;
350 - }
351 -
352 - /**
353 - * @return Array: Array of pages with JS not prefixed with namespace
354 - */
355 - public function getScripts() {
356 - return $this->scripts;
357 - }
358 -
359 - /**
360 - * @return Array: Array of pages with CSS not prefixed with namespace
361 - */
362 - public function getStyles() {
363 - return $this->styles;
364 - }
365 -
366 - /**
367 - * @return Array: Array of all of this gadget's resources
368 - */
369 - public function getScriptsAndStyles() {
370 - return array_merge( $this->scripts, $this->styles );
371 - }
372 -
373 - /**
374 - * Returns module for ResourceLoader, see getModuleName() for its name.
375 - * If our gadget has no scripts or styles suitable for RL, false will be returned.
376 - * @return Mixed: GadgetResourceLoaderModule or false
377 - */
378 - public function getModule() {
379 - $pages = array();
380 - foreach( $this->styles as $style ) {
381 - $pages['MediaWiki:' . $style] = array( 'type' => 'style' );
382 - }
383 - if ( $this->supportsResourceLoader() ) {
384 - foreach ( $this->scripts as $script ) {
385 - $pages['MediaWiki:' . $script] = array( 'type' => 'script' );
386 - }
387 - }
388 - if ( !count( $pages ) ) {
389 - return null;
390 - }
391 - return new GadgetResourceLoaderModule( $pages, $this->dependencies );
392 - }
393 -
394 - /**
395 - * Returns list of scripts that don't support ResourceLoader
396 - * @return Array
397 - */
398 - public function getLegacyScripts() {
399 - if ( $this->supportsResourceLoader() ) {
400 - return array();
401 - }
402 - return $this->scripts;
403 - }
404 -
405 - /**
406 - * Returns names of resources this gadget depends on
407 - * @return Array
408 - */
409 - public function getDependencies() {
410 - return $this->dependencies;
411 - }
412 -
413 - /**
414 - * Returns array of permissions required by this gadget
415 - * @return Array
416 - */
417 - public function getRequiredRights() {
418 - return $this->requiredRights;
419 - }
420 -
421 - /**
422 - * Loads and returns a list of all gadgets
423 - * @return Mixed: Array of gadgets or false
424 - */
425 - public static function loadList() {
426 - static $gadgets = null;
427 -
428 - if ( $gadgets !== null ) return $gadgets;
429 -
430 - wfProfileIn( __METHOD__ );
431 - $struct = self::loadStructuredList();
432 - if ( !$struct ) {
433 - $gadgets = $struct;
434 - wfProfileOut( __METHOD__ );
435 - return $gadgets;
436 - }
437 -
438 - $gadgets = array();
439 - foreach ( $struct as $section => $entries ) {
440 - $gadgets = array_merge( $gadgets, $entries );
441 - }
442 - wfProfileOut( __METHOD__ );
443 -
444 - return $gadgets;
445 - }
446 -
447 - /**
448 - * Checks whether gadget list from cache can be used.
449 - * @return Boolean
450 - */
451 - private static function isValidList( $gadgets ) {
452 - if ( !is_array( $gadgets ) ) return false;
453 - // Check if we have 1) array of gadgets 2) the gadgets are up to date
454 - // One check is enough
455 - foreach ( $gadgets as $section => $list ) {
456 - foreach ( $list as $g ) {
457 - if ( !( $g instanceof Gadget ) || $g->isOutdated() ) {
458 - return false;
459 - } else {
460 - return true;
461 - }
462 - }
463 - }
464 - return true; // empty array
465 - }
466 -
467 - /**
468 - * Loads list of gadgets and returns it as associative array of sections with gadgets
469 - * e.g. array( 'sectionnname1' => array( $gadget1, $gadget2),
470 - * 'sectionnname2' => array( $gadget3 ) );
471 - * @param $forceNewText String: New text of MediaWiki:gadgets-sdefinition. If specified, will
472 - * force a purge of cache and recreation of the gadget list.
473 - * @return Mixed: Array or false
474 - */
475 - public static function loadStructuredList( $forceNewText = null ) {
476 - global $wgMemc;
477 -
478 - static $gadgets = null;
479 - if ( $gadgets !== null && $forceNewText === null ) return $gadgets;
480 -
481 - wfProfileIn( __METHOD__ );
482 - $key = wfMemcKey( 'gadgets-definition', self::GADGET_CLASS_VERSION );
483 -
484 - if ( $forceNewText === null ) {
485 - //cached?
486 - $gadgets = $wgMemc->get( $key );
487 - if ( self::isValidList( $gadgets ) ) {
488 - wfProfileOut( __METHOD__ );
489 - return $gadgets;
490 - }
491 -
492 - $g = wfMsgForContentNoTrans( "gadgets-definition" );
493 - if ( wfEmptyMsg( "gadgets-definition", $g ) ) {
494 - $gadgets = false;
495 - wfProfileOut( __METHOD__ );
496 - return $gadgets;
497 - }
498 - } else {
499 - $g = $forceNewText;
500 - }
501 -
502 - $g = preg_replace( '/<!--.*-->/s', '', $g );
503 - $g = preg_split( '/(\r\n|\r|\n)+/', $g );
504 -
505 - $gadgets = array();
506 - $section = '';
507 -
508 - foreach ( $g as $line ) {
509 - $m = array();
510 - if ( preg_match( '/^==+ *([^*:\s|]+?)\s*==+\s*$/', $line, $m ) ) {
511 - $section = $m[1];
512 - }
513 - else {
514 - $gadget = self::newFromDefinition( $line );
515 - if ( $gadget ) {
516 - $gadgets[$section][$gadget->getName()] = $gadget;
517 - $gadget->category = $section;
518 - }
519 - }
520 - }
521 -
522 - //cache for a while. gets purged automatically when MediaWiki:Gadgets-definition is edited
523 - $wgMemc->set( $key, $gadgets, 60*60*24 );
524 - $source = $forceNewText !== null ? 'input text' : 'MediaWiki:Gadgets-definition';
525 - wfDebug( __METHOD__ . ": $source parsed, cache entry $key updated\n");
526 - wfProfileOut( __METHOD__ );
527 -
528 - return $gadgets;
529 - }
530 -}
531 -
532 -/**
533 - * Class representing a list of resources for one gadget
534 - */
535 -class GadgetResourceLoaderModule extends ResourceLoaderWikiModule {
536 - private $pages, $dependencies;
537 -
538 - /**
539 - * Creates an instance of this class
540 - * @param $pages Array: Associative array of pages in ResourceLoaderWikiModule-compatible
541 - * format, for example:
542 - * array(
543 - * 'MediaWiki:Gadget-foo.js' => array( 'type' => 'script' ),
544 - * 'MediaWiki:Gadget-foo.css' => array( 'type' => 'style' ),
545 - * )
546 - * @param $dependencies Array: Names of resources this module depends on
547 - */
548 - public function __construct( $pages, $dependencies ) {
549 - $this->pages = $pages;
550 - $this->dependencies = $dependencies;
551 - }
552 -
553 - /**
554 - * Overrides the abstract function from ResourceLoaderWikiModule class
555 - * @return Array: $pages passed to __construct()
556 - */
557 - protected function getPages( ResourceLoaderContext $context ) {
558 - return $this->pages;
559 - }
560 -
561 - /**
562 - * Overrides ResourceLoaderModule::getDependencies()
563 - * @return Array: Names of resources this module depends on
564 - */
565 - public function getDependencies() {
566 - return $this->dependencies;
567 - }
568 -}
Index: branches/Gadgets3.0/backend/Gadget.php
@@ -0,0 +1,347 @@
 2+<?php
 3+
 4+
 5+/**
 6+ * Wrapper for one gadget.
 7+ */
 8+class Gadget {
 9+ /**
 10+ * Increment this when changing class structure
 11+ */
 12+ const GADGET_CLASS_VERSION = 5;
 13+
 14+ private $version = self::GADGET_CLASS_VERSION,
 15+ $scripts = array(),
 16+ $styles = array(),
 17+ $dependencies = array(),
 18+ $name,
 19+ $definition,
 20+ $resourceLoaded = false,
 21+ $requiredRights = array(),
 22+ $onByDefault = false,
 23+ $category;
 24+
 25+ /**
 26+ * Creates an instance of this class from definition in MediaWiki:Gadgets-definition
 27+ * @param $definition String: Gadget definition
 28+ * @return Mixed: Instance of Gadget class or false if $definition is invalid
 29+ */
 30+ public static function newFromDefinition( $definition ) {
 31+ $m = array();
 32+ if ( !preg_match( '/^\*+ *([a-zA-Z](?:[-_:.\w\d ]*[a-zA-Z0-9])?)(\s*\[.*?\])?\s*((\|[^|]*)+)\s*$/', $definition, $m ) ) {
 33+ return false;
 34+ }
 35+ //NOTE: the gadget name is used as part of the name of a form field,
 36+ // and must follow the rules defined in http://www.w3.org/TR/html4/types.html#type-cdata
 37+ // Also, title-normalization applies.
 38+ $gadget = new Gadget();
 39+ $gadget->name = trim( str_replace(' ', '_', $m[1] ) );
 40+ $gadget->definition = $definition;
 41+ $options = trim( $m[2], ' []' );
 42+ foreach ( preg_split( '/\s*\|\s*/', $options, -1, PREG_SPLIT_NO_EMPTY ) as $option ) {
 43+ $arr = preg_split( '/\s*=\s*/', $option, 2 );
 44+ $option = $arr[0];
 45+ if ( isset( $arr[1] ) ) {
 46+ $params = explode( ',', $arr[1] );
 47+ $params = array_map( 'trim', $params );
 48+ } else {
 49+ $params = array();
 50+ }
 51+ switch ( $option ) {
 52+ case 'ResourceLoader':
 53+ $gadget->resourceLoaded = true;
 54+ break;
 55+ case 'dependencies':
 56+ $gadget->dependencies = $params;
 57+ break;
 58+ case 'rights':
 59+ $gadget->requiredRights = $params;
 60+ break;
 61+ case 'default':
 62+ $gadget->onByDefault = true;
 63+ break;
 64+ }
 65+ }
 66+ foreach ( preg_split( '/\s*\|\s*/', $m[3], -1, PREG_SPLIT_NO_EMPTY ) as $page ) {
 67+ $page = "Gadget-$page";
 68+ if ( preg_match( '/\.js/', $page ) ) {
 69+ $gadget->scripts[] = $page;
 70+ } elseif ( preg_match( '/\.css/', $page ) ) {
 71+ $gadget->styles[] = $page;
 72+ }
 73+ }
 74+ return $gadget;
 75+ }
 76+
 77+ /**
 78+ * @return String: Gadget name
 79+ */
 80+ public function getName() {
 81+ return $this->name;
 82+ }
 83+
 84+ /**
 85+ * @return String: Gadget description parsed into HTML
 86+ */
 87+ public function getDescription() {
 88+ return wfMessage( "gadget-{$this->getName()}" )->parse();
 89+ }
 90+
 91+ /**
 92+ * @return String: Wikitext of gadget description
 93+ */
 94+ public function getRawDescription() {
 95+ return wfMessage( "gadget-{$this->getName()}" )->plain();
 96+ }
 97+
 98+ /**
 99+ * @return String: Name of category (aka section) our gadget belongs to. Empty string if none.
 100+ */
 101+ public function getCategory() {
 102+ return $this->category;
 103+ }
 104+
 105+ /**
 106+ * @return String: Name of ResourceLoader module for this gadget
 107+ */
 108+ public function getModuleName() {
 109+ return "ext.gadget.{$this->name}";
 110+ }
 111+
 112+ /**
 113+ * Checks whether this is an instance of an older version of this class deserialized from cache
 114+ * @return Boolean
 115+ */
 116+ public function isOutdated() {
 117+ return $this->version != self::GADGET_CLASS_VERSION;
 118+ }
 119+
 120+ /**
 121+ * Checks whether this gadget is enabled for given user
 122+ *
 123+ * @param $user User: user to check against
 124+ * @return Boolean
 125+ */
 126+ public function isEnabled( $user ) {
 127+ return (bool)$user->getOption( "gadget-{$this->name}", $this->onByDefault );
 128+ }
 129+
 130+ /**
 131+ * Checks whether given user has permissions to use this gadget
 132+ *
 133+ * @param $user User: user to check against
 134+ * @return Boolean
 135+ */
 136+ public function isAllowed( $user ) {
 137+ return count( array_intersect( $this->requiredRights, $user->getRights() ) ) == count( $this->requiredRights );
 138+ }
 139+
 140+ /**
 141+ * @return Boolean: Whether this gadget is on by default for everyone (but can be disabled in preferences)
 142+ */
 143+ public function isOnByDefault() {
 144+ return $this->onByDefault;
 145+ }
 146+
 147+ /**
 148+ * @return Boolean: Whether all of this gadget's JS components support ResourceLoader
 149+ */
 150+ public function supportsResourceLoader() {
 151+ return $this->resourceLoaded;
 152+ }
 153+
 154+ /**
 155+ * @return Boolean: Whether this gadget has resources that can be loaded via ResourceLoader
 156+ */
 157+ public function hasModule() {
 158+ return count( $this->styles )
 159+ + ( $this->supportsResourceLoader() ? count( $this->scripts ) : 0 )
 160+ > 0;
 161+ }
 162+
 163+ /**
 164+ * @return String: Definition for this gadget from MediaWiki:gadgets-definition
 165+ */
 166+ public function getDefinition() {
 167+ return $this->definition;
 168+ }
 169+
 170+ /**
 171+ * @return Array: Array of pages with JS not prefixed with namespace
 172+ */
 173+ public function getScripts() {
 174+ return $this->scripts;
 175+ }
 176+
 177+ /**
 178+ * @return Array: Array of pages with CSS not prefixed with namespace
 179+ */
 180+ public function getStyles() {
 181+ return $this->styles;
 182+ }
 183+
 184+ /**
 185+ * @return Array: Array of all of this gadget's resources
 186+ */
 187+ public function getScriptsAndStyles() {
 188+ return array_merge( $this->scripts, $this->styles );
 189+ }
 190+
 191+ /**
 192+ * Returns module for ResourceLoader, see getModuleName() for its name.
 193+ * If our gadget has no scripts or styles suitable for RL, false will be returned.
 194+ * @return Mixed: GadgetResourceLoaderModule or false
 195+ */
 196+ public function getModule() {
 197+ $pages = array();
 198+ foreach( $this->styles as $style ) {
 199+ $pages['MediaWiki:' . $style] = array( 'type' => 'style' );
 200+ }
 201+ if ( $this->supportsResourceLoader() ) {
 202+ foreach ( $this->scripts as $script ) {
 203+ $pages['MediaWiki:' . $script] = array( 'type' => 'script' );
 204+ }
 205+ }
 206+ if ( !count( $pages ) ) {
 207+ return null;
 208+ }
 209+ return new GadgetResourceLoaderModule( $pages, $this->dependencies );
 210+ }
 211+
 212+ /**
 213+ * Returns list of scripts that don't support ResourceLoader
 214+ * @return Array
 215+ */
 216+ public function getLegacyScripts() {
 217+ if ( $this->supportsResourceLoader() ) {
 218+ return array();
 219+ }
 220+ return $this->scripts;
 221+ }
 222+
 223+ /**
 224+ * Returns names of resources this gadget depends on
 225+ * @return Array
 226+ */
 227+ public function getDependencies() {
 228+ return $this->dependencies;
 229+ }
 230+
 231+ /**
 232+ * Returns array of permissions required by this gadget
 233+ * @return Array
 234+ */
 235+ public function getRequiredRights() {
 236+ return $this->requiredRights;
 237+ }
 238+
 239+ /**
 240+ * Loads and returns a list of all gadgets
 241+ * @return Mixed: Array of gadgets or false
 242+ */
 243+ public static function loadList() {
 244+ static $gadgets = null;
 245+
 246+ if ( $gadgets !== null ) return $gadgets;
 247+
 248+ wfProfileIn( __METHOD__ );
 249+ $struct = self::loadStructuredList();
 250+ if ( !$struct ) {
 251+ $gadgets = $struct;
 252+ wfProfileOut( __METHOD__ );
 253+ return $gadgets;
 254+ }
 255+
 256+ $gadgets = array();
 257+ foreach ( $struct as $section => $entries ) {
 258+ $gadgets = array_merge( $gadgets, $entries );
 259+ }
 260+ wfProfileOut( __METHOD__ );
 261+
 262+ return $gadgets;
 263+ }
 264+
 265+ /**
 266+ * Checks whether gadget list from cache can be used.
 267+ * @return Boolean
 268+ */
 269+ private static function isValidList( $gadgets ) {
 270+ if ( !is_array( $gadgets ) ) return false;
 271+ // Check if we have 1) array of gadgets 2) the gadgets are up to date
 272+ // One check is enough
 273+ foreach ( $gadgets as $section => $list ) {
 274+ foreach ( $list as $g ) {
 275+ if ( !( $g instanceof Gadget ) || $g->isOutdated() ) {
 276+ return false;
 277+ } else {
 278+ return true;
 279+ }
 280+ }
 281+ }
 282+ return true; // empty array
 283+ }
 284+
 285+ /**
 286+ * Loads list of gadgets and returns it as associative array of sections with gadgets
 287+ * e.g. array( 'sectionnname1' => array( $gadget1, $gadget2),
 288+ * 'sectionnname2' => array( $gadget3 ) );
 289+ * @param $forceNewText String: New text of MediaWiki:gadgets-sdefinition. If specified, will
 290+ * force a purge of cache and recreation of the gadget list.
 291+ * @return Mixed: Array or false
 292+ */
 293+ public static function loadStructuredList( $forceNewText = null ) {
 294+ global $wgMemc;
 295+
 296+ static $gadgets = null;
 297+ if ( $gadgets !== null && $forceNewText === null ) return $gadgets;
 298+
 299+ wfProfileIn( __METHOD__ );
 300+ $key = wfMemcKey( 'gadgets-definition', self::GADGET_CLASS_VERSION );
 301+
 302+ if ( $forceNewText === null ) {
 303+ //cached?
 304+ $gadgets = $wgMemc->get( $key );
 305+ if ( self::isValidList( $gadgets ) ) {
 306+ wfProfileOut( __METHOD__ );
 307+ return $gadgets;
 308+ }
 309+
 310+ $g = wfMsgForContentNoTrans( "gadgets-definition" );
 311+ if ( wfEmptyMsg( "gadgets-definition", $g ) ) {
 312+ $gadgets = false;
 313+ wfProfileOut( __METHOD__ );
 314+ return $gadgets;
 315+ }
 316+ } else {
 317+ $g = $forceNewText;
 318+ }
 319+
 320+ $g = preg_replace( '/<!--.*-->/s', '', $g );
 321+ $g = preg_split( '/(\r\n|\r|\n)+/', $g );
 322+
 323+ $gadgets = array();
 324+ $section = '';
 325+
 326+ foreach ( $g as $line ) {
 327+ $m = array();
 328+ if ( preg_match( '/^==+ *([^*:\s|]+?)\s*==+\s*$/', $line, $m ) ) {
 329+ $section = $m[1];
 330+ }
 331+ else {
 332+ $gadget = self::newFromDefinition( $line );
 333+ if ( $gadget ) {
 334+ $gadgets[$section][$gadget->getName()] = $gadget;
 335+ $gadget->category = $section;
 336+ }
 337+ }
 338+ }
 339+
 340+ //cache for a while. gets purged automatically when MediaWiki:Gadgets-definition is edited
 341+ $wgMemc->set( $key, $gadgets, 60*60*24 );
 342+ $source = $forceNewText !== null ? 'input text' : 'MediaWiki:Gadgets-definition';
 343+ wfDebug( __METHOD__ . ": $source parsed, cache entry $key updated\n");
 344+ wfProfileOut( __METHOD__ );
 345+
 346+ return $gadgets;
 347+ }
 348+}
\ No newline at end of file
Property changes on: branches/Gadgets3.0/backend/Gadget.php
___________________________________________________________________
Added: svn:eol-style
1349 + native
Index: branches/Gadgets3.0/backend/GadgetHooks.php
@@ -0,0 +1,184 @@
 2+<?php
 3+/**
 4+ * Gadgets extension - lets users select custom javascript gadgets
 5+ *
 6+ *
 7+ * For more info see http://mediawiki.org/wiki/Extension:Gadgets
 8+ *
 9+ * @file
 10+ * @ingroup Extensions
 11+ * @author Daniel Kinzler, brightbyte.de
 12+ * @copyright © 2007 Daniel Kinzler
 13+ * @license GNU General Public Licence 2.0 or later
 14+ */
 15+
 16+class GadgetHooks {
 17+
 18+ /**
 19+ * ArticleSaveComplete hook handler.
 20+ *
 21+ * @param $article Article
 22+ * @param $user User
 23+ * @param $text String: New page text
 24+ */
 25+ public static function articleSaveComplete( $article, $user, $text ) {
 26+ //update cache if MediaWiki:Gadgets-definition was edited
 27+ $title = $article->mTitle;
 28+ if( $title->getNamespace() == NS_MEDIAWIKI && $title->getText() == 'Gadgets-definition' ) {
 29+ Gadget::loadStructuredList( $text );
 30+ }
 31+ return true;
 32+ }
 33+
 34+ /**
 35+ * GetPreferences hook handler.
 36+ * @param $user User
 37+ * @param $preferences Array: Preference descriptions
 38+ */
 39+ public static function getPreferences( $user, &$preferences ) {
 40+ $gadgets = Gadget::loadStructuredList();
 41+ if (!$gadgets) return true;
 42+
 43+ $options = array();
 44+ $default = array();
 45+ foreach( $gadgets as $section => $thisSection ) {
 46+ $available = array();
 47+ foreach( $thisSection as $gadget ) {
 48+ if ( $gadget->isAllowed( $user ) ) {
 49+ $gname = $gadget->getName();
 50+ $available[$gadget->getDescription()] = $gname;
 51+ if ( $gadget->isEnabled( $user ) ) {
 52+ $default[] = $gname;
 53+ }
 54+ }
 55+ }
 56+ if ( $section !== '' ) {
 57+ $section = wfMsgExt( "gadget-section-$section", 'parseinline' );
 58+ if ( count ( $available ) ) {
 59+ $options[$section] = $available;
 60+ }
 61+ } else {
 62+ $options = array_merge( $options, $available );
 63+ }
 64+ }
 65+
 66+ $preferences['gadgets-intro'] =
 67+ array(
 68+ 'type' => 'info',
 69+ 'label' => '&#160;',
 70+ 'default' => Xml::tags( 'tr', array(),
 71+ Xml::tags( 'td', array( 'colspan' => 2 ),
 72+ wfMsgExt( 'gadgets-prefstext', 'parse' ) ) ),
 73+ 'section' => 'gadgets',
 74+ 'raw' => 1,
 75+ 'rawrow' => 1,
 76+ );
 77+
 78+ $preferences['gadgets'] =
 79+ array(
 80+ 'type' => 'multiselect',
 81+ 'options' => $options,
 82+ 'section' => 'gadgets',
 83+ 'label' => '&#160;',
 84+ 'prefix' => 'gadget-',
 85+ 'default' => $default,
 86+ );
 87+
 88+ return true;
 89+ }
 90+
 91+ /**
 92+ * ResourceLoaderRegisterModules hook handler.
 93+ * @param $resourceLoader ResourceLoader
 94+ */
 95+ public static function registerModules( &$resourceLoader ) {
 96+ $gadgets = Gadget::loadList();
 97+ if ( !$gadgets ) {
 98+ return true;
 99+ }
 100+ foreach ( $gadgets as $g ) {
 101+ $module = $g->getModule();
 102+ if ( $module ) {
 103+ $resourceLoader->register( $g->getModuleName(), $module );
 104+ }
 105+ }
 106+ return true;
 107+ }
 108+
 109+ /**
 110+ * BeforePageDisplay hook handler.
 111+ * @param $out OutputPage
 112+ */
 113+ public static function beforePageDisplay( $out ) {
 114+ global $wgUser;
 115+
 116+ wfProfileIn( __METHOD__ );
 117+
 118+ $gadgets = Gadget::loadList();
 119+ if ( !$gadgets ) {
 120+ wfProfileOut( __METHOD__ );
 121+ return true;
 122+ }
 123+
 124+ $lb = new LinkBatch();
 125+ $lb->setCaller( __METHOD__ );
 126+ $pages = array();
 127+
 128+ foreach ( $gadgets as $gadget ) {
 129+ if ( $gadget->isEnabled( $wgUser ) && $gadget->isAllowed( $wgUser ) ) {
 130+ if ( $gadget->hasModule() ) {
 131+ $out->addModules( $gadget->getModuleName() );
 132+ }
 133+ foreach ( $gadget->getLegacyScripts() as $page ) {
 134+ $lb->add( NS_MEDIAWIKI, $page );
 135+ $pages[] = $page;
 136+ }
 137+ }
 138+ }
 139+
 140+ $lb->execute( __METHOD__ );
 141+
 142+ $done = array();
 143+ foreach ( $pages as $page ) {
 144+ if ( isset( $done[$page] ) ) continue;
 145+ $done[$page] = true;
 146+ self::applyScript( $page, $out );
 147+ }
 148+ wfProfileOut( __METHOD__ );
 149+
 150+ return true;
 151+ }
 152+
 153+ /**
 154+ * Adds one legacy script to output.
 155+ *
 156+ * @param $page String: Unprefixed page title
 157+ * @param $out OutputPage
 158+ */
 159+ private static function applyScript( $page, $out ) {
 160+ global $wgJsMimeType;
 161+
 162+ # bug 22929: disable gadgets on sensitive pages. Scripts loaded through the
 163+ # ResourceLoader handle this in OutputPage::getModules()
 164+ # TODO: make this extension load everything via RL, then we don't need to worry
 165+ # about any of this.
 166+ if( $out->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS ) < ResourceLoaderModule::ORIGIN_USER_SITEWIDE ){
 167+ return;
 168+ }
 169+
 170+ $t = Title::makeTitleSafe( NS_MEDIAWIKI, $page );
 171+ if ( !$t ) return;
 172+
 173+ $u = $t->getLocalURL( 'action=raw&ctype=' . $wgJsMimeType );
 174+ $out->addScriptFile( $u, $t->getLatestRevID() );
 175+ }
 176+
 177+ /**
 178+ * UnitTestsList hook handler
 179+ * @param $files Array: List of extension test files
 180+ */
 181+ public static function unitTestsList( $files ) {
 182+ $files[] = dirname( __FILE__ ) . '/Gadgets_tests.php';
 183+ return true;
 184+ }
 185+}
Property changes on: branches/Gadgets3.0/backend/GadgetHooks.php
___________________________________________________________________
Added: svn:mergeinfo
1186 Merged /branches/Gadgets-work/Gadgets_body.php:r73145-76526
2187 Merged /branches/wmf/1.17wmf1/extensions/Gadgets/Gadgets_body.php:r81884
Added: svn:eol-style
3188 + native
Added: svn:keywords
4189 + LastChangedDate LastChangedRevision
Index: branches/Gadgets3.0/ui/GadgetsView.php
@@ -0,0 +1,25 @@
 2+<?php
 3+
 4+abstract class GadgetsView {
 5+ protected $parent,
 6+ $params;
 7+
 8+ public function __construct( SpecialGadgets $parent, $params ) {
 9+ $this->parent = $parent;
 10+ $this->params = $params;
 11+ }
 12+
 13+ public abstract function execute();
 14+
 15+ public function post() {
 16+ }
 17+
 18+ /**
 19+ * @return Message
 20+ */
 21+ public abstract function getTitle();
 22+
 23+ protected function getContext() {
 24+ return $this->parent->getContext();
 25+ }
 26+}
\ No newline at end of file
Property changes on: branches/Gadgets3.0/ui/GadgetsView.php
___________________________________________________________________
Added: svn:eol-style
127 + native
Index: branches/Gadgets3.0/ui/ExportGadgetsView.php
Property changes on: branches/Gadgets3.0/ui/ExportGadgetsView.php
___________________________________________________________________
Added: svn:eol-style
228 + native
Index: branches/Gadgets3.0/ui/MainGadgetsView.php
@@ -0,0 +1,100 @@
 2+<?php
 3+
 4+class MainGadgetsView extends GadgetsView {
 5+ public function __construct( SpecialGadgets $parent ) {
 6+ parent::__construct( $parent, array() );
 7+ }
 8+
 9+ public function execute() {
 10+ global $wgOut, $wgUser, $wgLang, $wgContLang;
 11+
 12+ $skin = $wgUser->getSkin();
 13+
 14+ $wgOut->addWikiMsg( 'gadgets-pagetext' );
 15+
 16+ $gadgets = Gadget::loadStructuredList();
 17+ if ( !$gadgets ) return;
 18+
 19+ $lang = "";
 20+ if ( $wgLang->getCode() != $wgContLang->getCode() ) {
 21+ $lang = "/" . $wgLang->getCode();
 22+ }
 23+
 24+ $listOpen = false;
 25+
 26+ $msgOpt = array( 'parseinline', 'parsemag' );
 27+ $editInterfaceAllowed = $wgUser->isAllowed( 'editinterface' );
 28+
 29+ foreach ( $gadgets as $section => $entries ) {
 30+ if ( $section !== false && $section !== '' ) {
 31+ $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-section-$section$lang" );
 32+ if ( $editInterfaceAllowed ) {
 33+ $lnkTarget = $t
 34+ ? $skin->link( $t, wfMsgHTML( 'edit' ), array(), array( 'action' => 'edit' ) )
 35+ : htmlspecialchars( $section );
 36+ $lnk = "&#160; &#160; [$lnkTarget]";
 37+ } else {
 38+ $lnk = '';
 39+ }
 40+ $ttext = wfMsgExt( "gadget-section-$section", $msgOpt );
 41+
 42+ if( $listOpen ) {
 43+ $wgOut->addHTML( Xml::closeElement( 'ul' ) . "\n" );
 44+ $listOpen = false;
 45+ }
 46+ $wgOut->addHTML( Html::rawElement( 'h2', array(), $ttext . $lnk ) . "\n" );
 47+ }
 48+
 49+ foreach ( $entries as $gadget ) {
 50+ $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-{$gadget->getName()}$lang" );
 51+ if ( !$t ) continue;
 52+
 53+ $links = array();
 54+ if ( $editInterfaceAllowed ) {
 55+ $links[] = $skin->link( $t, wfMsgHTML( 'edit' ), array(), array( 'action' => 'edit' ) );
 56+ }
 57+ $links[] = $skin->link( $this->getTitle( "export/{$gadget->getName()}" ), wfMsgHtml( 'gadgets-export' ) );
 58+
 59+ $ttext = wfMsgExt( "gadget-{$gadget->getName()}", $msgOpt );
 60+
 61+ if( !$listOpen ) {
 62+ $listOpen = true;
 63+ $wgOut->addHTML( Xml::openElement( 'ul' ) );
 64+ }
 65+ $lnk = '&#160;&#160;' . wfMsg( 'parentheses', $wgLang->pipeList( $links ) );
 66+ $wgOut->addHTML( Xml::openElement( 'li' ) .
 67+ $ttext . $lnk . "<br />" .
 68+ wfMsgHTML( 'gadgets-uses' ) . wfMsg( 'colon-separator' )
 69+ );
 70+
 71+ $lnk = array();
 72+ foreach ( $gadget->getScriptsAndStyles() as $codePage ) {
 73+ $t = Title::makeTitleSafe( NS_MEDIAWIKI, $codePage );
 74+ if ( !$t ) continue;
 75+
 76+ $lnk[] = $skin->link( $t, htmlspecialchars( $t->getText() ) );
 77+ }
 78+ $wgOut->addHTML( $wgLang->commaList( $lnk ) );
 79+ $rights = $gadget->getRequiredRights();
 80+ if ( count( $rights ) ) {
 81+ $wgOut->addHTML( '<br />' .
 82+ wfMessage( 'gadgets-required-rights', $wgLang->commaList( $rights ), count( $rights ) )->parse()
 83+ );
 84+ }
 85+ if ( $gadget->isOnByDefault() ) {
 86+ $wgOut->addHTML( '<br />' . wfMessage( 'gadgets-default' )->parse() );
 87+ }
 88+
 89+ $wgOut->addHTML( Xml::closeElement( 'li' ) . "\n" );
 90+ }
 91+ }
 92+
 93+ if( $listOpen ) {
 94+ $wgOut->addHTML( Xml::closeElement( 'ul' ) . "\n" );
 95+ }
 96+ }
 97+
 98+ public function getTitle() {
 99+ return wfMessage( 'gadgets-title' );
 100+ }
 101+}
\ No newline at end of file
Property changes on: branches/Gadgets3.0/ui/MainGadgetsView.php
___________________________________________________________________
Added: svn:eol-style
1102 + native
Index: branches/Gadgets3.0/ui/SpecialGadgets.php
@@ -31,137 +31,19 @@
3232 * @param $par Parameters passed to the page
3333 */
3434 function execute( $par ) {
35 - $parts = explode( '/', $par );
36 - if ( count( $parts ) == 2 && $parts[0] == 'export' ) {
37 - $this->showExportForm( $parts[1] );
38 - } else {
39 - $this->showMainForm();
40 - }
41 - }
42 -
43 - /**
44 - * Displays form showing the list of installed gadgets
45 - */
46 - public function showMainForm() {
47 - global $wgOut, $wgUser, $wgLang, $wgContLang;
48 -
49 - $skin = $wgUser->getSkin();
50 -
 35+ // $parts = explode( '/', $par );
 36+ // if ( count( $parts ) == 2 && $parts[0] == 'export' ) {
 37+ // $this->showExportForm( $parts[1] );
 38+ // } else {
 39+ $view = new MainGadgetsView( $this );
 40+ // }
5141 $this->setHeaders();
52 - $wgOut->setPagetitle( wfMsg( "gadgets-title" ) );
53 - $wgOut->addWikiMsg( 'gadgets-pagetext' );
 42+ $this->getContext()->getOutput()->setPageTitle( $view->getTitle()->text() );
5443
55 - $gadgets = Gadget::loadStructuredList();
56 - if ( !$gadgets ) return;
57 -
58 - $lang = "";
59 - if ( $wgLang->getCode() != $wgContLang->getCode() ) {
60 - $lang = "/" . $wgLang->getCode();
 44+ if ( $this->getContext()->getRequest()->wasPosted() ) {
 45+ $view->post();
 46+ } else {
 47+ $view->execute();
6148 }
62 -
63 - $listOpen = false;
64 -
65 - $msgOpt = array( 'parseinline', 'parsemag' );
66 - $editInterfaceAllowed = $wgUser->isAllowed( 'editinterface' );
67 -
68 - foreach ( $gadgets as $section => $entries ) {
69 - if ( $section !== false && $section !== '' ) {
70 - $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-section-$section$lang" );
71 - if ( $editInterfaceAllowed ) {
72 - $lnkTarget = $t
73 - ? $skin->link( $t, wfMsgHTML( 'edit' ), array(), array( 'action' => 'edit' ) )
74 - : htmlspecialchars( $section );
75 - $lnk = "&#160; &#160; [$lnkTarget]";
76 - } else {
77 - $lnk = '';
78 - }
79 - $ttext = wfMsgExt( "gadget-section-$section", $msgOpt );
80 -
81 - if( $listOpen ) {
82 - $wgOut->addHTML( Xml::closeElement( 'ul' ) . "\n" );
83 - $listOpen = false;
84 - }
85 - $wgOut->addHTML( Html::rawElement( 'h2', array(), $ttext . $lnk ) . "\n" );
86 - }
87 -
88 - foreach ( $entries as $gadget ) {
89 - $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-{$gadget->getName()}$lang" );
90 - if ( !$t ) continue;
91 -
92 - $links = array();
93 - if ( $editInterfaceAllowed ) {
94 - $links[] = $skin->link( $t, wfMsgHTML( 'edit' ), array(), array( 'action' => 'edit' ) );
95 - }
96 - $links[] = $skin->link( $this->getTitle( "export/{$gadget->getName()}" ), wfMsgHtml( 'gadgets-export' ) );
97 -
98 - $ttext = wfMsgExt( "gadget-{$gadget->getName()}", $msgOpt );
99 -
100 - if( !$listOpen ) {
101 - $listOpen = true;
102 - $wgOut->addHTML( Xml::openElement( 'ul' ) );
103 - }
104 - $lnk = '&#160;&#160;' . wfMsg( 'parentheses', $wgLang->pipeList( $links ) );
105 - $wgOut->addHTML( Xml::openElement( 'li' ) .
106 - $ttext . $lnk . "<br />" .
107 - wfMsgHTML( 'gadgets-uses' ) . wfMsg( 'colon-separator' )
108 - );
109 -
110 - $lnk = array();
111 - foreach ( $gadget->getScriptsAndStyles() as $codePage ) {
112 - $t = Title::makeTitleSafe( NS_MEDIAWIKI, $codePage );
113 - if ( !$t ) continue;
114 -
115 - $lnk[] = $skin->link( $t, htmlspecialchars( $t->getText() ) );
116 - }
117 - $wgOut->addHTML( $wgLang->commaList( $lnk ) );
118 - $rights = $gadget->getRequiredRights();
119 - if ( count( $rights ) ) {
120 - $wgOut->addHTML( '<br />' .
121 - wfMessage( 'gadgets-required-rights', $wgLang->commaList( $rights ), count( $rights ) )->parse()
122 - );
123 - }
124 - if ( $gadget->isOnByDefault() ) {
125 - $wgOut->addHTML( '<br />' . wfMessage( 'gadgets-default' )->parse() );
126 - }
127 -
128 - $wgOut->addHTML( Xml::closeElement( 'li' ) . "\n" );
129 - }
130 - }
131 -
132 - if( $listOpen ) {
133 - $wgOut->addHTML( Xml::closeElement( 'ul' ) . "\n" );
134 - }
13549 }
136 -
137 - /**
138 - * Exports a gadget with its dependencies in a serialized form
139 - * @param $gadget String Name of gadget to export
140 - */
141 - public function showExportForm( $gadget ) {
142 - global $wgOut, $wgScript;
143 -
144 - $gadgets = Gadget::loadList();
145 - if ( !isset( $gadgets[$gadget] ) ) {
146 - $wgOut->showErrorPage( 'error', 'gadgets-not-found', array( $gadget ) );
147 - return;
148 - }
149 -
150 - $g = $gadgets[$gadget];
151 - $this->setHeaders();
152 - $wgOut->setPagetitle( wfMsg( "gadgets-export-title" ) );
153 - $wgOut->addWikiMsg( 'gadgets-export-text', $gadget, $g->getDefinition() );
154 -
155 - $exportList = "MediaWiki:gadget-$gadget\n";
156 - foreach ( $g->getScriptsAndStyles() as $page ) {
157 - $exportList .= "MediaWiki:$page\n";
158 - }
159 -
160 - $wgOut->addHTML( Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) )
161 - . Html::hidden( 'title', SpecialPage::getTitleFor( 'Export' )->getPrefixedDBKey() )
162 - . Html::hidden( 'pages', $exportList )
163 - . Html::hidden( 'wpDownload', '1' )
164 - . Xml::submitButton( wfMsg( 'gadgets-export-download' ) )
165 - . Html::closeElement( 'form' )
166 - );
167 - }
16850 }

Status & tagging log