35 private $userNameUtils;
37 private $userOptionsManager;
39 private $wikiPageFactory;
41 private $userOptionsLookup;
45 public const CONSTRUCTOR_OPTIONS = [
46 'TranslateUseSandbox',
49 public function __construct(
52 UserFactory $userFactory,
53 UserNameUtils $userNameUtils,
54 UserOptionsManager $userOptionsManager,
55 WikiPageFactory $wikiPageFactory,
56 UserOptionsLookup $userOptionsLookup,
57 ServiceOptions $options
59 parent::__construct( $mainModule, $moduleName );
60 $this->userFactory = $userFactory;
61 $this->userNameUtils = $userNameUtils;
62 $this->userOptionsManager = $userOptionsManager;
63 $this->wikiPageFactory = $wikiPageFactory;
64 $this->userOptionsLookup = $userOptionsLookup;
65 $this->options = $options;
68 public function execute():
void {
69 if ( !$this->options->get(
'TranslateUseSandbox' ) ) {
70 $this->dieWithError(
'apierror-translate-sandboxdisabled',
'sandboxdisabled' );
73 $params = $this->extractRequestParams();
74 switch ( $params[
'do'] ) {
88 $this->dieWithError( [
'apierror-badparameter',
'do' ] );
92 private function doCreate():
void {
93 $params = $this->extractRequestParams();
96 foreach ( explode(
'|',
'username|password|email' ) as $field ) {
97 if ( !isset( $params[$field] ) ) {
98 $this->dieWithError( [
'apierror-missingparam', $field ],
'missingparam' );
102 $username = $params[
'username'];
104 $canonicalName = $this->userNameUtils->getCanonical( $username, UserNameUtils::RIGOR_CREATABLE );
106 if ( $canonicalName ===
false ) {
107 $this->dieWithError(
'noname',
'invalidusername' );
110 $user = $this->userFactory->newFromName( $username );
111 if ( $user->getId() !== 0 ) {
112 $this->dieWithError(
'userexists',
'nonfreeusername' );
115 $password = $params[
'password'];
116 $passwordValidityStatus = $user->checkPasswordValidity( $password );
117 if ( !$passwordValidityStatus->isGood() ) {
118 $this->dieStatus( $passwordValidityStatus );
121 $email = $params[
'email'];
122 if ( !Sanitizer::validateEmail( $email ) ) {
123 $this->dieWithError(
'invalidemailaddress',
'invalidemail' );
126 $user = TranslateSandbox::addUser( $username, $email, $password );
127 $output = [
'user' => [
128 'name' => $user->getName(),
129 'id' => $user->getId(),
132 $this->userOptionsManager->setOption( $user,
'language', $this->getContext()->getLanguage()->getCode() );
133 $this->userOptionsManager->saveOptions( $user );
135 $this->getResult()->addValue(
null, $this->getModuleName(), $output );
138 private function doDelete():
void {
139 $this->checkUserRightsAny(
'translate-sandboxmanage' );
141 $params = $this->extractRequestParams();
143 foreach ( $params[
'userid'] as $userId ) {
144 $user = $this->userFactory->newFromId( $userId );
145 $userpage = $user->getUserPage();
147 TranslateSandbox::sendEmail( $this->getUser(), $user,
'rejection' );
150 TranslateSandbox::deleteUser( $user );
151 }
catch ( MWException $e ) {
153 [
'apierror-translate-sandbox-invalidparam', wfEscapeWikiText( $e->getMessage() ) ],
158 $logEntry =
new ManualLogEntry(
'translatorsandbox',
'rejected' );
159 $logEntry->setPerformer( $this->getUser() );
160 $logEntry->setTarget( $userpage );
161 $logid = $logEntry->insert();
162 $logEntry->publish( $logid );
166 private function doPromote():
void {
167 $this->checkUserRightsAny(
'translate-sandboxmanage' );
169 $params = $this->extractRequestParams();
171 foreach ( $params[
'userid'] as $userId ) {
172 $user = $this->userFactory->newFromId( $userId );
175 TranslateSandbox::promoteUser( $user );
176 }
catch ( MWException $e ) {
178 [
'apierror-translate-sandbox-invalidparam', wfEscapeWikiText( $e->getMessage() ) ],
183 TranslateSandbox::sendEmail( $this->getUser(), $user,
'promotion' );
185 $logEntry =
new ManualLogEntry(
'translatorsandbox',
'promoted' );
186 $logEntry->setPerformer( $this->getUser() );
187 $logEntry->setTarget( $user->getUserPage() );
188 $logEntry->setParameters( [
189 '4::userid' => $user->getId(),
191 $logid = $logEntry->insert();
192 $logEntry->publish( $logid );
194 $this->createUserPage( $user );
198 private function doRemind():
void {
199 $params = $this->extractRequestParams();
201 foreach ( $params[
'userid'] as $userId ) {
202 $target = $this->userFactory->newFromId( $userId );
205 TranslateSandbox::sendEmail( $this->getUser(), $target,
'reminder' );
206 }
catch ( MWException $e ) {
208 [
'apierror-translate-sandbox-invalidparam', wfEscapeWikiText( $e->getMessage() ) ],
216 private function createUserPage( User $user ):
void {
217 $userpage = $user->getUserPage();
219 if ( $userpage->exists() ) {
223 $languagePrefs = FormatJson::decode(
224 $this->userOptionsLookup->getOption( $user,
'translate-sandbox' ),
227 $languages = implode(
'|', $languagePrefs[
'languages' ] ?? [] );
228 $babeltext =
"{{#babel:$languages}}";
229 $summary = $this->msg(
'tsb-create-user-page' )->inContentLanguage()->text();
231 $page = $this->wikiPageFactory->newFromTitle( $userpage );
232 $content = ContentHandler::makeContent( $babeltext, $userpage );
234 $page->newPageUpdater( $user )
235 ->setContent( SlotRecord::MAIN, $content )
236 ->saveRevision( CommentStoreComment::newUnsavedComment( trim( $summary ) ), EDIT_NEW );
239 public function isWriteMode():
bool {
243 public function needsToken():
string {
247 protected function getAllowedParams(): array {
250 ParamValidator::PARAM_TYPE => [
'create',
'delete',
'promote',
'remind' ],
251 ParamValidator::PARAM_REQUIRED =>
true,
254 ParamValidator::PARAM_TYPE =>
'integer',
255 ParamValidator::PARAM_DEFAULT => 0,
256 ParamValidator::PARAM_ISMULTI =>
true,
259 ParamValidator::PARAM_TYPE =>
'string',
260 ParamValidator::PARAM_REQUIRED =>
true,
262 'username' => [ ParamValidator::PARAM_TYPE =>
'string' ],
263 'password' => [ ParamValidator::PARAM_TYPE =>
'string' ],
264 'email' => [ ParamValidator::PARAM_TYPE =>
'string' ],