Failed Conditions
Pull Request — master (#1851)
by Struan
04:38
created

Alert::prettifyCriteria()   F

Complexity

Conditions 17
Paths 242

Size

Total Lines 74
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 306

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 17
eloc 53
c 1
b 0
f 1
nc 242
nop 3
dl 0
loc 74
ccs 0
cts 0
cp 0
crap 306
rs 3.8583

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace MySociety\TheyWorkForYou\Utility;
4
5
/**
6
 * Alert Utilities
7
 *
8
 * Utility functions related to alerts
9
 */
10
11
class Alert {
12
    public static function sectionToTitle($section) {
13
        $section_map = [
14 3
            "uk" => gettext('All UK'),
15 3
            "debates" => gettext('House of Commons debates'),
16
            "whalls" => gettext('Westminster Hall debates'),
17 3
            "lords" => gettext('House of Lords debates'),
18 3
            "wrans" => gettext('Written answers'),
19
            "wms" => gettext('Written ministerial statements'),
20
            "standing" => gettext('Bill Committees'),
21 3
            "future" => gettext('Future Business'),
22
            "ni" => gettext('Northern Ireland Assembly Debates'),
23
            "scotland" => gettext('All Scotland'),
24
            "sp" => gettext('Scottish Parliament Debates'),
25 3
            "spwrans" => gettext('Scottish Parliament Written answers'),
26 3
            "wales" => gettext('Welsh parliament record'),
27
            "lmqs" => gettext('Questions to the Mayor of London'),
28
        ];
29
30
        return $section_map[$section];
31
    }
32
    public static function detailsToCriteria($details) {
33
        $criteria = [];
34
35
        if (!empty($details['keyword'])) {
36
            $criteria[] = $details['keyword'];
37
        }
38
39
        if (!empty($details['pid'])) {
40
            $criteria[] = 'speaker:' . $details['pid'];
41
        }
42
43
        if (!empty($details['search_section'])) {
44
            $criteria[] = 'section:' . $details['search_section'];
45
        }
46
47
        $criteria = join(' ', $criteria);
48
        return $criteria;
49
    }
50
51
    public static function forUser($email) {
52
        $db = new \ParlDB();
53
        $q = $db->query('SELECT * FROM alerts WHERE email = :email
54
            AND deleted != 1 ORDER BY created', [
55
            ':email' => $email,
56
        ]);
57
58
        $alerts = [];
59
        foreach ($q as $row) {
60
            $criteria = self::prettifyCriteria($row['criteria'], $row['ignore_speaker_votes']);
61
            $parts = self::prettifyCriteria($row['criteria'], $row['ignore_speaker_votes'], true);
62
            $token = $row['alert_id'] . '-' . $row['registrationtoken'];
63
64
            $status = 'confirmed';
65
            if (!$row['confirmed']) {
66
                $status = 'unconfirmed';
67
            } elseif ($row['deleted'] == 2) {
68
                $status = 'suspended';
69
            }
70
71
            $alert = [
72
                'token' => $token,
73
                'status' => $status,
74
                'criteria' => $criteria,
75
                'raw' => $row['criteria'],
76
                'ignore_speaker_votes' => $row['ignore_speaker_votes'],
77
                'keywords' => [],
78
                'exclusions' => [],
79
                'sections' => [],
80
            ];
81
82
            $alert = array_merge($alert, $parts);
83
84
            $alerts[] = $alert;
85
        }
86
87
        return $alerts;
88
    }
89
90
    public static function prettifyCriteria($alert_criteria, $ignore_speaker_votes = false, $as_parts = false) {
91
        $text = '';
92
        $parts = ['words' => [], 'sections' => [], 'exclusions' => [], 'match_all' => true, 'pid' => false];
93
        if ($alert_criteria) {
94
            # check for phrases
95
            if (strpos($alert_criteria, ' OR ') !== false) {
96
                $parts['match_all'] = false;
97
            }
98
            $alert_criteria = str_replace(' OR ', ' ', $alert_criteria);
99
            $alert_criteria = str_replace(['(', ')'], '', $alert_criteria);
100
            if (strpos($alert_criteria, '"') !== false) {
101
                # match phrases
102
                preg_match_all('/"([^"]*)"/', $alert_criteria, $phrases);
103
                # and then remove them from the criteria
104
                $alert_criteria = trim(preg_replace('/ +/', ' ', str_replace($phrases[0], "", $alert_criteria)));
105
106
                # and then create an array with the words and phrases
107
                $criteria = [];
108
                if ($alert_criteria != "") {
109
                    $criteria = explode(' ', $alert_criteria);
110
                }
111
                $criteria = array_merge($criteria, $phrases[1]);
112
            } else {
113
                $criteria = explode(' ', $alert_criteria);
114
            }
115
            $words = [];
116
            $exclusions = [];
117
            $sections = [];
118
            $sections_verbose = [];
119
            $speaker_parts = \MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($alert_criteria);
120
            $pids = array_keys($speaker_parts);
121
            $spokenby = array_values($speaker_parts);
122
123
            if (count($pids) == 1) {
124
                $parts['pid'] = $pids[0];
125
            }
126
127
            foreach ($criteria as $c) {
128
                if (preg_match('#^section:(\w+)#', $c, $m)) {
129
                    $sections[] = $m[1];
130
                    $sections_verbose[] = self::sectionToTitle($m[1]);
131
                } elseif (strpos($c, '-') === 0) {
132
                    $exclusions[] = str_replace('-', '', $c);
133
                } elseif (!preg_match('#^speaker:(\d+)#', $c, $m)) {
134
                    $words[] = $c;
135
                }
136
            }
137
            if ($spokenby && count($words)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $spokenby 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...
138
                $text = implode(' or ', $spokenby) . ' mentions [' . implode(' ', $words) . ']';
139
                $parts['spokenby'] = $spokenby;
140
                $parts['words'] = $words;
141
            } elseif (count($words)) {
142
                $text = '[' . implode(' ', $words) . ']' . ' is mentioned';
143
                $parts['words'] = $words;
144
            } elseif ($spokenby) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $spokenby 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...
145
                $text = implode(' or ', $spokenby) . " speaks";
146
                if ($ignore_speaker_votes) {
147
                    $text .= " excluding votes";
148
                }
149
                $parts['spokenby'] = $spokenby;
150
            }
151
152
            if ($sections) {
153
                $text = $text . " in " . implode(' or ', $sections_verbose);
154
                $parts['sections'] = $sections;
155
                $parts['sections_verbose'] = $sections_verbose;
156
            }
157
158
            $parts['exclusions'] = $exclusions;
159
        }
160
        if ($as_parts) {
161
            return $parts;
162
        }
163
        return $text;
164
    }
165
166
}
167