Index: branches/RL2/extensions/Gadgets/Gadgets.hooks.php |
— | — | @@ -262,15 +262,21 @@ |
263 | 263 | ); |
264 | 264 | |
265 | 265 | // This loop adds the preferences for all gadgets, both local and remote |
| 266 | + // We want to use gadget IDs in HTMLForm IDs and repo and category IDs |
| 267 | + // in section IDs, but because certain characters are restricted |
| 268 | + // (HTMLForm will barf on anything that's not a valid HTML ID, section IDs will |
| 269 | + // get confused when dashes or slashes are added), we encode these things as hex |
| 270 | + // so we know for sure they don't contain weird characters and are easy to decode |
266 | 271 | $repos = GadgetRepo::getAllRepos(); |
267 | 272 | foreach ( $repos as $repo ) { |
268 | | - $repoSource = $repo->getSource(); |
| 273 | + $encRepoSource = bin2hex( $repo->getSource() ); |
269 | 274 | $byCategory = $repo->getGadgetsByCategory(); |
270 | 275 | ksort( $byCategory ); |
271 | 276 | foreach ( $byCategory as $category => $gadgets ) { |
| 277 | + $encCategory = bin2hex( $category ); |
272 | 278 | foreach ( $gadgets as $gadget ) { |
273 | 279 | $id = $gadget->getId(); |
274 | | - $sectionCat = $category === '' ? '' : "/gadgetcategory-$repoSource-$category"; |
| 280 | + $sectionCat = $category === '' ? '' : "/gadgetcategory-$encRepoSource-$encCategory"; |
275 | 281 | if ( $repo->isLocal() ) { |
276 | 282 | // For local gadgets we have all the information |
277 | 283 | $title = htmlspecialchars( $gadget->getTitleMessage() ); |
— | — | @@ -286,18 +292,15 @@ |
287 | 293 | 'label' => $text, |
288 | 294 | 'section' => "gadgets$sectionCat", |
289 | 295 | 'default' => $gadget->isEnabledForUser( $user ), |
290 | | - // HTMLForm is very strict about the names/IDs it accepts |
291 | | - // So specify a custom name that we know is safe and won't change |
292 | | - 'name' => 'gadgetpref-' . md5( $id ), |
| 296 | + 'name' => 'gadgetpref-' . bin2hex( $id ), |
293 | 297 | ); |
294 | 298 | } else { |
295 | 299 | $preferences["gadget-$id"] = array( |
296 | 300 | 'type' => 'toggle', |
297 | 301 | 'label' => htmlspecialchars( $id ), // will be changed by JS |
298 | | - // TODO the below means source and category IDs can't contain slashes or dashes, enforce this |
299 | | - 'section' => "gadgetsshared/gadgetrepo-$repoSource$sectionCat", |
| 302 | + 'section' => "gadgetsshared/gadgetrepo-$encRepoSource$sectionCat", |
300 | 303 | 'cssclass' => 'mw-gadgets-shared-pref', |
301 | | - 'name' => 'gadgetpref-' . md5( $id ), |
| 304 | + 'name' => 'gadgetpref-' . bin2hex( $id ), |
302 | 305 | // 'default' isn't in here by design: we don't want |
303 | 306 | // enabledByDefault to be honored across wikis |
304 | 307 | ); |
— | — | @@ -311,10 +314,12 @@ |
312 | 315 | |
313 | 316 | public static function preferencesGetLegend( $form, $key, &$legend ) { |
314 | 317 | $matches = null; |
315 | | - if ( preg_match( '/^(gadgetrepo|gadgetcategory-.*?)-(.*)$/', $key, $matches ) ) { |
| 318 | + if ( preg_match( '/^(gadgetrepo|gadgetcategory-[A-Za-z0-9]*)-([A-Za-z0-9]*)$/', $key, $matches ) ) { |
| 319 | + // Decode the category ID |
| 320 | + $catID = pack( "H*", $matches[2] ); // PHP doesn't have hex2bin() yet |
316 | 321 | // Just display the ID itself (with ucfirst applied) |
317 | 322 | // This will be changed to a properly i18ned string by JS |
318 | | - $legend = $form->getLang()->ucfirst( $matches[2] ); |
| 323 | + $legend = $form->getLang()->ucfirst( $catID ); |
319 | 324 | } |
320 | 325 | return true; |
321 | 326 | } |