Merge "Record a log entry on page creation"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sun, 3 Jun 2018 07:43:34 +0000 (07:43 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sun, 3 Jun 2018 07:43:35 +0000 (07:43 +0000)
1  2 
RELEASE-NOTES-1.32
includes/DefaultSettings.php
includes/Setup.php
includes/page/WikiPage.php
languages/i18n/en.json
languages/i18n/qqq.json

diff --combined RELEASE-NOTES-1.32
@@@ -21,29 -21,23 +21,31 @@@ production
    adds a defense-in-depth feature to stop an attacker who has found a bug in
    the parser allowing them to insert malicious attributes. Disabled by default,
    you can configure this via $wgCSPHeader and $wgCSPReportOnlyHeader.
 +* New configuration variable has been added: $wgCookieSetOnIpBlock.
 +  This determines whether to set a cookie when an IP user is blocked. Doing so means
 +  that a blocked user, even after moving to a new IP address, will still be blocked.
  
  === New features in 1.32 ===
  * (T112474) Generalized the ResourceLoader mechanism for overriding modules
    using a particular page during edit previews.
+ * (T12331) You can now log page creation events by setting $wgPageCreationLog
+   to true.
  * Added 'ApiParseMakeOutputPage' hook.
 -* (T174313) Added checkbox on Special:ListUsers to display only users in temporary
 -  user groups.
 +* (T174313) Added checkbox on Special:ListUsers to display only users in
 +  temporary user groups.
 +* (T152462) A cookie can now be set when an IP user is blocked to track that user if
 +  they move to a new IP address. This is disabled by default.
  
  === External library changes in 1.32 ===
  * …
  
  ==== Upgraded external libraries ====
  * Updated QUnit from 2.4.0 to 2.6.0.
 +* Updated wikimedia/scoped-callback from 1.0.0 to 2.0.0.
 +** ScopedCallback objects can no longer be serialized.
  
  ==== New external libraries ====
 +* Added wikimedia/xmp-reader 0.5.1
  * …
  
  ==== Removed and replaced external libraries ====
@@@ -62,8 -56,6 +64,8 @@@
      from normal parameters. All parameter definitions now include an "index"
      key to allow clients to maintain parameter ordering when merging normal and
      templated parameters.
 +* It is now an error to submit too many values for a multi-valued parameter.
 +  This has generated a warning since MediaWiki 1.14.
  
  === Action API internal changes in 1.32 ===
  * Added 'ApiParseMakeOutputPage' hook.
@@@ -76,8 -68,6 +78,8 @@@ Below only new and removed languages ar
  because of Phabricator reports.
  
  * (T193566) Added language support for Ambonese Malay (abs).
 +* (T194047) Added language support for Shawiya, Latin script (shy-latn).
 +* (T195940) Added language support for Batak Mandailing (btm).
  
  === Breaking changes in 1.32 ===
  * $wgRequestTime, deprecated in 1.25, was removed. Use
  * mw.util.updateTooltipAccessKeys(), deprecated in 1.24, was removed. Use
    jquery.accessKeyLabel instead.
  * The SqlDataUpdate class, deprecated in 1.28, has been removed.
 -* The Html5Internal and Html5Depurate tidy driver classes were removed, along with the
 -  Balancer tidy implementation. Both implementations were experimental, and were replaced
 -  by RemexHtml.
 +* The Html5Internal and Html5Depurate tidy driver classes were removed, along
 +  with the Balancer tidy implementation. Both implementations were experimental,
 +  and were replaced by RemexHtml.
 +* (T179624) Job::insert() and ::batchInsert(), deprecated in 1.21, were both
 +  removed. Use JobQueueGroup::singleton()->push() instead.
 +* The jquery.footHovzer module, for mediawiki.debug, was removed.
 +* The es5-shim module, empty and deprecated since 1.29, was removed.
 +* The mediawiki.widgets.visibleByteLimit module alias, deprecated in 1.32, was
 +  removed. Use mediawiki.widgets.visibleLengthLimit instead.
 +* The jquery.farbtastic module, unused since 1.18, was removed.
 +* (T181318) The $wgStyleVersion setting and its appendage to various script and
 +  style URLs in OutputPage, deprecated in 1.31, was removed.
 +* The hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend' may provide
 +  any HTMLForm object rather than PreferencesForm.
 +* The non namespaced TimestampException class, deprecated in 1.29, was removed.
 +  Use Wikimedia\Timestamp\TimestampException instead.
 +* The global functions codepointToUtf8, hexSequenceToUtf8, utf8ToHexSequence,
 +  utf8ToCodepoint, and escapeSingleString (deprecated in 1.25) were removed.
 +  The UtfNormal\Utils class from the utfnormal library should be used instead.
 +* The deprecated UTF8_ and UNICODE_ constants were removed. The class constants
 +  from the UtfNormal\Constants class from the utfnormal library should be used
 +* (T140807) The wgResourceLoaderLESSImportPaths configuration option was removed
 +  from ResourceLoader. Instead, use `@import` statements in LESS to import
 +  files directly from nearby directories within the same project.
 +* The protected methods PHPSessionHandler::returnSuccess() and returnFailure(),
 +  only needed for PHP5 compatibility, have been removed. It now uses the boolean
 +  values `true` and `false` respectively.
 +* The $parserMemc global and wfGetParserCacheStorage(), deprecated since 1.30,
 +  were removed. Use the ParserCache class instead.
 +* ScopedCallback (deprecated in 1.28) was removed. Use Wikimedia\ScopedCallback
 +  instead.
  
  === Deprecations in 1.32 ===
  * Use of a StartProfiler.php file is deprecated in favour of placing
    in extending classes is deprecated.  Extend related doSearch* methods
    instead.
  * CollationFa has been removed completely as it's not needed anymore
 +* The following 'mediawiki.api' plugin modules were merged into mediawiki.api
 +  and deprecated: mediawiki.api.category, mediawiki.api.edit,
 +  mediawiki.api.login, mediawiki.api.options, mediawiki.api.parse,
 +  mediawiki.api.upload, mediawiki.api.user, mediawiki.api.watch,
 +  mediawiki.api.messages, and mediawiki.api.rollback.
 +* ApiBase::truncateArray() is deprecated. No replacement, as nothing is known
 +  to use it.
 +* WatchAction::getUnwatchToken is deprecated. Use WatchAction::getWatchToken
 +  with the 'unwatch' action parameter instead.
 +* IcuCollation::getICUVersion() is deprecated, as you can just use the PHP
 +  constant INTL_ICU_VERSION directly in all versions that MediaWiki supports.
 +* Parser::fetchFile() is deprecated. Use ::fetchFileAndTitle() instead.
 +* The ApiQueryContributions class has been renamed to ApiQueryUserContribs.
 +* The XMPInfo, XMPReader, and XMPValidate classes have been deprecated in favor
 +  of the namespaced classes provided by the wikimedia/xmp-reader library.
  
  === Other changes in 1.32 ===
 -* Soft hyphens (U+00AD) are now automatically removed from titles; these
 -  characters can accidentally end up in copy-and-pasted titles.
 -* Strip Unicode 6.3.0 directional formatting characters (U+061C, U+2066,
 -  U+2067, U+2068, U+2069) from the title.
  * …
  
  == Compatibility ==
 -MediaWiki 1.32 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is
 -supported, it is generally advised to use PHP 5.5.9 or later for long term
 +MediaWiki 1.32 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is
 +supported, it is generally advised to use PHP 7.0.0 or later for long term
  support.
  
  MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
@@@ -2565,6 -2565,17 +2565,6 @@@ $wgCacheEpoch = '20030516000000'
   */
  $wgGitInfoCacheDirectory = false;
  
 -/**
 - * Bump this number when changing the global style sheets and JavaScript.
 - *
 - * It should be appended in the query string of static CSS and JS includes,
 - * to ensure that client-side caches do not keep obsolete copies of global
 - * styles.
 - *
 - * @deprecated since 1.31
 - */
 -$wgStyleVersion = '303';
 -
  /**
   * This will cache static pages for non-logged-in users to reduce
   * database traffic on public sites. ResourceLoader requests to default
@@@ -3227,8 -3238,8 +3227,8 @@@ $wgHTMLFormAllowTableFormat = true
  $wgUseMediaWikiUIEverywhere = false;
  
  /**
 - * Temporary variable that determines whether the EditPage class should use OOjs UI or not.
 - * This will be removed later and OOjs UI will become the only option.
 + * Temporary variable that determines whether Special:Preferences should use OOUI or not.
 + * This will be removed later and OOUI will become the only option.
   *
   * @since 1.32
   */
@@@ -3778,6 -3789,23 +3778,6 @@@ $wgResourceLoaderLESSVars = 
        'deviceWidthTablet' => '720px',
  ];
  
 -/**
 - * Default import paths for LESS modules. LESS files referenced in @import
 - * statements will be looked up here first, and relative to the importing file
 - * second. To avoid collisions, it's important for the LESS files in these
 - * directories to have a common, predictable file name prefix.
 - *
 - * Extensions need not (and should not) register paths in
 - * $wgResourceLoaderLESSImportPaths. The import path includes the path of the
 - * currently compiling LESS file, which allows each extension to freely import
 - * files from its own tree.
 - *
 - * @since 1.22
 - */
 -$wgResourceLoaderLESSImportPaths = [
 -      "$IP/resources/src/mediawiki.less/",
 -];
 -
  /**
   * Whether ResourceLoader should attempt to persist modules in localStorage on
   * browsers that support the Web Storage API.
@@@ -6015,15 -6043,6 +6015,15 @@@ $wgSessionName = false
   */
  $wgCookieSetOnAutoblock = false;
  
 +/**
 + * Whether to set a cookie when a logged-out user is blocked. Doing so means that a blocked user,
 + * even after moving to a new IP address, will still be blocked. This cookie will contain an
 + * authentication code if $wgSecretKey is set, or otherwise will just be the block ID (in which
 + * case there is a possibility of an attacker discovering the names of revdeleted users, so it
 + * is best to use this in conjunction with $wgSecretKey being set).
 + */
 +$wgCookieSetOnIpBlock = false;
 +
  /** @} */ # end of cookie settings }
  
  /************************************************************************//**
@@@ -7869,10 -7888,16 +7869,16 @@@ $wgActionFilteredLogs = 
  ];
  
  /**
-  * Maintain a log of newusers at Log/newusers?
+  * Maintain a log of newusers at Special:Log/newusers?
   */
  $wgNewUserLog = true;
  
