Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.66% covered (warning)
89.66%
26 / 29
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryBlockInfoTrait
92.86% covered (success)
92.86%
26 / 28
50.00% covered (danger)
50.00%
1 / 2
8.02
0.00% covered (danger)
0.00%
0 / 1
 addDeletedUserFilter
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
 getBlockDetailsForRows
88.24% covered (warning)
88.24%
15 / 17
0.00% covered (danger)
0.00%
0 / 1
6.06
 getDB
n/a
0 / 0
n/a
0 / 0
0
 getAuthority
n/a
0 / 0
n/a
0 / 0
0
 addTables
n/a
0 / 0
n/a
0 / 0
0
 addFields
n/a
0 / 0
n/a
0 / 0
0
 addWhere
n/a
0 / 0
n/a
0 / 0
0
 addJoinConds
n/a
0 / 0
n/a
0 / 0
0
 getQueryBuilder
n/a
0 / 0
n/a
0 / 0
0
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\Api;
22
23use MediaWiki\Block\CompositeBlock;
24use MediaWiki\Block\HideUserUtils;
25use MediaWiki\MediaWikiServices;
26use MediaWiki\Permissions\Authority;
27use stdClass;
28use Wikimedia\Rdbms\IExpression;
29use Wikimedia\Rdbms\IReadableDatabase;
30use Wikimedia\Rdbms\IResultWrapper;
31use Wikimedia\Rdbms\SelectQueryBuilder;
32
33/**
34 * @ingroup API
35 */
36trait ApiQueryBlockInfoTrait {
37    use ApiBlockInfoTrait;
38
39    /**
40     * Filter hidden users if the current user does not have the ability to
41     * view them. Also add a field hu_deleted which will be true if the user
42     * is hidden.
43     *
44     * @since 1.42
45     */
46    private function addDeletedUserFilter() {
47        // TODO: inject dependencies the way ApiWatchlistTrait does
48        $utils = MediaWikiServices::getInstance()->getHideUserUtils();
49        if ( !$this->getAuthority()->isAllowed( 'hideuser' ) ) {
50            $this->addWhere( $utils->getExpression( $this->getDB() ) );
51            // The field is always false since we are filtering out rows where it is true
52            $this->addFields( [ 'hu_deleted' => '1=0' ] );
53        } else {
54            $this->addFields( [
55                'hu_deleted' => $utils->getExpression(
56                    $this->getDB(),
57                    'user_id',
58                    HideUserUtils::HIDDEN_USERS
59                )
60            ] );
61        }
62    }
63
64    /**
65     * For a set of rows with a user_id field, get the block details for all
66     * users, and return them in array, formatted using
67     * ApiBlockInfoTrait::getBlockDetails().
68     *
69     * @since 1.42
70     * @param iterable<stdClass>|IResultWrapper $rows Rows with a user_id field
71     * @return array The block details indexed by user_id. If a user is not blocked,
72     *   the key will be absent.
73     */
74    private function getBlockDetailsForRows( $rows ) {
75        $ids = [];
76        foreach ( $rows as $row ) {
77            $ids[] = (int)$row->user_id;
78        }
79        if ( !$ids ) {
80            return [];
81        }
82        $blocks = MediaWikiServices::getInstance()->getDatabaseBlockStore()
83            ->newListFromConds( [ 'bt_user' => $ids ] );
84        $blocksByUser = [];
85        foreach ( $blocks as $block ) {
86            $blocksByUser[$block->getTargetUserIdentity()->getId()][] = $block;
87        }
88        $infoByUser = [];
89        foreach ( $blocksByUser as $id => $userBlocks ) {
90            if ( count( $userBlocks ) > 1 ) {
91                $maybeCompositeBlock = CompositeBlock::createFromBlocks( ...$userBlocks );
92            } else {
93                $maybeCompositeBlock = $userBlocks[0];
94            }
95            $infoByUser[$id] = $this->getBlockDetails( $maybeCompositeBlock );
96        }
97        return $infoByUser;
98    }
99
100    /***************************************************************************/
101    // region   Methods required from ApiQueryBase
102    /** @name   Methods required from ApiQueryBase */
103
104    /**
105     * @see ApiBase::getDB
106     * @return IReadableDatabase
107     */
108    abstract protected function getDB();
109
110    /**
111     * @see IContextSource::getAuthority
112     * @return Authority
113     */
114    abstract public function getAuthority();
115
116    /**
117     * @see ApiQueryBase::addTables
118     * @param string|array $tables
119     * @param string|null $alias
120     */
121    abstract protected function addTables( $tables, $alias = null );
122
123    /**
124     * @see ApiQueryBase::addFields
125     * @param array|string $fields
126     */
127    abstract protected function addFields( $fields );
128
129    /**
130     * @see ApiQueryBase::addWhere
131     * @param string|array|IExpression $conds
132     */
133    abstract protected function addWhere( $conds );
134
135    /**
136     * @see ApiQueryBase::addJoinConds
137     * @param array $conds
138     */
139    abstract protected function addJoinConds( $conds );
140
141    /**
142     * @return SelectQueryBuilder
143     */
144    abstract protected function getQueryBuilder();
145
146    // endregion -- end of methods required from ApiQueryBase
147
148}
149
150/** @deprecated class alias since 1.43 */
151class_alias( ApiQueryBlockInfoTrait::class, 'ApiQueryBlockInfoTrait' );