Passed
Push — master ( d9b4e0...efcd2b )
by Daimona
01:45
created

SimpleUpdates::getGroupOutcomes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme\Task\Subtask;
4
5
use BotRiconferme\Message;
6
use BotRiconferme\Wiki\Element;
7
use BotRiconferme\Wiki\Page\PageBotList;
8
use BotRiconferme\Wiki\Page\PageRiconferma;
9
use BotRiconferme\TaskResult;
10
use BotRiconferme\Wiki\User;
11
12
/**
13
 * Update various pages around, to be done for all closed procedures
14
 */
15
class SimpleUpdates extends Subtask {
16
	/**
17
	 * @inheritDoc
18
	 */
19
	public function runInternal() : int {
20
		$pages = $this->getDataProvider()->getPagesToClose();
21
22
		if ( !$pages ) {
23
			return TaskResult::STATUS_NOTHING;
24
		}
25
26
		$this->updateVotazioni( $pages );
27
		$this->updateNews( $pages );
28
		$this->updateAdminList( $this->getGroupOutcomes( 'sysop', $pages ) );
29
		$checkUsers = $this->getGroupOutcomes( 'checkuser', $pages );
30
		if ( $checkUsers ) {
31
			$this->updateCUList( $checkUsers );
32
		}
33
34
		return TaskResult::STATUS_GOOD;
35
	}
36
37
	/**
38
	 * @param PageRiconferma[] $pages
39
	 * @see OpenUpdates::addToVotazioni()
40
	 */
41
	protected function updateVotazioni( array $pages ) {
42
		$this->getLogger()->info(
43
			'Updating votazioni: ' . implode( ', ', $pages )
44
		);
45
		$votePage = $this->getPage( $this->getOpt( 'vote-page-title' ) );
46
47
		$users = [];
48
		foreach ( $pages as $page ) {
49
			$users[] = $page->getUser();
50
		}
51
		$usersReg = Element::regexFromArray( $users );
52
53
		$search = "!^.+\{\{[^|}]*\/Riga\|[^|]*riconferma[^|]*\|utente=$usersReg\|.+\n!m";
54
55
		$newContent = preg_replace( $search, '', $votePage->getContent() );
56
57
		$summary = $this->msg( 'close-vote-page-summary' )
58
			->params( [ '$num' => count( $pages ) ] )->text();
59
60
		$votePage->edit( [
61
			'text' => $newContent,
62
			'summary' => $summary
63
		] );
64
	}
65
66
	/**
67
	 * @param array $pages
68
	 * @see OpenUpdates::addToNews()
69
	 */
70
	protected function updateNews( array $pages ) {
71
		$simpleAmount = $voteAmount = 0;
72
		foreach ( $pages as $page ) {
73
			if ( $page->isVote() ) {
74
				$voteAmount++;
75
			} else {
76
				$simpleAmount++;
77
			}
78
		}
79
80
		$this->getLogger()->info( "Updating news counter: -$simpleAmount simple, -$voteAmount votes." );
81
82
		$newsPage = $this->getPage( $this->getOpt( 'news-page-title' ) );
83
84
		$simpleReg = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d*)(?=\s*[}|])!';
85
		$voteReg = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d*)(?=\s*[}|])!';
86
87
		$simpleMatches = $newsPage->getMatch( $simpleReg );
88
		$voteMatches = $newsPage->getMatch( $voteReg );
89
90
		$newSimp = ( (int)$simpleMatches[2] - $simpleAmount ) ?: '';
91
		$newVote = ( (int)$voteMatches[2] - $voteAmount ) ?: '';
92
		$newContent = preg_replace( $simpleReg, '${1}' . $newSimp, $newsPage->getContent() );
93
		$newContent = preg_replace( $voteReg, '${1}' . $newVote, $newContent );
94
95
		$summary = $this->msg( 'close-news-page-summary' )
96
			->params( [ '$num' => count( $pages ) ] )->text();
97
98
		$newsPage->edit( [
99
			'text' => $newContent,
100
			'summary' => $summary
101
		] );
102
	}
103
104
	/**
105
	 * Update date on WP:Amministratori/Lista
106
	 *
107
	 * @param bool[] $outcomes
108
	 */
