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 ApiBase;
6use ApiCreateTempUserTrait;
7use ApiMain;
8use ApiUsageException;
9use Exception;
10use InvalidArgumentException;
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        $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        $this->showSuccessMessage( $params, $savedTempUser );
101    }
102
103    private function getLexemeIdFromParamOrDie( $serialization ): LexemeId {
104        try {
105            return new LexemeId( $serialization );
106        } catch ( InvalidArgumentException $e ) {
107            $this->errorReporter->dieException( $e, 'invalid-entity-id' );
108        }
109    }
110
111    /** @inheritDoc */
112    protected function getAllowedParams() {
113        return array_merge( [
114            self::SOURCE_ID_PARAM => [
115                ParamValidator::PARAM_TYPE => 'string',
116                ParamValidator::PARAM_REQUIRED => true,
117            ],
118            self::TARGET_ID_PARAM => [
119                ParamValidator::PARAM_TYPE => 'string',
120                ParamValidator::PARAM_REQUIRED => true,
121            ],
122            self::SUMMARY_PARAM => [
123                ParamValidator::PARAM_TYPE => 'string',
124            ],
125            'tags' => [
126                ParamValidator::PARAM_TYPE => 'tags',
127                ParamValidator::PARAM_ISMULTI => true,
128            ],
129            self::BOT_PARAM => [
130                ParamValidator::PARAM_TYPE => 'boolean',
131                ParamValidator::PARAM_DEFAULT => false,
132            ],
133        ], $this->getCreateTempUserParams() );
134    }
135
136    /** @inheritDoc */
137    protected function getExamplesMessages() {
138        return [
139            'action=wblmergelexemes&source=L123&target=L321' =>
140                'apihelp-wblmergelexemes-example-1',
141        ];
142    }
143
144    /** @inheritDoc */
145    public function needsToken() {
146        return 'csrf';
147    }
148
149    /** @inheritDoc */
150    public function isWriteMode() {
151        return true;
152    }
153
154    private function showSuccessMessage( array $params, ?UserIdentity $savedTempUser ) {
155        $result = $this->getResult();
156        $result->addContentValue( null, 'success', 1 );
157
158        if ( $savedTempUser !== null ) {
159            $result->addValue( null, 'tempusercreated', $savedTempUser->getName() );
160            $redirectUrl = $this->getTempUserRedirectUrl( $params, $savedTempUser );
161            if ( $redirectUrl === '' ) {
162                $redirectUrl = null;
163            }
164            $result->addValue( null, 'tempuserredirect', $redirectUrl );
165        }
166    }
167
168}