Merge "Change name of section so it does not get confused with Wikidata"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 25 Jan 2013 14:06:47 +0000 (14:06 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 25 Jan 2013 14:06:47 +0000 (14:06 +0000)
12 files changed:
includes/SkinTemplate.php
includes/installer/Installer.i18n.php
includes/site/SiteSQLStore.php
includes/specials/SpecialUserlogin.php
includes/templates/Usercreate.php
languages/Language.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php
resources/Resources.php
resources/mediawiki.special/mediawiki.special.userLogin.signup.js [new file with mode: 0644]
tests/phpunit/includes/site/SiteSQLStoreTest.php
tests/phpunit/languages/LanguageTest.php

index 58d443a..611223e 100644 (file)
@@ -1008,6 +1008,12 @@ class SkinTemplate extends Skin {
                                        // Gets preferred variant (note that user preference is
                                        // only possible for wiki content language variant)
                                        $preferred = $pageLang->getPreferredVariant();
+                                       if ( Action::getActionName( $this ) === 'view' ) {
+                                               $params = $request->getQueryValues();
+                                               unset( $params['title'] );
+                                       } else {
+                                               $params = array();
+                                       }
                                        // Loops over each variant
                                        foreach( $variants as $code ) {
                                                // Gets variant name from language code
@@ -1021,7 +1027,7 @@ class SkinTemplate extends Skin {
                                                $content_navigation['variants'][] = array(
                                                        'class' => ( $code == $preferred ) ? 'selected' : false,
                                                        'text' => $varname,
-                                                       'href' => $title->getLocalURL( array( 'variant' => $code ) ),
+                                                       'href' => $title->getLocalURL( array( 'variant' => $code ) + $params ),
                                                        'lang' => $code,
                                                        'hreflang' => $code
                                                );
index 98fff92..a272cfa 100644 (file)
@@ -249,7 +249,7 @@ If you do not see the database system you are trying to use listed below, then f
        'config-support-postgres'         => '* $1 is a popular open source database system as an alternative to MySQL ([http://www.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]). There may be some minor outstanding bugs, and it is not recommended for use in a production environment.',
        'config-support-sqlite'           => '* $1 is a lightweight database system which is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)',
        'config-support-oracle'           => '* $1 is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
-       'config-support-ibm_db2'          => '* $1 is a commercial enterprise database.',
+       'config-support-ibm_db2'          => '* $1 is a commercial enterprise database. ([http://www.php.net/manual/en/ibm-db2.installation.php How to compile PHP with IBM DB2 support])',
        'config-header-mysql'             => 'MySQL settings',
        'config-header-postgres'          => 'PostgreSQL settings',
        'config-header-sqlite'            => 'SQLite settings',
index 470fe26..e608736 100644 (file)
@@ -145,6 +145,8 @@ class SiteSQLStore implements SiteStore {
 
                $site->setGlobalId( $siteRow->getField( 'global_key' ) );
 
+               $site->setInternalId( $siteRow->getField( 'id' ) );
+
                if ( $siteRow->hasField( 'forward' ) ) {
                        $site->setForward( $siteRow->getField( 'forward' ) );
                }
index 7817b96..d9c4244 100644 (file)
@@ -95,9 +95,9 @@ class LoginForm extends SpecialPage {
                $this->mReason = $request->getText( 'wpReason' );
                $this->mCookieCheck = $request->getVal( 'wpCookieCheck' );
                $this->mPosted = $request->wasPosted();
-               $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' );
                $this->mCreateaccountMail = $request->getCheck( 'wpCreateaccountMail' )
                                                                        && $wgEnableEmail;
+               $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' ) && !$this->mCreateaccountMail;
                $this->mLoginattempt = $request->getCheck( 'wpLoginattempt' );
                $this->mAction = $request->getVal( 'action' );
                $this->mRemember = $request->getCheck( 'wpRemember' );
@@ -1044,6 +1044,7 @@ class LoginForm extends SpecialPage {
                        $q = 'action=submitlogin&type=signup';
                        $linkq = 'type=login';
                        $linkmsg = 'gotaccount';
+                       $this->getOutput()->addModules( 'mediawiki.special.userlogin.signup' );
                } else {
                        $template = new UserloginTemplate();
                        $q = 'action=submitlogin&type=login';
@@ -1083,6 +1084,7 @@ class LoginForm extends SpecialPage {
                $template->set( 'name', $this->mUsername );
                $template->set( 'password', $this->mPassword );
                $template->set( 'retype', $this->mRetype );
+               $template->set( 'createemailset', $this->mCreateaccountMail );
                $template->set( 'email', $this->mEmail );
                $template->set( 'realname', $this->mRealName );
                $template->set( 'domain', $this->mDomain );
index 6e1094f..569200d 100644 (file)
@@ -77,13 +77,27 @@ class UsercreateTemplate extends QuickTemplate {
                        </td>
                </tr>
                <tr>
+                       <td></td>
+                       <td class="mw-input">
+                               <?php if( $this->data['createemail'] ) {
+                                       echo Xml::checkLabel(
+                                               wfMessage( 'createaccountmail' )->text(),
+                                               'wpCreateaccountMail',
+                                               'wpCreateaccountMail',
+                                               $this->data['createemailset'],
+                                               array( 'tabindex' => '2' )
+                                       );
+                               } ?>
+                       </td>
+               </tr>
+               <tr class="mw-row-password">
                        <td class="mw-label"><label for='wpPassword2'><?php $this->msg('yourpassword') ?></label></td>
                        <td class="mw-input">
 <?php
                        echo Html::input( 'wpPassword', null, 'password', array(
                                'class' => 'loginPassword',
                                'id' => 'wpPassword2',
-                               'tabindex' => '2',
+                               'tabindex' => '3',
                                'size' => '20'
                        ) + User::passwordChangeInputAttribs() ); ?>
                        </td>
@@ -98,20 +112,20 @@ class UsercreateTemplate extends QuickTemplate {
                        <td class="mw-label"><?php $this->msg( 'yourdomainname' ) ?></td>
                        <td class="mw-input">
                                <select name="wpDomain" value="<?php $this->text( 'domain' ) ?>"
-                                       tabindex="3">
+                                       tabindex="4">
                                        <?php echo $doms ?>
                                </select>
                        </td>
                </tr>
        <?php } ?>
-               <tr>
+               <tr class="mw-row-password">
                        <td class="mw-label"><label for='wpRetype'><?php $this->msg('yourpasswordagain') ?></label></td>
                        <td class="mw-input">
                                <?php
                echo Html::input( 'wpRetype', null, 'password', array(
                        'class' => 'loginPassword',
                        'id' => 'wpRetype',
-                       'tabindex' => '4',
+                       'tabindex' => '5',
                        'size' => '20'
                ) + User::passwordChangeInputAttribs() ); ?>
                        </td>
@@ -124,7 +138,7 @@ class UsercreateTemplate extends QuickTemplate {
                echo Html::input( 'wpEmail', $this->data['email'], 'email', array(
                        'class' => 'loginText',
                        'id' => 'wpEmail',
-                       'tabindex' => '5',
+                       'tabindex' => '6',
                        'size' => '20'
                ) ); ?>
                                        <div class="prefsectiontip">
@@ -146,7 +160,7 @@ class UsercreateTemplate extends QuickTemplate {
                                        <td class="mw-label"><label for='wpRealName'><?php $this->msg('yourrealname') ?></label></td>
                                        <td class="mw-input">
                                                <input type='text' class='loginText' name="wpRealName" id="wpRealName"
-                                                       tabindex="6"
+                                                       tabindex="7"
                                                        value="<?php $this->text('realname') ?>" size='20' />
                                                <div class="prefsectiontip">
                                                        <?php $this->msgWiki('prefs-help-realname'); ?>
@@ -159,7 +173,7 @@ class UsercreateTemplate extends QuickTemplate {
                                        <td class="mw-label"><label for='wpReason'><?php $this->msg('createaccountreason') ?></label></td>
                                        <td class="mw-input">
                                                <input type='text' class='loginText' name="wpReason" id="wpReason"
-                                                       tabindex="7"
+                                                       tabindex="8"
                                                        value="<?php $this->text('reason') ?>" size='20' />
                                        </td>
                        <?php } ?>
@@ -176,14 +190,14 @@ class UsercreateTemplate extends QuickTemplate {
                                        'wpRemember',
                                        'wpRemember',
                                        $this->data['remember'],
-                                       array( 'tabindex' => '8' )
+                                       array( 'tabindex' => '9' )
                                )
                                ?>
                        </td>
                </tr>
 <?php   }
 
-               $tabIndex = 9;
+               $tabIndex = 10;
                if ( isset( $this->data['extraInput'] ) && is_array( $this->data['extraInput'] ) ) {
                        foreach ( $this->data['extraInput'] as $inputItem ) { ?>
                <tr>
@@ -234,11 +248,6 @@ class UsercreateTemplate extends QuickTemplate {
                                <input type='submit' name="wpCreateaccount" id="wpCreateaccount"
                                        tabindex="<?php echo $tabIndex++; ?>"
                                        value="<?php $this->msg('createaccount') ?>" />
-                               <?php if( $this->data['createemail'] ) { ?>
-                               <input type='submit' name="wpCreateaccountMail" id="wpCreateaccountMail"
-                                       tabindex="<?php echo $tabIndex++; ?>"
-                                       value="<?php $this->msg('createaccountmail') ?>" />
-                               <?php } ?>
                        </td>
                </tr>
        </table>
index 7a62112..2159052 100644 (file)
@@ -257,6 +257,66 @@ class Language {
                return is_readable( self::getMessagesFileName( $code ) );
        }
 
+       /**
+        * Returns true if a language code string is a well-formed language tag
+        * according to RFC 5646.
+        * This function only checks well-formedness; it doesn't check that
+        * language, script or variant codes actually exist in the repositories.
+        *
+        * Based on regexes by Mark Davis of the Unicode Consortium:
+        * http://unicode.org/repos/cldr/trunk/tools/java/org/unicode/cldr/util/data/langtagRegex.txt
+        *
+        * @param $code string
+        * @param $lenient boolean Whether to allow '_' as separator. The default is only '-'.
+        *
+        * @return bool
+        * @since 1.21
+        */
+       public static function isWellFormedLanguageTag( $code, $lenient = false ) {
+               $alpha = '[a-z]';
+               $digit = '[0-9]';
+               $alphanum = '[a-z0-9]';
+               $x = 'x' ; # private use singleton
+               $singleton = '[a-wy-z]'; # other singleton
+               $s = $lenient ? '[-_]' : '-';
+
+               $language = "$alpha{2,8}|$alpha{2,3}$s$alpha{3}";
+               $script = "$alpha{4}"; # ISO 15924
+               $region = "(?:$alpha{2}|$digit{3})"; # ISO 3166-1 alpha-2 or UN M.49
+               $variant = "(?:$alphanum{5,8}|$digit$alphanum{3})";
+               $extension = "$singleton(?:$s$alphanum{2,8})+";
+               $privateUse = "$x(?:$s$alphanum{1,8})+";
+
+               # Define certain grandfathered codes, since otherwise the regex is pretty useless.
+               # Since these are limited, this is safe even later changes to the registry --
+               # the only oddity is that it might change the type of the tag, and thus
+               # the results from the capturing groups.
+               # http://www.iana.org/assignments/language-subtag-registry
+
+               $grandfathered = "en{$s}GB{$s}oed"
+                       . "|i{$s}(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)"
+                       . "|no{$s}(?:bok|nyn)"
+                       . "|sgn{$s}(?:BE{$s}(?:fr|nl)|CH{$s}de)"
+                       . "|zh{$s}min{$s}nan";
+
+               $variantList = "$variant(?:$s$variant)*";
+               $extensionList = "$extension(?:$s$extension)*";
+
+               $langtag = "(?:($language)"
+                       . "(?:$s$script)?"
+                       . "(?:$s$region)?"
+                       . "(?:$s$variantList)?"
+                       . "(?:$s$extensionList)?"
+                       . "(?:$s$privateUse)?)";
+
+               # The final breakdown, with capturing groups for each of these components
+               # The variants, extensions, grandfathered, and private-use may have interior '-'
+
+               $root = "^(?:$langtag|$privateUse|$grandfathered)$";
+
+               return (bool)preg_match( "/$root/", strtolower( $code ) );
+       }
+
        /**
         * Returns true if a language code string is of a valid form, whether or
         * not it exists. This includes codes which are used solely for
@@ -4300,5 +4360,4 @@ class Language {
                $form = CLDRPluralRuleEvaluator::evaluateCompiled( $number, $pluralRules );
                return $form;
        }
-
 }
index 8cc8c04..80593ea 100644 (file)
@@ -1095,7 +1095,7 @@ Do not forget to change your [[Special:Preferences|{{SITENAME}} preferences]].',
 'gotaccount'                 => 'Already have an account? $1.',
 'gotaccountlink'             => 'Log in',
 'userlogin-resetlink'        => 'Forgotten your login details?',
-'createaccountmail'          => 'By e-mail',
+'createaccountmail'          => 'Use a temporary random password and send it to the e-mail address specified below',
 'createaccountreason'        => 'Reason:',
 'badretype'                  => 'The passwords you entered do not match.',
 'userexists'                 => 'Username entered already in use.
@@ -2774,7 +2774,7 @@ Supported {{PLURAL:$2|protocol|protocols}}: <code>$1</code> (defaults to http://
 'activeusers'            => 'Active users list',
 'activeusers-summary'    => '', # do not translate or duplicate this message to other languages
 'activeusers-intro'      => 'This is a list of users who had some kind of activity within the last $1 {{PLURAL:$1|day|days}}.',
-'activeusers-count'      => '$1 {{PLURAL:$1|edit|edits}} in the last {{PLURAL:$3|day|$3 days}}',
+'activeusers-count'      => '$1 {{PLURAL:$1|action|actions}} in the last {{PLURAL:$3|day|$3 days}}',
 'activeusers-from'       => 'Display users starting at:',
 'activeusers-hidebots'   => 'Hide bots',
 'activeusers-hidesysops' => 'Hide administrators',
index 506a9f9..02af790 100644 (file)
@@ -4042,8 +4042,8 @@ You can apparently use 'URL' instead of 'hostname'.",
 'activeusers' => 'Title of [[Special:ActiveUsers]]',
 'activeusers-intro' => 'Used as introduction in [[Special:ActiveUsers]]. Parameters:
 * $1 - number of days (<code>$wgActiveUserDays</code>)',
-'activeusers-count' => "Used in [[Special:ActiveUsers]] to show the active user's recent edit count in brackets ([]).
-* $1 is the number of recent edits
+'activeusers-count' => "Used in [[Special:ActiveUsers]] to show the active user's recent action count in brackets ([]).
+* $1 is the number of recent actions
 * $2 is the user's name for use with GENDER (optional)
 * $3 is the maximum number of days of the RecentChangesList",
 'activeusers-from' => 'Used as label for checkbox in the form on [[Special:ActiveUsers]].
index f279c84..950855f 100644 (file)
@@ -926,6 +926,9 @@ return array(
                ),
                'dependencies' => array( 'mediawiki.libs.jpegmeta', 'mediawiki.util' ),
        ),
+       'mediawiki.special.userlogin.signup' => array(
+               'scripts' => 'resources/mediawiki.special/mediawiki.special.userLogin.signup.js',
+       ),
        'mediawiki.special.javaScriptTest' => array(
                'scripts' => 'resources/mediawiki.special/mediawiki.special.javaScriptTest.js',
                'messages' => array_merge( Skin::getSkinNameMessages(), array(
diff --git a/resources/mediawiki.special/mediawiki.special.userLogin.signup.js b/resources/mediawiki.special/mediawiki.special.userLogin.signup.js
new file mode 100644 (file)
index 0000000..bba4260
--- /dev/null
@@ -0,0 +1,10 @@
+/**
+ * JavaScript for Special:UserLogin/signup
+ */
+jQuery( document ).ready( function ( $ ) {
+       $( '#wpCreateaccountMail' )
+               .on( 'change', function() {
+                       $( '.mw-row-password' ).toggle( !$( this ).attr( 'checked' ) );
+               } )
+               .trigger( 'change' );
+} );
index 5b66d29..cf4ce94 100644 (file)
@@ -76,10 +76,14 @@ class SiteSQLStoreTest extends MediaWikiTestCase {
                $site = $store->getSite( 'ertrywuutr' );
                $this->assertInstanceOf( 'Site', $site );
                $this->assertEquals( 'en', $site->getLanguageCode() );
+               $this->assertTrue( is_integer( $site->getInternalId() ) );
+               $this->assertTrue( $site->getInternalId() >= 0 );
 
                $site = $store->getSite( 'sdfhxujgkfpth' );
                $this->assertInstanceOf( 'Site', $site );
                $this->assertEquals( 'nl', $site->getLanguageCode() );
+               $this->assertTrue( is_integer( $site->getInternalId() ) );
+               $this->assertTrue( $site->getInternalId() >= 0 );
        }
 
        public function testReset() {
index 5d32ff4..5594670 100644 (file)
@@ -307,6 +307,118 @@ class LanguageTest extends LanguageClassesTestCase {
                );
        }
 
+       /**
+        * Test Language::isWellFormedLanguageTag()
+        * @dataProvider provideWellFormedLanguageTags
+        */
+       function testWellFormedLanguageTag( $code, $message = '' ) {
+               $this->assertTrue(
+                       Language::isWellFormedLanguageTag( $code ),
+                       "validating code $code $message"
+               );
+       }
+
+       /**
+        * The test cases are based on the tests in the GaBuZoMeu parser
+        * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr>
+        * and distributed as free software, under the GNU General Public Licence.
+        * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html
+        */
+       function provideWellFormedLanguageTags() {
+               return array(
+                       array( 'fr', 'two-letter code' ),
+                       array( 'fr-latn', 'two-letter code with lower case script code' ),
+                       array( 'fr-Latn-FR', 'two-letter code with title case script code and uppercase country code' ),
+                       array( 'fr-Latn-419', 'two-letter code with title case script code and region number' ),
+                       array( 'fr-FR', 'two-letter code with uppercase' ),
+                       array( 'ax-TZ', 'Not in the registry, but well-formed' ),
+                       array( 'fr-shadok', 'two-letter code with variant' ),
+                       array( 'fr-y-myext-myext2', 'non-x singleton' ),
+                       array( 'fra-Latn', 'ISO 639 can be 3-letters' ),
+                       array( 'fra', 'three-letter language code' ),
+                       array( 'fra-FX', 'three-letter language code with country code' ),
+                       array( 'i-klingon', 'grandfathered with singleton' ),
+                       array( 'I-kLINgon', 'tags are case-insensitive...' ),
+                       array( 'no-bok', 'grandfathered without singleton' ),
+                       array( 'i-enochian', 'Grandfathered' ),
+                       array( 'x-fr-CH', 'private use' ),
+                       array( 'es-419', 'two-letter code with region number' ),
+                       array( 'en-Latn-GB-boont-r-extended-sequence-x-private', 'weird, but well-formed' ),
+                       array( 'ab-x-abc-x-abc', 'anything goes after x' ),
+                       array( 'ab-x-abc-a-a', 'anything goes after x, including several non-x singletons' ),
+                       array( 'i-default', 'grandfathered' ),
+                       array( 'abcd-Latn', 'Language of 4 chars reserved for future use' ),
+                       array( 'AaBbCcDd-x-y-any-x', 'Language of 5-8 chars, registered' ),
+                       array( 'de-CH-1901', 'with country and year' ),
+                       array( 'en-US-x-twain', 'with country and singleton' ),
+                       array( 'zh-cmn', 'three-letter variant' ),
+                       array( 'zh-cmn-Hant', 'three-letter variant and script' ),
+                       array( 'zh-cmn-Hant-HK', 'three-letter variant, script and country' ),
+                       array( 'xr-p-lze', 'Extension' ),
+               );
+       }
+
+       /**
+        * Negative test for Language::isWellFormedLanguageTag()
+        * @dataProvider provideMalformedLanguageTags
+        */
+       function testMalformedLanguageTag( $code, $message = '' ) {
+               $this->assertFalse(
+                       Language::isWellFormedLanguageTag( $code ),
+                       "validating that code $code is a malformed language tag - $message"
+               );
+       }
+
+       /**
+        * The test cases are based on the tests in the GaBuZoMeu parser
+        * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr>
+        * and distributed as free software, under the GNU General Public Licence.
+        * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html
+        */
+       function provideMalformedLanguageTags() {
+               return array(
+                       array( 'f', 'language too short' ),
+                       array( 'f-Latn', 'language too short with script' ),
+                       array( 'xr-lxs-qut', 'variants too short' ), # extlangS
+                       array( 'fr-Latn-F', 'region too short' ),
+                       array( 'a-value', 'language too short with region' ),
+                       array( 'tlh-a-b-foo', 'valid three-letter with wrong variant' ),
+                       array( 'i-notexist', 'grandfathered but not registered: invalid, even if we only test well-formedness' ),
+                       array( 'abcdefghi-012345678', 'numbers too long' ),
+                       array( 'ab-abc-abc-abc-abc', 'invalid extensions' ),
+                       array( 'ab-abcd-abc', 'invalid extensions' ),
+                       array( 'ab-ab-abc', 'invalid extensions' ),
+                       array( 'ab-123-abc', 'invalid extensions' ),
+                       array( 'a-Hant-ZH', 'short language with valid extensions' ),
+                       array( 'a1-Hant-ZH', 'invalid character in language' ),
+                       array( 'ab-abcde-abc', 'invalid extensions' ),
+                       array( 'ab-1abc-abc', 'invalid characters in extensions' ),
+                       array( 'ab-ab-abcd', 'invalid order of extensions' ),
+                       array( 'ab-123-abcd', 'invalid order of extensions' ),
+                       array( 'ab-abcde-abcd', 'invalid extensions' ),
+                       array( 'ab-1abc-abcd', 'invalid characters in extensions' ),
+                       array( 'ab-a-b', 'extensions too short' ),
+                       array( 'ab-a-x', 'extensions too short, even with singleton' ),
+                       array( 'ab--ab', 'two separators' ),
+                       array( 'ab-abc-', 'separator in the end' ),
+                       array( '-ab-abc', 'separator in the beginning' ),
+                       array( 'abcd-efg', 'language too long' ),
+                       array( 'aabbccddE', 'tag too long' ),
+                       array( 'pa_guru', 'A tag with underscore is invalid in strict mode' ),
+                       array( 'de-f', 'subtag too short' ),
+               );
+       }
+
+       /**
+        * Negative test for Language::isWellFormedLanguageTag()
+        */
+       function testLenientLanguageTag() {
+               $this->assertTrue(
+                       Language::isWellFormedLanguageTag( 'pa_guru', true ),
+                       'pa_guru is a well-formed language tag in lenient mode'
+               );
+       }
+
        /**
         * Test Language::isValidBuiltInCode()
         * @dataProvider provideLanguageCodes