* - forceChange (bool): if set to true, the user should not be
* allowed to log with this password unless they change it during
* the login process (see ResetPasswordSecondaryAuthenticationProvider).
+ * - suggestChangeOnLogin (bool): if set to true, the user should be prompted for
+ * a password change on login.
*
* @param string $password Desired password
* @return Status
return false;
}
- // Reject various classes of invalid names
- $name = AuthManager::callLegacyAuthPlugin(
- 'getCanonicalName', [ $t->getText() ], $t->getText()
- );
+ $name = $t->getText();
switch ( $validate ) {
case false:
// update groups in external authentication database
Hooks::run( 'UserGroupsChanged', [ $this, $toPromote, [], false, false, $oldUGMs, $newUGMs ] );
- AuthManager::callLegacyAuthPlugin( 'updateExternalDBGroups', [ $this, $toPromote ] );
$logEntry = new ManualLogEntry( 'rights', 'autopromote' );
$logEntry->setPerformer( $this );
$this->mBlockedby = $block->getByName();
$this->mBlockreason = $block->mReason;
$this->mHideName = $block->mHideName;
- $this->mAllowUsertalk = !$block->prevents( 'editownusertalk' );
+ $this->mAllowUsertalk = $block->isUsertalkEditAllowed();
} else {
$this->mBlock = null;
$this->mBlockedby = '';
* @return bool True if blocked, false otherwise
*/
public function isBlocked( $bFromReplica = true ) {
- return $this->getBlock( $bFromReplica ) instanceof Block && $this->getBlock()->prevents( 'edit' );
+ return $this->getBlock( $bFromReplica ) instanceof Block &&
+ $this->getBlock()->appliesToRight( 'edit' );
}
/**
// Special handling for a user's own talk page. The block is not aware
// of the user, so this must be done here.
if ( $title->equals( $this->getTalkPage() ) ) {
- if ( $block->isSitewide() ) {
- // If the block is sitewide, whatever is set is what is honored.
- // This must be checked here, because Block::appliesToPage will
- // return true for a sitewide block.
- $blocked = $block->prevents( 'editownusertalk' );
- } else {
- // The page restrictions always take precedence over the namespace
- // restrictions. If the user is explicity blocked from their own
- // talk page, nothing can change that.
- $blocked = $block->appliesToPage( $title->getArticleID() );
-
- // If the block applies to the user talk namespace, then whatever is
- // set is what is honored.
- if ( !$blocked && $block->appliesToNamespace( NS_USER_TALK ) ) {
- $blocked = $block->prevents( 'editownusertalk' );
- }
-
- // If another type of restriction is added, it should be checked
- // here.
- }
+ $blocked = $block->appliesToUsertalk( $title );
} else {
$blocked = $block->appliesToTitle( $title );
}
if ( $this->mLocked !== null ) {
return $this->mLocked;
}
- // Avoid PHP 7.1 warning of passing $this by reference
- $user = $this;
- $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$user ], null );
- $this->mLocked = $authUser && $authUser->isLocked();
+ // Reset for hook
+ $this->mLocked = false;
Hooks::run( 'UserIsLocked', [ $this, &$this->mLocked ] );
return $this->mLocked;
}
}
$this->getBlockedStatus();
if ( !$this->mHideName ) {
- // Avoid PHP 7.1 warning of passing $this by reference
- $user = $this;
- $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$user ], null );
- $this->mHideName = $authUser && $authUser->isHidden();
+ // Reset for hook
+ $this->mHideName = false;
Hooks::run( 'UserIsHidden', [ $this, &$this->mHideName ] );
}
return (bool)$this->mHideName;
Hooks::run( 'UserSaveSettings', [ $this ] );
$this->clearSharedCache();
- $this->getUserPage()->invalidateCache();
+ $this->getUserPage()->purgeSquid();
}
/**
*/
public function isBlockedFromCreateAccount() {
$this->getBlockedStatus();
- if ( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ) {
+ if ( $this->mBlock && $this->mBlock->appliesToRight( 'createaccount' ) ) {
return $this->mBlock;
}
$this->mBlockedFromCreateAccount = Block::newFromTarget( null, $this->getRequest()->getIP() );
}
return $this->mBlockedFromCreateAccount instanceof Block
- && $this->mBlockedFromCreateAccount->prevents( 'createaccount' )
+ && $this->mBlockedFromCreateAccount->appliesToRight( 'createaccount' )
? $this->mBlockedFromCreateAccount
: false;
}
*/
public function isBlockedFromEmailuser() {
$this->getBlockedStatus();
- return $this->mBlock && $this->mBlock->prevents( 'sendemail' );
+ return $this->mBlock && $this->mBlock->appliesToRight( 'sendemail' );
}
/**
*/
public function isBlockedFromUpload() {
$this->getBlockedStatus();
- return $this->mBlock && $this->mBlock->prevents( 'upload' );
+ return $this->mBlock && $this->mBlock->appliesToRight( 'upload' );
}
/**
if ( $type == 'created' || $type === false ) {
$message = 'confirmemail_body';
+ $type = 'created';
} elseif ( $type === true ) {
$message = 'confirmemail_body_changed';
+ $type = 'changed';
} else {
// Messages: confirmemail_body_changed, confirmemail_body_set
$message = 'confirmemail_body_' . $type;
}
- return $this->sendMail( wfMessage( 'confirmemail_subject' )->text(),
- wfMessage( $message,
+ $mail = [
+ 'subject' => wfMessage( 'confirmemail_subject' )->text(),
+ 'body' => wfMessage( $message,
$this->getRequest()->getIP(),
$this->getName(),
$url,
$wgLang->userTimeAndDate( $expiration, $this ),
$invalidateURL,
$wgLang->userDate( $expiration, $this ),
- $wgLang->userTime( $expiration, $this ) )->text() );
+ $wgLang->userTime( $expiration, $this ) )->text(),
+ 'from' => null,
+ 'replyTo' => null,
+ ];
+ $info = [
+ 'type' => $type,
+ 'ip' => $this->getRequest()->getIP(),
+ 'confirmURL' => $url,
+ 'invalidateURL' => $invalidateURL,
+ 'expiration' => $expiration
+ ];
+
+ Hooks::run( 'UserSendConfirmationMail', [ $this, &$mail, $info ] );
+ return $this->sendMail( $mail['subject'], $mail['body'], $mail['from'], $mail['replyTo'] );
}
/**
* @param string $body Message body
* @param User|null $from Optional sending user; if unspecified, default
* $wgPasswordSender will be used.
- * @param string|null $replyto Reply-To address
+ * @param MailAddress|null $replyto Reply-To address
* @return Status
*/
public function sendMail( $subject, $body, $from = null, $replyto = null ) {
* non-existent/anonymous user accounts.
*/
public function getFirstEditTimestamp() {
+ return $this->getEditTimestamp( true );
+ }
+
+ /**
+ * Get the timestamp of the latest edit
+ *
+ * @since 1.33
+ * @return string|bool Timestamp of first edit, or false for
+ * non-existent/anonymous user accounts.
+ */
+ public function getLatestEditTimestamp() {
+ return $this->getEditTimestamp( false );
+ }
+
+ /**
+ * Get the timestamp of the first or latest edit
+ *
+ * @param bool $first True for the first edit, false for the latest one
+ * @return string|bool Timestamp of first or latest edit, or false for
+ * non-existent/anonymous user accounts.
+ */
+ private function getEditTimestamp( $first ) {
if ( $this->getId() == 0 ) {
return false; // anons
}
$actorWhere = ActorMigration::newMigration()->getWhere( $dbr, 'rev_user', $this );
$tsField = isset( $actorWhere['tables']['temp_rev_user'] )
? 'revactor_timestamp' : 'rev_timestamp';
+ $sortOrder = $first ? 'ASC' : 'DESC';
$time = $dbr->selectField(
[ 'revision' ] + $actorWhere['tables'],
$tsField,
[ $actorWhere['conds'] ],
__METHOD__,
- [ 'ORDER BY' => "$tsField ASC" ],
+ [ 'ORDER BY' => "$tsField $sortOrder" ],
$actorWhere['joins']
);
if ( !$time ) {