Passed
Push — master ( 98e5c5...7ca7e9 )
by Daimona
01:28
created

StartVote   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 92
dl 0
loc 175
rs 10
c 0
b 0
f 0
wmc 18

5 Methods

Rating   Name   Duplication   Size   Complexity  
A processPages() 0 14 5
A run() 0 13 2
A openVote() 0 30 1
A updateNews() 0 33 5
A updateVotePage() 0 50 5
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.+ dei votanti\.)\n-->!',
76
			'$1',
77
			$newContent,
78
			2
79
		);
80
81
		$params = [
82
			'text' => $newContent,
83
			'summary' => $this->getConfig()->get( 'vote-start-summary' )
84
		];
85
86
		$page->edit( $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( '|', array_map( 'preg_quote', $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 = $this->msg( 'vote-start-vote-page-summary' )
136
			->params( [ '$num' => count( $pages ) ] )
137
			->text();
138
139
		$params = [
140
			'title' => $votePage,
141
			'text' => $newContent,
142
			'summary' => $summary
143
		];
144
145
		$this->getController()->editPage( $params );
146
	}
147
148
	/**
149
	 * Template:VotazioniRCnews
150
	 *
151
	 * @param int $amount Of pages to move
152
	 * @see UpdatesAround::addNews()
153
	 * @see ClosePages::updateNews()
154
	 */
155
	protected function updateNews( int $amount ) {
156
		$this->getLogger()->info( "Turning $amount pages into votes" );
157
		$newsPage = $this->getConfig()->get( 'ric-news-page' );
158
159
		$content = $this->getController()->getPageContent( $newsPage );
160
		$regTac = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
161
		$regVot = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
162
163
		$tacMatches = $votMatches = [];
164
		if ( preg_match( $regTac, $content, $tacMatches ) === false ) {
165
			throw new TaskException( 'Param "tacite" not found in news page' );
166
		}
167
		if ( preg_match( $regVot, $content, $votMatches ) === false ) {
168
			throw new TaskException( 'Param "voto" not found in news page' );
169
		}
170
171
		$newTac = (int)$tacMatches[2] - $amount ?: '';
172
		$newVot = (int)$votMatches[2] + $amount ?: '';
173
174
		$newContent = preg_replace( $regTac, '${1}' . $newTac, $content );
175
		$newContent = preg_replace( $regVot, '${1}' . $newVot, $newContent );
176
177
		$summary = $this->msg( 'vote-start-news-page-summary' )
178
			->params( [ '$num' => $amount ] )
179
			->text();
180
181
		$params = [
182
			'title' => $newsPage,
183
			'text' => $newContent,
184
			'summary' => $summary
185
		];
186
187
		$this->getController()->editPage( $params );
188
	}
189
}
190