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

StartVote   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 104
dl 0
loc 189
rs 10
c 0
b 0
f 0
wmc 17

4 Methods

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