Passed
Push — master ( 98e5c5...7ca7e9 )
by Daimona
01:28
created

ClosePages::updateCUList()   B

Complexity

Conditions 10
Paths 40

Size

Total Lines 62
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 45
nc 40
nop 1
dl 0
loc 62
rs 7.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme\Task;
4
5
use BotRiconferme\PageRiconferma;
6
use BotRiconferme\Request\RequestBase;
7
use BotRiconferme\TaskResult;
8
9
/**
10
 * For each open page, close it if the time's up and no more than 15 opposing votes were added
11
 * @fixme Avoid duplication with UpdatesAround etc.
12
 */
13
class ClosePages extends Task {
14
	/**
15
	 * @inheritDoc
16
	 */
17
	public function run() : TaskResult {
18
		$this->getLogger()->info( 'Starting task ClosePages' );
19
20
		$pages = $this->getPagesList();
21
		$protectReason = $this->getConfig()->get( 'close-protect-summary' );
22
		foreach ( $pages as $page ) {
23
			if ( $page->isVote() ) {
24
				$this->addVoteCloseText( $page );
25
			}
26
			$this->getController()->protectPage( $page->getTitle(), $protectReason );
27
			$this->updateBasePage( $page );
28
		}
29
30
		$this->removeFromMainPage( $pages );
31
		$this->addToArchive( $pages );
32
		$this->updateVote( $pages );
33
		$this->updateNews( $pages );
34
		$this->updateAdminList( $pages );
35
		$this->updateCUList( $pages );
36
37
		$failed = $this->getFailures( $pages );
38
		if ( $failed ) {
39
			$this->updateBurList( $failed );
40
			$this->requestRemoval( $failed );
41
			$this->updateAnnunci( $failed );
42
			$this->updateUltimeNotizie( $failed );
43
		}
44
45
		$this->getLogger()->info( 'Task ClosePages completed successfully' );
46
		return new TaskResult( self::STATUS_OK );
47
	}
48
49
	/**
50
	 * Get a list of pages to close
51
	 *
52
	 * @return PageRiconferma[]
53
	 */
54
	protected function getPagesList() : array {
55
		$allPages = $this->getDataProvider()->getOpenPages();
56
		$ret = [];
57
		foreach ( $allPages as $page ) {
58
			if ( time() > $page->getEndTimestamp() ) {
59
				$ret[] = $page;
60
			}
61
		}
62
		return $ret;
63
	}
64
65
	/**
66
	 * Extract the list of failed votes from the given list of pages
67
	 *
68
	 * @param PageRiconferma[] $pages
69
	 * @return PageRiconferma[]
70
	 */
71
	private function getFailures( array $pages ) : array {
72
		$ret = [];
73
		foreach ( $pages as $page ) {
74
			if ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ) {
75
				$ret[] = $page;
76
			}
77
		}
78
		return $ret;
79
	}
80
81
	/**
82
	 * @param PageRiconferma $page
83
	 */
84
	protected function addVoteCloseText( PageRiconferma $page ) {
85
		$content = $page->getContent();
86
		$beforeReg = '!è necessario ottenere una maggioranza .+ votanti\.!';
87
		$newContent = preg_replace( $beforeReg, '$0' . "\n" . $page->getOutcomeText(), $content );
88
89
		$params = [
90
			'text' => $newContent,
91
			'summary' => $this->getConfig()->get( 'close-result-summary' )
92
		];
93
		$page->edit( $params );
94
	}
95
96
	/**
97
	 * Removes pages from WP:A/Riconferme annuali
98
	 *
99
	 * @param PageRiconferma[] $pages
100
	 * @see UpdatesAround::addToMainPage()
101
	 */
