memberships()   F
last analyzed

Complexity

Conditions 16
Paths 576

Size

Total Lines 57
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 16
eloc 34
c 2
b 0
f 0
nc 576
nop 1
dl 0
loc 57
rs 1.9888

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
/*
4
 * index.php
5
 *
6
 * For displaying info about a person for a postcode or constituency.
7
 *
8
 * This page accepts either 'm' (a member_id), 'pid' (a person_id),
9
 * 'c' (a postcode or constituency), or 'n' (a name).
10
 *
11
 * First, we check to see if a person_id's been submitted.
12
 * If so, we display that person.
13
 *
14
 * Else, we check to see if a member_id's been submitted.
15
 * If so, we display that person.
16
 *
17
 * Otherwise, we then check to see if a postcode's been submitted.
18
 * If it's valid we put it in a cookie.
19
 *
20
 * If no postcode, we check to see if a constituency's been submitted.
21
 *
22
 * If neither has been submitted, we see if either the user is logged in
23
 * and has a postcode set or the user has a cookied postcode from a previous
24
 * search.
25
 *
26
 * If we have a valid constituency after all this, we display its MP.
27
 *
28
 * Either way, we print the forms.
29
 */
30
31
// Disable the old PAGE class.
32
33
use MySociety\TheyWorkForYou\PolicyDistributionCollection;
34
use MySociety\TheyWorkForYou\PolicyComparisonPeriod;
35
36
$new_style_template = true;
37
38
// Include all the things this page needs.
39
include_once '../../includes/easyparliament/init.php';
40
include_once INCLUDESPATH . 'easyparliament/member.php';
41
include_once INCLUDESPATH . '../../commonlib/phplib/random.php';
42
include_once INCLUDESPATH . '../../commonlib/phplib/auth.php';
43
include_once '../api/api_getGeometry.php';
44
include_once '../api/api_getConstituencies.php';
45
46
// Ensure that page type is set
47
$allowed_page_types = ['divisions', 'votes', 'policy_set_svg', 'policy_set_png', 'recent', 'register', 'election_register', 'memberships', 'signatures', 'constituency', 'speeches'];
48
49
if (get_http_var('pagetype')) {
50
    $pagetype = get_http_var('pagetype');
51
} else {
52
    $pagetype = 'profile';
53
}
54
if (!in_array($pagetype, $allowed_page_types)) {
55
    $pagetype = 'profile';
56
}
57
if ($pagetype == 'profile') {
58
    $pagetype = '';
59
}
60
61
// list of years for which we have WTT response stats in
62
// reverse chronological order. Add new years here as we
63
// get them.
64
// NB: also need to update ./mpinfoin.pl to import the stats
65
$wtt_stats_years = [2015, 2014, 2013, 2008, 2007, 2006, 2005];
66
67
// Set the PID, name and constituency.
68
$pid = get_http_var('pid') != '' ? get_http_var('pid') : get_http_var('p');
69
$name = strtolower(str_replace('_', ' ', get_http_var('n')));
70
$constituency = strtolower(str_replace('_', ' ', get_http_var('c')));
71
72
// Fix for names with non-ASCII characters
73
if ($name == 'sion simon') {
74
    $name = 'si\xf4n simon';
75
}
76
if ($name == 'sian james') {
77
    $name = 'si\xe2n james';
78
}
79
if ($name == 'lembit opik') {
80
    $name = 'lembit \xf6pik';
81
}
82
if ($name == 'bairbre de brun') {
83
    $name = 'bairbre de br\xfan';
84
}
85
if ($name == 'daithi mckay') {
86
    $name = 'daith\xed mckay';
87
}
88
if ($name == 'caral ni chuilin') {
89
    $name = 'car\xe1l n\xed chuil\xedn';
90
}
91
if ($name == 'caledon du pre') {
92
    $name = 'caledon du pr\xe9';
93
}
94
if ($name == 'sean etchingham') {
95
    $name = 'se\xe1n etchingham';
96
}
97
if ($name == 'john tinne') {
98
    $name = 'john tinn\xe9';
99
}
100
if ($name == 'renee short') {
101
    $name = 'ren\xe9e short';
102
}
103
104
// Fix for common misspellings, name changes etc
105
$name_fix = [
106
    'a j beith' => 'alan beith',
107
    'micky brady' => 'mickey brady',
108
    'daniel rogerson' => 'dan rogerson',
109
    'andrew slaughter' => 'andy slaughter',
110
    'robert wilson' => ['rob wilson', 'reading east'],
111
    'james mcgovern' => 'jim mcgovern',
112
    'patrick mcfadden' => 'pat mcfadden',
113
    'chris leslie' => 'christopher leslie',
114
    'joseph meale' => 'alan meale',
115
    'james sheridan' => 'jim sheridan',
116
    'chinyelu onwurah' => 'chi onwurah',
117
    'steve rotherham' => 'steve rotheram',
118
    'michael weatherley' => 'mike weatherley',
119
    'louise bagshawe' => 'louise mensch',
120
    'andrew sawford' => 'andy sawford',
121
];
122
123
if (array_key_exists($name, $name_fix)) {
124
    if (is_array($name_fix[$name])) {
125
        if ($constituency == $name_fix[$name][1]) {
126
            $name = $name_fix[$name][0];
127
        }
128
    } else {
129
        $name = $name_fix[$name];
130
    }
131
}
132
133
// Fixes for Ynys Mon, and a Unicode URL
134
if ($constituency == 'ynys mon') {
135
    $constituency = "ynys m\xf4n";
136
}
137
if (preg_match("#^ynys m\xc3\xb4n#i", $constituency)) {
138
    $constituency = "ynys m\xf4n";
139
}
140
141
// If this is a request for recent appearances, redirect to search results
142
if (get_http_var('recent')) {
143
    if ($THEUSER->postcode_is_set() && !$pid) {
144
        $MEMBER = new MySociety\TheyWorkForYou\Member(['postcode' => $THEUSER->postcode(), 'house' => HOUSE_TYPE_COMMONS]);
145
        if ($MEMBER->person_id()) {
146
            $pid = $MEMBER->person_id();
147
        }
148
    }
149
    if ($pid) {
150
        $URL = new \MySociety\TheyWorkForYou\Url('search');
151
        $URL->insert(['pid' => $pid, 'pop' => 1]);
152
        header('Location: ' . $URL->generate('none'));
153
        exit;
154
    }
155
}
156
157
/////////////////////////////////////////////////////////
158
// DETERMINE TYPE OF REPRESENTITIVE
159
160
switch (get_http_var('representative_type')) {
161
    case 'peer':
162
        $this_page = 'peer';
163
        break;
164
    case 'royal':
165
        $this_page = 'royal';
166
        break;
167
    case 'mla':
168
        $this_page = 'mla';
169
        break;
170
    case 'msp':
171
        $this_page = 'msp';
172
        break;
173
    case 'ms':
174
        $this_page = 'ms';
175
        break;
176
    case 'london-assembly-member':
177
        $this_page = 'london-assembly-member';
178
        break;
179
    default:
180
        $this_page = 'mp';
181
        break;
182
}
183
184
try {
185
    if (is_numeric($pid)) {
186
        $MEMBER = get_person_by_id($pid);
187
    } elseif (is_numeric(get_http_var('m'))) {
188
        get_person_by_member_id(get_http_var('m'));
189
    } elseif (get_http_var('pc')) {
190
        get_person_by_postcode(get_http_var('pc'));
191
    } elseif ($name) {
192
        $MEMBER = get_person_by_name($name, $constituency);
193
    } elseif ($constituency) {
194
        get_mp_by_constituency($constituency);
195
    } elseif (($this_page == 'msp' || $this_page == 'mla' || $this_page == 'ms') && $THEUSER->postcode_is_set()) {
196
        get_regional_by_user_postcode($THEUSER->postcode(), $this_page);
197
        exit;
198
    } elseif ($THEUSER->postcode_is_set()) {
199
        get_mp_by_user_postcode($THEUSER->postcode());
200
    } else {
201
        twfy_debug('MP', "We don't have any way of telling what MP to display");
202
        throw new MySociety\TheyWorkForYou\MemberException(gettext('Sorry, but we can’t tell which representative to display.'));
203
    }
204
    if (!isset($MEMBER) || !$MEMBER->valid) {
205
        throw new MySociety\TheyWorkForYou\MemberException(gettext('You haven’t provided a way of identifying which representative you want'));
206
    }
207
} catch (MySociety\TheyWorkForYou\MemberMultipleException $e) {
208
    person_list_page($e->ids);
209
    exit;
210
} catch (MySociety\TheyWorkForYou\MemberException $e) {
211
    person_error_page($e->getMessage());
212
    exit;
213
}
214
215
# We have successfully looked up one person to show now.
216
217
if (!DEVSITE) {
218
    header('Cache-Control: max-age=900');
219
}
220
221
twfy_debug_timestamp("before load_extra_info");
222
$MEMBER->load_extra_info(true);
223
twfy_debug_timestamp("after load_extra_info");
224
225
// Basic name, title and description
226
$member_name = ucfirst($MEMBER->full_name());
227
$title = $member_name;
228
$desc = "Read $member_name's contributions to Parliament, including speeches and questions";
229
230
// Enhance description if this is a current member
231
if ($MEMBER->current_member_anywhere()) {
232
    $desc .= ', investigate their voting record, and get email alerts on their activity';
233
}
234
235
// Enhance title if this is a member of the Commons
236
if ($MEMBER->house(HOUSE_TYPE_COMMONS)) {
237
    if (!$MEMBER->current_member(1)) {
238
        $title .= ', former';
239
    }
240
    $title .= ' MP';
241
    if ($MEMBER->constituency()) {
242
        $title .= ', ' . $MEMBER->constituency();
243
    }
244
}
245
246
// Enhance title if this is a member of NIA
247
if ($MEMBER->house(HOUSE_TYPE_NI)) {
248
    if ($MEMBER->house(HOUSE_TYPE_COMMONS) || $MEMBER->house(HOUSE_TYPE_LORDS)) {
249
        $desc = str_replace('Parliament', 'Parliament and the Northern Ireland Assembly', $desc);
250
    } else {
251
        $desc = str_replace('Parliament', 'the Northern Ireland Assembly', $desc);
252
    }
253
    if (!$MEMBER->current_member(HOUSE_TYPE_NI)) {
254
        $title .= ', former';
255
    }
256
    $title .= ' MLA';
257
    if ($MEMBER->constituency()) {
258
        $title .= ', ' . $MEMBER->constituency();
259
    }
260
}
261
262
// Enhance title if this is a member of Scottish Parliament
263
if ($MEMBER->house(HOUSE_TYPE_SCOTLAND)) {
264
    if ($MEMBER->house(HOUSE_TYPE_COMMONS) || $MEMBER->house(HOUSE_TYPE_LORDS)) {
265
        $desc = str_replace('Parliament', 'the UK and Scottish Parliaments', $desc);
266
    } else {
267
        $desc = str_replace('Parliament', 'the Scottish Parliament', $desc);
268
    }
269
    $desc = str_replace(', and get email alerts on their activity', '', $desc);
270
    if (!$MEMBER->current_member(HOUSE_TYPE_SCOTLAND)) {
271
        $title .= ', former';
272
    }
273
    $title .= ' MSP, ' . $MEMBER->constituency();
274
}
275
276
// Enhance title if this is a member of Welsh Parliament
277
if ($MEMBER->house(HOUSE_TYPE_WALES)) {
278
    if ($MEMBER->house(HOUSE_TYPE_COMMONS) || $MEMBER->house(HOUSE_TYPE_LORDS)) {
279
        $desc = str_replace('Parliament', 'the UK and Welsh Parliaments', $desc);
280
    } else {
281
        $desc = str_replace('Parliament', 'the Senedd', $desc);
282
    }
283
    $desc = str_replace(', and get email alerts on their activity', '', $desc);
284
    if (!$MEMBER->current_member(HOUSE_TYPE_WALES)) {
285
        $title .= ', former';
286
    }
287
    $title .= ' MS, ' . $MEMBER->constituency();
288
}
289
290
$known_for = '';
291
$current_offices_ignoring_committees = $MEMBER->offices('current', true);
292
if (count($current_offices_ignoring_committees) > 0) {
293
    $known_for = $current_offices_ignoring_committees[0];
294
}
295
296
// Finally, if this is a Votes page, replace the page description with
297
// something more descriptive of the actual data on the page.
298
if ($pagetype == 'votes') {
299
    $title = "Voting record - " . $title;
300
    $desc = 'See how ' . $member_name . ' voted on topics like Employment, Social Issues, Foreign Policy, and more.';
301
}
302
303
// If this is a Speeches page, update title and description
304
if ($pagetype == 'speeches') {
305
    $title = "Speeches and Questions - " . $title;
306
    $desc = 'Read ' . $member_name . "'s most recent speeches and parliamentary questions.";
307
}
308
309
// Set page metadata
310
$DATA->set_page_metadata($this_page, 'title', $title);
311
$DATA->set_page_metadata($this_page, 'meta_description', $desc);
312
313
// Build the RSS link and add it to page data.
314
$feedurl = $DATA->page_metadata('mp_rss', 'url') . $MEMBER->person_id() . '.rdf';
315
if (file_exists(BASEDIR . '/' . $feedurl)) {
316
    $DATA->set_page_metadata($this_page, 'rss', $feedurl);
317
}
318
319
// Prepare data for the template
320
$data["pagetype"] = $pagetype;
321
$data['full_name'] = $MEMBER->full_name();
322
$data['person_id'] = $MEMBER->person_id();
323
$data['member_id'] = $MEMBER->member_id();
324
325
$data['known_for'] = $known_for;
326
$data['latest_membership'] = $MEMBER->getMostRecentMembership();
327
328
$data['constituency'] = $MEMBER->constituency();
329
$data['party'] = $MEMBER->party_text();
330
$data['current_party_comparison'] = $MEMBER->currentPartyComparison();
331
$data['current_member_anywhere'] = $MEMBER->current_member_anywhere();
332
$data['current_member'] = $MEMBER->current_member();
333
$data['the_users_mp'] = $MEMBER->the_users_mp();
334
$data['user_postcode'] = $THEUSER->postcode;
335
$data['houses'] = $MEMBER->houses();
336
$data['member_url'] = $MEMBER->url();
337
$data['abs_member_url'] = $MEMBER->url(true);
338
// If there's photo attribution information, copy it into data
339
foreach (['photo_attribution_text', 'photo_attribution_link'] as $key) {
340
    if (isset($MEMBER->extra_info[$key])) {
341
        $data[$key] = $MEMBER->extra_info[$key];
342
    }
343
}
344
$data['profile_message'] = $MEMBER->extra_info['profile_message'] ?? '';
345
$data['image'] = $MEMBER->image();
346
$data['member_summary'] = person_summary_description($MEMBER);
347
$data['enter_leave'] = $MEMBER->getEnterLeaveStrings();
348
$data['entry_date'] = $MEMBER->getEntryDate(HOUSE_TYPE_COMMONS);
349
$data['leave_date'] = $MEMBER->getLeftDate(HOUSE_TYPE_COMMONS);
350
$data['is_new_mp'] = $MEMBER->isNew();
351
$data['other_parties'] = $MEMBER->getOtherPartiesString();
352
$data['other_constituencies'] = $MEMBER->getOtherConstituenciesString();
353
$data['rebellion_rate'] = person_rebellion_rate($MEMBER);
354
$data['recent_appearances'] = person_recent_appearances($MEMBER);
355
$data['useful_links'] = person_useful_links($MEMBER);
356
$data['social_links'] = person_social_links($MEMBER);
357
$data['current_offices'] = $MEMBER->offices('current', true);
358
$data['previous_offices'] = $MEMBER->offices('previous', true);
359
$data['register_interests'] = person_register_interests($MEMBER, $MEMBER->extra_info);
360
$data['register_2024_enriched'] = person_register_interests_from_key('person_regmem_enriched2024_en', $MEMBER->extra_info);
361
$data['standing_down_2024'] = $MEMBER->extra_info['standing_down_2024'] ?? '';
362
$data['memberships'] = memberships($MEMBER);
363
$data['whip_removal_info'] = $MEMBER->getWhipRemovalInfo();
364
365
# People who are or were MPs and Lords potentially have voting records, except Sinn Fein MPs
366
$data['has_voting_record'] = (($MEMBER->house(HOUSE_TYPE_COMMONS) && $MEMBER->party() != 'Sinn Féin') || $MEMBER->house(HOUSE_TYPE_LORDS));
367
# Everyone who is currently somewhere has email alert signup, apart from current Sinn Fein MPs who are not MLAs
368
$data['has_email_alerts'] = ($MEMBER->current_member_anywhere() && !($MEMBER->current_member(HOUSE_TYPE_COMMONS) && $MEMBER->party() == 'Sinn Féin' && !$MEMBER->current_member(HOUSE_TYPE_NI)));
369
$data['has_expenses'] = $data['leave_date'] > '2004-01-01';
370
371
$data['pre_2010_expenses'] = false;
372
$data['post_2010_expenses'] = $data['leave_date'] > '2010-05-05' ? ($MEMBER->extra_info['datadotparl_id'] ?? '') : '';
373
374
if ($data['entry_date'] < '2010-05-05') {
375
    $data['pre_2010_expenses'] = true;
376
    // Set the expenses URL if we know it
377
    $data['expenses_url_2004'] = $MEMBER->extra_info['expenses_url'] ?? 'https://mpsallowances.parliament.uk/mpslordsandoffices/hocallowances/allowances%2Dby%2Dmp/';
378
}
379
380
$data['constituency_previous_mps'] = constituency_previous_mps($MEMBER);
381
$data['constituency_future_mps'] = constituency_future_mps($MEMBER);
382
$data['public_bill_committees'] = person_pbc_membership($MEMBER);
383
384
$data['this_page'] = $this_page;
385
$country = MySociety\TheyWorkForYou\Utility\House::getCountryDetails($data['latest_membership']['house']);
386
$data['current_assembly'] = $country[2];
387
388
$data['policy_last_update'] = MySociety\TheyWorkForYou\Divisions::getMostRecentDivisionDate();
389
390
$data['comparison_party'] = $MEMBER->cohortParty();
391
$data['unslugified_comparison_party'] = ucwords(str_replace('-', ' ', $data['comparison_party']));
392
393
// is the party we're comparing this MP to different from the party they're currently in?
394
$data['party_switcher'] = (slugify($data['current_party_comparison']) != slugify($data["comparison_party"]));
395
396
// Update the social image URL generation logic
397
switch ($pagetype) {
398
    case 'votes':
399
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Voting Summaries', $data['current_assembly']);
400
        $policy_set = get_http_var('policy');
401
402
        $policiesList = new MySociety\TheyWorkForYou\Policies();
403
        $divisions = new MySociety\TheyWorkForYou\Divisions($MEMBER);
404
        // Generate voting segments
405
        $set_descriptions = $policiesList->getSetDescriptions();
406
        if ($policy_set && array_key_exists($policy_set, $set_descriptions)) {
407
            $sets = [$policy_set];
408
            $data['page_title'] = $set_descriptions[$policy_set] . ' ' . $title . ' - TheyWorkForYou';
409
            $data['meta_description'] = 'See how ' . $data['full_name'] . ' voted on ' . $set_descriptions[$policy_set];
410
            $data['single_policy_page'] = true;
411
        } else {
412
            $data['single_policy_page'] = false;
413
            $sets = [
414
                'social', 'foreignpolicy', 'welfare', 'taxation', 'business',
415
                'health', 'education', 'reform', 'home', 'environment',
416
                'transport', 'housing', 'justice', 'misc',
417
            ];
418
            $sets = array_filter($sets, function ($v) use ($set_descriptions) {
419
                return array_key_exists($v, $set_descriptions);
420
            });
421
            shuffle($sets);
422
        }
423
        $house = HOUSE_TYPE_COMMONS;
424
        $party = new MySociety\TheyWorkForYou\Party($MEMBER->party());
425
        $voting_comparison_period_slug = get_http_var('comparison_period') ?: 'all_time';
426
        try {
427
            $voting_comparison_period = new PolicyComparisonPeriod($voting_comparison_period_slug, $house);
428
        } catch (\Exception $e) {
429
            member_redirect($MEMBER, 302, 'votes');
430
        }
431
        $cohort_party = $MEMBER->cohortParty();
432
433
        // this comes up if the votes page is being accessed for an old MP/Lord without party information.
434
        // by definition, not covered by our voting comparisons so just return an empty array.
435
        if ($cohort_party == null) {
436
            $data['key_votes_segments'] = [];
437
        } else {
438
            $data['key_votes_segments'] = PolicyDistributionCollection::getPersonDistributions($sets, $MEMBER->person_id(), $cohort_party, $voting_comparison_period->slug, $house);
439
        }
440
441
        $data['free_votes'] = $policiesList->getPoliciesWithFreeVote();
442
        $data["comparison_period"] = $voting_comparison_period;
443
        $data['available_periods'] = PolicyComparisonPeriod::getComparisonPeriodsForPerson($MEMBER->person_id(), $house);
444
        // shuffle the key_votes_segments for a random order
445
        shuffle($data['key_votes_segments']);
446
        $data["sig_diff_policy"] = PolicyDistributionCollection::getSignificantDistributions($data['key_votes_segments']);
447
        $data['party_member_count'] = $party->getCurrentMemberCount($house);
448
449
        // Send the output for rendering
450
        MySociety\TheyWorkForYou\Renderer::output('mp/votes', $data);
451
452
        break;
453
454
    case 'recent':
455
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Recent Votes', $data['current_assembly']);
456
        $divisions = new MySociety\TheyWorkForYou\Divisions($MEMBER);
457
        $data['divisions'] = $divisions->getRecentMemberDivisions();
458
        MySociety\TheyWorkForYou\Renderer::output('mp/recent', $data);
459
        break;
460
461
    case 'memberships':
462
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Committees and Memberships', $data['current_assembly']);
463
        MySociety\TheyWorkForYou\Renderer::output('mp/memberships', $data);
464
        break;
465
466
    case 'signatures':
467
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Signatures', $data['current_assembly']);
468
        MySociety\TheyWorkForYou\Renderer::output('mp/signatures', $data);
469
        break;
470
471
    case 'speeches':
472
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Speeches and Questions', $data['current_assembly']);
473
        MySociety\TheyWorkForYou\Renderer::output('mp/speeches', $data);
474
        break;
475
476
    case 'constituency':
477
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Constituency Information', $data['current_assembly']);
478
        MySociety\TheyWorkForYou\Renderer::output('mp/constituency', $data);
479
        break;
480
481
    case 'election_register':
482
        // Send the output for rendering
483
484
        $memcache = new \MySociety\TheyWorkForYou\Memcache();
485
        $mem_key = "highlighted_interests" . $MEMBER->person_id();
486
487
        $highlighted_for_this_mp = $memcache->get($mem_key);
488
489
        if (!$highlighted_for_this_mp) {
0 ignored issues
show
introduced by
The condition $highlighted_for_this_mp is always false.
Loading history...
490
            $highlighted_register = MySociety\TheyWorkForYou\DataClass\Regmem\Register::getMisc("highlighted_interests.json");
491
            $str_id = "uk.org.publicwhip/person/" . $MEMBER->person_id();
492
            $highlighted_for_this_mp = $highlighted_register->getPersonFromId($str_id);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $highlighted_for_this_mp is correct as $highlighted_register->getPersonFromId($str_id) targeting MySociety\TheyWorkForYou...ster::getPersonFromId() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
493
            $memcache->set($mem_key, $highlighted_for_this_mp, 60 * 60 * 24);
494
        }
495
496
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Election Register', $data['current_assembly']);
497
        $data['mp_has_highlighted_interests'] = (bool) $highlighted_for_this_mp;
498
        $overlapping_interests = [];
499
500
        MySociety\TheyWorkForYou\Renderer::output('mp/election_register', $data);
501
502
        // no break
503
    case 'register':
504
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Register of Interests', $data['current_assembly']);
505
        // Send the output for rendering
506
        MySociety\TheyWorkForYou\Renderer::output('mp/register', $data);
507
508
        // no break
509
    case '':
510
    default:
511
        $data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Profile', $data['current_assembly']);
512
        // if extra detail needed for overview page in future
513
514
        // Send the output for rendering
515
        MySociety\TheyWorkForYou\Renderer::output('mp/profile', $data);
516
517
        break;
518
519
}
520
521
522
/////////////////////////////////////////////////////////
523
// SUPPORTING FUNCTIONS
524
525
/* Person lookup functions */
526
527
function get_person_by_id($pid) {
528
    global $pagetype, $this_page;
529
    $MEMBER = new MySociety\TheyWorkForYou\Member(['person_id' => $pid]);
530
    if (!$MEMBER->valid) {
531
        throw new MySociety\TheyWorkForYou\MemberException('Sorry, that ID number wasn&rsquo;t recognised.');
532
    }
533
    // Ensure that we're actually at the current, correct and canonical URL for the person. If not, redirect.
534
    // No need to worry about other URL syntax forms for vote pages, they shouldn't happen.
535
    $at = str_replace('/mp/', "/$this_page/", get_http_var('url'));
536
    $shouldbe = urldecode($MEMBER->url());
537
    if ($pagetype) {
538
        $shouldbe .= "/$pagetype";
539
    }
540
    if ($at !== $shouldbe) {
541
        member_redirect($MEMBER, 301, $pagetype);
542
    }
543
    return $MEMBER;
544
}
545
546
function get_person_by_member_id($member_id) {
547
    // Got a member id, redirect to the canonical MP page, with a person id.
548
    $MEMBER = new MySociety\TheyWorkForYou\Member(['member_id' => $member_id]);
549
    member_redirect($MEMBER);
550
}
551
552
function get_person_by_postcode($pc) {
553
    global $THEUSER;
554
    $pc = preg_replace('#[^a-z0-9]#i', '', $pc);
555
    if (!validate_postcode($pc)) {
556
        twfy_debug('MP', "Can't display an MP because the submitted postcode wasn't of a valid form.");
557
        throw new MySociety\TheyWorkForYou\MemberException(sprintf(gettext('Sorry, %s isn’t a valid postcode'), _htmlentities($pc)));
558
    }
559
    twfy_debug('MP', "MP lookup by postcode");
560
    $constituency = strtolower(MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituency($pc));
561
    if ($constituency == "connection_timed_out") {
562
        throw new MySociety\TheyWorkForYou\MemberException(gettext('Sorry, we couldn’t check your postcode right now, as our postcode lookup server is under quite a lot of load.'));
563
    } elseif ($constituency == "") {
564
        twfy_debug('MP', "Can't display an MP, as submitted postcode didn't match a constituency");
565
        throw new MySociety\TheyWorkForYou\MemberException(sprintf(gettext('Sorry, %s isn’t a known postcode'), _htmlentities($pc)));
566
    } else {
567
        // Redirect to the canonical MP page, with a person id.
568
        $MEMBER = new MySociety\TheyWorkForYou\Member(['constituency' => $constituency, 'house' => HOUSE_TYPE_COMMONS]);
569
        if ($MEMBER->person_id()) {
570
            // This will cookie the postcode.
571
            $THEUSER->set_postcode_cookie($pc);
572
        }
573
        member_redirect($MEMBER, 302);
574
    }
575
}
576
577
function get_person_by_name($name, $const = '') {
578
    $MEMBER = new MySociety\TheyWorkForYou\Member(['name' => $name, 'constituency' => $const]);
579
    // Edge case, only attempt further detection if this isn't the Queen.
580
    if (($name !== 'elizabeth the second' && $name !== 'prince charles') || $const) {
581
        twfy_debug('MP', 'Redirecting for MP found by name/constituency');
582
        member_redirect($MEMBER);
583
    }
584
    return $MEMBER;
585
}
586
587
function get_mp_by_constituency($constituency) {
588
    $MEMBER = new MySociety\TheyWorkForYou\Member(['constituency' => $constituency, 'house' => HOUSE_TYPE_COMMONS]);
589
    member_redirect($MEMBER);
590
}
591
592
function get_regional_by_user_postcode($pc, $page) {
593
    global $this_page;
594
    $this_page = "your$page";
595
    $areas = \MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($pc);
596
    if ($page == 'msp' && isset($areas['SPC'])) {
597
        regional_list($pc, 'SPC', $page);
598
    } elseif ($page == 'ms' && isset($areas['WAC'])) {
599
        regional_list($pc, 'WAC', $page);
600
    } elseif ($page == 'mla' && isset($areas['NIE'])) {
601
        regional_list($pc, 'NIE', $page);
602
    } else {
603
        throw new MySociety\TheyWorkForYou\MemberException('Your set postcode is not in the right region.');
604
    }
605
}
606
607
function get_mp_by_user_postcode($pc) {
608
    $MEMBER = new MySociety\TheyWorkForYou\Member(['postcode' => $pc, 'house' => HOUSE_TYPE_COMMONS]);
609
    member_redirect($MEMBER, 302);
610
}
611
612
/**
613
 * Member Redirect
614
 *
615
 * Redirect to the canonical page for a member.
616
 */
