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

StartVote::run()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 13
rs 10
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.]+|maggioranza di \'\'\'2/3\'\'\' dei votanti\.)\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() . '|]]. ' .
116
				'La [[' . $page->getTitle() . "|votazione]] termina $time;\n";
117
		}
118
119
		$introReg = '!^Si vota per la \[\[Wikipedia:Amministratori/Riconferma annuale.+!m';
120
		if ( preg_match( $introReg, strip_tags( $content ) ) ) {
121
			// Put before the existing ones, if they're found outside comments
122
			$newContent = preg_replace( $introReg, '$0' . "\n$newLines", $newContent, 1 );
123
		} else {
124
			// Start section
125
			$matches = [];
126
			if ( preg_match( $introReg, $content, $matches ) === false ) {
127
				throw new TaskException( 'Intro not found in vote page' );
128
			}
129
			$beforeReg = '!INSERIRE LA NOTIZIA PIÙ NUOVA IN CIMA.+!m';
130
			// Replace semicolon with full stop
131
			$newLines = substr( $newLines, 0, -2 ) . ".\n";
132
			$newContent = preg_replace( $beforeReg, '$0' . "\n{$matches[0]}\n$newLines", $newContent, 1 );
133
		}
134
135
		$summary = strtr(
136
			$this->getConfig()->get( 'vote-start-vote-page-summary' ),
137
			[ '$num' => count( $pages ) ]
138
		);
139
		$summary = preg_replace_callback(
140
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
141
			function ( $matches ) {
142
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
143
			},
144
			$summary
145
		);
146
147
		$params = [
148
			'title' => $votePage,
149
			'text' => $newContent,
150
			'summary' => $summary
151
		];
152
153
		$this->getController()->editPage( $params );
154
	}
155
156
	/**
157
	 * Template:VotazioniRCnews
158
	 *
159
	 * @param int $amount Of pages to move
160
	 * @see UpdatesAround::addNews()
161
	 * @see ClosePages::updateNews()
162
	 */
163
	protected function updateNews( int $amount ) {
164
		$this->getLogger()->info( "Turning $amount pages into votes" );
165
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
166
167
		$content = $this->getController()->getPageContent( $newsPage );
168
		$regTac = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
169
		$regVot = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
170
171
		$tacMatches = $votMatches = [];
172
		if ( preg_match( $regTac, $content, $tacMatches ) === false ) {
173
			throw new TaskException( 'Param "tacite" not found in news page' );
174
		}
175
		if ( preg_match( $regVot, $content, $votMatches ) === false ) {
176
			throw new TaskException( 'Param "voto" not found in news page' );
177
		}
178
179
		$newTac = (int)$tacMatches[2] - $amount ?: '';
180
		$newVot = (int)$votMatches[2] + $amount ?: '';
181
182
		$newContent = preg_replace( $regTac, '${1}' . $newTac, $content );
183
		$newContent = preg_replace( $regVot, '${1}' . $newVot, $newContent );
184
185
		$summary = strtr(
186
			$this->getConfig()->get( 'vote-start-news-page-summary' ),
187
			[ '$num' => $amount ]
188
		);
189
		$summary = preg_replace_callback(
190
			'!\{\{$plur|(\d+)|([^|]+)|([^|]+)}}!',
191
			function ( $matches ) {
192
				return intval( $matches[1] ) > 1 ? trim( $matches[3] ) : trim( $matches[2] );
193
			},
194
			$summary
195
		);
196
197
		$params = [
198
			'title' => $newsPage,
199
			'text' => $newContent,
200
			'summary' => $summary
201
		];
202
203
		$this->getController()->editPage( $params );
204
	}
205
}
206