Passed
Push — master ( 95d2e4...8875f5 )
by MusikAnimal
05:41
created

RFX::getEndDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * An RFX object contains the parsed information for an RFX
4
 */
5
6
namespace Xtools;
7
8
/**
9
 * This class contains information about a single RfX page.
10
 */
11
class RFX extends Model
12
{
13
    /** @var array Data we parsed out of the page text */
14
    private $data;
15
16
    /** @var array Duplicate voters */
17
    private $duplicates;
18
19
    /** @var null|string Username of the user we're looking for. */
20
    private $userLookingFor;
21
22
    /** @var string Section we found the user we're looking for */
23
    private $userSectionFound;
24
25
    /**
26
     * Attempts to find a signature in $input using the default regex.
27
     * Returns matches.
28
     *
29
     * @param string $input   The line we're looking for
30
     * @param array  $matches Pointer to an array where we stash results
31
     *
32
     * @TODO: Make this cleaner
33
     *
34
     * @return int
35
     */
36
    protected function findSig($input, &$matches)
37
    {
38
        //Supports User: and User talk: wikilinks, {{fullurl}},
39
        // unsubstituted {{unsigned}}, unsubstituted {{unsigned2}},
40
        // anything that looks like a custom sig template
41
        // TODO: Cross-wiki this sucker
42
        $regexp
43
            = //1: Normal [[User:XX]] and [[User talk:XX]]
44
            "/\[\[[Uu]ser(?:[\s_][Tt]alk)?\:([^\]\|\/]*)(?:\|[^\]]*)?\]\]"
45
            //2: {{fullurl}} and {{unsigned}} templates
46
            . "|\{\{(?:[Ff]ullurl\:[Uu]ser(?:[\s_][Tt]alk)?\:|"
47
            . "[Uu]nsigned\|)([^\}\|]*)(?:|[\|\}]*)?\}\}"
48
            //3: {{User:XX/sig}} templates
49
            . "|(?:\{\{)[Uu]ser(?:[\s_][Tt]alk)?\:([^\}\/\|]*)"
50
            //4: {{unsigned2|Date|XX}} templates
51
            . "|\{\{[Uu]nsigned2\|[^\|]*\|([^\}]*)\}\}"
52
            //5: [[User:XX/sig]] links (compromise measure)
53
            . "|(?:\[\[)[Uu]ser\:([^\]\/\|]*)\/[Ss]ig[\|\]]/";
54
55
        return preg_match_all(
56
            $regexp,
57
            $input,
58
            $matches,
59
            PREG_OFFSET_CAPTURE
60
        );
61
    }
62
63
    /**
64
     * This function parses the wikitext and stores it within this function.
65
     * It's been split out to make this class testable
66
     *
67
     * @param array  $sectionArray Section names that we're looking for
68
     * @param string $rawWikiText  The text of the page we're parsing
69
     * @param string $dateRegexp   Valid Regular Expression for the end date
70
     */
71
    private function setUp($sectionArray, $rawWikiText, $dateRegexp)
72
    {
73
        $this->data = [];
74
75
        $lines = explode("\n", $rawWikiText);
76
77
        $keys = join("|", $sectionArray);
78
79
        $lastSection = "";
80
81
        foreach ($lines as $line) {
82
            if (preg_match("/={1,6}\s?($keys)\s?={1,6}/i", $line, $matches)) {
83
                $lastSection = strtolower($matches[1]);
84
            } elseif ($lastSection == ""
85
                && preg_match(
86
                    "/$dateRegexp/i",
87
                    $line,
88
                    $matches
89
                )
90
            ) {
91
                $this->end = $matches[1];
92
            } elseif ($lastSection != ""
93
                && preg_match("/^\s*#?:.*/i", $line) === 0
94
            ) {
95
                $this->findSig($line, $matches);
96
                if (!isset($matches[1][0])) {
97
                    continue;
98
                }
99
                $foundUser = trim($matches[1][0][0]);
100
                $this->data[$lastSection][] = $foundUser;
101
                if (strtolower($foundUser) === strtolower($this->userLookingFor)) {
102
                    $this->userSectionFound = $lastSection;
103
                }
104
            }
105
        }
106
107
        $final = [];    // initialize the final array
108
        $finalRaw = []; // Initialize the raw data array
109
110
        foreach ($this->data as $key => $value) {
111
            $finalRaw = array_merge($finalRaw, $this->data[$key]);
112
        }
113
114
        foreach ($finalRaw as $foundUsername) {
115
            $final[] = $foundUsername; // group all array's elements
116
        }
117
118
        $final = array_count_values($final); // find repetition and its count
119
120
        $final = array_diff($final, [1]);    // remove single occurrences
121
122
        $this->duplicates = array_keys($final);
123
    }
124
125
    /**
126
     * RFX constructor.
127
     *
128
     * @param string      $rawWikiText    The text of the page we're parsing
129
     * @param array       $sectionArray   Section names that we're looking for
130
     * @param string      $userNamespace  Plain text of the user namespace
131
     * @param string      $dateRegexp     Valid Regular Expression for the end date
132
     * @param string|null $userLookingFor User we're trying to find.
133
     */
134
    public function __construct(
135
        $rawWikiText,
136
        $sectionArray = ["Support", "Oppose", "Neutral"],
137
        $userNamespace = "User",
0 ignored issues
show
Unused Code introduced by
The parameter $userNamespace is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

137
        /** @scrutinizer ignore-unused */ $userNamespace = "User",

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
138
        $dateRegexp = "final .*end(?:ing|ed)?(?: no earlier than)? (.*?)? \(UTC\)",
139
        $userLookingFor = null
140
    ) {
141
        $this->userLookingFor = $userLookingFor;
142
143
        $this->setUp($sectionArray, $rawWikiText, $dateRegexp);
144
    }
145
146
    /**
147
     * Which section we found the user we're looking for.
148
     *
149
     * @return string
150
     */
151
    public function getUserSectionFound()
152
    {
153
        return $this->userSectionFound;
154
    }
155
156
    /**
157
     * Returns data on the given section name.
158
     *
159
     * @param string $sectionName The section we're looking at
160
     *
161
     * @return array
162
     */
163
    public function getSection($sectionName)
164
    {
165
        $sectionName = strtolower($sectionName);
166
        if (!isset($this->data[$sectionName])) {
167
            return [];
168
        } else {
169
            return $this->data[$sectionName];
170
        }
171
    }
172
173
    /**
174
     * Get an array of duplicate votes.
175
     *
176
     * @return array
177
     */
178
    public function getDuplicates()
179
    {
180
        return $this->duplicates;
181
    }
182
}
183