Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Voting copy tweaks #1782

Merged
merged 12 commits into from
Mar 27, 2024
2 changes: 1 addition & 1 deletion .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php_version: ["7.3", "7.4", "8.2"]
php_version: ["7.4", "8.2"]

services:
mariadb:
Expand Down
26 changes: 26 additions & 0 deletions classes/Divisions.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,24 @@ public function getMemberDivisionDetails($strong_only = false) {
$policy_divisions[$policy_id] = $summary;
}

// for each key in $policy_divisions, we want to add agreement information

$policies_list = new \MySociety\TheyWorkForYou\Policies();
foreach ($policy_divisions as $policy_id => &$summary) {
$agreement_details = $this->member->member_agreements($policy_id, HOUSE_TYPE_COMMONS, $policies_list );
$summary["agreements_for"] = 0;
$summary["agreements_against"] = 0;
foreach ($agreement_details as $agreement){
if ($strong_only == true & $agreement["strength"] != "strong") {
continue;
}
if ($agreement["alignment"] == "agree") {
$summary["agreements_for"] += 1;
} else {
$summary["agreements_against"] += 1;
}
}
}
return $policy_divisions;
}

Expand Down Expand Up @@ -468,6 +486,14 @@ public function generateSummary($votes) {
$votes['against'] . ' ' . make_plural('vote', $votes['against']) . ' against'
);

if ( $votes['agreements_for']) {
$actions[] = $votes['agreements_for'] . ' ' . make_plural('agreement', $votes['agreements_for']) . ' for';
}

if ( $votes['agreements_against']) {
$actions[] = $votes['agreements_against'] . ' ' . make_plural('agreement', $votes['agreements_against']) . ' against';
}

