Skip to content

Commit

Permalink
new forms for editing keyword and speaker alerts
Browse files Browse the repository at this point in the history
This splits out the two forms to have a multi step one for keyword
alerts that allows easier access to exlusions, limiting to sections and
also to limit it to a speaker.

The speaker only form handle the rest (search by postcode, name and
constituency) but only does when x speaks.
  • Loading branch information
struan committed Oct 24, 2024
1 parent c861390 commit 5a0a625
Show file tree
Hide file tree
Showing 9 changed files with 905 additions and 450 deletions.
200 changes: 185 additions & 15 deletions classes/AlertView/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ public function display() {
$this->checkInput();
$this->searchForConstituenciesAndMembers();

if (!sizeof($this->data['errors']) && ($this->data['keyword'] || $this->data['pid'])) {
if ($this->data['step'] || $this->data['addword']) {
$this->processStep();
} elseif (!$this->data['results'] == 'changes-abandoned' && !sizeof($this->data['errors']) && ($this->data['keyword'] || $this->data['pid'])) {
$this->addAlert();
}

Expand All @@ -48,7 +50,8 @@ private function processAction() {
$success = $this->confirmAlert($token);
if ($success) {
$this->data['results'] = 'alert-confirmed';
$this->data['criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria);
$this->data['criteria'] = $this->alert->criteria;
$this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria);
}
} elseif ($action == 'Suspend') {
$success = $this->suspendAlert($token);
Expand All @@ -70,6 +73,8 @@ private function processAction() {
if ($success) {
$this->data['results'] = 'all-alerts-deleted';
}
} elseif ($action == 'Abandon') {
$this->data['results'] = 'changes-abandoned';
}
if (!$success) {
$this->data['results'] = 'alert-fail';
Expand All @@ -79,6 +84,25 @@ private function processAction() {
$this->data['alert'] = $alert;
}

private function processStep() {
if ($this->data['step'] == 'confirm') {
$success = true;
if ($this->data['alert']) {
$success = $this->updateAlert($this->data['alert']['id'], $this->data);
if ($success) {
$this->data['results'] = 'alert-confirmed';
$this->data['step'] = '';
} else {
$this->data['results'] = 'alert-fail';
$this->data['step'] = 'review';
}
} else {
$success = $this->addAlert();
$this->data['step'] = '';
}
}
}


private function getBasicData() {
global $this_page;
Expand All @@ -93,12 +117,66 @@ private function getBasicData() {
$this->data["email"] = trim(get_http_var("email"));
$this->data['email_verified'] = false;
}
$this->data['keyword'] = trim(get_http_var("keyword"));

$this->data['token'] = get_http_var('t');
$this->data['step'] = trim(get_http_var("step"));
$this->data['addword'] = trim(get_http_var("addword"));
$this->data['this_step'] = trim(get_http_var("this_step"));

if ($this->data['addword'] || $this->data['step']) {
$alert = $this->alert->check_token($this->data['token']);

$criteria = '';
if ($alert) {
$criteria = $alert['criteria'];
}

$this->data['alert'] = $alert;

$this->data['alert_parts'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($criteria, true);

$existing_rep = '';
if (isset($this->data['alert_parts']['spokenby'])) {
$existing_rep = $this->data['alert_parts']['spokenby'][0];
}

$existing_section = '';
if (count($this->data['alert_parts']['sections'])) {
$existing_section = $this->data['alert_parts']['sections'][0];
}

$words = get_http_var('words', $this->data['alert_parts']['words'], true);

$this->data['words'] = [];
$this->data['keywords'] = [];
foreach ($words as $word) {
if (trim($word) != '') {
$this->data['keywords'][] = $word;
$this->data['words'][] = $this->wrap_phrase_in_quotes($word);
}
}
$this->data['exclusions'] = trim(get_http_var("exclusions", implode('', $this->data['alert_parts']['exclusions'])));
$this->data['representative'] = trim(get_http_var("representative", $existing_rep));

$this->data['search_section'] = trim(get_http_var("search_section", $existing_section));

$this->data['keyword'] = implode(' ', $this->data['words']);
if ($this->data['exclusions']) {
$this->data['keyword'] .= " -" . $this->data["exclusions"];
}

$this->data['results'] = '';

$this->getSearchSections();
} else {
$this->data['keyword'] = trim(get_http_var("keyword"));
$this->data['search_section'] = '';
}

$this->data['pid'] = trim(get_http_var("pid"));
$this->data['alertsearch'] = trim(get_http_var("alertsearch"));
$this->data['pc'] = get_http_var('pc');
$this->data['submitted'] = get_http_var('submitted') || $this->data['pid'] || $this->data['keyword'];
$this->data['token'] = get_http_var('t');
$this->data['submitted'] = get_http_var('submitted') || $this->data['pid'] || $this->data['keyword'] || $this->data['step'];
$this->data['sign'] = get_http_var('sign');
$this->data['site'] = get_http_var('site');
$this->data['message'] = '';
Expand All @@ -108,11 +186,45 @@ private function getBasicData() {
$this->data['actionurl'] = $ACTIONURL->generate();
}

private function checkInput() {
private function wrap_phrase_in_quotes($phrase) {
if (strpos($phrase, ' ') > 0) {
$phrase = '"' . trim($phrase, '"') . '"';
}

return $phrase;
}

private function getRecentResults($text) {
global $SEARCHENGINE;
$se = new \SEARCHENGINE($text);
$this->data['search_result_count'] = $se->run_count(0, 10);
$se->run_search(0, 1, 'date');
}

private function getSearchSections() {
$this->data['sections'] = [];
if ($this->data['search_section']) {
foreach (explode(' ', $this->data['search_section']) as $section) {
$this->data['sections'][] = \MySociety\TheyWorkForYou\Utility\Alert::sectionToTitle($section);
}
}
}

protected function updateAlert($token) {
$success = $this->alert->update($token, $this->data);
return $success;
}

protected function checkInput() {
global $SEARCHENGINE;

$errors = [];

if ($this->data['step'] == 'define' || $this->data['step'] == 'mp_alert') {
$this->data['errors'] = $errors;
return;
}

// Check each of the things the user has input.
// If there is a problem with any of them, set an entry in the $errors array.
// This will then be used to (a) indicate there were errors and (b) display
Expand Down Expand Up @@ -155,11 +267,32 @@ private function checkInput() {
$this->data['errors'] = $errors;
}

private function searchForConstituenciesAndMembers() {
// Do the search
if ($this->data['alertsearch']) {
protected function searchForConstituenciesAndMembers() {
if ($this->data['results'] == 'changes-abandoned') {
return;
}
$errors = [];
if ($this->data['alertsearch'] != '') {
$this->data['members'] = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($this->data['alertsearch'], true);
[$this->data['constituencies'], $this->data['valid_postcode']] = \MySociety\TheyWorkForYou\Utility\Search::searchConstituenciesByQuery($this->data['alertsearch']);
} elseif ($this->data['pid']) {
$MEMBER = new \MEMBER(['person_id' => $this->data['pid']]);
$this->data['members'] = [[
"person_id" => $MEMBER->person_id,
"given_name" => $MEMBER->given_name,
"family_name" => $MEMBER->family_name,
]];
} elseif (isset($this->data['representative']) && $this->data['representative'] != '') {
$this->data['members'] = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($this->data['representative'], true);

$member_count = count($this->data['members']);
if ($member_count == 0) {
$errors["representative"] = gettext("No matching representative found");
} elseif ($member_count > 1) {
$errors["representative"] = gettext("Multiple matching representatives found, please select one.");
} else {
$this->data['pid'] = $this->data['members'][0]['person_id'];
}
} else {
$this->data['members'] = [];
}
Expand All @@ -186,9 +319,15 @@ private function searchForConstituenciesAndMembers() {
}
$this->data['constituencies'] = $cons;
}

if (count($this->data["errors"]) > 0) {
$this->data["errors"] = array_merge($this->data["errors"], $errors);
} else {
$this->data["errors"] = $errors;
}
}

private function addAlert() {
protected function addAlert() {
$external_auth = auth_verify_with_shared_secret($this->data['email'], OPTION_AUTH_SHARED_SECRET, get_http_var('sign'));
if ($external_auth) {
$confirm = false;
Expand Down Expand Up @@ -230,11 +369,12 @@ private function addAlert() {
$this->data['pc'] = '';

$this->data['results'] = $result;
$this->data['criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria);
$this->data['criteria'] = $this->alert->criteria;
$this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria);
}


private function formatSearchTerms() {
protected function formatSearchTerms() {
if ($this->data['alertsearch']) {
$this->data['alertsearch_pretty'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['alertsearch']);
$this->data['search_text'] = $this->data['alertsearch'];
Expand All @@ -243,7 +383,7 @@ private function formatSearchTerms() {
}
}

private function checkForCommonMistakes() {
protected function checkForCommonMistakes() {
$mistakes = [];
if (strstr($this->data['alertsearch'], ',') > -1) {
$mistakes['multiple'] = 1;
Expand All @@ -261,7 +401,7 @@ private function checkForCommonMistakes() {
$this->data['mistakes'] = $mistakes;
}

private function formatSearchMemberData() {
protected function formatSearchMemberData() {
if (isset($this->data['postcode'])) {
try {
$postcode = $this->data['postcode'];
Expand Down Expand Up @@ -302,13 +442,38 @@ private function formatSearchMemberData() {
}
}

private function setUserData() {
protected function setUserData() {
if (!isset($this->data['criteria'])) {
$criteria = $this->data['keyword'];
if ($this->data['search_section']) {
$criteria .= " section:" . $this->data['search_section'];
}
if ($this->data['pid']) {
$criteria .= " speaker:" . $this->data['pid'];
}
$this->getRecentResults($criteria);

$this->data['criteria'] = $criteria;
$this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($criteria);
}
if ($this->data['alertsearch'] && !(isset($this->data['members']) || $this->data['pid'])) {
$this->data['step'] = 'define';
$this->data['words'] = [$this->data['alertsearch']];
$this->data['keywords'] = [$this->data['alertsearch']];
$this->data['exclusions'] = '';
$this->data['representative'] = '';
}
$this->data['current_mp'] = false;
$this->data['alerts'] = [];
$this->data['keyword_alerts'] = [];
$this->data['speaker_alerts'] = [];
$this->data['spoken_alerts'] = [];
$this->data['own_member_alerts'] = [];
$this->data['all_keywords'] = [];
if ($this->data['results'] == 'changes-abandoned') {
$this->data['members'] = false;
$this->data['alertsearch'] = '';
}
$own_mp_criteria = '';
if ($this->data['email_verified']) {
if ($this->user->postcode()) {
Expand All @@ -330,5 +495,10 @@ private function setUserData() {
}
}
}
if ($this->data['addword'] != '' || ($this->data['step'] && count($this->data['errors']) > 0)) {
$this->data["step"] = get_http_var('this_step');
} else {
$this->data['this_step'] = '';
}
}
}
48 changes: 40 additions & 8 deletions classes/Utility/Alert.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,23 @@

class Alert {
#XXX don't calculate this every time
private static function sectionToTitle($section) {
global $hansardmajors;
$section_map = [];
foreach ($hansardmajors as $major => $details) {
$section_map[$details["page_all"]] = $details["title"];
}
public static function sectionToTitle($section) {
$section_map = [
"uk" => gettext('All UK'),
"debates" => gettext('House of Commons debates'),
"whalls" => gettext('Westminster Hall debates'),
"lords" => gettext('House of Lords debates'),
"wrans" => gettext('Written answers'),
"wms" => gettext('Written ministerial statements'),
"standing" => gettext('Bill Committees'),
"future" => gettext('Future Business'),
"ni" => gettext('Northern Ireland Assembly Debates'),
"scotland" => gettext('All Scotland'),
"sp" => gettext('Scottish Parliament Debates'),
"spwrans" => gettext('Scottish Parliament Written answers'),
"wales" => gettext('Welsh parliament record'),
"lmqs" => gettext('Questions to the Mayor of London'),
];

return $section_map[$section];
}
Expand All @@ -30,6 +41,10 @@ public static function detailsToCriteria($details) {
$criteria[] = 'speaker:' . $details['pid'];
}

if (!empty($details['search_section'])) {
$criteria[] = 'section:' . $details['search_section'];
}

$criteria = join(' ', $criteria);
return $criteria;
}
Expand Down Expand Up @@ -74,10 +89,23 @@ public static function forUser($email) {

public static function prettifyCriteria($alert_criteria, $as_parts = false) {
$text = '';
$parts = ['words' => [], 'sections' => [], 'exclusions' => []];
if ($alert_criteria) {
$criteria = explode(' ', $alert_criteria);
$parts = [];
# check for phrases
if (strpos($alert_criteria, '"') !== false) {
# match phrases
preg_match_all('/"([^"]*)"/', $alert_criteria, $phrases);
# and then remove them from the criteria
$alert_criteria = trim(preg_replace('/ +/', ' ', str_replace($phrases[0], "", $alert_criteria)));

# and then create an array with the words and phrases
$criteria = explode(' ', $alert_criteria);
$criteria = array_merge($criteria, $phrases[1]);
} else {
$criteria = explode(' ', $alert_criteria);
}
$words = [];
$exclusions = [];
$sections = [];
$sections_verbose = [];
$spokenby = array_values(\MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($alert_criteria));
Expand All @@ -86,6 +114,8 @@ public static function prettifyCriteria($alert_criteria, $as_parts = false) {
if (preg_match('#^section:(\w+)#', $c, $m)) {
$sections[] = $m[1];
$sections_verbose[] = self::sectionToTitle($m[1]);
} elseif (strpos($c, '-') === 0) {
$exclusions[] = str_replace('-', '', $c);
} elseif (!preg_match('#^speaker:(\d+)#', $c, $m)) {
$words[] = $c;
}
Expand All @@ -107,6 +137,8 @@ public static function prettifyCriteria($alert_criteria, $as_parts = false) {
$parts['sections'] = $sections;
$parts['sections_verbose'] = $sections_verbose;
}

$parts['exclusions'] = $exclusions;
}
if ($as_parts) {
return $parts;
Expand Down
Loading

0 comments on commit 5a0a625

Please sign in to comment.