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']; |
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
|
|
|
// Set page metadata |
304
|
|
|
$DATA->set_page_metadata($this_page, 'title', $title); |
305
|
|
|
$DATA->set_page_metadata($this_page, 'meta_description', $desc); |
306
|
|
|
|
307
|
|
|
// Build the RSS link and add it to page data. |
308
|
|
|
$feedurl = $DATA->page_metadata('mp_rss', 'url') . $MEMBER->person_id() . '.rdf'; |
309
|
|
|
if (file_exists(BASEDIR . '/' . $feedurl)) { |
310
|
|
|
$DATA->set_page_metadata($this_page, 'rss', $feedurl); |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
// Prepare data for the template |
314
|
|
|
$data["pagetype"] = $pagetype; |
315
|
|
|
$data['full_name'] = $MEMBER->full_name(); |
316
|
|
|
$data['person_id'] = $MEMBER->person_id(); |
317
|
|
|
$data['member_id'] = $MEMBER->member_id(); |
318
|
|
|
|
319
|
|
|
$data['known_for'] = $known_for; |
320
|
|
|
$data['latest_membership'] = $MEMBER->getMostRecentMembership(); |
321
|
|
|
|
322
|
|
|
$data['constituency'] = $MEMBER->constituency(); |
323
|
|
|
$data['party'] = $MEMBER->party_text(); |
324
|
|
|
$data['current_party_comparison'] = $MEMBER->currentPartyComparison(); |
325
|
|
|
$data['current_member_anywhere'] = $MEMBER->current_member_anywhere(); |
326
|
|
|
$data['current_member'] = $MEMBER->current_member(); |
327
|
|
|
$data['the_users_mp'] = $MEMBER->the_users_mp(); |
328
|
|
|
$data['user_postcode'] = $THEUSER->postcode; |
329
|
|
|
$data['houses'] = $MEMBER->houses(); |
330
|
|
|
$data['member_url'] = $MEMBER->url(); |
331
|
|
|
$data['abs_member_url'] = $MEMBER->url(true); |
332
|
|
|
// If there's photo attribution information, copy it into data |
333
|
|
|
foreach (['photo_attribution_text', 'photo_attribution_link'] as $key) { |
334
|
|
|
if (isset($MEMBER->extra_info[$key])) { |
335
|
|
|
$data[$key] = $MEMBER->extra_info[$key]; |
336
|
|
|
} |
337
|
|
|
} |
338
|
|
|
$data['profile_message'] = $MEMBER->extra_info['profile_message'] ?? ''; |
339
|
|
|
$data['image'] = $MEMBER->image(); |
340
|
|
|
$data['member_summary'] = person_summary_description($MEMBER); |
341
|
|
|
$data['enter_leave'] = $MEMBER->getEnterLeaveStrings(); |
342
|
|
|
$data['entry_date'] = $MEMBER->getEntryDate(HOUSE_TYPE_COMMONS); |
343
|
|
|
$data['leave_date'] = $MEMBER->getLeftDate(HOUSE_TYPE_COMMONS); |
344
|
|
|
$data['is_new_mp'] = $MEMBER->isNew(); |
345
|
|
|
$data['other_parties'] = $MEMBER->getOtherPartiesString(); |
346
|
|
|
$data['other_constituencies'] = $MEMBER->getOtherConstituenciesString(); |
347
|
|
|
$data['rebellion_rate'] = person_rebellion_rate($MEMBER); |
348
|
|
|
$data['recent_appearances'] = person_recent_appearances($MEMBER); |
349
|
|
|
$data['useful_links'] = person_useful_links($MEMBER); |
350
|
|
|
$data['social_links'] = person_social_links($MEMBER); |
351
|
|
|
$data['current_offices'] = $MEMBER->offices('current', true); |
352
|
|
|
$data['previous_offices'] = $MEMBER->offices('previous', true); |
353
|
|
|
$data['register_interests'] = person_register_interests($MEMBER, $MEMBER->extra_info); |
354
|
|
|
$data['register_2024_enriched'] = person_register_interests_from_key('person_regmem_enriched2024_en', $MEMBER->extra_info); |
355
|
|
|
$data['standing_down_2024'] = $MEMBER->extra_info['standing_down_2024'] ?? ''; |
356
|
|
|
$data['memberships'] = memberships($MEMBER); |
357
|
|
|
|
358
|
|
|
# People who are or were MPs and Lords potentially have voting records, except Sinn Fein MPs |
359
|
|
|
$data['has_voting_record'] = (($MEMBER->house(HOUSE_TYPE_COMMONS) && $MEMBER->party() != 'Sinn Féin') || $MEMBER->house(HOUSE_TYPE_LORDS)); |
360
|
|
|
# Everyone who is currently somewhere has email alert signup, apart from current Sinn Fein MPs who are not MLAs |
361
|
|
|
$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))); |
362
|
|
|
$data['has_expenses'] = $data['leave_date'] > '2004-01-01'; |
363
|
|
|
|
364
|
|
|
$data['pre_2010_expenses'] = false; |
365
|
|
|
$data['post_2010_expenses'] = $data['leave_date'] > '2010-05-05' ? ($MEMBER->extra_info['datadotparl_id'] ?? '') : ''; |
366
|
|
|
|
367
|
|
|
if ($data['entry_date'] < '2010-05-05') { |
368
|
|
|
$data['pre_2010_expenses'] = true; |
369
|
|
|
// Set the expenses URL if we know it |
370
|
|
|
$data['expenses_url_2004'] = $MEMBER->extra_info['expenses_url'] ?? 'https://mpsallowances.parliament.uk/mpslordsandoffices/hocallowances/allowances%2Dby%2Dmp/'; |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
$data['constituency_previous_mps'] = constituency_previous_mps($MEMBER); |
374
|
|
|
$data['constituency_future_mps'] = constituency_future_mps($MEMBER); |
375
|
|
|
$data['public_bill_committees'] = person_pbc_membership($MEMBER); |
376
|
|
|
|
377
|
|
|
$data['this_page'] = $this_page; |
378
|
|
|
$country = MySociety\TheyWorkForYou\Utility\House::getCountryDetails($data['latest_membership']['house']); |
379
|
|
|
$data['current_assembly'] = $country[2]; |
380
|
|
|
|
381
|
|
|
$data['policy_last_update'] = MySociety\TheyWorkForYou\Divisions::getMostRecentDivisionDate(); |
382
|
|
|
|
383
|
|
|
$data['comparison_party'] = $MEMBER->cohortParty(); |
384
|
|
|
$data['unslugified_comparison_party'] = ucwords(str_replace('-', ' ', $data['comparison_party'])); |
385
|
|
|
|
386
|
|
|
// is the party we're comparing this MP to different from the party they're currently in? |
387
|
|
|
$data['party_switcher'] = (slugify($data['current_party_comparison']) != slugify($data["comparison_party"])); |
388
|
|
|
|
389
|
|
|
// Update the social image URL generation logic |
390
|
|
|
switch ($pagetype) { |
391
|
|
|
case 'votes': |
392
|
|
|
$data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Voting Summaries', $data['current_assembly']); |
393
|
|
|
$policy_set = get_http_var('policy'); |
394
|
|
|
|
395
|
|
|
$policiesList = new MySociety\TheyWorkForYou\Policies(); |
396
|
|
|
$divisions = new MySociety\TheyWorkForYou\Divisions($MEMBER); |
397
|
|
|
// Generate voting segments |
398
|
|
|
$set_descriptions = $policiesList->getSetDescriptions(); |
399
|
|
|
if ($policy_set && array_key_exists($policy_set, $set_descriptions)) { |
400
|
|
|
$sets = [$policy_set]; |
401
|
|
|
$data['page_title'] = $set_descriptions[$policy_set] . ' ' . $title . ' - TheyWorkForYou'; |
402
|
|
|
$data['meta_description'] = 'See how ' . $data['full_name'] . ' voted on ' . $set_descriptions[$policy_set]; |
403
|
|
|
$data['single_policy_page'] = true; |
404
|
|
|
} else { |
405
|
|
|
$data['single_policy_page'] = false; |
406
|
|
|
$sets = [ |
407
|
|
|
'social', 'foreignpolicy', 'welfare', 'taxation', 'business', |
408
|
|
|
'health', 'education', 'reform', 'home', 'environment', |
409
|
|
|
'transport', 'housing', 'misc', |
410
|
|
|
]; |
411
|
|
|
$sets = array_filter($sets, function ($v) use ($set_descriptions) { |
412
|
|
|
return array_key_exists($v, $set_descriptions); |
413
|
|
|
}); |
414
|
|
|
shuffle($sets); |
415
|
|
|
} |
416
|
|
|
$house = HOUSE_TYPE_COMMONS; |
417
|
|
|
$party = new MySociety\TheyWorkForYou\Party($MEMBER->party()); |
418
|
|
|
$voting_comparison_period_slug = get_http_var('comparison_period') ?: 'all_time'; |
419
|
|
|
$voting_comparison_period = new PolicyComparisonPeriod($voting_comparison_period_slug, $house); |
420
|
|
|
$cohort_party = $MEMBER->cohortParty(); |
421
|
|
|
|
422
|
|
|
// this comes up if the votes page is being accessed for an old MP/Lord without party information. |
423
|
|
|
// by definition, not covered by our voting comparisons so just return an empty array. |
424
|
|
|
if ($cohort_party == null) { |
425
|
|
|
$data['key_votes_segments'] = []; |
426
|
|
|
} else { |
427
|
|
|
$data['key_votes_segments'] = PolicyDistributionCollection::getPersonDistributions($sets, $MEMBER->person_id(), $cohort_party, $voting_comparison_period->slug, $house); |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
$data["comparison_period"] = $voting_comparison_period; |
431
|
|
|
$data['available_periods'] = PolicyComparisonPeriod::getComparisonPeriodsForPerson($MEMBER->person_id(), $house); |
432
|
|
|
// shuffle the key_votes_segments for a random order |
433
|
|
|
shuffle($data['key_votes_segments']); |
434
|
|
|
$data["sig_diff_policy"] = PolicyDistributionCollection::getSignificantDistributions($data['key_votes_segments']); |
435
|
|
|
$data['party_member_count'] = $party->getCurrentMemberCount($house); |
436
|
|
|
|
437
|
|
|
// Send the output for rendering |
438
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/votes', $data); |
439
|
|
|
|
440
|
|
|
break; |
441
|
|
|
|
442
|
|
|
case 'recent': |
443
|
|
|
$data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Recent Votes', $data['current_assembly']); |
444
|
|
|
$divisions = new MySociety\TheyWorkForYou\Divisions($MEMBER); |
445
|
|
|
$data['divisions'] = $divisions->getRecentMemberDivisions(); |
446
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/recent', $data); |
447
|
|
|
break; |
448
|
|
|
|
449
|
|
|
case 'memberships': |
450
|
|
|
$data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Committees, Memberships and Signatures', $data['current_assembly']); |
451
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/memberships', $data); |
452
|
|
|
break; |
453
|
|
|
|
454
|
|
|
case 'election_register': |
455
|
|
|
// Send the output for rendering |
456
|
|
|
|
457
|
|
|
$memcache = new \MySociety\TheyWorkForYou\Memcache(); |
458
|
|
|
$mem_key = "highlighted_interests" . $MEMBER->person_id(); |
459
|
|
|
|
460
|
|
|
$highlighted_for_this_mp = $memcache->get($mem_key); |
461
|
|
|
|
462
|
|
|
if (!$highlighted_for_this_mp) { |
|
|
|
|
463
|
|
|
$highlighted_register = MySociety\TheyWorkForYou\DataClass\Regmem\Register::getMisc("highlighted_interests.json"); |
464
|
|
|
$str_id = "uk.org.publicwhip/person/" . $MEMBER->person_id(); |
465
|
|
|
$highlighted_for_this_mp = $highlighted_register->getPersonFromId($str_id); |
|
|
|
|
466
|
|
|
$memcache->set($mem_key, $highlighted_for_this_mp, 60 * 60 * 24); |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
$data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Election Register', $data['current_assembly']); |
470
|
|
|
$data['mp_has_highlighted_interests'] = (bool) $highlighted_for_this_mp; |
471
|
|
|
$overlapping_interests = []; |
472
|
|
|
|
473
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/election_register', $data); |
474
|
|
|
|
475
|
|
|
// no break |
476
|
|
|
case 'register': |
477
|
|
|
$data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Register of Interests', $data['current_assembly']); |
478
|
|
|
// Send the output for rendering |
479
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/register', $data); |
480
|
|
|
|
481
|
|
|
// no break |
482
|
|
|
case '': |
483
|
|
|
default: |
484
|
|
|
$data['og_image'] = \MySociety\TheyWorkForYou\Url::generateSocialImageUrl($member_name, 'Profile', $data['current_assembly']); |
485
|
|
|
// if extra detail needed for overview page in future |
486
|
|
|
|
487
|
|
|
// Send the output for rendering |
488
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/profile', $data); |
489
|
|
|
|
490
|
|
|
break; |
491
|
|
|
|
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
|
495
|
|
|
///////////////////////////////////////////////////////// |
496
|
|
|
// SUPPORTING FUNCTIONS |
497
|
|
|
|
498
|
|
|
/* Person lookup functions */ |
499
|
|
|
|
500
|
|
|
function get_person_by_id($pid) { |
501
|
|
|
global $pagetype, $this_page; |
502
|
|
|
$MEMBER = new MySociety\TheyWorkForYou\Member(['person_id' => $pid]); |
503
|
|
|
if (!$MEMBER->valid) { |
504
|
|
|
throw new MySociety\TheyWorkForYou\MemberException('Sorry, that ID number wasn’t recognised.'); |
505
|
|
|
} |
506
|
|
|
// Ensure that we're actually at the current, correct and canonical URL for the person. If not, redirect. |
507
|
|
|
// No need to worry about other URL syntax forms for vote pages, they shouldn't happen. |
508
|
|
|
$at = str_replace('/mp/', "/$this_page/", get_http_var('url')); |
509
|
|
|
$shouldbe = urldecode($MEMBER->url()); |
510
|
|
|
if ($pagetype) { |
511
|
|
|
$shouldbe .= "/$pagetype"; |
512
|
|
|
} |
513
|
|
|
if ($at !== $shouldbe) { |
514
|
|
|
member_redirect($MEMBER, 301, $pagetype); |
515
|
|
|
} |
516
|
|
|
return $MEMBER; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
function get_person_by_member_id($member_id) { |
520
|
|
|
// Got a member id, redirect to the canonical MP page, with a person id. |
521
|
|
|
$MEMBER = new MySociety\TheyWorkForYou\Member(['member_id' => $member_id]); |
522
|
|
|
member_redirect($MEMBER); |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
function get_person_by_postcode($pc) { |
526
|
|
|
global $THEUSER; |
527
|
|
|
$pc = preg_replace('#[^a-z0-9]#i', '', $pc); |
528
|
|
|
if (!validate_postcode($pc)) { |
529
|
|
|
twfy_debug('MP', "Can't display an MP because the submitted postcode wasn't of a valid form."); |
530
|
|
|
throw new MySociety\TheyWorkForYou\MemberException(sprintf(gettext('Sorry, %s isn’t a valid postcode'), _htmlentities($pc))); |
531
|
|
|
} |
532
|
|
|
twfy_debug('MP', "MP lookup by postcode"); |
533
|
|
|
$constituency = strtolower(MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituency($pc)); |
534
|
|
|
if ($constituency == "connection_timed_out") { |
535
|
|
|
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.')); |
536
|
|
|
} elseif ($constituency == "") { |
537
|
|
|
twfy_debug('MP', "Can't display an MP, as submitted postcode didn't match a constituency"); |
538
|
|
|
throw new MySociety\TheyWorkForYou\MemberException(sprintf(gettext('Sorry, %s isn’t a known postcode'), _htmlentities($pc))); |
539
|
|
|
} else { |
540
|
|
|
// Redirect to the canonical MP page, with a person id. |
541
|
|
|
$MEMBER = new MySociety\TheyWorkForYou\Member(['constituency' => $constituency, 'house' => HOUSE_TYPE_COMMONS]); |
542
|
|
|
if ($MEMBER->person_id()) { |
543
|
|
|
// This will cookie the postcode. |
544
|
|
|
$THEUSER->set_postcode_cookie($pc); |
545
|
|
|
} |
546
|
|
|
member_redirect($MEMBER, 302); |
547
|
|
|
} |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
function get_person_by_name($name, $const = '') { |
551
|
|
|
$MEMBER = new MySociety\TheyWorkForYou\Member(['name' => $name, 'constituency' => $const]); |
552
|
|
|
// Edge case, only attempt further detection if this isn't the Queen. |
553
|
|
|
if (($name !== 'elizabeth the second' && $name !== 'prince charles') || $const) { |
554
|
|
|
twfy_debug('MP', 'Redirecting for MP found by name/constituency'); |
555
|
|
|
member_redirect($MEMBER); |
556
|
|
|
} |
557
|
|
|
return $MEMBER; |
558
|
|
|
} |
559
|
|
|
|
560
|
|
|
function get_mp_by_constituency($constituency) { |
561
|
|
|
$MEMBER = new MySociety\TheyWorkForYou\Member(['constituency' => $constituency, 'house' => HOUSE_TYPE_COMMONS]); |
562
|
|
|
member_redirect($MEMBER); |
563
|
|
|
} |
564
|
|
|
|
565
|
|
|
function get_regional_by_user_postcode($pc, $page) { |
566
|
|
|
global $this_page; |
567
|
|
|
$this_page = "your$page"; |
568
|
|
|
$areas = \MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($pc); |
569
|
|
|
if ($page == 'msp' && isset($areas['SPC'])) { |
570
|
|
|
regional_list($pc, 'SPC', $page); |
571
|
|
|
} elseif ($page == 'ms' && isset($areas['WAC'])) { |
572
|
|
|
regional_list($pc, 'WAC', $page); |
573
|
|
|
} elseif ($page == 'mla' && isset($areas['NIE'])) { |
574
|
|
|
regional_list($pc, 'NIE', $page); |
575
|
|
|
} else { |
576
|
|
|
throw new MySociety\TheyWorkForYou\MemberException('Your set postcode is not in the right region.'); |
577
|
|
|
} |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
function get_mp_by_user_postcode($pc) { |
581
|
|
|
$MEMBER = new MySociety\TheyWorkForYou\Member(['postcode' => $pc, 'house' => HOUSE_TYPE_COMMONS]); |
582
|
|
|
member_redirect($MEMBER, 302); |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
/** |
586
|
|
|
* Member Redirect |
587
|
|
|
* |
588
|
|
|
* Redirect to the canonical page for a member. |
589
|
|
|
*/ |
590
|
|
|
|
591
|
|
|
function member_redirect(&$MEMBER, $code = 301, $pagetype = null) { |
592
|
|
|
// We come here after creating a MEMBER object by various methods. |
593
|
|
|
// Now we redirect to the canonical MP page, with a person_id. |
594
|
|
|
if ($MEMBER->person_id()) { |
595
|
|
|
$url = $MEMBER->url(); |
596
|
|
|
$params = []; |
597
|
|
|
foreach ($_GET as $key => $value) { |
598
|
|
|
if (substr($key, 0, 4) == 'utm_' || $key == 'gclid') { |
599
|
|
|
$params[] = urlencode($key) . "=" . urlencode($value); |
600
|
|
|
} |
601
|
|
|
} |
602
|
|
|
if ($pagetype) { |
603
|
|
|
$url .= '/' . $pagetype; |
604
|
|
|
} |
605
|
|
|
if (count($params)) { |
606
|
|
|
$url .= '?' . join('&', $params); |
607
|
|
|
} |
608
|
|
|
header('Location: ' . $url, true, $code); |
609
|
|
|
exit; |
610
|
|
|
} |
611
|
|
|
} |
612
|
|
|
|
613
|
|
|
/* Error list page */ |
614
|
|
|
|
615
|
|
|
function person_list_page($ids) { |
616
|
|
|
global $name; |
617
|
|
|
if (!DEVSITE) { |
618
|
|
|
header('Cache-Control: max-age=900'); |
619
|
|
|
} |
620
|
|
|
$data = ['mps' => []]; |
621
|
|
|
foreach ($ids as $id => $constituency) { |
622
|
|
|
$data['mps'][] = [ |
623
|
|
|
'url' => WEBPATH . 'mp/?pid=' . $id, |
624
|
|
|
'name' => ucwords(strtolower($name)) . ', ' . $constituency, |
625
|
|
|
]; |
626
|
|
|
} |
627
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('mps'); |
628
|
|
|
$data['all_mps_url'] = $MPSURL->generate(); |
629
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/list', $data); |
630
|
|
|
} |
631
|
|
|
|
632
|
|
|
/* Error page */ |
633
|
|
|
|
634
|
|
|
function person_error_page($message) { |
635
|
|
|
global $this_page; |
636
|
|
|
$SEARCHURL = ''; |
637
|
|
|
switch($this_page) { |
638
|
|
|
case 'peer': |
639
|
|
|
$people = new MySociety\TheyWorkForYou\People\Peers(); |
640
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('peers'); |
641
|
|
|
break; |
642
|
|
|
case 'mla': |
643
|
|
|
$people = new MySociety\TheyWorkForYou\People\MLAs(); |
644
|
|
|
$SEARCHURL = '/postcode/'; |
645
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('mlas'); |
646
|
|
|
break; |
647
|
|
|
case 'msp': |
648
|
|
|
$people = new MySociety\TheyWorkForYou\People\MSPs(); |
649
|
|
|
$SEARCHURL = '/postcode/'; |
650
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('msps'); |
651
|
|
|
break; |
652
|
|
|
case 'ms': |
653
|
|
|
$people = new MySociety\TheyWorkForYou\People\MSs(); |
654
|
|
|
$SEARCHURL = '/postcode/'; |
655
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('mss'); |
656
|
|
|
break; |
657
|
|
|
case 'london-assembly-member': |
658
|
|
|
$people = new MySociety\TheyWorkForYou\People\LondonAssemblyMembers(); |
659
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('london-assembly-members'); |
660
|
|
|
break; |
661
|
|
|
default: |
662
|
|
|
$people = new MySociety\TheyWorkForYou\People\MPs(); |
663
|
|
|
$SEARCHURL = new \MySociety\TheyWorkForYou\Url('mp'); |
664
|
|
|
$SEARCHURL = $SEARCHURL->generate(); |
665
|
|
|
$MPSURL = new \MySociety\TheyWorkForYou\Url('mps'); |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
$data = [ |
669
|
|
|
'error' => $message, |
670
|
|
|
'rep_name' => $people->rep_name, |
671
|
|
|
'rep_name_plural' => $people->rep_plural, |
672
|
|
|
'all_mps_url' => $MPSURL->generate(), |
673
|
|
|
'rep_search_url' => $SEARCHURL, |
674
|
|
|
]; |
675
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/error', $data); |
676
|
|
|
} |
677
|
|
|
|
678
|
|
|
/** |
679
|
|
|
* Person Positions Summary |
680
|
|
|
* |
681
|
|
|
* Generate the summary of this person's held positions. |
682
|
|
|
*/ |
683
|
|
|
|
684
|
|
|
function person_summary_description($MEMBER) { |
685
|
|
|
$entered_house = $MEMBER->entered_house(); |
686
|
|
|
$current_member = $MEMBER->current_member(); |
687
|
|
|
$left_house = $MEMBER->left_house(); |
688
|
|
|
|
689
|
|
|
if (in_array(HOUSE_TYPE_ROYAL, $MEMBER->houses())) { |
690
|
|
|
# Royal short-circuit |
691
|
|
|
if (substr($entered_house[HOUSE_TYPE_ROYAL]['date'], 0, 4) == 1952) { |
692
|
|
|
return '<strong>Acceded on ' . $entered_house[HOUSE_TYPE_ROYAL]['date_pretty'] |
693
|
|
|
. '<br>Coronated on 2 June 1953</strong></li>'; |
694
|
|
|
} else { |
695
|
|
|
return ''; |
696
|
|
|
} |
697
|
|
|
} |
698
|
|
|
$desc = ''; |
699
|
|
|
foreach ($MEMBER->houses() as $house) { |
700
|
|
|
if ($house == HOUSE_TYPE_COMMONS && isset($entered_house[HOUSE_TYPE_LORDS])) { |
701
|
|
|
# Same info is printed further down |
702
|
|
|
continue; |
703
|
|
|
} |
704
|
|
|
|
705
|
|
|
$party = $left_house[$house]['party']; |
706
|
|
|
$party_br = ''; |
707
|
|
|
if (preg_match('#^(.*?)\s*\((.*?)\)$#', $party, $m)) { |
708
|
|
|
$party_br = " ($m[2])"; |
709
|
|
|
$party = $m[1]; |
710
|
|
|
} |
711
|
|
|
$pparty = $party != 'unknown' ? _htmlentities($party) : ''; |
712
|
|
|
|
713
|
|
|
if ($house != HOUSE_TYPE_LORDS) { |
714
|
|
|
if ($house == HOUSE_TYPE_COMMONS) { |
715
|
|
|
$type = gettext('<abbr title="Member of Parliament">MP</abbr>'); |
716
|
|
|
} elseif ($house == HOUSE_TYPE_NI) { |
717
|
|
|
$type = gettext('<abbr title="Member of the Legislative Assembly">MLA</abbr>'); |
718
|
|
|
} elseif ($house == HOUSE_TYPE_SCOTLAND) { |
719
|
|
|
$type = gettext('<abbr title="Member of the Scottish Parliament">MSP</abbr>'); |
720
|
|
|
} elseif ($house == HOUSE_TYPE_WALES) { |
721
|
|
|
$type = gettext('<abbr title="Member of the Senedd">MS</abbr>'); |
722
|
|
|
} elseif ($house == HOUSE_TYPE_LONDON_ASSEMBLY) { |
723
|
|
|
$type = gettext('Member of the London Assembly'); |
724
|
|
|
} |
725
|
|
|
|
726
|
|
|
if ($party == 'Speaker' || $party == 'Deputy Speaker') { |
727
|
|
|
# XXX: Might go horribly wrong if something odd happens |
728
|
|
|
if ($party == 'Deputy Speaker') { |
729
|
|
|
$last = end($MEMBER->other_parties); |
730
|
|
|
$oparty = $last['from']; |
731
|
|
|
} else { |
732
|
|
|
$oparty = ''; |
733
|
|
|
} |
734
|
|
|
if ($current_member[$house]) { |
735
|
|
|
$line = sprintf(gettext('%s, and %s %s for %s'), $pparty, $oparty, $type, $left_house[$house]['constituency']); |
|
|
|
|
736
|
|
|
} else { |
737
|
|
|
$line = sprintf(gettext('Former %s, and %s %s for %s'), $pparty, $oparty, $type, $left_house[$house]['constituency']); |
738
|
|
|
} |
739
|
|
|
} elseif ($current_member[$house]) { |
740
|
|
|
$line = sprintf(gettext('%s %s %s for %s'), $pparty, $type, $party_br, $left_house[$house]['constituency']); |
741
|
|
|
} else { |
742
|
|
|
$line = sprintf(gettext('Former %s %s %s for %s'), $pparty, $type, $party_br, $left_house[$house]['constituency']); |
743
|
|
|
} |
744
|
|
|
} elseif ($house == HOUSE_TYPE_LORDS && $party != 'Bishop') { |
745
|
|
|
if ($current_member[$house]) { |
746
|
|
|
$line = sprintf(gettext('%s Peer'), $pparty); |
747
|
|
|
} else { |
748
|
|
|
$line = sprintf(gettext('Former %s Peer'), $pparty); |
749
|
|
|
} |
750
|
|
|
} else { |
751
|
|
|
if ($current_member[$house]) { |
752
|
|
|
$line = $pparty; |
753
|
|
|
} else { |
754
|
|
|
$line = sprintf(gettext('Former %s'), $pparty); |
755
|
|
|
} |
756
|
|
|
} |
757
|
|
|
$desc .= $line . ', '; |
758
|
|
|
} |
759
|
|
|
$desc = preg_replace('#, $#', '', $desc); |
760
|
|
|
return $desc; |
761
|
|
|
} |
762
|
|
|
|
763
|
|
|
/** |
764
|
|
|
* Person Rebellion Rate |
765
|
|
|
* |
766
|
|
|
* How often has this person rebelled against their party? |
767
|
|
|
* |
768
|
|
|
* @param MEMBER $member The member to calculate rebellion rate for. |
769
|
|
|
* |
770
|
|
|
* @return string A HTML summary of this person's rebellion rate. |
771
|
|
|
*/ |
772
|
|
|
|
773
|
|
|
function person_rebellion_rate($member) { |
774
|
|
|
|
775
|
|
|
// Rebellion string may be empty. |
776
|
|
|
$rebellion_string = ''; |
777
|
|
|
|
778
|
|
|
if (isset($member->extra_info['party_vote_alignment_last_year'])) { |
779
|
|
|
|
780
|
|
|
// unserialise the data from json |
781
|
|
|
$data = json_decode($member->extra_info['party_vote_alignment_last_year'], true); |
782
|
|
|
$total_votes = $data['total_votes']; |
783
|
|
|
$avg_diff_from_party = $data['avg_diff_from_party']; |
784
|
|
|
|
785
|
|
|
// as int % |
786
|
|
|
$avg_diff_str = number_format((1 - $avg_diff_from_party) * 100, 0) . '%'; |
787
|
|
|
|
788
|
|
|
if ($total_votes == 0) { |
789
|
|
|
return ''; |
790
|
|
|
} |
791
|
|
|
$votes_help_url = TWFY_VOTES_URL . "/help/about#voting-breakdowns-and-party-alignment"; |
|
|
|
|
792
|
|
|
|
793
|
|
|
$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).'; |
794
|
|
|
$rebellion_string .= ' <small><a title="More about party alignment" href="' . $votes_help_url . '">Find out more</a>.</small>'; |
795
|
|
|
} |
796
|
|
|
return $rebellion_string; |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
function person_recent_appearances($member) { |
800
|
|
|
global $DATA, $SEARCHENGINE, $this_page; |
801
|
|
|
|
802
|
|
|
$out = []; |
803
|
|
|
$out['appearances'] = []; |
804
|
|
|
|
805
|
|
|
//$this->block_start(array('id'=>'hansard', 'title'=>$title)); |
806
|
|
|
// This is really far from ideal - I don't really want $PAGE to know |
807
|
|
|
// anything about HANSARDLIST / DEBATELIST / WRANSLIST. |
808
|
|
|
// But doing this any other way is going to be a lot more work for little |
809
|
|
|
// benefit unfortunately. |
810
|
|
|
twfy_debug_timestamp(); |
811
|
|
|
|
812
|
|
|
$person_id = $member->person_id(); |
813
|
|
|
|
814
|
|
|
$memcache = new MySociety\TheyWorkForYou\Memcache(); |
815
|
|
|
$recent = $memcache->get("recent_appear:$person_id:" . LANGUAGE); |
816
|
|
|
|
817
|
|
|
if (!$recent) { |
|
|
|
|
818
|
|
|
// Initialise the search engine |
819
|
|
|
$searchstring = "speaker:$person_id"; |
820
|
|
|
$SEARCHENGINE = new \SEARCHENGINE($searchstring); |
821
|
|
|
|
822
|
|
|
$hansard = new MySociety\TheyWorkForYou\Hansard(); |
823
|
|
|
$args = [ |
824
|
|
|
's' => $searchstring, |
825
|
|
|
'p' => 1, |
826
|
|
|
'num' => 3, |
827
|
|
|
'pop' => 1, |
828
|
|
|
'o' => 'd', |
829
|
|
|
]; |
830
|
|
|
$results = $hansard->search($searchstring, $args); |
831
|
|
|
$recent = serialize($results['rows']); |
832
|
|
|
$memcache->set('recent_appear:' . $person_id, $recent); |
833
|
|
|
} |
834
|
|
|
$out['appearances'] = unserialize($recent); |
835
|
|
|
twfy_debug_timestamp(); |
836
|
|
|
|
837
|
|
|
$MOREURL = new \MySociety\TheyWorkForYou\Url('search'); |
838
|
|
|
$MOREURL->insert(['pid' => $person_id, 'pop' => 1]); |
839
|
|
|
|
840
|
|
|
$out['more_href'] = $MOREURL->generate() . '#n4'; |
841
|
|
|
$out['more_text'] = sprintf(gettext('More of %s’s recent appearances'), ucfirst($member->full_name())); |
842
|
|
|
|
843
|
|
|
if ($rssurl = $DATA->page_metadata($this_page, 'rss')) { |
844
|
|
|
// If we set an RSS feed for this page. |
845
|
|
|
$HELPURL = new \MySociety\TheyWorkForYou\Url('help'); |
846
|
|
|
$out['additional_links'] = '<a href="' . WEBPATH . $rssurl . '" title="XML version of this person’s recent appearances">RSS feed</a> (<a href="' . $HELPURL->generate() . '#rss" title="An explanation of what RSS feeds are for">?</a>)'; |
847
|
|
|
} |
848
|
|
|
|
849
|
|
|
return $out; |
850
|
|
|
|
851
|
|
|
} |
852
|
|
|
|
853
|
|
|
function person_useful_links($member) { |
854
|
|
|
|
855
|
|
|
$links = $member->extra_info(); |
856
|
|
|
|
857
|
|
|
$out = []; |
858
|
|
|
|
859
|
|
|
if (isset($links['maiden_speech'])) { |
860
|
|
|
$maiden_speech = fix_gid_from_db($links['maiden_speech']); |
861
|
|
|
$out[] = [ |
862
|
|
|
'href' => WEBPATH . 'debate/?id=' . $maiden_speech, |
863
|
|
|
'text' => 'Maiden speech', |
864
|
|
|
]; |
865
|
|
|
} |
866
|
|
|
|
867
|
|
|
// BIOGRAPHY. |
868
|
|
|
global $THEUSER; |
869
|
|
|
if (isset($links['mp_website'])) { |
870
|
|
|
$out[] = [ |
871
|
|
|
'href' => $links['mp_website'], |
872
|
|
|
'text' => 'Personal website', |
873
|
|
|
]; |
874
|
|
|
} |
875
|
|
|
|
876
|
|
|
if (isset($links['sp_url'])) { |
877
|
|
|
$out[] = [ |
878
|
|
|
'href' => $links['sp_url'], |
879
|
|
|
'text' => 'Page on the Scottish Parliament website', |
880
|
|
|
]; |
881
|
|
|
} |
882
|
|
|
|
883
|
|
|
if (isset($links['wikipedia_url'])) { |
884
|
|
|
$out[] = [ |
885
|
|
|
'href' => $links['wikipedia_url'], |
886
|
|
|
'text' => 'Wikipedia page', |
887
|
|
|
]; |
888
|
|
|
} |
889
|
|
|
|
890
|
|
|
if (isset($links['bbc_profile_url'])) { |
891
|
|
|
$out[] = [ |
892
|
|
|
'href' => $links['bbc_profile_url'], |
893
|
|
|
'text' => 'BBC News profile', |
894
|
|
|
]; |
895
|
|
|
} |
896
|
|
|
|
897
|
|
|
if (isset($links['diocese_url'])) { |
898
|
|
|
$out[] = [ |
899
|
|
|
'href' => $links['diocese_url'], |
900
|
|
|
'text' => 'Diocese website', |
901
|
|
|
]; |
902
|
|
|
} |
903
|
|
|
|
904
|
|
|
return $out; |
905
|
|
|
} |
906
|
|
|
|
907
|
|
|
function person_social_links($member) { |
908
|
|
|
|
909
|
|
|
$links = $member->extra_info(); |
910
|
|
|
|
911
|
|
|
$out = []; |
912
|
|
|
|
913
|
|
|
|
914
|
|
|
if (isset($links['bluesky_handle'])) { |
915
|
|
|
$out[] = [ |
916
|
|
|
'href' => 'https://bsky.app/profile/' . _htmlentities($links['bluesky_handle']), |
917
|
|
|
'text' => '@' . _htmlentities($links['bluesky_handle']), |
918
|
|
|
'type' => 'bluesky', |
919
|
|
|
]; |
920
|
|
|
} |
921
|
|
|
|
922
|
|
|
if (isset($links['twitter_username'])) { |
923
|
|
|
$out[] = [ |
924
|
|
|
'href' => 'https://twitter.com/' . _htmlentities($links['twitter_username']), |
925
|
|
|
'text' => '@' . _htmlentities($links['twitter_username']), |
926
|
|
|
'type' => 'twitter', |
927
|
|
|
]; |
928
|
|
|
} |
929
|
|
|
|
930
|
|
|
if (isset($links['facebook_page'])) { |
931
|
|
|
$out[] = [ |
932
|
|
|
'href' => _htmlentities($links['facebook_page']), |
933
|
|
|
'text' => _htmlentities("Facebook"), |
934
|
|
|
'type' => 'facebook', |
935
|
|
|
]; |
936
|
|
|
} |
937
|
|
|
|
938
|
|
|
$official_keys = [ |
939
|
|
|
'profile_url_uk_parl' => 'UK Parliament Profile', |
940
|
|
|
'profile_url_scot_parl' => 'Scottish Parliament Profile', |
941
|
|
|
'profile_url_ni_assembly' => 'Northern Ireland Assembly Profile', |
942
|
|
|
]; |
943
|
|
|
|
944
|
|
|
if (LANGUAGE == 'cy') { |
|
|
|
|
945
|
|
|
$official_keys['profile_url_senedd_cy'] = 'Proffil Senedd'; |
946
|
|
|
} else { |
947
|
|
|
$official_keys['profile_url_senedd_en'] = 'Senedd Profile'; |
948
|
|
|
} |
949
|
|
|
|
950
|
|
|
foreach ($official_keys as $key => $text) { |
951
|
|
|
if (isset($links[$key])) { |
952
|
|
|
$out[] = [ |
953
|
|
|
'href' => $links[$key], |
954
|
|
|
'text' => $text, |
955
|
|
|
'type' => 'official', |
956
|
|
|
]; |
957
|
|
|
} |
958
|
|
|
} |
959
|
|
|
|
960
|
|
|
return $out; |
961
|
|
|
} |
962
|
|
|
|
963
|
|
|
function person_topics($member) { |
964
|
|
|
$out = []; |
965
|
|
|
|
966
|
|
|
$extra_info = $member->extra_info(); |
967
|
|
|
|
968
|
|
|
if (isset($extra_info['wrans_departments'])) { |
969
|
|
|
$subjects = explode(',', $extra_info['wrans_departments']); |
970
|
|
|
$out = array_merge($out, $subjects); |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
if (isset($extra_info['wrans_subjects'])) { |
974
|
|
|
$subjects = explode(',', $extra_info['wrans_subjects']); |
975
|
|
|
$out = array_merge($out, $subjects); |
976
|
|
|
} |
977
|
|
|
|
978
|
|
|
return $out; |
979
|
|
|
} |
980
|
|
|
|
981
|
|
|
function person_appg_memberships($member) { |
982
|
|
|
$out = []; |
983
|
|
|
|
984
|
|
|
$extra_info = $member->extra_info(); |
985
|
|
|
if (isset($extra_info['appg_membership'])) { |
986
|
|
|
$out = MySociety\TheyWorkForYou\DataClass\APPGs\APPGMembershipAssignment::fromJson($extra_info['appg_membership']); |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
return $out; |
990
|
|
|
} |
991
|
|
|
|
992
|
|
|
function person_statements($member) { |
993
|
|
|
$out = [ |
994
|
|
|
"edms" => null, |
995
|
|
|
"letter" => null, |
996
|
|
|
]; |
997
|
|
|
|
998
|
|
|
$extra_info = $member->extra_info(); |
999
|
|
|
if (isset($extra_info['edms_signed'])) { |
1000
|
|
|
$out["edms"] = MySociety\TheyWorkForYou\DataClass\Statements\SignatureList::fromJson($extra_info['edms_signed']); |
1001
|
|
|
} |
1002
|
|
|
if (isset($extra_info['letters_signed'])) { |
1003
|
|
|
$out["letters"] = MySociety\TheyWorkForYou\DataClass\Statements\SignatureList::fromJson($extra_info['letters_signed']); |
1004
|
|
|
} |
1005
|
|
|
|
1006
|
|
|
return $out; |
1007
|
|
|
} |
1008
|
|
|
|
1009
|
|
|
function memberships($member) { |
1010
|
|
|
$out = []; |
1011
|
|
|
|
1012
|
|
|
$committee_lookup = MySociety\TheyWorkForYou\DataClass\Groups\MiniGroupList::uk_committees(); |
1013
|
|
|
|
1014
|
|
|
$topics = person_topics($member); |
1015
|
|
|
if ($topics) { |
1016
|
|
|
$out['topics'] = $topics; |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
$posts = $member->offices('current', false, true); |
1020
|
|
|
if ($posts) { |
1021
|
|
|
// for each post we want to add the description and external_url from the committee lookup if possible |
1022
|
|
|
foreach ($posts as $post) { |
1023
|
|
|
$committee = $committee_lookup->findByName($post->dept); |
1024
|
|
|
if ($committee) { |
1025
|
|
|
$post->desc = $committee->description; |
1026
|
|
|
$post->external_url = $committee->external_url; |
1027
|
|
|
} |
1028
|
|
|
} |
1029
|
|
|
$out['posts'] = $posts; |
1030
|
|
|
} |
1031
|
|
|
|
1032
|
|
|
$posts = $member->offices('previous', false, true); |
1033
|
|
|
if ($posts) { |
1034
|
|
|
$out['previous_posts'] = $posts; |
1035
|
|
|
} |
1036
|
|
|
|
1037
|
|
|
$eu_stance = $member->getEUStance(); |
1038
|
|
|
if ($eu_stance) { |
1039
|
|
|
$out['eu_stance'] = $eu_stance; |
1040
|
|
|
} |
1041
|
|
|
|
1042
|
|
|
$topics_of_interest = person_topics($member); |
1043
|
|
|
if ($topics_of_interest) { |
1044
|
|
|
$out['topics_of_interest'] = $topics_of_interest; |
1045
|
|
|
} |
1046
|
|
|
|
1047
|
|
|
$appg_membership = person_appg_memberships($member); |
1048
|
|
|
if ($appg_membership) { |
1049
|
|
|
$out['appg_membership'] = $appg_membership; |
1050
|
|
|
} |
1051
|
|
|
|
1052
|
|
|
$statments_signed = person_statements($member); |
1053
|
|
|
if ($statments_signed) { |
1054
|
|
|
if (isset($statments_signed["edms"]) && $statments_signed["edms"]->count() > 0) { |
1055
|
|
|
$out['edms_signed'] = $statments_signed["edms"]; |
1056
|
|
|
} |
1057
|
|
|
if (isset($statments_signed["letters"]) && $statments_signed["letters"]->count() > 0) { |
1058
|
|
|
$out['letters_signed'] = $statments_signed["letters"]; |
1059
|
|
|
} |
1060
|
|
|
} |
1061
|
|
|
|
1062
|
|
|
return $out; |
1063
|
|
|
} |
1064
|
|
|
|
1065
|
|
|
function constituency_previous_mps($member) { |
1066
|
|
|
if ($member->house(HOUSE_TYPE_COMMONS)) { |
1067
|
|
|
return $member->previous_mps(); |
1068
|
|
|
} else { |
1069
|
|
|
return []; |
1070
|
|
|
} |
1071
|
|
|
} |
1072
|
|
|
|
1073
|
|
|
function constituency_future_mps($member) { |
1074
|
|
|
if ($member->house(HOUSE_TYPE_COMMONS)) { |
1075
|
|
|
return $member->future_mps(); |
1076
|
|
|
} else { |
1077
|
|
|
return []; |
1078
|
|
|
} |
1079
|
|
|
} |
1080
|
|
|
|
1081
|
|
|
function person_pbc_membership($member) { |
1082
|
|
|
|
1083
|
|
|
$extra_info = $member->extra_info(); |
1084
|
|
|
$out = ['info' => '', 'data' => []]; |
1085
|
|
|
|
1086
|
|
|
# Public Bill Committees |
1087
|
|
|
if (count($extra_info['pbc'])) { |
1088
|
|
|
if ($member->party() == 'Scottish National Party') { |
1089
|
|
|
$out['info'] = 'SNP MPs only attend sittings where the legislation pertains to Scotland.'; |
1090
|
|
|
} |
1091
|
|
|
foreach ($extra_info['pbc'] as $bill_id => $arr) { |
1092
|
|
|
$text = ''; |
1093
|
|
|
if ($arr['chairman']) { |
1094
|
|
|
$text .= 'Chairman, '; |
1095
|
|
|
} |
1096
|
|
|
$text .= $arr['title'] . ' Committee'; |
1097
|
|
|
$out['data'][] = [ |
1098
|
|
|
'href' => '/pbc/' . $arr['session'] . '/' . urlencode($arr['title']), |
1099
|
|
|
'text' => $text, |
1100
|
|
|
'attending' => $arr['attending'] . ' out of ' . $arr['outof'], |
1101
|
|
|
]; |
1102
|
|
|
} |
1103
|
|
|
} |
1104
|
|
|
|
1105
|
|
|
return $out; |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
function person_register_interests_from_key($key, $extra_info): ?MySociety\TheyWorkForYou\DataClass\Regmem\Person { |
1109
|
|
|
$lang = LANGUAGE; |
|
|
|
|
1110
|
|
|
$reg = null; |
1111
|
|
|
if (isset($extra_info[$key])) { |
1112
|
|
|
$reg = MySociety\TheyWorkForYou\DataClass\Regmem\Person::fromJson($extra_info[$key]); |
1113
|
|
|
} |
1114
|
|
|
return $reg; |
1115
|
|
|
} |
1116
|
|
|
|
1117
|
|
|
function person_register_interests($member, $extra_info) { |
|
|
|
|
1118
|
|
|
|
1119
|
|
|
$valid_chambers = ['house-of-commons', 'scottish-parliament', 'northern-ireland-assembly', 'senedd']; |
1120
|
|
|
|
1121
|
|
|
$lang = LANGUAGE; |
1122
|
|
|
|
1123
|
|
|
$reg = ['chamber_registers' => [] ]; |
1124
|
|
|
|
1125
|
|
|
foreach ($valid_chambers as $chamber) { |
1126
|
|
|
$key = 'person_regmem_' . $chamber . '_' . $lang; |
1127
|
|
|
$chamber_register = person_register_interests_from_key($key, $extra_info); |
1128
|
|
|
if ($chamber_register) { |
1129
|
|
|
$reg['chamber_registers'][$chamber] = $chamber_register; |
1130
|
|
|
} |
1131
|
|
|
} |
1132
|
|
|
// if chamber_registers is empty, we don't have any data |
1133
|
|
|
if (empty($reg['chamber_registers'])) { |
1134
|
|
|
return; |
1135
|
|
|
} |
1136
|
|
|
|
1137
|
|
|
// sort chamber registers by published_date |
1138
|
|
|
uasort($reg['chamber_registers'], function ($a, $b) { |
1139
|
|
|
return $a->published_date <=> $b->published_date; |
1140
|
|
|
}); |
1141
|
|
|
|
1142
|
|
|
return $reg; |
1143
|
|
|
} |
1144
|
|
|
|
1145
|
|
|
function regional_list($pc, $area_type, $rep_type) { |
1146
|
|
|
$constituencies = MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($pc); |
1147
|
|
|
if ($constituencies == 'CONNECTION_TIMED_OUT') { |
1148
|
|
|
throw new MySociety\TheyWorkForYou\MemberException('Sorry, we couldn’t check your postcode right now, as our postcode lookup server is under quite a lot of load.'); |
1149
|
|
|
} elseif (!$constituencies) { |
1150
|
|
|
throw new MySociety\TheyWorkForYou\MemberException('Sorry, ' . htmlentities($pc) . ' isn’t a known postcode'); |
1151
|
|
|
} elseif (!isset($constituencies[$area_type])) { |
1152
|
|
|
throw new MySociety\TheyWorkForYou\MemberException(htmlentities($pc) . ' does not appear to be a valid postcode'); |
1153
|
|
|
} |
1154
|
|
|
global $PAGE; |
1155
|
|
|
$a = array_values($constituencies); |
|
|
|
|
1156
|
|
|
$db = new ParlDB(); |
1157
|
|
|
$query_base = "SELECT member.person_id, given_name, family_name, constituency, house |
1158
|
|
|
FROM member, person_names pn |
1159
|
|
|
WHERE constituency IN ('" . join("','", $a) . "') |
1160
|
|
|
AND member.person_id = pn.person_id AND pn.type = 'name' |
1161
|
|
|
AND pn.end_date = (SELECT MAX(end_date) FROM person_names WHERE person_names.person_id = member.person_id)"; |
1162
|
|
|
$q = $db->query($query_base . " AND left_reason = 'still_in_office' AND house in (" . HOUSE_TYPE_NI . "," . HOUSE_TYPE_SCOTLAND . "," . HOUSE_TYPE_WALES . ")"); |
1163
|
|
|
$current = true; |
1164
|
|
|
if (!$q->rows() && ($dissolution = MySociety\TheyWorkForYou\Dissolution::db())) { |
1165
|
|
|
$current = false; |
1166
|
|
|
$q = $db->query( |
1167
|
|
|
$query_base . " AND $dissolution[query]", |
1168
|
|
|
$dissolution['params'] |
1169
|
|
|
); |
1170
|
|
|
} |
1171
|
|
|
$mcon = []; |
1172
|
|
|
$mreg = []; |
1173
|
|
|
foreach ($q as $row) { |
1174
|
|
|
$house = $row['house']; |
1175
|
|
|
$cons = $row['constituency']; |
1176
|
|
|
if ($house == HOUSE_TYPE_COMMONS) { |
1177
|
|
|
continue; |
1178
|
|
|
} elseif ($house == HOUSE_TYPE_NI) { |
1179
|
|
|
$mreg[] = $row; |
1180
|
|
|
} elseif ($house == HOUSE_TYPE_SCOTLAND) { |
1181
|
|
|
if ($cons == $constituencies['SPC']) { |
1182
|
|
|
$mcon = $row; |
1183
|
|
|
} elseif ($cons == $constituencies['SPE']) { |
1184
|
|
|
$mreg[] = $row; |
1185
|
|
|
} |
1186
|
|
|
} elseif ($house == HOUSE_TYPE_WALES) { |
1187
|
|
|
if ($cons == $constituencies['WAC']) { |
1188
|
|
|
$mcon = $row; |
1189
|
|
|
} elseif ($cons == $constituencies['WAE']) { |
1190
|
|
|
$mreg[] = $row; |
1191
|
|
|
} |
1192
|
|
|
} else { |
1193
|
|
|
throw new MySociety\TheyWorkForYou\MemberException('Odd result returned!' . $house); |
1194
|
|
|
} |
1195
|
|
|
} |
1196
|
|
|
if ($rep_type == 'msp') { |
1197
|
|
|
$name = $mcon['given_name'] . ' ' . $mcon['family_name']; |
1198
|
|
|
$cons = $mcon['constituency']; |
1199
|
|
|
$reg = $constituencies['SPE']; |
1200
|
|
|
$url = '/msp/?p=' . $mcon['person_id']; |
1201
|
|
|
if ($current) { |
1202
|
|
|
$data['members_statement'] = '<p>You have one constituency MSP (Member of the Scottish Parliament) and multiple region MSPs.</p>'; |
|
|
|
|
1203
|
|
|
$data['members_statement'] .= '<p>' . sprintf('Your <strong>constituency MSP</strong> is <a href="%s">%s</a>, MSP for %s.', $url, $name, $cons) . '</p>'; |
1204
|
|
|
$data['members_statement'] .= '<p>' . sprintf('Your <strong>%s region MSPs</strong> are:', $reg) . '</p>'; |
1205
|
|
|
} else { |
1206
|
|
|
$data['members_statement'] = '<p>' . 'You had one constituency MSP (Member of the Scottish Parliament) and multiple region MSPs.' . '</p>'; |
1207
|
|
|
$data['members_statement'] .= '<p>' . sprintf('Your <strong>constituency MSP</strong> was <a href="%s">%s</a>, MSP for %s.', $url, $name, $cons) . '</p>'; |
1208
|
|
|
$data['members_statement'] .= '<p>' . sprintf('Your <strong>%s region MSPs</strong> were:', $reg) . '</p>'; |
1209
|
|
|
} |
1210
|
|
|
} elseif ($rep_type == 'ms') { |
1211
|
|
|
$name = $mcon['given_name'] . ' ' . $mcon['family_name']; |
1212
|
|
|
$cons = gettext($mcon['constituency']); |
1213
|
|
|
$reg = gettext($constituencies['WAE']); |
1214
|
|
|
$url = '/ms/?p=' . $mcon['person_id']; |
1215
|
|
|
if ($current) { |
1216
|
|
|
$data['members_statement'] = '<p>' . gettext('You have one constituency MS (Member of the Senedd) and multiple region MSs.') . '</p>'; |
1217
|
|
|
$data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>constituency MS</strong> is <a href="%s">%s</a>, MS for %s.'), $url, $name, $cons) . '</p>'; |
1218
|
|
|
$data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>%s region MSs</strong> are:'), $reg) . '</p>'; |
1219
|
|
|
} else { |
1220
|
|
|
$data['members_statement'] = '<p>' . gettext('You had one constituency MS (Member of the Senedd) and multiple region MSs.') . '</p>'; |
1221
|
|
|
$data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>constituency MS</strong> was <a href="%s">%s</a>, MS for %s.'), $url, $name, $cons) . '</p>'; |
1222
|
|
|
$data['members_statement'] .= '<p>' . sprintf(gettext('Your <strong>%s region MSs</strong> were:'), $reg) . '</p>'; |
1223
|
|
|
} |
1224
|
|
|
} else { |
1225
|
|
|
if ($current) { |
1226
|
|
|
$data['members_statement'] = '<p>You have multiple MLAs (Members of the Legislative Assembly) who represent you in ' . $constituencies['NIE'] . '. They are:</p>'; |
1227
|
|
|
} else { |
1228
|
|
|
$data['members_statement'] = '<p>You had multiple MLAs (Members of the Legislative Assembly) who represented you in ' . $constituencies['NIE'] . '. They were:</p>'; |
1229
|
|
|
} |
1230
|
|
|
} |
1231
|
|
|
|
1232
|
|
|
foreach($mreg as $reg) { |
1233
|
|
|
$data['members'][] = [ |
1234
|
|
|
'url' => '/' . $rep_type . '/?p=' . $reg['person_id'], |
1235
|
|
|
'name' => $reg['given_name'] . ' ' . $reg['family_name'], |
1236
|
|
|
]; |
1237
|
|
|
|
1238
|
|
|
} |
1239
|
|
|
|
1240
|
|
|
// Send the output for rendering |
1241
|
|
|
MySociety\TheyWorkForYou\Renderer::output('mp/regional_list', $data); |
1242
|
|
|
|
1243
|
|
|
} |
1244
|
|
|
|