Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.11% covered (warning)
86.11%
62 / 72
66.67% covered (warning)
66.67%
6 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
MergeLexemes
86.11% covered (warning)
86.11%
62 / 72
66.67% covered (warning)
66.67%
6 / 9
15.60
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 factory
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 execute
78.26% covered (warning)
78.26%
18 / 23
0.00% covered (danger)
0.00%
0 / 1
4.16
 getLexemeIdFromParamOrDie
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getAllowedParams
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
1
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 needsToken
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isWriteMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 showSuccessMessage
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
3.02
1<?php
2
3namespace Wikibase\Lexeme\MediaWiki\Api;
4
5use Exception;
6use InvalidArgumentException;
7use MediaWiki\Api\ApiBase;
8use MediaWiki\Api\ApiCreateTempUserTrait;
9use MediaWiki\Api\ApiMain;
10use MediaWiki\Api\ApiUsageException;
11use MediaWiki\User\UserIdentity;
12use Wikibase\Lexeme\Domain\Merge\Exceptions\MergingException;
13use Wikibase\Lexeme\Domain\Model\LexemeId;
14use Wikibase\Lexeme\Interactors\MergeLexemes\MergeLexemesInteractor;
15use Wikibase\Repo\Api\ApiErrorReporter;
16use Wikibase\Repo\Api\ApiHelperFactory;
17use Wikimedia\ParamValidator\ParamValidator;
18
19/**
20 * WikibaseLexeme API endpoint wblmergelexemes
21 *
22 * @license GPL-2.0-or-later
23 */
24class MergeLexemes extends ApiBase {
25
26    use ApiCreateTempUserTrait;
27
28    public const SOURCE_ID_PARAM = 'source';
29    public const TARGET_ID_PARAM = 'target';
30    public const SUMMARY_PARAM = 'summary';
31    private const BOT_PARAM = 'bot';
32
33    /**
34     * @var ApiErrorReporter
35     */
36    private $errorReporter;
37
38    private MergeLexemesInteractor $mergeLexemesInteractor;
39
40    public function __construct(
41        ApiMain $mainModule,
42        string $moduleName,
43        callable $errorReporterCallback,
44        MergeLexemesInteractor $mergeLexemesInteractor
45    ) {
46        parent::__construct( $mainModule, $moduleName );
47        $this->errorReporter = $errorReporterCallback( $this );
48        $this->mergeLexemesInteractor = $mergeLexemesInteractor;
49    }
50
51    public static function factory(
52        ApiMain $mainModule,
53        string $moduleName,
54        ApiHelperFactory $apiHelperFactory,
55        MergeLexemesInteractor $mergeLexemesInteractor
56    ): self {
57        return new self(
58            $mainModule,
59            $moduleName,
60            static function ( $module ) use ( $apiHelperFactory ) {
61                return $apiHelperFactory->getErrorReporter( $module );
62            },
63            $mergeLexemesInteractor
64        );
65    }
66
67    /**
68     * @see ApiBase::execute()
69     *
70     * @throws ApiUsageException
71     */
72    public function execute() {
73        $params = $this->extractRequestParams();
74
75        $sourceId = $this->getLexemeIdFromParamOrDie( $params[self::SOURCE_ID_PARAM] );
76        $targetId = $this->getLexemeIdFromParamOrDie( $params[self::TARGET_ID_PARAM] );
77
78        try {
79            $status = $this->mergeLexemesInteractor->mergeLexemes(
80                $sourceId,
81                $targetId,
82                $this->getContext(),
83                $params[self::SUMMARY_PARAM],
84                $params[self::BOT_PARAM],
85                $params['tags'] ?: []
86            );
87            $savedTempUser = $status->getSavedTempUser();
88        } catch ( MergingException $e ) {
89            $this->errorReporter->dieException(
90                $e,
91                $e->getApiErrorCode()
92            );
93        } catch ( Exception $e ) {
94            $this->errorReporter->dieException(
95                $e,
96                'bad-request'
97            );
98        }
99
100        // @phan-suppress-next-line PhanPossiblyUndeclaredVariable
101        $this->showSuccessMessage( $params, $savedTempUser );
102    }
103
104    private function getLexemeIdFromParamOrDie( string $serialization ): LexemeId {
105        try {
106            return new LexemeId( $serialization );
107        } catch ( InvalidArgumentException $e ) {
108            $this->errorReporter->dieException( $e, 'invalid-entity-id' );
109        }
110    }
111
112    /** @inheritDoc */
113    protected function getAllowedParams() {
114        return array_merge( [
115            self::SOURCE_ID_PARAM => [
116                ParamValidator::PARAM_TYPE => 'string',
117                ParamValidator::PARAM_REQUIRED => true,
118            ],
119            self::TARGET_ID_PARAM => [
120                ParamValidator::PARAM_TYPE => 'string',
121                ParamValidator::PARAM_REQUIRED => true,
122            ],
123            self::SUMMARY_PARAM => [
124                ParamValidator::PARAM_TYPE => 'string',
125            ],
126            'tags' => [
127                ParamValidator::PARAM_TYPE => 'tags',
128                ParamValidator::PARAM_ISMULTI => true,
129            ],
130            self::BOT_PARAM => [
131                ParamValidator::PARAM_TYPE => 'boolean',
132                ParamValidator::PARAM_DEFAULT => false,
133            ],
134        ], $this->getCreateTempUserParams() );
135    }
136
137    /** @inheritDoc */
138    protected function getExamplesMessages() {
139        return [
140            'action=wblmergelexemes&source=L123&target=L321' =>
141                'apihelp-wblmergelexemes-example-1',
142        ];
143    }
144
145    /** @inheritDoc */
146    public function needsToken() {
147        return 'csrf';
148    }
149
150    /** @inheritDoc */
151    public function isWriteMode() {
152        return true;
153    }
154
155    private function showSuccessMessage( array $params, ?UserIdentity $savedTempUser ) {
156        $result = $this->getResult();
157        $result->addContentValue( null, 'success', 1 );
158
159        if ( $savedTempUser !== null ) {
160            $result->addValue( null, 'tempusercreated', $savedTempUser->getName() );
161            $redirectUrl = $this->getTempUserRedirectUrl( $params, $savedTempUser );
162            if ( $redirectUrl === '' ) {
163                $redirectUrl = null;
164            }
165            $result->addValue( null, 'tempuserredirect', $redirectUrl );
166        }
167    }
168
169}