Passed
Push — master ( 1e692f...8cd4b0 )
by Daimona
05:11
created

SimpleUpdates::getNextTs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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