aboutsummaryrefslogtreecommitdiffstats
path: root/includes/api/ApiQueryBlockInfoTrait.php
blob: 75a85ac436ce287aad15720663d8dbac5c702ff8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
/**
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 */

namespace MediaWiki\Api;

use MediaWiki\Block\CompositeBlock;
use MediaWiki\Block\HideUserUtils;
use MediaWiki\MediaWikiServices;
use MediaWiki\Permissions\Authority;
use stdClass;
use Wikimedia\Rdbms\IExpression;
use Wikimedia\Rdbms\IReadableDatabase;
use Wikimedia\Rdbms\IResultWrapper;
use Wikimedia\Rdbms\SelectQueryBuilder;

/**
 * @ingroup API
 */
trait ApiQueryBlockInfoTrait {
	use ApiBlockInfoTrait;

	/**
	 * Filter hidden users if the current user does not have the ability to
	 * view them. Also add a field hu_deleted which will be true if the user
	 * is hidden.
	 *
	 * @since 1.42
	 */
	private function addDeletedUserFilter() {
		// TODO: inject dependencies the way ApiWatchlistTrait does
		$utils = MediaWikiServices::getInstance()->getHideUserUtils();
		if ( !$this->getAuthority()->isAllowed( 'hideuser' ) ) {
			$this->addWhere( $utils->getExpression( $this->getDB() ) );
			// The field is always false since we are filtering out rows where it is true
			$this->addFields( [ 'hu_deleted' => '1=0' ] );
		} else {
			$this->addFields( [
				'hu_deleted' => $utils->getExpression(
					$this->getDB(),
					'user_id',
					HideUserUtils::HIDDEN_USERS
				)
			] );
		}
	}

	/**
	 * For a set of rows with a user_id field, get the block details for all
	 * users, and return them in array, formatted using
	 * ApiBlockInfoTrait::getBlockDetails().
	 *
	 * @since 1.42
	 * @param iterable<stdClass>|IResultWrapper $rows Rows with a user_id field
	 * @return array The block details indexed by user_id. If a user is not blocked,
	 *   the key will be absent.
	 */
	private function getBlockDetailsForRows( $rows ) {
		$ids = [];
		foreach ( $rows as $row ) {
			$ids[] = (int)$row->user_id;
		}
		if ( !$ids ) {
			return [];
		}
		$blocks = MediaWikiServices::getInstance()->getDatabaseBlockStore()
			->newListFromConds( [ 'bt_user' => $ids ] );
		$blocksByUser = [];
		foreach ( $blocks as $block ) {
			$blocksByUser[$block->getTargetUserIdentity()->getId()][] = $block;
		}
		$infoByUser = [];
		foreach ( $blocksByUser as $id => $userBlocks ) {
			if ( count( $userBlocks ) > 1 ) {
				$maybeCompositeBlock = CompositeBlock::createFromBlocks( ...$userBlocks );
			} else {
				$maybeCompositeBlock = $userBlocks[0];
			}
			$infoByUser[$id] = $this->getBlockDetails( $maybeCompositeBlock );
		}
		return $infoByUser;
	}

	/***************************************************************************/
	// region   Methods required from ApiQueryBase
	/** @name   Methods required from ApiQueryBase */

	/**
	 * @see ApiBase::getDB
	 * @return IReadableDatabase
	 */
	abstract protected function getDB();

	/**
	 * @see IContextSource::getAuthority
	 * @return Authority
	 */
	abstract public function getAuthority();

	/**
	 * @see ApiQueryBase::addTables
	 * @param string|array $tables
	 * @param string|null $alias
	 */
	abstract protected function addTables( $tables, $alias = null );

	/**
	 * @see ApiQueryBase::addFields
	 * @param array|string $fields
	 */
	abstract protected function addFields( $fields );

	/**
	 * @see ApiQueryBase::addWhere
	 * @param string|array|IExpression $conds
	 */
	abstract protected function addWhere( $conds );

	/**
	 * @see ApiQueryBase::addJoinConds
	 * @param array $conds
	 */
	abstract protected function addJoinConds( $conds );

	/**
	 * @return SelectQueryBuilder
	 */
	abstract protected function getQueryBuilder();

	// endregion -- end of methods required from ApiQueryBase

}

/** @deprecated class alias since 1.43 */
class_alias( ApiQueryBlockInfoTrait::class, 'ApiQueryBlockInfoTrait' );