102
	protected function removeFromMainPage( array $pages ) {
103
		$this->getLogger()->info(
104
			'Removing from main: ' . implode( ', ', array_map( 'strval', $pages ) )
105
		);
106
107
		$mainPage = $this->getConfig()->get( 'ric-main-page' );
108
		$content = $this->getController()->getPageContent( $mainPage );
109
		$translations = [];
110
		foreach ( $pages as $page ) {
111
			$translations[ '{{' . $page->getTitle() . '}}' ] = '';
112
		}
113
114
		$params = [
115
			'title' => $mainPage,
116
			'text' => strtr( $content, $translations ),
117
			'summary' => $this->getConfig()->get( 'close-main-summary' )
118
		];
119
		$this->getController()->editPage( $params );
120
	}
121
122
	/**
123
	 * Adds closed pages to the current archive
124
	 *
125
	 * @param PageRiconferma[] $pages
126
	 */
127
	protected function addToArchive( array $pages ) {
128
		$this->getLogger()->info(
129
			'Adding to archive: ' . implode( ', ', array_map( 'strval', $pages ) )
130
		);
131
132
		$simple = $votes = [];
133
		foreach ( $pages as $page ) {
134
			if ( $page->isVote() ) {
135
				$votes[] = $page;
136
			} else {
137
				$simple[] = $page;
138
			}
139
		}
140
141
		$simpleTitle = $this->getConfig()->get( 'close-simple-archive-title' );
142
		$voteTitle = $this->getConfig()->get( 'close-vote-archive-title' );
143
144
		$this->reallyAddToArchive( $simpleTitle, $simple );
145
		$this->reallyAddToArchive( $voteTitle, $votes );
146
	}
147
148
	/**
149
	 * Really add $pages to the given archive
150
	 *
151
	 * @param string $archiveTitle
152
	 * @param array $pages
153
	 */
154
	private function reallyAddToArchive( string $archiveTitle, array $pages ) {
155
		$curTitle = "$archiveTitle/" . date( 'Y' );
156
157
		$append = '';
158
		$archivedList = [];
159
		foreach ( $pages as $page ) {
160
			$append .= '{{' . $page->getTitle() . "}}\n";
161
			$archivedList[] = $page->getUserNum();
162
		}
163
164
		if ( count( $archivedList ) > 1 ) {
165
			$last = array_pop( $archivedList );
166
			$userNums = implode( ', ', $archivedList ) . " e $last";
167
		} else {
168
			$userNums = $archivedList[0];
169
		}
170
171
		$summary = $this->msg( 'close-archive-summary' )
172
			->params( [ '$usernums' => $userNums ] )->text();
173
174
		$params = [
175
			'title' => $curTitle,
176
			'appendtext' => $append,
177
			'summary' => $summary
178
		];
179
180
		$this->getController()->editPage( $params );
181
	}
182
183
	/**
184
	 * @param PageRiconferma $page
185
	 * @see CreatePages::updateBasePage()
186
	 */
187
	protected function updateBasePage( PageRiconferma $page ) {
188
		$this->getLogger()->info( "Updating base page for $page" );
189
190
		$current = $this->getController()->getPageContent( $page->getBaseTitle() );
191
192
		$outcomeText = $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ?
193
			'non riconfermato' :
194
			'riconfermato';
195
		$text = $page->isVote() ? "votazione: $outcomeText" : 'riconferma tacita';
196
197
		$newContent = str_replace( 'riconferma in corso', $text, $current );
198
		$params = [
199
			'title' => $page->getTitle(),
200
			'text' => $newContent,
201
			'summary' => $this->getConfig()->get( 'close-base-page-summary-update' )
202
		];
203
204
		$this->getController()->editPage( $params );
205
	}
206
207
	/**
208
	 * @param PageRiconferma[] $pages
209
	 * @see UpdatesAround::addVote()
210
	 */
