Passed
Pull Request — master (#1868)
by
unknown
32:06
created

PolicyDistribution::fromRow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 28
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 29
rs 9.472
1
<?php
2
3
/**
4
 * Party Cohort Class
5
 *
6
 * @package TheyWorkForYou
7
 */
8
9
namespace MySociety\TheyWorkForYou;
10
11
/**
12
 * Policy Distribution
13
 * This contains all the calculated information about the
14
 * number of votes and agreements relevant to the policy
15
 * distribution of a person (or their comparable MPs).
16
 * $is_target is 1 if the person is the target of the comparison,
17
 * 0 if they are the comparison.
18
 */
19
20
class PolicyDistribution {
21
    public int $id;
22
    public int $policy_id;
23
    public int $person_id;
24
    public int $period_id;
25
    public int $chamber_id;
26
    public ?int $party_id;
27
    public int $is_target;
28
    public float $num_votes_same;
29
    public float $num_strong_votes_same;
30
    public float $num_votes_different;
31
    public float $num_strong_votes_different;
32
    public float $num_votes_absent;
33
    public float $num_strong_votes_absent;
34
    public float $num_votes_abstain;
35
    public float $num_strong_votes_abstain;
36
    public float $num_agreements_same;
37
    public float $num_strong_agreements_same;
38
    public float $num_agreements_different;
39
    public float $num_strong_agreements_different;
40
    public int $start_year;
41
    public int $end_year;
42
    public float $distance_score;
43
    public string $party_slug;
44
    public string $period_slug;
45
    public string $party_name;
46
    public string $period_description;
47
48
    public function totalVotes(): float {
49
        return $this->num_votes_same + $this->num_votes_different + $this->num_strong_votes_same + $this->num_strong_votes_different;
50
    }
51
52
    public function getVerboseScoreLower(): string {
53
        $verbose_score = $this->getVerboseScore();
54
        return strtolower($verbose_score);
55
    }
56
57
    public function noDataAvailable(): bool {
58
        return $this->distance_score == -1;
59
    }
60
61
    public function getVerboseScore(): string {
62
        if ($this->distance_score >= 0 && $this->distance_score <= 0.05) {
63
            return "Consistently voted for";
64
        } elseif ($this->distance_score > 0.05 && $this->distance_score <= 0.15) {
65
            return "Almost always voted for";
66
        } elseif ($this->distance_score > 0.15 && $this->distance_score <= 0.4) {
67
            return "Generally voted for";
68
        } elseif ($this->distance_score > 0.4 && $this->distance_score <= 0.6) {
69
            return "Voted a mixture of for and against";
70
        } elseif ($this->distance_score > 0.6 && $this->distance_score <= 0.85) {
71
            return "Generally voted against";
72
        } elseif ($this->distance_score > 0.85 && $this->distance_score <= 0.95) {
73
            return "Almost always voted against";
74
        } elseif ($this->distance_score > 0.95 && $this->distance_score <= 1) {
75
            return "Consistently voted against";
76
        } elseif ($this->distance_score == -1) {
77
            return "No data available";
78
        } else {
79
            throw new \InvalidArgumentException("Score must be between 0 and 1");
80
        }
81
    }
82
83
    /**
84
     * Retrieves the policy distributions for a specific person, party, period, and chamber.
85
     *
86
     * @param int $person_id The ID of the person.
87
     * @param string $party_slug The slug of the party.
88
     * @param string $period_slug The slug of the period.
89
     * @param int $house The ID of the house (default is HOUSE_TYPE_COMMONS).
90
     * @return PolicyDistribution[] An array of PolicyDistribution objects.
91
     */
92
    public static function getPersonDistributions(int $person_id, string $party_slug, string $period_slug, int $house = HOUSE_TYPE_COMMONS): array {
93
94
        $db = new \ParlDB();
95
        // need to join to policyorganisationsto get the party_id
96
        // need to join to policycomparisonperiod to get slug to id
97
        $sql = "SELECT
98
                    pd.*,
99
                    po.slug as party_slug,
100
                    po.name as party_name,
101
                    pp.slug as period_slug,
102
                    pp.description as period_description
103
                FROM policyvotedistribution pd
104
                JOIN policycomparisonperiod pp ON pd.period_id = pp.id
105
                JOIN policyorganization po ON pd.party_id = po.id
106
                WHERE pd.person_id = :person_id
107
                AND po.slug = :party_slug
108
                AND pp.slug = :period_slug
109
                AND pd.chamber_id = :house
110
                AND pp.chamber_id = :house
111
                ";
112
113
        $params = ['person_id' => $person_id,
114
            'party_slug' => $party_slug,
115
            'period_slug' => $period_slug,
116
            'house' => $house];
117
118
        $rows = $db->query($sql, $params);
119
120
        $distributions = [];
121
        foreach ($rows as $row) {
122
            $distributions[] = self::fromRow($row);
123
        }
124
        return $distributions;
125
    }
126
127
    public static function fromRow(array $row): PolicyDistribution {
128
        $pd = new PolicyDistribution();
129
        $pd->id = (int) $row['id'];
130
        $pd->policy_id = (int) $row['policy_id'];
131
        $pd->person_id = (int) $row['person_id'];
132
        $pd->period_id = (int) $row['period_id'];
133
        $pd->chamber_id = (int) $row['chamber_id'];
134
        $pd->party_id = (int) $row['party_id'];
135
        $pd->is_target = (int) $row['is_target'];
136
        $pd->num_votes_same = (float) $row['num_votes_same'];
137
        $pd->num_strong_votes_same = (float) $row['num_strong_votes_same'];
138
        $pd->num_votes_different = (float) $row['num_votes_different'];
139
        $pd->num_strong_votes_different = (float) $row['num_strong_votes_different'];
140
        $pd->num_votes_absent = (float) $row['num_votes_absent'];
141
        $pd->num_strong_votes_absent = (float) $row['num_strong_votes_absent'];
142
        $pd->num_votes_abstain = (float) $row['num_votes_abstain'];
143
        $pd->num_strong_votes_abstain = (float) $row['num_strong_votes_abstain'];
144
        $pd->num_agreements_same = (float) $row['num_agreements_same'];
145
        $pd->num_strong_agreements_same = (float) $row['num_strong_agreements_same'];
146
        $pd->num_agreements_different = (float) $row['num_agreements_different'];
147
        $pd->num_strong_agreements_different = (float) $row['num_strong_agreements_different'];
148
        $pd->start_year = (int) $row['start_year'];
149
        $pd->end_year = (int) $row['end_year'];
150
        $pd->distance_score = (float) $row['distance_score'];
151
        $pd->party_slug = $row['party_slug'];
152
        $pd->period_slug = $row['period_slug'];
153
        $pd->party_name = $row['party_name'];
154
        $pd->period_description = $row['period_description'];
155
        return $pd;
156
    }
157
}
158