+ /**
+  * Maintain a log of page creations at Special:Log/create?
+  * @since 1.32
+  */
+ $wgPageCreationLog = false;
  /** @} */ # end logging }
  
  /*************************************************************************//**
diff --combined includes/Setup.php
@@@ -24,8 -24,6 +24,8 @@@
   * @file
   */
  use MediaWiki\MediaWikiServices;
 +use Wikimedia\Rdbms\LBFactory;
 +use Wikimedia\Rdbms\ChronologyProtector;
  
  /**
   * This file is not a valid entry point, perform no further processing unless
@@@ -533,7 -531,7 +533,7 @@@ if ( $wgInvalidateCacheOnLocalSettingsC
  }
  
  if ( $wgNewUserLog ) {
-       // Add a new log type
+       // Add new user log type
        $wgLogTypes[] = 'newusers';
        $wgLogNames['newusers'] = 'newuserlogpage';
        $wgLogHeaders['newusers'] = 'newuserlogpagetext';
        $wgLogActionsHandlers['newusers/autocreate'] = NewUsersLogFormatter::class;
  }
  
+ if ( $wgPageCreationLog ) {
+       // Add page creation log type
+       $wgLogTypes[] = 'create';
+       $wgLogActionsHandlers['create/create'] = LogFormatter::class;
+ }
  if ( $wgPageLanguageUseDB ) {
        $wgLogTypes[] = 'pagelang';
        $wgLogActionsHandlers['pagelang/pagelang'] = PageLangLogFormatter::class;
@@@ -627,6 -631,10 +633,6 @@@ define( 'MW_SERVICE_BOOTSTRAP_COMPLETE'
  
  MWExceptionHandler::installHandler();
  
 -require_once "$IP/includes/compat/normal/UtfNormalUtil.php";
 -
 -$ps_validation = Profiler::instance()->scopedProfileIn( $fname . '-validation' );
 -
  // T48998: Bail out early if $wgArticlePath is non-absolute
  foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
        }
  }
  
 -Profiler::instance()->scopedProfileOut( $ps_validation );
 -
  $ps_default2 = Profiler::instance()->scopedProfileIn( $fname . '-defaults2' );
  
  if ( $wgCanonicalServer === false ) {
@@@ -699,7 -709,7 +705,7 @@@ if ( $wgMainWANCache === false ) 
  
  Profiler::instance()->scopedProfileOut( $ps_default2 );
  
 -$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc1' );
 +$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc' );
  
  // Raise the memory limit if it's too low
  wfMemoryLimit();
@@@ -734,15 -744,9 +740,15 @@@ MediaWikiServices::getInstance()->getDB
        'IPAddress' => $wgRequest->getIP(),
        'UserAgent' => $wgRequest->getHeader( 'User-Agent' ),
        'ChronologyProtection' => $wgRequest->getHeader( 'ChronologyProtection' ),
 -      // The cpPosIndex cookie has no prefix and is set by MediaWiki::preOutputCommit()
 -      'ChronologyPositionIndex' =>
 -              $wgRequest->getInt( 'cpPosIndex', (int)$wgRequest->getCookie( 'cpPosIndex', '' ) )
 +      'ChronologyPositionIndex' => $wgRequest->getInt(
 +              'cpPosIndex',
 +              LBFactory::getCPIndexFromCookieValue(
 +                      // The cookie has no prefix and is set by MediaWiki::preOutputCommit()
 +                      $wgRequest->getCookie( 'cpPosIndex', '' ),
 +                      // Mitigate broken client-side cookie expiration handling (T190082)
 +                      time() - ChronologyProtector::POSITION_COOKIE_TTL
 +              )
 +      )
  ] );
  // Make sure that object caching does not undermine the ChronologyProtector improvements
  if ( $wgRequest->getCookie( 'UseDC', '' ) === 'master' ) {
@@@ -768,9 -772,19 +774,9 @@@ if ( $wgCommandLineMode ) 
        wfDebug( $debug );
  }
  
 -Profiler::instance()->scopedProfileOut( $ps_misc );
 -$ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' );
 -
  $wgMemc = wfGetMainCache();
  $messageMemc = wfGetMessageCacheStorage();
  
 -/**
 - * @deprecated since 1.30
 - */
 -$parserMemc = new DeprecatedGlobal( 'parserMemc', function () {
 -      return MediaWikiServices::getInstance()->getParserCache()->getCacheStorage();
 -}, '1.30' );
 -
  wfDebugLog( 'caches',
        'cluster: ' . get_class( $wgMemc ) .
        ', WAN: ' . ( $wgMainWANCache === CACHE_NONE ? 'CACHE_NONE' : $wgMainWANCache ) .
        ', session: ' . get_class( ObjectCache::getInstance( $wgSessionCacheType ) )
  );
  
 -Profiler::instance()->scopedProfileOut( $ps_memcached );
 +Profiler::instance()->scopedProfileOut( $ps_misc );
  
  // Most of the config is out, some might want to run hooks here.
  Hooks::run( 'SetupAfterCache' );