if ( $votes['both'] ) {
$actions[] = $votes['both'] . ' ' . make_plural('abstention', $votes['both']);
}
Expand Down
60 changes: 39 additions & 21 deletions classes/Policies.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,41 @@ class Policies {
private $db;

private $policy_id;
/**
* @var array $policies key-value of policy id to the context description.
* e.g. "363": "introducing <b>foundation hospitals</b>"
*/
private array $policies;

/**
* @var array $sets - key-value pair of a set slug to an array of policy IDs
* in that set.
* e.g. "foreignpolicy": ["975", "984"[]
*/
private array $sets;

/**
* @var array $set_descs - key-value pairs of a set slug to a description
* of that set.
* e.g. "foreignpolicy": "Foreign Policy"
*/
private array $set_descs;

/**
* @var array $all_policy_agreements - key-value pair of a policy ID to
* an array of
* agreements links.
* e.g. "1030": [{
* "division_name": "Approval of SI setting 2050 Net Zero target date",
* "alignment": "agree",
* "gid": "2019-06-24b.530.1",
* "url": "/debates/?id=2019-06-24b.530.1",
* "house": "commons",
* "strength": "strong",
* "date": "2019-06-24"
* }]
*/
public array $all_policy_agreements;

public function __construct($policy_id = null) {
$this->db = new \ParlDB;
Expand All @@ -40,27 +75,6 @@ public function __construct($policy_id = null) {
$this->set_descs = $policy_data['set_descs'];
$this->sets = $policy_data['sets'];

$this->sets['summary'] = array(
1113,
1136,
1132,
1052,
1109,
1110,
1027,
1084,
1065,
6670,
6673,
6674,
6678,
984,
837,
1079,
6671,
6672,
);

$this->all_policy_agreements = $policy_data['agreements'] ?? [];

if ( $policy_id ) {
Expand All @@ -79,6 +93,10 @@ public function getPolicies() {
return $this->policies;
}

public function getPolicyIDs() {
return array_keys($this->policies);
}

public function getSetDescriptions() {
return $this->set_descs;
}
Expand Down
8 changes: 4 additions & 4 deletions markdown/voting-information.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ In general, [we think it should be easier for MPs to vote](https://www.mysociety

MPs may be absent from a specific vote for many different reasons. Except where there is a narrow majority (or a minority) government, the outcome of a particular vote is generally predetermined by the government having more MPs than the opposition. As such, formal and informal mechanisms exist so that MPs can do other useful things with their time, resulting in fewer MPs voting: in practice the outcome is the same as if everyone was present.

The party managers (or ‘Whips’) collectively deal with absences by giving MPs permission to be absent, and ‘pairing’ them with someone from the other side — so while these MPs don’t vote, their absence has no effect on the result. However, this informal mechanism is not a right - and denying requests for absence (‘slips’) can be used as a form of punishment for MPs who have rebelled in other aspects.
The party managers (or ‘Whips’) collectively deal with absences by giving MPs permission to be absent, and ‘pairing’ them with someone from the other side — so while these MPs don’t vote, their absence has no effect on the result. However, this informal mechanism is not a right - and denying requests for absence (‘slips’) can be used as a form of punishment for MPs who have rebelled in other votes or are otherwise out of favour.

MPs may also be absent for longer periods during parental leave or sickness. Greater availability of ‘proxy voting’, where an MP's vote can be cast by another MP, has reduced (if not entirely closed) the problem that the previous informal mechanisms had created, of periods of absence in voting records.
MPs may also be absent for longer periods during parental leave or sickness. Greater availability of ‘proxy voting’, where an MP's vote can be cast by another MP, has reduced (if not entirely solved) the problem of periods of absence in voting records that the previous informal mechanisms had created.

But MPs may also be absent deliberately as a political decision. When party instructions are to attend and vote, not attending may be a lighter form of rebellion. In the absence of information about those party instructions (and allowed absences), we cannot determine the exact meaning of a particular absence. In our voting summaries, we do not count absences because we cannot be clear on how they should be interpreted — and especially historically, long absences may reflect a period of illness or maternity leave.

Expand Down Expand Up @@ -186,8 +186,8 @@ We are being conservative in how we apply this approach, and will review feedbac


### Votes are not opinions, but they matter
A complaint made about voting records is that they suggest MPs personally agree with what they are voting for.
In practice, MPs may be willing to vote for issues they disagree with in the interests of being a team player who can advance and be in a position to make more decisions. MPs can see voting, the area of their work the party tries to direct the most, as an unfair thing to be personally judged on when compared to the interests and projects they advance where they have the most individual freedom.
One complaint made about voting records is that they suggest MPs personally agree with what they are voting for.
In practice, MPs may be willing to vote for issues they disagree with in the interests of being a team player who can advance and be in a position to make more decisions. MPs can see voting, the area of their work the party tries to control the most, as an unfair thing to be personally judged on, compared to the more individual interests and work they spend much of their time on.

Our focus on “votes that do things” is about being clear why we think it is important to track and highlight voting records. These are votes that matter, and change how the country works.

Expand Down
2 changes: 0 additions & 2 deletions scripts/mpinfoin.pl
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,6 @@
chdir $FindBin::Bin;
print " Lords biographies\n" if $verbose;
$twig->parsefile($pwmembers . 'lordbiogs.xml', ErrorContext => 2);
print " Journalisted\n" if $verbose;
$twig->parsefile($pwmembers . 'journa-list.xml', ErrorContext => 2);
}

if ($action{'pw'}) {
Expand Down
19 changes: 5 additions & 14 deletions www/docs/mp/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@
$data['policy_last_update'] = MySociety\TheyWorkForYou\Divisions::getMostRecentDivisionDate();

$data['comparison_party'] = $MEMBER->cohortParty();
$data['unslugified_comparison_party'] = ucwords(str_replace('-', ' ', $data['comparison_party']));

// is the party we're comparing this MP to different from the party they're currently in?
$data['party_switcher'] = (slugify($data['current_party_comparison']) != slugify($data["comparison_party"]));

// Do any necessary extra work based on the page type, and send for rendering.
switch ($pagetype) {
Expand Down Expand Up @@ -447,13 +451,7 @@ function($k) { return $k['score_difference'] >= 2; }

if ( $policyID ) {
$data['policydivisions'] = $divisions->getMemberDivisionsForPolicy($policyID);
$rel_agreements = $policiesList->all_policy_agreements[$policyID] ?? [];
// filter down to where 'date' is within the member's term
// This won't be perfect where the member has been in and out of the house
// But it doesn't affect their score.
$rel_agreements = array_filter($rel_agreements, function($agreement) use ($MEMBER) {
return $MEMBER->date_in_memberships(HOUSE_TYPE_COMMONS, $agreement['date']);
});
$rel_agreements = $MEMBER->member_agreements($policyID, HOUSE_TYPE_COMMONS, $policiesList);
$data['policyagreements'] = array($policyID => $rel_agreements);
} else {
$data['policydivisions'] = $divisions->getAllMemberDivisionsByPolicy();
Expand Down Expand Up @@ -898,13 +896,6 @@ function person_useful_links($member) {
);
}

if (isset($links['journa_list_link'])) {
$out[] = array(
'href' => $links['journa_list_link'],
'text' => 'Newspaper articles written by this MP'
);
}

return $out;
}

Expand Down
5 changes: 5 additions & 0 deletions www/docs/style/sass/pages/_mp.scss
Original file line number Diff line number Diff line change
Expand Up @@ -781,3 +781,8 @@ a[href^="https://www.publicwhip.org"] {
margin-bottom: em-calc(30);
}
}

.person-panels .panel ul.rep-actions {
list-style: disc;
margin-left: 1.2em;
}
17 changes: 17 additions & 0 deletions www/includes/easyparliament/member.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

include_once INCLUDESPATH."easyparliament/glossary.php";

use MySociety\TheyWorkForYou\Policies as Policies;


class MEMBER {

public $valid = false;
Expand Down Expand Up @@ -242,6 +245,20 @@ public function date_in_memberships($house, $date){
return false;
}

public function member_agreements(int $policyID, int $house = HOUSE_TYPE_COMMONS, Policies $policiesList = null) {
// agreements that a member has been present for on a specific policy.
// Pass in a Policies object to avoid reloading the list of policies.
// Ideally one that has been initalised without a specific policy id.
if (!$policiesList) {
$policiesList = new Policies($policyID);
}
$rel_agreements = $policiesList->all_policy_agreements[$policyID] ?? [];
$rel_agreements = array_filter($rel_agreements, function($agreement) use ($house) {
return $this->date_in_memberships($house, $agreement['date']);
});
return $rel_agreements;
}

public function member_id_to_person_id($member_id) {
$q = $this->db->query("SELECT person_id FROM member
WHERE member_id = :member_id",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
<h2>
What you can do
</h2>
<ul class="rep-actions" style="li: > list-style: default">
<li>Find out <a href="#profile">more about your MP</a>, including <a href="<?= $member_url ?>/votes">their voting summary</a> and <a href="#appearances">recent speeches</a>.</li>
<ul class="rep-actions">
<li>Find out <a href="#profile">more about your MP</a>, including <a href="<?= $member_url ?>/votes">their voting summary</a><?php if ($register_interests) { ?>, <a href="#register">register of interests</a><?php } ?> and <a href="#appearances">recent speeches</a>.</li>
<li><a href="https://www.writetothem.com/">Write to your MP</a>, or find out about your other local representatives <a href="https://www.writetothem.com">on WriteToThem.com</a>.</li>
<li>Find out more about <a href="https://www.localintelligencehub.com/area/WMC/<?= $latest_membership['constituency'] ?>"><?= $latest_membership['constituency'] ?></a> on the <a href="https://www.localintelligencehub.com/">Local Intelligence Hub</a>.</li>
</ul>
Expand All @@ -29,7 +29,7 @@
<h2>
What you can do
</h2>
<ul class="rep-actions" style="li: > list-style: default">
<ul class="rep-actions">
<li>Find out <a href="#profile">more about your MP</a>, including <a href="#appearances">their speeches</a>.</li>
</div>
<?php }; ?>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

<h3>Voting records for MPs who change parties / have whip withdrawn</h3>
<p>This MP has either become an independent MP, changed parties, or had the party whip withdrawn over the course of their time in Parliament.
In the votes below they are compared to their original party (<?= $comparison_party ?>).<p>
In the votes below they are compared to their original party (<?= $unslugified_comparison_party ?>).<p>

</div>
7 changes: 4 additions & 3 deletions www/includes/easyparliament/templates/html/mp/profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,17 @@
<div class="panel register">
<a name="register"></a>
<h2>Register of Members&rsquo; Interests</h2>
<p><b>New</b>: <a href="https://www.mysociety.org/2024/01/17/improving-the-register-of-mps-interests/">Download a spreadsheet of all Members Interests.</a></p>

<p>
<a href="<?= WEBPATH ?>regmem/?p=<?= $person_id ?>">View the history of this MP&rsquo;s entries in the Register</a>
</p>
<?php if ($register_interests['date']): ?>
<p>Last updated: <?= $register_interests['date'] ?>.</p>
<?php endif; ?>

<?= $register_interests['data'] ?>

<p>
<a href="<?= WEBPATH ?>regmem/?p=<?= $person_id ?>">View the history of this MP&rsquo;s entries in the Register</a>
</p>

<p>
<a class="moreinfo-link" href="https://www.publications.parliament.uk/pa/cm/cmregmem/100927/introduction.htm">More about the register</a>
Expand Down
32 changes: 24 additions & 8 deletions www/includes/easyparliament/templates/html/mp/votes.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
<p>
On TheyWorkForYou, we create voting summaries that group a set of decisions together, show how an MP has generally voted on a set of related votes, and if they differ from their party.
</p>
<p>
You can see these groups, randomly ordered, below.
</p>
<p>
You can read more about <a href="/voting-information/#voting-summaries">how this works</a>, <a href="/voting-information/#what-kind-of-votes-are-included-in-theyworkforyou-s-policies">the kinds of votes we include</a>, <a href="/voting-information/#comparison-to-parties">how we compare MPs to parties</a>, and <a href="/voting-information/#votes-are-not-opinions-but-they-matter">why we think this is important</a>.</a>
</p>
Expand All @@ -54,8 +57,8 @@
</p>
</div>

<?php if (slugify($current_party_comparison) <> slugify($data["comparison_party"])): ?>
<?php include('_cross_party_mp_panel.php'); ?>
<?php if ($party_switcher == true): ?>
<?php include('_cross_party_mp_panel.php'); ?>
<?php endif; ?>

<?php if ($party == 'Sinn Féin' && in_array(HOUSE_TYPE_COMMONS, $houses)): ?>
Expand All @@ -75,15 +78,27 @@
<a name="votes"></a>
<h2><?= $full_name ?>&rsquo;s voting in Parliament</h2>

<p>
<?= $full_name ?> is a <?= $party ?> MP, and on the <b>vast majority</b> of issues <a href="/voting-information/#party-and-individual-responsibility-for-decisions">follow instructions from their party</a> and vote the <b>same way</b> as other <?= $party ?> MPs.
</p>
<?php if ($party_switcher == true) { ?>
<p>
<?= $full_name ?> was previously a <?= $unslugified_comparison_party ?> MP, and on the <b>vast majority</b> of issues <a href="/voting-information/#party-and-individual-responsibility-for-decisions">would have followed instructions from their party</a> and voted the <b>same way</b> as <?= $unslugified_comparison_party ?> MPs.
</p>
<?php } else { ?>
<p>
<?= $full_name ?> is a <?= $unslugified_comparison_party ?> MP, and on the <b>vast majority</b> of issues <a href="/voting-information/#party-and-individual-responsibility-for-decisions">follow instructions from their party</a> and vote the <b>same way</b> as other <?= $unslugified_comparison_party ?> MPs.
</p>
<?php } ?>


<?php if (count($sorted_diffs_only) > 0) { ?>
<p>
However, <?= $full_name ?> sometimes <b>differs</b> from their party colleagues, such as:
</p>
<?php if ($party_switcher == true) { ?>
<p>
However, <?= $full_name ?> sometimes <b>differs</b> from <?= $unslugified_comparison_party ?> MPs, such as:
</p>
<?php } else { ?>
<p>
However, <?= $full_name ?> sometimes <b>differs</b> from their party colleagues, such as:
</p>
<?php } ?>

<ul class="vote-descriptions">
<?php foreach ($sorted_diffs_only as $policy_id => $diff) {
Expand Down Expand Up @@ -146,6 +161,7 @@
<small><a class="nav-anchor" href="<?= $member_url ?>/votes#<?= $segment['key'] ?>">#</a></small>
</h2>

<p>For votes held while they were in office:</p>

<ul class="vote-descriptions">
<?php foreach ($segment['votes']->positions as $key_vote) {
Expand Down
Loading