Failed Conditions
Pull Request — master (#1846)
by Struan
54:09 queued 22:02
created

Alert::prettifyCriteria()   C

Complexity

Conditions 15
Paths 98

Size

Total Lines 65
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 4
Bugs 1 Features 1
Metric Value
cc 15
eloc 47
nc 98
nop 2
dl 0
loc 65
rs 5.9166
c 4
b 1
f 1
ccs 0
cts 0
cp 0
crap 240

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
    #XXX don't calculate this every time
13
    public static function sectionToTitle($section) {
14 3
        $section_map = [
15 3
            "uk" => gettext('All UK'),
16
            "debates" => gettext('House of Commons debates'),
17 3
            "whalls" => gettext('Westminster Hall debates'),
18 3
            "lords" => gettext('House of Lords debates'),
19
            "wrans" => gettext('Written answers'),
20
            "wms" => gettext('Written ministerial statements'),
21 3
            "standing" => gettext('Bill Committees'),
22
            "future" => gettext('Future Business'),
23
            "ni" => gettext('Northern Ireland Assembly Debates'),
24
            "scotland" => gettext('All Scotland'),
25 3
            "sp" => gettext('Scottish Parliament Debates'),
26 3
            "spwrans" => gettext('Scottish Parliament Written answers'),
27
            "wales" => gettext('Welsh parliament record'),
28
            "lmqs" => gettext('Questions to the Mayor of London'),
29
        ];
30
31
        return $section_map[$section];
32
    }
33
    public static function detailsToCriteria($details) {
34
        $criteria = [];
35
36
        if (!empty($details['keyword'])) {
37
            $criteria[] = $details['keyword'];
38
        }
39
40
        if (!empty($details['pid'])) {
41
            $criteria[] = 'speaker:' . $details['pid'];
42
        }
43
44
        if (!empty($details['search_section'])) {
45
            $criteria[] = 'section:' . $details['search_section'];
46
        }
47
48
        $criteria = join(' ', $criteria);
49
        return $criteria;
50
    }
51
52
    public static function forUser($email) {
53
        $db = new \ParlDB();
54
        $q = $db->query('SELECT * FROM alerts WHERE email = :email
55
            AND deleted != 1 ORDER BY created', [
56
            ':email' => $email,
57
        ]);
58
59
        $alerts = [];
60
        foreach ($q as $row) {
61
            $criteria = self::prettifyCriteria($row['criteria']);
62
            $parts = self::prettifyCriteria($row['criteria'], true);
63
            $token = $row['alert_id'] . '-' . $row['registrationtoken'];
64
65
            $status = 'confirmed';
66
            if (!$row['confirmed']) {
67
                $status = 'unconfirmed';
68
            } elseif ($row['deleted'] == 2) {
69
                $status = 'suspended';
70
            }
71
72
            $alert = [
73
                'token' => $token,
74
                'status' => $status,
75
                'criteria' => $criteria,
76
                'raw' => $row['criteria'],
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, $as_parts = false) {
91
        $text = '';
92
        $parts = ['words' => [], 'sections' => [], 'exclusions' => [], 'match_all' => true];
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
            $spokenby = array_values(\MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($alert_criteria));
120
121
            foreach ($criteria as $c) {
122
                if (preg_match('#^section:(\w+)#', $c, $m)) {
123
                    $sections[] = $m[1];
124
                    $sections_verbose[] = self::sectionToTitle($m[1]);
125
                } elseif (strpos($c, '-') === 0) {
126
                    $exclusions[] = str_replace('-', '', $c);
127
                } elseif (!preg_match('#^speaker:(\d+)#', $c, $m)) {
128
                    $words[] = $c;
129
                }
130
            }
131
            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...
132
                $text = implode(' or ', $spokenby) . ' mentions [' . implode(' ', $words) . ']';
133
                $parts['spokenby'] = $spokenby;
134
                $parts['words'] = $words;
135
            } elseif (count($words)) {
136
                $text = '[' . implode(' ', $words) . ']' . ' is mentioned';
137
                $parts['words'] = $words;
138
            } 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...
139
                $text = implode(' or ', $spokenby) . " speaks";
140
                $parts['spokenby'] = $spokenby;
141
            }
142
143
            if ($sections) {
144
                $text = $text . " in " . implode(' or ', $sections_verbose);
145
                $parts['sections'] = $sections;
146
                $parts['sections_verbose'] = $sections_verbose;
147
            }
148
149
            $parts['exclusions'] = $exclusions;
150
        }
151
        if ($as_parts) {
152
            return $parts;
153
        }
154
        return $text;
155
    }
156
157
}
158