Passed
Push — master ( e26f3b...6f3cd3 )
by Daimona
01:37
created

ClosePages::removeFromMainPage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 1
dl 0
loc 18
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
 * @todo Handle votes
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
36
		$this->getLogger()->info( 'Task ClosePages completed successfully' );
37
		return new TaskResult( self::STATUS_OK );
38
	}
39
40
	/**
41
	 * Get a list of pages to close
42
	 *
43
	 * @return PageRiconferma[]
44
	 */
45
	protected function getPagesList() : array {
46
		$allPages = $this->getDataProvider()->getOpenPages();
47
		$ret = [];
48
		foreach ( $allPages as $page ) {
49
			if ( time() > $page->getEndTimestamp() ) {
50
				$ret[] = $page;
51
			}
52
		}
53
		return $ret;
54
	}
55
56
	/**
57
	 * @param PageRiconferma $page
58
	 */
59
	protected function addVoteCloseText( PageRiconferma $page ) {
60
		$content = $page->getContent();
61
		$beforeReg = '!è necessario ottenere una maggioranza .+ votanti\.!';
62
		$newContent = preg_replace( $beforeReg, '$0' . "\n" . $page->getOutcomeText(), $content );
63
64
		$params = [
65
			'title' => $page->getTitle(),
66
			'text' => $newContent,
67
			'summary' => $this->getConfig()->get( 'close-result-summary' )
68
		];
69
		$this->getController()->editPage( $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
		$text = $page->isVote() ?
171
			'votazione: ' . ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ? 'non riconfermato' : 'riconfermato' ) :
172
			'riconferma tacita';
173
174
		$newContent = str_replace( 'riconferma in corso', $text, $current );
175
		$params = [
176
			'title' => $page->getTitle(),
177
			'text' => $newContent,
178
			'summary' => $this->getConfig()->get( 'close-base-page-summary-update' )
179
		];
180
181
		$this->getController()->editPage( $params );
182
	}
183
184
	/**
185
	 * @param PageRiconferma[] $pages
186
	 * @see UpdatesAround::addVote()
187
	 */
188
	protected function updateVote( array $pages ) {
189
		$votePage = $this->getConfig()->get( 'ric-vote-page' );
190
		$content = $this->getController()->getPageContent( $votePage );
191
192
		$titles = [];
193
		foreach ( $pages as $page ) {
194
			$titles[] = preg_quote( $page->getTitle() );
195
		}
196
197
		$titleReg = implode( '|', $titles );
198
		$search = "!^\*.+ La \[\[($titleReg)\|procedura]] termina.+\n!gm";
199
200
		$newContent = preg_replace( $search, '', $content );
201
		// Make sure the last line ends with a full stop in every section
202
		$simpleSectReg = '!(^;È in corso.+riconferma tacita.+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
203
		$voteSectReg = '!(^;Si vota per la .+riconferma .+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
204
		$newContent = preg_replace( $simpleSectReg, '$1.', $newContent );
205
		$newContent = preg_replace( $voteSectReg, '$1.', $newContent );
206
207
		// @fixme Remove empty sections, and add the "''Nessuna riconferma o votazione in corso''" message
208
		//   if the page is empty! Or just wait for the page to be restyled...
209
210
		$summary = strtr(
211
			$this->getConfig()->get( 'close-vote-page-summary' ),
212
			[ '$num' => count( $pages ) ]
213
		);
214
		$summary = preg_replace_callback(
215
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
216
			function ( $matches ) {
217
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
218
			},
219
			$summary
220
		);
221
222
		$params = [
223
			'title' => $votePage,
224
			'text' => $newContent,
225
			'summary' => $summary
226
		];
227
228
		$this->getController()->editPage( $params );
229
	}
230
231
	/**
232
	 * @param array $pages
233
	 * @see UpdatesAround::addNews()
234
	 */
