Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.63% covered (warning)
79.63%
43 / 54
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiEdit
79.63% covered (warning)
79.63%
43 / 54
75.00% covered (warning)
75.00%
3 / 4
10.85
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
 needsToken
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
69.44% covered (warning)
69.44%
25 / 36
0.00% covered (danger)
0.00%
0 / 1
8.40
 getAllowedParams
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\CommunityConfiguration\Api;
4
5use ApiBase;
6use ApiMain;
7use InvalidArgumentException;
8use MediaWiki\Extension\CommunityConfiguration\Provider\ConfigurationProviderFactory;
9use MediaWiki\Extension\CommunityConfiguration\Validation\ValidationStatus;
10use MediaWiki\Json\FormatJson;
11use MediaWiki\Logger\LoggerFactory;
12use Psr\Log\LoggerAwareTrait;
13use Wikimedia\ParamValidator\ParamValidator;
14
15class ApiEdit extends ApiBase {
16    use LoggerAwareTrait;
17
18    private ConfigurationProviderFactory $configurationProviderFactory;
19
20    /**
21     * @param ApiMain $mainModule
22     * @param string $moduleName
23     * @param ConfigurationProviderFactory $configurationProviderFactory
24     */
25    public function __construct(
26        ApiMain $mainModule,
27        $moduleName,
28        ConfigurationProviderFactory $configurationProviderFactory
29    ) {
30        parent::__construct( $mainModule, $moduleName );
31        $this->setLogger( LoggerFactory::getInstance( 'CommunityConfiguration' ) );
32
33        $this->configurationProviderFactory = $configurationProviderFactory;
34    }
35
36    /**
37     * @inheritDoc
38     */
39    public function needsToken() {
40        return 'csrf';
41    }
42
43    /**
44     * @inheritDoc
45     */
46    public function execute() {
47        $params = $this->extractRequestParams();
48        try {
49            $provider = $this->configurationProviderFactory->newProvider( $params['provider'] );
50        } catch ( InvalidArgumentException $e ) {
51            // NOTE: Assuming the list of supported keys in getAllowedParams() are correct, this
52            // branch should be never triggered.
53
54            $this->logger->error(
55                __METHOD__ . ' failed to construct the {provider} provider',
56                [ 'provider' => $params['provider'], 'exception' => $e ],
57            );
58            $this->dieWithException( $e );
59        }
60
61        $newConfigStatus = FormatJson::parse( $params['content'] );
62        if ( !$newConfigStatus->isOK() ) {
63            $this->dieStatus( $newConfigStatus );
64        }
65
66        $status = $provider->storeValidConfiguration(
67            $newConfigStatus->getValue(),
68            $this->getAuthority(),
69            $params['summary']
70        );
71
72        if ( !$status->isOK() ) {
73            if ( $status instanceof ValidationStatus ) {
74                $errorData = $status->getValidationErrorsData();
75                $lastIndex = count( $errorData ) - 1;
76                foreach ( $status->getMessages() as $index => $errorMessageSpecifier ) {
77                    if ( $index === $lastIndex ) {
78                        $this->dieWithError(
79                            $errorMessageSpecifier,
80                            null,
81                            $errorData[$index]
82                        );
83                    }
84                    $this->addError(
85                        $errorMessageSpecifier,
86                        null,
87                        $errorData[$index]
88                    );
89                }
90            }
91            $this->dieStatus( $status );
92        }
93
94        $this->getResult()->addValue( null, $this->getModuleName(), [
95            'result' => 'success',
96        ] );
97    }
98
99    /**
100     * @inheritDoc
101     */
102    protected function getAllowedParams() {
103        return [
104            'provider' => [
105                ParamValidator::PARAM_TYPE => $this->configurationProviderFactory->getSupportedKeys(),
106                ParamValidator::PARAM_REQUIRED => true,
107            ],
108            'content' => [
109                ParamValidator::PARAM_TYPE => 'string',
110                ParamValidator::PARAM_REQUIRED => true,
111            ],
112            'summary' => [
113                ParamValidator::PARAM_TYPE => 'string',
114                ParamValidator::PARAM_DEFAULT => '',
115            ],
116        ];
117    }
118}