Passed
Push — master ( aa5487...9959d3 )
by Daimona
01:41
created

ClosePages::addToArchive()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 0
loc 19
rs 9.8666
c 0
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme\Task;
4
5
use BotRiconferme\PageRiconferma;
6
use BotRiconferme\TaskResult;
7
8
/**
9
 * For each open page, close it if the time's up and no more than 15 opposing votes were added
10
 * @fixme Avoid duplication with UpdatesAround etc.
11
 */
12
class ClosePages extends Task {
13
	/**
14
	 * @inheritDoc
15
	 */
16
	public function run() : TaskResult {
17
		$this->getLogger()->info( 'Starting task ClosePages' );
18
19
		$pages = $this->getPagesList();
20
		$protectReason = $this->getConfig()->get( 'close-protect-summary' );
21
		foreach ( $pages as $page ) {
22
			if ( $page->isVote() ) {
23
				$this->addVoteCloseText( $page );
24
			}
25
			$this->getController()->protectPage( $page->getTitle(), $protectReason );
26
			$this->updateBasePage( $page );
27
		}
28
29
		$this->removeFromMainPage( $pages );
30
		$this->addToArchive( $pages );
31
		$this->updateVote( $pages );
32
		$this->updateNews( $pages );
33
		$this->updateAdminList( $pages );
34
		$this->updateCUList( $pages );
35
		$this->updateBurList( $pages );
36
37
		$this->getLogger()->info( 'Task ClosePages completed successfully' );
38
		return new TaskResult( self::STATUS_OK );
39
	}
40
41
	/**
42
	 * Get a list of pages to close
43
	 *
44
	 * @return PageRiconferma[]
45
	 */
46
	protected function getPagesList() : array {
47
		$allPages = $this->getDataProvider()->getOpenPages();
48
		$ret = [];
49
		foreach ( $allPages as $page ) {
50
			if ( time() > $page->getEndTimestamp() ) {
51
				$ret[] = $page;
52
			}
53
		}
54
		return $ret;
55
	}
56
57
	/**
58
	 * @param PageRiconferma $page
59
	 */
60
	protected function addVoteCloseText( PageRiconferma $page ) {
61
		$content = $page->getContent();
62
		$beforeReg = '!è necessario ottenere una maggioranza .+ votanti\.!';
63
		$newContent = preg_replace( $beforeReg, '$0' . "\n" . $page->getOutcomeText(), $content );
64
65
		$params = [
66
			'text' => $newContent,
67
			'summary' => $this->getConfig()->get( 'close-result-summary' )
68
		];
69
		$page->edit( $params );
70
	}
71
72
	/**
73
	 * Removes pages from WP:A/Riconferme annuali
74
	 *
75
	 * @param PageRiconferma[] $pages
76
	 * @see UpdatesAround::addToMainPage()
77
	 */
78
	protected function removeFromMainPage( array $pages ) {
79
		$this->getLogger()->info(
80
			'Removing from main: ' . implode( ', ', array_map( 'strval', $pages ) )
81
		);
82
83
		$mainPage = $this->getConfig()->get( 'ric-main-page' );
84
		$content = $this->getController()->getPageContent( $mainPage );
85
		$translations = [];
86
		foreach ( $pages as $page ) {
87
			$translations[ '{{' . $page->getTitle() . '}}' ] = '';
88
		}
89
90
		$params = [
91
			'title' => $mainPage,
92
			'text' => strtr( $content, $translations ),
93
			'summary' => $this->getConfig()->get( 'close-main-summary' )
94
		];
95
		$this->getController()->editPage( $params );
96
	}
97
98
	/**
99
	 * Adds closed pages to the current archive
100
	 *
101
	 * @param PageRiconferma[] $pages
102
	 */
103
	protected function addToArchive( array $pages ) {
104
		$this->getLogger()->info(
105
			'Adding to archive: ' . implode( ', ', array_map( 'strval', $pages ) )
106
		);
107
108
		$simple = $votes = [];
109
		foreach ( $pages as $page ) {
110
			if ( $page->isVote() ) {
111
				$votes[] = $page;
112
			} else {
113
				$simple[] = $page;
114
			}
115
		}
116
117
		$simpleTitle = $this->getConfig()->get( 'close-simple-archive-title' );
118
		$voteTitle = $this->getConfig()->get( 'close-vote-archive-title' );
119
120
		$this->reallyAddToArchive( $simpleTitle, $simple );
121
		$this->reallyAddToArchive( $voteTitle, $votes );
122
	}
123
124
	/**
125
	 * Really add $pages to the given archive
126
	 *
127
	 * @param string $archiveTitle
128
	 * @param array $pages
129
	 */
130
	private function reallyAddToArchive( string $archiveTitle, array $pages ) {
131
		$curTitle = "$archiveTitle/" . date( 'Y' );
132
133
		$append = '';
134
		$archivedList = [];
135
		foreach ( $pages as $page ) {
136
			$append .= '{{' . $page->getTitle() . "}}\n";
137
			$archivedList[] = $page->getUserNum();
138
		}
139
140
		if ( count( $archivedList ) > 1 ) {
141
			$last = array_pop( $archivedList );
142
			$userNums = implode( ', ', $archivedList ) . " e $last";
143
		} else {
144
			$userNums = $archivedList[0];
145
		}
146
147
		$summary = strtr(
148
			$this->getConfig()->get( 'close-archive-summary' ),
149
			[ '$usernums' => $userNums ]
150
		);
151
152
		$params = [
153
			'title' => $curTitle,
154
			'appendtext' => $append,
155
			'summary' => $summary
156
		];
157
158
		$this->getController()->editPage( $params );
159
	}
160
161
	/**
162
	 * @param PageRiconferma $page
163
	 * @see CreatePages::updateBasePage()
164
	 */
165
	protected function updateBasePage( PageRiconferma $page ) {
166
		$this->getLogger()->info( "Updating base page for $page" );
167
168
		$current = $this->getController()->getPageContent( $page->getBaseTitle() );
169
170
		$outcomeText = $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ?
171
			'non riconfermato' :
172
			'riconfermato';
173
		$text = $page->isVote() ? "votazione: $outcomeText" : 'riconferma tacita';
174
175
		$newContent = str_replace( 'riconferma in corso', $text, $current );
176
		$params = [
177
			'title' => $page->getTitle(),
178
			'text' => $newContent,
179
			'summary' => $this->getConfig()->get( 'close-base-page-summary-update' )
180
		];
181
182
		$this->getController()->editPage( $params );
183
	}
184
185
	/**
186
	 * @param PageRiconferma[] $pages
187
	 * @see UpdatesAround::addVote()
188
	 */
189
	protected function updateVote( array $pages ) {
190
		$votePage = $this->getConfig()->get( 'ric-vote-page' );
191
		$content = $this->getController()->getPageContent( $votePage );
192
193
		$titles = [];
194
		foreach ( $pages as $page ) {
195
			$titles[] = preg_quote( $page->getTitle() );
196
		}
197
198
		$titleReg = implode( '|', array_map( 'preg_quote', $titles ) );
199
		$search = "!^\*.+ La \[\[($titleReg)\|procedura]] termina.+\n!gm";
200
201
		$newContent = preg_replace( $search, '', $content );
202
		// Make sure the last line ends with a full stop in every section
203
		$simpleSectReg = '!(^;È in corso.+riconferma tacita.+amministrat.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
204
		$voteSectReg = '!(^;Si vota per la .+riconferma .+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
205
		$newContent = preg_replace( $simpleSectReg, '$1.', $newContent );
206
		$newContent = preg_replace( $voteSectReg, '$1.', $newContent );
207
208
		// @fixme Remove empty sections, and add the "''Nessuna riconferma o votazione in corso''" message
209
		// if the page is empty! Or just wait for the page to be restyled...
210
211
		$summary = strtr(
212
			$this->getConfig()->get( 'close-vote-page-summary' ),
213
			[ '$num' => count( $pages ) ]
214
		);
215
		$summary = preg_replace_callback(
216
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
217
			function ( $matches ) {
218
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
219
			},
220
			$summary
221
		);
222
223
		$params = [
224
			'title' => $votePage,
225
			'text' => $newContent,
226
			'summary' => $summary
227
		];
228
229
		$this->getController()->editPage( $params );
230
	}
231
232
	/**
233
	 * @param array $pages
234
	 * @see UpdatesAround::addNews()
235
	 */
236
	protected function updateNews( array $pages ) {
237
		$simpleAmount = $voteAmount = 0;
238
		foreach ( $pages as $page ) {
239
			if ( $page->isVote() ) {
240
				$voteAmount++;
241
			} else {
242
				$simpleAmount++;
243
			}
244
		}
245
246
		$this->getLogger()->info(
247
			"Decreasing the news counter: $simpleAmount simple, $voteAmount votes."
248
		);
249
250
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
251
252
		$content = $this->getController()->getPageContent( $newsPage );
253
		$simpleReg = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
254
		$voteReg = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
255
256
		$simpleMatches = $voteMatches = [];
257
		preg_match( $simpleReg, $content, $simpleMatches );
258
		preg_match( $voteReg, $content, $voteMatches );
259
260
		$newSimp = (int)$simpleMatches[2] - $simpleAmount ?: '';
261
		$newVote = (int)$voteMatches[2] - $voteAmount ?: '';
262
		$newContent = preg_replace( $simpleReg, '${1}' . $newSimp, $content );
263
		$newContent = preg_replace( $voteReg, '${1}' . $newVote, $newContent );
264
265
		$summary = strtr(
266
			$this->getConfig()->get( 'close-news-page-summary' ),
267
			[ '$num' => count( $pages ) ]
268
		);
269
		$summary = preg_replace_callback(
270
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
271
			function ( $matches ) {
272
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
273
			},
274
			$summary
275
		);
276
277
		$params = [
278
			'title' => $newsPage,
279
			'text' => $newContent,
280
			'summary' => $summary
281
		];
282
283
		$this->getController()->editPage( $params );
284
	}
285
286
	/**
287
	 * Update date on WP:Amministratori/Lista
288
	 *
289
	 * @param PageRiconferma[] $pages
290
	 */
291
	protected function updateAdminList( array $pages ) {
292
		$listTitle = $this->getConfig()->get( 'admins-list' );
293
		$newContent = $this->getController()->getPageContent( $listTitle );
294
		$newDate = date( 'Ymd', strtotime( '+1 year' ) );
295
296
		$riconfNames = $removeNames = [];
297
		foreach ( $pages as $page ) {
298
			$user = $page->getUser();
299
			$reg = "!(\{\{Amministratore\/riga\|$user.+\| *)\d+( *\|(?: *pausa)? *\}\}\n)!";
300
			if ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ) {
301
				// Remove the line
302
				$newContent = preg_replace( $reg, '', $newContent );
303
				$removeNames[] = $user;
304
			} else {
305
				$newContent = preg_replace( $reg, '$1' . $newDate . '$2', $newContent );
306
				$riconfNames[] = $user;
307
			}
308
		}
309
310
		if ( count( $riconfNames ) > 1 ) {
311
			$lastUser = array_pop( $riconfNames );
312
			$riconfList = implode( ', ', $riconfNames ) . " e $lastUser";
313
		} elseif ( $riconfNames ) {
314
			$riconfList = $riconfNames[0];
315
		} else {
316
			$riconfList = 'nessuno';
317
		}
318
319
		if ( count( $removeNames ) > 1 ) {
320
			$lastUser = array_pop( $removeNames );
321
			$removeList = implode( ', ', $removeNames ) . " e $lastUser";
322
		} elseif ( $removeNames ) {
323
			$removeList = $removeNames[0];
324
		} else {
325
			$removeList = 'nessuno';
326
		}
327
328
		$summary = strtr(
329
			$this->getConfig()->get( 'close-update-list-summary' ),
330
			[
331
				'$riconf' => $riconfList,
332
				'$remove' => $removeList
333
			]
334
		);
335
336
		$params = [
337
			'title' => $listTitle,
338
			'text' => $newContent,
339
			'summary' => $summary
340
		];
341
342
		$this->getController()->editPage( $params );
343
	}
