aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdb/rerun_dbic_loader.pl1
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm356
-rw-r--r--perllib/FixMyStreet/DB/Result/Secret.pm21
-rw-r--r--templates/web/default/admin/council_contacts.html89
-rw-r--r--templates/web/default/admin/council_contacts.txt4
-rw-r--r--templates/web/default/admin/council_edit.html62
-rw-r--r--templates/web/default/report/display.html2
7 files changed, 366 insertions, 169 deletions
diff --git a/db/rerun_dbic_loader.pl b/db/rerun_dbic_loader.pl
index 4437241e8..71efa5db5 100755
--- a/db/rerun_dbic_loader.pl
+++ b/db/rerun_dbic_loader.pl
@@ -19,7 +19,6 @@ my @tables_to_ignore = (
'debugdate', #
'flickr_imported', #
'partial_user', #
- 'secret', #
'textmystreet', #
);
my $exclude = '^(?:' . join( '|', @tables_to_ignore ) . ')$';
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index fcc55cba0..d2ea69c94 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -5,6 +5,7 @@ use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller'; }
use POSIX qw(strftime strcoll);
+use Digest::MD5 qw(md5_hex);
=head1 NAME
@@ -192,9 +193,162 @@ sub council_list : Path('council_list') : Args(0) {
return 1;
}
+
+sub council_contacts : Path('council_contacts') : Args(1) {
+ my ( $self, $c, $area_id ) = @_;
+
+ my $posted = $c->req->param('posted') || '';
+ $c->stash->{area_id} = $area_id;
+
+ $c->forward( 'get_token' );
+
+ if ( $posted ) {
+ $c->log->debug( 'posted' );
+ $c->forward('update_contacts');
+ }
+
+ $c->forward('display_contacts');
+
+ return 1;
+}
+
+sub update_contacts : Private {
+ my ( $self, $c ) = @_;
+
+ my $posted = $c->req->param('posted');
+ my $editor = $c->req->remote_user || _('*unknown*');
+
+ if ( $posted eq 'new' ) {
+ $c->forward('check_token');
+
+ my $category = $self->trim( $c->req->param( 'category' ) );
+ my $email = $self->trim( $c->req->param( 'email' ) );
+
+ $category = 'Empty property' if $c->cobrand->moniker eq 'emptyhomes';
+
+ my $contact = $c->model('DB::Contact')->find_or_new(
+ {
+ area_id => $c->stash->{area_id},
+ category => $category,
+ }
+ );
+
+ $contact->email( $email );
+ $contact->confirmed( $c->req->param('confirmed') ? 1 : 0 );
+ $contact->deleted( $c->req->param('deleted') ? 1 : 0 );
+ $contact->note( $c->req->param('note') );
+ $contact->whenedited( \'ms_current_timestamp()' );
+ $contact->editor( $editor );
+
+ if ( $contact->in_storage ) {
+ $c->stash->{updated} = _('Values updated');
+
+ # NB: History is automatically stored by a trigger in the database
+ $contact->update;
+ } else {
+ $c->stash->{updated} = _('New category contact added');
+ $contact->insert;
+ }
+
+ } elsif ( $posted eq 'update' ) {
+ $c->forward('check_token');
+
+ my @categories = $c->req->param('confirmed');
+
+ my $contacts = $c->model('DB::Contact')->search(
+ {
+ area_id => $c->stash->{area_id},
+ category => { -in => \@categories },
+ }
+ );
+
+ $contacts->update(
+ {
+ confirmed => 1,
+ whenedited => \'ms_current_timestamp()',
+ note => 'Confirmed',
+ editor => $editor,
+ }
+ );
+
+ $c->stash->{updated} = _('Values updated');
+ }
+}
+
+sub display_contacts : Private {
+ my ( $self, $c ) = @_;
+
+ $c->forward('setup_council_details');
+
+ my $area_id = $c->stash->{area_id};
+
+ my $contacts = $c->model('DB::Contact')->search(
+ { area_id => $area_id },
+ { order_by => ['category'] }
+ );
+
+ $c->stash->{contacts} = $contacts;
+
+ if ( $c->req->param('text') == 1 ) {
+ $c->stash->{template} = 'admin/council_contacts.txt';
+ $c->res->content_encoding('text/plain');
+ return 1;
+ }
+
+ return 1;
+}
+
+sub setup_council_details : Private {
+ my ( $self, $c ) = @_;
+
+ my $area_id = $c->stash->{area_id};
+
+ my $mapit_data = mySociety::MaPit::call('area', $area_id);
+
+ $c->stash->{council_name} = $mapit_data->{name};
+
+ my $example_postcode = mySociety::MaPit::call('area/example_postcode', $area_id);
+
+ if ($example_postcode && ! ref $example_postcode) {
+ $c->stash->{example_pc} = $example_postcode;
+ }
+
+ return 1;
+}
+
+sub council_edit : Path('council_edit') : Args(2) {
+ my ( $self, $c, $area_id, $category ) = @_;
+
+ $c->stash->{area_id} = $area_id;
+
+ $c->forward( 'get_token' );
+ $c->forward('setup_council_details');
+
+ my $contact = $c->model('DB::Contact')->search(
+ {
+ area_id => $area_id,
+ category => $category
+ }
+ )->first;
+
+ $c->stash->{contact} = $contact;
+
+ my $history = $c->model('DB::ContactsHistory')->search(
+ {
+ area_id => $area_id,
+ category => $category
+ },
+ {
+ order_by => ['contacts_history_id']
+ },
+ );
+
+ $c->stash->{history} = $history;
+
+ return 1;
+}
+
# use Encode;
-# use POSIX qw(strftime strcoll);
-# use Digest::MD5 qw(md5_hex);
#
# use Page;
# use mySociety::Config;
@@ -203,17 +357,32 @@ sub council_list : Path('council_list') : Args(0) {
# use mySociety::VotingArea;
# use mySociety::Web qw(NewURL ent);
#
-# =item get_token Q
-#
-# Generate a token based on user and secret
-#
-# =cut
-# sub get_token {
-# my ($q) = @_;
-# my $secret = scalar(dbh()->selectrow_array('select secret from secret'));
-# my $token = md5_hex(($q->remote_user() . $secret));
-# return $token;
-# }
+=item get_token
+
+Generate a token based on user and secret
+
+=cut
+sub get_token : Private {
+ my ( $self, $c ) = @_;
+
+ my $secret = $c->model('DB::Secret')->search()->first;
+
+ my $token = md5_hex(($c->req->remote_user() . $secret->secret));
+
+ $c->stash->{token} = $token;
+
+ return 1;
+}
+
+sub check_token : Private {
+ my ( $self, $c ) = @_;
+
+ if ( $c->req->param('token' ) ne $c->stash->{token} ) {
+ $c->detach( '/page_error_404_not_found', [ _('The requested URL was not found on this server.') ] );
+ }
+
+ return 1;
+}
#
# =item allowed_pages Q
#
@@ -271,154 +440,6 @@ sub council_list : Path('council_list') : Args(0) {
# }
#
#
-#
-# # admin_council_contacts CGI AREA_ID
-# sub admin_council_contacts ($$) {
-# my ($q, $area_id) = @_;
-#
-# # Submit form
-# my $updated = '';
-# my $posted = $q->param('posted') || '';
-# if ($posted eq 'new') {
-# return not_found($q) if $q->param('token') ne get_token($q);
-# my $email = trim($q->param('email'));
-# my $category = trim($q->param('category'));
-# $category = 'Empty property' if $q->{site} eq 'emptyhomes';
-# # History is automatically stored by a trigger in the database
-# my $update = dbh()->do("update contacts set
-# email = ?,
-# confirmed = ?,
-# deleted = ?,
-# editor = ?,
-# whenedited = ms_current_timestamp(),
-# note = ?
-# where area_id = ?
-# and category = ?
-# ", {},
-# $email, ($q->param('confirmed') ? 1 : 0),
-# ($q->param('deleted') ? 1 : 0),
-# ($q->remote_user() || _("*unknown*")), $q->param('note'),
-# $area_id, $category
-# );
-# $updated = $q->p($q->em(_("Values updated")));
-# unless ($update > 0) {
-# dbh()->do('insert into contacts
-# (area_id, category, email, editor, whenedited, note, confirmed, deleted)
-# values
-# (?, ?, ?, ?, ms_current_timestamp(), ?, ?, ?)', {},
-# $area_id, $category, $email,
-# ($q->remote_user() || _('*unknown*')), $q->param('note'),
-# ($q->param('confirmed') ? 1 : 0), ($q->param('deleted') ? 1 : 0)
-# );
-# $updated = $q->p($q->em(_("New category contact added")));
-# }
-# dbh()->commit();
-# } elsif ($posted eq 'update') {
-# return not_found($q) if $q->param('token') ne get_token($q);
-# my @cats = $q->param('confirmed');
-# foreach my $cat (@cats) {
-# dbh()->do("update contacts set
-# confirmed = 't', editor = ?,
-# whenedited = ms_current_timestamp(),
-# note = 'Confirmed'
-# where area_id = ?
-# and category = ?
-# ", {},
-# ($q->remote_user() || _("*unknown*")),
-# $area_id, $cat
-# );
-# }
-# $updated = $q->p($q->em(_("Values updated")));
-# dbh()->commit();
-# }
-#
-# my $bci_data = select_all("select * from contacts where area_id = ? order by category", $area_id);
-#
-# if ($q->param('text')) {
-# print $q->header(-type => 'text/plain', -charset => 'utf-8');
-# foreach my $l (@$bci_data) {
-# next if $l->{deleted} || !$l->{confirmed};
-# print $l->{category} . "\t" . $l->{email} . "\n";
-# }
-# return;
-# }
-#
-# $q->delete_all(); # No need for state!
-#
-# # Title
-# my $mapit_data = mySociety::MaPit::call('area', $area_id);
-# my $title = sprintf(_('Council contacts for %s'), $mapit_data->{name});
-# print html_head($q, $title);
-# print $q->h1($title);
-# print $updated;
-#
-# # Example postcode, link to list of problem reports
-# my $links_html;
-# my $example_postcode = mySociety::MaPit::call('area/example_postcode', $area_id);
-# if ($example_postcode && ! ref $example_postcode) {
-# $links_html .= $q->a({ href => mySociety::Config::get('BASE_URL') . '/?pc=' . $q->escape($example_postcode) },
-# "Example postcode " . $example_postcode) . " | ";
-# }
-# $links_html .= ' ' .
-# $q->a({ href => mySociety::Config::get('BASE_URL') . "/reports?council=" . $area_id }, _(" List all reported problems"));
-# $links_html .= ' ' .
-# $q->a({ href => NewURL($q, area_id => $area_id, page => 'councilcontacts', text => 1) }, _('Text only version'));
-# print $q->p($links_html);
-#
-# # Display of addresses / update statuses form
-# print $q->start_form(-method => 'POST', -action => './');
-# print $q->start_table({border=>1, cellpadding=>2, cellspacing=>0});
-# print $q->Tr({}, $q->th({}, [_("Category"), _("Email"), _("Confirmed"), _("Deleted"), _("Last editor"), _("Note"), _("When edited"), _('Confirm')]));
-# foreach my $l (@$bci_data) {
-# print $q->Tr($q->td([
-# $q->a({ href => NewURL($q, area_id => $area_id, category => $l->{category}, page => 'counciledit') },
-# $l->{category}), $l->{email}, $l->{confirmed} ? _('Yes') : _('No'),
-# $l->{deleted} ? _('Yes') : _('No'), $l->{editor}, ent($l->{note}),
-# $l->{whenedited} =~ m/^(.+)\.\d+$/,
-# $q->checkbox(-name => 'confirmed', -value => $l->{category}, -label => '')
-# ]));
-# }
-# print $q->end_table();
-# # XXX
-# print $q->p(
-# $q->hidden('area_id', $area_id),
-# $q->hidden('posted', 'update'),
-# $q->hidden('token', get_token($q)),
-# $q->hidden('page', 'councilcontacts'),
-# $q->submit(_('Update statuses'))
-# );
-# print $q->end_form();
-#
-# # Display form for adding new category
-# print $q->h2(_('Add new category'));
-# print $q->start_form(-method => 'POST', -action => './');
-# if ($q->{site} ne 'emptyhomes') {
-# print $q->p($q->strong(_("Category: ")),
-# $q->textfield(-name => "category", -size => 30));
-# }
-# print $q->p($q->strong(_("Email: ")),
-# $q->textfield(-name => "email", -size => 30));
-# $q->autoEscape(0);
-# print $q->p(
-# $q->checkbox(-id => 'confirmed', -name => "confirmed", -value => 1, -label => ' ' . $q->label({-for => 'confirmed'}, _('Confirmed'))),
-# ' ',
-# $q->checkbox(-id => 'deleted', -name => "deleted", -value => 1, -label => ' ' . $q->label({-for => 'deleted'}, _('Deleted')))
-# );
-# $q->autoEscape(1);
-# print $q->p($q->strong(_("Note: ")),
-# $q->textarea(-name => "note", -rows => 3, -columns=>40));
-# print $q->p(
-# $q->hidden('area_id', $area_id),
-# $q->hidden('posted', 'new'),
-# $q->hidden('token', get_token($q)),
-# $q->hidden('page', 'councilcontacts'),
-# $q->submit(_('Create category'))
-# );
-# print $q->end_form();
-#
-# print html_tail($q);
-# }
-#
# # admin_council_edit CGI AREA_ID CATEGORY
# sub admin_council_edit ($$$) {
# my ($q, $area_id, $category) = @_;
@@ -962,12 +983,13 @@ sub council_list : Path('council_list') : Args(0) {
# }
# Page::do_fastcgi(\&main);
#
-# sub trim {
-# my $e = shift;
-# $e =~ s/^\s+//;
-# $e =~ s/\s+$//;
-# return $e;
-# }
+sub trim {
+ my $self = shift;
+ my $e = shift;
+ $e =~ s/^\s+//;
+ $e =~ s/\s+$//;
+ return $e;
+}
=head1 AUTHOR
diff --git a/perllib/FixMyStreet/DB/Result/Secret.pm b/perllib/FixMyStreet/DB/Result/Secret.pm
new file mode 100644
index 000000000..399f0be18
--- /dev/null
+++ b/perllib/FixMyStreet/DB/Result/Secret.pm
@@ -0,0 +1,21 @@
+package FixMyStreet::DB::Result::Secret;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime");
+__PACKAGE__->table("secret");
+__PACKAGE__->add_columns("secret", { data_type => "text", is_nullable => 0 });
+
+
+# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-06-03 12:02:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Htl6+DHfHy9l+bjBxAbH6Q
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/templates/web/default/admin/council_contacts.html b/templates/web/default/admin/council_contacts.html
new file mode 100644
index 000000000..03b487d9c
--- /dev/null
+++ b/templates/web/default/admin/council_contacts.html
@@ -0,0 +1,89 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Council contacts for %s'), council_name) -%]
+
+<p>
+<em>[% updated %]</em>
+</p>
+
+<p>
+[% IF example_pc %]
+<a href="[% c.uri_for( '/around', { pc => example_pc } ) %]">[% tprintf( loc('Example postcode %s'), example_pc ) | html %]</a> |
+[% END %]
+<a href="[% c.uri_for( '/reports', { council => area_id } ) %]">[% loc('List all reported problems' ) %]</a>
+<a href="[% c.uri_for( 'council_contacts', area_id, { text => 1 } ) %]">[% loc('Text only version') %]</a>
+</p>
+
+<form method="post" action="[% c.uri_for('council_contacts', area_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+
+ <table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>Category</th>
+ <th>Email</th>
+ <th>Confirmed</th>
+ <th>Deleted</th>
+ <th>Last editor</th>
+ <th>Note</th>
+ <th>When edited</th>
+ <th>Confirm</th>
+ </tr>
+ [% WHILE ( contact = contacts.next ) %]
+ <tr>
+ <td><a href="[% c.uri_for( 'council_edit', area_id, contact.category ) %]">[% contact.category %]</a></td>
+ <td>[% contact.email | html %]</td>
+ <td>[% IF contact.confirmed %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% IF contact.deleted %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% contact.editor %]</td>
+ <td>[% contact.note | html %]</td>
+ <td>[% contact.whenedited.ymd _ ' ' _ contact.whenedited.hms %]</td>
+ <td><input type="checkbox" name="confirmed" value="[% contact.category %]"></td>
+ </tr>
+ [% END %]
+ </table>
+
+ <p>
+ <input type="hidden" name="area_id" value="[% area_id %]">
+ <input type="hidden" name="posted" value="update">
+ <input type="hidden" name="token" value="[% token %]">
+ <input type="submit" name="Update statuses" value="Update statuses">
+ </p>
+ </form>
+
+ <h2>Add new category</h2>
+
+ <form method="post" action="[% c.uri_for('council_contacts', area_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+
+ [% IF c.cobrand.moniker != 'emptyhomes' %]
+ <p>
+ <strong>Category: </strong><input type="text" name="category" size="30">
+ </p>
+ [% END %]
+
+ <p>
+ <strong>Email: </strong><input type="text" name="email" size="30">
+ </p>
+
+ <p>
+ <input type="checkbox" name="confirmed" value="1" id="confirmed">
+ <label for="confirmed">Confirmed</label>
+
+ <input type="checkbox" name="deleted" value="1"id="deleted">
+ <label for="deleted">Deleted</label>
+ </p>
+
+ <p>
+ <strong>Note: </strong> <textarea name="note" rows="3" cols="40"></textarea>
+ </p>
+
+ <p>
+ <input type="hidden" name="area_id" value="[% area_id %]" >
+ <input type="hidden" name="posted" value="new" >
+ <input type="hidden" name="token" value="[% token %]" >
+ <input type="submit" name="Create category" value="Create category" >
+ </p>
+
+ <div>
+ <input type="hidden" name=".cgifields" value="confirmed" >
+ <input type="hidden" name=".cgifields" value="deleted" >
+ </div>
+ </form>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/default/admin/council_contacts.txt b/templates/web/default/admin/council_contacts.txt
new file mode 100644
index 000000000..2d1e04bfa
--- /dev/null
+++ b/templates/web/default/admin/council_contacts.txt
@@ -0,0 +1,4 @@
+[% WHILE ( contact = contacts.next ) -%]
+[%- NEXT IF contact.deleted || ! contact.confirmed %]
+[% contact.category %] [% contact.email %]
+[%- END %]
diff --git a/templates/web/default/admin/council_edit.html b/templates/web/default/admin/council_edit.html
new file mode 100644
index 000000000..c9ce0e602
--- /dev/null
+++ b/templates/web/default/admin/council_edit.html
@@ -0,0 +1,62 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Council contacts for %s'), council_name) -%]
+
+[% BLOCK highlightchanged_yesno %]
+[%- output = loc('No') %]
+[%- IF new.$value %][% output = loc('Yes') %][% END %]
+[%- IF old && old.$value != new.$value %]<strong>[% output %]</strong>[% ELSE %][% output %][% END %]
+[%- END %]
+
+[% BLOCK highlightchanged %]
+[%- IF old && old.$value != new.$value %]<strong>[% new.$value %]</strong>[% ELSE %][% new.$value %][% END %]
+[%- END %]
+<p>
+<em>[% updated %]</em>
+</p>
+
+<p>
+[% IF example_pc %]
+<a href="[% c.uri_for( '/around', { pc => example_pc } ) %]">[% tprintf( loc('Example postcode %s'), example_pc ) | html %]</a>
+[% END %]
+</p>
+
+<form method="post" action="[% c.uri_for('council_contacts', area_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <strong>Category: </strong>test
+ <input type="hidden" name="category" value="[% contact.category | html %]" >
+ <input type="hidden" name="token" value="[% token %]" >1
+ <strong> Email: </strong>
+ <input type="text" name="email" value="[% contact.email | html %]" size="30">
+ <input type="checkbox" name="confirmed" value="1" id="confirmed"[% ' checked' IF contact.confirmed %]> <label for="confirmed">Confirmed</label>
+ <input type="checkbox" name="deleted" value="1" id="deleted"[% ' checked' IF contact.deleted %]> <label for="deleted">Deleted</label><br>
+
+ <strong>Note: </strong><textarea name="note" rows="3" cols="40">[% contact.note | html %]</textarea> <br>
+
+ <input type="hidden" name="area_id" value="[% area_id %]">
+ <input type="hidden" name="posted" value="new">
+ <input type="submit" name="Save changes" value="Save changes">
+</form>
+
+<h2>History</h2>
+<table border="1">
+ <tr>
+ <th>When edited</th>
+ <th>Email</th>
+ <th>Confirmed</th>
+ <th>Deleted</th>
+ <th>Editor</th>
+ <th>Note</th>
+ </tr>
+ [%- prev = '' %]
+ [%- WHILE ( contact = history.next ) %]
+ <tr>
+ <td>[% contact.whenedited.ymd _ ' ' _ contact.whenedited.hms %]</td>
+ <td>[% PROCESS highlightchanged old=prev new=contact value='email' %]</td>
+ <td>[% PROCESS highlightchanged_yesno old=prev new=contact value='confirmed' %]</td>
+ <td>[% PROCESS highlightchanged_yesno old=prev new=contact value='deleted' %]</td>
+ <td>[% contact.editor %]</td>
+ <td>[% contact.note | html %]</td>
+ </tr>
+ [%- prev = contact %]
+ [%- END %]
+</table>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/default/report/display.html b/templates/web/default/report/display.html
index fdef6c775..4fa58c1db 100644
--- a/templates/web/default/report/display.html
+++ b/templates/web/default/report/display.html
@@ -44,7 +44,7 @@
<form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post" id="email_alert_box">
<p>[% loc('Receive email when updates are left on this problem.' ) %]</p>
<label class="n" for="alert_rznvy">[% loc('Email') %]</label>
- <input type="text" name="rznvy" id="alert_rznvy" value="[% email %]" size="30">
+ <input type="text" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30">
<input type="hidden" name="id" value="[% problem.id %]">
<input type="hidden" name="type" value="updates">
<input type="submit" value="[% loc('Subscribe') %]">