Passed
Branch master (a4e902)
by Daimona
01:39
created

StartVote::runInternal()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
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\Exception\TaskException;
6
use BotRiconferme\Message;
7
use BotRiconferme\Page\Page;
8
use BotRiconferme\Page\PageRiconferma;
9
10
/**
11
 * Start a vote if there are >= 15 opposing comments
12
 */
13
class StartVote extends Task {
14
	/**
15
	 * @inheritDoc
16
	 */
17
	protected function getSubtasksMap(): array {
18
		// Everything is done here.
19
		return [];
20
	}
21
22
	/**
23
	 * @inheritDoc
24
	 */
25
	public function runInternal() : int {
26
		$pages = $this->getDataProvider()->getOpenPages();
27
28
		if ( !$pages ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $pages of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
29
			return self::STATUS_NOTHING;
30
		}
31
32
		$this->processPages( $pages );
33
34
		return self::STATUS_GOOD ;
35
	}
36
37
	/**
38
	 * @param PageRiconferma[] $pages
39
	 */
40
	protected function processPages( array $pages ) {
41
		$actualPages = [];
42
		foreach ( $pages as $page ) {
43
			if ( $page->hasOpposition() && !$page->isVote() ) {
44
				$this->openVote( $page );
45
				$actualPages[] = $page;
46
			}
47
		}
48
49
		if ( $actualPages ) {
50
			$this->updateVotePage( $actualPages );
51
			$this->updateNews( count( $actualPages ) );
52
		} else {
53
			$this->getLogger()->info( 'No votes to open' );
54
		}
55
	}
56
57
	/**
58
	 * Start the vote for the given page
59
	 *
60
	 * @param PageRiconferma $page
61
	 */
62
	protected function openVote( PageRiconferma $page ) {
63
		$this->getLogger()->info( "Starting vote on $page" );
64
65
		$content = $page->getContent();
66
67
		$newContent = preg_replace(
68
			'!^La procedura di riconferma tacita .+!m',
69
			'<del>$0</del>',
70
			$content
71
		);
72
73
		$newContent = preg_replace(
74
			'/<!-- SEZIONE DA UTILIZZARE PER L\'EVENTUALE VOTAZIONE DI RICONFERMA.*\n/',
75
			'',
76
			$newContent
77
		);
78
79
		$newContent = preg_replace(
80
			'!(==== *Favorevoli alla riconferma *====\n\#[\s.]+|maggioranza di.+ dei votanti\.)\n-->!',
81
			'$1',
82
			$newContent,
83
			2
84
		);
85
86
		$params = [
87
			'text' => $newContent,
88
			'summary' => $this->getConfig()->get( 'vote-start-summary' )
89
		];
90
91
		$page->edit( $params );
92
	}
93
94
	/**
95
	 * Update [[WP:Wikipediano/Votazioni]]
96
	 *
97
	 * @param PageRiconferma[] $pages
98
	 * @see SimpleUpdates::updateVote()
99
	 * @see UpdatesAround::addVote()
100
	 */
101
	protected function updateVotePage( array $pages ) {
102
		$votePage = new Page( $this->getConfig()->get( 'ric-vote-page' ) );
103
		$content = $votePage->getContent();
104
105
		$titles = [];
106
		foreach ( $pages as $page ) {
107
			$titles[] = preg_quote( $page->getTitle() );
108
		}
109
		$titleReg = implode( '|', $titles );
110
		$search = "!^\*.+ La \[\[($titleReg)\|procedura]] termina.+\n!gm";
111
112
		$newContent = preg_replace( $search, '', $content );
113
		// Make sure the last line ends with a full stop
114
		$sectionReg = '!(^;È in corso.+riconferma tacita.+amministratori.+\n(?:\*.+[;\.]\n)+\*.+)[\.;]!m';
115
		$newContent = preg_replace( $sectionReg, '$1.', $newContent );
116
117
		$newLines = '';
118
		$time = Message::getTimeWithArticle( time() + ( 60 * 60 * 24 * 14 ) );
119
		foreach ( $pages as $page ) {
120
			$newLines .= '*[[Utente:' . $page->getUser() . '|]]. ' .
121
				'La [[' . $page->getTitle() . "|votazione]] termina $time;\n";
122
		}
123
124
		$introReg = '!^Si vota per la \[\[Wikipedia:Amministratori/Riconferma annuale.+!m';
125
		if ( preg_match( $introReg, strip_tags( $newContent ) ) ) {
126
			// Put before the existing ones, if they're found outside comments
127
			$newContent = preg_replace( $introReg, '$0' . "\n$newLines", $newContent, 1 );
128
		} else {
129
			// Start section
130
			$matches = [];
131
			if ( preg_match( $introReg, $newContent, $matches ) === false ) {
132
				throw new TaskException( 'Intro not found in vote page' );
133
			}
134
			$beforeReg = '!INSERIRE LA NOTIZIA PIÙ NUOVA IN CIMA.+!m';
135
			// Replace semicolon with full stop
136
			$newLines = substr( $newLines, 0, -2 ) . ".\n";
137
			$newContent = preg_replace( $beforeReg, '$0' . "\n{$matches[0]}\n$newLines", $newContent, 1 );
138
		}
139
140
		$summary = $this->msg( 'vote-start-vote-page-summary' )
141
			->params( [ '$num' => count( $pages ) ] )
142
			->text();
143
144
		$params = [
145
			'text' => $newContent,
146
			'summary' => $summary
147
		];
148
149
		$votePage->edit( $params );
150
	}
151
152
	/**
153
	 * Template:VotazioniRCnews
154
	 *
155
	 * @param int $amount Of pages to move
156
	 * @see UpdatesAround::addNews()
157
	 * @see SimpleUpdates::updateNews()
158
	 */
159
	protected function updateNews( int $amount ) {
160
		$this->getLogger()->info( "Turning $amount pages into votes" );
161
		$newsPage = new Page( $this->getConfig()->get( 'ric-news-page' ) );
162
163
		$content = $newsPage->getContent();
164
		$regTac = '!(\| *riconferme[ _]tacite[ _]amministratori *= *)(\d+)!';
165
		$regVot = '!(\| *riconferme[ _]voto[ _]amministratori *= *)(\d+)!';
166
167
		if ( !$newsPage->matches( $regTac ) ) {
168
			throw new TaskException( 'Param "tacite" not found in news page' );
169
		}
170
		if ( !$newsPage->matches( $regVot ) ) {
171
			throw new TaskException( 'Param "voto" not found in news page' );
172
		}
173
174
		$newTac = intval( $newsPage->getMatch( $regTac )[2] ) - $amount ?: '';
175
		$newVot = intval( $newsPage->getMatch( $regVot )[2] ) + $amount ?: '';
176
177
		$newContent = preg_replace( $regTac, '${1}' . $newTac, $content );
178
		$newContent = preg_replace( $regVot, '${1}' . $newVot, $newContent );
179
180
		$summary = $this->msg( 'vote-start-news-page-summary' )
181
			->params( [ '$num' => $amount ] )
182
			->text();
183
184
		$params = [
185
			'text' => $newContent,
186
			'summary' => $summary
187
		];
188
189
		$newsPage->edit( $params );
190
	}
191
}
192