Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ListsCreateBatchHandler
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 7
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 postInitSetup
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 validate
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 detectExtraneousBodyFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
 getParamSettings
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBodyParamSettings
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\ReadingLists\Rest;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Extension\ReadingLists\ReadingListRepositoryException;
7use MediaWiki\Logger\LoggerFactory;
8use MediaWiki\Rest\Handler;
9use MediaWiki\Rest\LocalizedHttpException;
10use MediaWiki\Rest\Response;
11use MediaWiki\Rest\Validator\Validator;
12use MediaWiki\User\CentralId\CentralIdLookup;
13use Psr\Log\LoggerInterface;
14use Wikimedia\ParamValidator\ParamValidator;
15use Wikimedia\Rdbms\LBFactory;
16
17/**
18 * Handle POST requests to /{module}/lists/batch
19 *
20 * Creates reading lists
21 */
22class ListsCreateBatchHandler extends Handler {
23    use ReadingListsHandlerTrait;
24    use ReadingListsTokenAwareHandlerTrait;
25
26    private LBFactory $dbProvider;
27
28    private Config $config;
29
30    private CentralIdLookup $centralIdLookup;
31
32    private LoggerInterface $logger;
33
34    /**
35     * @param LBFactory $dbProvider
36     * @param Config $config
37     * @param CentralIdLookup $centralIdLookup
38     */
39    public function __construct(
40        LBFactory $dbProvider,
41        Config $config,
42        CentralIdLookup $centralIdLookup
43    ) {
44        $this->dbProvider = $dbProvider;
45        $this->config = $config;
46        $this->centralIdLookup = $centralIdLookup;
47        $this->logger = LoggerFactory::getInstance( 'readinglists' );
48    }
49
50    /**
51     * Create the repository data access object instance.
52     *
53     * @return void
54     */
55    public function postInitSetup() {
56        $this->repository = $this->createRepository(
57            $this->getAuthority()->getUser(),
58            $this->dbProvider,
59            $this->config,
60            $this->centralIdLookup,
61            $this->logger
62        );
63    }
64
65    /**
66     * @inheritDoc
67     */
68    public function validate( Validator $restValidator ) {
69        try {
70            parent::validate( $restValidator );
71            $this->validateToken();
72        } catch ( LocalizedHttpException $e ) {
73            // Add fields expected by WMF mobile apps
74            $this->die( $e->getMessageValue(), [], $e->getCode(), $e->getErrorData() );
75        }
76    }
77
78    /**
79     * Disable extraneous body fields detection.
80     *
81     * @param Validator $restValidator
82     */
83    protected function detectExtraneousBodyFields( Validator $restValidator ) {
84        // No-op to disable extraneous body fields detection
85    }
86
87    /**
88     * @return array|Response
89     */
90    public function execute() {
91        $result = [];
92        $repository = $this->getRepository();
93        $this->checkAuthority( $this->getAuthority() );
94
95        $validatedBody = $this->getValidatedBody() ?? [];
96        $batch = $validatedBody['batch'];
97
98        $listData = $listIds = [];
99        foreach ( $this->getBatchOps( $batch ) as $op ) {
100            $description = $op['description'] ?? '';
101            $this->requireAtLeastOneBatchParameter( $op, 'name' );
102            try {
103                $list = $repository->addList( $op['name'], $description );
104            } catch ( ReadingListRepositoryException $e ) {
105                $this->die( $e->getMessageObject() );
106            }
107            $listIds[] = (object)[ 'id' => (int)$list->rl_id ];
108            $listData[] = $this->getListFromRow( $list );
109        }
110        $result['batch'] = $listIds;
111        $result['lists'] = $listData;
112
113        return $this->getResponseFactory()->createJson( $result );
114    }
115
116    /**
117     * @return array[]
118     */
119    public function getParamSettings(): array {
120        return $this->getReadingListsTokenParamDefinition();
121    }
122
123    /**
124     * @return array[]
125     */
126    public function getBodyParamSettings(): array {
127        return [
128            // TODO: consider additional validation on "batch", once we have that capability.
129            'batch' => [
130                self::PARAM_SOURCE => 'body',
131                ParamValidator::PARAM_TYPE => 'array',
132                ParamValidator::PARAM_REQUIRED => true,
133            ],
134        ] + $this->getTokenParamDefinition();
135    }
136}