344
345
	/**
346
	 * @param PageRiconferma[] $pages
347
	 */
348
	protected function updateCUList( array $pages ) {
349
		$cuListTitle = $this->getConfig()->get( 'cu-list-title' );
350
		$listTitle = $this->getConfig()->get( 'list-title' );
351
		$admins = json_decode( $this->getController()->getPageContent( $listTitle ), true );
352
		$newContent = $this->getController()->getPageContent( $cuListTitle );
353
354
		$riconfNames = $removeNames = [];
355
		foreach ( $pages as $page ) {
356
			$user = $page->getUser();
357
			if ( array_key_exists( 'checkuser', $admins[ $user ] ) ) {
358
				$reg = "!(\{\{ *Checkuser *\| *$user *\|[^}]+\| *)[\w \d](}}.*\n)!";
359
				if ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ) {
360
					// Remove the line
361
					$newContent = preg_replace( $reg, '', $newContent );
362
					$removeNames[] = $user;
363
				} else {
364
					$newContent = preg_replace( $reg, '$1{{subst:#time:j F Y}}$2', $newContent );
365
					$riconfNames[] = $user;
366
				}
367
			}
368
		}
369
370
		if ( !$riconfNames && !$removeNames ) {
0 ignored issues
show
introduced by
$riconfNames is of type array|string[], thus it always evaluated to false.
Loading history...
371
			return;
372
		}
