diff options
Diffstat (limited to 'perllib/FixMyStreet')
49 files changed, 896 insertions, 971 deletions
diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm index 6ccc801ce..fda9d665c 100644 --- a/perllib/FixMyStreet/App.pm +++ b/perllib/FixMyStreet/App.pm @@ -153,17 +153,16 @@ sub setup_request { my $cobrand = $c->cobrand; # append the cobrand templates to the include path - $c->stash->{additional_template_paths} = $cobrand->path_to_web_templates - unless $cobrand->is_default; + $c->stash->{additional_template_paths} = $cobrand->path_to_web_templates; # work out which language to use my $lang_override = $c->get_override('lang'); my $host = $c->req->uri->host; my $lang = $lang_override ? $lang_override - : $host =~ /^en\./ ? 'en-gb' - : $host =~ /cy/ ? 'cy' - : undef; + : $host =~ /^(..)\./ ? $1 + : undef; + $lang = 'en-gb' if $lang && $lang eq 'en'; # set the language and the translation file to use - store it on stash my $set_lang = $cobrand->set_lang_and_domain( @@ -177,12 +176,18 @@ sub setup_request { $c->log->debug( sprintf "Set lang to '%s' and cobrand to '%s'", $set_lang, $cobrand->moniker ); - $c->model('DB::Problem')->set_restriction( $cobrand->site_restriction() ); + $c->model('DB::Problem')->set_restriction( $cobrand->site_key() ); Memcached::set_namespace( FixMyStreet->config('FMS_DB_NAME') . ":" ); FixMyStreet::Map::set_map_class( $cobrand->map_type || $c->req->param('map_override') ); + unless ( FixMyStreet->config('MAPIT_URL') ) { + my $port = $c->req->uri->port; + $host = "$host:$port" unless $port == 80; + mySociety::MaPit::configure( "http://$host/fakemapit/" ); + } + return $c; } @@ -387,11 +392,10 @@ and uses that. =cut sub uri_for_email { - my $c = shift; - my @args = @_; + my $c = shift; my $normal_uri = $c->uri_for(@_)->absolute; - my $base = $c->cobrand->base_url_with_lang( 1 ); + my $base = $c->cobrand->base_url_with_lang; my $email_uri = $base . $normal_uri->path_query; @@ -418,7 +422,7 @@ call), use this method. sub render_fragment { my ($c, $template, $vars) = @_; $vars->{additional_template_paths} = $c->cobrand->path_to_web_templates - if $vars && !$c->cobrand->is_default; + if $vars; $c->view('Web')->render($c, $template, $vars); } diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 998cb83a8..298c75352 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -50,7 +50,7 @@ sub index : Path : Args(0) { $c->forward('check_page_allowed'); - my ( $sql_restriction, $id, $site_restriction ) = $c->cobrand->site_restriction(); + my $site_restriction = $c->cobrand->site_restriction(); my $problems = $c->cobrand->problems->summary_count; @@ -122,7 +122,7 @@ sub timeline : Path( 'timeline' ) : Args(0) { $c->forward('check_page_allowed'); - my ( $sql_restriction, $id, $site_restriction ) = $c->cobrand->site_restriction(); + my $site_restriction = $c->cobrand->site_restriction(); my %time; $c->model('DB')->schema->storage->sql_maker->quote_char( '"' ); @@ -221,10 +221,10 @@ sub council_list : Path('council_list') : Args(0) { $c->stash->{edit_activity} = $edit_activity; # Not London, as treated separately - my @area_types = $c->cobrand->moniker eq 'emptyhomes' + my $area_types = $c->cobrand->moniker eq 'emptyhomes' ? $c->cobrand->area_types - : grep { $_ ne 'LBO' } $c->cobrand->area_types; - my $areas = mySociety::MaPit::call('areas', \@area_types); + : [ grep { $_ ne 'LBO' } @{ $c->cobrand->area_types } ]; + my $areas = mySociety::MaPit::call('areas', $area_types); my @councils_ids = sort { strcoll($areas->{$a}->{name}, $areas->{$b}->{name}) } keys %$areas; @councils_ids = $c->cobrand->filter_all_council_ids_list( @councils_ids ); @@ -472,7 +472,7 @@ sub search_reports : Path('search_reports') { if (my $search = $c->req->param('search')) { $c->stash->{searched} = 1; - my ( $site_res_sql, $site_key, $site_restriction ) = $c->cobrand->site_restriction; + my $site_restriction = $c->cobrand->site_restriction; my $search_n = 0; $search_n = int($search) if $search =~ /^\d+$/; @@ -532,13 +532,11 @@ sub search_reports : Path('search_reports') { if (is_valid_email($search)) { $query = [ 'user.email' => { ilike => $like_search }, - %{ $site_restriction }, ]; } elsif ($search =~ /^id:(\d+)$/) { $query = [ 'me.id' => int($1), - 'problem.id' => int($1), - %{ $site_restriction }, + 'me.problem_id' => int($1), ]; } elsif ($search =~ /^area:(\d+)$/) { $query = []; @@ -550,13 +548,13 @@ sub search_reports : Path('search_reports') { 'me.name' => { ilike => $like_search }, text => { ilike => $like_search }, 'me.cobrand_data' => { ilike => $like_search }, - %{ $site_restriction }, ]; } if (@$query) { my $updates = $c->model('DB::Comment')->search( { + %{ $site_restriction }, -or => $query, }, { @@ -576,7 +574,7 @@ sub search_reports : Path('search_reports') { sub report_edit : Path('report_edit') : Args(1) { my ( $self, $c, $id ) = @_; - my ( $site_res_sql, $site_key, $site_restriction ) = $c->cobrand->site_restriction; + my $site_restriction = $c->cobrand->site_restriction; my $problem = $c->cobrand->problems->search( { @@ -737,8 +735,7 @@ sub search_users: Path('search_users') : Args(0) { sub update_edit : Path('update_edit') : Args(1) { my ( $self, $c, $id ) = @_; - my ( $site_res_sql, $site_key, $site_restriction ) = - $c->cobrand->site_restriction; + my $site_restriction = $c->cobrand->site_restriction; my $update = $c->model('DB::Comment')->search( { id => $id, @@ -1258,8 +1255,7 @@ sub check_page_allowed : Private { sub set_up_council_details : Private { my ($self, $c ) = @_; - my @area_types = $c->cobrand->area_types; - my $areas = mySociety::MaPit::call('areas', \@area_types); + my $areas = mySociety::MaPit::call('areas', $c->cobrand->area_types); my @councils_ids = sort { strcoll($areas->{$a}->{name}, $areas->{$b}->{name}) } keys %$areas; @councils_ids = $c->cobrand->filter_all_council_ids_list( @councils_ids ); diff --git a/perllib/FixMyStreet/App/Controller/Alert.pm b/perllib/FixMyStreet/App/Controller/Alert.pm index 6e9ae819c..4e5319a59 100644 --- a/perllib/FixMyStreet/App/Controller/Alert.pm +++ b/perllib/FixMyStreet/App/Controller/Alert.pm @@ -184,7 +184,7 @@ sub create_alert : Private { unless ($alert) { $options->{cobrand} = $c->cobrand->moniker(); - $options->{cobrand_data} = $c->cobrand->extra_update_data(); + $options->{cobrand_data} = ''; $options->{lang} = $c->stash->{lang_code}; $alert = $c->model('DB::Alert')->new($options); diff --git a/perllib/FixMyStreet/App/Controller/Contact.pm b/perllib/FixMyStreet/App/Controller/Contact.pm index c300aee9a..926a3f2a5 100644 --- a/perllib/FixMyStreet/App/Controller/Contact.pm +++ b/perllib/FixMyStreet/App/Controller/Contact.pm @@ -139,7 +139,7 @@ sub prepare_params_for_email : Private { $c->stash->{message} =~ s/\r\n/\n/g; $c->stash->{subject} =~ s/\r|\n/ /g; - my $base_url = $c->cobrand->base_url_for_emails( $c->cobrand->extra_data ); + my $base_url = $c->cobrand->base_url(); my $admin_url = $c->cobrand->admin_base_url; if ( $c->stash->{update} ) { diff --git a/perllib/FixMyStreet/App/Controller/Council.pm b/perllib/FixMyStreet/App/Controller/Council.pm index 7a0f9b73f..a6ce533e4 100644 --- a/perllib/FixMyStreet/App/Controller/Council.pm +++ b/perllib/FixMyStreet/App/Controller/Council.pm @@ -23,8 +23,8 @@ there are no councils then return false. sub load_and_check_councils_and_wards : Private { my ( $self, $c ) = @_; - my @area_types = ( $c->cobrand->area_types(), @$mySociety::VotingArea::council_child_types ); - $c->stash->{area_types} = \@area_types; + my $area_types = [ @{$c->cobrand->area_types}, @{$c->cobrand->area_types_children} ]; + $c->stash->{area_types} = $area_types; $c->forward('load_and_check_councils'); } @@ -42,11 +42,11 @@ sub load_and_check_councils : Private { my $longitude = $c->stash->{longitude}; # Look up councils and do checks for the point we've got - my @area_types; + my $area_types; if ( $c->stash->{area_types} and scalar @{ $c->stash->{area_types} } ) { - @area_types = @{ $c->stash->{area_types} }; + $area_types = $c->stash->{area_types}; } else { - @area_types = $c->cobrand->area_types(); + $area_types = $c->cobrand->area_types; } my $short_latitude = Utils::truncate_coordinate($latitude); @@ -55,7 +55,7 @@ sub load_and_check_councils : Private { # TODO: I think we want in_gb_locale around the MaPit line, needs testing my $all_councils; if ( $c->stash->{fetch_all_areas} ) { - my %area_types = map { $_ => 1 } @area_types; + my %area_types = map { $_ => 1 } @$area_types; my $all_areas = mySociety::MaPit::call( 'point', "4326/$short_longitude,$short_latitude" ); $c->stash->{all_areas} = $all_areas; @@ -67,7 +67,11 @@ sub load_and_check_councils : Private { } else { $all_councils = mySociety::MaPit::call( 'point', "4326/$short_longitude,$short_latitude", - type => \@area_types ); + type => $area_types ); + } + if ($all_councils->{error}) { + $c->stash->{location_error} = $all_councils->{error}; + return; } # Let cobrand do a check @@ -83,9 +87,8 @@ sub load_and_check_councils : Private { $c->cobrand->remove_redundant_councils($all_councils) if $c->stash->{remove_redundant_councils}; # If we don't have any councils we can't accept the report - if ( !scalar keys %$all_councils || $all_councils->{error}) { - $c->stash->{location_offshore} = 1; - $c->stash->{location_error} = 'That point is outside the boundaries.'; + if ( !scalar keys %$all_councils ) { + $c->stash->{location_error} = _('That location does not appear to be covered by a council; perhaps it is offshore or outside the country. Please try again.'); return; } diff --git a/perllib/FixMyStreet/App/Controller/Location.pm b/perllib/FixMyStreet/App/Controller/Location.pm index df8a090c2..c3d754485 100644 --- a/perllib/FixMyStreet/App/Controller/Location.pm +++ b/perllib/FixMyStreet/App/Controller/Location.pm @@ -104,7 +104,7 @@ sub check_location : Private { eval { Utils::convert_latlon_to_en( $c->stash->{latitude}, $c->stash->{longitude} ); }; if (my $error = $@) { mySociety::Locale::pop(); # We threw exception, so it won't have happened. - $error = _('That location does not appear to be in Britain; please try again.') + $error = _('That location does not appear to be in the UK; please try again.') if $error =~ /of the area covered/; $c->stash->{location_error} = $error; return; diff --git a/perllib/FixMyStreet/App/Controller/Open311.pm b/perllib/FixMyStreet/App/Controller/Open311.pm index 34e2b7cd3..040b0d3e6 100644 --- a/perllib/FixMyStreet/App/Controller/Open311.pm +++ b/perllib/FixMyStreet/App/Controller/Open311.pm @@ -163,10 +163,10 @@ sub get_services : Private { my $categories = $c->model('DB::Contact')->not_deleted; if ($lat || $lon) { - my @area_types = $c->cobrand->area_types; + my $area_types = $c->cobrand->area_types; my $all_councils = mySociety::MaPit::call('point', "4326/$lon,$lat", - type => \@area_types); + type => $area_types); $categories = $categories->search( { area_id => [ keys %$all_councils ], } ); @@ -319,8 +319,6 @@ sub get_requests : Private { service_request_id => [ '=', 'id' ], service_code => [ '=', 'category' ], status => [ 'IN', 'state' ], - start_date => [ '>=', 'confirmed' ], - end_date => [ '<', 'confirmed' ], agency_responsible => [ '~', 'council' ], interface_used => [ '=', 'service' ], has_photo => [ '=', 'photo' ], @@ -365,6 +363,14 @@ sub get_requests : Private { $criteria->{$key} = { $op, $value }; } + if ( $c->req->param('start_date') and $c->req->param('end_date') ) { + $criteria->{confirmed} = [ '-and' => { '>=', $c->req->param('start_date') }, { '<', $c->req->param('end_date') } ]; + } elsif ( $c->req->param('start_date') ) { + $criteria->{confirmed} = { '>=', $c->req->param('start_date') }; + } elsif ( $c->req->param('end_date') ) { + $criteria->{confirmed} = { '<', $c->req->param('end_date') }; + } + if ('rss' eq $c->stash->{format}) { $c->stash->{type} = 'new_problems'; $c->forward( '/rss/lookup_type' ); diff --git a/perllib/FixMyStreet/App/Controller/Questionnaire.pm b/perllib/FixMyStreet/App/Controller/Questionnaire.pm index 6aa4f7604..f0cc72e07 100755 --- a/perllib/FixMyStreet/App/Controller/Questionnaire.pm +++ b/perllib/FixMyStreet/App/Controller/Questionnaire.pm @@ -31,27 +31,27 @@ sub check_questionnaire : Private { my $questionnaire = $c->stash->{questionnaire}; - my $problem_id = $questionnaire->problem_id; + my $problem = $questionnaire->problem; if ( $questionnaire->whenanswered ) { - my $problem_url = $c->uri_for( "/report/$problem_id" ); + my $problem_url = $c->cobrand->base_url_for_report( $problem ) . $problem->url; my $contact_url = $c->uri_for( "/contact" ); $c->stash->{message} = sprintf(_("You have already answered this questionnaire. If you have a question, please <a href='%s'>get in touch</a>, or <a href='%s'>view your problem</a>.\n"), $contact_url, $problem_url); $c->stash->{template} = 'errors/generic.html'; $c->detach; } - unless ( $questionnaire->problem->is_visible ) { + unless ( $problem->is_visible ) { $c->detach('missing_problem'); } - $c->stash->{problem} = $questionnaire->problem; - $c->stash->{answered_ever_reported} = $questionnaire->problem->user->answered_ever_reported; + $c->stash->{problem} = $problem; + $c->stash->{answered_ever_reported} = $problem->user->answered_ever_reported; # EHA needs to know how many to alter display, and whether to send another or not if ($c->cobrand->moniker eq 'emptyhomes') { $c->stash->{num_questionnaire} = $c->model('DB::Questionnaire')->count( - { problem_id => $c->stash->{problem}->id } + { problem_id => $problem->id } ); } @@ -96,15 +96,16 @@ sub submit_creator_fixed : Private { my @errors; - map { $c->stash->{$_} = $c->req->params->{$_} || '' } qw(reported problem); + $c->stash->{reported} = $c->req->params->{reported}; + $c->stash->{problem_id} = $c->req->params->{problem}; # should only be able to get to here if we are logged and we have a # problem - unless ( $c->user && $c->stash->{problem} ) { + unless ( $c->user && $c->stash->{problem_id} ) { $c->detach('missing_problem'); } - my $problem = $c->cobrand->problems->find( { id => $c->stash->{problem} } ); + my $problem = $c->cobrand->problems->find( { id => $c->stash->{problem_id} } ); # you should not be able to answer questionnaires about problems # that you've not submitted @@ -114,13 +115,12 @@ sub submit_creator_fixed : Private { push @errors, _('Please say whether you\'ve ever reported a problem to your council before') unless $c->stash->{reported}; - $c->stash->{problem_id} = $c->stash->{problem}; $c->stash->{errors} = \@errors; $c->detach( 'creator_fixed' ) if scalar @errors; my $questionnaire = $c->model( 'DB::Questionnaire' )->find_or_new( { - problem_id => $c->stash->{problem}, + problem_id => $c->stash->{problem_id}, # we want to look for any previous questionnaire here rather than one for # this specific open state -> fixed transistion old_state => [ FixMyStreet::DB::Result::Problem->open_states() ], @@ -199,7 +199,7 @@ sub submit_standard : Private { mark_open => $new_state eq 'confirmed' ? 1 : 0, lang => $c->stash->{lang_code}, cobrand => $c->cobrand->moniker, - cobrand_data => $c->cobrand->extra_update_data, + cobrand_data => '', confirmed => \'ms_current_timestamp()', anonymous => $problem->anonymous, } @@ -281,10 +281,10 @@ sub display : Private { map { Utils::truncate_coordinate($_) } ( $problem->latitude, $problem->longitude ); - $c->stash->{updates} = $c->model('DB::Comment')->search( + $c->stash->{updates} = [ $c->model('DB::Comment')->search( { problem_id => $problem->id, state => 'confirmed' }, { order_by => 'confirmed' } - ); + )->all ]; $c->stash->{page} = 'questionnaire'; FixMyStreet::Map::display_map( diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 6f249b2fe..d36ba32fe 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -115,8 +115,6 @@ sub format_problem_for_display : Private { my $problem = $c->stash->{problem}; - $c->stash->{banner} = $c->cobrand->generate_problem_banner($problem); - ( $c->stash->{short_latitude}, $c->stash->{short_longitude} ) = map { Utils::truncate_coordinate($_) } ( $problem->latitude, $problem->longitude ); @@ -125,7 +123,7 @@ sub format_problem_for_display : Private { $c->stash->{add_alert} = 1; } - $c->stash->{extra_name_info} = $problem->council eq '2482' ? 1 : 0; + $c->stash->{extra_name_info} = $problem->council && $problem->council eq '2482' ? 1 : 0; $c->forward('generate_map_tags'); diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index b0b338c69..b18e6e39f 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -78,6 +78,7 @@ partial =cut use constant COUNCIL_ID_BARNET => 2489; +use constant COUNCIL_ID_BROMLEY => 2482; sub report_new : Path : Args(0) { my ( $self, $c ) = @_; @@ -93,6 +94,7 @@ sub report_new : Path : Args(0) { $c->stash->{template} = "report/new/fill_in_details.html"; $c->forward('setup_categories_and_councils'); $c->forward('generate_map'); + $c->forward('check_for_category'); # deal with the user and report and check both are happy return unless $c->forward('check_form_submitted'); @@ -614,12 +616,12 @@ sub setup_categories_and_councils : Private { ); $category_label = _('Property type:'); - } elsif ($first_council->{id} != 2482 && $first_council->{type} eq 'LBO') { + } elsif ($first_council->{id} != COUNCIL_ID_BROMLEY && $first_council->{type} eq 'LBO') { $area_ids_to_list{ $first_council->{id} } = 1; my @local_categories; if ($first_council->{id} == COUNCIL_ID_BARNET) { - @local_categories = sort(keys %{ Utils::barnet_categories() }); # removed 'Other' option + @local_categories = sort keys %{ Utils::barnet_categories() } } else { @local_categories = sort keys %{ Utils::london_categories() } } @@ -639,8 +641,6 @@ sub setup_categories_and_councils : Private { $area_ids_to_list{ $contact->area_id } = 1; - next if $contact->category eq _('Other'); - unless ( $seen{$contact->category} ) { push @category_options, $contact->category; @@ -651,9 +651,9 @@ sub setup_categories_and_councils : Private { } if (@category_options) { - @category_options = ( _('-- Pick a category --'), @category_options ); - push @category_options, _('Other') - unless $first_council->{id} == 2482; + # If there's an Other category present, put it at the bottom + @category_options = ( _('-- Pick a category --'), grep { $_ ne _('Other') } @category_options ); + push @category_options, _('Other') if $seen{_('Other')}; $category_label = _('Category'); } } @@ -664,7 +664,7 @@ sub setup_categories_and_councils : Private { $c->stash->{category_options} = \@category_options; $c->stash->{category_extras} = \%category_extras; $c->stash->{category_extras_json} = encode_json \%category_extras; - $c->stash->{extra_name_info} = $first_council->{id} == 2482 ? 1 : 0; + $c->stash->{extra_name_info} = $first_council->{id} == COUNCIL_ID_BROMLEY ? 1 : 0; my @missing_details_councils = grep { !$area_ids_to_list{$_} } # @@ -815,12 +815,12 @@ sub process_report : Private { } elsif ( $first_council->{id} == COUNCIL_ID_BARNET ) { - unless ( exists Utils::barnet_categories()->{ $report->category } or $report->category eq 'Other') { + unless ( exists Utils::barnet_categories()->{ $report->category } ) { $c->stash->{field_errors}->{category} = _('Please choose a category'); } $report->council( $first_council->{id} ); - } elsif ( $first_council->{id} != 2482 && $first_council->{type} eq 'LBO') { + } elsif ( $first_council->{id} != COUNCIL_ID_BROMLEY && $first_council->{type} eq 'LBO') { unless ( Utils::london_categories()->{ $report->category } ) { $c->stash->{field_errors}->{category} = _('Please choose a category'); @@ -896,7 +896,7 @@ sub process_report : Private { # save the cobrand and language related information $report->cobrand( $c->cobrand->moniker ); - $report->cobrand_data( $c->cobrand->extra_problem_data ); + $report->cobrand_data( '' ); $report->lang( $c->stash->{lang_code} ); return 1; @@ -1055,6 +1055,14 @@ sub generate_map : Private { return 1; } +sub check_for_category : Private { + my ( $self, $c ) = @_; + + $c->stash->{category} = $c->req->param('category'); + + return 1; +} + =head2 redirect_or_confirm_creation Now that the report has been created either redirect the user to its page if it @@ -1075,7 +1083,7 @@ sub redirect_or_confirm_creation : Private { if ( $c->cobrand->moniker eq 'fixmybarangay' && $c->user->from_council && $c->stash->{external_source_id}) { $report_uri = $c->uri_for( '/report', $report->id, undef, { external_source_id => $c->stash->{external_source_id} } ); } else { - $report_uri = $c->uri_for( '/report', $report->id ); + $report_uri = $c->cobrand->base_url_for_report( $report ) . $report->url; } $c->log->info($report->user->id . ' was logged in, redirecting to /report/' . $report->id); $c->res->redirect($report_uri); diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm index 3a2b40c2c..c49123a90 100644 --- a/perllib/FixMyStreet/App/Controller/Report/Update.pm +++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm @@ -189,7 +189,7 @@ sub process_update : Private { mark_fixed => $params{fixed} ? 1 : 0, mark_open => $params{reopen} ? 1 : 0, cobrand => $c->cobrand->moniker, - cobrand_data => $c->cobrand->extra_update_data, + cobrand_data => '', lang => $c->stash->{lang_code}, anonymous => $anonymous, } @@ -348,7 +348,7 @@ sub redirect_or_confirm_creation : Private { if ( $update->confirmed ) { $c->forward( 'update_problem' ); $c->forward( 'signup_for_alerts' ); - my $report_uri = $c->uri_for( '/report', $update->problem_id ); + my $report_uri = $c->cobrand->base_url_for_report( $update->problem ) . $update->problem->url; $c->res->redirect($report_uri); $c->detach; } diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index c5f709054..37766db44 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -34,8 +34,8 @@ sub index : Path : Args(0) { # Fetch all areas of the types we're interested in my $areas_info; eval { - my @area_types = $c->cobrand->area_types; - $areas_info = mySociety::MaPit::call('areas', \@area_types, + my $area_types = $c->cobrand->area_types; + $areas_info = mySociety::MaPit::call('areas', $area_types, min_generation => $c->cobrand->area_min_generation ); }; @@ -57,6 +57,7 @@ sub index : Path : Args(0) { $c->stash->{areas_info} = $areas_info; my @keys = sort { strcoll($areas_info->{$a}{name}, $areas_info->{$b}{name}) } keys %$areas_info; + @keys = $c->cobrand->filter_all_council_ids_list( @keys ); $c->stash->{areas_info_sorted} = [ map { $areas_info->{$_} } @keys ]; eval { @@ -68,8 +69,11 @@ sub index : Path : Args(0) { $c->stash->{open} = $j->{open}; }; if ($@) { - $c->stash->{message} = _("There was a problem showing the All Reports page. Please try again later.") . ' ' . - sprintf(_('The error was: %s'), $@); + $c->stash->{message} = _("There was a problem showing the All Reports page. Please try again later."); + if ($c->config->{STAGING_SITE}) { + $c->stash->{message} .= '</p><p>Perhaps the bin/update-all-reports script needs running.</p><p>' + . sprintf(_('The error was: %s'), $@); + } $c->stash->{template} = 'errors/generic.html'; return; } @@ -126,6 +130,8 @@ sub ward : Path : Args(2) { any_zoom => 1, ); + $c->cobrand->tweak_all_reports_map( $c ); + # List of wards unless ($c->stash->{ward}) { my $children = mySociety::MaPit::call('area/children', [ $c->stash->{council}->{id} ], @@ -211,13 +217,6 @@ sub council_check : Private { $q_council =~ s/\+/ /g; $q_council =~ s/\.html//; - # Manual misspelling redirect - if ($q_council =~ /^rhondda cynon taff$/i) { - my $url = $c->uri_for( '/reports/rhondda+cynon+taf' ); - $c->res->redirect( $url ); - $c->detach(); - } - # Check cobrand specific incantations - e.g. ONS codes for UK, # Oslo/ kommunes sharing a name in Norway return if $c->cobrand->reports_council_check( $c, $q_council ); @@ -232,9 +231,9 @@ sub council_check : Private { } # We must now have a string to check - my @area_types = $c->cobrand->area_types; + my $area_types = $c->cobrand->area_types; my $areas = mySociety::MaPit::call( 'areas', $q_council, - type => \@area_types, + type => $area_types, min_generation => $c->cobrand->area_min_generation ); if (keys %$areas == 1) { @@ -351,7 +350,7 @@ sub load_and_group_problems : Private { { photo => 'photo is not null' }, ], order_by => { -desc => 'lastupdate' }, - rows => 100, + rows => $c->cobrand->reports_per_page, } )->page( $page ); $c->stash->{pager} = $problems->pager; diff --git a/perllib/FixMyStreet/App/Controller/Rss.pm b/perllib/FixMyStreet/App/Controller/Rss.pm index 4d0b6cb93..fe4b652ed 100755 --- a/perllib/FixMyStreet/App/Controller/Rss.pm +++ b/perllib/FixMyStreet/App/Controller/Rss.pm @@ -172,7 +172,6 @@ sub generate : Private { $c->stash->{rss} = new XML::RSS( version => '2.0', encoding => 'UTF-8', - stylesheet => $c->cobrand->feed_xsl, encode_output => undef ); $c->stash->{rss}->add_module( @@ -205,14 +204,10 @@ sub query_main : Private { my ( $self, $c ) = @_; my $alert_type = $c->stash->{alert_type}; - my ( $site_restriction, $site_id ) = $c->cobrand->site_restriction( $c->cobrand->extra_data ); - # Only apply a site restriction if the alert uses the problem table - $site_restriction = '' unless $alert_type->item_table eq 'problem'; - # FIXME Do this in a nicer way at some point in the future... my $query = 'select * from ' . $alert_type->item_table . ' where ' . ($alert_type->head_table ? $alert_type->head_table . '_id=? and ' : '') - . $alert_type->item_where . $site_restriction . ' order by ' + . $alert_type->item_where . ' order by ' . $alert_type->item_order; my $rss_limit = mySociety::Config::get('RSS_LIMIT'); $query .= " limit $rss_limit" unless $c->stash->{type} =~ /^all/; @@ -250,12 +245,13 @@ sub add_row : Private { (my $title = _($alert_type->item_title)) =~ s/{{(.*?)}}/$row->{$1}/g; (my $link = $alert_type->item_link) =~ s/{{(.*?)}}/$row->{$1}/g; (my $desc = _($alert_type->item_description)) =~ s/{{(.*?)}}/$row->{$1}/g; - my $url = $c->uri_for( $link ); - if ( $row->{postcode} ) { - my $pc = $c->cobrand->format_postcode( $row->{postcode} ); - $title .= ", $pc"; + my $hashref_restriction = $c->cobrand->site_restriction; + my $base_url = $c->cobrand->base_url; + if ( $hashref_restriction && $hashref_restriction->{council} && $row->{council} && $row->{council} ne $hashref_restriction->{council} ) { + $base_url = $c->config->{BASE_URL}; } + my $url = $base_url . $link; my %item = ( title => ent($title), @@ -268,7 +264,7 @@ sub add_row : Private { if ($c->cobrand->allow_photo_display && $row->{photo}) { my $key = $alert_type->item_table eq 'comment' ? 'c/' : ''; - $item{description} .= ent("\n<br><img src=\"". $c->cobrand->base_url . "/photo/$key$row->{id}.jpeg\">"); + $item{description} .= ent("\n<br><img src=\"". $base_url . "/photo/$key$row->{id}.jpeg\">"); } if ( $row->{used_map} ) { diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm index 1434838f2..03dc69b00 100644 --- a/perllib/FixMyStreet/App/Controller/Tokens.pm +++ b/perllib/FixMyStreet/App/Controller/Tokens.pm @@ -34,7 +34,8 @@ sub confirm_problem : Path('/P') { # Load the problem my $data = $auth_token->data; my $problem_id = ref $data ? $data->{id} : $data; - my $problem = $c->cobrand->problems->find( { id => $problem_id } ) + # Look at all problems, not just cobrand, in case am approving something we don't actually show + my $problem = $c->model('DB::Problem')->find( { id => $problem_id } ) || $c->detach('token_error'); $c->stash->{problem} = $problem; @@ -78,7 +79,7 @@ sub confirm_problem : Path('/P') { $c->set_session_cookie_expire(0); if ( FixMyStreet::DB::Result::Problem->visible_states()->{$old_state} ) { - my $report_uri = $c->uri_for( '/report', $problem->id ); + my $report_uri = $c->cobrand->base_url_for_report( $problem ) . $problem->url; $c->res->redirect($report_uri); } diff --git a/perllib/FixMyStreet/App/View/Web.pm b/perllib/FixMyStreet/App/View/Web.pm index 092e362f9..eac194dff 100644 --- a/perllib/FixMyStreet/App/View/Web.pm +++ b/perllib/FixMyStreet/App/View/Web.pm @@ -83,14 +83,12 @@ sub tprintf { [% display_crosssell_advert( email, name ) %] -Displays a crosssell advert if permitted by the cobrand. +Displays a crosssell advert (will be fixmystreet cobrand only). =cut sub display_crosssell_advert { my ( $self, $c, $email, $name, %data ) = @_; - - return unless $c->cobrand->allow_crosssell_adverts(); return CrossSell::display_advert( $c, $email, $name, %data ); } diff --git a/perllib/FixMyStreet/Cobrand.pm b/perllib/FixMyStreet/Cobrand.pm index b88f6facc..881183463 100644 --- a/perllib/FixMyStreet/Cobrand.pm +++ b/perllib/FixMyStreet/Cobrand.pm @@ -38,7 +38,7 @@ Simply returns the config variable (so this function can be overridden in test s =cut sub _get_allowed_cobrands { - return FixMyStreet->config('ALLOWED_COBRANDS'); + return FixMyStreet->config('ALLOWED_COBRANDS') || []; } =head2 available_cobrand_classes @@ -46,9 +46,9 @@ sub _get_allowed_cobrands { @available_cobrand_classes = FixMyStreet::Cobrand->available_cobrand_classes(); -Return an array of all the classes that were found and that have monikers -that match the values from get_allowed_cobrands, in the order of -get_allowed_cobrands. +Return an array of all the classes from get_allowed_cobrands, in +the order of get_allowed_cobrands, with added class information +for those that have found classes. =cut @@ -58,7 +58,7 @@ sub available_cobrand_classes { my %all = map { $_->moniker => $_ } @ALL_COBRAND_CLASSES; my @avail; foreach (@{ $class->get_allowed_cobrands }) { - next unless $all{$_->{moniker}}; + #next unless $all{$_->{moniker}}; $_->{class} = $all{$_->{moniker}}; push @avail, $_; } @@ -66,6 +66,20 @@ sub available_cobrand_classes { return @avail; } +=head2 class + +=cut + +sub class { + my $avail = shift; + return $avail->{class} if $avail->{class}; + my $moniker = $avail->{moniker}; + Class::MOP::Class->create("FixMyStreet::Cobrand::$moniker" => ( + superclasses => [ 'FixMyStreet::Cobrand::Default' ], + )); + return "FixMyStreet::Cobrand::$moniker"; +} + =head2 get_class_for_host $cobrand_class = FixMyStreet::Cobrand->get_class_for_host( $host ); @@ -79,7 +93,7 @@ sub get_class_for_host { my $host = shift; foreach my $avail ( $class->available_cobrand_classes ) { - return $avail->{class} if $host =~ /$avail->{host}/; + return class($avail) if $host =~ /$avail->{host}/; } # if none match then use the default @@ -99,7 +113,7 @@ sub get_class_for_moniker { my $moniker = shift; foreach my $avail ( $class->available_cobrand_classes ) { - return $avail->{class} if $moniker eq $avail->{moniker}; + return class($avail) if $moniker eq $avail->{moniker}; } # Special case for old blank cobrand entries in fixmystreet.com. diff --git a/perllib/FixMyStreet/Cobrand/Barnet.pm b/perllib/FixMyStreet/Cobrand/Barnet.pm index b3876a2c6..768ca9efb 100644 --- a/perllib/FixMyStreet/Cobrand/Barnet.pm +++ b/perllib/FixMyStreet/Cobrand/Barnet.pm @@ -1,5 +1,5 @@ package FixMyStreet::Cobrand::Barnet; -use base 'FixMyStreet::Cobrand::UKCouncils'; +use parent 'FixMyStreet::Cobrand::UKCouncils'; use strict; use warnings; @@ -8,7 +8,6 @@ sub council_id { return 2489; } sub council_area { return 'Barnet'; } sub council_name { return 'Barnet Council'; } sub council_url { return 'barnet'; } -sub all_reports_style { return 'detailed'; } sub path_to_web_templates { my $self = shift; @@ -25,83 +24,13 @@ sub disambiguate_location { town => 'Barnet', centre => '51.612832,-0.218169', span => '0.0563,0.09', - bounds => [ '51.584682,-0.263169', '51.640982,-0.173169' ], + bounds => [ 51.584682, -0.263169, 51.640982, -0.173169 ], }; } -sub generate_problem_banner { - my ( $self, $problem ) = @_; - - my $banner = {}; - if ( $problem->is_open && time() - $problem->lastupdate_local->epoch > 8 * 7 * 24 * 60 * 60 ) - { - $banner->{id} = 'unknown'; - $banner->{text} = _('Unknown'); - } - if ($problem->is_fixed) { - $banner->{id} = 'fixed'; - $banner->{text} = _('Fixed'); - } - if ($problem->is_closed) { - $banner->{id} = 'closed'; - $banner->{text} = _('Closed'); - } - - if ( grep { $problem->state eq $_ } ( 'investigating', 'in progress', 'planned' ) ) { - $banner->{id} = 'progress'; - $banner->{text} = _('In progress'); - } - - return $banner; -} - -sub council_rss_alert_options { - my $self = shift; - my $all_councils = shift; - my $c = shift; - - my %councils = map { $_ => 1 } $self->area_types(); - - my $num_councils = scalar keys %$all_councils; - - my ( @options, @reported_to_options ); - if ( $num_councils == 1 or $num_councils == 2 ) { - my ($council, $ward); - foreach (values %$all_councils) { - if ($councils{$_->{type}}) { - $council = $_; - $council->{short_name} = $self->short_name( $council ); - ( $council->{id_name} = $council->{short_name} ) =~ tr/+/_/; - } else { - $ward = $_; - $ward->{short_name} = $self->short_name( $ward ); - ( $ward->{id_name} = $ward->{short_name} ) =~ tr/+/_/; - } - } - - push @options, - { - type => 'council', - id => sprintf( 'council:%s:%s', $council->{id}, $council->{id_name} ), - text => 'All problems within the council.', - rss_text => sprintf( _('RSS feed of problems within %s'), $council->{name}), - uri => $c->uri_for( '/rss/reports/' . $council->{short_name} ), - }; - push @options, - { - type => 'ward', - id => sprintf( 'ward:%s:%s:%s:%s', $council->{id}, $ward->{id}, $council->{id_name}, $ward->{id_name} ), - rss_text => sprintf( _('RSS feed of problems within %s ward'), $ward->{name}), - text => sprintf( _('Problems within %s ward'), $ward->{name}), - uri => $c->uri_for( '/rss/reports/' . $council->{short_name} . '/' . $ward->{short_name} ), - } if $ward; - } - - return ( \@options, @reported_to_options ? \@reported_to_options : undef ); -} - sub example_places { return [ 'N11 1NP', 'Wood St' ]; } + 1; diff --git a/perllib/FixMyStreet/Cobrand/Base.pm b/perllib/FixMyStreet/Cobrand/Base.pm index fada33b78..4941712b2 100644 --- a/perllib/FixMyStreet/Cobrand/Base.pm +++ b/perllib/FixMyStreet/Cobrand/Base.pm @@ -51,19 +51,5 @@ sub is_default { return $self->moniker eq 'default'; } -=head2 path_to_web_templates - - $path = $cobrand->path_to_web_templates( ); - -Returns the path to the templates for this cobrand - by default -"templates/web/$moniker" - -=cut - -sub path_to_web_templates { - my $self = shift; - return [ FixMyStreet->path_to( 'templates/web', $self->moniker )->stringify ]; -} - 1; diff --git a/perllib/FixMyStreet/Cobrand/Bromley.pm b/perllib/FixMyStreet/Cobrand/Bromley.pm index c5c6c6345..c33135673 100644 --- a/perllib/FixMyStreet/Cobrand/Bromley.pm +++ b/perllib/FixMyStreet/Cobrand/Bromley.pm @@ -1,6 +1,4 @@ package FixMyStreet::Cobrand::Bromley; -use mro 'c3'; -use parent 'FixMyStreet::Cobrand::FixMyStreet'; use parent 'FixMyStreet::Cobrand::UKCouncils'; use strict; @@ -10,15 +8,12 @@ sub council_id { return 2482; } sub council_area { return 'Bromley'; } sub council_name { return 'Bromley Council'; } sub council_url { return 'bromley'; } -sub all_reports_style { return 'detailed'; } sub base_url { return FixMyStreet->config('BASE_URL') if FixMyStreet->config('STAGING_SITE'); return 'https://fix.bromley.gov.uk'; } -sub admin_base_url { '' } - sub path_to_web_templates { my $self = shift; return [ @@ -27,22 +22,22 @@ sub path_to_web_templates { ]; } -sub site_title { - my ($self) = @_; - return "London Borough of Bromley - Report a problem in Bromley\x{2019}s streets or parks"; -} -sub site_name { - return 'Bromley FixMyStreet'; -} - sub disambiguate_location { - my $self = shift; + my $self = shift; + my $string = shift; + + my $town = 'Bromley'; + # Bing turns High St Bromley into Bromley High St which is in + # Bromley by Bow. + if ( $string =~ /high\+st/i ) { + $town .= ', BR1'; + } return { %{ $self->SUPER::disambiguate_location() }, - town => 'Bromley', + town => $town, centre => '51.366836,0.040623', span => '0.154963,0.24347', - bounds => [ '51.289355,-0.081112', '51.444318,0.162358' ], + bounds => [ 51.289355, -0.081112, 51.444318, 0.162358 ], }; } @@ -91,5 +86,20 @@ sub contact_email { } sub contact_name { 'Bromley Council (do not reply)'; } +sub reports_per_page { return 20; } + +sub tweak_all_reports_map { + my $self = shift; + my $c = shift; + + if ( !$c->stash->{ward} ) { + $c->stash->{map}->{longitude} = 0.040622967881348; + $c->stash->{map}->{latitude} = 51.36690161822; + $c->stash->{map}->{any_zoom} = 0; + $c->stash->{map}->{zoom} = 11; + } +} + + 1; diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 87bd2d316..0eff95d48 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -11,14 +11,34 @@ use Carp; use mySociety::MaPit; use mySociety::PostcodeUtil; +=head1 path_to_web_templates + + $path = $cobrand->path_to_web_templates( ); + +Returns the path to the templates for this cobrand - by default +"templates/web/$moniker" and "templates/web/fixmystreet" + +=cut + +sub path_to_web_templates { + my $self = shift; + my $paths = []; + push @$paths, FixMyStreet->path_to( 'templates/web', $self->moniker )->stringify + unless $self->is_default; + push @$paths, FixMyStreet->path_to( 'templates/web/fixmystreet' )->stringify; + return $paths; +} + =head1 country Returns the country that this cobrand operates in, as an ISO3166-alpha2 code. +Default is none. This is not really used for anything important (minor GB only +things involving eastings/northings mostly). =cut sub country { - return 'GB'; + return ''; } =head1 problems_clause @@ -44,13 +64,14 @@ sub problems { =head1 site_restriction -Return a site restriction clause and a site key if the cobrand uses a subset of -the FixMyStreet data. Parameter is any extra data the cobrand needs. Returns an -empty string and site key 0 if the cobrand uses all the data. +Return a site key and a hash of extra query parameters if the cobrand uses a +subset of the FixMyStreet data. Parameter is any extra data the cobrand needs. +Returns a site key of 0 and an empty hash if the cobrand uses all the data. =cut -sub site_restriction { return ( "", 0, {} ) } +sub site_restriction { return {}; } +sub site_key { return 0; } =head2 restriction @@ -64,31 +85,13 @@ sub restriction { return $self->moniker ? { cobrand => $self->moniker } : {}; } -=head2 base_url_for_emails - -Return the base url to use in links in emails for the cobranded version of the -site, parameter is extra data. - -=cut - -sub base_url_for_emails { - my $self = shift; - return $self->base_url; -} - =head2 base_url_with_lang =cut sub base_url_with_lang { my $self = shift; - my $email = shift; - - if ($email) { - return $self->base_url_for_emails; - } else { - return $self->base_url; - } + return $self->base_url; } =head2 admin_base_url @@ -97,23 +100,27 @@ Base URL for the admin interface. =cut -sub admin_base_url { '' } +sub admin_base_url { FixMyStreet->config('ADMIN_BASE_URL') || '' } -=head2 writetothem_url +=head2 base_url -URL for writetothem; parameter is COBRAND_DATA. +Return the base url for the cobranded version of the site =cut -sub writetothem_url { 0 } +sub base_url { FixMyStreet->config('BASE_URL') } -=head2 base_url +=head2 base_url_for_report -Return the base url for the cobranded version of the site +Return the base url for a report (might be different in a two-tier county, but +most of the time will be same as base_url). =cut -sub base_url { mySociety::Config::get('BASE_URL') } +sub base_url_for_report { + my ( $self, $report ) = @_; + return $self->base_url; +} =head2 base_host @@ -129,21 +136,12 @@ sub base_host { =head2 enter_postcode_text -Return the text that prompts the user to enter their postcode/place name. -Parameter is QUERY - -=cut - -sub enter_postcode_text { _('Enter a nearby street name and area') } - -=head2 all_reports_style - -Return the type of problem information to display on the all reports -pages for councils. Can be either simple or detailed. +Return override text that prompts the user to enter their postcode/place name. +Can be specified in template. =cut -sub all_reports_style { return 'simple'; } +sub enter_postcode_text { } =head2 set_lang_and_domain @@ -155,13 +153,19 @@ Set the language and domain of the site based on the cobrand and host. sub set_lang_and_domain { my ( $self, $lang, $unicode, $dir ) = @_; - my $set_lang = mySociety::Locale::negotiate_language( - 'en-gb,English,en_GB', $lang - ); - mySociety::Locale::gettext_domain( 'FixMyStreet', $unicode, $dir ); + + my $languages = join('|', @{$self->languages}); + my $lang_override = $self->language_override || $lang; + my $lang_domain = $self->language_domain || 'FixMyStreet'; + + my $set_lang = mySociety::Locale::negotiate_language( $languages, $lang_override ); + mySociety::Locale::gettext_domain( $lang_domain, $unicode, $dir ); mySociety::Locale::change(); return $set_lang; } +sub languages { FixMyStreet->config('LANGUAGES') || [ 'en-gb,English,en_GB' ] } +sub language_domain { } +sub language_override { } =head2 alert_list_options @@ -242,17 +246,11 @@ sub front_stats_data { =head2 disambiguate_location -Returns disambiguating information available +Returns any disambiguating information available. Defaults to none. =cut -sub disambiguate_location { - return { - country => 'uk', - bing_culture => 'en-GB', - bing_country => 'United Kingdom' - }; -} +sub disambiguate_location { FixMyStreet->config('GEOCODING_DISAMBIGUATION') or {}; } =head2 cobrand_data_for_generic_update @@ -272,54 +270,6 @@ Return cobrand extra data for the problem sub cobrand_data_for_generic_problem { '' } -=head2 extra_problem_data - -Parameter is QUERY. Return a string of extra data to be stored with a problem - -=cut - -sub extra_problem_data { '' } - -=head2 extra_update_data - -Parameter is QUERY. Return a string of extra data to be stored with an update - -=cut - -sub extra_update_data { '' } - -=head2 extra_alert_data - -Parameter is QUERY. Return a string of extra data to be stored with an alert - -=cut - -sub extra_alert_data { '' } - -=head2 extra_data - -Given a QUERY, extract any extra data required by the cobrand - -=cut - -sub extra_data { '' } - -=head2 extra_problem_meta_text - -Returns any extra text to be displayed with a PROBLEM. - -=cut - -sub extra_problem_meta_text { '' } - -=head2 extra_update_meta_text - -Returns any extra text to be displayed with an UPDATE. - -=cut - -sub extra_update_meta_text { '' } - =head2 uri Given a URL ($_[1]), QUERY, EXTRA_DATA, return a URL with any extra params @@ -352,24 +302,6 @@ Return any params to be added to responses sub header_params { return {} } -=head2 site_title - -Return the title to be used in page heads. - -=cut - -sub site_title { 'FixMyStreet' } - -=head2 site_name - -Return short name for use in emails. - -=cut -sub site_name { - my $self = shift; - $self->site_title; -} - =head2 map_type Return an override type of map if necessary. @@ -381,6 +313,16 @@ sub map_type { return; } +=head2 reports_per_page + +The number of reports to show per page on all reports page. + +=cut + +sub reports_per_page { + return FixMyStreet->config('ALL_REPORTS_PER_PAGE') || 100; +} + =head2 on_map_list_limit Return the maximum number of items to be given in the list of reports on the map @@ -405,15 +347,6 @@ Return a boolean indicating whether the cobrand allows photo uploads sub allow_photo_upload { return 1; } -=head2 allow_crosssell_adverts - -Return a boolean indicating whether the cobrand allows the display of crosssell -adverts - -=cut - -sub allow_crosssell_adverts { return 1; } - =head2 allow_photo_display Return a boolean indicating whether the cobrand allows photo display @@ -439,35 +372,6 @@ Given a QUERY, return LAT/LON and/or ERROR. sub geocode_postcode { my ( $self, $s ) = @_; - - if ($s =~ /^\d+$/) { - return { - error => 'FixMyStreet is a UK-based website that currently works in England, Scotland, and Wales. Please enter either a postcode, or a Great British street name and area.' - }; - } elsif (mySociety::PostcodeUtil::is_valid_postcode($s)) { - my $location = mySociety::MaPit::call('postcode', $s); - if ($location->{error}) { - return { - error => $location->{code} =~ /^4/ - ? _('That postcode was not recognised, sorry.') - : $location->{error} - }; - } - my $island = $location->{coordsyst}; - if (!$island) { - return { - error => _("Sorry, that appears to be a Crown dependency postcode, which we don't cover.") - }; - } elsif ($island eq 'I') { - return { - error => _("We do not currently cover Northern Ireland, I'm afraid.") - }; - } - return { - latitude => $location->{wgs84_lat}, - longitude => $location->{wgs84_lon}, - }; - } return {}; } @@ -502,17 +406,6 @@ sub find_closest { } } - # Get nearest postcode from Matthew's random gazetteer (put in MaPit? Or elsewhere?) - my $url = "http://gazetteer.dracos.vm.bytemark.co.uk/point/$latitude,$longitude.json"; - my $j = LWP::Simple::get($url); - if ($j) { - $j = JSON->new->utf8->allow_nonref->decode($j); - if ($j->{postcode}) { - $str .= sprintf(_("Nearest postcode to the pin placed on the map (automatically generated): %s (%sm away)"), - $j->{postcode}[0], $j->{postcode}[1]) . "\n\n"; - } - } - return $str; } @@ -581,14 +474,6 @@ COUNCILS pass any extra checks. CONTEXT is where we are on the site. sub council_check { return ( 1, '' ); } -=head2 feed_xsl - -Return an XSL to be used in rendering feeds - -=cut - -sub feed_xsl { '/xsl.xsl' } - =head2 all_councils_report Return a boolean indicating whether the cobrand displays a report of all @@ -636,7 +521,8 @@ The MaPit types this site handles =cut -sub area_types { qw(ZZZ) } +sub area_types { FixMyStreet->config('MAPIT_TYPES') || [ 'ZZZ' ] } +sub area_types_children { FixMyStreet->config('MAPIT_TYPES_CHILDREN') || [] } sub area_min_generation { '' } =head2 contact_name, contact_email @@ -646,42 +532,8 @@ used in emails). =cut -sub contact_name { $_[0]->get_cobrand_conf('CONTACT_NAME') } -sub contact_email { $_[0]->get_cobrand_conf('CONTACT_EMAIL') } - -=head2 get_cobrand_conf COBRAND KEY - -Get the value for KEY from the config file for COBRAND - -=cut - -sub get_cobrand_conf { - my ( $self, $key ) = @_; - my $value = undef; - my $cobrand_moniker = $self->moniker; - - my $cobrand_config_file = - FixMyStreet->path_to("conf/cobrands/$cobrand_moniker/general"); - my $normal_config_file = FixMyStreet->path_to('conf/general'); - - if ( -e $cobrand_config_file ) { - - # FIXME - don't rely on the config file name - should - # change mySociety::Config so that it can return values from a - # particular config file instead - mySociety::Config::set_file("$cobrand_config_file"); - my $config_key = $key . "_" . uc($cobrand_moniker); - $value = mySociety::Config::get( $config_key, undef ); - mySociety::Config::set_file("$normal_config_file"); - } - - # If we didn't find a value use one from normal config - if ( !defined($value) ) { - $value = mySociety::Config::get($key); - } - - return $value; -} +sub contact_name { FixMyStreet->config('CONTACT_NAME') } +sub contact_email { FixMyStreet->config('CONTACT_EMAIL') } =item email_host @@ -702,16 +554,6 @@ Remove councils whose reports go to another council sub remove_redundant_councils { my $self = shift; my $all_councils = shift; - - # Ipswich & St Edmundsbury are responsible for everything in their - # areas, not Suffolk - delete $all_councils->{2241} - if $all_councils->{2446} # - || $all_councils->{2443}; - - # Norwich is responsible for everything in its areas, not Norfolk - delete $all_councils->{2233} # - if $all_councils->{2391}; } =item filter_all_council_ids_list @@ -733,23 +575,21 @@ Remove extra information from council names for tidy URIs =cut sub short_name { - my $self = shift; - my ($area, $info) = @_; - # Special case Durham as it's the only place with two councils of the same name - return 'Durham+County' if $area->{name} eq 'Durham County Council'; - return 'Durham+City' if $area->{name} eq 'Durham City Council'; - - my $name = $area->{name}; - $name =~ s/ (Borough|City|District|County) Council$//; - $name =~ s/ Council$//; - $name =~ s/ & / and /; - $name =~ s{/}{_}g; - $name = URI::Escape::uri_escape_utf8($name); - $name =~ s/%20/+/g; - return $name; - + my $self = shift; + my ($area, $info) = @_; + my $name = $area->{name}; + $name = URI::Escape::uri_escape_utf8($name); + $name =~ s/%20/+/g; + return $name; } +=item is_council + +For UK sub-cobrands, to specify various alternations needed for them. + +=cut +sub is_council { 0; } + =item council_rss_alert_options Generate a set of options for council rss alerts. @@ -757,187 +597,34 @@ Generate a set of options for council rss alerts. =cut sub council_rss_alert_options { - my $self = shift; - my $all_councils = shift; - my $c = shift; - - my %councils = map { $_ => 1 } $self->area_types(); + my ( $self, $all_councils, $c ) = @_; - my $num_councils = scalar keys %$all_councils; - - my ( @options, @reported_to_options ); - if ( $num_councils == 1 or $num_councils == 2 ) { - my ($council, $ward); + my ( @options, @reported_to_options ); foreach (values %$all_councils) { - if ($councils{$_->{type}}) { - $council = $_; - $council->{short_name} = $self->short_name( $council ); - ( $council->{id_name} = $council->{short_name} ) =~ tr/+/_/; - } else { - $ward = $_; - $ward->{short_name} = $self->short_name( $ward ); - ( $ward->{id_name} = $ward->{short_name} ) =~ tr/+/_/; - } - } - $council->{name} = 'London Borough of Bromley' - if $council->{name} eq 'Bromley Council'; - - push @options, - { - type => 'council', - id => sprintf( 'council:%s:%s', $council->{id}, $council->{id_name} ), - text => sprintf( _('Problems within %s'), $council->{name}), - rss_text => sprintf( _('RSS feed of problems within %s'), $council->{name}), - uri => $c->uri_for( '/rss/reports/' . $council->{short_name} ), - }; - push @options, - { - type => 'ward', - id => sprintf( 'ward:%s:%s:%s:%s', $council->{id}, $ward->{id}, $council->{id_name}, $ward->{id_name} ), - rss_text => sprintf( _('RSS feed of problems within %s ward'), $ward->{name}), - text => sprintf( _('Problems within %s ward'), $ward->{name}), - uri => $c->uri_for( '/rss/reports/' . $council->{short_name} . '/' . $ward->{short_name} ), - } if $ward; - } elsif ( $num_councils == 4 ) { -# # Two-tier council - my ($county, $district, $c_ward, $d_ward); - foreach (values %$all_councils) { - $_->{short_name} = $self->short_name( $_ ); - ( $_->{id_name} = $_->{short_name} ) =~ tr/+/_/; - if ($_->{type} eq 'CTY') { - $county = $_; - } elsif ($_->{type} eq 'DIS') { - $district = $_; - } elsif ($_->{type} eq 'CED') { - $c_ward = $_; - } elsif ($_->{type} eq 'DIW') { - $d_ward = $_; - } - } - my $district_name = $district->{name}; - my $d_ward_name = $d_ward->{name}; - my $county_name = $county->{name}; - my $c_ward_name = $c_ward->{name}; - - push @options, - { - type => 'area', - id => sprintf( 'area:%s:%s', $district->{id}, $district->{id_name} ), - text => $district_name, - rss_text => sprintf( _('RSS feed for %s'), $district_name ), - uri => $c->uri_for( '/rss/area/' . $district->{short_name} ) - }, - { - type => 'area', - id => sprintf( 'area:%s:%s:%s:%s', $district->{id}, $d_ward->{id}, $district->{id_name}, $d_ward->{id_name} ), - text => sprintf( _('%s ward, %s'), $d_ward_name, $district_name ), - rss_text => sprintf( _('RSS feed for %s ward, %s'), $d_ward_name, $district_name ), - uri => $c->uri_for( '/rss/area/' . $district->{short_name} . '/' . $d_ward->{short_name} ) - }, - { - type => 'area', - id => sprintf( 'area:%s:%s', $county->{id}, $county->{id_name} ), - text => $county_name, - rss_text => sprintf( _('RSS feed for %s'), $county_name ), - uri => $c->uri_for( '/rss/area/' . $county->{short_name} ) - }, - { - type => 'area', - id => sprintf( 'area:%s:%s:%s:%s', $county->{id}, $c_ward->{id}, $county->{id_name}, $c_ward->{id_name} ), - text => sprintf( _('%s ward, %s'), $c_ward_name, $county_name ), - rss_text => sprintf( _('RSS feed for %s ward, %s'), $c_ward_name, $county_name ), - uri => $c->uri_for( '/rss/area/' . $county->{short_name} . '/' . $c_ward->{short_name} ) - }; - - push @reported_to_options, - { + $_->{short_name} = $self->short_name( $_ ); + ( $_->{id_name} = $_->{short_name} ) =~ tr/+/_/; + push @options, { type => 'council', - id => sprintf( 'council:%s:%s', $district->{id}, $district->{id_name} ), - text => $district->{name}, - rss_text => sprintf( _('RSS feed of %s'), $district->{name}), - uri => $c->uri_for( '/rss/reports/' . $district->{short_name} ), - }, - { - type => 'ward', - id => sprintf( 'ward:%s:%s:%s:%s', $district->{id}, $d_ward->{id}, $district->{id_name}, $d_ward->{id_name} ), - rss_text => sprintf( _('RSS feed of %s, within %s ward'), $district->{name}, $d_ward->{name}), - text => sprintf( _('%s, within %s ward'), $district->{name}, $d_ward->{name}), - uri => $c->uri_for( '/rss/reports/' . $district->{short_name} . '/' . $d_ward->{short_name} ), - }, - { - type => 'council', - id => sprintf( 'council:%s:%s', $county->{id}, $county->{id_name} ), - text => $county->{name}, - rss_text => sprintf( _('RSS feed of %s'), $county->{name}), - uri => $c->uri_for( '/rss/reports/' . $county->{short_name} ), - }, - { - type => 'ward', - id => sprintf( 'ward:%s:%s:%s:%s', $county->{id}, $c_ward->{id}, $county->{id_name}, $c_ward->{id_name} ), - rss_text => sprintf( _('RSS feed of %s, within %s ward'), $county->{name}, $c_ward->{name}), - text => sprintf( _('%s, within %s ward'), $county->{name}, $c_ward->{name}), - uri => $c->uri_for( '/rss/reports/' . $county->{short_name} . '/' . $c_ward->{short_name} ), - }; - - - } else { - throw Error::Simple('An area with three tiers of council? Impossible! '. join('|',keys %$all_councils)); + id => sprintf( 'council:%s:%s', $_->{id}, $_->{id_name} ), + text => sprintf( _('Problems within %s'), $_->{name}), + rss_text => sprintf( _('RSS feed of problems within %s'), $_->{name}), + uri => $c->uri_for( '/rss/reports/' . $_->{short_name} ), + }; } return ( \@options, @reported_to_options ? \@reported_to_options : undef ); } -=head2 generate_problem_banner - - my $banner = $c->cobrand->generate_problem_banner; - - <p id="[% banner.id %]:>[% banner.text %]</p> +=head2 reports_council_check -Generate id and text for banner that appears at top of problem page. +This function is called by the All Reports page, and lets you do some cobrand +specific checking on the URL passed to try and match to a relevant area. =cut -sub generate_problem_banner { - my ( $self, $problem ) = @_; - - my $banner = {}; - if ( $problem->is_open && time() - $problem->lastupdate_local->epoch > 8 * 7 * 24 * 60 * 60 ) - { - $banner->{id} = 'unknown'; - $banner->{text} = _('This problem is old and of unknown status.'); - } - if ($problem->is_fixed) { - $banner->{id} = 'fixed'; - $banner->{text} = _('This problem has been fixed') . '.'; - } - if ($problem->is_closed) { - $banner->{id} = 'closed'; - $banner->{text} = _('This problem has been closed') . '.'; - } - - if ( grep { $problem->state eq $_ } ( 'investigating', 'in progress', 'planned' ) ) { - $banner->{id} = 'progress'; - $banner->{text} = _('This problem is in progress') . '.'; - } - - return $banner; -} - sub reports_council_check { my ( $self, $c, $code ) = @_; - - if ($code =~ /^(\d\d)([a-z]{2})?([a-z]{2})?$/i) { - my $area = mySociety::MaPit::call( 'area', uc $code ); - $c->detach( 'redirect_index' ) if $area->{error}; # Given a bad/old ONS code - if (length($code) == 6) { - my $council = mySociety::MaPit::call( 'area', $area->{parent_area} ); - $c->stash->{ward} = $area; - $c->stash->{council} = $council; - } else { - $c->stash->{council} = $area; - } - $c->detach( 'redirect_area' ); - } + return 0; } =head2 default_photo_resize @@ -960,7 +647,7 @@ sub get_report_stats { return 0; } sub get_council_sender { return 'Email' }; sub example_places { - return [ 'B2 4QA', 'Tib St, Manchester' ]; + return FixMyStreet->config('EXAMPLE_PLACES') || [ 'High Street', 'Main Street' ]; } =head2 only_authed_can_create @@ -996,5 +683,15 @@ sub pin_colour { return $p->is_fixed ? 'green' : 'red'; } +=head2 tweak_all_reports_map + +Used to tweak the display settings of the map on the all reports pages. + +Used in some cobrands to improve the intial display for Internet Explorer. + +=cut + +sub tweak_all_reports_map {} + 1; diff --git a/perllib/FixMyStreet/Cobrand/EmptyHomes.pm b/perllib/FixMyStreet/Cobrand/EmptyHomes.pm index 6885f6a95..c3d13448d 100644 --- a/perllib/FixMyStreet/Cobrand/EmptyHomes.pm +++ b/perllib/FixMyStreet/Cobrand/EmptyHomes.pm @@ -1,5 +1,5 @@ package FixMyStreet::Cobrand::EmptyHomes; -use base 'FixMyStreet::Cobrand::FixMyStreet'; +use base 'FixMyStreet::Cobrand::UK'; use strict; use warnings; @@ -22,25 +22,15 @@ sub base_url { return $base_url; } -sub admin_base_url { - return 'https://secure.mysociety.org/admin/emptyhomes/'; -} - sub area_types { - return qw(DIS LBO MTD UTA LGD COI); # No CTY + [ 'DIS', 'LBO', 'MTD', 'UTA', 'LGD', 'COI' ]; # No CTY } - sub base_url_with_lang { my $self = shift; - my $email = shift; my $base = $self->base_url; - if ($email) { - $base = $self->base_url_for_emails; - } - my $lang = $mySociety::Locale::lang; if ($lang eq 'cy') { $base =~ s{http://}{$&cy.}; @@ -50,43 +40,8 @@ sub base_url_with_lang { return $base; } -=item set_lang_and_domain LANG UNICODE - -Set the language and text domain for the site based on the query and host. - -=cut - -sub set_lang_and_domain { - my ( $self, $lang, $unicode, $dir ) = @_; - my $set_lang = mySociety::Locale::negotiate_language( - 'en-gb,English,en_GB|cy,Cymraeg,cy_GB', $lang ); - mySociety::Locale::gettext_domain( 'FixMyStreet-EmptyHomes', $unicode, - $dir ); - mySociety::Locale::change(); - return $set_lang; -} - -=item site_title - -Return the title to be used in page heads - -=cut - -sub site_title { - my ($self) = @_; - return _('Report Empty Homes'); -} - -=item feed_xsl - -Return the XSL file path to be used for feeds' - -=cut - -sub feed_xsl { - my ($self) = @_; - return '/xsl.eha.xsl'; -} +sub languages { [ 'en-gb,English,en_GB', 'cy,Cymraeg,cy_GB' ] } +sub language_domain { 'FixMyStreet-EmptyHomes' } =item shorten_recency_if_new_greater_than_fixed @@ -98,28 +53,6 @@ sub shorten_recency_if_new_greater_than_fixed { return 0; } -=head2 generate_problem_banner - - my $banner = $c->cobrand->generate_problem_banner; - - <p id="[% banner.id %]:>[% banner.text %]</p> - -Generate id and text for banner that appears at top of problem page. - -=cut - -sub generate_problem_banner { - my ( $self, $problem ) = @_; - - my $banner = {}; - if ($problem->is_fixed ) { - $banner->{id} = 'fixed'; - $banner->{text} = _('This problem has been fixed') . '.'; - } - - return $banner; -} - =head2 default_photo_resize Size that photos are to be resized to for display. If photos aren't @@ -140,7 +73,7 @@ sub council_rss_alert_options { my $all_councils = shift; my $c = shift; - my %councils = map { $_ => 1 } $self->area_types(); + my %councils = map { $_ => 1 } @{$self->area_types}; my $num_councils = scalar keys %$all_councils; diff --git a/perllib/FixMyStreet/Cobrand/FiksGataMi.pm b/perllib/FixMyStreet/Cobrand/FiksGataMi.pm index 8ff5e3656..85ebf035e 100644 --- a/perllib/FixMyStreet/Cobrand/FiksGataMi.pm +++ b/perllib/FixMyStreet/Cobrand/FiksGataMi.pm @@ -8,24 +8,17 @@ use Carp; use mySociety::MaPit; use FixMyStreet::Geocode::OSM; -sub country { - return 'NO'; +sub path_to_web_templates { + my $self = shift; + return [ FixMyStreet->path_to( 'templates/web', $self->moniker )->stringify ]; } -sub set_lang_and_domain { - my ( $self, $lang, $unicode, $dir ) = @_; - my $set_lang = mySociety::Locale::negotiate_language( - 'en-gb,English,en_GB|nb,Norwegian,nb_NO', 'nb' - ); - mySociety::Locale::gettext_domain( 'FixMyStreet', $unicode, $dir ); - mySociety::Locale::change(); - return $set_lang; +sub country { + return 'NO'; } -sub site_title { - my ($self) = @_; - return 'FiksGataMi'; -} +sub languages { [ 'en-gb,English,en_GB', 'nb,Norwegian,nb_NO' ] } +sub language_override { 'nb' } sub enter_postcode_text { my ( $self ) = @_; @@ -41,21 +34,13 @@ sub disambiguate_location { } sub area_types { - return ( 'NKO', 'NFY', 'NRA' ); -} - -sub area_min_generation { - return ''; + [ 'NKO', 'NFY', 'NRA' ]; } sub admin_base_url { return 'http://www.fiksgatami.no/admin/'; } -sub writetothem_url { - return 'http://www.norge.no/styresmakter/'; -} - # If lat/lon are present in the URL, OpenLayers will use that to centre the map. # Need to specify a zoom to stop it defaulting to null/0. sub uri { @@ -243,9 +228,9 @@ sub reports_council_check { # Some kommunes have the same name, use the fylke name to work out which. my ($kommune, $fylke) = split /\s*,\s*/, $council; - my @area_types = $c->cobrand->area_types; - my $areas_k = mySociety::MaPit::call('areas', $kommune, type => \@area_types); - my $areas_f = mySociety::MaPit::call('areas', $fylke, type => \@area_types); + my $area_types = $c->cobrand->area_types; + my $areas_k = mySociety::MaPit::call('areas', $kommune, type => $area_types); + my $areas_f = mySociety::MaPit::call('areas', $fylke, type => $area_types); if (keys %$areas_f == 1) { ($fylke) = values %$areas_f; foreach (values %$areas_k) { diff --git a/perllib/FixMyStreet/Cobrand/FixMyStreet.pm b/perllib/FixMyStreet/Cobrand/FixMyStreet.pm index fbc48449c..00f161dea 100644 --- a/perllib/FixMyStreet/Cobrand/FixMyStreet.pm +++ b/perllib/FixMyStreet/Cobrand/FixMyStreet.pm @@ -1,5 +1,5 @@ package FixMyStreet::Cobrand::FixMyStreet; -use base 'FixMyStreet::Cobrand::Default'; +use base 'FixMyStreet::Cobrand::UK'; sub area_types { return qw(DIS LBO MTD UTA CTY COI); } sub area_min_generation { 10 } @@ -18,76 +18,5 @@ sub admin_base_url { return 'https://secure.mysociety.org/admin/bci/'; } -sub get_council_sender { - my ( $self, $area_id, $area_info ) = @_; - - my $send_method; - - my $council_config = FixMyStreet::App->model("DB::Open311conf")->search( { area_id => $area_id } )->first; - $send_method = $council_config->send_method if $council_config; - - return $send_method if $send_method; - - return 'London' if $area_info->{type} eq 'LBO'; - - return 'Email'; -} - -sub all_reports_style { return 'detailed'; } - -sub generate_problem_banner { - my ( $self, $problem ) = @_; - - my $banner = {}; - if ( $problem->is_open && time() - $problem->lastupdate_local->epoch > 8 * 7 * 24 * 60 * 60 ) - { - $banner->{id} = 'unknown'; - $banner->{text} = _('Unknown'); - } - if ($problem->is_fixed) { - $banner->{id} = 'fixed'; - $banner->{text} = _('Fixed'); - } - if ($problem->is_closed) { - $banner->{id} = 'closed'; - $banner->{text} = _('Closed'); - } - - if ( grep { $problem->state eq $_ } ( 'investigating', 'in progress', 'planned' ) ) { - $banner->{id} = 'progress'; - $banner->{text} = _('In progress'); - } - - return $banner; -} - -sub process_extras { - my $self = shift; - my $ctx = shift; - my $area_id = shift; - my $extra = shift; - my $fields = shift || []; - - if ( $area_id == 2482 ) { - my @fields = ( 'fms_extra_title', @$fields ); - for my $field ( @fields ) { - my $value = $ctx->request->param( $field ); - - if ( !$value ) { - $ctx->stash->{field_errors}->{ $field } = _('This information is required'); - } - push @$extra, { - name => $field, - description => uc( $field), - value => $value || '', - }; - } - - if ( $ctx->request->param('fms_extra_title') ) { - $ctx->stash->{fms_extra_title} = $ctx->request->param('fms_extra_title'); - $ctx->stash->{extra_name_info} = 1; - } - } -} 1; diff --git a/perllib/FixMyStreet/Cobrand/LichfieldDC.pm b/perllib/FixMyStreet/Cobrand/LichfieldDC.pm index 804289d34..5c8a04681 100644 --- a/perllib/FixMyStreet/Cobrand/LichfieldDC.pm +++ b/perllib/FixMyStreet/Cobrand/LichfieldDC.pm @@ -11,10 +11,6 @@ sub council_url { return 'lichfielddc'; } # Different to councils parent due to this being a two-tier council. If we get # more, this can be genericised in the parent. -sub site_restriction { - return ( "and council like '%2434%'", 'lichfield', { council => '2434' } ); -} - sub problems_clause { return { council => { like => '%2434%' } }; } @@ -26,9 +22,20 @@ sub disambiguate_location { %{ $self->SUPER::disambiguate_location() }, centre => '52.688198,-1.804966', span => '0.1196,0.218675', - bounds => [ '52.584891,-1.963232', '52.807793,-1.586291' ], + bounds => [ 52.584891, -1.963232, 52.807793, -1.586291 ], }; } +# If we ever link to a county problem report, needs to be to main FixMyStreet +sub base_url_for_report { + my ( $self, $report ) = @_; + my %councils = map { $_ => 1 } @{$report->councils}; + if ( $councils{2434} ) { + return $self->base_url; + } else { + return FixMyStreet->config('BASE_URL'); + } +} + 1; diff --git a/perllib/FixMyStreet/Cobrand/Reading.pm b/perllib/FixMyStreet/Cobrand/Reading.pm index c8591924e..4cd3f82e2 100644 --- a/perllib/FixMyStreet/Cobrand/Reading.pm +++ b/perllib/FixMyStreet/Cobrand/Reading.pm @@ -18,7 +18,7 @@ sub disambiguate_location { town => 'Reading', centre => '51.452983,-0.983827', span => '0.083355,0.1245', - bounds => [ '51.409779,-1.052994', '51.493134,-0.928494' ], + bounds => [ 51.409779, -1.052994, 51.493134, -0.928494 ], }; } diff --git a/perllib/FixMyStreet/Cobrand/Southampton.pm b/perllib/FixMyStreet/Cobrand/Southampton.pm index b57091bef..b7374149a 100644 --- a/perllib/FixMyStreet/Cobrand/Southampton.pm +++ b/perllib/FixMyStreet/Cobrand/Southampton.pm @@ -16,7 +16,7 @@ sub disambiguate_location { town => 'Southampton', centre => '50.913822,-1.400493', span => '0.084628,0.15701', - bounds => [ '50.871508,-1.478998', '50.956136,-1.321988' ], + bounds => [ 50.871508, -1.478998, 50.956136, -1.321988 ], }; } diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm new file mode 100644 index 000000000..c2618cbd9 --- /dev/null +++ b/perllib/FixMyStreet/Cobrand/UK.pm @@ -0,0 +1,339 @@ +package FixMyStreet::Cobrand::UK; +use base 'FixMyStreet::Cobrand::Default'; + +use mySociety::VotingArea; + +sub path_to_web_templates { + my $self = shift; + return [ FixMyStreet->path_to( 'templates/web', $self->moniker )->stringify ]; +} + +sub country { return 'GB'; } +sub area_types { [ 'DIS', 'LBO', 'MTD', 'UTA', 'CTY', 'COI', 'LGD' ] } +sub area_types_children { $mySociety::VotingArea::council_child_types } +sub area_min_generation { 10 } + +sub enter_postcode_text { + my ( $self ) = @_; + return _("Enter a nearby UK postcode, or street name and area"); +} + +sub example_places { + return [ 'B2 4QA', 'Tib St, Manchester' ]; +} + +sub disambiguate_location { + return { + country => 'gb', + google_country => 'uk', + bing_culture => 'en-GB', + bing_country => 'United Kingdom' + }; +} + +sub get_council_sender { + my ( $self, $area_id, $area_info ) = @_; + + my $send_method; + + my $council_config = FixMyStreet::App->model("DB::Open311conf")->search( { area_id => $area_id } )->first; + $send_method = $council_config->send_method if $council_config; + + return $send_method if $send_method; + + return 'London' if $area_info->{type} eq 'LBO'; + return 'NI' if $area_info->{type} eq 'LGD'; + return 'Email'; +} + +sub process_extras { + my $self = shift; + my $ctx = shift; + my $area_id = shift; + my $extra = shift; + my $fields = shift || []; + + if ( $area_id == 2482 ) { + my @fields = ( 'fms_extra_title', @$fields ); + for my $field ( @fields ) { + my $value = $ctx->request->param( $field ); + + if ( !$value ) { + $ctx->stash->{field_errors}->{ $field } = _('This information is required'); + } + push @$extra, { + name => $field, + description => uc( $field), + value => $value || '', + }; + } + + if ( $ctx->request->param('fms_extra_title') ) { + $ctx->stash->{fms_extra_title} = $ctx->request->param('fms_extra_title'); + $ctx->stash->{extra_name_info} = 1; + } + } +} + +sub geocode_postcode { + my ( $self, $s ) = @_; + + if ($s =~ /^\d+$/) { + return { + error => 'FixMyStreet is a UK-based website. Please enter either a UK postcode, or street name and area.' + }; + } elsif (mySociety::PostcodeUtil::is_valid_postcode($s)) { + my $location = mySociety::MaPit::call('postcode', $s); + if ($location->{error}) { + return { + error => $location->{code} =~ /^4/ + ? _('That postcode was not recognised, sorry.') + : $location->{error} + }; + } + my $island = $location->{coordsyst}; + if (!$island) { + return { + error => _("Sorry, that appears to be a Crown dependency postcode, which we don't cover.") + }; + } + return { + latitude => $location->{wgs84_lat}, + longitude => $location->{wgs84_lon}, + }; + } + return {}; +} + +sub remove_redundant_councils { + my $self = shift; + my $all_councils = shift; + + # Ipswich & St Edmundsbury are responsible for everything in their + # areas, not Suffolk + delete $all_councils->{2241} + if $all_councils->{2446} # + || $all_councils->{2443}; + + # Norwich is responsible for everything in its areas, not Norfolk + delete $all_councils->{2233} # + if $all_councils->{2391}; +} + +sub filter_all_council_ids_list { + my $self = shift; + my @all_councils_ids = @_; + + # Ignore the four council areas introduced because of generation 15 + # (where we put the new boundaries under the old IDs) + return grep { $_ < 141648 || $_ > 141651 } @all_councils_ids; +} + +sub short_name { + my $self = shift; + my ($area, $info) = @_; + # Special case Durham as it's the only place with two councils of the same name + return 'Durham+County' if $area->{name} eq 'Durham County Council'; + return 'Durham+City' if $area->{name} eq 'Durham City Council'; + + my $name = $area->{name}; + $name =~ s/ (Borough|City|District|County) Council$//; + $name =~ s/ Council$//; + $name =~ s/ & / and /; + $name =~ s{/}{_}g; + $name = URI::Escape::uri_escape_utf8($name); + $name =~ s/%20/+/g; + return $name; + +} + +sub find_closest { + my ( $self, $latitude, $longitude, $problem ) = @_; + + my $str = $self->SUPER::find_closest( $latitude, $longitude, $problem ); + + # Get nearest postcode from Matthew's random gazetteer (put in MaPit? Or elsewhere?) + my $url = "http://gazetteer.dracos.vm.bytemark.co.uk/point/$latitude,$longitude.json"; + my $j = LWP::Simple::get($url); + if ($j) { + $j = JSON->new->utf8->allow_nonref->decode($j); + if ($j->{postcode}) { + $str .= sprintf(_("Nearest postcode to the pin placed on the map (automatically generated): %s (%sm away)"), + $j->{postcode}[0], $j->{postcode}[1]) . "\n\n"; + } + } + + return $str; +} + +sub reports_council_check { + my ( $self, $c, $code ) = @_; + + # Manual misspelling redirect + if ($code =~ /^rhondda cynon taff$/i) { + my $url = $c->uri_for( '/reports/Rhondda+Cynon+Taf' ); + $c->res->redirect( $url ); + $c->detach(); + } + + # Old ONS codes + if ($code =~ /^(\d\d)([a-z]{2})?([a-z]{2})?$/i) { + my $area = mySociety::MaPit::call( 'area', uc $code ); + $c->detach( 'redirect_index' ) if $area->{error}; # Given a bad/old ONS code + if (length($code) == 6) { + my $council = mySociety::MaPit::call( 'area', $area->{parent_area} ); + $c->stash->{ward} = $area; + $c->stash->{council} = $council; + } else { + $c->stash->{council} = $area; + } + $c->detach( 'redirect_area' ); + } + + # New ONS codes + if ($code =~ /^[ESWN]\d{8}$/i) { + my $area = mySociety::MaPit::call( 'area', uc $code ); + $c->detach( 'redirect_index' ) if $area->{error}; # Given a bad/old ONS code + if ($code =~ /^(E05|W05|S13)/) { + my $council = mySociety::MaPit::call( 'area', $area->{parent_area} ); + $c->stash->{ward} = $area; + $c->stash->{council} = $council; + $c->detach( 'redirect_area' ); + } elsif ($code =~ /^(W06|S12|E0[6-9]|E10)/) { + $c->stash->{council} = $area; + $c->detach( 'redirect_area' ); + } + } + +} + +sub council_rss_alert_options { + my $self = shift; + my $all_councils = shift; + my $c = shift; + + my %councils = map { $_ => 1 } @{$self->area_types}; + + my $num_councils = scalar keys %$all_councils; + + my ( @options, @reported_to_options ); + if ( $num_councils == 1 or $num_councils == 2 ) { + my ($council, $ward); + foreach (values %$all_councils) { + if ($councils{$_->{type}}) { + $council = $_; + $council->{short_name} = $self->short_name( $council ); + ( $council->{id_name} = $council->{short_name} ) =~ tr/+/_/; + } else { + $ward = $_; + $ward->{short_name} = $self->short_name( $ward ); + ( $ward->{id_name} = $ward->{short_name} ) =~ tr/+/_/; + } + } + $council->{name} = 'London Borough of Bromley' + if $council->{name} eq 'Bromley Council'; + + my $council_text; + if ( $c->cobrand->is_council ) { + $council_text = 'All problems within the council'; + } else { + $council_text = sprintf( _('Problems within %s'), $council->{name}); + } + + push @options, { + type => 'council', + id => sprintf( 'council:%s:%s', $council->{id}, $council->{id_name} ), + text => $council_text, + rss_text => sprintf( _('RSS feed of problems within %s'), $council->{name}), + uri => $c->uri_for( '/rss/reports/' . $council->{short_name} ), + }; + push @options, { + type => 'ward', + id => sprintf( 'ward:%s:%s:%s:%s', $council->{id}, $ward->{id}, $council->{id_name}, $ward->{id_name} ), + rss_text => sprintf( _('RSS feed of problems within %s ward'), $ward->{name}), + text => sprintf( _('Problems within %s ward'), $ward->{name}), + uri => $c->uri_for( '/rss/reports/' . $council->{short_name} . '/' . $ward->{short_name} ), + } if $ward; + + } elsif ( $num_councils == 4 ) { + # Two-tier council + my ($county, $district, $c_ward, $d_ward); + foreach (values %$all_councils) { + $_->{short_name} = $self->short_name( $_ ); + ( $_->{id_name} = $_->{short_name} ) =~ tr/+/_/; + if ($_->{type} eq 'CTY') { + $county = $_; + } elsif ($_->{type} eq 'DIS') { + $district = $_; + } elsif ($_->{type} eq 'CED') { + $c_ward = $_; + } elsif ($_->{type} eq 'DIW') { + $d_ward = $_; + } + } + my $district_name = $district->{name}; + my $d_ward_name = $d_ward->{name}; + my $county_name = $county->{name}; + my $c_ward_name = $c_ward->{name}; + + push @options, { + type => 'area', + id => sprintf( 'area:%s:%s', $district->{id}, $district->{id_name} ), + text => $district_name, + rss_text => sprintf( _('RSS feed for %s'), $district_name ), + uri => $c->uri_for( '/rss/area/' . $district->{short_name} ) + }, { + type => 'area', + id => sprintf( 'area:%s:%s:%s:%s', $district->{id}, $d_ward->{id}, $district->{id_name}, $d_ward->{id_name} ), + text => sprintf( _('%s ward, %s'), $d_ward_name, $district_name ), + rss_text => sprintf( _('RSS feed for %s ward, %s'), $d_ward_name, $district_name ), + uri => $c->uri_for( '/rss/area/' . $district->{short_name} . '/' . $d_ward->{short_name} ) + }, { + type => 'area', + id => sprintf( 'area:%s:%s', $county->{id}, $county->{id_name} ), + text => $county_name, + rss_text => sprintf( _('RSS feed for %s'), $county_name ), + uri => $c->uri_for( '/rss/area/' . $county->{short_name} ) + }, { + type => 'area', + id => sprintf( 'area:%s:%s:%s:%s', $county->{id}, $c_ward->{id}, $county->{id_name}, $c_ward->{id_name} ), + text => sprintf( _('%s ward, %s'), $c_ward_name, $county_name ), + rss_text => sprintf( _('RSS feed for %s ward, %s'), $c_ward_name, $county_name ), + uri => $c->uri_for( '/rss/area/' . $county->{short_name} . '/' . $c_ward->{short_name} ) + }; + + push @reported_to_options, { + type => 'council', + id => sprintf( 'council:%s:%s', $district->{id}, $district->{id_name} ), + text => $district->{name}, + rss_text => sprintf( _('RSS feed of %s'), $district->{name}), + uri => $c->uri_for( '/rss/reports/' . $district->{short_name} ), + }, { + type => 'ward', + id => sprintf( 'ward:%s:%s:%s:%s', $district->{id}, $d_ward->{id}, $district->{id_name}, $d_ward->{id_name} ), + rss_text => sprintf( _('RSS feed of %s, within %s ward'), $district->{name}, $d_ward->{name}), + text => sprintf( _('%s, within %s ward'), $district->{name}, $d_ward->{name}), + uri => $c->uri_for( '/rss/reports/' . $district->{short_name} . '/' . $d_ward->{short_name} ), + }, { + type => 'council', + id => sprintf( 'council:%s:%s', $county->{id}, $county->{id_name} ), + text => $county->{name}, + rss_text => sprintf( _('RSS feed of %s'), $county->{name}), + uri => $c->uri_for( '/rss/reports/' . $county->{short_name} ), + }, { + type => 'ward', + id => sprintf( 'ward:%s:%s:%s:%s', $county->{id}, $c_ward->{id}, $county->{id_name}, $c_ward->{id_name} ), + rss_text => sprintf( _('RSS feed of %s, within %s ward'), $county->{name}, $c_ward->{name}), + text => sprintf( _('%s, within %s ward'), $county->{name}, $c_ward->{name}), + uri => $c->uri_for( '/rss/reports/' . $county->{short_name} . '/' . $c_ward->{short_name} ), + }; + + } else { + throw Error::Simple('An area with three tiers of council? Impossible! '. join('|',keys %$all_councils)); + } + + return ( \@options, @reported_to_options ? \@reported_to_options : undef ); +} + +1; + diff --git a/perllib/FixMyStreet/Cobrand/UKCouncils.pm b/perllib/FixMyStreet/Cobrand/UKCouncils.pm index 8a6954418..a9ebb1b3f 100644 --- a/perllib/FixMyStreet/Cobrand/UKCouncils.pm +++ b/perllib/FixMyStreet/Cobrand/UKCouncils.pm @@ -1,5 +1,5 @@ package FixMyStreet::Cobrand::UKCouncils; -use base 'FixMyStreet::Cobrand::Default'; +use base 'FixMyStreet::Cobrand::UK'; use strict; use warnings; @@ -13,13 +13,18 @@ sub is_council { sub site_restriction { my $self = shift; - return ( "and council='" . $self->council_id . "'", $self->council_url, { council => sprintf('%d', $self->council_id) } ); + return { council => sprintf('%d', $self->council_id) }; +} +sub site_key { + my $self = shift; + return $self->council_url; } sub restriction { return { cobrand => shift->moniker }; } +# Different function to site_restriction due to two-tier use sub problems_clause { my $self = shift; return { council => sprintf('%d', $self->council_id) }; @@ -41,11 +46,6 @@ sub base_url { return $base_url; } -sub site_title { - my ($self) = @_; - return $self->council_name . ' FixMyStreet'; -} - sub enter_postcode_text { my ($self) = @_; return 'Enter a ' . $self->council_area . ' postcode, or street name and area'; @@ -86,19 +86,4 @@ sub recent_photos { return $self->problems->recent_photos( $num, $lat, $lon, $dist ); } -sub get_council_sender { - my ( $self, $area_id, $area_info ) = @_; - - my $send_method; - - my $council_config = FixMyStreet::App->model("DB::Open311conf")->search( { area_id => $area_id } )->first; - $send_method = $council_config->send_method if $council_config; - - return $send_method if $send_method; - - return 'London' if $area_info->{type} eq 'LBO'; - - return 'Email'; -} - 1; diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index 4f35e7c94..c55ed3403 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -542,7 +542,6 @@ sub meta_line { } - $meta .= $c->cobrand->extra_problem_meta_text($problem); $meta .= '; ' . _('the map was not used so pin location may be inaccurate') unless $problem->used_map; @@ -555,9 +554,8 @@ sub body { if ($problem->external_body) { $body = $problem->external_body; } else { - (my $council = $problem->council) =~ s/\|.*//g; - my @councils = split( /,/, $council ); - my $areas_info = mySociety::MaPit::call('areas', \@councils); + my $councils = $problem->councils; + my $areas_info = mySociety::MaPit::call('areas', $councils); $body = join( _(' and '), map { my $name = $areas_info->{$_}->{name}; @@ -568,7 +566,7 @@ sub body { } else { $name; } - } @councils + } @$councils ); } return $body; diff --git a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm index 26d8f32a9..a0320ccc3 100644 --- a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm +++ b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm @@ -65,7 +65,7 @@ sub email_alerts ($) { # call checks if this is the host that sends mail for this cobrand. next unless $cobrand->email_host; - my ( $sql_restriction, $name_restictions, $hashref_restriction ) = $cobrand->site_restriction( $row->{cobrand_data} ); + my $hashref_restriction = $cobrand->site_restriction( $row->{cobrand_data} ); FixMyStreet::App->model('DB::AlertSent')->create( { alert_id => $row->{alert_id}, @@ -85,7 +85,7 @@ sub email_alerts ($) { $data{state_message} = _("This report is currently marked as open."); } - my $url = $cobrand->base_url_for_emails( $row->{alert_cobrand_data} ); + my $url = $cobrand->base_url( $row->{alert_cobrand_data} ); if ( $hashref_restriction && $hashref_restriction->{council} && $row->{council} ne $hashref_restriction->{council} ) { $url = mySociety::Config::get('BASE_URL'); } @@ -96,9 +96,7 @@ sub email_alerts ($) { $data{data} .= $row->{item_text} . "\n\n------\n\n"; # this is ward and council problems } else { - my $postcode = $cobrand->format_postcode( $row->{postcode} ); - $postcode = ", $postcode" if $postcode; - $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}$postcode\n\n"; + $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n"; if ( exists $row->{geocode} && $row->{geocode} && $ref =~ /ward|council/ ) { my $nearest_st = _get_address_from_gecode( $row->{geocode} ); $data{data} .= $nearest_st if $nearest_st; @@ -141,7 +139,7 @@ sub email_alerts ($) { my $longitude = $alert->parameter; my $latitude = $alert->parameter2; - my ($site_restriction, $site_id, $hashref_restriction) = $cobrand->site_restriction( $alert->cobrand_data ); + my $hashref_restriction = $cobrand->site_restriction( $alert->cobrand_data ); my $d = mySociety::Gaze::get_radius_containing_population($latitude, $longitude, 200000); # Convert integer to GB locale string (with a ".") $d = mySociety::Locale::in_gb_locale { @@ -164,13 +162,11 @@ sub email_alerts ($) { alert_id => $alert->id, parameter => $row->{id}, } ); - my $url = $cobrand->base_url_for_emails( $alert->cobrand_data ); + my $url = $cobrand->base_url( $alert->cobrand_data ); if ( $hashref_restriction && $hashref_restriction->{council} && $row->{council} ne $hashref_restriction->{council} ) { $url = mySociety::Config::get('BASE_URL'); } - my $postcode = $cobrand->format_postcode( $row->{postcode} ); - $postcode = ", $postcode" if $postcode; - $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}$postcode\n\n"; + $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n"; if ( exists $row->{geocode} && $row->{geocode} ) { my $nearest_st = _get_address_from_gecode( $row->{geocode} ); $data{data} .= $nearest_st if $nearest_st; @@ -203,7 +199,7 @@ sub _send_aggregated_alert_email(%) { email => $data{alert_email}, } } ); - $data{unsubscribe_url} = $cobrand->base_url_for_emails( $data{cobrand_data} ) . '/A/' . $token->token; + $data{unsubscribe_url} = $cobrand->base_url( $data{cobrand_data} ) . '/A/' . $token->token; my $template = FixMyStreet->path_to( "templates", "email", $cobrand->moniker, $data{lang}, "$data{template}.txt" diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm index a7738becf..bac367b87 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm @@ -14,13 +14,11 @@ use mySociety::MaPit; use FixMyStreet::App; use FixMyStreet::SendReport; -my $site_restriction; my $site_key; sub set_restriction { - my ( $rs, $sql, $key, $restriction ) = @_; + my ( $rs, $key ) = @_; $site_key = $key; - $site_restriction = $restriction; } # Front page statistics @@ -252,13 +250,13 @@ sub send_reports { } # Template variables for the email - my $email_base_url = $cobrand->base_url_for_emails($row->cobrand_data); + my $email_base_url = $cobrand->base_url_for_report($row); my %h = map { $_ => $row->$_ } qw/id title detail name category latitude longitude used_map/; map { $h{$_} = $row->user->$_ } qw/email phone/; $h{confirmed} = DateTime::Format::Pg->format_datetime( $row->confirmed->truncate (to => 'second' ) ); $h{query} = $row->postcode; - $h{url} = $email_base_url . '/report/' . $row->id; + $h{url} = $email_base_url . $row->url; $h{phone_line} = $h{phone} ? _('Phone:') . " $h{phone}\n\n" : ''; if ($row->photo) { $h{has_photo} = _("This web page also contains a photo of the problem, provided by the user.") . "\n\n"; @@ -289,16 +287,14 @@ sub send_reports { } my %reporters = (); - my (@to, @recips, $template, $areas_info, $sender_count ); + my ( $sender_count ); if ($site eq 'emptyhomes') { my $council = $row->council; - $areas_info = mySociety::MaPit::call('areas', $council); - my $name = $areas_info->{$council}->{name}; + my $areas_info = mySociety::MaPit::call('areas', $council); my $sender = "FixMyStreet::SendReport::EmptyHomes"; $reporters{ $sender } = $sender->new() unless $reporters{$sender}; - $reporters{ $sender }->add_council( $council, $name ); - $template = Utils::read_file("$FindBin::Bin/../templates/email/emptyhomes/" . $row->lang . "/submit.txt"); + $reporters{ $sender }->add_council( $council, $areas_info->{$council} ); } else { @@ -306,7 +302,7 @@ sub send_reports { my @all_councils = split /,|\|/, $row->council; my ($councils, $missing) = $row->council =~ /^([\d,]+)(?:\|([\d,]+))?/; my @councils = split(/,/, $councils); - $areas_info = mySociety::MaPit::call('areas', \@all_councils); + my $areas_info = mySociety::MaPit::call('areas', \@all_councils); my @dear; foreach my $council (@councils) { @@ -326,17 +322,10 @@ sub send_reports { $reporters{ $sender }->skipped; } else { push @dear, $name; - $reporters{ $sender }->add_council( $council, $name ); + $reporters{ $sender }->add_council( $council, $areas_info->{$council} ); } } - $template = 'submit.txt'; - $template = 'submit-brent.txt' if $row->council eq 2488 || $row->council eq 2237; - my $template_path = FixMyStreet->path_to( "templates", "email", $cobrand->moniker, $template )->stringify; - $template_path = FixMyStreet->path_to( "templates", "email", "default", $template )->stringify - unless -e $template_path; - $template = Utils::read_file( $template_path ); - if ($h{category} eq _('Other')) { $h{category_footer} = _('this type of local problem'); $h{category_line} = ''; @@ -374,9 +363,10 @@ sub send_reports { # on a staging server send emails to ourselves rather than the councils my @testing_councils = split( '\|', mySociety::Config::get('TESTING_COUNCILS') ); unless ( grep { $row->council eq $_ } @testing_councils ) { - %reporters = ( - 'FixMyStreet::SendReport::Email' => $reporters{ 'FixMyStreet::SendReport::Email' } || FixMyStreet::SendReport::Email->new() - ); + %reporters = map { $_ => $reporters{$_} } grep { /FixMyStreet::SendReport::(Email|NI)/ } keys %reporters; + unless (%reporters) { + %reporters = ( 'FixMyStreet::SendReport::Email' => FixMyStreet::SendReport::Email->new() ); + } } } @@ -384,9 +374,18 @@ sub send_reports { my $result = -1; for my $sender ( keys %reporters ) { - $result *= $reporters{ $sender }->send( - $row, \%h, \@to, $template, \@recips, $nomail, $areas_info - ); + $result *= $reporters{ $sender }->send( $row, \%h ); + if ( $reporters{ $sender }->unconfirmed_counts) { + foreach my $e (keys %{ $reporters{ $sender }->unconfirmed_counts } ) { + foreach my $c (keys %{ $reporters{ $sender }->unconfirmed_counts->{$e} }) { + $notgot{$e}{$c} += $reporters{ $sender }->unconfirmed_counts->{$e}{$c}; + } + } + %note = ( + %note, + %{ $reporters{ $sender }->unconfirmed_notes } + ); + } } if ($result == mySociety::EmailUtil::EMAIL_SUCCESS) { @@ -409,7 +408,7 @@ sub send_reports { print "Council email addresses that need checking:\n" if keys %notgot; foreach my $e (keys %notgot) { foreach my $c (keys %{$notgot{$e}}) { - print $notgot{$e}{$c} . " problem, to $e category $c (" . $note{$e}{$c}. ")\n"; + print " " . $notgot{$e}{$c} . " problem, to $e category $c (" . $note{$e}{$c}. ")\n"; } } if (keys %sending_skipped_by_method) { diff --git a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm index 753eb2084..bbf0c9a9e 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm @@ -85,7 +85,7 @@ sub send_questionnaires_period { scope => 'questionnaire', data => $questionnaire->id, } ); - $h{url} = $cobrand->base_url_for_emails($row->cobrand_data) . '/Q/' . $token->token; + $h{url} = $cobrand->base_url($row->cobrand_data) . '/Q/' . $token->token; my $sender = $cobrand->contact_email; my $sender_name = _($cobrand->contact_name); diff --git a/perllib/FixMyStreet/Geocode.pm b/perllib/FixMyStreet/Geocode.pm index 6ee17029a..f92e9cc9a 100644 --- a/perllib/FixMyStreet/Geocode.pm +++ b/perllib/FixMyStreet/Geocode.pm @@ -12,13 +12,13 @@ use strict; use URI::Escape; use FixMyStreet::Geocode::Bing; use FixMyStreet::Geocode::Google; +use FixMyStreet::Geocode::OSM; # lookup STRING CONTEXT # Given a user-inputted string, try and convert it into co-ordinates using either # MaPit if it's a postcode, or some web API otherwise. Returns an array of -# data, including an error if there is one (which includes a location being in -# Northern Ireland). The information in the query may be used by cobranded versions -# of the site to diambiguate locations. +# data, including an error if there is one. The information in the query may be +# used by cobranded versions of the site to diambiguate locations. sub lookup { my ($s, $c) = @_; my $data = $c->cobrand->geocode_postcode($s); @@ -38,11 +38,13 @@ sub string { $s =~ s/\s+/ /g; $s = URI::Escape::uri_escape_utf8($s); $s =~ s/%20/+/g; - my $params = $c->cobrand->disambiguate_location(); + my $params = $c->cobrand->disambiguate_location($s); return FixMyStreet::Geocode::Bing::string($s, $c, $params) if FixMyStreet->config('BING_MAPS_API_KEY'); - # Fall back to Google API, which allow acces with and without a key - return FixMyStreet::Geocode::Google::string($s, $c, $params); + # Fall back to Google API, which allow access with and without a key + return FixMyStreet::Geocode::Google::string($s, $c, $params) + if FixMyStreet->config('GOOGLE_MAPS_API_KEY'); + return FixMyStreet::Geocode::OSM::string($s, $c, $params); } 1; diff --git a/perllib/FixMyStreet/Geocode/Bing.pm b/perllib/FixMyStreet/Geocode/Bing.pm index 3bbb9dcdc..18e6b56ce 100644 --- a/perllib/FixMyStreet/Geocode/Bing.pm +++ b/perllib/FixMyStreet/Geocode/Bing.pm @@ -24,7 +24,7 @@ sub string { my ( $s, $c, $params ) = @_; $s .= '+' . $params->{town} if $params->{town} and $s !~ /$params->{town}/i; my $url = "http://dev.virtualearth.net/REST/v1/Locations?q=$s"; - $url .= '&userMapView=' . $params->{bounds}[0] . ',' . $params->{bounds}[1] + $url .= '&userMapView=' . join(',', @{$params->{bounds}}) if $params->{bounds}; $url .= '&userLocation=' . $params->{centre} if $params->{centre}; $url .= '&c=' . $params->{bing_culture} if $params->{bing_culture}; @@ -52,15 +52,11 @@ sub string { } my $results = $js->{resourceSets}->[0]->{resources}; - my ( $error, @valid_locations, $latitude, $longitude, $ni ); + my ( $error, @valid_locations, $latitude, $longitude ); foreach (@$results) { my $address = $_->{name}; - next unless $_->{address}->{countryRegion} eq $params->{bing_country}; - if ($params->{bing_country} eq 'United Kingdom' && $_->{address}{adminDistrict} eq 'Northern Ireland') { - $ni = 1; - next; - } + next if $params->{bing_country} && $_->{address}->{countryRegion} ne $params->{bing_country}; # Getting duplicate, yet different, results from Bing sometimes next if @valid_locations @@ -82,10 +78,6 @@ sub string { push (@valid_locations, $_); } - if ($ni && !scalar @valid_locations) { - return { error => _("We do not currently cover Northern Ireland, I'm afraid.") }; - } - return { latitude => $latitude, longitude => $longitude } if scalar @valid_locations == 1; return { error => $error }; } diff --git a/perllib/FixMyStreet/Geocode/Google.pm b/perllib/FixMyStreet/Geocode/Google.pm index 1ab347066..db3a8ae91 100644 --- a/perllib/FixMyStreet/Geocode/Google.pm +++ b/perllib/FixMyStreet/Geocode/Google.pm @@ -24,10 +24,14 @@ sub string { my ( $s, $c, $params ) = @_; my $url = 'http://maps.google.com/maps/geo?q=' . $s; - $url .= '&ll=' . $params->{centre} if $params->{centre}; - $url .= '&spn=' . $params->{span} if $params->{span}; - $url .= '&gl=' . $params->{country} if $params->{country}; - $url .= '&hl=' . $params->{lang} if $params->{lang}; + $url .= '&ll=' . $params->{centre} if $params->{centre}; + $url .= '&spn=' . $params->{span} if $params->{span}; + if ($params->{google_country}) { + $url .= '&gl=' . $params->{google_country}; + } elsif ($params->{country}) { + $url .= '&gl=' . $params->{country}; + } + $url .= '&hl=' . $params->{lang} if $params->{lang}; my $cache_dir = FixMyStreet->config('GEO_CACHE') . 'google/'; my $cache_file = $cache_dir . md5_hex($url); @@ -58,9 +62,6 @@ sub string { if (!$js) { return { error => _('Sorry, we could not parse that location. Please try again.') }; - } elsif ($js =~ /BT\d/) { - # Northern Ireland, hopefully - return { error => _("We do not currently cover Northern Ireland, I'm afraid.") }; } $js = JSON->new->utf8->allow_nonref->decode($js); diff --git a/perllib/FixMyStreet/Geocode/OSM.pm b/perllib/FixMyStreet/Geocode/OSM.pm index b1becaa7a..ba939b443 100644 --- a/perllib/FixMyStreet/Geocode/OSM.pm +++ b/perllib/FixMyStreet/Geocode/OSM.pm @@ -11,20 +11,79 @@ package FixMyStreet::Geocode::OSM; use warnings; use strict; -use Memcached; -use mySociety::Config; +use Digest::MD5 qw(md5_hex); +use Encode; +use File::Slurp; +use File::Path (); use LWP::Simple; +use Memcached; use XML::Simple; my $osmapibase = "http://www.openstreetmap.org/api/"; my $nominatimbase = "http://nominatim.openstreetmap.org/"; +# string STRING CONTEXT +# Looks up on Nominatim, and caches, a user-inputted location. +# Returns array of (LAT, LON, ERROR), where ERROR is either undef, a string, or +# an array of matches if there are more than one. The information in the query +# may be used to disambiguate the location in cobranded versions of the site. +sub string { + my ( $s, $c, $params ) = @_; + $s .= '+' . $params->{town} if $params->{town} and $s !~ /$params->{town}/i; + my $url = "${nominatimbase}search?"; + my %query_params = ( + q => $s, + format => 'json', + #'accept-language' => '', + email => 'support' . chr(64) . 'fixmystreet.com', + ); + $query_params{viewbox} = $params->{bounds}[1] . ',' . $params->{bounds}[2] . ',' . $params->{bounds}[3] . ',' . $params->{bounds}[0] + if $params->{bounds}; + $query_params{countrycodes} = $params->{country} + if $params->{country}; + $url .= join('&', map { "$_=$query_params{$_}" } keys %query_params); + + my $cache_dir = FixMyStreet->config('GEO_CACHE') . 'osm/'; + my $cache_file = $cache_dir . md5_hex($url); + my $js; + if (-s $cache_file) { + $js = File::Slurp::read_file($cache_file); + } else { + $js = LWP::Simple::get($url); + $js = encode_utf8($js) if utf8::is_utf8($js); + File::Path::mkpath($cache_dir); + File::Slurp::write_file($cache_file, $js) if $js; + } + + if (!$js) { + return { error => _('Sorry, we could not parse that location. Please try again.') }; + } + + $js = JSON->new->utf8->allow_nonref->decode($js); + + my ( $error, @valid_locations, $latitude, $longitude ); + foreach (@$js) { + # These co-ordinates are output as query parameters in a URL, make sure they have a "." + ( $latitude, $longitude ) = ( $_->{lat}, $_->{lon} ); + mySociety::Locale::in_gb_locale { + push (@$error, { + address => $_->{display_name}, + latitude => sprintf('%0.6f', $latitude), + longitude => sprintf('%0.6f', $longitude) + }); + }; + push (@valid_locations, $_); + } + + return { latitude => $latitude, longitude => $longitude } if scalar @valid_locations == 1; + return { error => $error }; +} -sub lookup_location { +sub reverse_geocode { my ($latitude, $longitude, $zoom) = @_; my $url = "${nominatimbase}reverse?format=xml&zoom=$zoom&lat=$latitude&lon=$longitude"; - my $key = "OSM:lookup_location:$url"; + my $key = "OSM:reverse_geocode:$url"; my $result = Memcached::get($key); unless ($result) { my $j = LWP::Simple::get($url); @@ -74,7 +133,7 @@ sub get_object_tags { # http://www.geonames.org/maps/osm-reverse-geocoder.html#findNearbyStreetsOSM sub get_nearest_road_tags { my ( $cobrand, $latitude, $longitude ) = @_; - my $inforef = lookup_location($latitude, $longitude, 16); + my $inforef = reverse_geocode($latitude, $longitude, 16); if (exists $inforef->{result}->{osm_type} && 'way' eq $inforef->{result}->{osm_type}) { my $osmtags = get_object_tags('way', diff --git a/perllib/FixMyStreet/Map.pm b/perllib/FixMyStreet/Map.pm index 08bba3285..d36b91ffe 100644 --- a/perllib/FixMyStreet/Map.pm +++ b/perllib/FixMyStreet/Map.pm @@ -18,7 +18,6 @@ use Module::Pluggable # Get the list of maps we want and load map classes at compile time my @ALL_MAP_CLASSES = allowed_maps(); -use mySociety::Config; use mySociety::Gaze; use mySociety::Locale; use Utils; @@ -31,7 +30,8 @@ are permitted by the config. =cut sub allowed_maps { - my @allowed = split /,/, mySociety::Config::get('MAP_TYPE'); + my @allowed = split /,/, ( FixMyStreet->config('MAP_TYPE') or ""); + push @allowed, 'OSM'; # OSM is always allowed @allowed = map { __PACKAGE__.'::'.$_ } @allowed; my %avail = map { $_ => 1 } __PACKAGE__->maps; return grep { $avail{$_} } @allowed; diff --git a/perllib/FixMyStreet/Map/FMS.pm b/perllib/FixMyStreet/Map/FMS.pm index b1dd29002..e7aa46784 100644 --- a/perllib/FixMyStreet/Map/FMS.pm +++ b/perllib/FixMyStreet/Map/FMS.pm @@ -42,8 +42,10 @@ sub map_tile_base { } sub map_tiles { - my ($self, $x, $y, $z) = @_; - if ($z >= 16) { + my ( $self, %params ) = @_; + my ( $x, $y, $z ) = ( $params{x_tile}, $params{y_tile}, $params{zoom_act} ); + my $ni = in_northern_ireland_box( $params{latitude}, $params{longitude} ); + if (!$ni && $z >= 16) { my ($tile_sep, $tile_base) = $self->map_tile_base; return [ sprintf($tile_base, 'a' . $tile_sep, $z, $x-1, $y-1), @@ -53,7 +55,7 @@ sub map_tiles { ]; } else { my $url = "g=701"; - $url .= "&productSet=mmOS" if $z > 10; + $url .= "&productSet=mmOS" if $z > 10 && !$ni; return [ "//ecn.t0.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y-1, $z) . ".png?$url", "//ecn.t1.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y-1, $z) . ".png?$url", @@ -63,4 +65,10 @@ sub map_tiles { } } +sub in_northern_ireland_box { + my ($lat, $lon) = @_; + return 1 if $lat >= 54.015 && $lat <= 55.315 && $lon >= -8.18 && $lon <= -5.415; + return 0; +} + 1; diff --git a/perllib/FixMyStreet/Map/OSM.pm b/perllib/FixMyStreet/Map/OSM.pm index 119337e37..693f42e4f 100644 --- a/perllib/FixMyStreet/Map/OSM.pm +++ b/perllib/FixMyStreet/Map/OSM.pm @@ -25,7 +25,8 @@ sub map_template { } sub map_tiles { - my ($self, $x, $y, $z) = @_; + my ( $self, %params ) = @_; + my ( $x, $y, $z ) = ( $params{x_tile}, $params{y_tile}, $params{zoom_act} ); my $tile_url = $self->base_tile_url(); return [ "http://a.$tile_url/$z/" . ($x - 1) . "/" . ($y - 1) . ".png", @@ -73,26 +74,23 @@ sub display_map { my $zoom = defined $c->req->params->{zoom} ? $c->req->params->{zoom} + 0 : $default_zoom; $zoom = $numZoomLevels - 1 if $zoom >= $numZoomLevels; $zoom = 0 if $zoom < 0; - my $zoom_act = $zoomOffset + $zoom; - my ($x_tile, $y_tile) = latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $zoom_act); + $params{zoom_act} = $zoomOffset + $zoom; + ($params{x_tile}, $params{y_tile}) = latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $params{zoom_act}); foreach my $pin (@{$params{pins}}) { - ($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $x_tile, $y_tile, $zoom_act); + ($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $params{zoom_act}); } $c->stash->{map} = { %params, type => $self->map_template(), map_type => $self->map_type(), - tiles => $self->map_tiles( $x_tile, $y_tile, $zoom_act ), + tiles => $self->map_tiles( %params ), copyright => $self->copyright(), - x_tile => $x_tile, - y_tile => $y_tile, zoom => $zoom, - zoom_act => $zoom_act, zoomOffset => $zoomOffset, numZoomLevels => $numZoomLevels, - compass => compass( $x_tile, $y_tile, $zoom_act ), + compass => compass( $params{x_tile}, $params{y_tile}, $params{zoom_act} ), }; } diff --git a/perllib/FixMyStreet/Map/OSM/MapQuest.pm b/perllib/FixMyStreet/Map/OSM/MapQuest.pm index 9cf6de01f..4751679f5 100644 --- a/perllib/FixMyStreet/Map/OSM/MapQuest.pm +++ b/perllib/FixMyStreet/Map/OSM/MapQuest.pm @@ -16,7 +16,8 @@ sub map_type { } sub map_tiles { - my ($self, $x, $y, $z) = @_; + my ( $self, %params ) = @_; + my ( $x, $y, $z ) = ( $params{x_tile}, $params{y_tile}, $params{zoom_act} ); my $tile_url = $self->base_tile_url(); return [ "http://otile1.$tile_url/$z/" . ($x - 1) . "/" . ($y - 1) . ".png", diff --git a/perllib/FixMyStreet/SendReport.pm b/perllib/FixMyStreet/SendReport.pm index 915fe4a20..f750ef479 100644 --- a/perllib/FixMyStreet/SendReport.pm +++ b/perllib/FixMyStreet/SendReport.pm @@ -12,6 +12,8 @@ has 'to' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } ); has 'success' => ( is => 'rw', isa => 'Bool', default => 0 ); has 'error' => ( is => 'rw', isa => 'Str', default => '' ); has 'skipped' => ( 'is' => 'rw', isa => 'Str', default => '' ); +has 'unconfirmed_counts' => ( 'is' => 'rw', isa => 'HashRef', default => sub { {} } ); +has 'unconfirmed_notes' => ( 'is' => 'rw', isa => 'HashRef', default => sub { {} } ); sub should_skip { @@ -36,9 +38,9 @@ sub reset { sub add_council { my $self = shift; my $council = shift; - my $name = shift; + my $info = shift; - $self->councils->{ $council } = $name; + $self->councils->{ $council } = $info; } diff --git a/perllib/FixMyStreet/SendReport/Barnet.pm b/perllib/FixMyStreet/SendReport/Barnet.pm index ecbe82872..9a92686ec 100644 --- a/perllib/FixMyStreet/SendReport/Barnet.pm +++ b/perllib/FixMyStreet/SendReport/Barnet.pm @@ -19,15 +19,15 @@ use constant MAX_LINE_LENGTH => 132; sub should_skip { my $self = shift; - my $problem = shift; + my $row = shift; my $council_name = 'Barnet'; my $err_msg = ""; - if ($problem->send_fail_count >= SEND_FAIL_RETRIES_CUTOFF) { + if ($row->send_fail_count >= SEND_FAIL_RETRIES_CUTOFF) { $council_name &&= " to $council_name"; - $err_msg = "skipped: problem id=" . $problem->id . " send$council_name has failed " - . $problem->send_fail_count . " times, cutoff is " . SEND_FAIL_RETRIES_CUTOFF; + $err_msg = "skipped: problem id=" . $row->id . " send$council_name has failed " + . $row->send_fail_count . " times, cutoff is " . SEND_FAIL_RETRIES_CUTOFF; $self->skipped( $err_msg ); @@ -52,7 +52,7 @@ EOF sub send { - my ( $self, $problem, $h, $to, $template, $recips, $nomail ) = @_; + my ( $self, $row, $h ) = @_; my %h = %$h; @@ -127,9 +127,9 @@ sub send { if ($result) { # currently not using this: get_EV_ORDER_GUID (maybe that's the customer number in the CRM) if (my $barnet_id = $result->get_EV_ORDER_NO()) { - $problem->external_id( $barnet_id ); - $problem->external_body( 'Barnet Borough Council' ); # better to use $problem->body()? - $problem->send_method_used('barnet'); + $row->external_id( $barnet_id ); + $row->external_body( 'Barnet Borough Council' ); # better to use $row->body()? + $row->send_method_used('barnet'); $return = 0; } else { my @returned_items = split /<item[^>]*>/, $result->get_ET_RETURN; diff --git a/perllib/FixMyStreet/SendReport/EastHants.pm b/perllib/FixMyStreet/SendReport/EastHants.pm index 681a9d4c4..beab9d55c 100644 --- a/perllib/FixMyStreet/SendReport/EastHants.pm +++ b/perllib/FixMyStreet/SendReport/EastHants.pm @@ -32,7 +32,7 @@ EOF sub send { return if mySociety::Config::get('STAGING_SITE'); - my ( $self, $row, $h, $to, $template, $recips, $nomail ) = @_; + my ( $self, $row, $h ) = @_; # FIXME: should not recreate this each time my $eh_service; diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm index 239bee715..654ed6b3a 100644 --- a/perllib/FixMyStreet/SendReport/Email.pm +++ b/perllib/FixMyStreet/SendReport/Email.pm @@ -7,8 +7,7 @@ BEGIN { extends 'FixMyStreet::SendReport'; } use mySociety::EmailUtil; sub build_recipient_list { - my $self = shift; - my $row = shift; + my ( $self, $row, $h ) = @_; my %recips; my $all_confirmed = 1; @@ -26,14 +25,14 @@ sub build_recipient_list { unless ($confirmed) { $all_confirmed = 0; - #$note = 'Council ' . $row->council . ' deleted' - #unless $note; + $note = 'Council ' . $row->council . ' deleted' + unless $note; $council_email = 'N/A' unless $council_email; - #$notgot{$council_email}{$row->category}++; - #$note{$council_email}{$row->category} = $note; + $self->unconfirmed_counts->{$council_email}{$row->category}++; + $self->unconfirmed_notes->{$council_email}{$row->category} = $note; } - push @{ $self->to }, [ $council_email, $self->councils->{ $council } ]; + push @{ $self->to }, [ $council_email, $self->councils->{ $council }->{name} ]; $recips{$council_email} = 1; } @@ -41,24 +40,38 @@ sub build_recipient_list { return keys %recips; } +sub get_template { + my ( $self, $row ) = @_; + + my $template = 'submit.txt'; + $template = 'submit-brent.txt' if $row->council eq 2488 || $row->council eq 2237; + my $template_path = FixMyStreet->path_to( "templates", "email", $row->cobrand, $template )->stringify; + $template_path = FixMyStreet->path_to( "templates", "email", "default", $template )->stringify + unless -e $template_path; + $template = Utils::read_file( $template_path ); + return $template; +} + sub send { my $self = shift; - my ( $row, $h, $to, $template, $recips, $nomail, $areas_info ) = @_; - - my @recips; + my ( $row, $h ) = @_; - @recips = $self->build_recipient_list( $row, $areas_info ); + my @recips = $self->build_recipient_list( $row, $h ); # on a staging server send emails to ourselves rather than the councils - if (mySociety::Config::get('STAGING_SITE')) { + if (mySociety::Config::get('STAGING_SITE') && !FixMyStreet->test_mode) { @recips = ( mySociety::Config::get('CONTACT_EMAIL') ); } - return unless @recips; + unless ( @recips ) { + $self->error( 'No recipients' ); + return 1; + } + my ($verbose, $nomail) = CronFns::options(); my $result = FixMyStreet::App->send_email_cron( { - _template_ => $template, + _template_ => $self->get_template( $row ), _parameters_ => $h, To => $self->to, From => [ $row->user->email, $row->name ], diff --git a/perllib/FixMyStreet/SendReport/EmptyHomes.pm b/perllib/FixMyStreet/SendReport/EmptyHomes.pm index 9453b4ca5..e1b914523 100644 --- a/perllib/FixMyStreet/SendReport/EmptyHomes.pm +++ b/perllib/FixMyStreet/SendReport/EmptyHomes.pm @@ -6,9 +6,7 @@ use namespace::autoclean; BEGIN { extends 'FixMyStreet::SendReport::Email'; } sub build_recipient_list { - my $self = shift; - my $row = shift; - my $areas_info = shift; + my ( $self, $row, $h ) = @_; my %recips; my $all_confirmed = 1; @@ -21,9 +19,6 @@ sub build_recipient_list { my ($council_email, $confirmed, $note) = ( $contact->email, $contact->confirmed, $contact->note ); - $council_email = essex_contact($row->latitude, $row->longitude) if $council == 2225; - $council_email = oxfordshire_contact($row->latitude, $row->longitude) if $council == 2237 && $council_email eq 'SPECIAL'; - unless ($confirmed) { $all_confirmed = 0; #$note = 'Council ' . $row->council . ' deleted' @@ -33,10 +28,10 @@ sub build_recipient_list { #$note{$council_email}{$row->category} = $note; } - push @{ $self->to }, [ $council_email, $self->councils->{ $council } ]; + push @{ $self->to }, [ $council_email, $self->councils->{ $council }->{name} ]; $recips{$council_email} = 1; - my $country = $areas_info->{$council}->{country}; + my $country = $self->councils->{$council}->{country}; if ($country eq 'W') { $recips{ 'shelter@' . mySociety::Config::get('EMAIL_DOMAIN') } = 1; } else { @@ -48,4 +43,9 @@ sub build_recipient_list { return keys %recips; } +sub get_template { + my ( $self, $row ) = @_; + return Utils::read_file( FixMyStreet->path_to( "templates", "email", "emptyhomes", $row->lang, "submit.txt" )->stringify ); +} + 1; diff --git a/perllib/FixMyStreet/SendReport/London.pm b/perllib/FixMyStreet/SendReport/London.pm index 58ecb2375..6e7951922 100644 --- a/perllib/FixMyStreet/SendReport/London.pm +++ b/perllib/FixMyStreet/SendReport/London.pm @@ -33,7 +33,7 @@ EOF sub send { return if mySociety::Config::get('STAGING_SITE'); - my ( $self, $row, $h, $to, $template, $recips, $nomail ) = @_; + my ( $self, $row, $h ) = @_; $h->{message} = construct_message( %$h ); my $phone = $h->{phone}; diff --git a/perllib/FixMyStreet/SendReport/NI.pm b/perllib/FixMyStreet/SendReport/NI.pm new file mode 100644 index 000000000..0783a385b --- /dev/null +++ b/perllib/FixMyStreet/SendReport/NI.pm @@ -0,0 +1,40 @@ +package FixMyStreet::SendReport::NI; + +use Moose; + +BEGIN { extends 'FixMyStreet::SendReport::Email'; } + +sub build_recipient_list { + my ( $self, $row, $h ) = @_; + my %recips; + + my $all_confirmed = 1; + foreach my $council ( keys %{ $self->councils } ) { + my $contact = FixMyStreet::App->model("DB::Contact")->find( { + deleted => 0, + area_id => $council, + category => $row->category + } ); + + my ($email, $confirmed, $note) = ( $contact->email, $contact->confirmed, $contact->note ); + + unless ($confirmed) { + $all_confirmed = 0; + $email = 'N/A' unless $email; + } + + my $name = $self->councils->{$council}->{name}; + if ( $email =~ /^roads.([^@]*)\@drdni/ ) { + $name = "Roads Service (\u$1)"; + $h->{councils_name} = $name; + $row->external_body( 'Roads Service' ); + } + push @{ $self->to }, [ $email, $name ]; + $recips{$email} = 1; + } + + return () unless $all_confirmed; + return keys %recips; +} + +1; diff --git a/perllib/FixMyStreet/SendReport/Open311.pm b/perllib/FixMyStreet/SendReport/Open311.pm index b4380df02..56473cf5f 100644 --- a/perllib/FixMyStreet/SendReport/Open311.pm +++ b/perllib/FixMyStreet/SendReport/Open311.pm @@ -23,7 +23,7 @@ sub should_skip { sub send { my $self = shift; - my ( $row, $h, $to, $template, $recips, $nomail ) = @_; + my ( $row, $h ) = @_; my $result = -1; @@ -32,6 +32,7 @@ sub send { my $always_send_latlong = 1; my $send_notpinpointed = 0; + my $use_service_as_deviceid = 0; my $basic_desc = 0; @@ -54,6 +55,15 @@ sub send { $always_send_latlong = 0; $send_notpinpointed = 1; + $use_service_as_deviceid = 0; + + # make sure we have last_name attribute present in row's extra, so + # it is passed correctly to Bromley as attribute[] + if ( $row->cobrand ne 'bromley' ) { + my ( $firstname, $lastname ) = ( $row->user->name =~ /(\w+)\.?\s+(.+)/ ); + push @$extra, { name => 'last_name', value => $lastname }; + } + $basic_desc = 1; } @@ -65,12 +75,13 @@ sub send { } ); my $open311 = Open311->new( - jurisdiction => $conf->jurisdiction, - endpoint => $conf->endpoint, - api_key => $conf->api_key, - always_send_latlong => $always_send_latlong, - send_notpinpointed => $send_notpinpointed, - basic_description => $basic_desc, + jurisdiction => $conf->jurisdiction, + endpoint => $conf->endpoint, + api_key => $conf->api_key, + always_send_latlong => $always_send_latlong, + send_notpinpointed => $send_notpinpointed, + use_service_as_deviceid => $use_service_as_deviceid, + basic_description => $basic_desc, ); # non standard west berks end points diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm index dc42c1aba..2a49cc2f8 100644 --- a/perllib/FixMyStreet/TestMech.pm +++ b/perllib/FixMyStreet/TestMech.pm @@ -211,26 +211,6 @@ sub get_email { return $emails[0]; } -=head2 form_errors - - my $arrayref = $mech->form_errors; - -Find all the form errors on the current page and return them in page order as an -arrayref of TEXTs. If none found return empty arrayref. - -=cut - -sub form_errors { - my $mech = shift; - my $result = scraper { - process 'div.form-error', 'errors[]', 'TEXT'; - process 'p.form-error', 'errors[]', 'TEXT'; - process 'p.error', 'errors[]', 'TEXT'; - } - ->scrape( $mech->response ); - return $result->{errors} || []; -} - =head2 page_errors my $arrayref = $mech->page_errors; @@ -243,8 +223,7 @@ arrayref of TEXTs. If none found return empty arrayref. sub page_errors { my $mech = shift; my $result = scraper { - process 'p.error', 'errors[]', 'TEXT'; - process 'ul.error li', 'errors[]', 'TEXT'; + process 'div.form-error, p.form-error, p.error, ul.error li', 'errors[]', 'TEXT'; } ->scrape( $mech->response ); return $result->{errors} || []; @@ -327,6 +306,7 @@ sub extract_problem_meta { my $result = scraper { process 'div#side p em', 'meta', 'TEXT'; + process '.problem-header p em', 'meta', 'TEXT'; } ->scrape( $mech->response ); @@ -348,6 +328,7 @@ sub extract_problem_title { my $result = scraper { process 'div#side h1', 'title', 'TEXT'; + process '.problem-header h1', 'title', 'TEXT'; } ->scrape( $mech->response ); @@ -388,6 +369,7 @@ sub extract_update_metas { my $result = scraper { process 'div#updates div.problem-update p em', 'meta[]', 'TEXT'; + process '.update-text .meta-2', 'meta[]', 'TEXT'; } ->scrape( $mech->response ); |