Passed
Push — master ( d72fa1...8ee621 )
by Daimona
01:55
created

ClosePages::getPagesList()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 3
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme\Task;
4
5
use BotRiconferme\TaskResult;
6
use BotRiconferme\Request\RequestBase;
7
use BotRiconferme\Exception\TaskException;
8
use BotRiconferme\WikiController;
9
10
/**
11
 * For each open page, close it if the time's up and no more than 15 opposing votes were added
12
 * @fixme Avoid duplication with UpdatesAround etc.
13
 * @todo Handle votes
14
 */
15
class ClosePages extends Task {
16
	/**
17
	 * @inheritDoc
18
	 */
19
	public function run() : TaskResult {
20
		$this->getLogger()->info( 'Starting task ClosePages' );
21
22
		$titles = $this->getPagesList();
23
		$protectReason = $this->getConfig()->get( 'close-protect-summary' );
24
		foreach ( $titles as $title ) {
25
			$this->getController()->protectPage( $title, $protectReason );
26
			$this->updateBasePage( $title );
27
		}
28
29
		$this->removeFromMainPage( $titles );
30
		$this->addToArchive( $titles );
31
		$this->updateVote( $titles );
32
		$this->updateNews( count( $titles ) );
33
		$this->updateAdminList( $titles );
34
35
		$this->getLogger()->info( 'Task ClosePages completed successfully' );
36
		return new TaskResult( self::STATUS_OK );
37
	}
38
39
	/**
40
	 * Get a list of pages to close
41
	 *
42
	 * @return string[]
43
	 */
44
	protected function getPagesList() : array {
45
		$allPages = $this->getDataProvider()->getOpenPages();
46
		$ret = [];
47
		foreach ( $allPages as $page ) {
48
			$created = $this->getController()->getPageCreationTS( $page );
49
			if ( time() - $created <= 60 * 60 * 24 * 7 && !WikiController::hasOpposition( $page ) ) {
50
				$ret[] = $page;
51
			}
52
		}
53
		return $ret;
54
	}
55
56
	/**
57
	 * Removes pages from WP:A/Riconferme annuali
58
	 * @param string[] $titles
59
	 * @see UpdatesAround::addToMainPage()
60
	 */
61
	protected function removeFromMainPage( array $titles ) {
62
		$this->getLogger()->info( 'Removing from main: ' . implode( ', ', $titles ) );
63
64
		$mainPage = $this->getConfig()->get( 'ric-main-page' );
65
		$content = $this->getController()->getPageContent( $mainPage );
66
		$translations = [];
67
		foreach ( $titles as $title ) {
68
			$translations[ '{{' . $title . '}}' ] = '';
69
		}
70
71
		$params = [
72
			'title' => $mainPage,
73
			'text' => strtr( $content, $translations ),
74
			'summary' => $this->getConfig()->get( 'close-main-summary' )
75
		];
76
		$this->getController()->editPage( $params );
77
	}
78
79
	/**
80
	 * Adds closed pages to the current archive
81
	 *
82
	 * @param string[] $titles
83
	 */
84
	protected function addToArchive( array $titles ) {
85
		$this->getLogger()->info( 'Adding to archive: ' . implode( ', ', $titles ) );
86
87
		$archiveTitle = $this->getConfig()->get( 'close-archive-title' );
88
		$archiveTitle = "$archiveTitle/" . date( 'Y' );
89
90
		$append = '';
91
		$archivedList = [];
92
		foreach ( $titles as $page ) {
93
			$append .= '{{' . $page . "}}\n";
94
			$archivedList[] = explode( '/', $page, 3 )[2];
95
		}
96
97
		if ( count( $archivedList ) > 1 ) {
98
			$last = array_pop( $archivedList );
99
			$userNums = implode( ', ', $archivedList ) . " e $last";
100
		} else {
101
			$userNums = $archivedList[0];
102
		}
103
104
		$summary = strtr(
105
			$this->getConfig()->get( 'close-archive-summary' ),
106
			[ '$usernums' => $userNums ]
107
		);
108
109
		$params = [
110
			'title' => $archiveTitle,
111
			'appendtext' => $append,
112
			'summary' => $summary
113
		];
114
115
		$this->getController()->editPage( $params );
116
	}
117
118
	/**
119
	 * @param string $title
120
	 * @see CreatePages::updateBasePage()
121
	 */
122
	protected function updateBasePage( string $title ) {
123
		$this->getLogger()->info( "Updating base page $title" );
124
125
		// @phan-suppress-next-line PhanTypeMismatchArgumentInternal WTF Phan what's wrong w/ u?
126
		$baseTitle = substr( $title, 0, strrpos( $title, '/' ) );
127
		$current = $this->getController()->getPageContent( $baseTitle );
128
129
		$newContent = str_replace( 'riconferma in corso', 'riconferma tacita', $current );
130
		$params = [
131
			'title' => $title,
132
			'text' => $newContent,
133
			'summary' => $this->getConfig()->get( 'close-base-page-summary-update' )
134
		];
135
136
		$this->getController()->editPage( $params );
137
	}
138
139
	/**
140
	 * @param string[] $titles
141
	 * @see UpdatesAround::addVote()
142
	 */
143
	protected function updateVote( array $titles ) {
144
		$votePage = $this->getConfig()->get( 'ric-vote-page' );
145
		$content = $this->getController()->getPageContent( $votePage );
146
147
		$titleReg = implode( '|', array_map( 'preg_quote', $titles ) );
148
		$search = "!^\*.+ La \[\[($titleReg)\|procedura]] termina.+\n!gm";
149
150
		$newContent = preg_replace( $search, '', $content );
151
		// Make sure the last line ends with a full stop
152
		$sectionReg = '!(^;È in corso.+riconferma tacita.+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
153
		$newContent = preg_replace( $sectionReg, '$1.', $newContent );
154
155
		$summary = strtr(
156
			$this->getConfig()->get( 'close-vote-page-summary' ),
157
			[ '$num' => count( $titles ) ]
158
		);
159
		$summary = preg_replace_callback(
160
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
161
			function ( $matches ) {
162
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
163
			},
164
			$summary
165
		);
166
167
		$params = [
168
			'title' => $votePage,
169
			'text' => $newContent,
170
			'summary' => $summary
171
		];
172
173
		$this->getController()->editPage( $params );
174
	}
175
176
	/**
177
	 * @param int $amount
178
	 * @throws TaskException
179
	 * @see UpdatesAround::addNews()
180
	 */
181
	protected function updateNews( int $amount ) {
182
		$this->getLogger()->info( "Decreasing the news counter by $amount" );
183
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
184
185
		$content = $this->getController()->getPageContent( $newsPage );
186
		$reg = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
187
188
		$matches = [];
189
		if ( preg_match( $reg, $content, $matches ) === false ) {
190
			throw new TaskException( 'Param not found in news page' );
191
		}
192
193
		$newNum = (int)$matches[2] - $amount;
194
		$newContent = preg_replace( $reg, '${1}' . $newNum, $content );
195
196
		$summary = strtr(
197
			$this->getConfig()->get( 'close-news-page-summary' ),
198
			[ '$num' => $amount ]
199
		);
200
		$summary = preg_replace_callback(
201
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
202
			function ( $matches ) {
203
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
204
			},
205
			$summary
206
		);
207
208
		$params = [
209
			'title' => $newsPage,
210
			'text' => $newContent,
211
			'summary' => $summary
212
		];
213
214
		$this->getController()->editPage( $params );
215
	}
216
217
	/**
218
	 * Update date on WP:Amministratori/Lista
219
	 *
220
	 * @param string[] $titles
221
	 */
222
	protected function updateAdminList( array $titles ) {
223
		$listTitle = $this->getConfig()->get( 'admins-list' );
224
		$content = $this->getController()->getPageContent( $listTitle );
225
		$newDate = date( 'Ymd', strtotime( '+1 year' ) );
226
227
		$names = [];
228
		foreach ( $titles as $title ) {
229
			$user = explode( '/', $title )[2];
230
			$names[] = $user;
231
			$reg = "!(\{\{Amministratore\/riga\|$user.+\| *)\d+(?= *\|(?: *pausa)? *\}\})!";
232
			$content = preg_replace( $reg, '$1' . $newDate, $content );
233
		}
234
235
		if ( count( $names ) > 1 ) {
236
			$lastUser = array_pop( $names );
237
			$usersList = implode( ', ', $names ) . " e $lastUser";
238
		} else {
239
			$usersList = $names[0];
240
		}
241
242
		$summary = strtr(
243
			$this->getConfig()->get( 'close-update-list-summary' ),
244
			[ '$names' => $usersList ]
245
		);
246
247
		$params = [
248
			'title' => $listTitle,
249
			'text' => $content,
250
			'summary' => $summary
251
		];
252
253
		$this->getController()->editPage( $params );
254
	}
255
}
256