617
618
function member_redirect(&$MEMBER, $code = 301, $pagetype = null) {
619
    // We come here after creating a MEMBER object by various methods.
620
    // Now we redirect to the canonical MP page, with a person_id.
621
    if ($MEMBER->person_id()) {
622
        $url = $MEMBER->url();
623
        $params = [];
624
        foreach ($_GET as $key => $value) {
625
            if (substr($key, 0, 4) == 'utm_' || $key == 'gclid') {
626
                $params[] = urlencode($key) . "=" . urlencode($value);
627
            }
628
        }
629
        if ($pagetype) {
630
            $url .= '/' . $pagetype;
631
        }
632
        if (count($params)) {
633
            $url .= '?' . join('&', $params);
634
        }
635
        header('Location: ' . $url, true, $code);
636
        exit;
637
    }
638
}
639
640
/* Error list page */
641
642
function person_list_page($ids) {
643
    global $name;
644
    if (!DEVSITE) {
645
        header('Cache-Control: max-age=900');
646
    }
647
    $data = ['mps' => []];
648
    foreach ($ids as $id => $constituency) {
649
        $data['mps'][] = [
650
            'url'  => WEBPATH . 'mp/?pid=' . $id,
651
            'name' => ucwords(strtolower($name)) . ', ' . $constituency,
652
        ];
653
    }
654
    $MPSURL = new \MySociety\TheyWorkForYou\Url('mps');
655
    $data['all_mps_url'] = $MPSURL->generate();
656
    MySociety\TheyWorkForYou\Renderer::output('mp/list', $data);
657
}
658
659
/* Error page */
660
661
function person_error_page($message) {
662
    global $this_page;
663
    $SEARCHURL = '';
664
    switch($this_page) {
665
        case 'peer':
666
            $people = new MySociety\TheyWorkForYou\People\Peers();
667
            $MPSURL = new \MySociety\TheyWorkForYou\Url('peers');
668
            break;
669
        case 'mla':
670
            $people = new MySociety\TheyWorkForYou\People\MLAs();
671
            $SEARCHURL = '/postcode/';
672
            $MPSURL = new \MySociety\TheyWorkForYou\Url('mlas');
673
            break;
674
        case 'msp':
675
            $people = new MySociety\TheyWorkForYou\People\MSPs();
676
            $SEARCHURL = '/postcode/';
677
            $MPSURL = new \MySociety\TheyWorkForYou\Url('msps');
678
            break;
679
        case 'ms':
680
            $people = new MySociety\TheyWorkForYou\People\MSs();
681
            $SEARCHURL = '/postcode/';
682
            $MPSURL = new \MySociety\TheyWorkForYou\Url('mss');
683
            break;
684
        case 'london-assembly-member':
685
            $people = new MySociety\TheyWorkForYou\People\LondonAssemblyMembers();
686
            $MPSURL = new \MySociety\TheyWorkForYou\Url('london-assembly-members');
687
            break;
688
        default:
689
            $people = new MySociety\TheyWorkForYou\People\MPs();
690
            $SEARCHURL = new \MySociety\TheyWorkForYou\Url('mp');
691
            $SEARCHURL = $SEARCHURL->generate();
692
            $MPSURL = new \MySociety\TheyWorkForYou\Url('mps');
693
    }
694
695
    $data = [
696
        'error' => $message,
697
        'rep_name' => $people->rep_name,
698
        'rep_name_plural' => $people->rep_plural,
699
        'all_mps_url' => $MPSURL->generate(),
700
        'rep_search_url' => $SEARCHURL,
701
    ];
702
    MySociety\TheyWorkForYou\Renderer::output('mp/error', $data);
703
}
704
705
/**
706
 * Person Positions Summary
707
 *
708
 * Generate the summary of this person's held positions.
709
 */
