Passed
Push — master ( 0986c5...31e6ff )
by Daimona
01:50
created

PageRiconferma::getUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme;
4
5
/**
6
 * Represents a single riconferma page
7
 */
8
class PageRiconferma extends Page {
9
	// Sections of the page. The value is the section number
10
	const SECTION_SUPPORT = 3;
11
	const SECTION_OPPOSE = 4;
12
13
	// Possible outcomes of a vote
14
	const OUTCOME_OK = 0;
15
	const OUTCOME_FAIL_VOTES = 1;
16
	const OUTCOME_NO_QUOR = 2;
17
	const OUTCOME_FAIL = self::OUTCOME_FAIL_VOTES | self::OUTCOME_NO_QUOR;
18
19
	/**
20
	 * Get the name of the user from the title
21
	 *
22
	 * @return string
23
	 */
24
	public function getUser() : string {
25
		return explode( '/', $this->title )[2];
26
	}
27
28
	/**
29
	 * Returns the progressive number in the title
30
	 *
31
	 * @return int
32
	 */
33
	public function getNum() : int {
34
		$bits = explode( '/', $this->getTitle() );
35
		return intval( end( $bits ) );
36
	}
37
38
	/**
39
	 * Get the last part of the title as Username/Num
40
	 *
41
	 * @return string
42
	 */
43
	public function getUserNum() : string {
44
		return explode( '/', $this->getTitle(), 3 )[2];
45
	}
46
47
	/**
48
	 * Strip the part with the progressive number
49
	 *
50
	 * @return string
51
	 */
52
	public function getBaseTitle() : string {
53
		// @phan-suppress-next-line PhanTypeMismatchArgumentInternal Phan bug
54
		return substr( $this->getTitle(), 0, strrpos( $this->getTitle(), '/' ) );
55
	}
56
57
	/**
58
	 * Get the amount of opposing votes
59
	 *
60
	 * @return int
61
	 */
62
	public function getOpposingCount() : int {
63
		return $this->getCountForSection( self::SECTION_OPPOSE );
64
	}
65
66
	/**
67
	 * Get the amount support votes
68
	 *
69
	 * @return int
70
	 */
71
	public function getSupportCount() : int {
72
		return $this->getCountForSection( self::SECTION_SUPPORT );
73
	}
74
75
	/**
76
	 * Count the votes in the given section
77
	 *
78
	 * @param int $secNum
79
	 * @return int
80
	 */
81
	protected function getCountForSection( int $secNum ) : int {
82
		$content = $this->controller->getPageContent( $this->title, $secNum );
83
		// Let's hope that this is good enough...
84
		return substr_count( $content, "\n\# *(?![#*])" );
85
	}
86
87
	/**
88
	 * Gets the quorum used for the current page
89
	 *
90
	 * @return int
91
	 */
92
	protected function getQuorum() : int {
93
		$reg = "!soddisfare il \[\[[^|\]]+\|quorum]] di '''(\d+) voti'''!";
94
		$matches = [];
95
		preg_match( $reg, $this->getContent(), $matches );
96
		return intval( $matches[1] );
97
	}
98
99
	/**
100
	 * Whether this page has enough opposing votes
101
	 *
102
	 * @return bool
103
	 */
104
	public function hasOpposition() : bool {
105
		return $this->getOpposingCount() >= 15;
106
	}
107
108
	/**
109
	 * Gets the outcome for the vote
110
	 *
111
	 * @return int One of the OUTCOME_* constants
112
	 * @throws \BadMethodCallException
113
	 */
114
	public function getOutcome() : int {
115
		if ( !$this->isVote() ) {
116
			throw new \BadMethodCallException( 'Cannot get outcome for a non-vote page.' );
117
		}
118
		$totalVotes = $this->getOpposingCount() + $this->getSupportCount();
119
		if ( $this->getSupportCount() < $this->getQuorum() ) {
120
			return self::OUTCOME_NO_QUOR;
121
		} elseif ( $this->getSupportCount() < 2 * $totalVotes / 3 ) {
122
			return self::OUTCOME_FAIL_VOTES;
123
		}
124
		return self::OUTCOME_OK;
125
	}
126
127
	/**
128
	 * Get the result text for the page itself
129
	 *
130
	 * @return string
131
	 * @throws \BadMethodCallException
132
	 */
133
	public function getOutcomeText() : string {
134
		if ( !$this->isVote() ) {
135
			throw new \BadMethodCallException( 'No need for an outcome text.' );
136
		}
137
138
		$text = sprintf(
139
			' Con %d voti a favore e %d contrari',
140
			$this->getSupportCount(),
141
			$this->getOpposingCount()
142
		);
143
		$user = $this->getUser();
144
145
		switch ( $this->getOutcome() ) {
146
			case self::OUTCOME_OK:
147
				$text .= " $user viene riconfermato amministratore.";
148
				break;
149
			/** @noinspection PhpMissingBreakStatementInspection */
150
			case self::OUTCOME_NO_QUOR:
151
				$text .= ', non raggiungendo il quorum,';
152
				// Fall through intended
153
			case self::OUTCOME_FAIL:
154
				$text .= " $user non viene riconfermato amministratore";
155
				break;
156
		}
157
		return $text;
158
	}
159
160
	/**
161
	 * Whether this page is a vote
162
	 *
163
	 * @return bool
164
	 */
165
	public function isVote() : bool {
166
		$sectionReg = '/<!-- SEZIONE DA UTILIZZARE PER/';
167
		return preg_match( $sectionReg, $this->getContent() ) === false;
168
	}
169
170
	/**
171
	 * Get the end time
172
	 *
173
	 * @return int
174
	 */
175
	public function getEndTimestamp() : int {
176
		if ( $this->isVote() ) {
177
			$matches = [];
178
			$reg = "!La votazione ha inizio il.+ e ha termine.+ '''([^']+)''' alle ore '''([^']+)'''!";
179
			preg_match( $reg, $this->getContent(), $matches );
180
			list( , $day, $hours ) = $matches;
181
			$day = preg_replace( '![^\d \w]!', '', $day );
182
			return WikiController::getTimestampFromLocalTime( $day . " alle " . $hours );
183
		} else {
184
			$created = $this->controller->getPageCreationTS( $this->title );
185
			return $created + 60 * 60 * 24 * 7;
186
		}
187
	}
188
}
189