Passed
Push — master ( 33a572...6f44ea )
by Daimona
01:49
created

StartVote::processPages()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 6
nop 1
dl 0
loc 14
rs 9.6111
c 0
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme\Task;
4
5
use BotRiconferme\Exception\TaskException;
6
use BotRiconferme\PageRiconferma;
7
use BotRiconferme\TaskResult;
8
use BotRiconferme\WikiController;
9
10
/**
11
 * Start a vote if there are >= 15 opposing comments
12
 */
13
class StartVote extends Task {
14
	/**
15
	 * @inheritDoc
16
	 */
17
	public function run() : TaskResult {
18
		$this->getLogger()->info( 'Starting task StartVote' );
19
20
		$pages = $this->getDataProvider()->getOpenPages();
21
22
		if ( $pages ) {
23
			$this->processPages( $pages );
24
		} else {
25
			$this->getLogger()->info( 'No open procedures.' );
26
		}
27
28
		$this->getLogger()->info( 'Task StartVote completed successfully' );
29
		return new TaskResult( self::STATUS_OK );
30
	}
31
32
	/**
33
	 * @param PageRiconferma[] $pages
34
	 */
35
	protected function processPages( array $pages ) {
36
		$actualPages = [];
37
		foreach ( $pages as $page ) {
38
			if ( $page->hasOpposition() && !$page->isVote() ) {
39
				$this->openVote( $page );
40
				$actualPages[] = $page;
41
			}
42
		}
43
44
		if ( $actualPages ) {
45
			$this->updateVotePage( $actualPages );
46
			$this->updateNews( count( $actualPages ) );
47
		} else {
48
			$this->getLogger()->info( 'No votes to open' );
49
		}
50
	}
51
52
	/**
53
	 * Start the vote for the given page
54
	 *
55
	 * @param PageRiconferma $page
56
	 */
57
	protected function openVote( PageRiconferma $page ) {
58
		$this->getLogger()->info( "Starting vote on $page" );
59
60
		$content = $page->getContent();
61
62
		$newContent = preg_replace(
63
			'!^La procedura di riconferma tacita .+!m',
64
			'<del>$0</del>',
65
			$content
66
		);
67
68
		$newContent = preg_replace(
69
			'/<!-- SEZIONE DA UTILIZZARE PER L\'EVENTUALE VOTAZIONE DI RICONFERMA.*\n/',
70
			'',
71
			$newContent
72
		);
73
74
		$newContent = preg_replace(
75
			'!(==== *Favorevoli alla riconferma *====\n\#[\s.]+)\n-->!',
76
			'$1',
77
			$newContent
78
		);
79
80
		$params = [
81
			'title' => $page->getTitle(),
82
			'text' => $newContent,
83
			'summary' => $this->getConfig()->get( 'vote-start-summary' )
84
		];
85
86
		$this->getController()->editPage( $params );
87
	}
88
89
	/**
90
	 * Update [[WP:Wikipediano/Votazioni]]
91
	 *
92
	 * @param PageRiconferma[] $pages
93
	 * @see ClosePages::updateVote()
94
	 * @see UpdatesAround::addVote()
95
	 */
96
	protected function updateVotePage( array $pages ) {
97
		$votePage = $this->getConfig()->get( 'ric-vote-page' );
98
		$content = $this->getController()->getPageContent( $votePage );
99
100
		$titles = [];
101
		foreach ( $pages as $page ) {
102
			$titles[] = preg_quote( $page->getTitle() );
103
		}
104
		$titleReg = implode( '|', $titles );
105
		$search = "!^\*.+ La \[\[($titleReg)\|procedura]] termina.+\n!gm";
106
107
		$newContent = preg_replace( $search, '', $content );
108
		// Make sure the last line ends with a full stop
109
		$sectionReg = '!(^;È in corso.+riconferma tacita.+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
110
		$newContent = preg_replace( $sectionReg, '$1.', $newContent );
111
112
		$newLines = '';
113
		$time = WikiController::getTimeWithArticle( time() + ( 60 * 60 * 24 * 14 ) );
114
		foreach ( $pages as $page ) {
115
			$newLines .= "*[[Utente:{$page->getUser()}|]]. La [[{$page->getTitle()}|votazione]] termina $time;\n";
116
		}
117
118
		$introReg = '!^Si vota per la \[\[Wikipedia:Amministratori/Riconferma annuale.+!m';
119
		if ( preg_match( $introReg, strip_tags( $content ) ) ) {
120
			// Put before the existing ones, if they're found outside comments
121
			$newContent = preg_replace( $introReg, '$0' . "\n$newLines", $newContent, 1 );
122
		} else {
123
			// Start section
124
			$matches = [];
125
			if ( preg_match( $introReg, $content, $matches ) === false ) {
126
				throw new TaskException( 'Intro not found in vote page' );
127
			}
128
			$beforeReg = '!INSERIRE LA NOTIZIA PIÙ NUOVA IN CIMA.+!m';
129
			// Replace semicolon with full stop
130
			$newLines = substr( $newLines, 0, -2 ) . ".\n";
131
			$newContent = preg_replace( $beforeReg, '$0' . "\n{$matches[0]}\n$newLines", $newContent, 1 );
132
		}
133
134
		$summary = strtr(
135
			$this->getConfig()->get( 'vote-start-vote-page-summary' ),
136
			[ '$num' => count( $pages ) ]
137
		);
138
		$summary = preg_replace_callback(
139
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
140
			function ( $matches ) {
141
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
142
			},
143
			$summary
144
		);
145
146
		$params = [
147
			'title' => $votePage,
148
			'text' => $newContent,
149
			'summary' => $summary
150
		];
151
152
		$this->getController()->editPage( $params );
153
	}
154
155
	/**
156
	 * Template:VotazioniRCnews
157
	 *
158
	 * @param int $amount Of pages to move
159
	 * @see UpdatesAround::addNews()
160
	 * @see ClosePages::updateNews()
161
	 */
162
	protected function updateNews( int $amount ) {
163
		$this->getLogger()->info( "Turning $amount pages into votes" );
164
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
165
166
		$content = $this->getController()->getPageContent( $newsPage );
167
		$regTac = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
168
		$regVot = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
169
170
		$tacMatches = $votMatches = [];
171
		if ( preg_match( $regTac, $content, $tacMatches ) === false ) {
172
			throw new TaskException( 'Param "tacite" not found in news page' );
173
		}
174
		if ( preg_match( $regVot, $content, $votMatches ) === false ) {
175
			throw new TaskException( 'Param "voto" not found in news page' );
176
		}
177
178
		$newTac = (int)$tacMatches[2] - $amount;
179
		$newVot = (int)$votMatches[2] + $amount;
180
181
		$newContent = preg_replace( $regTac, '${1}' . $newTac, $content );
182
		$newContent = preg_replace( $regVot, '${1}' . $newVot, $newContent );
183
184
		$summary = strtr(
185
			$this->getConfig()->get( 'vote-start-news-page-summary' ),
186
			[ '$num' => $amount ]
187
		);
188
		$summary = preg_replace_callback(
189
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
190
			function ( $matches ) {
191
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
192
			},
193
			$summary
194
		);
195
196
		$params = [
197
			'title' => $newsPage,
198
			'text' => $newContent,
199
			'summary' => $summary
200
		];
201
202
		$this->getController()->editPage( $params );
203
	}
204
}
205