Index: branches/new-installer/phase3/skins/common/config.js |
— | — | @@ -0,0 +1,96 @@ |
| 2 | + |
| 3 | +function showHelp(idx, show) { |
| 4 | + var showDiv = document.getElementById( 'config-show-help-' + idx ); |
| 5 | + var hideDiv = document.getElementById( 'config-hide-help-' + idx ); |
| 6 | + var msgDiv = document.getElementById( 'config-help-message-' + idx ); |
| 7 | + if ( !showDiv || !hideDiv || !msgDiv ) return; |
| 8 | + if ( show ) { |
| 9 | + showDiv.style.display = 'none'; |
| 10 | + hideDiv.style.display = 'block'; |
| 11 | + msgDiv.style.display = 'block'; |
| 12 | + } else { |
| 13 | + showDiv.style.display = 'block'; |
| 14 | + hideDiv.style.display = 'none'; |
| 15 | + msgDiv.style.display = 'none'; |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +function hideAllDBs() { |
| 20 | + for ( var i = 0; i < dbTypes.length; i++ ) { |
| 21 | + elt = document.getElementById( 'DB_wrapper_' + dbTypes[i] ); |
| 22 | + if ( elt ) elt.style.display = 'none'; |
| 23 | + } |
| 24 | +} |
| 25 | +function showDBArea(type) { |
| 26 | + hideAllDBs(); |
| 27 | + var div = document.getElementById('DB_wrapper_' + type); |
| 28 | + if (div) div.style.display = 'block'; |
| 29 | +} |
| 30 | +function resetDBArea() { |
| 31 | + for ( var i = 0; i < dbTypes.length; i++ ) { |
| 32 | + input = document.getElementById('DBType_' + dbTypes[i]); |
| 33 | + if ( input && input.checked ) { |
| 34 | + showDBArea( dbTypes[i] ); |
| 35 | + return; |
| 36 | + } |
| 37 | + } |
| 38 | +} |
| 39 | +function enableOrDisableControlArray( sourceID, targetIDs, enable ) { |
| 40 | + var source = document.getElementById( sourceID ); |
| 41 | + var disabled = !!source.checked == enable ? '' : '1'; |
| 42 | + if ( !source ) { |
| 43 | + return; |
| 44 | + } |
| 45 | + for ( var i = 0; i < targetIDs.length; i++ ) { |
| 46 | + var elt = document.getElementById( targetIDs[i] ); |
| 47 | + if ( elt ) elt.disabled = disabled; |
| 48 | + } |
| 49 | +} |
| 50 | +function enableControlArray( sourceID, targetIDs, enable ) { |
| 51 | + enableOrDisableControlArray( sourceID, targetIDs, true ); |
| 52 | +} |
| 53 | +function disableControlArray( sourceID, targetIDs ) { |
| 54 | + enableOrDisableControlArray( sourceID, targetIDs, false ); |
| 55 | +} |
| 56 | + |
| 57 | +function showControlArray( sourceID, targetIDs ) { |
| 58 | + var source = document.getElementById( sourceID ); |
| 59 | + var show = !!source.checked == false ? '' : '1'; |
| 60 | + if ( !source ) { |
| 61 | + return; |
| 62 | + } |
| 63 | + for ( var i = 0; i < targetIDs.length; i++ ) { |
| 64 | + var elt = document.getElementById( targetIDs[i] ); |
| 65 | + if ( !elt ) continue; |
| 66 | + if ( show ) { |
| 67 | + elt.style.display = 'block'; |
| 68 | + } else { |
| 69 | + elt.style.display = 'none'; |
| 70 | + } |
| 71 | + } |
| 72 | +} |
| 73 | +wgSameNamespacePrefix = null; |
| 74 | + |
| 75 | +function setProjectNamespace() { |
| 76 | + var radio = document.getElementById( 'config__NamespaceType_site-name' ); |
| 77 | + if ( radio == null ) return; |
| 78 | + var li = radio.parentNode; |
| 79 | + var labels = li.getElementsByTagName( 'label' ); |
| 80 | + if ( labels.length == 0 ) return; |
| 81 | + var label = labels.item( 0 ); |
| 82 | + |
| 83 | + if ( wgSameNamespacePrefix == null ) { |
| 84 | + wgSameNamespacePrefix = label.innerHTML; |
| 85 | + } |
| 86 | + var input = document.getElementById( 'config_wgSitename' ); |
| 87 | + if ( input == null ) return; |
| 88 | + var value = input.value; |
| 89 | + value = value.replace(/[\[\]\{\}|#<>%+? ]/g, '_'); |
| 90 | + value = value.replace(/&/, '&'); |
| 91 | + value = value.replace(/__+/g, '_'); |
| 92 | + value = value.replace(/^_+/, '').replace(/_+$/, ''); |
| 93 | + value = value.substr(0, 1).toUpperCase() |
| 94 | + + value.substr(1); |
| 95 | + label.innerHTML = wgSameNamespacePrefix + value; |
| 96 | +} |
| 97 | + |
Property changes on: branches/new-installer/phase3/skins/common/config.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 98 | + native |
Index: branches/new-installer/phase3/skins/common/config.css |
— | — | @@ -0,0 +1,146 @@ |
| 2 | +.env-check { |
| 3 | + font-size: 90%; |
| 4 | + margin: 1em 0 1em 2.5em; |
| 5 | +} |
| 6 | + |
| 7 | +.config-section { |
| 8 | + margin-top: 2em; |
| 9 | +} |
| 10 | + |
| 11 | +.config-label { |
| 12 | + clear: left; |
| 13 | + font-weight: bold; |
| 14 | + width: 10em; |
| 15 | + float: left; |
| 16 | + text-align: right; |
| 17 | + padding-right: 1em; |
| 18 | + padding-top: .2em; |
| 19 | +} |
| 20 | + |
| 21 | +.config-input { |
| 22 | + clear: left; |
| 23 | + zoom: 100%; /* IE hack */ |
| 24 | +} |
| 25 | + |
| 26 | +.config-page-wrapper { |
| 27 | + padding: 0.5em; |
| 28 | +} |
| 29 | + |
| 30 | +.config-page-list { |
| 31 | + float: right; |
| 32 | + width: 12em; |
| 33 | + border: 1px solid #aaa; |
| 34 | + padding: 0.5em; |
| 35 | + margin: 0.5em; |
| 36 | +} |
| 37 | + |
| 38 | +.config-page { |
| 39 | + padding: 0.5em 2em 0.5em 2em; |
| 40 | + /* 15em right margin to leave space for 12em page list */ |
| 41 | + margin: 0.5em 15em 0.5em 0.5em; |
| 42 | + border: 1px solid #aaa; |
| 43 | +} |
| 44 | + |
| 45 | +.config-submit { |
| 46 | + clear: left; |
| 47 | + text-align: center; |
| 48 | + padding: 1em; |
| 49 | +} |
| 50 | + |
| 51 | +.config-submit input { |
| 52 | + margin-left: 0.5em; |
| 53 | + margin-right: 0.5em; |
| 54 | +} |
| 55 | + |
| 56 | +.config-page-disabled { |
| 57 | + color: #aaa; |
| 58 | +} |
| 59 | + |
| 60 | +.config-error-box { |
| 61 | + border: 2px solid #f00; |
| 62 | + margin: 0.4em; |
| 63 | + clear: left; |
| 64 | +} |
| 65 | + |
| 66 | +.config-info-left { |
| 67 | + margin: 7px; |
| 68 | + float: left; |
| 69 | + width: 35px; |
| 70 | +} |
| 71 | + |
| 72 | +.config-info-right { |
| 73 | + margin: 0.5em 0.5em 0.5em 49px; |
| 74 | + width: 30em; |
| 75 | +} |
| 76 | + |
| 77 | +.config-page-current { |
| 78 | + font-weight: bold; |
| 79 | +} |
| 80 | + |
| 81 | +.config-help-wrapper { |
| 82 | + clear: left; |
| 83 | + margin: 0 0 2em 12em; |
| 84 | + padding-top: 1em; |
| 85 | +} |
| 86 | +.config-show-help, .config-hide-help { |
| 87 | + margin-left: 14em; |
| 88 | +} |
| 89 | +.config-help-message { display: none; } |
| 90 | +.config-hide-help { display: none; } |
| 91 | + |
| 92 | +.config-help-message { |
| 93 | + font-size: 85%; |
| 94 | +} |
| 95 | + |
| 96 | +.config-message { |
| 97 | + display: list-item; |
| 98 | + line-height: 1.5em; |
| 99 | + list-style-image: url(../skins/common/images/bullet.gif); |
| 100 | + list-style-type: square; |
| 101 | +} |
| 102 | + |
| 103 | +.config-input-text { |
| 104 | + width: 20em; |
| 105 | + margin-right: 1em; |
| 106 | +} |
| 107 | + |
| 108 | +.config-input-check { |
| 109 | + margin-left: 10em; |
| 110 | +} |
| 111 | + |
| 112 | +.error { |
| 113 | + color: red; |
| 114 | + background-color: #fff; |
| 115 | + font-weight: bold; |
| 116 | + left: 1em; |
| 117 | + font-size: 100%; |
| 118 | +} |
| 119 | + |
| 120 | +.config-settings-block { |
| 121 | + list-style-type: none; |
| 122 | + list-style-image: none; |
| 123 | + float: left; |
| 124 | + margin: 0; |
| 125 | + padding: 0; |
| 126 | +} |
| 127 | + |
| 128 | +.btn-install { |
| 129 | + font-weight: bold; |
| 130 | + font-size: 110%; |
| 131 | + padding: .2em .3em; |
| 132 | +} |
| 133 | + |
| 134 | +.success-message { |
| 135 | + font-weight: bold; |
| 136 | + font-size: 110%; |
| 137 | + color: green; |
| 138 | +} |
| 139 | +.success-box { |
| 140 | + font-size: 130%; |
| 141 | +} |
| 142 | + |
| 143 | +.config-cc-wrapper { |
| 144 | + clear: left; |
| 145 | + /* If you change this height, also change it in WebInstaller_Options::submitCC() */ |
| 146 | + height: 54em; |
| 147 | +} |
Property changes on: branches/new-installer/phase3/skins/common/config.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 148 | + native |
Index: branches/new-installer/phase3/skins/common/config-cc.css |
— | — | @@ -0,0 +1,56 @@ |
| 2 | +/** |
| 3 | + * Copy of CC standard stylesheet, plus tweaks for iframe usage |
| 4 | + */ |
| 5 | + |
| 6 | +body { |
| 7 | + margin:0px; |
| 8 | + background:#eee; |
| 9 | + font-family:verdana; |
| 10 | + color:#333; |
| 11 | +} |
| 12 | + |
| 13 | +#main { |
| 14 | + border:1px solid #D0D0D0; |
| 15 | + background:#fff; |
| 16 | + margin: 0.5em; |
| 17 | +} |
| 18 | + |
| 19 | +/* Looks like you have to specify the width of #menu |
| 20 | +or IE5 Mac stretches it all the way across the div, and |
| 21 | +Opera streches it half way. */ |
| 22 | + |
| 23 | +#main #menu { |
| 24 | + border-left:1px dotted #ccc; |
| 25 | + /* border-bottom:1px solid #000;*/ |
| 26 | + float:right; |
| 27 | + width:230px; |
| 28 | + background:white; |
| 29 | + margin:0px 0px 10px 10px; |
| 30 | +} |
| 31 | + |
| 32 | +td, h3, p,h1,pre { |
| 33 | + margin:0px 20px 20px 20px; |
| 34 | + font-size:11px; |
| 35 | + line-height:140%; |
| 36 | +} |
| 37 | + |
| 38 | +.header { |
| 39 | + padding-left: 10px; |
| 40 | + padding-top:10px; |
| 41 | +} |
| 42 | + |
| 43 | +.nav { |
| 44 | + padding-left:10px; |
| 45 | + padding-bottom:10px; |
| 46 | + font-size:11px; |
| 47 | + margin-bottom:16px; |
| 48 | +} |
| 49 | + |
| 50 | +#menu p { |
| 51 | + font-size:11px; |
| 52 | +} |
| 53 | + |
| 54 | +.dent { |
| 55 | + margin-left:64px; |
| 56 | +} |
| 57 | + |
Property changes on: branches/new-installer/phase3/skins/common/config-cc.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 58 | + native |
Index: branches/new-installer/phase3/skins/MonoBook.php |
— | — | @@ -131,8 +131,8 @@ |
132 | 132 | </div> |
133 | 133 | </div> |
134 | 134 | </div> |
135 | | - <div id="column-one"> |
136 | | - <div id="p-cactions" class="portlet"> |
| 135 | + <div id="column-one" style="padding-top: <? echo intval($this->data['logoHeight'] + 25); ?>px"> |
| 136 | + <div id="p-cactions" class="portlet"> |
137 | 137 | <h5><?php $this->msg('views') ?></h5> |
138 | 138 | <div class="pBody"> |
139 | 139 | <ul> |
— | — | @@ -175,12 +175,17 @@ |
176 | 176 | </ul> |
177 | 177 | </div> |
178 | 178 | </div> |
| 179 | +<?php |
| 180 | +if ( strval( $this->data['logopath'] ) !== '' ): |
| 181 | +?> |
179 | 182 | <div class="portlet" id="p-logo"> |
180 | 183 | <a style="background-image: url(<?php $this->text('logopath') ?>);" <?php |
181 | 184 | ?>href="<?php echo htmlspecialchars($this->data['nav_urls']['mainpage']['href'])?>"<?php |
182 | 185 | echo $skin->tooltipAndAccesskey('n-mainpage') ?>></a> |
183 | 186 | </div> |
184 | 187 | <script type="<?php $this->text('jsmimetype') ?>"> if (window.isMSIE55) fixalpha(); </script> |
| 188 | +<? endif; ?> |
| 189 | + |
185 | 190 | <?php |
186 | 191 | $sidebar = $this->data['sidebar']; |
187 | 192 | if ( !isset( $sidebar['SEARCH'] ) ) $sidebar['SEARCH'] = true; |
Index: branches/new-installer/phase3/includes/db/Database.php |
— | — | @@ -1608,6 +1608,19 @@ |
1609 | 1609 | } |
1610 | 1610 | |
1611 | 1611 | /** |
| 1612 | + * Convert a wildcard (as used in LIKE) to a regex |
| 1613 | + * Slashes are escaped, slash terminators included |
| 1614 | + */ |
| 1615 | + function likeToRegex( $wildcard ) { |
| 1616 | + $r = preg_quote( $wildcard, '/' ); |
| 1617 | + $r = strtr( $r, array( |
| 1618 | + '%' => '.*', |
| 1619 | + '_' => '.' |
| 1620 | + ) ); |
| 1621 | + return "/$r/s"; |
| 1622 | + } |
| 1623 | + |
| 1624 | + /** |
1612 | 1625 | * Returns an appropriately quoted sequence value for inserting a new row. |
1613 | 1626 | * MySQL has autoincrement fields, so this is just NULL. But the PostgreSQL |
1614 | 1627 | * subclass will return an integer, and save the value for insertId() |
Index: branches/new-installer/phase3/includes/Setup.php |
— | — | @@ -42,8 +42,6 @@ |
43 | 43 | if( $wgStylePath === false ) $wgStylePath = "$wgScriptPath/skins"; |
44 | 44 | if( $wgStyleDirectory === false) $wgStyleDirectory = "$IP/skins"; |
45 | 45 | |
46 | | -if( $wgLogo === false ) $wgLogo = "$wgStylePath/common/images/wiki.png"; |
47 | | - |
48 | 46 | if( $wgUploadPath === false ) $wgUploadPath = "$wgScriptPath/images"; |
49 | 47 | if( $wgUploadDirectory === false ) $wgUploadDirectory = "$IP/images"; |
50 | 48 | |
— | — | @@ -53,9 +51,9 @@ |
54 | 52 | |
55 | 53 | if( $wgReadOnlyFile === false ) $wgReadOnlyFile = "{$wgUploadDirectory}/lock_yBgMBwiR"; |
56 | 54 | if( $wgFileCacheDirectory === false ) $wgFileCacheDirectory = "{$wgUploadDirectory}/cache"; |
57 | | - |
| 55 | +if ( $wgDeletedDirectory === false ) $wgDeletedDirectory = "{$wgUploadDirectory}/deleted"; |
58 | 56 | if ( empty( $wgFileStore['deleted']['directory'] ) ) { |
59 | | - $wgFileStore['deleted']['directory'] = "{$wgUploadDirectory}/deleted"; |
| 57 | + $wgFileStore['deleted']['directory'] = $wgDeletedDirectory; |
60 | 58 | } |
61 | 59 | |
62 | 60 | /** |
Index: branches/new-installer/phase3/includes/installer/WebInstaller.php |
— | — | @@ -20,13 +20,12 @@ |
21 | 21 | */ |
22 | 22 | var $pageSequence = array( |
23 | 23 | 'Language', |
24 | | - 'Environment', |
| 24 | + 'Welcome', |
25 | 25 | 'DBConnect', |
26 | 26 | 'Upgrade', |
27 | 27 | 'DBSettings', |
28 | | - 'Identity', |
29 | | - 'License', |
30 | | - 'Email', |
| 28 | + 'Name', |
| 29 | + 'Options', |
31 | 30 | 'Install', |
32 | 31 | 'Complete', |
33 | 32 | ); |
— | — | @@ -36,6 +35,9 @@ |
37 | 36 | */ |
38 | 37 | var $otherPages = array( |
39 | 38 | 'Restart', |
| 39 | + 'Readme', |
| 40 | + 'ReleaseNotes', |
| 41 | + 'Copying', |
40 | 42 | ); |
41 | 43 | |
42 | 44 | /** |
— | — | @@ -56,12 +58,16 @@ |
57 | 59 | */ |
58 | 60 | var $showSessionWarning = false; |
59 | 61 | |
| 62 | + var $helpId = 0; |
| 63 | + var $tabIndex = 1; |
| 64 | + |
| 65 | + var $currentPageName; |
| 66 | + |
60 | 67 | /** Constructor */ |
61 | 68 | function __construct( $request ) { |
62 | 69 | parent::__construct(); |
63 | 70 | $this->output = new WebInstallerOutput( $this ); |
64 | 71 | $this->request = $request; |
65 | | - $this->internalDefaults['_UserLang'] = 'en'; |
66 | 72 | } |
67 | 73 | |
68 | 74 | /** |
— | — | @@ -74,6 +80,7 @@ |
75 | 81 | if ( isset( $session['settings'] ) ) { |
76 | 82 | $this->settings = $session['settings'] + $this->settings; |
77 | 83 | } |
| 84 | + |
78 | 85 | if ( isset( $session['happyPages'] ) ) { |
79 | 86 | $this->happyPages = $session['happyPages']; |
80 | 87 | } else { |
— | — | @@ -86,6 +93,19 @@ |
87 | 94 | } |
88 | 95 | $lowestUnhappy = $this->getLowestUnhappy(); |
89 | 96 | |
| 97 | + # Special case for Creative Commons partner chooser box |
| 98 | + if ( $this->request->getVal( 'SubmitCC' ) ) { |
| 99 | + $page = $this->getPageByName( 'Options' ); |
| 100 | + $this->output->useShortHeader(); |
| 101 | + $page->submitCC(); |
| 102 | + return $this->finish(); |
| 103 | + } |
| 104 | + if ( $this->request->getVal( 'ShowCC' ) ) { |
| 105 | + $page = $this->getPageByName( 'Options' ); |
| 106 | + $this->output->useShortHeader(); |
| 107 | + $this->output->addHTML( $page->getCCDoneBox() ); |
| 108 | + return $this->finish(); |
| 109 | + } |
90 | 110 | |
91 | 111 | # Get the page name |
92 | 112 | $pageName = $this->request->getVal( 'page' ); |
— | — | @@ -134,6 +154,7 @@ |
135 | 155 | } |
136 | 156 | |
137 | 157 | # Execute the page |
| 158 | + $this->currentPageName = $page->getName(); |
138 | 159 | $this->startPageWrapper( $pageName ); |
139 | 160 | $result = $page->execute(); |
140 | 161 | $this->endPageWrapper(); |
— | — | @@ -204,8 +225,8 @@ |
205 | 226 | $args = func_get_args(); |
206 | 227 | array_shift( $args ); |
207 | 228 | $args = array_map( 'htmlspecialchars', $args ); |
208 | | - $msg = wfMsgReal( $msg, $args ); |
209 | | - $this->output->addHTML( "<div class=\"config-error-top\">\n$msg\n</div>\n" ); |
| 229 | + $msg = wfMsgReal( $msg, $args, false, false, false ); |
| 230 | + $this->output->addHTML( $this->getErrorBox( $msg ) ); |
210 | 231 | } |
211 | 232 | |
212 | 233 | /** |
— | — | @@ -276,6 +297,13 @@ |
277 | 298 | } |
278 | 299 | |
279 | 300 | /** |
| 301 | + * Get the next tabindex attribute value |
| 302 | + */ |
| 303 | + function nextTabIndex() { |
| 304 | + return $this->tabIndex++; |
| 305 | + } |
| 306 | + |
| 307 | + /** |
280 | 308 | * Called by execute() before page output starts, to show a page list |
281 | 309 | */ |
282 | 310 | function startPageWrapper( $currentPageName ) { |
— | — | @@ -311,7 +339,9 @@ |
312 | 340 | if ( $enabled ) { |
313 | 341 | $query = array( 'page' => $pageName ); |
314 | 342 | if ( !in_array( $pageName, $this->pageSequence ) ) { |
315 | | - $query['lastPage'] = $currentPageName; |
| 343 | + if ( in_array( $currentPageName, $this->pageSequence ) ) { |
| 344 | + $query['lastPage'] = $currentPageName; |
| 345 | + } |
316 | 346 | $link = Xml::element( 'a', |
317 | 347 | array( |
318 | 348 | 'href' => $this->getUrl( $query ) |
— | — | @@ -349,34 +379,42 @@ |
350 | 380 | } |
351 | 381 | |
352 | 382 | /** |
| 383 | + * Get HTML for an error box with an icon |
| 384 | + * @param string $text Wikitext, get this with wfMsgNoTrans() |
| 385 | + */ |
| 386 | + function getErrorBox( $text ) { |
| 387 | + return $this->getInfoBox( $text, 'critical-32.png', 'config-error-box' ); |
| 388 | + } |
| 389 | + |
| 390 | + /** |
353 | 391 | * Get HTML for a warning box with an icon |
| 392 | + * @param string $text Wikitext, get this with wfMsgNoTrans() |
354 | 393 | */ |
355 | | - function getWarningBox( $msg ) { |
356 | | - return $this->getInfoBox( $msg, 'warning-32.png' ); |
| 394 | + function getWarningBox( $text ) { |
| 395 | + return $this->getInfoBox( $text, 'warning-32.png', 'config-warning-box' ); |
357 | 396 | } |
358 | 397 | |
359 | 398 | /** |
360 | 399 | * Get HTML for an info box with an icon |
| 400 | + * @param string $text Wikitext, get this with wfMsgNoTrans() |
| 401 | + * @param string $icon Icon name, file in skins/common/images |
| 402 | + * @param string $class Additional class name to add to the wrapper div |
361 | 403 | */ |
362 | | - function getInfoBox( $msg, $icon = 'info-32.png' ) { |
363 | | - if ( is_array( $msg ) ) { |
364 | | - $args = $msg; |
365 | | - $msg = array_shift( $args ); |
366 | | - $text = wfMsgReal( $msg, $args, false, false, false ); |
367 | | - } else { |
368 | | - $text = wfMsgNoTrans( $msg ); |
369 | | - } |
370 | | - $s = "<div class=\"config-info\">\n" . |
371 | | - "<div class=\"config-info-left\">\n" . |
372 | | - Xml::element( 'img', |
373 | | - array( |
374 | | - 'src' => '../skins/common/images/' . $icon |
375 | | - ) |
376 | | - ) . "\n" . |
377 | | - "</div>\n" . |
378 | | - "<div class=\"config-info-right\">\n" . |
379 | | - $this->parse( $text ) . |
380 | | - "</div></div>\n"; |
| 404 | + function getInfoBox( $text, $icon = 'info-32.png', $class = false ) { |
| 405 | + $s = |
| 406 | + "<div class=\"config-info $class\">\n" . |
| 407 | + "<div class=\"config-info-left\">\n" . |
| 408 | + Xml::element( 'img', |
| 409 | + array( |
| 410 | + 'src' => '../skins/common/images/' . $icon |
| 411 | + ) |
| 412 | + ) . "\n" . |
| 413 | + "</div>\n" . |
| 414 | + "<div class=\"config-info-right\">\n" . |
| 415 | + $this->parse( $text ) . "\n" . |
| 416 | + "</div>\n" . |
| 417 | + "<div style=\"clear: left;\"></div>\n" . |
| 418 | + "</div>\n"; |
381 | 419 | return $s; |
382 | 420 | } |
383 | 421 | |
— | — | @@ -388,9 +426,25 @@ |
389 | 427 | $args = func_get_args(); |
390 | 428 | array_shift( $args ); |
391 | 429 | $args = array_map( 'htmlspecialchars', $args ); |
392 | | - return "<div class=\"config-desc\">\n" . |
393 | | - $this->parse( wfMsgReal( $msg, $args, false, false, false ) ) . |
394 | | - "</div>\n"; |
| 430 | + $text = wfMsgReal( $msg, $args, false, false, false ); |
| 431 | + $html = $this->parse( $text, true ); |
| 432 | + $id = $this->helpId++; |
| 433 | + |
| 434 | + return |
| 435 | + "<div class=\"config-help-wrapper\">\n" . |
| 436 | + "<div class=\"config-show-help\" id=\"config-show-help-$id\">\n" . |
| 437 | + Xml::openElement( 'a', array( 'href' => "javascript:showHelp($id,true)" ) ) . |
| 438 | + "<img src=\"../skins/common/images/help-22.png\"/> " . |
| 439 | + wfMsgHtml( 'config-show-help' ) . |
| 440 | + "</a></div>\n" . |
| 441 | + "<div class=\"config-help-message\" id=\"config-help-message-$id\">\n" . |
| 442 | + $html. |
| 443 | + "</div>\n" . |
| 444 | + "<div class=\"config-hide-help\" id=\"config-hide-help-$id\">\n" . |
| 445 | + Xml::openElement( 'a', array( 'href' => "javascript:showHelp($id,false)" ) ) . |
| 446 | + "<img src=\"../skins/common/images/help-22.png\"/> " . |
| 447 | + wfMsgHtml( 'config-hide-help' ) . |
| 448 | + "</a></div>\n</div>\n"; |
395 | 449 | } |
396 | 450 | |
397 | 451 | /** |
— | — | @@ -416,64 +470,244 @@ |
417 | 471 | } |
418 | 472 | |
419 | 473 | /** |
420 | | - * Get a label element using a message name |
| 474 | + * Label a control by wrapping a config-input div around it and putting a |
| 475 | + * label before it |
421 | 476 | */ |
422 | | - function getLabel( $msg, $for ) { |
423 | | - return Xml::element( 'label', |
424 | | - array( 'for' => $for, 'class' => 'config-label' ), |
425 | | - wfMsg( $msg ) ) . "\n"; |
| 477 | + function label( $msg, $forId, $contents ) { |
| 478 | + if ( strval( $msg ) == '' ) { |
| 479 | + $labelText = ' '; |
| 480 | + } else { |
| 481 | + $labelText = wfMsgHtml( $msg ); |
| 482 | + } |
| 483 | + return |
| 484 | + "<div class=\"config-input\">\n" . |
| 485 | + Xml::tags( 'label', |
| 486 | + array( 'for' => $forId, 'class' => 'config-label' ), |
| 487 | + $labelText ) . "\n" . |
| 488 | + $contents . |
| 489 | + "</div>\n"; |
426 | 490 | } |
427 | 491 | |
428 | 492 | /** |
429 | | - * Get a text box |
| 493 | + * Get a labelled text box to configure a variable |
| 494 | + * @param array $params |
| 495 | + * Parameters are: |
| 496 | + * var: The variable to be configured (required) |
| 497 | + * label: The message name for the label (required) |
| 498 | + * attribs: Additional attributes for the input element (optional) |
| 499 | + * controlName: The name for the input element (optional) |
| 500 | + * value: The current value of the variable (optional) |
430 | 501 | */ |
431 | | - function getTextBox( $name, $value = '', $type = 'text' ) { |
432 | | - return Xml::element( 'input', |
433 | | - array( |
434 | | - 'type' => $type, |
435 | | - 'name' => $name, |
436 | | - 'id' => $name, |
437 | | - 'value' => $value, |
438 | | - 'class' => 'config-input-text', |
439 | | - ) |
440 | | - ); |
| 502 | + function getTextBox( $params ) { |
| 503 | + if ( !isset( $params['controlName'] ) ) { |
| 504 | + $params['controlName'] = 'config_' . $params['var']; |
| 505 | + } |
| 506 | + if ( !isset( $params['value'] ) ) { |
| 507 | + $params['value'] = $this->getVar( $params['var'] ); |
| 508 | + } |
| 509 | + if ( !isset( $params['attribs'] ) ) { |
| 510 | + $params['attribs'] = array(); |
| 511 | + } |
| 512 | + return |
| 513 | + $this->label( |
| 514 | + $params['label'], |
| 515 | + $params['controlName'], |
| 516 | + Xml::input( |
| 517 | + $params['controlName'], |
| 518 | + 30, // intended to be overridden by CSS |
| 519 | + $params['value'], |
| 520 | + $params['attribs'] + array( |
| 521 | + 'id' => $params['controlName'], |
| 522 | + 'class' => 'config-input-text', |
| 523 | + 'tabindex' => $this->nextTabIndex() |
| 524 | + ) |
| 525 | + ) |
| 526 | + ); |
441 | 527 | } |
442 | 528 | |
443 | 529 | /** |
444 | | - * Get a checkbox |
| 530 | + * Get a labelled password box to configure a variable |
| 531 | + * Implements password hiding |
| 532 | + * @param array $params |
| 533 | + * Parameters are: |
| 534 | + * var: The variable to be configured (required) |
| 535 | + * label: The message name for the label (required) |
| 536 | + * attribs: Additional attributes for the input element (optional) |
| 537 | + * controlName: The name for the input element (optional) |
| 538 | + * value: The current value of the variable (optional) |
445 | 539 | */ |
446 | | - function getCheckBox( $name, $value, $attribs ) { |
447 | | - return Xml::element( 'input', |
448 | | - $attribs + array( |
449 | | - 'type' => 'checkbox', |
450 | | - 'name' => $name, |
451 | | - 'id' => $name, |
452 | | - 'checked' => $value ? '1' : '', |
453 | | - 'class' => 'config-input-text', |
454 | | - ) |
455 | | - ); |
| 540 | + function getPasswordBox( $params ) { |
| 541 | + if ( !isset( $params['value'] ) ) { |
| 542 | + $params['value'] = $this->getVar( $params['var'] ); |
| 543 | + } |
| 544 | + if ( !isset( $params['attribs'] ) ) { |
| 545 | + $params['attribs'] = array(); |
| 546 | + } |
| 547 | + $params['value'] = $this->getFakePassword( $params['value'] ); |
| 548 | + $params['attribs']['type'] = 'password'; |
| 549 | + return $this->getTextBox( $params ); |
456 | 550 | } |
457 | 551 | |
458 | 552 | /** |
| 553 | + * Get a labelled checkbox to configure a boolean variable |
| 554 | + * @param array $params |
| 555 | + * Parameters are: |
| 556 | + * var: The variable to be configured (required) |
| 557 | + * label: The message name for the label (required) |
| 558 | + * attribs: Additional attributes for the input element (optional) |
| 559 | + * controlName: The name for the input element (optional) |
| 560 | + * value: The current value of the variable (optional) |
| 561 | + */ |
| 562 | + function getCheckBox( $params ) { |
| 563 | + if ( !isset( $params['controlName'] ) ) { |
| 564 | + $params['controlName'] = 'config_' . $params['var']; |
| 565 | + } |
| 566 | + if ( !isset( $params['value'] ) ) { |
| 567 | + $params['value'] = $this->getVar( $params['var'] ); |
| 568 | + } |
| 569 | + if ( !isset( $params['attribs'] ) ) { |
| 570 | + $params['attribs'] = array(); |
| 571 | + } |
| 572 | + return |
| 573 | + "<div class=\"config-input-check\">\n" . |
| 574 | + "<label>\n" . |
| 575 | + Xml::check( |
| 576 | + $params['controlName'], |
| 577 | + $params['value'], |
| 578 | + $params['attribs'] + array( |
| 579 | + 'id' => $params['controlName'], |
| 580 | + 'class' => 'config-input-text', |
| 581 | + 'tabindex' => $this->nextTabIndex(), |
| 582 | + ) |
| 583 | + ) . |
| 584 | + $this->parse( wfMsg( $params['label'] ) ) . "\n" . |
| 585 | + "</label>\n" . |
| 586 | + "</div>\n"; |
| 587 | + } |
| 588 | + |
| 589 | + /** |
| 590 | + * Get a set of labelled radio buttons |
| 591 | + * |
| 592 | + * @param array $params |
| 593 | + * Parameters are: |
| 594 | + * var: The variable to be configured (required) |
| 595 | + * label: The message name for the label (required) |
| 596 | + * itemLabelPrefix: The message name prefix for the item labels (required) |
| 597 | + * values: List of allowed values (required) |
| 598 | + * itemAttribs Array of attribute arrays, outer key is the value name (optional) |
| 599 | + * commonAttribs Attribute array applied to all items |
| 600 | + * controlName: The name for the input element (optional) |
| 601 | + * value: The current value of the variable (optional) |
| 602 | + */ |
| 603 | + function getRadioSet( $params ) { |
| 604 | + if ( !isset( $params['controlName'] ) ) { |
| 605 | + $params['controlName'] = 'config_' . $params['var']; |
| 606 | + } |
| 607 | + if ( !isset( $params['value'] ) ) { |
| 608 | + $params['value'] = $this->getVar( $params['var'] ); |
| 609 | + } |
| 610 | + if ( !isset( $params['label'] ) ) { |
| 611 | + $label = ''; |
| 612 | + } else { |
| 613 | + $label = $this->parse( wfMsgNoTrans( $params['label'] ) ); |
| 614 | + } |
| 615 | + $s = "<label class=\"config-label\">\n" . |
| 616 | + $label . |
| 617 | + "</label>\n" . |
| 618 | + "<ul class=\"config-settings-block\">\n"; |
| 619 | + foreach ( $params['values'] as $value ) { |
| 620 | + $itemAttribs = array(); |
| 621 | + if ( isset( $params['commonAttribs'] ) ) { |
| 622 | + $itemAttribs = $params['commonAttribs']; |
| 623 | + } |
| 624 | + if ( isset( $params['itemAttribs'][$value] ) ) { |
| 625 | + $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs; |
| 626 | + } |
| 627 | + $checked = $value == $params['value']; |
| 628 | + $id = $params['controlName'] . '_' . $value; |
| 629 | + $itemAttribs['id'] = $id; |
| 630 | + $itemAttribs['tabindex'] = $this->nextTabIndex(); |
| 631 | + $s .= |
| 632 | + '<li>' . |
| 633 | + Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) . |
| 634 | + ' ' . |
| 635 | + Xml::tags( 'label', array( 'for' => $id ), $this->parse( |
| 636 | + wfMsgNoTrans( $params['itemLabelPrefix'] . strtolower( $value ) ) |
| 637 | + ) ) . |
| 638 | + "</li>\n"; |
| 639 | + } |
| 640 | + $s .= "</ul>\n"; |
| 641 | + return $s; |
| 642 | + } |
| 643 | + |
| 644 | + /** |
459 | 645 | * Output an error box using a Status object |
460 | 646 | */ |
461 | 647 | function showStatusErrorBox( $status ) { |
462 | 648 | $text = $status->getWikiText(); |
463 | | - $this->parent->output->addWikiText( |
464 | | - "<div class=\"config-error-top\">\n" . |
465 | | - $text . |
466 | | - "</div>" |
467 | | - ); |
| 649 | + $this->output->addHTML( $this->getErrorBox( $text ) ); |
468 | 650 | } |
469 | 651 | |
470 | 652 | function showStatusError( $status ) { |
471 | 653 | $text = $status->getWikiText(); |
472 | | - $this->parent->output->addWikiText( |
| 654 | + $this->output->addWikiText( |
473 | 655 | "<div class=\"config-message\">\n" . |
474 | 656 | $text . |
475 | 657 | "</div>" |
476 | 658 | ); |
477 | 659 | } |
| 660 | + |
| 661 | + /** |
| 662 | + * Convenience function to set variables based on form data. |
| 663 | + * Assumes that variables containing "password" in the name are (potentially |
| 664 | + * fake) passwords. |
| 665 | + * @param array $varNames |
| 666 | + * @param string $prefix The prefix added to variables to obtain form names |
| 667 | + */ |
| 668 | + function setVarsFromRequest( $varNames, $prefix = 'config_' ) { |
| 669 | + $newValues = array(); |
| 670 | + foreach ( $varNames as $name ) { |
| 671 | + $value = $this->request->getVal( $prefix . $name ); |
| 672 | + $newValues[$name] = $value; |
| 673 | + if ( $value === null ) { |
| 674 | + // Checkbox? |
| 675 | + $this->setVar( $name, false ); |
| 676 | + } else { |
| 677 | + if ( stripos( $name, 'password' ) !== false ) { |
| 678 | + $this->setPassword( $name, $value ); |
| 679 | + } else { |
| 680 | + $this->setVar( $name, $value ); |
| 681 | + } |
| 682 | + } |
| 683 | + } |
| 684 | + return $newValues; |
| 685 | + } |
| 686 | + |
| 687 | + /** |
| 688 | + * Get the starting tags of a fieldset |
| 689 | + * @param string $legend Message name |
| 690 | + */ |
| 691 | + function getFieldsetStart( $legend ) { |
| 692 | + return "\n<fieldset><legend>" . wfMsgHtml( $legend ) . "</legend>\n"; |
| 693 | + } |
| 694 | + |
| 695 | + /** |
| 696 | + * Get the end tag of a fieldset |
| 697 | + */ |
| 698 | + function getFieldsetEnd() { |
| 699 | + return "</fieldset>\n"; |
| 700 | + } |
| 701 | + |
| 702 | + /** |
| 703 | + * Helper for Installer::docLink() |
| 704 | + */ |
| 705 | + function getDocUrl( $page ) { |
| 706 | + $url = "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page ); |
| 707 | + if ( in_array( $this->currentPageName, $this->pageSequence ) ) { |
| 708 | + $url .= '&lastPage=' . urlencode( $this->currentPageName ); |
| 709 | + } |
| 710 | + return $url; |
| 711 | + } |
478 | 712 | } |
479 | 713 | |
480 | 714 | class WebInstallerPage { |
— | — | @@ -503,14 +737,21 @@ |
504 | 738 | if ( $continue ) { |
505 | 739 | // Fake submit button for enter keypress |
506 | 740 | $s .= Xml::submitButton( wfMsg( "config-$continue" ), |
507 | | - array( 'name' => "enter-$continue", 'style' => 'display:none' ) ); |
| 741 | + array( 'name' => "enter-$continue", 'style' => 'display:none' ) ) . "\n"; |
508 | 742 | } |
509 | 743 | if ( $id !== 0 ) { |
510 | | - $s .= Xml::submitButton( wfMsg( 'config-back' ), array( 'name' => 'submit-back' ) ); |
| 744 | + $s .= Xml::submitButton( wfMsg( 'config-back' ), |
| 745 | + array( |
| 746 | + 'name' => 'submit-back', |
| 747 | + 'tabindex' => $this->parent->nextTabIndex() |
| 748 | + ) ) . "\n"; |
511 | 749 | } |
512 | 750 | if ( $continue ) { |
513 | 751 | $s .= Xml::submitButton( wfMsg( "config-$continue" ), |
514 | | - array( 'name' => "submit-$continue" ) ); |
| 752 | + array( |
| 753 | + 'name' => "submit-$continue", |
| 754 | + 'tabindex' => $this->parent->nextTabIndex(), |
| 755 | + ) ) . "\n"; |
515 | 756 | } |
516 | 757 | $s .= "</div></form></div>\n"; |
517 | 758 | $this->parent->output->addHTML( $s ); |
— | — | @@ -533,6 +774,14 @@ |
534 | 775 | $this->endForm(); |
535 | 776 | } |
536 | 777 | } |
| 778 | + |
| 779 | + function getVar( $var ) { |
| 780 | + return $this->parent->getVar( $var ); |
| 781 | + } |
| 782 | + |
| 783 | + function setVar( $name, $value ) { |
| 784 | + $this->parent->setVar( $name, $value ); |
| 785 | + } |
537 | 786 | } |
538 | 787 | |
539 | 788 | class WebInstaller_Language extends WebInstallerPage { |
— | — | @@ -544,12 +793,12 @@ |
545 | 794 | |
546 | 795 | if ( $r->wasPosted() ) { |
547 | 796 | # Do session test |
| 797 | + $lifetime = intval( ini_get( 'session.gc_maxlifetime' ) ); |
| 798 | + if ( !$lifetime ) { |
| 799 | + $lifetime = 1440; // PHP default |
| 800 | + } |
548 | 801 | if ( $this->parent->getSession( 'test' ) === null ) { |
549 | 802 | $requestTime = $r->getVal( 'LanguageRequestTime' ); |
550 | | - $lifetime = intval( ini_get( 'session.gc_maxlifetime' ) ); |
551 | | - if ( !$lifetime ) { |
552 | | - $lifetime = 1440; |
553 | | - } |
554 | 803 | if ( !$requestTime ) { |
555 | 804 | // The most likely explanation is that the user was knocked back |
556 | 805 | // from another page on POST due to session expiry |
— | — | @@ -563,26 +812,26 @@ |
564 | 813 | } else { |
565 | 814 | $languages = Language::getLanguageNames(); |
566 | 815 | if ( isset( $languages[$userLang] ) ) { |
567 | | - $this->parent->setVar( '_UserLang', $userLang ); |
| 816 | + $this->setVar( '_UserLang', $userLang ); |
568 | 817 | } |
569 | 818 | if ( isset( $languages[$contLang] ) ) { |
570 | | - $this->parent->setVar( 'wgLanguageCode', $contLang ); |
| 819 | + $this->setVar( 'wgLanguageCode', $contLang ); |
571 | 820 | } |
572 | 821 | return 'continue'; |
573 | 822 | } |
574 | 823 | } elseif ( $this->parent->showSessionWarning ) { |
575 | 824 | # The user was knocked back from another page to the start |
576 | 825 | # This probably indicates a session expiry |
577 | | - $this->parent->showError( 'config-session-expired' ); |
| 826 | + $this->parent->showError( 'config-session-expired', $wgLang->formatTimePeriod( $lifetime ) ); |
578 | 827 | } |
579 | 828 | |
580 | 829 | $this->parent->setSession( 'test', true ); |
581 | 830 | |
582 | 831 | if ( !isset( $languages[$userLang] ) ) { |
583 | | - $userLang = $this->parent->getVar( '_UserLang', 'en' ); |
| 832 | + $userLang = $this->getVar( '_UserLang', 'en' ); |
584 | 833 | } |
585 | 834 | if ( !isset( $languages[$contLang] ) ) { |
586 | | - $contLang = $this->parent->getVar( 'wgLanguageCode', 'en' ); |
| 835 | + $contLang = $this->getVar( 'wgLanguageCode', 'en' ); |
587 | 836 | } |
588 | 837 | $this->startForm(); |
589 | 838 | $s = |
— | — | @@ -601,30 +850,30 @@ |
602 | 851 | * Get a <select> for selecting languages |
603 | 852 | */ |
604 | 853 | function getLanguageSelector( $name, $label, $selectedCode ) { |
605 | | - $s = "<div class=\"config-input\">\n" . |
606 | | - $this->parent->getLabel( $label, $name ) . |
607 | | - Xml::openElement( 'select', array( 'id' => $name, 'name' => $name ) ) . "\n"; |
| 854 | + $s = Xml::openElement( 'select', array( 'id' => $name, 'name' => $name ) ) . "\n"; |
608 | 855 | |
609 | 856 | $languages = Language::getLanguageNames(); |
610 | 857 | ksort( $languages ); |
611 | 858 | foreach ( $languages as $code => $name ) { |
612 | 859 | $s .= "\n" . Xml::option( "$code - $name", $code, $code == $selectedCode ); |
613 | 860 | } |
614 | | - $s .= "\n</select>\n</div>\n"; |
615 | | - return $s; |
| 861 | + $s .= "\n</select>\n"; |
| 862 | + return $this->parent->label( $label, $name, $s ); |
616 | 863 | } |
617 | 864 | |
618 | 865 | } |
619 | 866 | |
620 | | -class WebInstaller_Environment extends WebInstallerPage { |
| 867 | +class WebInstaller_Welcome extends WebInstallerPage { |
621 | 868 | function execute() { |
622 | 869 | if ( $this->parent->request->wasPosted() ) { |
623 | | - if ( $this->parent->getVar( '_Environment' ) ) { |
| 870 | + if ( $this->getVar( '_Environment' ) ) { |
624 | 871 | return 'continue'; |
625 | 872 | } |
626 | 873 | } |
| 874 | + $this->parent->output->addWikiText( wfMsgNoTrans( 'config-welcome' ) ); |
627 | 875 | $status = $this->parent->doEnvironmentChecks(); |
628 | 876 | if ( $status ) { |
| 877 | + $this->parent->output->addWikiText( wfMsgNoTrans( 'config-copyright' ) ); |
629 | 878 | $this->startForm(); |
630 | 879 | $this->endForm(); |
631 | 880 | } |
— | — | @@ -634,30 +883,22 @@ |
635 | 884 | class WebInstaller_DBConnect extends WebInstallerPage { |
636 | 885 | function execute() { |
637 | 886 | $r = $this->parent->request; |
638 | | - if ( $this->parent->request->wasPosted() ) { |
| 887 | + if ( $r->wasPosted() ) { |
639 | 888 | $status = $this->submit(); |
640 | 889 | if ( $status->isGood() ) { |
641 | | - $this->parent->setVar( '_UpgradeDone', false ); |
| 890 | + $this->setVar( '_UpgradeDone', false ); |
642 | 891 | return 'continue'; |
643 | 892 | } else { |
644 | | - $error = $status->getWikiText(); |
645 | | - $this->parent->output->addWikiText( |
646 | | - "<div class=\"config-error-top\">\n" . |
647 | | - $error . |
648 | | - "</div>" |
649 | | - ); |
| 893 | + $this->parent->showStatusErrorBox( $status ); |
650 | 894 | } |
651 | 895 | } |
652 | 896 | |
653 | 897 | |
654 | 898 | $this->startForm(); |
655 | 899 | |
656 | | - $types = "<label class=\"config-label\">" . |
657 | | - wfMsg( 'config-db-type' ) . |
658 | | - "</label>" . |
659 | | - "<ul class=\"config-settings-block\">\n"; |
| 900 | + $types = "<ul class=\"config-settings-block\">\n"; |
660 | 901 | $settings = ''; |
661 | | - $defaultType = $this->parent->getVar( 'wgDBtype' ); |
| 902 | + $defaultType = $this->getVar( 'wgDBtype' ); |
662 | 903 | foreach ( $this->parent->getDBTypes() as $type ) { |
663 | 904 | $installer = $this->parent->getDBInstaller( $type ); |
664 | 905 | $encType = Xml::encodeJsVar( $type ); |
— | — | @@ -683,9 +924,9 @@ |
684 | 925 | $encType = Xml::encodeJsVar( $defaultType ); |
685 | 926 | |
686 | 927 | $this->parent->output->addHTML( |
687 | | - $types . |
| 928 | + $this->parent->label( 'config-db-type', false, $types ) . |
688 | 929 | $settings . |
689 | | - "<script>resetDBArea();</script>\n" |
| 930 | + "<script type=\"text/javascript\">resetDBArea();</script>\n" |
690 | 931 | ); |
691 | 932 | |
692 | 933 | $this->endForm(); |
— | — | @@ -694,7 +935,7 @@ |
695 | 936 | function submit() { |
696 | 937 | $r = $this->parent->request; |
697 | 938 | $type = $r->getVal( 'DBType' ); |
698 | | - $this->parent->setVar( 'wgDBtype', $type ); |
| 939 | + $this->setVar( 'wgDBtype', $type ); |
699 | 940 | $installer = $this->parent->getDBInstaller( $type ); |
700 | 941 | if ( !$installer ) { |
701 | 942 | return Status::newFatal( 'config-invalid-db-type' ); |
— | — | @@ -705,7 +946,7 @@ |
706 | 947 | |
707 | 948 | class WebInstaller_Upgrade extends WebInstallerPage { |
708 | 949 | function execute() { |
709 | | - if ( $this->parent->getVar( '_UpgradeDone' ) ) { |
| 950 | + if ( $this->getVar( '_UpgradeDone' ) ) { |
710 | 951 | if ( $this->parent->request->wasPosted() ) { |
711 | 952 | // Done message acknowledged |
712 | 953 | return 'continue'; |
— | — | @@ -720,31 +961,16 @@ |
721 | 962 | |
722 | 963 | // wgDBtype is generally valid here because otherwise the previous page |
723 | 964 | // (connect) wouldn't have declared its happiness |
724 | | - $type = $this->parent->getVar( 'wgDBtype' ); |
| 965 | + $type = $this->getVar( 'wgDBtype' ); |
725 | 966 | $installer = $this->parent->getDBInstaller( $type ); |
726 | 967 | |
727 | | - // There's no guarantee the connection will still succeed though |
728 | | - $conn = $installer->getConnection(); |
729 | | - if ( $conn instanceof Status ) { |
730 | | - $this->startForm(); |
731 | | - $this->showStatusErrorBox( $conn ); |
732 | | - $this->endForm(); |
733 | | - return 'output'; |
734 | | - } |
735 | | - |
736 | | - $ok = $conn->selectDB( $this->parent->getVar( 'wgDBname' ) ); |
737 | | - if ( !$ok ) { |
738 | | - // No DB exists yet |
| 968 | + if ( !$installer->needsUpgrade() ) { |
739 | 969 | return 'skip'; |
740 | 970 | } |
741 | | - if ( !$conn->tableExists( 'cur' ) && !$conn->tableExists( 'revision' ) ) { |
742 | | - // Nothing to upgrade |
743 | | - return 'skip'; |
744 | | - } |
745 | 971 | |
746 | 972 | if ( $this->parent->request->wasPosted() ) { |
747 | 973 | if ( true || $installer->doUpgrade() ) { |
748 | | - $this->parent->setVar( '_UpgradeDone', true ); |
| 974 | + $this->setVar( '_UpgradeDone', true ); |
749 | 975 | $this->showDoneMessage(); |
750 | 976 | return 'output'; |
751 | 977 | } |
— | — | @@ -752,7 +978,7 @@ |
753 | 979 | |
754 | 980 | $this->startForm(); |
755 | 981 | $this->parent->output->addHTML( $this->parent->getInfoBox( |
756 | | - array( 'config-can-upgrade', $GLOBALS['wgVersion'] ) ) ); |
| 982 | + wfMsgNoTrans( 'config-can-upgrade', $GLOBALS['wgVersion'] ) ) ); |
757 | 983 | $this->endForm(); |
758 | 984 | } |
759 | 985 | |
— | — | @@ -760,11 +986,10 @@ |
761 | 987 | $this->startForm(); |
762 | 988 | $this->parent->output->addHTML( |
763 | 989 | $this->parent->getInfoBox( |
764 | | - array( |
765 | | - 'config-upgrade-done', |
| 990 | + wfMsgNoTrans( 'config-upgrade-done', |
766 | 991 | $GLOBALS['wgServer'] . |
767 | | - $this->parent->getVar( 'wgScriptPath' ) . '/index' . |
768 | | - $this->parent->getVar( 'wgScriptExtension' ) |
| 992 | + $this->getVar( 'wgScriptPath' ) . '/index' . |
| 993 | + $this->getVar( 'wgScriptExtension' ) |
769 | 994 | ), 'tick-32.png' |
770 | 995 | ) |
771 | 996 | ); |
— | — | @@ -774,11 +999,25 @@ |
775 | 1000 | |
776 | 1001 | class WebInstaller_DBSettings extends WebInstallerPage { |
777 | 1002 | function execute() { |
778 | | - $installer = $this->parent->getDBInstaller( $this->parent->getVar( 'wgDBtype' ) ); |
| 1003 | + $installer = $this->parent->getDBInstaller( $this->getVar( 'wgDBtype' ) ); |
| 1004 | + |
| 1005 | + $r = $this->parent->request; |
| 1006 | + if ( $r->wasPosted() ) { |
| 1007 | + $status = $installer->submitSettingsForm(); |
| 1008 | + if ( $status === false ) { |
| 1009 | + return 'skip'; |
| 1010 | + } elseif ( $status->isGood() ) { |
| 1011 | + return 'continue'; |
| 1012 | + } else { |
| 1013 | + $this->parent->showStatusErrorBox( $status ); |
| 1014 | + } |
| 1015 | + } |
| 1016 | + |
779 | 1017 | $form = $installer->getSettingsForm(); |
780 | 1018 | if ( $form === false ) { |
781 | 1019 | return 'skip'; |
782 | 1020 | } |
| 1021 | + |
783 | 1022 | $this->startForm(); |
784 | 1023 | $this->parent->output->addHTML( $form ); |
785 | 1024 | $this->endForm(); |
— | — | @@ -786,12 +1025,353 @@ |
787 | 1026 | |
788 | 1027 | } |
789 | 1028 | |
790 | | -class WebInstaller_Identity extends WebInstallerPage { |
| 1029 | +class WebInstaller_Name extends WebInstallerPage { |
| 1030 | + function execute() { |
| 1031 | + $r = $this->parent->request; |
| 1032 | + if ( $r->wasPosted() ) { |
| 1033 | + if ( $this->submit() ) { |
| 1034 | + return 'continue'; |
| 1035 | + } |
| 1036 | + } |
| 1037 | + |
| 1038 | + $this->startForm(); |
| 1039 | + |
| 1040 | + if ( $this->getVar( 'wgSitename' ) == $GLOBALS['wgSitename'] ) { |
| 1041 | + $this->setVar( 'wgSitename', '' ); |
| 1042 | + } |
| 1043 | + $js = 'enableControlArray("config__NamespaceType_other", ["config_wgMetaNamespace"])'; |
| 1044 | + $attribs = array( 'onclick' => $js ); |
| 1045 | + |
| 1046 | + $this->parent->output->addHTML( |
| 1047 | + $this->parent->getTextBox( array( |
| 1048 | + 'var' => 'wgSitename', |
| 1049 | + 'label' => 'config-site-name', |
| 1050 | + 'attribs' => array( |
| 1051 | + 'onkeyup' => 'setProjectNamespace();', |
| 1052 | + 'onchange' => 'setProjectNamespace();' |
| 1053 | + ) |
| 1054 | + ) ) . |
| 1055 | + $this->parent->getHelpBox( 'config-site-name-help' ) . |
| 1056 | + $this->parent->getRadioSet( array( |
| 1057 | + 'var' => '_NamespaceType', |
| 1058 | + 'label' => 'config-project-namespace', |
| 1059 | + 'itemLabelPrefix' => 'config-ns-', |
| 1060 | + 'values' => array( 'site-name', 'generic', 'other' ), |
| 1061 | + 'commonAttribs' => $attribs, |
| 1062 | + ) ) . |
| 1063 | + $this->parent->getTextBox( array( |
| 1064 | + 'var' => 'wgMetaNamespace', |
| 1065 | + 'label' => '', |
| 1066 | + ) ) . |
| 1067 | + "<script type=\"text/javascript\">\nsetProjectNamespace();\n$js\n</script>\n" . |
| 1068 | + $this->parent->getHelpBox( 'config-project-namespace-help' ) . |
| 1069 | + $this->parent->getFieldsetStart( 'config-admin-box' ) . |
| 1070 | + $this->parent->getTextBox( array( |
| 1071 | + 'var' => '_AdminName', |
| 1072 | + 'label' => 'config-admin-name' |
| 1073 | + ) ) . |
| 1074 | + $this->parent->getPasswordBox( array( |
| 1075 | + 'var' => '_AdminPassword', |
| 1076 | + 'label' => 'config-admin-password', |
| 1077 | + ) ) . |
| 1078 | + $this->parent->getPasswordBox( array( |
| 1079 | + 'var' => '_AdminPassword2', |
| 1080 | + 'label' => 'config-admin-password-confirm' |
| 1081 | + ) ) . |
| 1082 | + $this->parent->getHelpBox( 'config-admin-help' ) . |
| 1083 | + $this->parent->getTextBox( array( |
| 1084 | + 'var' => '_AdminEmail', |
| 1085 | + 'label' => 'config-admin-email' |
| 1086 | + ) ) . |
| 1087 | + $this->parent->getHelpBox( 'config-admin-email-help' ) . |
| 1088 | + $this->parent->getCheckBox( array( |
| 1089 | + 'var' => '_Subscribe', |
| 1090 | + 'label' => 'config-subscribe' |
| 1091 | + ) ) . |
| 1092 | + $this->parent->getHelpBox( 'config-subscribe-help' ) . |
| 1093 | + $this->parent->getFieldsetEnd() . |
| 1094 | + $this->parent->getInfoBox( wfMsg( 'config-almost-done' ) ) . |
| 1095 | + $this->parent->getRadioSet( array( |
| 1096 | + 'var' => '_SkipOptional', |
| 1097 | + 'itemLabelPrefix' => 'config-optional-', |
| 1098 | + 'values' => array( 'continue', 'skip' ) |
| 1099 | + ) ) |
| 1100 | + ); |
| 1101 | + |
| 1102 | + $this->endForm(); |
| 1103 | + return 'output'; |
| 1104 | + } |
| 1105 | + |
| 1106 | + function submit() { |
| 1107 | + $retVal = true; |
| 1108 | + $this->parent->setVarsFromRequest( array( 'wgSitename', '_NamespaceType', |
| 1109 | + '_AdminName', '_AdminPassword', '_AdminPassword2', '_AdminEmail', |
| 1110 | + '_Subscribe', '_SkipOptional' ) ); |
| 1111 | + |
| 1112 | + // Validate site name |
| 1113 | + if ( strval( $this->getVar( 'wgSitename' ) ) === '' ) { |
| 1114 | + $this->parent->showError( 'config-site-name-blank' ); |
| 1115 | + $retVal = false; |
| 1116 | + } |
| 1117 | + |
| 1118 | + // Fetch namespace |
| 1119 | + $nsType = $this->getVar( '_NamespaceType' ); |
| 1120 | + if ( $nsType == 'site-name' ) { |
| 1121 | + $name = $this->getVar( 'wgSitename' ); |
| 1122 | + // Sanitize for namespace |
| 1123 | + // This algorithm should match the JS one in WebInstallerOutput.php |
| 1124 | + $name = preg_replace( '/[\[\]\{\}|#<>%+? ]/', '_', $name ); |
| 1125 | + $name = str_replace( '&', '&', $name ); |
| 1126 | + $name = preg_replace( '/__+/', '_', $name ); |
| 1127 | + $name = ucfirst( trim( $name, '_' ) ); |
| 1128 | + } elseif ( $nsType == 'generic' ) { |
| 1129 | + $name = wfMsg( 'config-ns-generic' ); |
| 1130 | + } else { // other |
| 1131 | + $name = $this->getVar( 'wgMetaNamespace' ); |
| 1132 | + } |
| 1133 | + |
| 1134 | + // Validate namespace |
| 1135 | + if ( strpos( $name, ':' ) !== false ) { |
| 1136 | + $good = false; |
| 1137 | + } else { |
| 1138 | + // Title-style validation |
| 1139 | + $title = Title::newFromText( $name ); |
| 1140 | + if ( !$title ) { |
| 1141 | + $good = false; |
| 1142 | + } else { |
| 1143 | + $name = $title->getDBkey(); |
| 1144 | + $good = true; |
| 1145 | + } |
| 1146 | + } |
| 1147 | + if ( !$good ) { |
| 1148 | + $this->parent->showError( 'config-ns-invalid', $name ); |
| 1149 | + $retVal = false; |
| 1150 | + } |
| 1151 | + $this->setVar( 'wgMetaNamespace', $name ); |
| 1152 | + |
| 1153 | + // Validate username for creation |
| 1154 | + $name = $this->getVar( '_AdminName' ); |
| 1155 | + if ( strval( $name ) === '' ) { |
| 1156 | + $this->parent->showError( 'config-admin-name-blank' ); |
| 1157 | + $cname = $name; |
| 1158 | + $retVal = false; |
| 1159 | + } else { |
| 1160 | + $cname = User::getCanonicalName( $name, 'creatable' ); |
| 1161 | + if ( $cname === false ) { |
| 1162 | + $this->parent->showError( 'config-admin-name-invalid', $name ); |
| 1163 | + $retVal = false; |
| 1164 | + } else { |
| 1165 | + $this->setVar( '_AdminName', $cname ); |
| 1166 | + } |
| 1167 | + } |
| 1168 | + |
| 1169 | + // Validate password |
| 1170 | + $msg = false; |
| 1171 | + $pwd = $this->getVar( '_AdminPassword' ); |
| 1172 | + if ( strval( $pwd ) === '' ) { |
| 1173 | + $msg = 'config-admin-password-blank'; |
| 1174 | + } elseif ( $pwd === $cname ) { |
| 1175 | + $msg = 'config-admin-password-same'; |
| 1176 | + } elseif ( $pwd !== $this->getVar( '_AdminPassword2' ) ) { |
| 1177 | + $msg = 'config-admin-password-mismatch'; |
| 1178 | + } |
| 1179 | + if ( $msg !== false ) { |
| 1180 | + $this->parent->showError( $msg ); |
| 1181 | + $this->setVar( '_AdminPassword', '' ); |
| 1182 | + $this->setVar( '_AdminPassword2', '' ); |
| 1183 | + $retVal = false; |
| 1184 | + } |
| 1185 | + return $retVal; |
| 1186 | + } |
| 1187 | + |
791 | 1188 | } |
792 | | -class WebInstaller_License extends WebInstallerPage { |
| 1189 | +class WebInstaller_Options extends WebInstallerPage { |
| 1190 | + function execute() { |
| 1191 | + if ( $this->getVar( '_SkipOptional' ) == 'skip' ) { |
| 1192 | + return 'skip'; |
| 1193 | + } |
| 1194 | + if ( $this->parent->request->wasPosted() ) { |
| 1195 | + if ( $this->submit() ) { |
| 1196 | + return 'continue'; |
| 1197 | + } |
| 1198 | + } |
| 1199 | + |
| 1200 | + $licenseJs = 'showControlArray("config__LicenseCode_cc-choose", ["config-cc-wrapper"]);'; |
| 1201 | + $emailJs = 'enableControlArray("config_wgEnableEmail", ["config_wgPasswordSender"]);'; |
| 1202 | + $uploadJs = 'enableControlArray("config_wgEnableUploads", ["config_wgDeletedDirectory"]);'; |
| 1203 | + |
| 1204 | + $this->startForm(); |
| 1205 | + $this->parent->output->addHTML( |
| 1206 | + $this->parent->getRadioSet( array( |
| 1207 | + 'var' => '_RightsProfile', |
| 1208 | + 'label' => 'config-profile', |
| 1209 | + 'itemLabelPrefix' => 'config-profile-', |
| 1210 | + 'values' => array_keys( $this->parent->rightsProfiles ), |
| 1211 | + ) ) . |
| 1212 | + $this->parent->getHelpBox( 'config-profile-help' ) . |
| 1213 | + $this->parent->getRadioSet( array( |
| 1214 | + 'var' => '_LicenseCode', |
| 1215 | + 'label' => 'config-license', |
| 1216 | + 'itemLabelPrefix' => 'config-license-', |
| 1217 | + 'values' => array_keys( $this->parent->licenses ), |
| 1218 | + 'commonAttribs' => array( 'onclick' => $licenseJs ) |
| 1219 | + ) ) . |
| 1220 | + $this->getCCChooser() . |
| 1221 | + $this->parent->getHelpBox( 'config-license-help' ) . |
| 1222 | + $this->parent->getFieldsetStart( 'config-email-settings' ) . |
| 1223 | + $this->parent->getCheckBox( array( |
| 1224 | + 'var' => 'wgEnableEmail', |
| 1225 | + 'label' => 'config-enable-email', |
| 1226 | + 'attribs' => array( 'onclick' => $emailJs ), |
| 1227 | + ) ) . |
| 1228 | + $this->parent->getHelpBox( 'config-enable-email-help' ) . |
| 1229 | + $this->parent->getTextBox( array( |
| 1230 | + 'var' => 'wgPasswordSender', |
| 1231 | + 'label' => 'config-email-sender' |
| 1232 | + ) ) . |
| 1233 | + $this->parent->getHelpBox( 'config-email-sender-help' ) . |
| 1234 | + $this->parent->getFieldsetEnd() . |
| 1235 | + $this->parent->getFieldsetStart( 'config-upload-settings' ) . |
| 1236 | + $this->parent->getCheckBox( array( |
| 1237 | + 'var' => 'wgEnableUploads', |
| 1238 | + 'label' => 'config-upload-enable', |
| 1239 | + 'attribs' => array( 'onclick' => $uploadJs ), |
| 1240 | + ) ) . |
| 1241 | + $this->parent->getHelpBox( 'config-upload-help' ) . |
| 1242 | + $this->parent->getTextBox( array( |
| 1243 | + 'var' => 'wgDeletedDirectory', |
| 1244 | + 'label' => 'config-upload-deleted', |
| 1245 | + ) ) . |
| 1246 | + $this->parent->getHelpBox( 'config-upload-deleted-help' ) . |
| 1247 | + $this->parent->getTextBox( array( |
| 1248 | + 'var' => 'wgLogo', |
| 1249 | + 'label' => 'config-logo' |
| 1250 | + ) ) . |
| 1251 | + $this->parent->getHelpBox( 'config-logo-help' ) . |
| 1252 | + $this->parent->getFieldsetEnd() . |
| 1253 | + "<script type=\"text/javascript\">$licenseJs $emailJs $uploadJs</script>\n" |
| 1254 | + |
| 1255 | + ); |
| 1256 | + $this->endForm(); |
| 1257 | + } |
| 1258 | + |
| 1259 | + function getCCPartnerUrl() { |
| 1260 | + global $wgServer; |
| 1261 | + $exitUrl = $wgServer . $this->parent->getUrl( array( |
| 1262 | + 'page' => 'Options', |
| 1263 | + 'SubmitCC' => 'indeed', |
| 1264 | + 'config__LicenseCode' => 'cc', |
| 1265 | + 'config_wgRightsUrl' => '[license_url]', |
| 1266 | + 'config_wgRightsText' => '[license_name]', |
| 1267 | + 'config_wgRightsIcon' => '[license_button]', |
| 1268 | + ) ); |
| 1269 | + $styleUrl = $wgServer . dirname( dirname( $this->parent->getUrl() ) ) . |
| 1270 | + '/skins/common/config-cc.css'; |
| 1271 | + $iframeUrl = 'http://creativecommons.org/license/?' . |
| 1272 | + wfArrayToCGI( array( |
| 1273 | + 'partner' => 'MediaWiki', |
| 1274 | + 'exit_url' => $exitUrl, |
| 1275 | + 'lang' => $this->getVar( '_UserLang' ), |
| 1276 | + 'stylesheet' => $styleUrl, |
| 1277 | + ) ); |
| 1278 | + return $iframeUrl; |
| 1279 | + } |
| 1280 | + |
| 1281 | + function getCCChooser() { |
| 1282 | + $iframeAttribs = array( |
| 1283 | + 'class' => 'config-cc-iframe', |
| 1284 | + 'name' => 'config-cc-iframe', |
| 1285 | + 'id' => 'config-cc-iframe', |
| 1286 | + 'frameborder' => 0, |
| 1287 | + 'width' => '100%', |
| 1288 | + 'height' => '100%', |
| 1289 | + ); |
| 1290 | + if ( $this->getVar( '_CCDone' ) ) { |
| 1291 | + $iframeAttribs['src'] = $this->parent->getUrl( array( 'ShowCC' => 'yes' ) ); |
| 1292 | + } else { |
| 1293 | + $iframeAttribs['src'] = $this->getCCPartnerUrl(); |
| 1294 | + } |
| 1295 | + |
| 1296 | + return |
| 1297 | + "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\">\n" . |
| 1298 | + Xml::element( 'iframe', $iframeAttribs, '', false /* not short */ ) . |
| 1299 | + "</div>\n"; |
| 1300 | + } |
| 1301 | + |
| 1302 | + function getCCDoneBox() { |
| 1303 | + $js = "parent.document.getElementById('config-cc-wrapper').style.height = '$1';"; |
| 1304 | + // If you change this height, also change it in config.css |
| 1305 | + $expandJs = str_replace( '$1', '54em', $js ); |
| 1306 | + $reduceJs = str_replace( '$1', '70px', $js ); |
| 1307 | + return |
| 1308 | + '<p>'. |
| 1309 | + Xml::element( 'img', array( 'src' => $this->getVar( 'wgRightsIcon' ) ) ) . |
| 1310 | + ' ' . |
| 1311 | + htmlspecialchars( $this->getVar( 'wgRightsText' ) ) . |
| 1312 | + "</p>\n" . |
| 1313 | + "<p style=\"text-align: center\">" . |
| 1314 | + Xml::element( 'a', |
| 1315 | + array( |
| 1316 | + 'href' => $this->getCCPartnerUrl(), |
| 1317 | + 'onclick' => $expandJs, |
| 1318 | + ), |
| 1319 | + wfMsg( 'config-cc-again' ) |
| 1320 | + ) . |
| 1321 | + "</p>\n" . |
| 1322 | + "<script type=\"text/javascript\">\n" . |
| 1323 | + # Reduce the wrapper div height |
| 1324 | + htmlspecialchars( $reduceJs ) . |
| 1325 | + "\n" . |
| 1326 | + "</script>\n"; |
| 1327 | + } |
| 1328 | + |
| 1329 | + |
| 1330 | + function submitCC() { |
| 1331 | + $newValues = $this->parent->setVarsFromRequest( |
| 1332 | + array( 'wgRightsUrl', 'wgRightsText', 'wgRightsIcon' ) ); |
| 1333 | + if ( count( $newValues ) != 3 ) { |
| 1334 | + $this->parent->showError( 'config-cc-error' ); |
| 1335 | + return; |
| 1336 | + } |
| 1337 | + $this->setVar( '_CCDone', true ); |
| 1338 | + $this->parent->output->addHTML( $this->getCCDoneBox() ); |
| 1339 | + } |
| 1340 | + |
| 1341 | + function submit() { |
| 1342 | + $this->parent->setVarsFromRequest( array( '_RightsProfile', '_LicenseCode', |
| 1343 | + 'wgEnableEmail', 'wgPasswordSender', 'wgEnableUpload', 'wgLogo' ) ); |
| 1344 | + |
| 1345 | + if ( !in_array( $this->getVar( '_RightsProfile' ), |
| 1346 | + array_keys( $this->parent->rightsProfiles ) ) ) |
| 1347 | + { |
| 1348 | + reset( $this->parent->rightsProfiles ); |
| 1349 | + $this->setVar( '_RightsProfile', key( $this->parent->rightsProfiles ) ); |
| 1350 | + } |
| 1351 | + |
| 1352 | + $code = $this->getVar( '_LicenseCode' ); |
| 1353 | + if ( $code == 'cc-choose' ) { |
| 1354 | + if ( !$this->getVar( '_CCDone' ) ) { |
| 1355 | + $this->parent->showError( 'config-cc-not-chosen' ); |
| 1356 | + return false; |
| 1357 | + } |
| 1358 | + } elseif ( in_array( $code, array_keys( $this->parent->licenses ) ) ) { |
| 1359 | + $entry = $this->parent->licenses[$code]; |
| 1360 | + if ( isset( $entry['text'] ) ) { |
| 1361 | + $this->setVar( 'wgRightsText', $entry['text'] ); |
| 1362 | + } else { |
| 1363 | + $this->setVar( 'wgRightsText', wfMsg( 'config-license-' . $code ) ); |
| 1364 | + } |
| 1365 | + $this->setVar( 'wgRightsUrl', $entry['url'] ); |
| 1366 | + $this->setVar( 'wgRightsIcon', $entry['icon'] ); |
| 1367 | + } else { |
| 1368 | + $this->setVar( 'wgRightsText', '' ); |
| 1369 | + $this->setVar( 'wgRightsUrl', '' ); |
| 1370 | + $this->setVar( 'wgRightsIcon', '' ); |
| 1371 | + } |
| 1372 | + |
| 1373 | + return true; |
| 1374 | + } |
793 | 1375 | } |
794 | | -class WebInstaller_Email extends WebInstallerPage { |
795 | | -} |
796 | 1376 | class WebInstaller_Install extends WebInstallerPage { |
797 | 1377 | } |
798 | 1378 | class WebInstaller_Complete extends WebInstallerPage { |
— | — | @@ -810,9 +1390,29 @@ |
811 | 1391 | } |
812 | 1392 | |
813 | 1393 | $this->startForm(); |
814 | | - $s = $this->parent->getWarningBox( 'config-help-restart' ); |
| 1394 | + $s = $this->parent->getWarningBox( wfMsgNoTrans( 'config-help-restart' ) ); |
815 | 1395 | $this->parent->output->addHTML( $s ); |
816 | 1396 | $this->endForm( 'restart' ); |
817 | 1397 | } |
818 | 1398 | } |
819 | 1399 | |
| 1400 | +abstract class WebInstaller_Document extends WebInstallerPage { |
| 1401 | + abstract function getFileName(); |
| 1402 | + |
| 1403 | + function execute() { |
| 1404 | + $text = file_get_contents( dirname( __FILE__ ) . '/../../' . $this->getFileName() ); |
| 1405 | + $this->parent->output->addWikiText( $text ); |
| 1406 | + $this->startForm(); |
| 1407 | + $this->endForm( false ); |
| 1408 | + } |
| 1409 | +} |
| 1410 | + |
| 1411 | +class WebInstaller_Readme extends WebInstaller_Document { |
| 1412 | + function getFileName() { return 'README'; } |
| 1413 | +} |
| 1414 | +class WebInstaller_ReleaseNotes extends WebInstaller_Document { |
| 1415 | + function getFileName() { return 'RELEASE-NOTES'; } |
| 1416 | +} |
| 1417 | +class WebInstaller_Copying extends WebInstaller_Document { |
| 1418 | + function getFileName() { return 'COPYING'; } |
| 1419 | +} |
Index: branches/new-installer/phase3/includes/installer/WebInstallerOutput.php |
— | — | @@ -14,6 +14,7 @@ |
15 | 15 | var $headerDone = false; |
16 | 16 | var $redirectTarget; |
17 | 17 | var $debug = true; |
| 18 | + var $useShortHeader = false; |
18 | 19 | |
19 | 20 | function __construct( $parent ) { |
20 | 21 | $this->parent = $parent; |
— | — | @@ -41,6 +42,10 @@ |
42 | 43 | $this->outputFooter(); |
43 | 44 | } |
44 | 45 | |
| 46 | + function useShortHeader( $use = true ) { |
| 47 | + $this->useShortHeader = $use; |
| 48 | + } |
| 49 | + |
45 | 50 | function flush() { |
46 | 51 | if ( !$this->headerDone ) { |
47 | 52 | $this->outputHeader(); |
— | — | @@ -63,202 +68,34 @@ |
64 | 69 | return; |
65 | 70 | } |
66 | 71 | |
67 | | - |
| 72 | + if ( $this->useShortHeader ) { |
| 73 | + $this->outputShortHeader(); |
| 74 | + return; |
| 75 | + } |
| 76 | + |
68 | 77 | ?> |
69 | 78 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
70 | 79 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
71 | 80 | <head> |
| 81 | + <meta name="robots" content="noindex, nofollow"> |
72 | 82 | <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> |
73 | 83 | <title>MediaWiki <?php echo( htmlspecialchars( $wgVersion ) ); ?> Installation</title> |
74 | | - <style type="text/css"> |
75 | | - |
76 | | - @import "../skins/monobook/main.css"; |
77 | | - |
78 | | - .env-check { |
79 | | - font-size: 90%; |
80 | | - margin: 1em 0 1em 2.5em; |
81 | | - } |
82 | | - |
83 | | - .config-section { |
84 | | - margin-top: 2em; |
85 | | - } |
86 | | - |
87 | | - .config-label { |
88 | | - clear: left; |
89 | | - font-weight: bold; |
90 | | - width: 10em; |
91 | | - float: left; |
92 | | - text-align: right; |
93 | | - padding-right: 1em; |
94 | | - padding-top: .2em; |
95 | | - } |
96 | | - |
97 | | - .config-input { |
98 | | - clear: left; |
99 | | - zoom: 100%; /* IE hack */ |
100 | | - } |
101 | | - |
102 | | - .config-page-wrapper { |
103 | | - padding: 0.5em; |
104 | | - } |
105 | | - |
106 | | - .config-page-list { |
107 | | - float: right; |
108 | | - width: 12em; |
109 | | - border: 1px solid #aaa; |
110 | | - padding: 0.5em; |
111 | | - margin: 0.5em; |
112 | | - } |
113 | | - |
114 | | - .config-page { |
115 | | - padding: 0.5em 2em 0.5em 2em; |
116 | | - /* 15em right margin to leave space for 12em page list */ |
117 | | - margin: 0.5em 15em 0.5em 0.5em; |
118 | | - border: 1px solid #aaa; |
119 | | - } |
120 | | - |
121 | | - .config-submit { |
122 | | - clear: left; |
123 | | - text-align: center; |
124 | | - padding: 1em; |
125 | | - } |
126 | | - |
127 | | - .config-submit input { |
128 | | - margin-left: 0.5em; |
129 | | - margin-right: 0.5em; |
130 | | - } |
131 | | - |
132 | | - .config-page-disabled { |
133 | | - color: #aaa; |
134 | | - } |
135 | | - |
136 | | - .config-info-left { |
137 | | - margin: 0.5em; |
138 | | - float: left; |
139 | | - width: 35px; |
140 | | - } |
141 | | - |
142 | | - .config-info-right { |
143 | | - margin: 0.5em; |
144 | | - float: left; |
145 | | - width: 30em; |
146 | | - } |
147 | | - |
148 | | - .config-page-current { |
149 | | - font-weight: bold; |
150 | | - } |
151 | | - |
152 | | - .config-desc { |
153 | | - clear: left; |
154 | | - margin: 0 0 2em 12em; |
155 | | - padding-top: 1em; |
156 | | - font-size: 85%; |
157 | | - } |
158 | | - |
159 | | - .config-message { |
160 | | - display: list-item; |
161 | | - line-height: 1.5em; |
162 | | - list-style-image: url(../skins/common/images/bullet.gif); |
163 | | - list-style-type: square; |
164 | | - } |
165 | | - |
166 | | - .config-input-text { |
167 | | - width: 20em; |
168 | | - margin-right: 1em; |
169 | | - } |
170 | | - |
171 | | - .config-input-check { |
172 | | - margin-left: 10em; |
173 | | - } |
174 | | - |
175 | | - .error { |
176 | | - color: red; |
177 | | - background-color: #fff; |
178 | | - font-weight: bold; |
179 | | - left: 1em; |
180 | | - font-size: 100%; |
181 | | - } |
182 | | - |
183 | | - .config-error-top { |
184 | | - background-color: #FFF0F0; |
185 | | - border: 2px solid red; |
186 | | - font-size: 110%; |
187 | | - font-weight: bold; |
188 | | - padding: 1em 1.5em; |
189 | | - margin: 2em 0 1em; |
190 | | - } |
191 | | - |
192 | | - .config-settings-block { |
193 | | - list-style-type: none; |
194 | | - list-style-image: none; |
195 | | - float: left; |
196 | | - margin: 0; |
197 | | - padding: 0; |
198 | | - } |
199 | | - |
200 | | - .btn-install { |
201 | | - font-weight: bold; |
202 | | - font-size: 110%; |
203 | | - padding: .2em .3em; |
204 | | - } |
205 | | - |
206 | | - .license { |
207 | | - clear: both; |
208 | | - font-size: 85%; |
209 | | - padding-top: 3em; |
210 | | - } |
211 | | - |
212 | | - .success-message { |
213 | | - font-weight: bold; |
214 | | - font-size: 110%; |
215 | | - color: green; |
216 | | - } |
217 | | - .success-box { |
218 | | - font-size: 130%; |
219 | | - } |
220 | | - |
221 | | - </style> |
222 | | - <script type="text/javascript"> |
223 | | - <!-- |
224 | | -<?php |
225 | | - echo "var dbTypes = " . Xml::encodeJsVar( $dbTypes ) . "\n"; |
226 | | -?> |
227 | | - function hideAllDBs() { |
228 | | - for ( var i = 0; i < dbTypes.length; i++ ) { |
229 | | - elt = document.getElementById( 'DB_wrapper_' + dbTypes[i] ); |
230 | | - if ( elt ) elt.style.display = 'none'; |
231 | | - } |
232 | | - } |
233 | | - function showDBArea(type) { |
234 | | - hideAllDBs(); |
235 | | - var div = document.getElementById('DB_wrapper_' + type); |
236 | | - if (div) div.style.display = 'block'; |
237 | | - } |
238 | | - function resetDBArea() { |
239 | | - for ( var i = 0; i < dbTypes.length; i++ ) { |
240 | | - input = document.getElementById('DBType_' + dbTypes[i]); |
241 | | - if ( input && input.checked ) { |
242 | | - showDBArea( dbTypes[i] ); |
243 | | - return; |
244 | | - } |
245 | | - } |
246 | | - } |
247 | | - function disableControlArray( sourceID, targetIDs ) { |
248 | | - var source = document.getElementById( sourceID ); |
249 | | - var disabled = source.checked ? '1' : ''; |
250 | | - if ( !source ) { |
251 | | - return; |
252 | | - } |
253 | | - for ( var i = 0; i < targetIDs.length; i++ ) { |
254 | | - var elt = document.getElementById( targetIDs[i] ); |
255 | | - if ( elt ) elt.disabled = disabled; |
256 | | - } |
257 | | - } |
| 84 | + <link rel="stylesheet" type="text/css" href="../skins/monobook/main.css"/> |
| 85 | + <link rel="stylesheet" type="text/css" href="../skins/common/config.css"/> |
| 86 | + <script type="text/javascript"><!-- |
| 87 | +<?php echo "var dbTypes = " . Xml::encodeJsVar( $dbTypes ) . ";\n"; ?> |
258 | 88 | // --> |
259 | 89 | </script> |
| 90 | + <script type="text/javascript" src="../skins/common/config.js"></script> |
260 | 91 | </head> |
261 | 92 | |
262 | 93 | <body> |
| 94 | +<noscript> |
| 95 | +<style> |
| 96 | +.config-help-message { display: block; } |
| 97 | +.config-show-help { display: none; } |
| 98 | +</style> |
| 99 | +</noscript> |
263 | 100 | <div id="globalWrapper"> |
264 | 101 | <div id="column-content"> |
265 | 102 | <div id="content"> |
— | — | @@ -269,25 +106,14 @@ |
270 | 107 | } |
271 | 108 | |
272 | 109 | function outputFooter() { |
| 110 | + if ( $this->useShortHeader ) { |
273 | 111 | ?> |
274 | | - <div class="license"> |
275 | | - <hr/> |
276 | | - <p>This program is free software; you can redistribute it and/or modify |
277 | | - it under the terms of the GNU General Public License as published by |
278 | | - the Free Software Foundation; either version 2 of the License, or |
279 | | - (at your option) any later version.</p> |
| 112 | +</body></html> |
| 113 | +<?php |
| 114 | + return; |
| 115 | + } |
| 116 | +?> |
280 | 117 | |
281 | | - <p>This program is distributed in the hope that it will be useful, |
282 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
283 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
284 | | - GNU General Public License for more details.</p> |
285 | | - |
286 | | - <p>You should have received <a href="../COPYING">a copy of the GNU General Public License</a> |
287 | | - along with this program; if not, write to the Free Software |
288 | | - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
289 | | - or <a href="http://www.gnu.org/copyleft/gpl.html">read it online</a></p> |
290 | | - </div> |
291 | | - |
292 | 118 | </div></div></div> |
293 | 119 | |
294 | 120 | |
— | — | @@ -299,18 +125,9 @@ |
300 | 126 | </div> |
301 | 127 | <script type="text/javascript"> if (window.isMSIE55) fixalpha(); </script> |
302 | 128 | <div class='portlet'><div class='pBody'> |
303 | | - <ul> |
304 | | - <li><strong><a href="http://www.mediawiki.org/">MediaWiki home</a></strong></li> |
305 | | - <li><a href="../README">Readme</a></li> |
306 | | - <li><a href="../RELEASE-NOTES">Release notes</a></li> |
307 | | - <li><a href="../docs/">Documentation</a></li> |
308 | | - <li><a href="http://www.mediawiki.org/wiki/Help:Contents">User's Guide</a></li> |
309 | | - <li><a href="http://www.mediawiki.org/wiki/Manual:Contents">Administrator's Guide</a></li> |
310 | | - <li><a href="http://www.mediawiki.org/wiki/Manual:FAQ">FAQ</a></li> |
311 | | - </ul> |
312 | | - <p style="font-size:90%;margin-top:1em">MediaWiki is Copyright © 2001-2008 by Magnus Manske, Brion Vibber, |
313 | | - Lee Daniel Crocker, Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason, Niklas Laxström, |
314 | | - Domas Mituzas, Rob Church, Yuri Astrakhan, Aryeh Gregor, Aaron Schulz and others.</p> |
| 129 | +<?php |
| 130 | + echo $this->parent->parse( wfMsgNoTrans( 'config-sidebar' ), true ); |
| 131 | +?> |
315 | 132 | </div></div> |
316 | 133 | </div> |
317 | 134 | |
— | — | @@ -320,4 +137,21 @@ |
321 | 138 | </html> |
322 | 139 | <?php |
323 | 140 | } |
| 141 | + |
| 142 | + function outputShortHeader() { |
| 143 | +?> |
| 144 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| 145 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
| 146 | +<head> |
| 147 | + <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> |
| 148 | + <meta name="robots" content="noindex, nofollow"> |
| 149 | + <title>MediaWiki <?php echo( htmlspecialchars( $wgVersion ) ); ?> Installation</title> |
| 150 | + <link rel="stylesheet" type="text/css" href="../skins/monobook/main.css"/> |
| 151 | + <link rel="stylesheet" type="text/css" href="../skins/common/config.css"/> |
| 152 | + <script type="text/javascript" src="../skins/common/config.js"></script> |
| 153 | +</head> |
| 154 | + |
| 155 | +<body style="background-image: none"> |
| 156 | +<?php |
| 157 | + } |
324 | 158 | } |
Index: branches/new-installer/phase3/includes/installer/Installer.php |
— | — | @@ -22,15 +22,16 @@ |
23 | 23 | 'wgRightsUrl', |
24 | 24 | 'wgMainCacheType', |
25 | 25 | 'wgEnableEmail', |
26 | | - 'wgEnableUserEmail', |
27 | | - 'wgEnotifUserTalk', |
28 | | - 'wgEnotifWatchlist', |
29 | 26 | 'wgDBtype', |
30 | 27 | 'wgDiff3', |
31 | 28 | 'wgImageMagickConvertCommand', |
32 | 29 | 'IP', |
33 | 30 | 'wgScriptPath', |
34 | 31 | 'wgScriptExtension', |
| 32 | + 'wgMetaNamespace', |
| 33 | + 'wgDeletedDirectory', |
| 34 | + 'wgEnableUploads', |
| 35 | + 'wgLogo', |
35 | 36 | ); |
36 | 37 | |
37 | 38 | /** |
— | — | @@ -40,12 +41,27 @@ |
41 | 42 | * @protected |
42 | 43 | */ |
43 | 44 | var $internalDefaults = array( |
| 45 | + '_UserLang' => 'en', |
44 | 46 | '_Environment' => false, |
45 | 47 | '_CompiledDBs' => array(), |
46 | 48 | '_SafeMode' => false, |
47 | 49 | '_RaiseMemory' => false, |
48 | 50 | '_UpgradeDone' => false, |
49 | 51 | '_Caches' => array(), |
| 52 | + '_InstallUser' => 'root', |
| 53 | + '_InstallPassword' => '', |
| 54 | + '_SameAccount' => true, |
| 55 | + '_CreateDBAccount' => false, |
| 56 | + '_NamespaceType' => 'site-name', |
| 57 | + '_AdminName' => '', |
| 58 | + '_AdminPassword' => '', |
| 59 | + '_AdminPassword2' => '', |
| 60 | + '_AdminEmail' => '', |
| 61 | + '_Subscribe' => false, |
| 62 | + '_SkipOptional' => 'continue', |
| 63 | + '_RightsProfile' => 'wiki', |
| 64 | + '_LicenseCode' => 'none', |
| 65 | + '_CCDone' => false, |
50 | 66 | ); |
51 | 67 | |
52 | 68 | /** |
— | — | @@ -63,6 +79,11 @@ |
64 | 80 | ); |
65 | 81 | |
66 | 82 | /** |
| 83 | + * Minimum memory size in MB |
| 84 | + */ |
| 85 | + var $minMemory = 50; |
| 86 | + |
| 87 | + /** |
67 | 88 | * Cached DB installer instances, access using getDBInstaller() |
68 | 89 | * @private |
69 | 90 | */ |
— | — | @@ -104,6 +125,57 @@ |
105 | 126 | ); |
106 | 127 | |
107 | 128 | /** |
| 129 | + * User rights profiles |
| 130 | + */ |
| 131 | + var $rightsProfiles = array( |
| 132 | + 'wiki' => array(), |
| 133 | + 'no-anon' => array( |
| 134 | + '*' => array( 'edit' => false ) |
| 135 | + ), |
| 136 | + 'fishbowl' => array( |
| 137 | + '*' => array( |
| 138 | + 'createaccount' => false, |
| 139 | + 'edit' => false, |
| 140 | + ), |
| 141 | + ), |
| 142 | + 'private' => array( |
| 143 | + '*' => array( |
| 144 | + 'createaccount' => false, |
| 145 | + 'edit' => false, |
| 146 | + 'read' => false, |
| 147 | + ), |
| 148 | + ), |
| 149 | + ); |
| 150 | + |
| 151 | + /** |
| 152 | + * License types |
| 153 | + */ |
| 154 | + var $licenses = array( |
| 155 | + 'none' => array( |
| 156 | + 'url' => '', |
| 157 | + 'icon' => '', |
| 158 | + 'text' => '' |
| 159 | + ), |
| 160 | + 'pd' => array( |
| 161 | + 'url' => 'http://creativecommons.org/licenses/publicdomain/', |
| 162 | + 'icon' => '${wgScriptPath}/skins/common/images/public-domain.png', |
| 163 | + ), |
| 164 | + 'gfdl-old' => array( |
| 165 | + 'url' => 'http://www.gnu.org/licenses/old-licenses/fdl-1.2.html', |
| 166 | + 'icon' => '${wgScriptPath}/skins/common/images/gnu-fdl.png', |
| 167 | + ), |
| 168 | + 'gfdl-current' => array( |
| 169 | + 'url' => 'http://www.gnu.org/copyleft/fdl.html', |
| 170 | + 'icon' => '${wgScriptPath}/skins/common/images/gnu-fdl.png', |
| 171 | + ), |
| 172 | + 'cc-choose' => array( |
| 173 | + // details will be filled in by the selector |
| 174 | + 'url' => '', |
| 175 | + 'icon' => '', |
| 176 | + 'text' => '', |
| 177 | + ), |
| 178 | + ); |
| 179 | + /** |
108 | 180 | * Cached Title and ParserOptions used by parse() |
109 | 181 | * @private |
110 | 182 | */ |
— | — | @@ -343,11 +415,12 @@ |
344 | 416 | if( preg_match( '/^([0-9]+)[Mm]$/', trim( $limit ), $m ) ) { |
345 | 417 | $n = intval( $m[1] * (1024*1024) ); |
346 | 418 | } |
347 | | - if( $n < 20*1024*1024 ) { |
348 | | - if( false === ini_set( "memory_limit", "20M" ) ) { |
| 419 | + if( $n < $this->minMemorySize*1024*1024 ) { |
| 420 | + $newLimit = "{$this->minMemorySize}M"; |
| 421 | + if( false === ini_set( "memory_limit", $newLimit ) ) { |
349 | 422 | $this->showMessage( 'config-memory-bad', $limit ); |
350 | 423 | } else { |
351 | | - $this->showMessage( 'config-memory-raised', $limit ); |
| 424 | + $this->showMessage( 'config-memory-raised', $limit, $newLimit ); |
352 | 425 | $this->setVar( '_RaiseMemory', true ); |
353 | 426 | } |
354 | 427 | } else { |
— | — | @@ -507,19 +580,36 @@ |
508 | 581 | * @param string $text |
509 | 582 | * @return string |
510 | 583 | */ |
511 | | - function parse( $text ) { |
| 584 | + function parse( $text, $lineStart = false ) { |
512 | 585 | global $wgParser; |
513 | 586 | try { |
514 | | - $out = $wgParser->parse( $text, $this->parserTitle, $this->parserOptions, false ); |
| 587 | + $out = $wgParser->parse( $text, $this->parserTitle, $this->parserOptions, $lineStart ); |
515 | 588 | $html = $out->getText(); |
516 | 589 | } catch ( InstallerDBAccessError $e ) { |
517 | 590 | $html = '<!--DB access attempted during parse--> ' . htmlspecialchars( $text ); |
518 | | - if ( $this->debug ) { |
| 591 | + if ( !empty( $this->debug ) ) { |
519 | 592 | $html .= "<!--\n" . $e->getTraceAsString() . "\n-->"; |
520 | 593 | } |
521 | 594 | } |
522 | 595 | return $html; |
523 | 596 | } |
| 597 | + |
| 598 | + /** |
| 599 | + * Extension tag hook for a documentation link |
| 600 | + */ |
| 601 | + function docLink( $linkText, $attribs, $parser ) { |
| 602 | + $url = $this->getDocUrl( $attribs['href'] ); |
| 603 | + return '<a href="' . htmlspecialchars( $url ) . '">' . |
| 604 | + htmlspecialchars( $linkText ) . |
| 605 | + '</a>'; |
| 606 | + } |
| 607 | + |
| 608 | + /** |
| 609 | + * Overridden by WebInstaller to provide lastPage parameters |
| 610 | + */ |
| 611 | + protected function getDocUrl( $page ) { |
| 612 | + return "{$_SERVER['PHP_SELF']}?page=" . urlencode( $attribs['href'] ); |
| 613 | + } |
524 | 614 | } |
525 | 615 | |
526 | 616 | /** |
Index: branches/new-installer/phase3/includes/installer/SqliteInstaller.php |
— | — | @@ -28,15 +28,15 @@ |
29 | 29 | |
30 | 30 | function getConnectForm() { |
31 | 31 | return |
32 | | - $this->getLabelledTextBox( 'wgSQLiteDataDir', 'config-sqlite-dir' ) . |
| 32 | + $this->getTextBox( 'wgSQLiteDataDir', 'config-sqlite-dir' ) . |
33 | 33 | $this->parent->getHelpBox( 'config-sqlite-dir-help' ) . |
34 | | - $this->getLabelledTextBox( 'wgDBname', 'config-db-name' ) . |
| 34 | + $this->getTextBox( 'wgDBname', 'config-db-name' ) . |
35 | 35 | $this->parent->getHelpBox( 'config-sqlite-name-help' ); |
36 | 36 | } |
37 | 37 | |
38 | 38 | function submitConnectForm() { |
39 | 39 | global $wgSQLiteDataDirMode, $wgSQLiteDataDir; |
40 | | - $newValues = $this->setVarsFromRequest(); |
| 40 | + $newValues = $this->setVarsFromRequest( array( 'wgSQLiteDataDir', 'wgDBname' ) ); |
41 | 41 | $dir = $newValues['wgSQLiteDataDir']; |
42 | 42 | if ( !is_dir( $dir ) ) { |
43 | 43 | if ( !is_writable( dirname( $dir ) ) ) { |
— | — | @@ -55,17 +55,46 @@ |
56 | 56 | return Status::newFatal( 'config-sqlite-unwritable', $dir ); |
57 | 57 | } |
58 | 58 | return Status::newGood(); |
59 | | - /* -- during install: |
| 59 | + } |
| 60 | + |
| 61 | + function getConnection() { |
60 | 62 | $status = Status::newGood(); |
| 63 | + $dir = $this->getVar( 'wgSQLiteDataDir' ); |
| 64 | + $dbName = $this->getVar( 'wgDBname' ); |
| 65 | + |
61 | 66 | try { |
62 | 67 | # FIXME: need more sensible constructor parameters, e.g. single associative array |
63 | 68 | # Setting globals kind of sucks |
64 | 69 | $wgSQLiteDataDir = $dir; |
65 | | - $this->conn = new DatabaseSqlite( false, false, false, $newValues['wgDBname'] ); |
| 70 | + $this->conn = new DatabaseSqlite( false, false, false, $dbName ); |
| 71 | + return $this->conn; |
66 | 72 | } catch ( DBConnectionError $e ) { |
67 | 73 | $status->fatal( 'config-sqlite-connection-error', $e->getMessage() ); |
68 | 74 | } |
69 | 75 | return $status; |
70 | | - */ |
71 | 76 | } |
| 77 | + |
| 78 | + function needsUpgrade() { |
| 79 | + $dir = $this->getVar( 'wgSQLiteDataDir' ); |
| 80 | + $dbName = $this->getVar( 'wgDBname' ); |
| 81 | + // Don't create the data file yet |
| 82 | + if ( !file_exists( "$dir/$dbName.sqlite" ) ) { |
| 83 | + return false; |
| 84 | + } |
| 85 | + |
| 86 | + // If the data file exists, look inside it |
| 87 | + return parent::needsUpgrade(); |
| 88 | + } |
| 89 | + |
| 90 | + function getSettingsForm() { |
| 91 | + return false; |
| 92 | + } |
| 93 | + |
| 94 | + function submitSettingsForm() { |
| 95 | + return Status::newGood(); |
| 96 | + } |
| 97 | + |
| 98 | + function install() { |
| 99 | + echo "TODO"; |
| 100 | + } |
72 | 101 | } |
Index: branches/new-installer/phase3/includes/installer/MysqlInstaller.php |
— | — | @@ -12,13 +12,22 @@ |
13 | 13 | ); |
14 | 14 | |
15 | 15 | var $internalDefaults = array( |
16 | | - '_MysqlInstallUser' => 'root', |
17 | | - '_MysqlInstallPassword' => '', |
18 | | - '_MysqlSameAccount' => true, |
| 16 | + '_MysqlEngine' => 'InnoDB', |
| 17 | + '_MysqlCharset' => 'binary', |
19 | 18 | ); |
20 | 19 | |
| 20 | + var $supportedEngines = array( 'InnoDB', 'MyISAM' ); |
| 21 | + |
21 | 22 | var $minimumVersion = '4.0.14'; |
22 | 23 | |
| 24 | + var $webUserPrivs = array( |
| 25 | + 'DELETE', |
| 26 | + 'INSERT', |
| 27 | + 'SELECT', |
| 28 | + 'UPDATE', |
| 29 | + 'CREATE TEMPORARY TABLES', |
| 30 | + ); |
| 31 | + |
23 | 32 | var $conn; |
24 | 33 | |
25 | 34 | function getName() { |
— | — | @@ -43,26 +52,21 @@ |
44 | 53 | |
45 | 54 | function getConnectForm() { |
46 | 55 | return |
47 | | - $this->getLabelledTextBox( 'wgDBserver', 'config-db-host' ) . |
| 56 | + $this->getTextBox( 'wgDBserver', 'config-db-host' ) . |
48 | 57 | $this->parent->getHelpBox( 'config-db-host-help' ) . |
49 | 58 | Xml::openElement( 'fieldset' ) . |
50 | 59 | Xml::element( 'legend', array(), wfMsg( 'config-db-wiki-settings' ) ) . |
51 | | - $this->getLabelledTextBox( 'wgDBname', 'config-db-name' ) . |
| 60 | + $this->getTextBox( 'wgDBname', 'config-db-name' ) . |
52 | 61 | $this->parent->getHelpBox( 'config-db-name-help' ) . |
53 | | - $this->getLabelledTextBox( 'wgDBprefix', 'config-db-prefix' ) . |
| 62 | + $this->getTextBox( 'wgDBprefix', 'config-db-prefix' ) . |
54 | 63 | $this->parent->getHelpBox( 'config-db-prefix-help' ) . |
55 | 64 | Xml::closeElement( 'fieldset' ) . |
56 | | - Xml::openElement( 'fieldset' ) . |
57 | | - Xml::element( 'legend', array(), wfMsg( 'config-db-install-account' ) ) . |
58 | | - $this->getLabelledTextBox( '_MysqlInstallUser', 'config-db-username' ) . |
59 | | - $this->getLabelledPasswordBox( '_MysqlInstallPassword', 'config-db-password' ) . |
60 | | - $this->parent->getHelpBox( 'config-db-install-help' ) . |
61 | | - Xml::closeElement( 'fieldset' ); |
| 65 | + $this->getInstallUserBox(); |
62 | 66 | } |
63 | 67 | |
64 | 68 | function submitConnectForm() { |
65 | 69 | // Get variables from the request |
66 | | - $newValues = $this->setVarsFromRequest(); |
| 70 | + $newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBname', 'wgDBprefix' ) ); |
67 | 71 | |
68 | 72 | // Validate them |
69 | 73 | $status = Status::newGood(); |
— | — | @@ -78,14 +82,21 @@ |
79 | 83 | return $status; |
80 | 84 | } |
81 | 85 | |
| 86 | + // Submit user box |
| 87 | + $status = $this->submitInstallUserBox(); |
| 88 | + if ( !$status->isOK() ) { |
| 89 | + return $status; |
| 90 | + } |
| 91 | + |
82 | 92 | // Try to connect |
83 | | - $status = $this->attemptConnection(); |
| 93 | + $status = $this->getConnection(); |
84 | 94 | if ( !$status->isOK() ) { |
85 | 95 | return $status; |
86 | 96 | } |
| 97 | + $conn = $status->value; |
87 | 98 | |
88 | 99 | // Check version |
89 | | - $version = $this->conn->getServerVersion(); |
| 100 | + $version = $conn->getServerVersion(); |
90 | 101 | if ( version_compare( $version, $this->minimumVersion ) < 0 ) { |
91 | 102 | return Status::newFatal( 'config-mysql-old', $this->minimumVersion, $version ); |
92 | 103 | } |
— | — | @@ -93,39 +104,33 @@ |
94 | 105 | return $status; |
95 | 106 | } |
96 | 107 | |
97 | | - function attemptConnection() { |
| 108 | + function getConnection() { |
98 | 109 | $status = Status::newGood(); |
99 | 110 | try { |
100 | 111 | $this->conn = new Database( |
101 | 112 | $this->getVar( 'wgDBserver' ), |
102 | | - $this->getVar( '_MysqlInstallUser' ), |
103 | | - $this->getVar( '_MysqlInstallPassword' ), |
| 113 | + $this->getVar( '_InstallUser' ), |
| 114 | + $this->getVar( '_InstallPassword' ), |
104 | 115 | false, |
105 | 116 | false, |
106 | 117 | 0, |
107 | 118 | $this->getVar( 'wgDBprefix' ) |
108 | 119 | ); |
| 120 | + $status->value = $this->conn; |
| 121 | + return $status; |
109 | 122 | } catch ( DBConnectionError $e ) { |
110 | 123 | $status->fatal( 'config-connection-error', $e->getMessage() ); |
111 | 124 | } |
112 | 125 | return $status; |
113 | 126 | } |
114 | 127 | |
115 | | - function getConnection() { |
116 | | - $status = $this->attemptConnection(); |
117 | | - if ( $status->isOK() ) { |
118 | | - return $this->conn; |
119 | | - } else { |
120 | | - return $status; |
121 | | - } |
122 | | - } |
123 | | - |
124 | 128 | function doUpgrade() { |
125 | | - $conn = $this->getConnection(); |
126 | | - if ( $conn instanceof Status ) { |
127 | | - $this->parent->showStatusError( $conn ); |
| 129 | + $status = $this->getConnection(); |
| 130 | + if ( !$status->isOK() ) { |
| 131 | + $this->parent->showStatusError( $status ); |
128 | 132 | return; |
129 | 133 | } |
| 134 | + $conn = $status->value; |
130 | 135 | |
131 | 136 | # Determine existing default character set |
132 | 137 | if ( $conn->tableExists( "revision" ) ) { |
— | — | @@ -154,44 +159,218 @@ |
155 | 160 | } |
156 | 161 | } |
157 | 162 | } |
158 | | - |
159 | | - // TODO... |
160 | | - return; |
| 163 | + |
| 164 | + // TODO |
| 165 | + } |
161 | 166 | |
162 | | - # Create user if required |
163 | | - if ( $conf->Root ) { |
164 | | - $conn = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 ); |
165 | | - if ( $conn->isOpen() ) { |
166 | | - print "<li>DB user account ok</li>\n"; |
167 | | - $conn->close(); |
168 | | - } else { |
169 | | - print "<li>Granting user permissions..."; |
170 | | - if( $mysqlOldClient && $mysqlNewAuth ) { |
171 | | - print " <b class='error'>If the next step fails, see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'>http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>"; |
172 | | - } |
173 | | - print "</li>\n"; |
174 | | - dbsource( "../maintenance/users.sql", $conn ); |
| 167 | + /** |
| 168 | + * Get a list of storage engines that are available and supported |
| 169 | + */ |
| 170 | + function getEngines() { |
| 171 | + $engines = array( 'InnoDB', 'MyISAM' ); |
| 172 | + $status = $this->getConnection(); |
| 173 | + if ( !$status->isOK() ) { |
| 174 | + return $engines; |
| 175 | + } |
| 176 | + $conn = $status->value; |
| 177 | + |
| 178 | + $version = $conn->getServerVersion(); |
| 179 | + if ( version_compare( $version, "4.1.2", "<" ) ) { |
| 180 | + // No SHOW ENGINES in this version |
| 181 | + return $engines; |
| 182 | + } |
| 183 | + |
| 184 | + $engines = array(); |
| 185 | + $res = $conn->query( 'SHOW ENGINES' ); |
| 186 | + foreach ( $res as $row ) { |
| 187 | + $engines[] = $row->Engine; |
| 188 | + } |
| 189 | + $engines = array_intersect( $this->supportedEngines, $engines ); |
| 190 | + return $engines; |
| 191 | + } |
| 192 | + |
| 193 | + /** |
| 194 | + * Get a list of character sets that are available and supported |
| 195 | + */ |
| 196 | + function getCharsets() { |
| 197 | + $status = $this->getConnection(); |
| 198 | + $mysql5 = array( 'binary', 'utf-8' ); |
| 199 | + $mysql4 = array( 'mysql4' ); |
| 200 | + if ( !$status->isOK() ) { |
| 201 | + return $mysql5; |
| 202 | + } |
| 203 | + if ( version_compare( $status->value->getServerVersion(), '4.1.0', '>=' ) ) { |
| 204 | + return $mysql5; |
| 205 | + } |
| 206 | + return $mysql4; |
| 207 | + } |
| 208 | + |
| 209 | + /** |
| 210 | + * Return true if the install user can create accounts |
| 211 | + */ |
| 212 | + function canCreateAccounts() { |
| 213 | + $status = $this->getConnection(); |
| 214 | + if ( !$status->isOK() ) { |
| 215 | + return false; |
| 216 | + } |
| 217 | + $conn = $status->value; |
| 218 | + |
| 219 | + // Check version, need INFORMATION_SCHEMA and CREATE USER |
| 220 | + if ( version_compare( $conn->getServerVersion(), '5.0.2', '<' ) ) { |
| 221 | + return false; |
| 222 | + } |
| 223 | + |
| 224 | + // Get current account name |
| 225 | + $currentName = $conn->selectField( '', 'CURRENT_USER()', '', __METHOD__ ); |
| 226 | + $parts = explode( '@', $currentName ); |
| 227 | + if ( count( $parts ) != 2 ) { |
| 228 | + return false; |
| 229 | + } |
| 230 | + $quotedUser = $conn->addQuotes( $parts[0] ) . |
| 231 | + '@' . $conn->addQuotes( $parts[1] ); |
| 232 | + |
| 233 | + // The user needs to have INSERT on mysql.* to be able to CREATE USER |
| 234 | + // The grantee will be double-quoted in this query, as required |
| 235 | + $res = $conn->select( 'INFORMATION_SCHEMA.USER_PRIVILEGES', '*', |
| 236 | + array( 'GRANTEE' => $quotedUser ), __METHOD__ ); |
| 237 | + $insertMysql = false; |
| 238 | + $grantOptions = array_flip( $this->webUserPrivs ); |
| 239 | + foreach ( $res as $row ) { |
| 240 | + if ( $row->PRIVILEGE_TYPE == 'INSERT' ) { |
| 241 | + $insertMysql = true; |
175 | 242 | } |
| 243 | + if ( $row->IS_GRANTABLE ) { |
| 244 | + unset( $grantOptions[$row->PRIVILEGE_TYPE] ); |
| 245 | + } |
176 | 246 | } |
| 247 | + |
| 248 | + // Check for DB-specific privs for mysql.* |
| 249 | + if ( !$insertMysql ) { |
| 250 | + $row = $conn->selectRow( 'INFORMATION_SCHEMA.SCHEMA_PRIVILEGES', '*', |
| 251 | + array( |
| 252 | + 'GRANTEE' => $quotedUser, |
| 253 | + 'TABLE_SCHEMA' => 'mysql', |
| 254 | + 'PRIVILEGE_TYPE' => 'INSERT', |
| 255 | + ), __METHOD__ ); |
| 256 | + if ( $row ) { |
| 257 | + $insertMysql = true; |
| 258 | + } |
| 259 | + } |
| 260 | + |
| 261 | + if ( !$insertMysql ) { |
| 262 | + return false; |
| 263 | + } |
| 264 | + |
| 265 | + // Check for DB-level grant options |
| 266 | + $res = $conn->select( 'INFORMATION_SCHEMA.SCHEMA_PRIVILEGES', '*', |
| 267 | + array( |
| 268 | + 'GRANTEE' => $quotedUser, |
| 269 | + 'IS_GRANTABLE' => 1, |
| 270 | + ), __METHOD__ ); |
| 271 | + foreach ( $res as $row ) { |
| 272 | + $regex = $conn->likeToRegex( $row->TABLE_SCHEMA ); |
| 273 | + if ( preg_match( $regex, $this->getVar( 'wgDBname' ) ) ) { |
| 274 | + unset( $grantOptions[$row->PRIVILEGE_TYPE] ); |
| 275 | + } |
| 276 | + } |
| 277 | + if ( count( $grantOptions ) ) { |
| 278 | + // Can't grant everything |
| 279 | + return false; |
| 280 | + } |
| 281 | + return true; |
177 | 282 | } |
178 | 283 | |
179 | 284 | function getSettingsForm() { |
180 | | - $installUser = $this->getVar( '_MysqlInstallUser' ); |
181 | | - $installPass = $this->parent->getFakePassword( $this->getVar( '_MysqlInstallPassword' ) ); |
182 | | - $js = 'disableControlArray( "mysql__MysqlSameAccount", ' . |
183 | | - '["mysql_wgDBuser", "mysql_wgDBpassword"] )'; |
| 285 | + if ( $this->canCreateAccounts() ) { |
| 286 | + $noCreateMsg = false; |
| 287 | + } else { |
| 288 | + $noCreateMsg = 'config-db-web-no-create-privs'; |
| 289 | + } |
| 290 | + $s = $this->getWebUserBox( $noCreateMsg ); |
184 | 291 | |
185 | | - return |
186 | | - Xml::openElement( 'fieldset' ) . |
187 | | - Xml::element( 'legend', array(), wfMsg( 'config-db-web-account' ) ) . |
188 | | - $this->getLabelledCheckBox( |
189 | | - '_MysqlSameAccount', 'config-db-web-account-same', array( 'onclick' => $js ) |
190 | | - ) . |
191 | | - "<br/>\n" . |
192 | | - $this->getLabelledTextBox( 'wgDBuser', 'config-db-username' ) . |
193 | | - $this->getLabelledPasswordBox( 'wgDBpassword', 'config-db-password' ) . |
194 | | - $this->parent->getHelpBox( 'config-db-web-help' ) . |
195 | | - Xml::closeElement( 'fieldset' ) . |
196 | | - "<script type=\"text/javascript\">$js</script>"; |
| 292 | + // Do engine selector |
| 293 | + $engines = $this->getEngines(); |
| 294 | + // If the current default engine is not supported, use an engine that is |
| 295 | + if ( !in_array( $this->getVar( '_MysqlEngine' ), $engines ) ) { |
| 296 | + $this->setVar( '_MysqlEngine', reset( $engines ) ); |
| 297 | + } |
| 298 | + if ( count( $engines ) >= 2 ) { |
| 299 | + $s .= $this->getRadioSet( array( |
| 300 | + 'var' => '_MysqlEngine', |
| 301 | + 'label' => 'config-mysql-engine', |
| 302 | + 'itemLabelPrefix' => 'config-mysql-', |
| 303 | + 'values' => $engines |
| 304 | + )); |
| 305 | + $s .= $this->parent->getHelpBox( 'config-mysql-engine-help' ); |
| 306 | + } |
| 307 | + |
| 308 | + // If the current default charset is not supported, use a charset that is |
| 309 | + $charsets = $this->getCharsets(); |
| 310 | + if ( !in_array( $this->getVar( '_MysqlCharset' ), $charsets ) ) { |
| 311 | + $this->setVar( '_MysqlCharset', reset( $charsets ) ); |
| 312 | + } |
| 313 | + |
| 314 | + // Do charset selector |
| 315 | + if ( count( $charsets ) >= 2 ) { |
| 316 | + $s .= $this->getRadioSet( array( |
| 317 | + 'var' => '_MysqlCharset', |
| 318 | + 'label' => 'config-mysql-charset', |
| 319 | + 'itemLabelPrefix' => 'config-mysql-', |
| 320 | + 'values' => $charsets |
| 321 | + )); |
| 322 | + $s .= $this->parent->getHelpBox( 'config-mysql-charset-help' ); |
| 323 | + } |
| 324 | + |
| 325 | + return $s; |
197 | 326 | } |
| 327 | + |
| 328 | + function submitSettingsForm() { |
| 329 | + $newValues = $this->setVarsFromRequest( array( '_MysqlEngine', '_MysqlCharset' ) ); |
| 330 | + $status = $this->submitWebUserBox(); |
| 331 | + if ( !$status->isOK() ) { |
| 332 | + return $status; |
| 333 | + } |
| 334 | + |
| 335 | + // Validate the create checkbox |
| 336 | + $canCreate = $this->canCreateAccounts(); |
| 337 | + if ( !$canCreate ) { |
| 338 | + $this->setVar( '_CreateDBAccount', false ); |
| 339 | + $create = false; |
| 340 | + } else { |
| 341 | + $create = $this->getVar( '_CreateDBAccount' ); |
| 342 | + } |
| 343 | + |
| 344 | + if ( !$create ) { |
| 345 | + // Test the web account |
| 346 | + try { |
| 347 | + $webConn = new Database( |
| 348 | + $this->getVar( 'wgDBserver' ), |
| 349 | + $this->getVar( 'wgDBuser' ), |
| 350 | + $this->getVar( 'wgDBpassword' ), |
| 351 | + false, |
| 352 | + false, |
| 353 | + 0, |
| 354 | + $this->getVar( 'wgDBprefix' ) |
| 355 | + ); |
| 356 | + } catch ( DBConnectionError $e ) { |
| 357 | + return Status::newFatal( 'config-connection-error', $e->getMessage() ); |
| 358 | + } |
| 359 | + } |
| 360 | + |
| 361 | + // Validate engines and charsets |
| 362 | + // This is done pre-submit already so it's just for security |
| 363 | + $engines = $this->getEngines(); |
| 364 | + if ( !in_array( $this->getVar( '_MysqlEngine' ), $engines ) ) { |
| 365 | + $this->setVar( '_MysqlEngine', reset( $engines ) ); |
| 366 | + } |
| 367 | + $charsets = $this->getCharsets(); |
| 368 | + if ( !in_array( $this->getVar( '_MysqlCharset' ), $charsets ) ) { |
| 369 | + $this->setVar( '_MysqlCharset', reset( $charsets ) ); |
| 370 | + } |
| 371 | + return Status::newGood(); |
| 372 | + } |
| 373 | + |
| 374 | + function install() { |
| 375 | + echo "TODO"; |
| 376 | + } |
198 | 377 | } |
Index: branches/new-installer/phase3/includes/installer/PostgresInstaller.php |
— | — | @@ -39,28 +39,24 @@ |
40 | 40 | |
41 | 41 | function getConnectForm() { |
42 | 42 | return |
43 | | - $this->getLabelledTextBox( 'wgDBserver', 'config-db-host' ) . |
| 43 | + $this->getTextBox( 'wgDBserver', 'config-db-host' ) . |
44 | 44 | $this->parent->getHelpBox( 'config-db-host-help' ) . |
45 | | - $this->getLabelledTextBox( 'wgDBport', 'config-db-port' ) . |
| 45 | + $this->getTextBox( 'wgDBport', 'config-db-port' ) . |
46 | 46 | Xml::openElement( 'fieldset' ) . |
47 | 47 | Xml::element( 'legend', array(), wfMsg( 'config-db-wiki-settings' ) ) . |
48 | | - $this->getLabelledTextBox( 'wgDBname', 'config-db-name' ) . |
| 48 | + $this->getTextBox( 'wgDBname', 'config-db-name' ) . |
49 | 49 | $this->parent->getHelpBox( 'config-db-name-help' ) . |
50 | | - $this->getLabelledTextBox( 'wgDBmwschema', 'config-db-schema' ) . |
51 | | - $this->getLabelledTextBox( 'wgDBts2schema', 'config-db-ts2-schema' ) . |
| 50 | + $this->getTextBox( 'wgDBmwschema', 'config-db-schema' ) . |
| 51 | + $this->getTextBox( 'wgDBts2schema', 'config-db-ts2-schema' ) . |
52 | 52 | $this->parent->getHelpBox( 'config-db-schema-help' ) . |
53 | 53 | Xml::closeElement( 'fieldset' ) . |
54 | | - Xml::openElement( 'fieldset' ) . |
55 | | - Xml::element( 'legend', array(), wfMsg( 'config-db-install-account' ) ) . |
56 | | - $this->getLabelledTextBox( '_PostgresInstallUser', 'config-db-username' ) . |
57 | | - $this->getLabelledPasswordBox( '_PostgresInstallPassword', 'config-db-password' ) . |
58 | | - $this->parent->getHelpBox( 'config-db-install-help' ) . |
59 | | - Xml::closeElement( 'fieldset' ); |
| 54 | + $this->getInstallUserBox(); |
60 | 55 | } |
61 | 56 | |
62 | 57 | function submitConnectForm() { |
63 | 58 | // Get variables from the request |
64 | | - $newValues = $this->setVarsFromRequest(); |
| 59 | + $newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBport', |
| 60 | + 'wgDBname', 'wgDBmwschema', 'wgDBts2schema' ) ); |
65 | 61 | |
66 | 62 | // Validate them |
67 | 63 | $status = Status::newGood(); |
— | — | @@ -107,4 +103,24 @@ |
108 | 104 | return $status; |
109 | 105 | } |
110 | 106 | |
| 107 | + function getConnection() { |
| 108 | + $status = $this->attemptConnection(); |
| 109 | + if ( $status->isOK() ) { |
| 110 | + return $this->conn; |
| 111 | + } else { |
| 112 | + return $status; |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + function getSettingsForm() { |
| 117 | + return false; |
| 118 | + } |
| 119 | + |
| 120 | + function submitSettingsForm() { |
| 121 | + return Status::newGood(); |
| 122 | + } |
| 123 | + |
| 124 | + function install() { |
| 125 | + echo "TODO"; |
| 126 | + } |
111 | 127 | } |
Index: branches/new-installer/phase3/includes/installer/InstallerDBType.php |
— | — | @@ -7,6 +7,70 @@ |
8 | 8 | /** The Installer object */ |
9 | 9 | var $parent; |
10 | 10 | |
| 11 | + /** |
| 12 | + * Return the internal name, e.g. 'mysql', or 'sqlite' |
| 13 | + */ |
| 14 | + abstract function getName(); |
| 15 | + |
| 16 | + /** |
| 17 | + * @return true if the client library is compiled in |
| 18 | + */ |
| 19 | + abstract function isCompiled(); |
| 20 | + |
| 21 | + /** |
| 22 | + * Get an array of MW configuration globals that will be configured by this class. |
| 23 | + */ |
| 24 | + abstract function getGlobalNames(); |
| 25 | + |
| 26 | + /** |
| 27 | + * Get HTML for a web form that configures this database. Configuration |
| 28 | + * at this time should be the minimum needed to connect and test |
| 29 | + * whether install or upgrade is required. |
| 30 | + * |
| 31 | + * If this is called, $this->parent can be assumed to be a WebInstaller |
| 32 | + */ |
| 33 | + abstract function getConnectForm(); |
| 34 | + |
| 35 | + /** |
| 36 | + * Set variables based on the request array, assuming it was submitted |
| 37 | + * via the form returned by getConnectForm(). Validate the connection |
| 38 | + * settings by attempting to connect with them. |
| 39 | + * |
| 40 | + * If this is called, $this->parent can be assumed to be a WebInstaller |
| 41 | + * |
| 42 | + * @return Status |
| 43 | + */ |
| 44 | + abstract function submitConnectForm(); |
| 45 | + |
| 46 | + /** |
| 47 | + * Get HTML for a web form that retrieves settings used for installation. |
| 48 | + * $this->parent can be assumed to be a WebInstaller. |
| 49 | + * If the DB type has no settings beyond those already configured with |
| 50 | + * getConnectForm(), this should return false. |
| 51 | + */ |
| 52 | + abstract function getSettingsForm(); |
| 53 | + |
| 54 | + /** |
| 55 | + * Set variables based on the request array, assuming it was submitted via |
| 56 | + * the form return by getSettingsForm(). |
| 57 | + * @return Status |
| 58 | + */ |
| 59 | + abstract function submitSettingsForm(); |
| 60 | + |
| 61 | + /** |
| 62 | + * Connect to the database using the administrative user/password currently |
| 63 | + * defined in the session. On success, return the connection, on failure, |
| 64 | + * return a Status object. |
| 65 | + * |
| 66 | + * This may be called multiple times, so the result should be cached. |
| 67 | + */ |
| 68 | + abstract function getConnection(); |
| 69 | + |
| 70 | + /** |
| 71 | + * Create a database and MediaWiki tables with the configured settings |
| 72 | + */ |
| 73 | + abstract function install(); |
| 74 | + |
11 | 75 | /** |
12 | 76 | * Construct and initialise parent. |
13 | 77 | * This is typically only called from Installer::getDBInstaller() |
— | — | @@ -28,26 +92,11 @@ |
29 | 93 | } |
30 | 94 | |
31 | 95 | /** |
32 | | - * Return the internal name, e.g. 'mysql', or 'sqlite' |
33 | | - */ |
34 | | - abstract function getName(); |
35 | | - |
36 | | - /** |
37 | 96 | * Get the internationalised name for this DBMS |
38 | 97 | */ |
39 | 98 | function getReadableName() { |
40 | 99 | return wfMsg( 'config-type-' . $this->getName() ); |
41 | 100 | } |
42 | | - |
43 | | - /** |
44 | | - * @return true if the client library is compiled in |
45 | | - */ |
46 | | - abstract function isCompiled(); |
47 | | - |
48 | | - /** |
49 | | - * Get an array of MW configuration globals that will be configured by this class. |
50 | | - */ |
51 | | - abstract function getGlobalNames(); |
52 | 101 | |
53 | 102 | /** |
54 | 103 | * Get a name=>value map of MW configuration globals that overrides |
— | — | @@ -65,19 +114,6 @@ |
66 | 115 | } |
67 | 116 | |
68 | 117 | /** |
69 | | - * Get HTML for a web form that configures this database |
70 | | - * If this is called, $this->parent can be assumed to be a WebInstaller |
71 | | - */ |
72 | | - abstract function getConnectForm(); |
73 | | - |
74 | | - /** |
75 | | - * Set variables based on the request array, assuming it was submitted |
76 | | - * via the form returned by getConnectForm() |
77 | | - * If this is called, $this->parent can be assumed to be a WebInstaller |
78 | | - */ |
79 | | - abstract function submitConnectForm(); |
80 | | - |
81 | | - /** |
82 | 118 | * Get a variable, taking local defaults into account |
83 | 119 | */ |
84 | 120 | function getVar( $var, $default = null ) { |
— | — | @@ -92,72 +128,170 @@ |
93 | 129 | } |
94 | 130 | |
95 | 131 | /** |
96 | | - * Convenience function for a labelled text box to configure a variable |
| 132 | + * Convenience alias for $this->parent->setVar() |
97 | 133 | */ |
98 | | - function getLabelledTextBox( $var, $label ) { |
| 134 | + function setVar( $name, $value ) { |
| 135 | + $this->parent->setVar( $name, $value ); |
| 136 | + } |
| 137 | + |
| 138 | + /** |
| 139 | + * Get a labelled text box to configure a local variable |
| 140 | + */ |
| 141 | + function getTextBox( $var, $label, $attribs = array() ) { |
99 | 142 | $name = $this->getName() . '_' . $var; |
100 | 143 | $value = $this->getVar( $var ); |
101 | | - return |
102 | | - "<div class=\"config-input\">\n" . |
103 | | - $this->parent->getLabel( $label, $name ) . |
104 | | - $this->parent->getTextBox( $name, $value ) . |
105 | | - "</div>\n"; |
| 144 | + return $this->parent->getTextBox( array( |
| 145 | + 'var' => $var, |
| 146 | + 'label' => $label, |
| 147 | + 'attribs' => $attribs, |
| 148 | + 'controlName' => $name, |
| 149 | + 'value' => $value |
| 150 | + ) ); |
106 | 151 | } |
107 | 152 | |
108 | 153 | /** |
109 | | - * Convenience function for a labelled password box. |
| 154 | + * Get a labelled password box to configure a local variable |
110 | 155 | * Implements password hiding |
111 | 156 | */ |
112 | | - function getLabelledPasswordBox( $var, $label ) { |
| 157 | + function getPasswordBox( $var, $label, $attribs = array() ) { |
113 | 158 | $name = $this->getName() . '_' . $var; |
114 | | - $realPassword = $this->getVar( $var ); |
115 | | - if ( strlen( $var ) ) { |
116 | | - $fakeValue = $this->parent->getFakePassword( $realPassword ); |
117 | | - } else { |
118 | | - $fakeValue = ''; |
119 | | - } |
120 | | - return |
121 | | - "<div class=\"config-input\">\n" . |
122 | | - $this->parent->getLabel( $label, $name ) . |
123 | | - $this->parent->getTextBox( $name, $fakeValue, 'password' ) . |
124 | | - "</div>\n"; |
| 159 | + $value = $this->getVar( $var ); |
| 160 | + return $this->parent->getPasswordBox( array( |
| 161 | + 'var' => $var, |
| 162 | + 'label' => $label, |
| 163 | + 'attribs' => $attribs, |
| 164 | + 'controlName' => $name, |
| 165 | + 'value' => $value |
| 166 | + ) ); |
125 | 167 | } |
126 | 168 | |
127 | 169 | /** |
128 | | - * Convenience function for a labelled checkbox |
| 170 | + * Get a labelled checkbox to configure a local boolean variable |
129 | 171 | */ |
130 | | - function getLabelledCheckBox( $var, $label, $attribs = array() ) { |
| 172 | + function getCheckBox( $var, $label, $attribs = array() ) { |
131 | 173 | $name = $this->getName() . '_' . $var; |
132 | 174 | $value = $this->getVar( $var ); |
133 | | - return |
134 | | - "<div class=\"config-input-check\">\n" . |
135 | | - "<label>\n" . |
136 | | - $this->parent->getCheckBox( $name, $value, $attribs ) . "\n" . |
137 | | - wfMsgHtml( $label ) . "\n" . |
138 | | - "</label>\n" . |
139 | | - "</div>\n"; |
| 175 | + return $this->parent->getCheckBox( array( |
| 176 | + 'var' => $var, |
| 177 | + 'label' => $label, |
| 178 | + 'attribs' => $attribs, |
| 179 | + 'controlName' => $name, |
| 180 | + 'value' => $value, |
| 181 | + )); |
140 | 182 | } |
141 | 183 | |
142 | 184 | /** |
143 | | - * Convenience function to set variables based on form data |
144 | | - * Has some heuristics that may need to be overridden in child classes. |
| 185 | + * Get a set of labelled radio buttons |
| 186 | + * |
| 187 | + * @param array $params |
| 188 | + * Parameters are: |
| 189 | + * var: The variable to be configured (required) |
| 190 | + * label: The message name for the label (required) |
| 191 | + * itemLabelPrefix: The message name prefix for the item labels (required) |
| 192 | + * values: List of allowed values (required) |
| 193 | + * itemAttribs Array of attribute arrays, outer key is the value name (optional) |
| 194 | + * |
145 | 195 | */ |
146 | | - function setVarsFromRequest() { |
147 | | - $newValues = array(); |
148 | | - $varNames = array_merge( $this->getGlobalNames(), |
149 | | - array_keys( $this->getInternalDefaults() ) ); |
150 | | - foreach ( $varNames as $name ) { |
151 | | - $value = $this->parent->request->getVal( $this->getName() . '_' . $name ); |
152 | | - $newValues[$name] = $value; |
153 | | - if ( $value !== null ) { |
154 | | - if ( stripos( $name, 'password' ) !== false ) { |
155 | | - $this->parent->setPassword( $name, $value ); |
156 | | - } else { |
157 | | - $this->parent->setVar( $name, $value ); |
158 | | - } |
159 | | - } |
| 196 | + function getRadioSet( $params ) { |
| 197 | + $params['controlName'] = $this->getName() . '_' . $params['var']; |
| 198 | + $params['value'] = $this->getVar( $params['var'] ); |
| 199 | + return $this->parent->getRadioSet( $params ); |
| 200 | + } |
| 201 | + |
| 202 | + /** |
| 203 | + * Convenience function to set variables based on form data. |
| 204 | + * Assumes that variables containing "password" in the name are (potentially |
| 205 | + * fake) passwords. |
| 206 | + * @param array $varNames |
| 207 | + */ |
| 208 | + function setVarsFromRequest( $varNames ) { |
| 209 | + return $this->parent->setVarsFromRequest( $varNames, $this->getName() . '_' ); |
| 210 | + } |
| 211 | + |
| 212 | + /** |
| 213 | + * Determine whether an existing installation of MediaWiki is present in |
| 214 | + * the configured administrative connection. Returns true if there is |
| 215 | + * such a wiki, false if the database doesn't exist. |
| 216 | + * |
| 217 | + * Traditionally, this is done by testing for the existence of either |
| 218 | + * the revision table or the cur table. |
| 219 | + * |
| 220 | + * @return boolean |
| 221 | + */ |
| 222 | + function needsUpgrade() { |
| 223 | + $status = $this->getConnection(); |
| 224 | + if ( !$status->isOK() ) { |
| 225 | + return false; |
160 | 226 | } |
161 | | - return $newValues; |
| 227 | + $conn = $status->value; |
| 228 | + if ( !$conn->selectDB( $this->getVar( 'wgDBname' ) ) ) { |
| 229 | + return false; |
| 230 | + } |
| 231 | + return $conn->tableExists( 'cur' ) || $conn->tableExists( 'revision' ); |
162 | 232 | } |
| 233 | + |
| 234 | + /** |
| 235 | + * Get a standard install-user fieldset |
| 236 | + */ |
| 237 | + function getInstallUserBox() { |
| 238 | + return |
| 239 | + Xml::openElement( 'fieldset' ) . |
| 240 | + Xml::element( 'legend', array(), wfMsg( 'config-db-install-account' ) ) . |
| 241 | + $this->getTextBox( '_InstallUser', 'config-db-username' ) . |
| 242 | + $this->getPasswordBox( '_InstallPassword', 'config-db-password' ) . |
| 243 | + $this->parent->getHelpBox( 'config-db-install-help' ) . |
| 244 | + Xml::closeElement( 'fieldset' ); |
| 245 | + } |
| 246 | + |
| 247 | + /** |
| 248 | + * Submit a standard install user fieldset |
| 249 | + */ |
| 250 | + function submitInstallUserBox() { |
| 251 | + $this->setVarsFromRequest( array( '_InstallUser', '_InstallPassword' ) ); |
| 252 | + return Status::newGood(); |
| 253 | + } |
| 254 | + |
| 255 | + /** |
| 256 | + * Get a standard web-user fieldset |
| 257 | + * @param string $noCreateMsg Message to display instead of the creation checkbox. |
| 258 | + * Set this to false to show a creation checkbox. |
| 259 | + */ |
| 260 | + function getWebUserBox( $noCreateMsg = false ) { |
| 261 | + $name = $this->getName(); |
| 262 | + $js = "disableControlArray( \"{$name}__SameAccount\", " . |
| 263 | + "[\"{$name}_wgDBuser\", \"{$name}_wgDBpassword\", \"{$name}__CreateDBAccount\"] )"; |
| 264 | + $s = Xml::openElement( 'fieldset' ) . |
| 265 | + Xml::element( 'legend', array(), wfMsg( 'config-db-web-account' ) ) . |
| 266 | + $this->getCheckBox( |
| 267 | + '_SameAccount', 'config-db-web-account-same', array( 'onclick' => $js ) |
| 268 | + ) . |
| 269 | + "<br/>\n" . |
| 270 | + $this->getTextBox( 'wgDBuser', 'config-db-username' ) . |
| 271 | + $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) . |
| 272 | + $this->parent->getHelpBox( 'config-db-web-help' ); |
| 273 | + if ( $noCreateMsg ) { |
| 274 | + $s .= $this->parent->getHelpBox( $noCreateMsg ); |
| 275 | + } else { |
| 276 | + $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' ); |
| 277 | + } |
| 278 | + $s .= Xml::closeElement( 'fieldset' ) . |
| 279 | + "<script type=\"text/javascript\">$js</script>"; |
| 280 | + return $s; |
| 281 | + } |
| 282 | + |
| 283 | + /** |
| 284 | + * Submit the form from getWebUserBox(). |
| 285 | + * @return Status |
| 286 | + */ |
| 287 | + function submitWebUserBox() { |
| 288 | + $this->setVarsFromRequest( array( 'wgDBuser', 'wgDBpassword', |
| 289 | + '_SameAccount', '_CreateDBAccount' ) ); |
| 290 | + if ( $this->getVar( '_SameAccount' ) ) { |
| 291 | + $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) ); |
| 292 | + $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) ); |
| 293 | + } |
| 294 | + return Status::newGood(); |
| 295 | + } |
| 296 | + |
163 | 297 | } |
164 | 298 | |
Index: branches/new-installer/phase3/includes/SkinTemplate.php |
— | — | @@ -143,6 +143,7 @@ |
144 | 144 | global $wgPageShowWatchingUsers; |
145 | 145 | global $wgUseTrackbacks, $wgUseSiteJs; |
146 | 146 | global $wgArticlePath, $wgScriptPath, $wgServer, $wgLang, $wgCanonicalNamespaceNames; |
| 147 | + global $wgLogoHeight; |
147 | 148 | |
148 | 149 | wfProfileIn( __METHOD__ ); |
149 | 150 | |
— | — | @@ -264,6 +265,11 @@ |
265 | 266 | $tpl->setRef( 'scriptpath', $wgScriptPath ); |
266 | 267 | $tpl->setRef( 'serverurl', $wgServer ); |
267 | 268 | $tpl->setRef( 'logopath', $wgLogo ); |
| 269 | + if ( strval( $wgLogo ) == '' ) { |
| 270 | + $tpl->set( 'logoHeight', 10 ); |
| 271 | + } else { |
| 272 | + $tpl->set( 'logoHeight', $wgLogoHeight ); |
| 273 | + } |
268 | 274 | $tpl->setRef( "lang", $wgContLanguageCode ); |
269 | 275 | $tpl->set( 'dir', $wgContLang->isRTL() ? "rtl" : "ltr" ); |
270 | 276 | $tpl->set( 'rtl', $wgContLang->isRTL() ); |
Index: branches/new-installer/phase3/includes/DefaultSettings.php |
— | — | @@ -155,12 +155,14 @@ |
156 | 156 | $wgUploadPath = false; ///< defaults to "{$wgScriptPath}/images" |
157 | 157 | $wgUploadDirectory = false; ///< defaults to "{$IP}/images" |
158 | 158 | $wgHashedUploadDirectory = true; |
159 | | -$wgLogo = false; ///< defaults to "{$wgStylePath}/common/images/wiki.png" |
| 159 | +$wgLogo = false; |
| 160 | +$wgLogoHeight = 135; |
160 | 161 | $wgFavicon = '/favicon.ico'; |
161 | 162 | $wgAppleTouchIcon = false; ///< This one'll actually default to off. For iPhone and iPod Touch web app bookmarks |
162 | 163 | $wgMathPath = false; ///< defaults to "{$wgUploadPath}/math" |
163 | 164 | $wgMathDirectory = false; ///< defaults to "{$wgUploadDirectory}/math" |
164 | 165 | $wgTmpDirectory = false; ///< defaults to "{$wgUploadDirectory}/tmp" |
| 166 | +$wgDeletedDirectory = false; ///< defaults to "{$wgUploadDirectory}/deleted" |
165 | 167 | $wgUploadBaseUrl = ""; |
166 | 168 | /**@}*/ |
167 | 169 | |
— | — | @@ -177,7 +179,7 @@ |
178 | 180 | * |
179 | 181 | */ |
180 | 182 | $wgFileStore = array(); |
181 | | -$wgFileStore['deleted']['directory'] = false;///< Defaults to $wgUploadDirectory/deleted |
| 183 | +$wgFileStore['deleted']['directory'] = false;///< Defaults to $wgDeletedDirectory |
182 | 184 | $wgFileStore['deleted']['url'] = null; ///< Private |
183 | 185 | $wgFileStore['deleted']['hash'] = 3; ///< 3-level subdirectory split |
184 | 186 | |
Index: branches/new-installer/phase3/config/new-index.php |
— | — | @@ -4,15 +4,20 @@ |
5 | 5 | define( 'MW_CONFIG_CALLBACK', 'wfInstallerConfig' ); |
6 | 6 | |
7 | 7 | function wfInstallerConfig() { |
| 8 | + // Don't access the database |
8 | 9 | $GLOBALS['wgUseDatabaseMessages'] = false; |
9 | 10 | $GLOBALS['wgLBFactoryConf'] = array( 'class' => 'LBFactory_InstallerFake' ); |
| 11 | + // Debug-friendly |
10 | 12 | $GLOBALS['wgShowExceptionDetails'] = true; |
| 13 | + // Don't break forms |
| 14 | + $GLOBALS['wgExternalLinkTarget'] = '_blank'; |
11 | 15 | } |
12 | 16 | |
13 | 17 | chdir( ".." ); |
14 | 18 | require( './includes/WebStart.php' ); |
15 | 19 | |
16 | 20 | $installer = new WebInstaller( $wgRequest ); |
| 21 | +$wgParser->setHook( 'doclink', array( $installer, 'docLink' ) ); |
17 | 22 | |
18 | 23 | if ( !$installer->startSession() ) { |
19 | 24 | $installer->finish(); |
— | — | @@ -30,6 +35,9 @@ |
31 | 36 | } |
32 | 37 | $wgLang = Language::factory( $langCode ); |
33 | 38 | |
| 39 | +$wgMetaNamspace = $wgCanonicalNamespaceNames[NS_PROJECT]; |
| 40 | + |
34 | 41 | $session = $installer->execute( $session ); |
| 42 | + |
35 | 43 | $_SESSION['installData'] = $session; |
36 | 44 | |
Index: branches/new-installer/phase3/languages/messages/MessagesEn.php |
— | — | @@ -3710,6 +3710,8 @@ |
3711 | 3711 | Please restart the installation process.', |
3712 | 3712 | 'config-no-session' => 'Your session data was lost! |
3713 | 3713 | Please check your php.ini and make sure session.save_path is set to an appropriate directory.', |
| 3714 | +'config-show-help' => 'Help', |
| 3715 | +'config-hide-help' => 'Hide help', |
3714 | 3716 | 'config-your-language' => 'Your language:', |
3715 | 3717 | 'config-your-language-help' => 'Select a language to use during the installation process', |
3716 | 3718 | 'config-wiki-language' => 'Wiki language:', |
— | — | @@ -3717,25 +3719,51 @@ |
3718 | 3720 | 'config-back' => '< Back', |
3719 | 3721 | 'config-continue' => 'Continue >', |
3720 | 3722 | 'config-page-language' => 'Language', |
3721 | | -'config-page-environment' => 'Environment', |
| 3723 | +'config-page-welcome' => 'Welcome', |
3722 | 3724 | 'config-page-dbconnect' => 'Connect to DB', |
3723 | 3725 | 'config-page-upgrade' => 'Upgrade existing', |
3724 | 3726 | 'config-page-dbsettings' => 'DB settings', |
3725 | | -'config-page-identity' => 'Identity', |
3726 | | -'config-page-license' => 'License', |
3727 | | -'config-page-email' => 'Email', |
| 3727 | +'config-page-name' => 'Name', |
| 3728 | +'config-page-options' => 'Options', |
3728 | 3729 | 'config-page-install' => 'Install', |
3729 | 3730 | 'config-page-complete' => 'Complete!', |
3730 | 3731 | 'config-page-restart' => 'Restart installation', |
| 3732 | +'config-page-readme' => 'Read me', |
| 3733 | +'config-page-releasenotes' => 'Release notes', |
| 3734 | +'config-page-copying' => 'Copying', |
3731 | 3735 | 'config-help-restart' => 'Do you want to clear all saved data that you have entered, and restart the installation process?', |
3732 | 3736 | 'config-restart' => 'Yes, restart it', |
| 3737 | +'config-welcome' => 'Welcome to MediaWiki! |
3733 | 3738 | |
| 3739 | +=== Technical data === |
| 3740 | + |
| 3741 | +Below is some technical data that you can provide to us if you need help during installation.', |
| 3742 | +'config-copyright' => " |
| 3743 | +=== Copyright and Terms === |
| 3744 | + |
| 3745 | +MediaWiki is Copyright © 2001-2008 by Magnus Manske, Brion Vibber, Lee Daniel Crocker, Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason, Niklas Laxström, Domas Mituzas, Rob Church, Yuri Astrakhan, Aryeh Gregor, Aaron Schulz and others. |
| 3746 | + |
| 3747 | +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
| 3748 | + |
| 3749 | +This program is distributed in the hope that it will be useful, but <strong>without any warranty</strong>; without even the implied warranty of <strong>merchantability</strong> or <strong>fitness for a particular purpose</strong>. See the GNU General Public License for more details. |
| 3750 | + |
| 3751 | +You should have received <doclink href=Copying>a copy of the GNU General Public License</doclink> along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. or [http://www.gnu.org/copyleft/gpl.html read it online]. |
| 3752 | +", |
| 3753 | +'config-sidebar' => " |
| 3754 | +* [http://www.mediawiki.org MediaWiki home] |
| 3755 | +* <doclink href=Readme>Readme</doclink> |
| 3756 | +* <doclink href=ReleaseNotes>Release notes</doclink> |
| 3757 | +* [http://www.mediawiki.org/wiki/Help:Contents User's Guide] |
| 3758 | +* [http://www.mediawiki.org/wiki/Manual:Contents Administrator's Guide] |
| 3759 | +* [http://www.mediawiki.org/wiki/Manual:FAQ FAQ] |
| 3760 | +", |
3734 | 3761 | 'config-env-good' => '<span class="success-message">Environment checked. You can install MediaWiki.</span>', |
3735 | 3762 | 'config-env-bad' => 'Cannot install MediaWiki.', |
3736 | 3763 | 'config-env-php' => 'PHP $1 installed', |
3737 | 3764 | 'config-no-db' => 'Could not find a suitable database driver!', |
3738 | 3765 | 'config-no-db-help' => 'You need to install a database driver for PHP. |
3739 | 3766 | The following database types are supported: $1. |
| 3767 | + |
3740 | 3768 | If you are on shared hosting, ask your hosting provider to install a suitable database driver. |
3741 | 3769 | If you compiled PHP yourself, reconfigure it with a database client enabled, for example using the ./configure --with-mysql. |
3742 | 3770 | If you installed PHP from a Debian or Ubuntu package, then you also need install the php5-mysql module.', |
— | — | @@ -3787,10 +3815,12 @@ |
3788 | 3816 | 'config-db-type' => 'DB type:', |
3789 | 3817 | 'config-db-host' => 'DB host:', |
3790 | 3818 | 'config-db-host-help' => 'If your database server isn\'t on your web server, enter the name or IP address here. |
| 3819 | + |
3791 | 3820 | If you are using a shared web host, your hosting provider should give you the correct host name in their documentation.', |
3792 | 3821 | 'config-db-wiki-settings' => 'Identify this wiki', |
3793 | 3822 | 'config-db-name' => 'DB name:', |
3794 | 3823 | 'config-db-name-help' => 'Choose a name that identifies your wiki. It should not contain spaces or hyphens. |
| 3824 | + |
3795 | 3825 | If you are using a shared host, your hosting provider will either give you a specific database name to use, or let you create databases via a control panel.', |
3796 | 3826 | 'config-db-install-account' => 'User account for installation', |
3797 | 3827 | 'config-db-username' => 'DB username:', |
— | — | @@ -3860,12 +3890,112 @@ |
3861 | 3891 | |
3862 | 3892 | 'config-db-web-account' => 'DB account for web access', |
3863 | 3893 | 'config-db-web-help' => 'Select the username and password that the web server will use to connect to the database server, during ordinary operation of the wiki. |
3864 | | - |
3865 | | -If the account specified does not exist, the installer will attempt to create it. |
3866 | 3894 | ', |
3867 | 3895 | 'config-db-web-account-same' => 'Use the same account as for installation', |
| 3896 | +'config-db-web-create' => 'Create the account if it doesn\'t already exist', |
| 3897 | +'config-db-web-no-create-privs' => 'The account you specified for installation does not have enough privileges to safely create accounts, so the account you specify here must already exist.', |
| 3898 | +'config-mysql-engine' => 'Storage engine', |
| 3899 | +'config-mysql-innodb' => 'InnoDB', |
| 3900 | +'config-mysql-myisam' => 'MyISAM', |
| 3901 | +'config-mysql-engine-help' => '<strong>InnoDB</strong> is best for public web installations, since it has good concurrency support. |
3868 | 3902 | |
| 3903 | +<strong>MyISAM</strong> may be faster in single-user installations. MyISAM databases tend to get corrupted more often than InnoDB databases. |
| 3904 | +', |
| 3905 | +'config-mysql-charset' => 'Database character set', |
| 3906 | +'config-mysql-binary' => 'Binary', |
| 3907 | +'config-mysql-utf-8' => 'UTF-8', |
| 3908 | +'config-mysql-charset-help' => "In '''binary mode''', MediaWiki stores UTF-8 text to the database in binary fields. This is more efficient than MySQL's UTF-8 mode, and allows you to use the full range of Unicode characters. |
3869 | 3909 | |
| 3910 | +In '''UTF-8 mode''', MySQL will know what character set your data is in, and can present and convert it appropriately, but it won't let you store characters above the [http://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane]. ", |
| 3911 | +'config-site-name' => 'Name of wiki:', |
| 3912 | +'config-site-name-help' => 'This will appear in the browser\'s title bar and various other places.', |
| 3913 | +'config-site-name-blank' => 'Please enter a site name.', |
| 3914 | +'config-project-namespace' => 'Project namespace', |
| 3915 | +'config-ns-generic' => 'Project', |
| 3916 | +'config-ns-site-name' => 'Same as the wiki name: ', |
| 3917 | +'config-ns-other' => 'Other (please specify)', |
| 3918 | +'config-project-namespace-help' => 'Following Wikipedia\'s example, many wikis keep their policy and help pages separate from their content pages, in a "<strong>project namespace</strong>". |
| 3919 | +All page titles in this namespace start with a certain prefix, which you can specify here. |
| 3920 | +Traditionally, this prefix is derived from the name of the wiki, but it cannot contain punctuation characters such as # or :', |
| 3921 | +'config-ns-invalid' => 'The specified namespace "<nowiki>$1</nowiki>" is invalid. Please specify a different project namespace', |
| 3922 | +'config-admin-box' => 'Administrator account', |
| 3923 | +'config-admin-name' => 'Your name:', |
| 3924 | +'config-admin-password' => 'Password:', |
| 3925 | +'config-admin-password-confirm' => 'Password again:', |
| 3926 | +'config-admin-help' => 'Enter your preferred username here, for example "Joe Bloggs". |
| 3927 | +This is the name you will use to log in to the wiki. |
| 3928 | + |
| 3929 | +The password cannot be the same as the username. ', |
| 3930 | +'config-admin-name-blank' => 'Please enter an administrator username.', |
| 3931 | +'config-admin-name-invalid' => 'The specified username "<nowiki>$1</nowiki>" is invalid. Please specify a different username.', |
| 3932 | +'config-admin-password-blank' => 'Please enter an administrator password.', |
| 3933 | +'config-admin-password-same' => 'The password must not be the same as the username.', |
| 3934 | +'config-admin-password-mismatch' => 'The two passwords you entered do not match.', |
| 3935 | +'config-admin-email' => 'Email address:', |
| 3936 | +'config-admin-email-help' => 'Enter an email address here to allow you to receive email from other users on the wiki, reset your password, and be notified of changes to pages on your watchlist.', |
| 3937 | +'config-subscribe' => 'Subscribe to the [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce release announcements mailing list].', |
| 3938 | +'config-subscribe-help' => 'This is a low-volume mailing list used for release announcements, including important security announcements. |
| 3939 | +You should subscribe to it and update your copy of MediaWiki when new versions come out.', |
| 3940 | +'config-almost-done' => "You're almost done! If you like, you can skip the remaining configuration and install the wiki right now.", |
| 3941 | +'config-optional-continue' => "Ask me more questions.", |
| 3942 | +'config-optional-skip' => "I'm bored already, just install the wiki.", |
| 3943 | +'config-profile' => 'User rights profile', |
| 3944 | +'config-profile-wiki' => 'Traditional wiki', |
| 3945 | +'config-profile-no-anon' => 'Account creation required', |
| 3946 | +'config-profile-fishbowl' => 'Fishbowl', |
| 3947 | +'config-profile-private' => 'Private wiki', |
| 3948 | +'config-profile-help' => "Wikis work best when you let as many people edit them as possible. |
| 3949 | +In MediaWiki, it's easy to review the recent changes, and to revert any damage that is done by naïve or malicious users. |
| 3950 | + |
| 3951 | +However, many people have found MediaWiki to be useful in a wide variety of roles, and sometimes it's not easy to convince everyone around you of the benefits of the wiki way. So we give you the choice. |
| 3952 | + |
| 3953 | +A '''traditional wiki''' allows anyone to edit, without even logging in. Some people prefer a wiki with '''account creation required''', since this provides extra accountability (but may deter casual contributors). |
| 3954 | + |
| 3955 | +A '''fishbowl''' only allows approved users to edit, but the public can view the pages, including history. A '''private wiki''' only allows approved users to view pages, with the same group allowed to edit. |
| 3956 | + |
| 3957 | +More complex user rights configurations are available after installation, see the [http://www.mediawiki.org/wiki/Manual:User_rights relevant manual entry]. |
| 3958 | +", |
| 3959 | +'config-license' => 'Copyright/License', |
| 3960 | +'config-license-none' => 'No license footer', |
| 3961 | +'config-license-gfdl-old' => 'GNU Free Documentation License 1.2 or later', |
| 3962 | +'config-license-gfdl-current' => 'GNU Free Documentation License 1.3 or later', |
| 3963 | +'config-license-pd' => 'Public Domain', |
| 3964 | +'config-license-cc-choose' => 'A Creative Commons license', |
| 3965 | +'config-license-help' => 'Many public wikis put all contributions under a [http://freedomdefined.org/Definition free license]. |
| 3966 | +This helps to create a sense of community ownership and encourages long-term contribution. |
| 3967 | +It is not generally necessary for a private or corporate wiki. |
| 3968 | + |
| 3969 | +If you want to be able to use text from Wikipedia, and you want Wikipedia to be able to accept text copied from your wiki, you should choose <strong>GNU Free Documentation License 1.2</strong>. |
| 3970 | +However, this license has some features which make reuse and interpretation difficult. |
| 3971 | + |
| 3972 | +If Wikipedia-compatibility is not important, <strong>Creative Commons</strong> with the <strong>Share Alike</strong> option (cc-by-sa) is a good choice. |
| 3973 | +', |
| 3974 | +'config-email-settings' => 'Email settings', |
| 3975 | +'config-enable-email' => 'Enable outbound email', |
| 3976 | +'config-enable-email-help' => "If you want email to work, [http://au2.php.net/manual/en/mail.configuration.php PHP's mail settings] need to be configured correctly. |
| 3977 | +If you don't want any email features, you can disable it here.", |
| 3978 | +'config-email-sender' => 'Return address:', |
| 3979 | +'config-email-sender-help' => 'Enter the email address to use as the return address on outbound email. |
| 3980 | +This is where bounces will be sent. |
| 3981 | +Many mail servers require at least the domain name part to be valid.', |
| 3982 | +'config-upload-settings' => 'Images and file uploads', |
| 3983 | +'config-upload-enable' => 'Enable file uploads', |
| 3984 | +'config-upload-help' => "File uploads potentially expose your server to security risks. |
| 3985 | +For more information, read the [http://www.mediawiki.org/wiki/Manual:Security security section] in the manual. |
| 3986 | + |
| 3987 | +To enable uploads, change the mode on the <tt>images</tt> subdirectory under MediaWiki's root directory so that the web server can write to it. Then enable this option.", |
| 3988 | +'config-upload-deleted' => 'Deleted directory:', |
| 3989 | +'config-upload-deleted-help' => 'Choose a directory in which to archive deleted files. |
| 3990 | +Ideally, this should not be publically accessible.', |
| 3991 | +'config-logo' => 'Logo URL:', |
| 3992 | +'config-logo-help' => "MediaWiki's default skin includes space for a 135x135 pixel logo in the top left corner. |
| 3993 | +Upload an image of the appropriate size, and enter the URL here. |
| 3994 | + |
| 3995 | +If you don't want a logo, leave this box blank.", |
| 3996 | +'config-cc-error' => 'The Creative Commons license chooser gave no result. Please enter the license name manually.', |
| 3997 | +'config-cc-again' => 'Pick again...', |
| 3998 | +'config-cc-not-chosen' => 'Please choose which Creative Commons license you want and click "proceed".', |
| 3999 | + |
3870 | 4000 | # Special:Version |
3871 | 4001 | 'version' => 'Version', # Not used as normal message but as header for the special page itself |
3872 | 4002 | 'version-extensions' => 'Installed extensions', |