211
	protected function updateVote( array $pages ) {
212
		$this->getLogger()->info(
213
			'Updating votazioni: ' . implode( ', ', array_map( 'strval', $pages ) )
214
		);
215
		$votePage = $this->getConfig()->get( 'ric-vote-page' );
216
		$content = $this->getController()->getPageContent( $votePage );
217
218
		$titles = [];
219
		foreach ( $pages as $page ) {
220
			$titles[] = preg_quote( $page->getTitle() );
221
		}
222
223
		$titleReg = implode( '|', array_map( 'preg_quote', $titles ) );
224
		$search = "!^\*.+ La \[\[($titleReg)\|procedura]] termina.+\n!gm";
225
226
		$newContent = preg_replace( $search, '', $content );
227
		// Make sure the last line ends with a full stop in every section
228
		$simpleSectReg = '!(^;È in corso.+riconferma tacita.+amministrat.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
229
		$voteSectReg = '!(^;Si vota per la .+riconferma .+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
230
		$newContent = preg_replace( $simpleSectReg, '$1.', $newContent );
231
		$newContent = preg_replace( $voteSectReg, '$1.', $newContent );
232
233
		// @fixme Remove empty sections, and add the "''Nessuna riconferma o votazione in corso''" message
234
		// if the page is empty! Or just wait for the page to be restyled...
235
236
		$summary = $this->msg( 'close-vote-page-summary' )
237
			->params( [ '$num' => count( $pages ) ] )->text();
238
239
		$params = [
240
			'title' => $votePage,
241
			'text' => $newContent,
242
			'summary' => $summary
243
		];
244
245
		$this->getController()->editPage( $params );
246
	}
247
248
	/**
249
	 * @param array $pages
250
	 * @see UpdatesAround::addNews()
251
	 */
252
	protected function updateNews( array $pages ) {
253
		$simpleAmount = $voteAmount = 0;
254
		foreach ( $pages as $page ) {
255
			if ( $page->isVote() ) {
256
				$voteAmount++;
257
			} else {
258
				$simpleAmount++;
259
			}
260
		}
261
262
		$this->getLogger()->info(
263
			"Decreasing the news counter: $simpleAmount simple, $voteAmount votes."
264
		);
265
266
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
267
268
		$content = $this->getController()->getPageContent( $newsPage );
269
		$simpleReg = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
270
		$voteReg = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
271
272
		$simpleMatches = $voteMatches = [];
273
		preg_match( $simpleReg, $content, $simpleMatches );
274
		preg_match( $voteReg, $content, $voteMatches );
275
276
		$newSimp = (int)$simpleMatches[2] - $simpleAmount ?: '';
277
		$newVote = (int)$voteMatches[2] - $voteAmount ?: '';
278
		$newContent = preg_replace( $simpleReg, '${1}' . $newSimp, $content );
279
		$newContent = preg_replace( $voteReg, '${1}' . $newVote, $newContent );
280
281
		$summary = $this->msg( 'close-news-page-summary' )
282
			->params( [ '$num' => count( $pages ) ] )->text();
283
284
		$params = [
285
			'title' => $newsPage,
286
			'text' => $newContent,
287
			'summary' => $summary
288
		];
289
290
		$this->getController()->editPage( $params );
291
	}
292
293
	/**
294
	 * Update date on WP:Amministratori/Lista
295
	 *
296
	 * @param PageRiconferma[] $pages
297
	 */
298
	protected function updateAdminList( array $pages ) {
299
		$this->getLogger()->info(
300
			'Updating admin list: ' . implode( ', ', array_map( 'strval', $pages ) )
301
		);
302
		$listTitle = $this->getConfig()->get( 'admins-list' );
303
		$newContent = $this->getController()->getPageContent( $listTitle );
304
		$newDate = date( 'Ymd', strtotime( '+1 year' ) );
305
306
		$riconfNames = $removeNames = [];
307
		foreach ( $pages as $page ) {
308
			$user = $page->getUser();
309
			$reg = "!(\{\{Amministratore\/riga\|$user.+\| *)\d+( *\|(?: *pausa)? *\}\}\n)!";
310
			if ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ) {
311
				// Remove the line
312
				$newContent = preg_replace( $reg, '', $newContent );
313
				$removeNames[] = $user;
314
			} else {
315
				$newContent = preg_replace( $reg, '$1' . $newDate . '$2', $newContent );
316
				$riconfNames[] = $user;
317
			}
318
		}
