Index: branches/REL1_17/phase3/maintenance/install.php |
— | — | @@ -20,12 +20,18 @@ |
21 | 21 | * @see wfWaitForSlaves() |
22 | 22 | */ |
23 | 23 | |
| 24 | +if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.2.3' ) < 0 ) ) { |
| 25 | + echo "You are using PHP version " . phpversion() . " but MediaWiki needs PHP 5.2.3 or higher. ABORTING.\n" . |
| 26 | + "Check if you have a newer php executable with a different name, such as php5.\n"; |
| 27 | + die( 1 ); |
| 28 | +} |
| 29 | + |
24 | 30 | define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' ); |
25 | 31 | |
26 | 32 | require_once( dirname( dirname( __FILE__ ) )."/maintenance/Maintenance.php" ); |
27 | 33 | |
28 | 34 | class CommandLineInstaller extends Maintenance { |
29 | | - public function __construct() { |
| 35 | + function __construct() { |
30 | 36 | parent::__construct(); |
31 | 37 | global $IP; |
32 | 38 | |
— | — | @@ -54,7 +60,7 @@ |
55 | 61 | $this->addOption( 'env-checks', "Run environment checks only, don't change anything" ); |
56 | 62 | } |
57 | 63 | |
58 | | - public function execute() { |
| 64 | + function execute() { |
59 | 65 | global $IP, $wgTitle; |
60 | 66 | $siteName = isset( $this->mArgs[0] ) ? $this->mArgs[0] : "Don't care"; // Will not be set if used with --env-checks |
61 | 67 | $adminName = isset( $this->mArgs[1] ) ? $this->mArgs[1] : null; |
— | — | @@ -76,7 +82,7 @@ |
77 | 83 | } |
78 | 84 | } |
79 | 85 | |
80 | | - protected function validateParamsAndArgs() { |
| 86 | + function validateParamsAndArgs() { |
81 | 87 | if ( !$this->hasOption( 'env-checks' ) ) { |
82 | 88 | parent::validateParamsAndArgs(); |
83 | 89 | } |
Property changes on: branches/REL1_17/phase3/maintenance/install.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
84 | 90 | Merged /trunk/phase3/maintenance/install.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/maintenance/language/messages.inc |
— | — | @@ -1094,7 +1094,6 @@ |
1095 | 1095 | 'right-reset-passwords', |
1096 | 1096 | 'right-override-export-depth', |
1097 | 1097 | 'right-sendemail', |
1098 | | - 'right-disableaccount', |
1099 | 1098 | ), |
1100 | 1099 | 'rightslog' => array( |
1101 | 1100 | 'rightslog', |
— | — | @@ -3213,17 +3212,6 @@ |
3214 | 3213 | 'sqlite-has-fts', |
3215 | 3214 | 'sqlite-no-fts', |
3216 | 3215 | ), |
3217 | | - 'disableaccount' => array( |
3218 | | - 'disableaccount', |
3219 | | - 'disableaccount-user', |
3220 | | - 'disableaccount-reason', |
3221 | | - 'disableaccount-confirm', |
3222 | | - 'disableaccount-mustconfirm', |
3223 | | - 'disableaccount-confirm', |
3224 | | - 'disableaccount-nosuchuser', |
3225 | | - 'disableaccount-success', |
3226 | | - 'disableaccount-logentry', |
3227 | | - ), |
3228 | 3216 | ); |
3229 | 3217 | |
3230 | 3218 | /** Comments for each block */ |
— | — | @@ -3437,5 +3425,4 @@ |
3438 | 3426 | 'db-error-messages' => 'Database error messages', |
3439 | 3427 | 'html-forms' => 'HTML forms', |
3440 | 3428 | 'sqlite' => 'SQLite database support', |
3441 | | - 'disableaccount' => 'Special:DisableAccount', |
3442 | 3429 | ); |
Property changes on: branches/REL1_17/phase3/maintenance/language/messages.inc |
___________________________________________________________________ |
Modified: svn:mergeinfo |
3443 | 3430 | Merged /trunk/phase3/maintenance/language/messages.inc:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/maintenance/rebuildtextindex.php |
— | — | @@ -49,11 +49,11 @@ |
50 | 50 | |
51 | 51 | $this->db = wfGetDB( DB_MASTER ); |
52 | 52 | if ( $this->db->getType() == 'sqlite' ) { |
53 | | - if ( !$this->db->getFulltextSearchModule() ) { |
54 | | - $this->error( "Your version of SQLite module for PHP doesn't support full-text search (FTS3).\n" ); |
| 53 | + if ( !DatabaseSqlite::getFulltextSearchModule() ) { |
| 54 | + $this->error( "Your version of SQLite module for PHP doesn't support full-text search (FTS3).\n", true ); |
55 | 55 | } |
56 | 56 | if ( !$this->db->checkForEnabledSearch() ) { |
57 | | - $this->error( "Your database schema is not configured for full-text search support. Run update.php.\n" ); |
| 57 | + $this->error( "Your database schema is not configured for full-text search support. Run update.php.\n", true ); |
58 | 58 | } |
59 | 59 | } |
60 | 60 | |
Index: branches/REL1_17/phase3/includes/CategoryPage.php |
— | — | @@ -193,6 +193,9 @@ |
194 | 194 | * entry in the categorylinks table is Category:A, not A, which it SHOULD be. |
195 | 195 | * Workaround: If sortkey == "Category:".$title, than use $title for sorting, |
196 | 196 | * else use sortkey... |
| 197 | + * |
| 198 | + * @param Title $title |
| 199 | + * @param string $sortkey The human-readable sortkey (before transforming to icu or whatever). |
197 | 200 | */ |
198 | 201 | function getSubcategorySortChar( $title, $sortkey ) { |
199 | 202 | global $wgContLang; |
— | — | @@ -295,7 +298,8 @@ |
296 | 299 | array( 'page', 'categorylinks', 'category' ), |
297 | 300 | array( 'page_id', 'page_title', 'page_namespace', 'page_len', |
298 | 301 | 'page_is_redirect', 'cl_sortkey', 'cat_id', 'cat_title', |
299 | | - 'cat_subcats', 'cat_pages', 'cat_files', 'cl_sortkey_prefix' ), |
| 302 | + 'cat_subcats', 'cat_pages', 'cat_files', |
| 303 | + 'cl_sortkey_prefix', 'cl_collation' ), |
300 | 304 | array( 'cl_to' => $this->title->getDBkey() ) + $extraConds, |
301 | 305 | __METHOD__, |
302 | 306 | array( |
— | — | @@ -312,22 +316,29 @@ |
313 | 317 | $count = 0; |
314 | 318 | foreach ( $res as $row ) { |
315 | 319 | $title = Title::newFromRow( $row ); |
316 | | - $rawSortkey = $title->getCategorySortkey( $row->cl_sortkey_prefix ); |
| 320 | + if ( $row->cl_collation === '' ) { |
| 321 | + // Hack to make sure that while updating from 1.16 schema |
| 322 | + // and db is inconsistent, that the sky doesn't fall. |
| 323 | + // See r83544. Could perhaps be removed in a couple decades... |
| 324 | + $humanSortkey = $row->cl_sortkey; |
| 325 | + } else { |
| 326 | + $humanSortkey = $title->getCategorySortkey( $row->cl_sortkey_prefix ); |
| 327 | + } |
317 | 328 | |
318 | 329 | if ( ++$count > $this->limit ) { |
319 | 330 | # We've reached the one extra which shows that there |
320 | 331 | # are additional pages to be had. Stop here... |
321 | | - $this->nextPage[$type] = $rawSortkey; |
| 332 | + $this->nextPage[$type] = $humanSortkey; |
322 | 333 | break; |
323 | 334 | } |
324 | 335 | |
325 | 336 | if ( $title->getNamespace() == NS_CATEGORY ) { |
326 | 337 | $cat = Category::newFromRow( $row, $title ); |
327 | | - $this->addSubcategoryObject( $cat, $rawSortkey, $row->page_len ); |
| 338 | + $this->addSubcategoryObject( $cat, $humanSortkey, $row->page_len ); |
328 | 339 | } elseif ( $title->getNamespace() == NS_FILE ) { |
329 | | - $this->addImage( $title, $rawSortkey, $row->page_len, $row->page_is_redirect ); |
| 340 | + $this->addImage( $title, $humanSortkey, $row->page_len, $row->page_is_redirect ); |
330 | 341 | } else { |
331 | | - $this->addPage( $title, $rawSortkey, $row->page_len, $row->page_is_redirect ); |
| 342 | + $this->addPage( $title, $humanSortkey, $row->page_len, $row->page_is_redirect ); |
332 | 343 | } |
333 | 344 | } |
334 | 345 | } |
Index: branches/REL1_17/phase3/includes/diff/DifferenceEngine.php |
— | — | @@ -724,7 +724,7 @@ |
725 | 725 | # input text to be HTML-escaped already |
726 | 726 | $otext = htmlspecialchars ( $wgContLang->segmentForDiff( $otext ) ); |
727 | 727 | $ntext = htmlspecialchars ( $wgContLang->segmentForDiff( $ntext ) ); |
728 | | - return $wgContLang->unsegementForDiff( wikidiff_do_diff( $otext, $ntext, 2 ) ) . |
| 728 | + return $wgContLang->unsegmentForDiff( wikidiff_do_diff( $otext, $ntext, 2 ) ) . |
729 | 729 | $this->debug( 'wikidiff1' ); |
730 | 730 | } |
731 | 731 | |
Index: branches/REL1_17/phase3/includes/ImagePage.php |
— | — | @@ -995,16 +995,16 @@ |
996 | 996 | |
997 | 997 | // Uploading user |
998 | 998 | $row .= '<td>'; |
999 | | - if ( $local ) { |
1000 | | - // Hide deleted usernames |
1001 | | - if ( $file->isDeleted( File::DELETED_USER ) ) { |
1002 | | - $row .= '<span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>'; |
| 999 | + // Hide deleted usernames |
| 1000 | + if ( $file->isDeleted( File::DELETED_USER ) ) { |
| 1001 | + $row .= '<span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>'; |
| 1002 | + } else { |
| 1003 | + if ( $local ) { |
| 1004 | + $row .= $this->skin->userLink( $user, $usertext ) . ' <span style="white-space: nowrap;">' . |
| 1005 | + $this->skin->userToolLinks( $user, $usertext ) . '</span>'; |
1003 | 1006 | } else { |
1004 | | - $row .= $this->skin->userLink( $user, $usertext ) . " <span style='white-space: nowrap;'>" . |
1005 | | - $this->skin->userToolLinks( $user, $usertext ) . "</span>"; |
| 1007 | + $row .= htmlspecialchars( $usertext ); |
1006 | 1008 | } |
1007 | | - } else { |
1008 | | - $row .= htmlspecialchars( $usertext ); |
1009 | 1009 | } |
1010 | 1010 | $row .= '</td><td>'; |
1011 | 1011 | |
Index: branches/REL1_17/phase3/includes/db/DatabaseSqlite.php |
— | — | @@ -134,19 +134,20 @@ |
135 | 135 | * Returns version of currently supported SQLite fulltext search module or false if none present. |
136 | 136 | * @return String |
137 | 137 | */ |
138 | | - function getFulltextSearchModule() { |
| 138 | + static function getFulltextSearchModule() { |
139 | 139 | static $cachedResult = null; |
140 | 140 | if ( $cachedResult !== null ) { |
141 | 141 | return $cachedResult; |
142 | 142 | } |
143 | 143 | $cachedResult = false; |
144 | 144 | $table = 'dummy_search_test'; |
145 | | - $this->query( "DROP TABLE IF EXISTS $table", __METHOD__ ); |
| 145 | + |
| 146 | + $db = new DatabaseSqliteStandalone( ':memory:' ); |
146 | 147 | |
147 | | - if ( $this->query( "CREATE VIRTUAL TABLE $table USING FTS3(dummy_field)", __METHOD__, true ) ) { |
148 | | - $this->query( "DROP TABLE IF EXISTS $table", __METHOD__ ); |
| 148 | + if ( $db->query( "CREATE VIRTUAL TABLE $table USING FTS3(dummy_field)", __METHOD__, true ) ) { |
149 | 149 | $cachedResult = 'FTS3'; |
150 | 150 | } |
| 151 | + $db->close(); |
151 | 152 | return $cachedResult; |
152 | 153 | } |
153 | 154 | |
— | — | @@ -468,7 +469,7 @@ |
469 | 470 | * @return string User-friendly database information |
470 | 471 | */ |
471 | 472 | public function getServerInfo() { |
472 | | - return wfMsg( $this->getFulltextSearchModule() ? 'sqlite-has-fts' : 'sqlite-no-fts', $this->getServerVersion() ); |
| 473 | + return wfMsg( self::getFulltextSearchModule() ? 'sqlite-has-fts' : 'sqlite-no-fts', $this->getServerVersion() ); |
473 | 474 | } |
474 | 475 | |
475 | 476 | /** |
Index: branches/REL1_17/phase3/includes/OutputPage.php |
— | — | @@ -2283,7 +2283,9 @@ |
2284 | 2284 | $wgUser->getOption( 'editondblclick' ) |
2285 | 2285 | ) |
2286 | 2286 | { |
2287 | | - $bodyAttrs['ondblclick'] = "document.location = '" . Xml::escapeJsString( $this->getTitle()->getEditURL() ) . "'"; |
| 2287 | + $editUrl = $this->getTitle()->getLocalUrl( $sk->editUrlOptions() ); |
| 2288 | + $bodyAttrs['ondblclick'] = "document.location = '" . |
| 2289 | + Xml::escapeJsString( $editUrl ) . "'"; |
2288 | 2290 | } |
2289 | 2291 | |
2290 | 2292 | # Class bloat |
Property changes on: branches/REL1_17/phase3/includes/OutputPage.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
2291 | 2293 | Merged /trunk/phase3/includes/OutputPage.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/includes/installer/Installer.php |
— | — | @@ -628,8 +628,7 @@ |
629 | 629 | // Check for FTS3 full-text search module |
630 | 630 | $sqlite = $this->getDBInstaller( 'sqlite' ); |
631 | 631 | if ( $sqlite->isCompiled() ) { |
632 | | - $db = new DatabaseSqliteStandalone( ':memory:' ); |
633 | | - if( $db->getFulltextSearchModule() != 'FTS3' ) { |
| 632 | + if( DatabaseSqlite::getFulltextSearchModule() != 'FTS3' ) { |
634 | 633 | $this->showMessage( 'config-no-fts3' ); |
635 | 634 | } |
636 | 635 | } |
Property changes on: branches/REL1_17/phase3/includes/installer/Installer.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
637 | 636 | Merged /trunk/phase3/includes/installer/Installer.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/includes/installer/SqliteInstaller.php |
— | — | @@ -170,7 +170,7 @@ |
171 | 171 | public function setupSearchIndex( &$status ) { |
172 | 172 | global $IP; |
173 | 173 | |
174 | | - $module = $this->db->getFulltextSearchModule(); |
| 174 | + $module = DatabaseSqlite::getFulltextSearchModule(); |
175 | 175 | $fts3tTable = $this->db->checkForEnabledSearch(); |
176 | 176 | if ( $fts3tTable && !$module ) { |
177 | 177 | $status->warning( 'config-sqlite-fts3-downgrade' ); |
Index: branches/REL1_17/phase3/includes/installer/SqliteUpdater.php |
— | — | @@ -67,7 +67,7 @@ |
68 | 68 | } |
69 | 69 | |
70 | 70 | protected function sqliteSetupSearchindex() { |
71 | | - $module = $this->db->getFulltextSearchModule(); |
| 71 | + $module = DatabaseSqlite::getFulltextSearchModule(); |
72 | 72 | $fts3tTable = $this->updateRowExists( 'fts3' ); |
73 | 73 | if ( $fts3tTable && !$module ) { |
74 | 74 | $this->output( '...PHP is missing FTS3 support, downgrading tables...' ); |
Index: branches/REL1_17/phase3/includes/api/ApiQueryCategoryMembers.php |
— | — | @@ -107,7 +107,6 @@ |
108 | 108 | $this->addOption( 'USE INDEX', 'cl_timestamp' ); |
109 | 109 | } else { |
110 | 110 | if ( $params['continue'] ) { |
111 | | - // type|from|sortkey |
112 | 111 | $cont = explode( '|', $params['continue'], 3 ); |
113 | 112 | if ( count( $cont ) != 3 ) { |
114 | 113 | $this->dieUsage( 'Invalid continue param. You should pass the original value returned '. |
— | — | @@ -120,8 +119,9 @@ |
121 | 120 | $queryTypes = array_slice( $queryTypes, $contTypeIndex ); |
122 | 121 | |
123 | 122 | // Add a WHERE clause for sortkey and from |
124 | | - $from = intval( $cont[1] ); |
125 | | - $escSortkey = $this->getDB()->addQuotes( $cont[2] ); |
| 123 | + // pack( "H*", $foo ) is used to convert hex back to binary |
| 124 | + $escSortkey = $this->getDB()->addQuotes( pack( "H*", $cont[1] ) ); |
| 125 | + $from = intval( $cont[2] ); |
126 | 126 | $op = $dir == 'newer' ? '>' : '<'; |
127 | 127 | // $contWhere is used further down |
128 | 128 | $contWhere = "cl_sortkey $op $escSortkey OR " . |
— | — | @@ -181,12 +181,9 @@ |
182 | 182 | if ( $params['sort'] == 'timestamp' ) { |
183 | 183 | $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) ); |
184 | 184 | } else { |
185 | | - // Continue format is type|from|sortkey |
186 | | - // The order is a bit weird but it's convenient to put the sortkey at the end |
187 | | - // because we don't have to worry about pipes in the sortkey that way |
188 | | - // (and type and from can't contain pipes anyway) |
| 185 | + $sortkey = bin2hex( $row->cl_sortkey ); |
189 | 186 | $this->setContinueEnumParameter( 'continue', |
190 | | - "{$row->cl_type}|{$row->cl_from}|{$row->cl_sortkey}" |
| 187 | + "{$row->cl_type}|$sortkey|{$row->cl_from}" |
191 | 188 | ); |
192 | 189 | } |
193 | 190 | break; |
— | — | @@ -210,7 +207,7 @@ |
211 | 208 | ApiQueryBase::addTitleInfo( $vals, $title ); |
212 | 209 | } |
213 | 210 | if ( $fld_sortkey ) { |
214 | | - $vals['sortkey'] = $row->cl_sortkey; |
| 211 | + $vals['sortkey'] = bin2hex( $row->cl_sortkey ); |
215 | 212 | } |
216 | 213 | if ( $fld_sortkeyprefix ) { |
217 | 214 | $vals['sortkeyprefix'] = $row->cl_sortkey_prefix; |
— | — | @@ -227,8 +224,9 @@ |
228 | 225 | if ( $params['sort'] == 'timestamp' ) { |
229 | 226 | $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) ); |
230 | 227 | } else { |
| 228 | + $sortkey = bin2hex( $row->cl_sortkey ); |
231 | 229 | $this->setContinueEnumParameter( 'continue', |
232 | | - "{$row->cl_type}|{$row->cl_from}|{$row->cl_sortkey}" |
| 230 | + "{$row->cl_type}|$sortkey|{$row->cl_from}" |
233 | 231 | ); |
234 | 232 | } |
235 | 233 | break; |
— | — | @@ -317,7 +315,7 @@ |
318 | 316 | 'What pieces of information to include', |
319 | 317 | ' ids - Adds the page ID', |
320 | 318 | ' title - Adds the title and namespace ID of the page', |
321 | | - ' sortkey - Adds the sortkey used for sorting in the category (may not be human-readble)', |
| 319 | + ' sortkey - Adds the sortkey used for sorting in the category (hexadecimal string)', |
322 | 320 | ' sortkeyprefix - Adds the sortkey prefix used for sorting in the category (human-readable part of the sortkey)', |
323 | 321 | ' type - Adds the type that the page has been categorised as (page, subcat or file)', |
324 | 322 | ' timestamp - Adds the timestamp of when the page was included', |
Index: branches/REL1_17/phase3/includes/api/ApiQueryCategories.php |
— | — | @@ -66,7 +66,7 @@ |
67 | 67 | 'cl_to' |
68 | 68 | ) ); |
69 | 69 | |
70 | | - $this->addFieldsIf( 'cl_sortkey', isset( $prop['sortkey'] ) ); |
| 70 | + $this->addFieldsIf( array( 'cl_sortkey', 'cl_sortkey_prefix' ), isset( $prop['sortkey'] ) ); |
71 | 71 | $this->addFieldsIf( 'cl_timestamp', isset( $prop['timestamp'] ) ); |
72 | 72 | |
73 | 73 | $this->addTables( 'categorylinks' ); |
— | — | @@ -147,7 +147,8 @@ |
148 | 148 | $vals = array(); |
149 | 149 | ApiQueryBase::addTitleInfo( $vals, $title ); |
150 | 150 | if ( isset( $prop['sortkey'] ) ) { |
151 | | - $vals['sortkey'] = $row->cl_sortkey; |
| 151 | + $vals['sortkey'] = bin2hex( $row->cl_sortkey ); |
| 152 | + $vals['sortkeyprefix'] = $row->cl_sortkey_prefix; |
152 | 153 | } |
153 | 154 | if ( isset( $prop['timestamp'] ) ) { |
154 | 155 | $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp ); |
— | — | @@ -215,7 +216,7 @@ |
216 | 217 | return array( |
217 | 218 | 'prop' => array( |
218 | 219 | 'Which additional properties to get for each category', |
219 | | - ' sortkey - Adds the sortkey for the category', |
| 220 | + ' sortkey - Adds the sortkey (hexadecimal string) and sortkey prefix (human-readable part) for the category', |
220 | 221 | ' timestamp - Adds timestamp of when the category was added', |
221 | 222 | ' hidden - Tags categories that are hidden with __HIDDENCAT__', |
222 | 223 | ), |
Index: branches/REL1_17/phase3/includes/resourceloader/ResourceLoaderFileModule.php |
— | — | @@ -208,8 +208,6 @@ |
209 | 209 | * @return String: JavaScript code for $context |
210 | 210 | */ |
211 | 211 | public function getScript( ResourceLoaderContext $context ) { |
212 | | - global $wgServer; |
213 | | - |
214 | 212 | $files = array_merge( |
215 | 213 | $this->scripts, |
216 | 214 | self::tryForKey( $this->languageScripts, $context->getLanguage() ), |
— | — | @@ -220,7 +218,7 @@ |
221 | 219 | if ( $this->debugRaw ) { |
222 | 220 | $script = ''; |
223 | 221 | foreach ( $files as $file ) { |
224 | | - $path = $wgServer . $this->getRemotePath( $file ); |
| 222 | + $path = $this->getRemotePath( $file ); |
225 | 223 | $script .= "\n\t" . Xml::encodeJsCall( 'mediaWiki.loader.load', array( $path ) ); |
226 | 224 | } |
227 | 225 | return $script; |
Index: branches/REL1_17/phase3/includes/AutoLoader.php |
— | — | @@ -136,7 +136,6 @@ |
137 | 137 | 'IndexPager' => 'includes/Pager.php', |
138 | 138 | 'Interwiki' => 'includes/Interwiki.php', |
139 | 139 | 'IP' => 'includes/IP.php', |
140 | | - 'JavaScriptDistiller' => 'includes/libs/JavaScriptDistiller.php', |
141 | 140 | 'JavaScriptMinifier' => 'includes/libs/JavaScriptMinifier.php', |
142 | 141 | 'LCStore_DB' => 'includes/LocalisationCache.php', |
143 | 142 | 'LCStore_CDB' => 'includes/LocalisationCache.php', |
— | — | @@ -628,7 +627,6 @@ |
629 | 628 | 'SpecialBookSources' => 'includes/specials/SpecialBooksources.php', |
630 | 629 | 'SpecialCategories' => 'includes/specials/SpecialCategories.php', |
631 | 630 | 'SpecialComparePages' => 'includes/specials/SpecialComparePages.php', |
632 | | - 'SpecialDisableAccount' => 'includes/specials/SpecialDisableAccount.php', |
633 | 631 | 'SpecialExport' => 'includes/specials/SpecialExport.php', |
634 | 632 | 'SpecialFilepath' => 'includes/specials/SpecialFilepath.php', |
635 | 633 | 'SpecialImport' => 'includes/specials/SpecialImport.php', |
Property changes on: branches/REL1_17/phase3/includes/AutoLoader.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
636 | 634 | Merged /trunk/phase3/includes/AutoLoader.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/includes/SkinTemplate.php |
— | — | @@ -606,7 +606,9 @@ |
607 | 607 | $personal_urls['logout'] = array( |
608 | 608 | 'text' => wfMsg( 'userlogout' ), |
609 | 609 | 'href' => self::makeSpecialUrl( 'Userlogout', |
610 | | - $title->isSpecial( 'Preferences' ) ? '' : $returnto |
| 610 | + // userlogout link must always contain an & character, otherwise we might not be able |
| 611 | + // to detect a buggy precaching proxy (bug 17790) |
| 612 | + $title->isSpecial( 'Preferences' ) ? 'noreturnto' : $returnto |
611 | 613 | ), |
612 | 614 | 'active' => false |
613 | 615 | ); |
Index: branches/REL1_17/phase3/includes/libs/JavaScriptDistiller.php |
— | — | @@ -1,337 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * JavaScript Distiller |
5 | | - * |
6 | | - * Author: Dean Edwards, Nicholas Martin, Trevor Parscal |
7 | | - * License: LGPL |
8 | | - */ |
9 | | -class JavaScriptDistiller { |
10 | | - |
11 | | - /* Static Methods */ |
12 | | - |
13 | | - /** |
14 | | - * Removes most of the white-space from JavaScript code. |
15 | | - * |
16 | | - * This code came from the first pass of Dean Edwards' JavaScript Packer. Compared to using |
17 | | - * JSMin::minify, this produces < 1% larger output (after gzip) in approx. 25% of the time. |
18 | | - * |
19 | | - * @param $script String: JavaScript code to minify |
20 | | - * @param $stripVerticalSpace Boolean: Try to remove as much vertical whitespace as possible |
21 | | - */ |
22 | | - public static function stripWhiteSpace( $script, $stripVerticalSpace = false ) { |
23 | | - // Try to avoid segfaulting |
24 | | - // I saw segfaults with a limit of 10000, 1000 seems to work |
25 | | - $oldLimit = ini_get( 'pcre.recursion_limit' ); |
26 | | - if ( intval( $oldLimit ) > 1000 ) { |
27 | | - ini_set( 'pcre.recursion_limit', '1000' ); |
28 | | - } |
29 | | - |
30 | | - $script = self::stripHorizontalSpace( $script ); |
31 | | - // If requested, make some vertical whitespace collapsing as well |
32 | | - if ( $stripVerticalSpace ) { |
33 | | - $script = self::stripVerticalSpace( $script ); |
34 | | - } |
35 | | - // Done |
36 | | - ini_set( 'pcre.recursion_limit', $oldLimit ); |
37 | | - return $script; |
38 | | - } |
39 | | - |
40 | | - public static function stripHorizontalSpace( $script ) { |
41 | | - $parser = self::createParser(); |
42 | | - // Collapse horizontal whitespaces between variable names into a single space |
43 | | - $parser->add( '(\b|\$) [ \t]+ (\b|\$)', '$2 $3' ); |
44 | | - // Collapse horizontal whitespaces between unary operators into a single space |
45 | | - $parser->add( '([+\-]) [ \t]+ ([+\-])', '$2 $3' ); |
46 | | - // Remove all remaining un-protected horizontal whitespace |
47 | | - $parser->add( '[ \t]+'); |
48 | | - // Collapse multiple vertical whitespaces with some horizontal spaces between them |
49 | | - $parser->add( '[\r\n]+ [ \t]* [\r\n]+', "\n" ); |
50 | | - // Execute and return |
51 | | - return $parser->exec($script); |
52 | | - } |
53 | | - |
54 | | - public static function stripVerticalSpace( $script ) { |
55 | | - $parser = self::createParser(); |
56 | | - // Collapse whitespaces between and after a ){ pair (function definitions) |
57 | | - $parser->add( '\) \s+ \{ \s+', '){' ); |
58 | | - // Collapse whitespaces between and after a ({ pair (JSON argument) |
59 | | - $parser->add( '\( \s+ \{ \s+', '({' ); |
60 | | - // Collapse whitespaces between a parenthesis and a period (call chaining) |
61 | | - $parser->add( '\) \s+ \.', ').'); |
62 | | - // Collapse vertical whitespaces which come directly after a semicolon or a comma |
63 | | - $parser->add( '( [;,] ) \s+', '$2' ); |
64 | | - // Collapse whitespaces between multiple parenthesis/brackets of similar direction |
65 | | - $parser->add( '( [\)\}] ) \s+ ( [\)\}] )', '$2$3' ); |
66 | | - $parser->add( '( [\(\{] ) \s+ ( [\(\{] )', '$2$3' ); |
67 | | - return $parser->exec( $script ); |
68 | | - } |
69 | | - |
70 | | - /* |
71 | | - * Creates an instance of ParseMaster and protects sensitive JavaScript regions. |
72 | | - * |
73 | | - * This parser is based on regular expressions, which all get or'd together, so rules take |
74 | | - * precedence in the order they are added. We can use it to minify by armoring certain regions |
75 | | - * by matching them and replacing them with the full match, leaving the remaining regions around |
76 | | - * for further matching and replacing. When creating rules please note that because ParseMaster |
77 | | - * "or"s all of the rules together in a single pattern, encapsulating them in parenthesis, $1 |
78 | | - * represents the whole match for a given rule, and $2 is the first submatch. |
79 | | - */ |
80 | | - private static function createParser() { |
81 | | - $parser = new ParseMaster(); |
82 | | - // There is a bug in ParseMaster that causes a backslash at the end of a line to be changed |
83 | | - // to \s if we use a backslash as the escape character. We work around this by using an |
84 | | - // obscure escape character that we hope will never appear at the end of a line. |
85 | | - $parser->escapeChar = chr( 1 ); |
86 | | - |
87 | | - // C-style comment: use non-greedy repetition to find the end |
88 | | - $parser->add( '\/ \* .*? \* \/' ); |
89 | | - |
90 | | - // Preserve the newline after a C++-style comment -- bug 27046 |
91 | | - $parser->add( '\/ \/ [^\r\n]* ( [\r\n] )', '$2' ); |
92 | | - |
93 | | - // Protect strings. The original code had [^\'\\v] here, but that didn't armor multiline |
94 | | - // strings correctly. This also armors multiline strings that don't have backslashes at the |
95 | | - // end of the line (these are invalid), but that's fine because we're just armoring here. |
96 | | - |
97 | | - // Single quotes |
98 | | - $parser->add( |
99 | | - '\'' . // start quote |
100 | | - '[^\'\\\\]*' . // a run of non-special characters |
101 | | - '(?:' . |
102 | | - '\\\\ .' . // a backslash followed by any character |
103 | | - '[^\'\\\\]*' . // a run of non-special characters |
104 | | - ')*' . // any number of the above |
105 | | - '\'', // end quote |
106 | | - '$1' ); |
107 | | - |
108 | | - // Double quotes: same as above |
109 | | - $parser->add( '" [^"\\\\]* (?: \\\\ . [^"\\\\]* )* "', '$1' ); |
110 | | - |
111 | | - // Protect regular expressions |
112 | | - $parser->add( |
113 | | - '(?<= [ \t] | [^\w\$\/\'"*)\?:] )' . // assert that whitespace or punctuation precedes |
114 | | - '\/' . // start slash |
115 | | - '[^\r\n\*]' . // not a comment-start or line ending |
116 | | - '[^\/\r\n\\\\]*' . // a sequence of non-special characters |
117 | | - '(?:' . |
118 | | - '\\\\ .' . // a backslash followed by any character |
119 | | - '[^\/\r\n\\\\]*' . // a sequence of non-special characters |
120 | | - ')*' . // any number of the above |
121 | | - '\/[ig]*' , // pattern end, optional modifier |
122 | | - '$1' ); |
123 | | - return $parser; |
124 | | - } |
125 | | -} |
126 | | - |
127 | | -/** |
128 | | - * ParseMaster, version 1.0.2 (2005-08-19) Copyright 2005, Dean Edwards |
129 | | - * A multi-pattern parser. |
130 | | - * License: http://creativecommons.org/licenses/LGPL/2.1/ |
131 | | - * |
132 | | - * This is the PHP version of the ParseMaster component of Dean Edwards' (http://dean.edwards.name/) |
133 | | - * Packer, which was originally written in JavaScript. It was ported to PHP by Nicolas Martin. |
134 | | - * |
135 | | - * Original Source: http://joliclic.free.fr/php/javascript-packer/en/ |
136 | | - * |
137 | | - * Changes should be pushed back upstream. |
138 | | - */ |
139 | | -class ParseMaster { |
140 | | - public $ignoreCase = false; |
141 | | - public $escapeChar = ''; |
142 | | - |
143 | | - // constants |
144 | | - const EXPRESSION = 0; |
145 | | - const REPLACEMENT = 1; |
146 | | - const LENGTH = 2; |
147 | | - |
148 | | - // used to determine nesting levels |
149 | | - private $GROUPS = '/\( (?! \? ) /x';//g |
150 | | - private $SUB_REPLACE = '/\$\d/'; |
151 | | - private $INDEXED = '/^\$\d+$/'; |
152 | | - private $ESCAPE = '/\\\./';//g |
153 | | - private $QUOTE = '/\'/'; |
154 | | - private $DELETED = '/\x01[^\x01]*\x01/';//g |
155 | | - |
156 | | - public function add($expression, $replacement = '') { |
157 | | - // count the number of sub-expressions |
158 | | - // - add one because each pattern is itself a sub-expression |
159 | | - $length = 1 + preg_match_all($this->GROUPS, $this->_internalEscape((string)$expression), $out); |
160 | | - |
161 | | - // treat only strings $replacement |
162 | | - if (is_string($replacement)) { |
163 | | - // does the pattern deal with sub-expressions? |
164 | | - if (preg_match($this->SUB_REPLACE, $replacement)) { |
165 | | - // a simple lookup? (e.g. "$2") |
166 | | - if (preg_match($this->INDEXED, $replacement)) { |
167 | | - // store the index (used for fast retrieval of matched strings) |
168 | | - $replacement = (int)(substr($replacement, 1)) - 1; |
169 | | - } else { // a complicated lookup (e.g. "Hello $2 $1") |
170 | | - // build a function to do the lookup |
171 | | - $quote = preg_match($this->QUOTE, $this->_internalEscape($replacement)) |
172 | | - ? '"' : "'"; |
173 | | - $replacement = array( |
174 | | - 'fn' => '_backReferences', |
175 | | - 'data' => array( |
176 | | - 'replacement' => $replacement, |
177 | | - 'length' => $length, |
178 | | - 'quote' => $quote |
179 | | - ) |
180 | | - ); |
181 | | - } |
182 | | - } |
183 | | - } |
184 | | - // pass the modified arguments |
185 | | - if (!empty($expression)) $this->_add($expression, $replacement, $length); |
186 | | - else $this->_add('/^$/', $replacement, $length); |
187 | | - } |
188 | | - |
189 | | - public function exec($string) { |
190 | | - // execute the global replacement |
191 | | - $this->_escaped = array(); |
192 | | - |
193 | | - // simulate the _patterns.toSTring of Dean |
194 | | - $regexp = '/'; |
195 | | - foreach ($this->_patterns as $reg) { |
196 | | - $regexp .= '(' . $reg[self::EXPRESSION] . ")|\n"; |
197 | | - } |
198 | | - $regexp = substr($regexp, 0, -2) . '/Sxs'; |
199 | | - $regexp .= ($this->ignoreCase) ? 'i' : ''; |
200 | | - |
201 | | - $string = $this->_escape($string, $this->escapeChar); |
202 | | - $string = preg_replace_callback( |
203 | | - $regexp, |
204 | | - array( |
205 | | - &$this, |
206 | | - '_replacement' |
207 | | - ), |
208 | | - $string |
209 | | - ); |
210 | | - $string = $this->_unescape($string, $this->escapeChar); |
211 | | - |
212 | | - return preg_replace($this->DELETED, '', $string); |
213 | | - } |
214 | | - |
215 | | - public function reset() { |
216 | | - // clear the patterns collection so that this object may be re-used |
217 | | - $this->_patterns = array(); |
218 | | - } |
219 | | - |
220 | | - // private |
221 | | - private $_escaped = array(); // escaped characters |
222 | | - private $_patterns = array(); // patterns stored by index |
223 | | - |
224 | | - // create and add a new pattern to the patterns collection |
225 | | - private function _add() { |
226 | | - $arguments = func_get_args(); |
227 | | - $this->_patterns[] = $arguments; |
228 | | - } |
229 | | - |
230 | | - // this is the global replace function (it's quite complicated) |
231 | | - private function _replacement($arguments) { |
232 | | - if (empty($arguments)) return ''; |
233 | | - |
234 | | - $i = 1; $j = 0; |
235 | | - // loop through the patterns |
236 | | - while (isset($this->_patterns[$j])) { |
237 | | - $pattern = $this->_patterns[$j++]; |
238 | | - // do we have a result? |
239 | | - if (isset($arguments[$i]) && ($arguments[$i] != '')) { |
240 | | - $replacement = $pattern[self::REPLACEMENT]; |
241 | | - |
242 | | - if (is_array($replacement) && isset($replacement['fn'])) { |
243 | | - |
244 | | - if (isset($replacement['data'])) $this->buffer = $replacement['data']; |
245 | | - return call_user_func(array(&$this, $replacement['fn']), $arguments, $i); |
246 | | - |
247 | | - } elseif (is_int($replacement)) { |
248 | | - return $arguments[$replacement + $i]; |
249 | | - |
250 | | - } |
251 | | - $delete = ($this->escapeChar == '' || |
252 | | - strpos($arguments[$i], $this->escapeChar) === false) |
253 | | - ? '' : "\x01" . $arguments[$i] . "\x01"; |
254 | | - return $delete . $replacement; |
255 | | - |
256 | | - // skip over references to sub-expressions |
257 | | - } else { |
258 | | - $i += $pattern[self::LENGTH]; |
259 | | - } |
260 | | - } |
261 | | - } |
262 | | - |
263 | | - private function _backReferences($match, $offset) { |
264 | | - $replacement = $this->buffer['replacement']; |
265 | | - //$quote = $this->buffer['quote']; |
266 | | - $i = $this->buffer['length']; |
267 | | - while ($i) { |
268 | | - $replacement = str_replace('$'.$i--, $match[$offset + $i], $replacement); |
269 | | - } |
270 | | - return $replacement; |
271 | | - } |
272 | | - |
273 | | - private function _replace_name($match, $offset){ |
274 | | - $length = strlen($match[$offset + 2]); |
275 | | - $start = $length - max($length - strlen($match[$offset + 3]), 0); |
276 | | - return substr($match[$offset + 1], $start, $length) . $match[$offset + 4]; |
277 | | - } |
278 | | - |
279 | | - private function _replace_encoded($match, $offset) { |
280 | | - return $this->buffer[$match[$offset]]; |
281 | | - } |
282 | | - |
283 | | - |
284 | | - // php : we cannot pass additional data to preg_replace_callback, |
285 | | - // and we cannot use &$this in create_function, so let's go to lower level |
286 | | - private $buffer; |
287 | | - |
288 | | - // encode escaped characters |
289 | | - private function _escape($string, $escapeChar) { |
290 | | - if ($escapeChar) { |
291 | | - $this->buffer = $escapeChar; |
292 | | - return preg_replace_callback( |
293 | | - '/\\' . $escapeChar . '(.)' .'/', |
294 | | - array(&$this, '_escapeBis'), |
295 | | - $string |
296 | | - ); |
297 | | - |
298 | | - } else { |
299 | | - return $string; |
300 | | - } |
301 | | - } |
302 | | - private function _escapeBis($match) { |
303 | | - $this->_escaped[] = $match[1]; |
304 | | - return $this->buffer; |
305 | | - } |
306 | | - |
307 | | - // decode escaped characters |
308 | | - private function _unescape($string, $escapeChar) { |
309 | | - if ($escapeChar) { |
310 | | - $regexp = '/'.'\\'.$escapeChar.'/'; |
311 | | - $this->buffer = array('escapeChar'=> $escapeChar, 'i' => 0); |
312 | | - return preg_replace_callback |
313 | | - ( |
314 | | - $regexp, |
315 | | - array(&$this, '_unescapeBis'), |
316 | | - $string |
317 | | - ); |
318 | | - |
319 | | - } else { |
320 | | - return $string; |
321 | | - } |
322 | | - } |
323 | | - private function _unescapeBis() { |
324 | | - if (isset($this->_escaped[$this->buffer['i']]) |
325 | | - && $this->_escaped[$this->buffer['i']] != '') |
326 | | - { |
327 | | - $temp = $this->_escaped[$this->buffer['i']]; |
328 | | - } else { |
329 | | - $temp = ''; |
330 | | - } |
331 | | - $this->buffer['i']++; |
332 | | - return $this->buffer['escapeChar'] . $temp; |
333 | | - } |
334 | | - |
335 | | - private function _internalEscape($string) { |
336 | | - return preg_replace($this->ESCAPE, '', $string); |
337 | | - } |
338 | | -} |
Index: branches/REL1_17/phase3/includes/DefaultSettings.php |
— | — | @@ -3304,11 +3304,6 @@ |
3305 | 3305 | // For private suppression log access |
3306 | 3306 | #$wgGroupPermissions['suppress']['suppressionlog'] = true; |
3307 | 3307 | |
3308 | | -// Permission to disable user accounts |
3309 | | -// Note that disabling an account is not reversible without a system administrator |
3310 | | -// who has direct access to the database |
3311 | | -#$wgGroupPermissions['bureaucrat']['disableaccount'] = true; |
3312 | | - |
3313 | 3308 | /** |
3314 | 3309 | * The developer group is deprecated, but can be activated if need be |
3315 | 3310 | * to use the 'lockdb' and 'unlockdb' special pages. Those require |
Property changes on: branches/REL1_17/phase3/includes/DefaultSettings.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
3316 | 3311 | Merged /trunk/phase3/includes/DefaultSettings.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/includes/specials/SpecialDisableAccount.php |
— | — | @@ -1,73 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -class SpecialDisableAccount extends SpecialPage { |
5 | | - function __construct() { |
6 | | - parent::__construct( 'DisableAccount', 'disableaccount', |
7 | | - true, array( $this, 'show' ) ); |
8 | | - } |
9 | | - |
10 | | - public function show( $par ) { |
11 | | - $formFields = array( |
12 | | - 'account' => array( |
13 | | - 'type' => 'text', |
14 | | - 'validation-callback' => array( __CLASS__, 'validateUser' ), |
15 | | - 'label-message' => 'disableaccount-user', |
16 | | - ), |
17 | | - 'comment' => array( |
18 | | - 'type' => 'text', |
19 | | - 'label-message' => 'disableaccount-reason', |
20 | | - ), |
21 | | - 'confirm' => array( |
22 | | - 'type' => 'toggle', |
23 | | - 'validation-callback' => array( __CLASS__, 'checkConfirmation' ), |
24 | | - 'label-message' => 'disableaccount-confirm', |
25 | | - ), |
26 | | - ); |
27 | | - |
28 | | - $htmlForm = new HTMLForm( $formFields, 'disableaccount' ); |
29 | | - |
30 | | - $htmlForm->setSubmitCallback( array( __CLASS__, 'submit' ) ); |
31 | | - $htmlForm->setTitle( $this->getTitle() ); |
32 | | - |
33 | | - $htmlForm->show(); |
34 | | - } |
35 | | - |
36 | | - static function validateUser( $field, $allFields ) { |
37 | | - $u = User::newFromName( $field ); |
38 | | - |
39 | | - if ( $u && $u->getID() != 0 ) { |
40 | | - return true; |
41 | | - } else { |
42 | | - return wfMsgExt( 'disableaccount-nosuchuser', 'parseinline', array( $field ) ); |
43 | | - } |
44 | | - } |
45 | | - |
46 | | - static function checkConfirmation( $field, $allFields ) { |
47 | | - if ( $field ) { |
48 | | - return true; |
49 | | - } else { |
50 | | - return wfMsgExt( 'disableaccount-mustconfirm', 'parseinline' ); |
51 | | - } |
52 | | - } |
53 | | - |
54 | | - static function submit( $fields ) { |
55 | | - $user = User::newFromName( $fields['account'] ); |
56 | | - |
57 | | - $user->setPassword( null ); |
58 | | - $user->setEmail( null ); |
59 | | - $user->setToken(); |
60 | | - $user->addGroup( 'inactive' ); |
61 | | - |
62 | | - $user->saveSettings(); |
63 | | - $user->invalidateCache(); |
64 | | - |
65 | | - $logPage = new LogPage( 'rights' ); |
66 | | - |
67 | | - $logPage->addEntry( 'disable', $user->getUserPage(), $fields['comment'] ); |
68 | | - |
69 | | - global $wgOut; |
70 | | - $wgOut->addWikiMsg( 'disableaccount-success', $user->getName() ); |
71 | | - |
72 | | - return true; |
73 | | - } |
74 | | -} |
\ No newline at end of file |
Index: branches/REL1_17/phase3/includes/SpecialPage.php |
— | — | @@ -133,7 +133,6 @@ |
134 | 134 | 'Listbots' => array( 'SpecialRedirectToSpecial', 'Listbots', 'Listusers', 'bot' ), |
135 | 135 | 'Activeusers' => 'SpecialActiveUsers', |
136 | 136 | 'Userrights' => 'UserrightsPage', |
137 | | - 'DisableAccount' => 'SpecialDisableAccount', |
138 | 137 | |
139 | 138 | # Recent changes and logs |
140 | 139 | 'Newimages' => array( 'IncludableSpecialPage', 'Newimages' ), |
— | — | @@ -1063,4 +1062,4 @@ |
1064 | 1063 | global $wgUser; |
1065 | 1064 | return SpecialPage::getTitleFor( 'Listfiles', $wgUser->getName() ); |
1066 | 1065 | } |
1067 | | -} |
\ No newline at end of file |
| 1066 | +} |
Property changes on: branches/REL1_17/phase3/includes/SpecialPage.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
1068 | 1067 | Merged /trunk/phase3/includes/SpecialPage.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/includes/normal/UtfNormal.php |
— | — | @@ -79,19 +79,30 @@ |
80 | 80 | * @return string a clean, shiny, normalized UTF-8 string |
81 | 81 | */ |
82 | 82 | static function cleanUp( $string ) { |
83 | | - if( NORMALIZE_ICU || NORMALIZE_INTL ) { |
84 | | - # We exclude a few chars that ICU would not. |
85 | | - $string = preg_replace( |
86 | | - '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', |
87 | | - UTF8_REPLACEMENT, |
88 | | - $string ); |
89 | | - $string = str_replace( UTF8_FFFE, UTF8_REPLACEMENT, $string ); |
90 | | - $string = str_replace( UTF8_FFFF, UTF8_REPLACEMENT, $string ); |
| 83 | + if( NORMALIZE_ICU ) { |
| 84 | + $string = self::replaceForNativeNormalize( $string ); |
91 | 85 | |
92 | 86 | # UnicodeString constructor fails if the string ends with a |
93 | 87 | # head byte. Add a junk char at the end, we'll strip it off. |
94 | | - if ( NORMALIZE_ICU ) return rtrim( utf8_normalize( $string . "\x01", UNORM_NFC ), "\x01" ); |
95 | | - if ( NORMALIZE_INTL ) return normalizer_normalize( $string, Normalizer::FORM_C ); |
| 88 | + return rtrim( utf8_normalize( $string . "\x01", UNORM_NFC ), "\x01" ); |
| 89 | + } elseif( NORMALIZE_INTL ) { |
| 90 | + $string = self::replaceForNativeNormalize( $string ); |
| 91 | + $norm = normalizer_normalize( $string, Normalizer::FORM_C ); |
| 92 | + if( $norm === null || $norm === false ) { |
| 93 | + # normalizer_normalize will either return false or null |
| 94 | + # (depending on which doc you read) if invalid utf8 string. |
| 95 | + # quickIsNFCVerify cleans up invalid sequences. |
| 96 | + |
| 97 | + if( UtfNormal::quickIsNFCVerify( $string ) ) { |
| 98 | + # if that's true, the string is actually already normal. |
| 99 | + return $string; |
| 100 | + } else { |
| 101 | + # Now we are valid but non-normal |
| 102 | + return normalizer_normalize( $string, Normalizer::FORM_C ); |
| 103 | + } |
| 104 | + } else { |
| 105 | + return $norm; |
| 106 | + } |
96 | 107 | } elseif( UtfNormal::quickIsNFCVerify( $string ) ) { |
97 | 108 | # Side effect -- $string has had UTF-8 errors cleaned up. |
98 | 109 | return $string; |
— | — | @@ -748,4 +759,20 @@ |
749 | 760 | } |
750 | 761 | return $out; |
751 | 762 | } |
| 763 | + /** |
| 764 | + * Function to replace some characters that we don't want |
| 765 | + * but most of the native normalize functions keep. |
| 766 | + * |
| 767 | + * @param $string String The string |
| 768 | + * @return String String with the character codes replaced. |
| 769 | + */ |
| 770 | + private static function replaceForNativeNormalize( $string ) { |
| 771 | + $string = preg_replace( |
| 772 | + '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', |
| 773 | + UTF8_REPLACEMENT, |
| 774 | + $string ); |
| 775 | + $string = str_replace( UTF8_FFFE, UTF8_REPLACEMENT, $string ); |
| 776 | + $string = str_replace( UTF8_FFFF, UTF8_REPLACEMENT, $string ); |
| 777 | + return $string; |
| 778 | + } |
752 | 779 | } |
Index: branches/REL1_17/phase3/includes/DjVuImage.php |
— | — | @@ -254,8 +254,7 @@ |
255 | 255 | $txt = wfShellExec( $cmd, $retval ); |
256 | 256 | wfProfileOut( 'djvutxt' ); |
257 | 257 | if( $retval == 0) { |
258 | | - # Get rid of invalid UTF-8, strip control characters |
259 | | - $txt = UtfNormal::cleanUp( $txt ); |
| 258 | + # Strip some control characters |
260 | 259 | $txt = preg_replace( "/[\013\035\037]/", "", $txt ); |
261 | 260 | $reg = <<<EOR |
262 | 261 | /\(page\s[\d-]*\s[\d-]*\s[\d-]*\s[\d-]*\s*" |
— | — | @@ -279,7 +278,8 @@ |
280 | 279 | } |
281 | 280 | |
282 | 281 | function pageTextCallback( $matches ) { |
283 | | - return '<PAGE value="' . htmlspecialchars( $matches[1] ) . '" />'; |
| 282 | + # Get rid of invalid UTF-8, strip control characters |
| 283 | + return '<PAGE value="' . htmlspecialchars( UtfNormal::cleanUp( $matches[1] ) ) . '" />'; |
284 | 284 | } |
285 | 285 | |
286 | 286 | /** |
Index: branches/REL1_17/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1931,7 +1931,6 @@ |
1932 | 1932 | 'right-reset-passwords' => "Reset other users' passwords", |
1933 | 1933 | 'right-override-export-depth' => 'Export pages including linked pages up to a depth of 5', |
1934 | 1934 | 'right-sendemail' => 'Send e-mail to other users', |
1935 | | -'right-disableaccount' => 'Disable accounts', |
1936 | 1935 | |
1937 | 1936 | # User rights log |
1938 | 1937 | 'rightslog' => 'User rights log', |
— | — | @@ -4357,18 +4356,4 @@ |
4358 | 4357 | # SQLite database support |
4359 | 4358 | 'sqlite-has-fts' => '$1 with full-text search support', |
4360 | 4359 | 'sqlite-no-fts' => '$1 without full-text search support', |
4361 | | - |
4362 | | -# Special:DisableAccount |
4363 | | -'disableaccount' => 'Disable a user account', |
4364 | | -'disableaccount-user' => 'Username:', |
4365 | | -'disableaccount-reason' => 'Reason:', |
4366 | | -'disableaccount-confirm' => "Disable this user account. |
4367 | | -The user will not be able to log in, reset their password, or receive e-mail notifications. |
4368 | | -If the user is currently logged in anywhere, they will be immediately logged out. |
4369 | | -''Note that disabling an account is not reversible without system administrator intervention.''", |
4370 | | -'disableaccount-mustconfirm' => 'You must confirm that you wish to disable this account.', |
4371 | | -'disableaccount-nosuchuser' => 'The user account "$1" does not exist.', |
4372 | | -'disableaccount-success' => 'The user account "$1" has been permanently disabled.', |
4373 | | -'disableaccount-logentry' => 'permanently disabled the user account [[$1]]', |
4374 | | - |
4375 | 4360 | ); |
Property changes on: branches/REL1_17/phase3/languages/messages/MessagesEn.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
4376 | 4361 | Merged /trunk/phase3/languages/messages/MessagesEn.php:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |
Index: branches/REL1_17/phase3/RELEASE-NOTES |
— | — | @@ -512,6 +512,8 @@ |
513 | 513 | * (bug 26781) {{PAGENAME}} and related parser functions escape their output better. |
514 | 514 | * (bug 26716) Provide link to instructions for external editor related preferences |
515 | 515 | and add a comment to the ini control file explaining what is going on. |
| 516 | +* (bug 28422) Remove color:black from tables in Monobook and Vector. And add it |
| 517 | + to table.wikitable instead. |
516 | 518 | * (bug 27560) Search queries no longer fail in walloon language |
517 | 519 | * (bug 27700) The upload protection can now also be set for files that do not |
518 | 520 | exist. |
— | — | @@ -523,6 +525,9 @@ |
524 | 526 | * (bug 28242) Make redirects generated by urls containing a local interwiki |
525 | 527 | prefix be a 301 instead of a 302. |
526 | 528 | * (bug 28568) Entries in the iwlinks table are now removed on page deletion |
| 529 | +* (bug 28306) Fix exposure of suppressed usernames in ForeignDBRepo |
| 530 | +* (bug 28444) Fix regression: edit-on-doubleclick retains revision id again |
| 531 | +* UtfNormal::cleanUp on an invalid utf-8 sequence no longer returns false if intl installed. |
527 | 532 | |
528 | 533 | === API changes in 1.17 === |
529 | 534 | * BREAKING CHANGE: action=patrol now requires POST |
Property changes on: branches/REL1_17/phase3/RELEASE-NOTES |
___________________________________________________________________ |
Modified: svn:mergeinfo |
530 | 535 | Merged /trunk/phase3/RELEASE-NOTES:r81731,82038-82039,85377,85547,85555,85583,85803,85881,86065,86100,86121,86130,86142,86146,86182,86210,86257,86385,86394 |