109
	protected function updateAdminList( array $outcomes ) {
110
		$this->getLogger()->info( 'Updating admin list' );
111
		$adminsPage = $this->getPage( $this->getOpt( 'admins-list-title' ) );
112
		$newContent = $adminsPage->getContent();
113
114
		$riconfNames = $removeNames = [];
115
		foreach ( $outcomes as $username => $confirmed ) {
116
			$user = $this->getUser( $username );
117
			$userReg = $user->getRegex();
118
			$reg = "!({{Ammini\w+\/riga\|$userReg\|\D+\|\d{8}\|)(?:\d{8})?\|\d{8}((?:\|[a-z]*)?}}.*\n)!";
119
			if ( $confirmed ) {
120
				$nextDate = date( 'Ymd', $this->getNextTs( $user ) );
121
				$newContent = preg_replace(
122
					$reg,
123
					'${1}{{subst:#timel:Ymd}}|' . $nextDate . '$2',
124
					$newContent
125
				);
126
				$riconfNames[] = $username;
127
			} else {
128
				$newContent = preg_replace( $reg, '', $newContent );
129
				$removeNames[] = $username;
130
			}
131
		}
132
133
		$summary = $this->msg( 'close-update-list-summary' )
134
			->params( [
135
				'$riconf' => Message::commaList( $riconfNames ),
136
				'$remove' => Message::commaList( $removeNames )
137
			] )
138
			->text();
139
140
		$adminsPage->edit( [
141
			'text' => $newContent,
142
			'summary' => $summary
143
		] );
144
	}
145
146
	/**
147
	 * Get the next valid timestamp for the given user
148
	 *
149
	 * @param User $user
150
	 * @return int
151
	 */
152
	private function getNextTs( User $user ) : int {
153
		$userInfo = $user->getUserInfo();
154
		if ( isset( $userInfo['override-perm'] ) ) {
155
			$date = \DateTime::createFromFormat(
156
				'd/m/Y',
157
				$userInfo['override-perm'] . '/' . date( 'Y' )
158
			);
159
		} else {
160
			$date = null;
161
			if ( isset( $userInfo['override'] ) ) {
162
				$date = \DateTime::createFromFormat( 'd/m/Y', $userInfo['override'] );
163
			}
164
			if ( !$date || $date <= new \DateTime ) {
165
				$ts = PageBotList::getValidFlagTimestamp( $userInfo );
166
				$date = ( new \DateTime )->setTimestamp( $ts );
167
			}
168
		}
169
		while ( $date <= new \DateTime ) {
170
			$date->modify( '+1 year' );
171
		}
172
		return $date->getTimestamp();
173
	}
174
175
	/**
176
	 * @param bool[] $outcomes
177
	 */
178
	protected function updateCUList( array $outcomes ) {
179
		$this->getLogger()->info( 'Updating CU list.' );
180
		$cuList = $this->getPage( $this->getOpt( 'cu-list-title' ) );
181
		$newContent = $cuList->getContent();
182
183
		$riconfNames = $removeNames = [];
184
		foreach ( $outcomes as $user => $confirmed ) {
185
			$userReg = $this->getUser( $user )->getRegex();
186
			$reg = "!(\{\{ *Checkuser *\| *$userReg *\|[^}]+\| *)[\w \d]+(}}.*\n)!";
187
			if ( $confirmed ) {
188
				$newContent = preg_replace( $reg, '${1}{{subst:#time:j F Y}}$2', $newContent );
189
				$riconfNames[] = $user;
190
			} else {
191
				$newContent = preg_replace( $reg, '', $newContent );
192
				$removeNames[] = $user;
193
			}
194
		}
195
196
		$summary = $this->msg( 'cu-list-update-summary' )
197
			->params( [
198
				'$riconf' => Message::commaList( $riconfNames ),
199
				'$remove' => Message::commaList( $removeNames )
200
			] )
201
			->text();
202
203
		$cuList->edit( [
204
			'text' => $newContent,
205
			'summary' => $summary
206
		] );
207
	}
208
209
	/**
210
	 * Given a user group and an array of PageRiconferma, get an array of users from $pages
211
	 * which are in the given groups and the outcome of the procedure (true = confirmed)
212
	 * @param string $group
213
	 * @param PageRiconferma[] $pages
214
	 * @return bool[]
215
	 */
216
	private function getGroupOutcomes( string $group, array $pages ) : array {
217
		$ret = [];
218
		foreach ( $pages as $page ) {
219
			$user = $page->getUser();
220
			if ( $user->inGroup( $group ) ) {
221
				$ret[ $user->getName() ] = !( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL );
222
			}
223
		}
224
		return $ret;
225
	}
226
}
227