319
320
		if ( count( $riconfNames ) > 1 ) {
321
			$lastUser = array_pop( $riconfNames );
322
			$riconfList = implode( ', ', $riconfNames ) . " e $lastUser";
323
		} elseif ( $riconfNames ) {
324
			$riconfList = $riconfNames[0];
325
		} else {
326
			$riconfList = 'nessuno';
327
		}
328
329
		if ( count( $removeNames ) > 1 ) {
330
			$lastUser = array_pop( $removeNames );
331
			$removeList = implode( ', ', $removeNames ) . " e $lastUser";
332
		} elseif ( $removeNames ) {
333
			$removeList = $removeNames[0];
334
		} else {
335
			$removeList = 'nessuno';
336
		}
337
338
		$summary = $this->msg( 'close-update-list-summary' )
339
			->params( [
340
				'$riconf' => $riconfList,
341
				'$remove' => $removeList
342
			] )
343
			->text();
344
345
		$params = [
346
			'title' => $listTitle,
347
			'text' => $newContent,
348
			'summary' => $summary
349
		];
350
351
		$this->getController()->editPage( $params );
352
	}
353
354
	/**
355
	 * @param PageRiconferma[] $pages
356
	 */
357
	protected function updateCUList( array $pages ) {
358
		$this->getLogger()->info( 'Checking if CU list needs updating.' );
359
		$cuListTitle = $this->getConfig()->get( 'cu-list-title' );
360
		$listTitle = $this->getConfig()->get( 'list-title' );
361
		$admins = json_decode( $this->getController()->getPageContent( $listTitle ), true );
362
		$newContent = $this->getController()->getPageContent( $cuListTitle );
363
364
		$riconfNames = $removeNames = [];
365
		foreach ( $pages as $page ) {
366
			$user = $page->getUser();
367
			if ( array_key_exists( 'checkuser', $admins[ $user ] ) ) {
368
				$reg = "!(\{\{ *Checkuser *\| *$user *\|[^}]+\| *)[\w \d](}}.*\n)!";
369
				if ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ) {
370
					// Remove the line
371
					$newContent = preg_replace( $reg, '', $newContent );
372
					$removeNames[] = $user;
373
				} else {
374
					$newContent = preg_replace( $reg, '$1{{subst:#time:j F Y}}$2', $newContent );
375
					$riconfNames[] = $user;
376
				}
377
			}
378
		}
379
380
		if ( !$riconfNames || !$removeNames ) {
0 ignored issues
show
introduced by
$riconfNames is of type array|string[], thus it always evaluated to false.
Loading history...
381
			return;
382
		}
383
384
		$this->getLogger()->info(
385
			'Updating CU list. Riconf: ' . implode( ', ', $riconfNames ) .
386
			'; remove: ' . implode( ', ', $removeNames )
387
		);
388
		if ( count( $riconfNames ) > 1 ) {
389
			$lastUser = array_pop( $riconfNames );
390
			$riconfList = implode( ', ', $riconfNames ) . " e $lastUser";
391
		} elseif ( $riconfNames ) {
392
			$riconfList = $riconfNames[0];
393
		} else {
394
			$riconfList = 'nessuno';
395
		}
396
397
		if ( count( $removeNames ) > 1 ) {
398
			$lastUser = array_pop( $removeNames );
399
			$removeList = implode( ', ', $removeNames ) . " e $lastUser";
400
		} elseif ( $removeNames ) {
401
			$removeList = $removeNames[0];
402
		} else {
403
			$removeList = 'nessuno';
404
		}
405
406
		$summary = $this->msg( 'cu-list-update-summary' )
407
			->params( [
408
				'$riconf' => $riconfList,
409
				'$remove' => $removeList
410
			] )
411
			->text();