235
	protected function updateNews( array $pages ) {
236
		$simpleAmount = $voteAmount = 0;
237
		foreach ( $pages as $page ) {
238
			if ( $page->isVote() ) {
239
				$voteAmount++;
240
			} else {
241
				$simpleAmount++;
242
			}
243
		}
244
245
		$this->getLogger()->info( "Decreasing the news counter: $simpleAmount simple, $voteAmount votes." );
246
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
247
248
		$content = $this->getController()->getPageContent( $newsPage );
249
		$simpleReg = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
250
		$voteReg = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
251
252
		$simpleMatches = $voteMatched = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $voteMatched is dead and can be removed.
Loading history...
253
		preg_match( $simpleReg, $content, $simpleMatches );
254
		preg_match( $voteReg, $content, $voteMatches );
255
256
		$newSimp = (int)$simpleMatches[2] - $simpleAmount ?: '';
257
		$newVote = (int)$voteMatches[2] - $voteAmount ?: '';
258
		$newContent = preg_replace( $simpleReg, '${1}' . $newSimp, $content );
259
		$newContent = preg_replace( $voteReg, '${1}' . $newVote, $newContent );
260
261
		$summary = strtr(
262
			$this->getConfig()->get( 'close-news-page-summary' ),
263
			[ '$num' => count( $pages ) ]
264
		);
265
		$summary = preg_replace_callback(
266
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
267
			function ( $matches ) {
268
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
269
			},
270
			$summary
271
		);
272
273
		$params = [
274
			'title' => $newsPage,
275
			'text' => $newContent,
276
			'summary' => $summary
277
		];
278
279
		$this->getController()->editPage( $params );
280
	}
281
282
	/**
283
	 * Update date on WP:Amministratori/Lista
284
	 *
285
	 * @param PageRiconferma[] $pages
286
	 */
287
	protected function updateAdminList( array $pages ) {
288
		$listTitle = $this->getConfig()->get( 'admins-list' );
289
		$newContent = $this->getController()->getPageContent( $listTitle );
290
		$newDate = date( 'Ymd', strtotime( '+1 year' ) );
291
292
		$riconfNames = $removeNames = [];
293
		foreach ( $pages as $page ) {
294
			$user = $page->getUser();
295
			$reg = "!(\{\{Amministratore\/riga\|$user.+\| *)\d+( *\|(?: *pausa)? *\}\}\n)!";
296
			if ( $page->getOutcome() & PageRiconferma::OUTCOME_FAIL ) {
297
				// Remove the line
298
				$newContent = preg_replace( $reg, '', $newContent );
299
				$removeNames[] = $user;
300
			} else {
301
				$newContent = preg_replace( $reg, '$1' . $newDate . '$2', $newContent );
302
				$riconfNames[] = $user;
303
			}
304
		}
305
306
307
		if ( count( $riconfNames ) > 1 ) {
308
			$lastUser = array_pop( $riconfNames );
309
			$riconfList = implode( ', ', $riconfNames ) . " e $lastUser";
310
		} elseif ( $riconfNames ) {
311
			$riconfList = $riconfNames[0];
312
		} else {
313
			$riconfList = 'nessuno';
314
		}
315
316
		if ( count( $removeNames ) > 1 ) {
317
			$lastUser = array_pop( $removeNames );
318
			$removeList = implode( ', ', $removeNames ) . " e $lastUser";
319
		} elseif ( $removeNames ) {
320
			$removeList = $removeNames[0];
321
		} else {
322
			$removeList = 'nessuno';
323
		}
324
325
		$summary = strtr(
326
			$this->getConfig()->get( 'close-update-list-summary' ),
327
			[
328
				'$riconf' => $riconfList,
329
				'$remove' => $removeList
330
			]
331
		);
332
333
		$params = [
334
			'title' => $listTitle,
335
			'text' => $newContent,
336
			'summary' => $summary
337
		];
338
339
		$this->getController()->editPage( $params );
340
	}
341
}
342