710
711
function person_summary_description($MEMBER) {
712
    $entered_house = $MEMBER->entered_house();
713
    $current_member = $MEMBER->current_member();
714
    $left_house = $MEMBER->left_house();
715
716
    if (in_array(HOUSE_TYPE_ROYAL, $MEMBER->houses())) {
717
        # Royal short-circuit
718
        if (substr($entered_house[HOUSE_TYPE_ROYAL]['date'], 0, 4) == 1952) {
719
            return '<strong>Acceded on ' . $entered_house[HOUSE_TYPE_ROYAL]['date_pretty']
720
                . '<br>Coronated on 2 June 1953</strong></li>';
721
        } else {
722
            return '';
723
        }
724
    }
725
    $desc = '';
726
    foreach ($MEMBER->houses() as $house) {
727
        if ($house == HOUSE_TYPE_COMMONS && isset($entered_house[HOUSE_TYPE_LORDS])) {
728
            # Same info is printed further down
729
            continue;
730
        }
731
732
        $party = $left_house[$house]['party'];
733
        $party_br = '';
734
        if (preg_match('#^(.*?)\s*\((.*?)\)$#', $party, $m)) {
735
            $party_br = " ($m[2])";
736
            $party = $m[1];
737
        }
738
        $pparty = $party != 'unknown' ? _htmlentities($party) : '';
739
740
        if ($house != HOUSE_TYPE_LORDS) {
741
            if ($house == HOUSE_TYPE_COMMONS) {
742
                $type = gettext('<abbr title="Member of Parliament">MP</abbr>');
743
            } elseif ($house == HOUSE_TYPE_NI) {
744
                $type = gettext('<abbr title="Member of the Legislative Assembly">MLA</abbr>');
745
            } elseif ($house == HOUSE_TYPE_SCOTLAND) {
746
                $type = gettext('<abbr title="Member of the Scottish Parliament">MSP</abbr>');
747
            } elseif ($house == HOUSE_TYPE_WALES) {
748
                $type = gettext('<abbr title="Member of the Senedd">MS</abbr>');
749
            } elseif ($house == HOUSE_TYPE_LONDON_ASSEMBLY) {
750
                $type = gettext('Member of the London Assembly');
751
            }
752
753
            if ($party == 'Speaker' || $party == 'Deputy Speaker') {
754
                # XXX: Might go horribly wrong if something odd happens
755
                if ($party == 'Deputy Speaker') {
756
                    $last = end($MEMBER->other_parties);
757
                    $oparty = $last['from'];
758
                } else {
759
                    $oparty = '';
760
                }
761
                if ($current_member[$house]) {
762
                    $line = sprintf(gettext('%s, and %s %s for %s'), $pparty, $oparty, $type, $left_house[$house]['constituency']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.
Loading history...
763
                } else {
764
                    $line = sprintf(gettext('Former %s, and %s %s for %s'), $pparty, $oparty, $type, $left_house[$house]['constituency']);
765
                }
766
            } elseif ($current_member[$house]) {
767
                $line = sprintf(gettext('%s %s %s for %s'), $pparty, $type, $party_br, $left_house[$house]['constituency']);
768
            } else {
769
                $line = sprintf(gettext('Former %s %s %s for %s'), $pparty, $type, $party_br, $left_house[$house]['constituency']);
770
            }
771
        } elseif ($house == HOUSE_TYPE_LORDS && $party != 'Bishop') {
772
            if ($current_member[$house]) {
773
                $line = sprintf(gettext('%s Peer'), $pparty);
774
            } else {
775
                $line = sprintf(gettext('Former %s Peer'), $pparty);
776
            }
777
        } else {
778
            if ($current_member[$house]) {
779
                $line = $pparty;
780
            } else {
781
                $line = sprintf(gettext('Former %s'), $pparty);
782
            }
783
        }
784
        $desc .= $line . ', ';
785
    }
786
    $desc = preg_replace('#, $#', '', $desc);
787
    return $desc;
788
}
789
790
/**
791
 * Person Rebellion Rate
792
 *
793
 * How often has this person rebelled against their party?
794
 *
795
 * @param MEMBER $member The member to calculate rebellion rate for.
796
 *
797
 * @return string A HTML summary of this person's rebellion rate.
798
 */
799
800
function person_rebellion_rate($member) {
801
802
    // Rebellion string may be empty.
803
    $rebellion_string = '';
804
805
    if (isset($member->extra_info['party_vote_alignment_last_year'])) {
806
807
        // unserialise the data from json
808
        $data = json_decode($member->extra_info['party_vote_alignment_last_year'], true);
809
        $total_votes = $data['total_votes'];
810
        $avg_diff_from_party = $data['avg_diff_from_party'];
811
812
        // as int %
813
        $avg_diff_str = number_format((1 - $avg_diff_from_party) * 100, 0) . '%';
814
815
        if ($total_votes == 0) {
816
            return '';
817
        }
818
        $votes_help_url = TWFY_VOTES_URL . "/help/about#voting-breakdowns-and-party-alignment";
0 ignored issues
show
Bug introduced by
The constant TWFY_VOTES_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
819
820
        $rebellion_string .= 'In the last year, ' . $member->full_name() . ' has an alignment score of ' . $avg_diff_str . ' with other MPs of their party (over ' . $total_votes . ' votes).';
821
        $rebellion_string .= ' <small><a title="More about party alignment" href="' . $votes_help_url . '">Find out more</a>.</small>';
822
    }
823
    return $rebellion_string;
824
}
825
826
function person_recent_appearances($member) {
827
    global $DATA, $SEARCHENGINE, $this_page, $hansardmajors;
828
829
    $out = [];
830
    $out['speeches'] = [];
831
    $out['written_questions'] = [];
832
833
    //$this->block_start(array('id'=>'hansard', 'title'=>$title));
834
    // This is really far from ideal - I don't really want $PAGE to know
835
    // anything about HANSARDLIST / DEBATELIST / WRANSLIST.
836
    // But doing this any other way is going to be a lot more work for little
837
    // benefit unfortunately.
838
    twfy_debug_timestamp();
839
840
    $person_id = $member->person_id();
841
842
    $memcache = new MySociety\TheyWorkForYou\Memcache();
843
844
    // Perform separate searches for each category to ensure adequate coverage
845
    $hansard = new MySociety\TheyWorkForYou\Hansard();
846
847
    // Search for speeches and debates (everything except written questions - major != 3)
848
    $speeches_key = "recent_speeches:$person_id:" . LANGUAGE;
849
    $recent_speeches = $memcache->get($speeches_key);
850
851
    if (!$recent_speeches) {
0 ignored issues
show
introduced by
The condition $recent_speeches is always false.
Loading history...
852
        $searchstring_speeches = "speaker:$person_id -section:wrans";  // Exclude written answers section
853
        $SEARCHENGINE = new \SEARCHENGINE($searchstring_speeches);
854
855
        // Search query excluding written questions
856
        $args_speeches = [
857
            's' => $searchstring_speeches,
858
            'p' => 1,                       // First page
859
            'num' => 8,                     // 8 recent speeches/debates
860
            'pop' => 1,                     // Disable search logging
861
            'o' => 'd',                     // Decending by date order
862
        ];
863
        $results_speeches = $hansard->search($searchstring_speeches, $args_speeches);
864
        $recent_speeches = serialize($results_speeches['rows'] ?? []);
865
        $memcache->set($speeches_key, $recent_speeches, 3600); // Cache for 1 hour
866
    }
867
    $out['speeches'] = unserialize($recent_speeches);
868
869
    // Search for written questions/answers (major = 3)
870
    $wrans_key = "recent_wrans:$person_id:" . LANGUAGE;
871
    $recent_wrans = $memcache->get($wrans_key);
872
873
    if (!$recent_wrans) {
0 ignored issues
show
introduced by
The condition $recent_wrans is always false.
Loading history...
874
        $searchstring_wrans = "speaker:$person_id section:wrans";  // Only written answers section
875
        $SEARCHENGINE = new \SEARCHENGINE($searchstring_wrans);
876
877
        // Search query for written questions only
878
        $args_wrans = [
879
            's' => $searchstring_wrans,
880
            'p' => 1,
881
            'num' => 8,
882
            'pop' => 1,
883
            'o' => 'd',
884
        ];
885
        $results_wrans = $hansard->search($searchstring_wrans, $args_wrans);
886
        $recent_wrans = serialize($results_wrans['rows'] ?? []);
887
        $memcache->set($wrans_key, $recent_wrans, 3600); // Cache for 1 hour
888
    }
889
    $out['written_questions'] = unserialize($recent_wrans);
890
    twfy_debug_timestamp();
891
892
    $MOREURL = new \MySociety\TheyWorkForYou\Url('search');
893
    $MOREURL->insert(['pid' => $person_id, 'pop' => 1]);
894
895
    $out['more_href'] = $MOREURL->generate();
896
    $out['more_text'] = sprintf(gettext('More of %s’s recent appearances'), ucfirst($member->full_name()));
897
898
    // Create separate "More" links for speeches and written questions
899
    $MORE_SPEECHES_URL = new \MySociety\TheyWorkForYou\Url('search');
900
    $MORE_SPEECHES_URL->insert(['pid' => $person_id, 'pop' => 1, 's' => "speaker:$person_id -section:wrans"]);
901
    $out['more_speeches_href'] = $MORE_SPEECHES_URL->generate();
902
    $out['more_speeches_text'] = sprintf(gettext('More of %s\'s speeches and debates'), ucfirst($member->full_name()));
903
904
    $MORE_QUESTIONS_URL = new \MySociety\TheyWorkForYou\Url('search');
905
    $MORE_QUESTIONS_URL->insert(['pid' => $person_id, 'pop' => 1, 's' => "speaker:$person_id section:wrans"]);
906
    $out['more_questions_href'] = $MORE_QUESTIONS_URL->generate();
907
    $out['more_questions_text'] = sprintf(gettext('More of %s\'s written questions'), ucfirst($member->full_name()));
908
909
    if ($rssurl = $DATA->page_metadata($this_page, 'rss')) {
910
        // If we set an RSS feed for this page.
911
        $HELPURL = new \MySociety\TheyWorkForYou\Url('help');
912
        $out['additional_links'] = '<a href="' . WEBPATH . $rssurl . '" title="XML version of this person&rsquo;s recent appearances">RSS feed</a> (<a href="' . $HELPURL->generate() . '#rss" title="An explanation of what RSS feeds are for">?</a>)';
913
    }
914
915
    // Keep array of combined list for overview and menu checks
916
    $out['appearances'] = array_merge($out['speeches'], $out['written_questions']);
917
918
    return $out;
919
920
}
921
922
function person_useful_links($member) {
923
924
    $links = $member->extra_info();
925
926
    $out = [];
927
928
    if (isset($links['maiden_speech'])) {
929
        $maiden_speech = fix_gid_from_db($links['maiden_speech']);
930
        $out[] = [
931
            'href' => WEBPATH . 'debate/?id=' . $maiden_speech,
932
            'text' => 'Maiden speech',
933
        ];
934
    }
935
936
    // BIOGRAPHY.
937
    global $THEUSER;
938
    if (isset($links['mp_website'])) {
939
        $out[] = [
940
            'href' => $links['mp_website'],
941
            'text' => 'Personal website',
942
        ];
943
    }
944
945
    if (isset($links['sp_url'])) {
946
        $out[] = [
947
            'href' => $links['sp_url'],
948
            'text' => 'Page on the Scottish Parliament website',
949
        ];
950
    }
951
952
    if (isset($links['wikipedia_url'])) {
953
        $out[] = [
954
            'href' => $links['wikipedia_url'],
955
            'text' => 'Wikipedia page',
956
        ];
957
    }
958
959
    if (isset($links['bbc_profile_url'])) {
960
        $out[] = [
961
            'href' => $links['bbc_profile_url'],
962
            'text' => 'BBC News profile',
963
        ];
964
    }
965
966
    if (isset($links['diocese_url'])) {
967
        $out[] = [
968
            'href' => $links['diocese_url'],
969
            'text' => 'Diocese website',
970
        ];
971
    }
972
973
    return $out;
974
}
975
976
function person_social_links($member) {
977
978
    $links = $member->extra_info();
979
980
    $out = [];
981
982
983
    if (isset($links['bluesky_handle'])) {
984
        $out[] = [
985
            'href' => 'https://bsky.app/profile/' . _htmlentities($links['bluesky_handle']),
986
            'text' => '@' . _htmlentities($links['bluesky_handle']),
987
            'type' => 'bluesky',
988
        ];
989
    }
990
991
    if (isset($links['twitter_username'])) {
992
        $out[] = [
993
            'href' => 'https://twitter.com/' . _htmlentities($links['twitter_username']),
994
            'text' => '@' . _htmlentities($links['twitter_username']),
995
            'type' => 'twitter',
996
        ];
997
    }
998
999
    if (isset($links['facebook_page'])) {
1000
        $out[] = [
1001
            'href' => _htmlentities($links['facebook_page']),
1002
            'text' => _htmlentities("Facebook"),
1003
            'type' => 'facebook',
1004
        ];
1005
    }
1006
1007
    $official_keys = [
1008
        'profile_url_uk_parl' => 'UK Parliament Profile',
1009
        'profile_url_scot_parl' => 'Scottish Parliament Profile',
1010
        'profile_url_ni_assembly' => 'Northern Ireland Assembly Profile',
1011
    ];
1012
1013
    if (LANGUAGE == 'cy') {
0 ignored issues
show
introduced by
The condition LANGUAGE == 'cy' is always false.
Loading history...
1014
        $official_keys['profile_url_senedd_cy'] = 'Proffil Senedd';
1015
    } else {
1016
        $official_keys['profile_url_senedd_en'] = 'Senedd Profile';
1017
    }
1018
1019
    foreach ($official_keys as $key => $text) {
1020
        if (isset($links[$key])) {
1021
            $out[] = [
1022
                'href' => $links[$key],
1023
                'text' => $text,
1024
                'type' => 'official',
1025
            ];
1026
        }
1027
    }
1028
1029
    return $out;
1030
}
1031
1032
function person_topics($member) {
1033
    $out = [];
1034
1035
    $extra_info = $member->extra_info();
1036
1037
    if (isset($extra_info['wrans_departments'])) {
1038
        $subjects = explode(',', $extra_info['wrans_departments']);
1039
        $out = array_merge($out, $subjects);
1040
    }
1041
1042
    if (isset($extra_info['wrans_subjects'])) {
1043
        $subjects = explode(',', $extra_info['wrans_subjects']);
1044
        $out = array_merge($out, $subjects);
1045
    }
1046
1047
    return $out;
1048
}
1049
1050
function person_appg_memberships($member) {
1051
    $out = [];
1052
1053
    $extra_info = $member->extra_info();
1054
    if (isset($extra_info['appg_membership'])) {
1055
        $out = MySociety\TheyWorkForYou\DataClass\APPGs\APPGMembershipAssignment::fromJson($extra_info['appg_membership']);
1056
    }
1057
1058
    return $out;
1059
}
1060
1061
function person_statements($member) {
1062
    $out = [
1063
        "edms" => null,
1064
        "letter" => null,
1065
        "annul_motions" => null,
1066
    ];
1067
1068
    $extra_info = $member->extra_info();
1069
    if (isset($extra_info['edms_signed'])) {
1070
        $out["edms"] = MySociety\TheyWorkForYou\DataClass\Statements\SignatureList::fromJson($extra_info['edms_signed']);
1071
    }
1072
    if (isset($extra_info['letters_signed'])) {
1073
        $out["letters"] = MySociety\TheyWorkForYou\DataClass\Statements\SignatureList::fromJson($extra_info['letters_signed']);
1074
    }
1075
    if (isset($extra_info['annul_motions_signed'])) {
1076
        $out["annul_motions"] = MySociety\TheyWorkForYou\DataClass\Statements\SignatureList::fromJson($extra_info['annul_motions_signed']);
1077
    }
1078
1079
    return $out;
1080
}
1081
1082
function memberships($member) {
1083
    $out = [];
1084
1085
    $committee_lookup = MySociety\TheyWorkForYou\DataClass\Groups\MiniGroupList::uk_committees();
1086
1087
    $topics = person_topics($member);
1088
    if ($topics) {
1089
        $out['topics'] = $topics;
1090
    }
1091
1092
    $posts = $member->offices('current', false, true);
1093
    if ($posts) {
1094
        // for each post we want to add the description and external_url from the committee lookup if possible
1095
        foreach ($posts as $post) {
1096
            $committee = $committee_lookup->findByName($post->dept);
1097
            if ($committee) {
1098
                $post->desc = $committee->description;
1099
                $post->external_url = $committee->external_url;
1100
            }
1101
        }
1102
        $out['posts'] = $posts;
1103
    }
1104
1105
    $posts = $member->offices('previous', false, true);
1106
    if ($posts) {
1107
        $out['previous_posts'] = $posts;
1108
    }
1109
1110
    $eu_stance = $member->getEUStance();
1111
    if ($eu_stance) {
1112
        $out['eu_stance'] = $eu_stance;
1113
    }
1114
1115
    $topics_of_interest = person_topics($member);
1116
    if ($topics_of_interest) {
1117
        $out['topics_of_interest'] = $topics_of_interest;
1118
    }
1119
1120
    $appg_membership = person_appg_memberships($member);
1121
    if ($appg_membership) {
1122
        $out['appg_membership'] = $appg_membership;
1123
    }
1124
1125
    $statments_signed = person_statements($member);
1126
    if ($statments_signed) {
1127
        if (isset($statments_signed["edms"]) && $statments_signed["edms"]->count() > 0) {
1128
            $out['edms_signed'] = $statments_signed["edms"];
1129
        }
1130
        if (isset($statments_signed["letters"]) && $statments_signed["letters"]->count() > 0) {
1131
            $out['letters_signed'] = $statments_signed["letters"];
1132
        }
1133
        if (isset($statments_signed["annul_motions"]) && $statments_signed["annul_motions"]->count() > 0) {
1134
            $out['annul_motions_signed'] = $statments_signed["annul_motions"];
1135
        }
1136
    }
1137
1138
    return $out;
1139
}
1140
1141
function constituency_previous_mps($member) {
1142
    if ($member->house(HOUSE_TYPE_COMMONS)) {
1143
        return $member->previous_mps();
1144
    } else {
1145
        return [];
1146
    }
1147
}
1148
1149
function constituency_future_mps($member) {
1150
    if ($member->house(HOUSE_TYPE_COMMONS)) {
1151
        return $member->future_mps();
1152
    } else {
1153
        return [];
1154
    }
1155
}
1156
1157
function person_pbc_membership($member) {
1158
1159
    $extra_info = $member->extra_info();
1160
    $out = ['info' => '', 'data' => []];
1161
1162
    # Public Bill Committees
1163
    if (count($extra_info['pbc'])) {
1164
        if ($member->party() == 'Scottish National Party') {
1165
            $out['info'] = 'SNP MPs only attend sittings where the legislation pertains to Scotland.';
1166
        }
1167
        foreach ($extra_info['pbc'] as $bill_id => $arr) {
1168
            $text = '';
1169
            if ($arr['chairman']) {
1170
                $text .= 'Chairman, ';
1171
            }
1172
            $text .= $arr['title'] . ' Committee';
1173
            $out['data'][] = [
1174
                'href'      => '/pbc/' . $arr['session'] . '/' . urlencode($arr['title']),
1175
                'text'      => $text,
1176
                'attending' => $arr['attending'] . ' out of ' . $arr['outof'],
1177
            ];
1178
        }
1179
    }
1180
1181
    return $out;
1182
}
1183
1184
function person_register_interests_from_key($key, $extra_info): ?MySociety\TheyWorkForYou\DataClass\Regmem\Person {
1185
    $lang = LANGUAGE;
0 ignored issues
show
Unused Code introduced by
The assignment to $lang is dead and can be removed.
Loading history...
1186
    $reg = null;
1187
    if (isset($extra_info[$key])) {
1188
        $reg = MySociety\TheyWorkForYou\DataClass\Regmem\Person::fromJson($extra_info[$key]);
1189
    }
1190
    return $reg;
1191
}
1192
1193
function person_register_interests($member, $extra_info) {
0 ignored issues
show
Unused Code introduced by
The parameter $member 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

1193
function person_register_interests(/** @scrutinizer ignore-unused */ $member, $extra_info) {

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...
1194
1195
    $valid_chambers = ['house-of-commons', 'scottish-parliament', 'northern-ireland-assembly', 'senedd'];
1196
1197
    $lang = LANGUAGE;
1198
1199
    $reg = ['chamber_registers' => [] ];
1200
1201
    foreach ($valid_chambers as $chamber) {
1202
        $key = 'person_regmem_' . $chamber . '_' . $lang;
1203
        $chamber_register = person_register_interests_from_key($key, $extra_info);
1204
        if ($chamber_register) {
1205
            $reg['chamber_registers'][$chamber] = $chamber_register;
1206
        }
1207
    }
1208
    // if chamber_registers is empty, we don't have any data
1209
    if (empty($reg['chamber_registers'])) {
1210
        return;
1211
    }
1212
1213
    // sort chamber registers by published_date
1214
    uasort($reg['chamber_registers'], function ($a, $b) {
1215
        return $a->published_date <=> $b->published_date;
1216
    });
1217
1218
    return $reg;
1219
}
1220
1221
function regional_list($pc, $area_type, $rep_type) {
1222
    $constituencies = MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($pc);
1223
    if ($constituencies == 'CONNECTION_TIMED_OUT') {
1224
        throw new MySociety\TheyWorkForYou\MemberException('Sorry, we couldn&rsquo;t check your postcode right now, as our postcode lookup server is under quite a lot of load.');
1225
    } elseif (!$constituencies) {
1226
        throw new MySociety\TheyWorkForYou\MemberException('Sorry, ' . htmlentities($pc) . ' isn&rsquo;t a known postcode');
1227
    } elseif (!isset($constituencies[$area_type])) {
1228
        throw new MySociety\TheyWorkForYou\MemberException(htmlentities($pc) . ' does not appear to be a valid postcode');
1229
    }
1230
    global $PAGE;
1231
    $a = array_values($constituencies);
0 ignored issues
show
Bug introduced by
It seems like $constituencies can also be of type string; however, parameter $array of array_values() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

1231
    $a = array_values(/** @scrutinizer ignore-type */ $constituencies);
Loading history...
1232
    $db = new ParlDB();
1233
    $query_base = "SELECT member.person_id, given_name, family_name, constituency, house
1234
        FROM member, person_names pn
1235
        WHERE constituency IN ('" . join("','", $a) . "')
1236
            AND member.person_id = pn.person_id AND pn.type = 'name'
1237
            AND pn.end_date = (SELECT MAX(end_date) FROM person_names WHERE person_names.person_id = member.person_id)";
1238
    $q = $db->query($query_base . " AND left_reason = 'still_in_office' AND house in (" . HOUSE_TYPE_NI . "," . HOUSE_TYPE_SCOTLAND . "," . HOUSE_TYPE_WALES . ")");
1239
    $current = true;
1240
    if (!$q->rows() && ($dissolution = MySociety\TheyWorkForYou\Dissolution::db())) {
1241
        $current = false;
1242
        $q = $db->query(
1243
            $query_base . " AND $dissolution[query]",
1244
            $dissolution['params']
1245
        );
1246
    }
1247
    $mcon = [];
1248
    $mreg = [];
1249
    foreach ($q as $row) {
1250
        $house = $row['house'];
1251
        $cons = $row['constituency'];
1252
        if ($house == HOUSE_TYPE_COMMONS) {
1253
            continue;
1254
        } elseif ($house == HOUSE_TYPE_NI) {
1255
            $mreg[] = $row;
1256
        } elseif ($house == HOUSE_TYPE_SCOTLAND) {
1257
            if ($cons == $constituencies['SPC']) {
1258
                $mcon = $row;
1259
            } elseif ($cons == $constituencies['SPE']) {
1260
                $mreg[] = $row;
1261
            }
1262
        } elseif ($house == HOUSE_TYPE_WALES) {
1263
            if ($cons == $constituencies['WAC']) {
1264
                $mcon = $row;
1265
            } elseif ($cons == $constituencies['WAE']) {
1266
                $mreg[] = $row;
1267
            }
1268
        } else {
1269
            throw new MySociety\TheyWorkForYou\MemberException('Odd result returned!' . $house);
1270
        }
1271
    }
1272
    if ($rep_type == 'msp') {
1273
        $name = $mcon['given_name'] . ' ' . $mcon['family_name'];
1274
        $cons = $mcon['constituency'];
1275
        $reg = $constituencies['SPE'];
1276
        $url = '/msp/?p=' . $mcon['person_id'];
1277
        if ($current) {
1278
            $data['members_statement'] = '<p>You have one constituency MSP (Member of the Scottish Parliament) and multiple region MSPs.</p>';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
1279
            $data['members_statement'] .= '<p>' . sprintf('Your <strong>constituency MSP</strong> is <a href="%s">%s</a>, MSP for %s.', $url, $name, $cons) . '</p>';
1280
            $data['members_statement'] .= '<p>' . sprintf('Your <strong>%s region MSPs</strong> are:', $reg) . '</p>';
1281
        } else {
1282
            $data['members_statement'] = '<p>' . 'You had one constituency MSP (Member of the Scottish Parliament) and multiple region MSPs.' . '</p>';
1283
            $data['members_statement'] .= '<p>' . sprintf('Your <strong>constituency MSP</strong> was <a href="%s">%s</a>, MSP for %s.', $url, $name, $cons) . '</p>';
1284
            $data['members_statement'] .= '<p>' . sprintf('Your <strong>%s region MSPs</strong> were:', $reg) . '</p>';
1285
        }
1286
    } elseif ($rep_type == 'ms') {
1287
        $name = $mcon['given_name'] . ' ' . $mcon['family_name'];
1288
        $cons = gettext($mcon['constituency']);
1289
        $reg = gettext($constituencies['WAE']);
1290
        $url = '/ms/?p=' . $mcon['person_id'];
1291
        if ($current) {
1292
            $data['members_statement'] = '<p>' . gettext('You have one constituency MS (Member of the Senedd) and multiple region MSs.') . '</p>';
1293
            $data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>constituency MS</strong> is <a href="%s">%s</a>, MS for %s.'), $url, $name, $cons) . '</p>';
1294
            $data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>%s region MSs</strong> are:'), $reg) . '</p>';
1295
        } else {
1296
            $data['members_statement'] = '<p>' . gettext('You had one constituency MS (Member of the Senedd) and multiple region MSs.') . '</p>';
1297
            $data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>constituency MS</strong> was <a href="%s">%s</a>, MS for %s.'), $url, $name, $cons) . '</p>';
1298
            $data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>%s region MSs</strong> were:'), $reg) . '</p>';
1299
        }
1300
    } else {
1301
        if ($current) {
1302
            $data['members_statement'] = '<p>You have multiple MLAs (Members of the Legislative Assembly) who represent you in ' . $constituencies['NIE'] . '. They are:</p>';
1303
        } else {
1304
            $data['members_statement'] = '<p>You had multiple MLAs (Members of the Legislative Assembly) who represented you in ' . $constituencies['NIE'] . '. They were:</p>';
1305
        }
1306
    }
1307
1308
    foreach($mreg as $reg) {
1309
        $data['members'][] =  [
1310
            'url' => '/' . $rep_type . '/?p=' . $reg['person_id'],
1311
            'name' => $reg['given_name'] . ' ' . $reg['family_name'],
1312
        ];
1313
1314
    }
1315
1316
    // Send the output for rendering
1317
    MySociety\TheyWorkForYou\Renderer::output('mp/regional_list', $data);
1318
1319
}
1320