412
413
		$params = [
414
			'title' => $cuListTitle,
415
			'text' => $newContent,
416
			'summary' => $summary
417
		];
418
		$this->getController()->editPage( $params );
419
	}
420
421
	/**
422
	 * @param PageRiconferma[] $pages
423
	 */
424
	protected function updateBurList( array $pages ) {
425
		$this->getLogger()->info( 'Checking if bur list needs updating.' );
426
		$listTitle = $this->getConfig()->get( 'list-title' );
427
		$admins = json_decode( $this->getController()->getPageContent( $listTitle ), true );
428
429
		$remove = [];
430
		foreach ( $pages as $page ) {
431
			$user = $page->getUser();
432
			if ( array_key_exists( 'bureaucrat', $admins[ $user ] ) &&
433
				$page->getOutcome() & PageRiconferma::OUTCOME_FAIL
434
			) {
435
				$remove[] = $user;
436
			}
437
		}
438
439
		if ( !$remove ) {
440
			return;
441
		}
442
443
		$this->getLogger()->info( 'Updating bur list. Removing: ' . implode( ', ', $remove ) );
444
		$remList = implode( '|', array_map( 'preg_quote', $remove ) );
445
		$burListTitle = $this->getConfig()->get( 'bur-list-title' );
446
		$content = $this->getController()->getPageContent( $burListTitle );
447
		$reg = "!^\#\{\{ *Burocrate *\| *($remList).+\n!m";
448
		$newContent = preg_replace( $reg, '', $content );
449
450
		if ( count( $remove ) > 1 ) {
451
			$lastUser = array_pop( $remove );
452
			$removeList = implode( ', ', $remove ) . " e $lastUser";
453
		} else {
454
			$removeList = $remove[0];
455
		}
456
457
		$summary = $this->msg( 'bur-list-update-summary' )
458
			->params( [ '$remove' => $removeList ] )
459
			->text();
460
461
		$params = [
462
			'title' => $burListTitle,
463
			'text' => $newContent,
464
			'summary' => $summary
465
		];
466
		$this->getController()->editPage( $params );
467
	}
468
469
	/**
470
	 * Request the removal of the flag on meta
471
	 *
472
	 * @param PageRiconferma[] $pages
473
	 */
474
	protected function requestRemoval( array $pages ) {
475
		$this->getLogger()->info(
476
			'Requesting removal on meta for: ' . implode( ', ', array_map( 'strval', $pages ) )
477
		);
478
		$listTitle = $this->getConfig()->get( 'list-title' );
479
		$admins = json_decode( $this->getController()->getPageContent( $listTitle ), true );
480
481
		$oldUrl = RequestBase::$url;
482
		RequestBase::$url = 'https://meta.wikimedia.org/w/api.php';
483
		$pageTitle = $this->getConfig()->get( 'flag-removal-page' );
484
		$section = $this->getConfig()->get( 'flag-removal-section' );
485
		$baseText = $this->getConfig()->get( 'flag-removal-text' );
486
487
		$newContent = $this->getController()->getPageContent( $pageTitle, $section );
488
		foreach ( $pages as $page ) {
489
			$curText = strtr(
490
				$baseText,
491
				[
492
					'$username' => $page->getUser(),
493
					'$link' => '[[:it:' . $page->getTitle() . ']]',
494
					'$groups' => implode( ', ', array_keys( $admins[ $page->getUser() ] ) )
495
				]
496
			);
497
			$newContent .= $curText;
498
		}
499
500
		$summary = $this->msg( 'flag-removal-summary' )
501
			->params( [ '$num' => count( $pages ) ] )
502
			->text();
503
504
		$params = [
505
			'title' => $pageTitle,
506
			'text' => $newContent,
507
			'summary' => $summary
508
		];
509
		$this->getController()->editPage( $params );
510
511
		RequestBase::$url = $oldUrl;
512
	}
