}
}
+ // "wpExtraQueryRedirect" is a hidden input to modify
+ // after save URL and is not used by actual edit form
+ $request = RequestContext::getMain()->getRequest();
+ $extraQueryRedirect = $request->getVal( 'wpExtraQueryRedirect' );
+
switch ( $status->value ) {
case self::AS_HOOK_ERROR_EXPECTED:
case self::AS_CONTENT_TOO_BIG:
case self::AS_SUCCESS_NEW_ARTICLE:
$query = $resultDetails['redirect'] ? 'redirect=no' : '';
+ if ( $extraQueryRedirect ) {
+ if ( $query === '' ) {
+ $query = $extraQueryRedirect;
+ } else {
+ $query = $query . '&' . $extraQueryRedirect;
+ }
+ }
$anchor = isset( $resultDetails['sectionanchor'] ) ? $resultDetails['sectionanchor'] : '';
$wgOut->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
return false;
$extraQuery = 'redirect=no&' . $extraQuery;
}
}
+ if ( $extraQueryRedirect ) {
+ if ( $extraQuery === '' ) {
+ $extraQuery = $extraQueryRedirect;
+ } else {
+ $extraQuery = $extraQuery . '&' . $extraQueryRedirect;
+ }
+ }
+
$wgOut->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
return false;
* WARNING: do not use this function on arbitrary user-supplied titles!
* On heavily-used templates it will max out the memory.
*
- * @param array $options May be FOR UPDATE
+ * @param array $options Query option to Database::select()
* @return Title[] Array of Title the Title objects linking here
*/
public function getTemplateLinksTo( $options = [] ) {
* WARNING: do not use this function on arbitrary user-supplied titles!
* On heavily-used templates it will max out the memory.
*
- * @param array $options May be FOR UPDATE
+ * @param array $options Query option to Database::select()
* @param string $table Table name
* @param string $prefix Fields prefix
* @return array Array of Title objects linking here
return [];
}
- if ( count( $options ) > 0 ) {
- $db = wfGetDB( DB_MASTER );
- } else {
- $db = wfGetDB( DB_SLAVE );
- }
+ $db = wfGetDB( DB_SLAVE );
$blNamespace = "{$prefix}_namespace";
$blTitle = "{$prefix}_title";
return $wgLang;
}
+ // Checking if DB language is set
+ $dbPageLanguage = $this->getDbPageLanguageCode();
+ if ( $dbPageLanguage ) {
+ $pageLang = wfGetLangObj( $dbPageLanguage );
+ $variant = $pageLang->getPreferredVariant();
+ if ( $pageLang->getCode() !== $variant ) {
+ $pageLang = Language::factory( $variant );
+ }
+
+ return $pageLang;
+ }
+
// @note Can't be cached persistently, depends on user settings.
// @note ContentHandler::getPageViewLanguage() may need to load the
// content to determine the page language!
$this->addWhereIf( 'rc_user != 0', isset( $show['!anon'] ) );
$this->addWhereIf( 'rc_patrolled = 0', isset( $show['!patrolled'] ) );
$this->addWhereIf( 'rc_patrolled != 0', isset( $show['patrolled'] ) );
- $this->addWhereIf( 'wl_notificationtimestamp IS NOT NULL', isset( $show['unread'] ) );
- $this->addWhereIf( 'wl_notificationtimestamp IS NULL', isset( $show['!unread'] ) );
+ $this->addWhereIf( 'rc_timestamp >= wl_notificationtimestamp', isset( $show['unread'] ) );
+ $this->addWhereIf(
+ 'wl_notificationtimestamp IS NULL OR rc_timestamp < wl_notificationtimestamp',
+ isset( $show['!unread'] )
+ );
}
if ( !is_null( $params['type'] ) ) {
$table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
) {
if ( $var === '*' ) { // sanity
- throw new DBUnexpectedError( $this, "Cannot use a * field: got '$var'" );
+ throw new DBUnexpectedError( $this, "Cannot use a * field" );
+ } elseif ( !is_string( $var ) ) { // sanity
+ throw new DBUnexpectedError( $this, "Cannot use an array of fields" );
}
if ( !is_array( $options ) ) {
? $info['ResourceFileModulePaths']
: false;
if ( isset( $defaultPaths['localBasePath'] ) ) {
- $defaultPaths['localBasePath'] = "$dir/{$defaultPaths['localBasePath']}";
+ if ( $defaultPaths['localBasePath'] === '' ) {
+ // Avoid double slashes (e.g. /extensions/Example//path)
+ $defaultPaths['localBasePath'] = $dir;
+ } else {
+ $defaultPaths['localBasePath'] = "$dir/{$defaultPaths['localBasePath']}";
+ }
}
foreach ( [ 'ResourceModules', 'ResourceModuleSkinStyles' ] as $setting ) {
if ( isset( $info[$setting] ) ) {
foreach ( $info[$setting] as $name => $data ) {
if ( isset( $data['localBasePath'] ) ) {
- $data['localBasePath'] = "$dir/{$data['localBasePath']}";
+ if ( $data['localBasePath'] === '' ) {
+ // Avoid double slashes (e.g. /extensions/Example//path)
+ $data['localBasePath'] = $dir;
+ } else {
+ $data['localBasePath'] = "$dir/{$data['localBasePath']}";
+ }
}
if ( $defaultPaths ) {
$data += $defaultPaths;
// Try the local user from the slave DB
$localId = User::idFromName( $user->getName() );
+ $flags = 0;
// Fetch the user ID from the master, so that we don't try to create the user
// when they already exist, due to replication lag
// @codeCoverageIgnoreStart
if ( !$localId && wfGetLB()->getReaderIndex() != 0 ) {
$localId = User::idFromName( $user->getName(), User::READ_LATEST );
+ $flags = User::READ_LATEST;
}
// @codeCoverageIgnoreEnd
if ( $localId ) {
// User exists after all.
$user->setId( $localId );
- $user->loadFromId();
+ $user->loadFromId( $flags );
return false;
}
$status = $user->addToDatabase();
if ( !$status->isOK() ) {
// @codeCoverageIgnoreStart
- $logger->error( __METHOD__ . ': failed with message ' . $status->getWikiText(),
- [
- 'username' => $userName,
- ] );
- $user->setId( 0 );
- $user->loadFromId();
+ // double-check for a race condition (T70012)
+ $id = User::idFromName( $user->getName(), User::READ_LATEST );
+ if ( $id ) {
+ $logger->info( __METHOD__ . ': tried to autocreate existing user',
+ [
+ 'username' => $userName,
+ ] );
+ } else {
+ $logger->error( __METHOD__ . ': failed with message ' . $status->getWikiText(),
+ [
+ 'username' => $userName,
+ ] );
+ }
+ $user->setId( $id );
+ $user->loadFromId( User::READ_LATEST );
return false;
// @codeCoverageIgnoreEnd
}
$out->addReturnTo( $this->getPageTitle() );
}
+ /**
+ * Return an array of subpages beginning with $search that this special page will accept.
+ *
+ * @param string $search Prefix to search for
+ * @param int $limit Maximum number of results to return (usually 10)
+ * @param int $offset Number of results to skip (usually 0)
+ * @return string[] Matching subpages
+ */
+ public function prefixSearchSubpages( $search, $limit, $offset ) {
+ $user = User::newFromName( $search );
+ if ( !$user ) {
+ // No prefix suggestion for invalid user
+ return [];
+ }
+ // Autocomplete subpage as user list - public to allow caching
+ return UserNamePrefixSearch::search( 'public', $search, $limit, $offset );
+ }
+
protected function getGroupName() {
return 'users';
}
}
public static function provideExtractResourceLoaderModules() {
- $dir = __DIR__ . '/FooBar/';
+ $dir = __DIR__ . '/FooBar';
return [
// Generic module with localBasePath/remoteExtPath specified
[
],
'test.bar' => [
'styles' => 'bar.js',
- 'localBasePath' => $dir . 'subdir',
+ 'localBasePath' => "$dir/subdir",
'remoteExtPath' => 'FooBar/subdir',
],
'test.class' => [