Index: trunk/extensions/AdminLinks/AdminLinks.php |
— | — | @@ -0,0 +1,32 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * A special page holding special convenience links for sysops |
| 5 | + * |
| 6 | + * @author Yaron Koren |
| 7 | + */ |
| 8 | + |
| 9 | +if (!defined('MEDIAWIKI')) die(); |
| 10 | + |
| 11 | +// credits |
| 12 | +$wgExtensionCredits['specialpage'][] = array( |
| 13 | + 'name' => 'Admin Links', |
| 14 | + 'version' => '0.1', |
| 15 | + 'author' => 'Yaron Koren', |
| 16 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:Admin_Links', |
| 17 | + 'description' => 'A special page that holds helpful links for administrators', |
| 18 | + 'descriptionmsg' => 'adminlinks-desc', |
| 19 | +); |
| 20 | + |
| 21 | +$wgAdminLinksIP = dirname(__FILE__) . '/'; |
| 22 | +$wgExtensionMessagesFiles['AdminLinks'] = $wgAdminLinksIP . 'AdminLinks.i18n.php'; |
| 23 | +$wgSpecialPages['AdminLinks'] = array('AdminLinks', 'adminlinks'); |
| 24 | +$wgHooks['PersonalUrls'][] = 'AdminLinks::addURLToUserLinks'; |
| 25 | +$wgAvailableRights[] = 'adminlinks'; |
| 26 | +// by default, sysops see the link to this page |
| 27 | +$wgGroupPermissions['sysop']['adminlinks'] = true; |
| 28 | +$wgAutoloadClasses['AdminLinks'] |
| 29 | + = $wgAutoloadClasses['ALTree'] |
| 30 | + = $wgAutoloadClasses['ALSection'] |
| 31 | + = $wgAutoloadClasses['ALRow'] |
| 32 | + = $wgAutoloadClasses['ALItem'] |
| 33 | + = "$wgAdminLinksIP/AdminLinks_body.php"; |
Index: trunk/extensions/AdminLinks/AdminLinks_body.php |
— | — | @@ -0,0 +1,282 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Classes for the Admin Links extension |
| 5 | + * |
| 6 | + * @author Yaron Koren |
| 7 | + */ |
| 8 | + |
| 9 | +if (!defined('MEDIAWIKI')) die(); |
| 10 | + |
| 11 | +class AdminLinks extends SpecialPage { |
| 12 | + |
| 13 | + var $skin; |
| 14 | + |
| 15 | + /** |
| 16 | + * Constructor |
| 17 | + */ |
| 18 | + function AdminLinks() { |
| 19 | + SpecialPage::SpecialPage('AdminLinks'); |
| 20 | + wfLoadExtensionMessages('AdminLinks'); |
| 21 | + global $wgUser; |
| 22 | + $this->skin = $wgUser->getSkin(); |
| 23 | + } |
| 24 | + |
| 25 | + function createInitialTree() { |
| 26 | + $tree = new ALTree(); |
| 27 | + |
| 28 | + // 'general' section |
| 29 | + $general_section = new ALSection(wfMsg('adminlinks_general')); |
| 30 | + $main_row = new ALRow('main'); |
| 31 | + $main_row->addItem(ALItem::newFromSpecialPage('Specialpages')); |
| 32 | + $main_row->addItem(ALItem::newFromSpecialPage('Allmessages')); |
| 33 | + $main_row->addItem(ALItem::newFromEditLink('Sidebar', wfMsg('adminlinks_sidebar'))); |
| 34 | + $main_row->addItem(ALItem::newFromEditLink('Common.css', wfMsg('adminlinks_cssfile'))); |
| 35 | + $main_row->addItem(ALItem::newFromEditLink('Mainpage', wfMsg('adminlinks_mainpagename'))); |
| 36 | + $general_section->addRow($main_row); |
| 37 | + $tree->addSection($general_section); |
| 38 | + |
| 39 | + // 'users' section |
| 40 | + $users_section = new ALSection(wfMsg('adminlinks_users')); |
| 41 | + $main_row = new ALRow('main'); |
| 42 | + $main_row->addItem(ALItem::newFromSpecialPage('Listusers')); |
| 43 | + $ul = SpecialPage::getPage('Userlogin'); |
| 44 | + $main_row->addItem(AlItem::newFromPage($ul->getTitle(), wfMsg('adminlinks_createuser'), 'type=signup&returnto=Special:HelpfulLinks')); |
| 45 | + $main_row->addItem(ALItem::newFromSpecialPage('Userrights')); |
| 46 | + $users_section->addRow($main_row); |
| 47 | + $tree->addSection($users_section); |
| 48 | + |
| 49 | + // 'browsing and searching' section |
| 50 | + $browse_search_section = new ALSection(wfMsg('adminlinks_browsesearch')); |
| 51 | + $main_row = new ALRow('main'); |
| 52 | + $main_row->addItem(ALItem::newFromSpecialPage('Allpages')); |
| 53 | + $main_row->addItem(ALItem::newFromSpecialPage('Search')); |
| 54 | + $browse_search_section->addRow($main_row); |
| 55 | + $tree->addSection($browse_search_section); |
| 56 | + |
| 57 | + // 'importing and exporting' section |
| 58 | + $import_export_section = new ALSection(wfMsg('adminlinks_importexport')); |
| 59 | + $main_row = new ALRow('main'); |
| 60 | + $main_row->addItem(ALItem::newFromSpecialPage('Export')); |
| 61 | + $main_row->addItem(ALItem::newFromSpecialPage('Import')); |
| 62 | + $import_export_section->addRow($main_row); |
| 63 | + $tree->addSection($import_export_section); |
| 64 | + |
| 65 | + return $tree; |
| 66 | + } |
| 67 | + |
| 68 | + function execute() { |
| 69 | + $this->setHeaders(); |
| 70 | + $admin_links_tree = $this->createInitialTree(); |
| 71 | + wfRunHooks( 'AdminLinks', array( &$admin_links_tree ) ); |
| 72 | + global $wgOut; |
| 73 | + $wgOut->addHTML($admin_links_tree->toString()); |
| 74 | + } |
| 75 | + |
| 76 | + /** |
| 77 | + * For administrators, add a link to the special 'AdminLinks' page |
| 78 | + * among the user's "personal URLs" at the top, if they have |
| 79 | + * the 'adminlinks' permission |
| 80 | + */ |
| 81 | + function addURLToUserLinks(&$personal_urls, &$title) { |
| 82 | + global $wgUser; |
| 83 | + // if user is a sysop, add link |
| 84 | + if ($wgUser->isAllowed('adminlinks')) { |
| 85 | + wfLoadExtensionMessages('AdminLinks'); |
| 86 | + $al = SpecialPage::getTitleFor( 'AdminLinks' ); |
| 87 | + $href = $al->getLocalURL(); |
| 88 | + $admin_links_vals = array( |
| 89 | + 'text' => wfMsg('adminlinks'), |
| 90 | + 'href' => $href, |
| 91 | + 'active' => ( $href == $title->getLocalURL() ) |
| 92 | + ); |
| 93 | + // find the location of the 'my preferences' link, and |
| 94 | + // add the link to 'AdminLinks' right before it. |
| 95 | + // this is a "key-safe" splice - it preserves both the |
| 96 | + // keys and the values of the array, by editing them |
| 97 | + // separately and then rebuilding the array. |
| 98 | + // based on the example at http://us2.php.net/manual/en/function.array-splice.php#31234 |
| 99 | + $tab_keys = array_keys($personal_urls); |
| 100 | + $tab_values = array_values($personal_urls); |
| 101 | + $prefs_location = array_search('preferences', $tab_keys); |
| 102 | + array_splice($tab_keys, $prefs_location, 0, 'adminlinks'); |
| 103 | + array_splice($tab_values, $prefs_location, 0, array($admin_links_vals)); |
| 104 | + $personal_urls = array(); |
| 105 | + for ($i = 0; $i < count($tab_keys); $i++) |
| 106 | + $personal_urls[$tab_keys[$i]] = $tab_values[$i]; |
| 107 | + |
| 108 | + } |
| 109 | + return true; |
| 110 | + } |
| 111 | +} |
| 112 | + |
| 113 | +/** |
| 114 | + * The 'tree' that holds all the sections, rows, and links for the AdminLinks |
| 115 | + * page |
| 116 | + */ |
| 117 | +class ALTree { |
| 118 | + var $sections; |
| 119 | + |
| 120 | + function ALTree() { |
| 121 | + $this->sections = array(); |
| 122 | + } |
| 123 | + |
| 124 | + function getSection($section_header) { |
| 125 | + foreach ($this->sections as $cur_section) { |
| 126 | + if ($cur_section->header === $section_header) { |
| 127 | + return $cur_section; |
| 128 | + } |
| 129 | + } |
| 130 | + return null; |
| 131 | + } |
| 132 | + |
| 133 | + function addSection($section, $next_section_header = null) { |
| 134 | + if ($next_section_header == null) { |
| 135 | + $this->sections[] = $section; |
| 136 | + return; |
| 137 | + } |
| 138 | + foreach ($this->sections as $i => $cur_section) { |
| 139 | + if ($cur_section->header === $next_section_header) { |
| 140 | + array_splice($this->sections, $i, 0, array($section)); |
| 141 | + return; |
| 142 | + } |
| 143 | + } |
| 144 | + $this->sections[] = $section; |
| 145 | + } |
| 146 | + |
| 147 | + function toString() { |
| 148 | + $text = ""; |
| 149 | + foreach ($this->sections as $section) { |
| 150 | + $text .= $section->toString(); |
| 151 | + } |
| 152 | + return $text; |
| 153 | + } |
| 154 | +} |
| 155 | + |
| 156 | +/** |
| 157 | + * A single section of the Admin Links 'tree', composed of a header and rows |
| 158 | + */ |
| 159 | +class ALSection { |
| 160 | + var $header; |
| 161 | + var $rows; |
| 162 | + |
| 163 | + function ALSection($header) { |
| 164 | + $this->header = $header; |
| 165 | + $this->rows = array(); |
| 166 | + } |
| 167 | + |
| 168 | + function getRow($row_name) { |
| 169 | + foreach ($this->rows as $cur_row) { |
| 170 | + if ($cur_row->name === $row_name) { |
| 171 | + return $cur_row; |
| 172 | + } |
| 173 | + } |
| 174 | + return null; |
| 175 | + } |
| 176 | + |
| 177 | + function addRow($row, $next_row_name = null) { |
| 178 | + if ($next_row_name == null) { |
| 179 | + $this->rows[] = $row; |
| 180 | + return; |
| 181 | + } |
| 182 | + foreach ($this->rows as $i => $cur_row) { |
| 183 | + if ($cur_row->name === $next_row_name) { |
| 184 | + array_splice($this->rows, $i, 0, array($row)); |
| 185 | + return; |
| 186 | + } |
| 187 | + } |
| 188 | + $this->rows[] = $row; |
| 189 | + } |
| 190 | + |
| 191 | + function toString() { |
| 192 | + $text = ' <h4 class="mw-specialpagesgroup">' . $this->header . "</h4>\n"; |
| 193 | + foreach ($this->rows as $row) { |
| 194 | + $text .= $row->toString(); |
| 195 | + } |
| 196 | + return $text; |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +/** |
| 201 | + * A single row of the AdminLinks page, with a name (not displayed, used only |
| 202 | + * for organizing the rows), and a set of "items" (links) |
| 203 | + */ |
| 204 | +class ALRow { |
| 205 | + var $name; |
| 206 | + var $items; |
| 207 | + |
| 208 | + function ALRow($name) { |
| 209 | + $this->name = $name; |
| 210 | + $this->items = array(); |
| 211 | + } |
| 212 | + |
| 213 | + function addItem($item, $next_item_label = null) { |
| 214 | + if ($next_item_label == null) { |
| 215 | + $this->items[] = $item; |
| 216 | + return; |
| 217 | + } |
| 218 | + foreach ($this->items as $i => $cur_item) { |
| 219 | + if ($cur_item->label === $next_item_label) { |
| 220 | + array_splice($this->items, $i, 0, array($item)); |
| 221 | + return; |
| 222 | + } |
| 223 | + } |
| 224 | + $this->items[] = $item; |
| 225 | + } |
| 226 | + |
| 227 | + function toString() { |
| 228 | + $text = " <p>\n"; |
| 229 | + foreach ($this->items as $i => $item) { |
| 230 | + if ($i > 0) |
| 231 | + $text .= " ·\n"; |
| 232 | + $text .= ' ' . $item->text; |
| 233 | + } |
| 234 | + return $text . "\n </p>\n"; |
| 235 | + } |
| 236 | +} |
| 237 | + |
| 238 | +/** |
| 239 | + * A single 'item' in the AdminLinks page, most likely representing a link |
| 240 | + * but also conceivably containing other text; also contains a label, which |
| 241 | + * is not displayed and is only used for organizational purposes. |
| 242 | + */ |
| 243 | +class ALItem { |
| 244 | + var $text; |
| 245 | + var $label; |
| 246 | + |
| 247 | + function newFromPage($page_name, $desc = null, $params = null) { |
| 248 | + $item = new ALItem(); |
| 249 | + $item->label = $desc; |
| 250 | + if ($params != null) { |
| 251 | + global $wgUser; |
| 252 | + $item->text = $wgUser->getSkin()->makeKnownLinkObj($page_name, $desc, $params); |
| 253 | + } else |
| 254 | + $item->text = "[[$page_name|$desc]]"; |
| 255 | + return $item; |
| 256 | + } |
| 257 | + |
| 258 | + function newFromSpecialPage($page_name) { |
| 259 | + $item = new ALItem(); |
| 260 | + $item->label = $page_name; |
| 261 | + $page = SpecialPage::getPage($page_name); |
| 262 | + global $wgUser; |
| 263 | + $item->text = $wgUser->getSkin()->makeKnownLinkObj($page->getTitle(), $page->getDescription()); |
| 264 | + return $item; |
| 265 | + } |
| 266 | + |
| 267 | + function newFromEditLink($page_name, $desc) { |
| 268 | + $item = new ALItem(); |
| 269 | + $item->label = $page_name; |
| 270 | + $title = Title::makeTitleSafe(NS_MEDIAWIKI, $page_name); |
| 271 | + $edit_link = $title->getFullURL('action=edit'); |
| 272 | + $full_desc = wfMsg('adminlinks_edit', $desc); |
| 273 | + $item->text = "<a href=\"$edit_link\">$full_desc</a>"; |
| 274 | + return $item; |
| 275 | + } |
| 276 | + |
| 277 | + function newFromExternalLink($url, $label) { |
| 278 | + $item = new ALItem(); |
| 279 | + $item->label = $label; |
| 280 | + $item->text = "<a class=\"external text\" rel=\"nofollow\" href=\"$url\">$label</a>"; |
| 281 | + return $item; |
| 282 | + } |
| 283 | +} |
Index: trunk/extensions/AdminLinks/AdminLinks.i18n.php |
— | — | @@ -0,0 +1,28 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalization file for Admin Links |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Language |
| 8 | + * @ingroup I18n |
| 9 | + */ |
| 10 | + |
| 11 | +$messages = array(); |
| 12 | + |
| 13 | +/** English |
| 14 | + * @author Yaron Koren |
| 15 | + */ |
| 16 | +$messages['en'] = array( |
| 17 | + 'adminlinks' => 'Admin links', |
| 18 | + 'adminlinks_documentation' => '$1 documentation', |
| 19 | + 'adminlinks_edit' => 'Edit $1', |
| 20 | + 'adminlinks_general' => 'General', |
| 21 | + 'adminlinks_sidebar' => 'sidebar', |
| 22 | + 'adminlinks_cssfile' => 'CSS file', |
| 23 | + 'adminlinks_mainpagename' => 'name of main page', |
| 24 | + 'adminlinks_users' => 'Users', |
| 25 | + 'adminlinks_createuser' => 'Create a user', |
| 26 | + 'adminlinks_browsesearch' => 'Browsing and searching', |
| 27 | + 'adminlinks_importexport' => 'Importing and exporting', |
| 28 | +); |
| 29 | + |
Index: trunk/extensions/AdminLinks/README |
— | — | @@ -0,0 +1,42 @@ |
| 2 | +Admin Links extension |
| 3 | + |
| 4 | + Version 0.1 |
| 5 | + Yaron Koren |
| 6 | + |
| 7 | +This is free software licensed under the GNU General Public License. Please |
| 8 | +see http://www.gnu.org/copyleft/gpl.html for further details, including the |
| 9 | +full text and terms of the license. |
| 10 | + |
| 11 | +== Overview == |
| 12 | + |
| 13 | +Admin Links is an extension to MediaWiki that provides a new special page |
| 14 | +meant to hold links that are useful to an administrator; it attempts to |
| 15 | +function as a "control panel" for the actions that a wiki administrator |
| 16 | +typically has to perform. Any user can access this page, but for |
| 17 | +administrators a new link to this page is placed within their "navigation |
| 18 | +links" (between "my talk" and "my preferences"). |
| 19 | + |
| 20 | +Admin Links provides an API that other extensions can call in order to |
| 21 | +add their own sections and links to the page; links can be to both special |
| 22 | +pages and outside documentation URLs, among others. |
| 23 | + |
| 24 | +For more information, see the extension homepage at: |
| 25 | +http://www.mediawiki.org/wiki/Extension:Admin_Links |
| 26 | + |
| 27 | +== Requirements == |
| 28 | + |
| 29 | +This version of the Admin Links extension requires MediaWiki 1.8 or higher. |
| 30 | + |
| 31 | +== Installation == |
| 32 | + |
| 33 | +To install the extension, place the entire 'AdminLinks' directory |
| 34 | +within your MediaWiki 'extensions' directory, then add the following |
| 35 | +line to your 'LocalSettings.php' file: |
| 36 | + |
| 37 | + require_once( "$IP/extensions/AdminLinks/AdminLinks.php" ); |
| 38 | + |
| 39 | +== Contact == |
| 40 | + |
| 41 | +Comments, questions, suggestions and bug reports are welcome, and can |
| 42 | +be placed on the Talk page for the extension, or sent to Yaron at |
| 43 | +yaron57@gmail.com. |