513
514
	/**
515
	 * Update [[Wikipedia:Wikipediano/Annunci]]
516
	 *
517
	 * @param PageRiconferma[] $pages
518
	 */
519
	protected function updateAnnunci( array $pages ) {
520
		$this->getLogger()->info( 'Updating annunci' );
521
		$title = $this->getConfig()->get( 'annunci-title' );
522
523
		$names = [];
524
		$text = '';
525
		foreach ( $pages as $page ) {
526
			$user = $page->getUser();
527
			$names[] = $user;
528
			$text .= "{{Breve|admin|{{subst:#time:j}}|[[Utente:$user|]] " .
529
				"non è stato riconfermato [[WP:A|amministratore]].}}\n";
530
		}
531
532
		$oldLoc = setlocale( LC_TIME, 'it_IT', 'Italian_Italy', 'Italian' );
533
		$month = ucfirst( strftime( '%B', time() ) );
534
		setlocale( LC_TIME, $oldLoc );
535
536
		$content = $this->getController()->getPageContent( $title, 1 );
537
		$secReg = "!=== *$month *===!";
538
		if ( preg_match( $secReg, $content ) !== false ) {
539
			$newContent = preg_replace( $secReg, '$0' . "\n" . $text, $content );
540
		} else {
541
			$re = '!</div>\s*}}\s*</includeonly>!';
542
			$newContent = preg_replace( $re, '$0' . "\n=== $month ===\n" . $text, $content );
543
		}
544
545
		if ( count( $names ) > 1 ) {
546
			$lastUser = array_pop( $names );
547
			$namesList = implode( ', ', $names ) . " e $lastUser";
548
		} else {
549
			$namesList = $names[0];
550
		}
551
552
		$summary = $this->msg( 'flag-removal-summary' )
553
			->params( [ '$names' => $namesList ] )
554
			->text();
555
556
		$params = [
557
			'title' => $title,
558
			'text' => $newContent,
559
			'summary' => $summary
560
		];
561
		$this->getController()->editPage( $params );
562
	}
563
564
	/**
565
	 * Update [[Wikipedia:Ultime notizie]]
566
	 *
567
	 * @param PageRiconferma[] $pages
568
	 */
569
	protected function updateUltimeNotizie( array $pages ) {
570
		$this->getLogger()->info( 'Updating ultime notizie' );
571
		$title = $this->getConfig()->get( 'ultimenotizie-title' );
572
573
		$names = [];
574
		$text = '';
575
		foreach ( $pages as $page ) {
576
			$user = $page->getUser();
577
			$title = $page->getTitle();
578
			$names[] = $user;
579
			$text .= "'''{{subst:#time:j F}}''': [[Utente:$user|]] non è stato [[$title|riconfermato]] " .
580
				'[[WP:A|amministratore]]; ora gli admin sono {{subst:#expr: {{NUMBEROFADMINS}} - 1}}.';
581
		}
582
583
		$content = $this->getController()->getPageContent( $title );
584
		$year = date( 'Y' );
585
		$secReg = "!== *$year *==!";
586
		if ( preg_match( $secReg, $content ) !== false ) {
587
			$newContent = preg_replace( $secReg, '$0' . "\n" . $text, $content );
588
		} else {
589
			$re = '!si veda la \[\[[^\]+relativa discussione]]\.\n!';
590
			$newContent = preg_replace( $re, '$0' . "\n== $year ==\n" . $text, $content );
591
		}
592
593
		if ( count( $names ) > 1 ) {
594
			$lastUser = array_pop( $names );
595
			$namesList = implode( ', ', $names ) . " e $lastUser";
596
		} else {
597
			$namesList = $names[0];
598
		}
599
600
		$summary = $this->msg( 'ultimenotizie-summary' )
601
			->params( [ '$names' => $namesList ] )
602
			->text();
603
604
		$params = [
605
			'title' => $title,
606
			'text' => $newContent,
607
			'summary' => $summary
608
		];
609
		$this->getController()->editPage( $params );
610
	}
611
}
612