@@@ -811,6 -825,8 +817,6 @@@ if ( $wgAuth && !$wgAuth instanceof Med
        ], '$wgAuth is ' . get_class( $wgAuth ) );
  }
  
 -// Set up the session
 -$ps_session = Profiler::instance()->scopedProfileIn( $fname . '-session' );
  /**
   * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent
   * session ID (if any) loaded at startup
@@@ -874,6 -890,7 +880,6 @@@ if ( !defined( 'MW_NO_SESSION' ) && !$w
                );
        }
  }
 -Profiler::instance()->scopedProfileOut( $ps_session );
  
  /**
   * @var User $wgUser
@@@ -910,7 -927,22 +916,7 @@@ $ps_extensions = Profiler::instance()->
  // of the extension file. This allows the extension to perform
  // any necessary initialisation in the fully initialised environment
  foreach ( $wgExtensionFunctions as $func ) {
 -      // Allow closures in PHP 5.3+
 -      if ( is_object( $func ) && $func instanceof Closure ) {
 -              $profName = $fname . '-extensions-closure';
 -      } elseif ( is_array( $func ) ) {
 -              if ( is_object( $func[0] ) ) {
 -                      $profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1];
 -              } else {
 -                      $profName = $fname . '-extensions-' . implode( '::', $func );
 -              }
 -      } else {
 -              $profName = $fname . '-extensions-' . strval( $func );
 -      }
 -
 -      $ps_ext_func = Profiler::instance()->scopedProfileIn( $profName );
        call_user_func( $func );
 -      Profiler::instance()->scopedProfileOut( $ps_ext_func );
  }
  
  // If the session user has a 0 id but a valid name, that means we need to
  if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
        $sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser();
        if ( $sessionUser->getId() === 0 && User::isValidUserName( $sessionUser->getName() ) ) {
 -              $ps_autocreate = Profiler::instance()->scopedProfileIn( $fname . '-autocreate' );
                $res = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
                        $sessionUser,
                        MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION,
                        true
                );
 -              Profiler::instance()->scopedProfileOut( $ps_autocreate );
                \MediaWiki\Logger\LoggerFactory::getInstance( 'authevents' )->info( 'Autocreation attempt', [
                        'event' => 'autocreate',
                        'status' => $res,
@@@ -1874,7 -1874,7 +1874,7 @@@ class WikiPage implements Page, IDBAcce
        private function doCreate(
                Content $content, $flags, User $user, $summary, array $meta
        ) {
-               global $wgUseRCPatrol, $wgUseNPPatrol;
+               global $wgUseRCPatrol, $wgUseNPPatrol, $wgPageCreationLog;
  
                $status = Status::newGood( [ 'new' => true, 'revision' => null ] );
  
  
                $user->incEditCount();
  
+               if ( $wgPageCreationLog ) {
+                       // Log the page creation
+                       // @TODO: Do we want a 'recreate' action?
+                       $logEntry = new ManualLogEntry( 'create', 'create' );
+                       $logEntry->setPerformer( $user );
+                       $logEntry->setTarget( $this->mTitle );
+                       $logEntry->setComment( $summary );
+                       $logEntry->setTimestamp( $now );
+                       $logEntry->setAssociatedRevId( $revisionId );
+                       $logid = $logEntry->insert();
+                       // Note that we don't publish page creation events to recentchanges
+                       // (i.e. $logEntry->publish()) since this would create duplicate entries,
+                       // one for the edit and one for the page creation.
+               }
                $dbw->endAtomic( __METHOD__ );
                $this->mTimestamp = $now;
  
                }
  
                // raise error, when the edit is an edit without a new version
 -              $statusRev = isset( $status->value['revision'] )
 -                      ? $status->value['revision']
 -                      : null;
 +              $statusRev = $status->value['revision'] ?? null;
                if ( !( $statusRev instanceof Revision ) ) {
                        $resultDetails = [ 'current' => $current ];
                        return [ [ 'alreadyrolled',
diff --combined languages/i18n/en.json
        "dellogpage": "Deletion log",
        "dellogpagetext": "Below is a list of the most recent deletions.",
        "deletionlog": "deletion log",
+       "log-name-create": "Page creation log",
+       "log-description-create": "Below is a list of the most recent page creations.",
+       "logentry-create-create": "$1 {{GENDER:$2|created}} page $3",
        "reverted": "Reverted to earlier revision",
        "deletecomment": "Reason:",
        "deleteotherreason": "Other/additional reason:",
        "whatlinkshere-title": "Pages that link to \"$1\"",
        "whatlinkshere-summary": "",
        "whatlinkshere-page": "Page:",
 -      "linkshere-2": "The following pages link to <strong>$1</strong>:",
 -      "nolinkshere-2": "No pages link to <strong>$1</strong>.",
 -      "nolinkshere-ns-2": "No pages link to <strong>$1</strong> in the chosen namespace.",
 +      "linkshere-2": "The following pages link to <strong>$2</strong>:",
 +      "nolinkshere-2": "No pages link to <strong>$2</strong>.",
 +      "nolinkshere-ns-2": "No pages link to <strong>$2</strong> in the chosen namespace.",
        "isredirect": "redirect page",
        "istemplate": "transclusion",
        "isimage": "file link",
        "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on your client's Accept header. This means that the page data will be provided in the format preferred by your client.",
        "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1",
        "pagedata-bad-title": "Invalid title: $1.",
 -      "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users."
 +      "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users.",
 +      "passwordpolicies": "Password policies",
 +      "passwordpolicies-summary": "This is a list of the effective password policies for the user groups defined in this wiki.",
 +      "passwordpolicies-group": "Group",
 +      "passwordpolicies-policies": "Policies",
 +      "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
 +      "passwordpolicies-policy-minimalpasswordlength": "Password must be at least $1 {{PLURAL:$1|character|characters}} long",
 +      "passwordpolicies-policy-minimumpasswordlengthtologin": "Password must be at least $1 {{PLURAL:$1|character|characters}} long to be able to login",
 +      "passwordpolicies-policy-passwordcannotmatchusername": "Password cannot be the same as username",
 +      "passwordpolicies-policy-passwordcannotmatchblacklist": "Password cannot match specifically blacklisted passwords",
 +      "passwordpolicies-policy-maximalpasswordlength": "Password must be less than $1 {{PLURAL:$1|character|characters}} long",
 +      "passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}"
  }
diff --combined languages/i18n/qqq.json
                        "Trizek (WMF)",
                        "Acamicamacaraca",
                        "Avatar6",
 -                      "Akapochtli"
 +                      "Akapochtli",
 +                      "ديفيد",
 +                      "Daimona Eaytoy"
                ]
        },
        "sidebar": "{{notranslate}}",
        "pool-servererror": "Error message. Parameters:\n* $1 - list of server addresses\n\nSee e.g. {{msg-mw|Poolcounter-desc}} (and the Pool Counter extension in general) for translation hints for “pool counter service”.",
        "poolcounter-usage-error": "Used as error message. Parameters:\n* $1 - non-localized string describing usage mistake.",
        "aboutsite": "Used as the label of the link that appears at the footer of every page on the wiki (in most of  the skins) and leads to the page that contains the site description. The link target is {{msg-mw|aboutpage}}.\n\n[[mw:Manual:Interface/Aboutsite|MediaWiki manual]].\n\n{{doc-important|Do not change <nowiki>{{SITENAME}}</nowiki>.}}\n\n{{Identical|About}}",
 -      "aboutpage": "Used as the target of the link that appears at the footer of every page on the wiki (in most of  the skins) and leads to the page that contains the site description. Therefore the content should be the same with the page name of the site description page. Only the message in the [[mw:Manual:$wgLanguageCode|site language]]  ([[MediaWiki:Aboutpage]]) is used. The link label is {{msg-mw|aboutsite}}.\n\n{{doc-important|Do not translate \"Project:\" part, for this is the namespace prefix.}}",
 +      "aboutpage": "{{doc-important|Do not translate \"Project:\" part, for this is the namespace prefix.}}\n\nUsed as the target of the link that appears at the footer of every page on the wiki (in most of  the skins) and leads to the page that contains the site description. Therefore the content should be the same with the page name of the site description page. Only the message in the [[mw:Manual:$wgLanguageCode|site language]]  ([[MediaWiki:Aboutpage]]) is used. The link label is {{msg-mw|aboutsite}}.",
        "copyright": "Parameters:\n* $1 - license name\n'''See also'''\n* {{msg-mw|Mobile-frontend-copyright}}",
        "copyrightpage": "{{doc-important|Do not change <nowiki>{{ns:project}}</nowiki>}}\n\n{{Identical|Copyright}}",
        "currentevents": "Standard link in the sidebar, for news.\n\nSee also {{msg-mw|Currentevents-url}} for the link URL.\n\nSee also:\n* {{msg-mw|Currentevents}}\n* {{msg-mw|Accesskey-n-currentevents}}\n* {{msg-mw|Tooltip-n-currentevents}}",
        "expansion-depth-exceeded-category": "This message is used as a category name for a [[mw:Help:Tracking categories|tracking category]] where pages are placed automatically if the [[meta:Help:Expansion_depth|expansion depth]] of the preprocessor exceeds the limit.",
        "expansion-depth-exceeded-category-desc": "Expansion depth exceeded category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
        "expansion-depth-exceeded-warning": "Error message shown when a page exceeded the [[meta:Help:Expansion_depth|expansion depth limit]] of the preprocessor.\n\nParameters:\n* $1 - (Unused) the value of the depth limit\n* $2 - (Unused) the value of the max depth limit\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
 -      "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.\n\nSee also:\n*{{msg-mw|Parser-unstrip-recursion-limit}}",
 -      "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
 -      "unstrip-depth-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.",
 -      "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
 -      "unstrip-size-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.",
 +      "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
 +      "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
 +      "unstrip-depth-category": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
 +      "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}",
 +      "unstrip-size-category": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-warning}}",
        "converter-manual-rule-error": "Used as error message when a manual conversion rule for the [[mw:Language_converter|language converter]] has errors. For example it's not using the correct syntax, or not supplying text in all variants.",
        "undo-success": "Text on special page to confirm edit revert. You arrive on this page by clicking on the \"undo\" link on a revision history special page.\n\n{{Identical|Undo}}",
        "undo-failure": "Message appears if an attempt to revert an edit by clicking the \"undo\" link on the page history fails.\n\nSee also:\n* {{msg-mw|Undo-norev}}\n* {{msg-mw|Undo-nochange}}\n{{Identical|Undo}}",
        "dellogpage": "{{doc-logpage}}\n\nThe name of the deletion log. Used as heading on [[Special:Log/delete]] and in the drop down menu for selecting logs on [[Special:Log]].\n{{Identical|Deletion log}}",
        "dellogpagetext": "Text in [[Special:Log/delete]].",
        "deletionlog": "Used as text for the link which points to the deletion log:\n* Used as <code>$1</code> in {{msg-mw|Filewasdeleted}}\n* Used as <code>$2</code> in {{msg-mw|Deletedtext}}\n* Used in log lines on [[Special:DeletedContributions]]\n{{Identical|Deletion log}}",
+       "log-name-create": "{{doc-logpage}}\n\nThe name of the page creation log. Used as heading on [[Special:Log/create]] and in the drop down menu for selecting logs on [[Special:Log]].",
+       "log-description-create": "Text in [[Special:Log/create]].",
+       "logentry-create-create": "{{Logentry|[[Special:Log/create]]}}",
        "reverted": "{{Identical|Revert}}",
        "deletecomment": "{{Identical|Reason}}",
        "deleteotherreason": "{{Identical|Other/additional reason}}",
        "whatlinkshere-title": "Title of the special page [[Special:WhatLinksHere]]. This page appears when you click on the 'What links here' button in the toolbox. $1 is the name of the page concerned.",
        "whatlinkshere-summary": "{{doc-specialpagesummary|whatlinkshere}}",
        "whatlinkshere-page": "{{Identical|Page}}",
 -      "linkshere-2": "This message is the header line of the [[Special:WhatLinksHere/$1]] page generated by clicking \"What links here\" in the sidebar toolbox.\n\nIt is followed by a navigation bar built using {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - HTML link to the page.",
 -      "nolinkshere-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - HTML link to the page\nSee also:\n* {{msg-mw|Nolinkshere-ns-html}}",
 -      "nolinkshere-ns-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - HTML link to the page\nSee also:\n* {{msg-mw|Nolinkshere-html}}",
 +      "linkshere-2": "This message is the header line of the [[Special:WhatLinksHere/$1]] page generated by clicking \"What links here\" in the sidebar toolbox.\n\nIt is followed by a navigation bar built using {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - Plain page title\n* $2 - HTML link to the page.",
 +      "nolinkshere-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - Plain page title\n* $2 - HTML link to the page.\nSee also:\n* {{msg-mw|Nolinkshere-ns-2}}",
 +      "nolinkshere-ns-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - Plain page title\n* $2 - HTML link to the page.\nSee also:\n* {{msg-mw|Nolinkshere-2}}",
        "isredirect": "Displayed in [[Special:WhatLinksHere]] (see [{{fullurl:Special:WhatLinksHere/Project:Translator|hidelinks=1}} Special:WhatLinksHere/Project:Translator] for example).\n\n{{Identical|Redirect page}}",
        "istemplate": "Means that a page (a template, specifically) is used as <code><nowiki>{{Page name}}</nowiki></code>.\nDisplayed in [[Special:WhatLinksHere]] (see [[Special:WhatLinksHere/Template:New portal]] for example).\nIf you are not sure how to translate this term, think of something like \"inclusion\", \"embedding\", or \"insertion\".\n{{Identical|Transclusion}}",
        "isimage": "This message is displayed on [[Special:WhatLinksHere]] for images. It means that the image is used on the page (as opposed to just being linked to like an non-image page).\n{{Identical|File link}}",
        "limitreport-expansiondepth-value": "{{optional}}\nFormat for the \"Highest expansion depth\" row in the limit report table.\n\nParameters:\n* $1 - the depth\n* $2 - the maximum",
        "limitreport-expensivefunctioncount": "Label for the \"Expensive parser function count\" row in the limit report table",
        "limitreport-expensivefunctioncount-value": "{{optional}}\nFormat for the \"Expensive parser function count\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
 -      "limitreport-unstrip-depth": "Label for the \"unstrip depth\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
 +      "limitreport-unstrip-depth": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nLabel for the \"unstrip depth\" row in the limit report table.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
        "limitreport-unstrip-depth-value": "{{optional}}\nFormat for the \"unstrip depth\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
 -      "limitreport-unstrip-size": "Label for the \"unstrip size\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
 +      "limitreport-unstrip-size": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nLabel for the \"unstrip size\" row in the limit report table.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
        "limitreport-unstrip-size-value": "Format for the \"unstrip size\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum\n{{Identical|Byte}}",
        "expandtemplates": "{{doc-special|ExpandTemplates}}\nThe name of the [[mw:Extension:ExpandTemplates|Expand Templates extension]].",
        "expand_templates_intro": "This is the explanation given in the heading of the [[Special:ExpandTemplates]] page; it describes its functionality to the users.\nFor more information, see [[mw:Extension:ExpandTemplates]]",
        "mediastatistics-header-3d": "Header on [[Special:MediaStatistics]] for file types that are in the 3D category. Includes STL files.",
        "mediastatistics-header-total": "Header on [[Special:MediaStatistics]] for a summary of all file types.",
        "json-warn-trailing-comma": "A warning message notifying that JSON text was automatically corrected by removing erroneous commas.\n\nParameters:\n* $1 - number of commas that were removed\n{{Related|Json-error}}",
 -      "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See http://php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",
 -      "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 -      "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\n\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 -      "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 -      "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}\n{{Identical|Syntax error}}",
 -      "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 -      "json-error-recursion": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 -      "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 -      "json-error-unsupported-type": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See https://secure.php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",
 +      "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\n\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}\n{{Identical|Syntax error}}",
 +      "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-recursion": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
 +      "json-error-unsupported-type": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
        "headline-anchor-title": "Title tooltip for the section anchor symbol, which is a link to the current section. Can be interpreted both as a noun (\"this is a link\") or as a verb (\"use this to link\").",
        "special-characters-group-latin": "This is the name of a script, or alphabet, not a language.",
        "special-characters-group-latinextended": "The name of the Latin Extended character set.",
        "pagedata-text": "Error shown when none of the formats acceptable to the client is supported (HTTP error 406). Parameters:\n* $1 - the list of supported MIME types",
        "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1",
        "pagedata-bad-title": "Error shown when the requested title is invalid. Parameters:\n* $1: the malformed ID",
 -      "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype=<mime type> where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'."
 +      "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype=<mime type> where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'.",
 +      "passwordpolicies": "The name of the special page [[Special:PasswordPolicies]].",
 +      "passwordpolicies-summary": "The description used on [[Special:PasswordPolicies]].\n\nRefers to {{msg-mw|Passwordpolicies-helppage}}.",
 +      "passwordpolicies-group": "The title of the column in the table, about user groups (like you are in the ''translator'' group).\n\n{{Identical|Group}}\n{{Related|Passwordpolicies}}",
 +      "passwordpolicies-policies": "The title of the column in the table, about password policies.\n{{Related|Passwordpolicies}}",
 +      "passwordpolicies-policy-display": "{{optional}}\nParameters:\n* $1 - the text from the \"passwordpolicies-policy-...\" messages, i.e. {{msg-mw|passwordpolicies-policy-minimalpasswordlength}}\n* $2 - the name of this password policy",
 +      "passwordpolicies-policy-minimalpasswordlength": "Password policy that enforces a minimum number of characters a password must be. $1 - minimum number of characters that a password can be",
 +      "passwordpolicies-policy-minimumpasswordlengthtologin": "Password policy that enforces a minimum number of characters a password must be to be able to login to the wiki. $1 - minimum number of characters that a password can be to be able to login",
 +      "passwordpolicies-policy-passwordcannotmatchusername": "Password policy that enforces that the password of the account cannot be the same as the username",
 +      "passwordpolicies-policy-passwordcannotmatchblacklist": "Password policy that enforces that passwords are not on a list of blacklisted passwords (often previously used during MediaWiki automated testing)",
 +      "passwordpolicies-policy-maximalpasswordlength": "Password policy that enforces a maximum number of characters a password must be. $1 - maximum number of characters that a password can be",
 +      "passwordpolicies-policy-passwordcannotbepopular": "Password policy that enforces that a password is not in a list of $1 number of \"popular\" passwords. $1 - number of popular passwords the password will be checked against"
  }