373
374
		if ( count( $riconfNames ) > 1 ) {
375
			$lastUser = array_pop( $riconfNames );
376
			$riconfList = implode( ', ', $riconfNames ) . " e $lastUser";
377
		} elseif ( $riconfNames ) {
378
			$riconfList = $riconfNames[0];
379
		} else {
380
			$riconfList = 'nessuno';
381
		}
382
383
		if ( count( $removeNames ) > 1 ) {
384
			$lastUser = array_pop( $removeNames );
385
			$removeList = implode( ', ', $removeNames ) . " e $lastUser";
386
		} elseif ( $removeNames ) {
387
			$removeList = $removeNames[0];
388
		} else {
389
			$removeList = 'nessuno';
390
		}
391
392
		$summary = strtr(
393
			$this->getConfig()->get( 'cu-list-update-summary' ),
394
			[
395
				'$riconf' => $riconfList,
396
				'$remove' => $removeList
397
			]
398
		);
399
400
		$params = [
401
			'title' => $cuListTitle,
402
			'text' => $newContent,
403
			'summary' => $summary
404
		];
405
		$this->getController()->editPage( $params );
406
	}
407
408
	/**
409
	 * @param PageRiconferma[] $pages
410
	 */
411
	protected function updateBurList( array $pages ) {
412
		$listTitle = $this->getConfig()->get( 'list-title' );
413
		$admins = json_decode( $this->getController()->getPageContent( $listTitle ), true );
414
415
		$remove = [];
416
		foreach ( $pages as $page ) {
417
			$user = $page->getUser();
418
			if ( array_key_exists( 'bureaucrat', $admins[ $user ] ) &&
419
				$page->getOutcome() & PageRiconferma::OUTCOME_FAIL
420
			) {
421
				$remove[] = $user;
422
			}
423
		}
424
425
		if ( !$remove ) {
426
			return;
427
		}
428
429
		$remList = implode( '|', array_map( 'preg_quote', $remove ) );
430
		$burListTitle = $this->getConfig()->get( 'bur-list-title' );
431
		$content = $this->getController()->getPageContent( $burListTitle );
432
		$reg = "!^\#\{\{ *Burocrate *\| *($remList).+\n!m";
433
		$newContent = preg_replace( $reg, '', $content );
434
435
		if ( count( $remove ) > 1 ) {
436
			$lastUser = array_pop( $remove );
437
			$removeList = implode( ', ', $remove ) . " e $lastUser";
438
		} else {
439
			$removeList = $remove[0];
440
		}
441
442
		$summary = strtr(
443
			$this->getConfig()->get( 'bur-list-update-summary' ),
444
			[
445
				'$remove' => $removeList
446
			]
447
		);
448
449
		$params = [
450
			'title' => $burListTitle,
451
			'text' => $newContent,
452
			'summary' => $summary
453
		];
454
		$this->getController()->editPage( $params );
455
	}
456
}
457