diff options
Diffstat (limited to 'perllib/FixMyStreet/DB/Result')
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Body.pm | 34 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Comment.pm | 113 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Contact.pm | 36 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/ContactsHistory.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 201 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/ReportExtraFields.pm | 45 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/ResponsePriority.pm | 6 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/State.pm | 48 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Translation.pm | 44 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 43 |
10 files changed, 364 insertions, 216 deletions
diff --git a/perllib/FixMyStreet/DB/Result/Body.pm b/perllib/FixMyStreet/DB/Result/Body.pm index 82015ad2d..6481d5cfc 100644 --- a/perllib/FixMyStreet/DB/Result/Body.pm +++ b/perllib/FixMyStreet/DB/Result/Body.pm @@ -121,18 +121,52 @@ __PACKAGE__->has_many( # Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-02-13 15:11:11 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BOJANVwg3kR/1VjDq0LykA +use Moo; +use namespace::clean; + +with 'FixMyStreet::Roles::Translatable'; + sub url { my ( $self, $c, $args ) = @_; # XXX $areas_info was used here for Norway parent - needs body parents, I guess return $c->uri_for( '/reports/' . $c->cobrand->short_name( $self ), $args || {} ); } +__PACKAGE__->might_have( + "translations", + "FixMyStreet::DB::Result::Translation", + sub { + my $args = shift; + return { + "$args->{foreign_alias}.object_id" => { -ident => "$args->{self_alias}.id" }, + "$args->{foreign_alias}.tbl" => { '=' => \"?" }, + "$args->{foreign_alias}.col" => { '=' => \"?" }, + "$args->{foreign_alias}.lang" => { '=' => \"?" }, + }; + }, + { cascade_copy => 0, cascade_delete => 0 }, +); + +around name => \&translate_around; + sub areas { my $self = shift; my %ids = map { $_->area_id => 1 } $self->body_areas->all; return \%ids; } +sub first_area_children { + my ( $self, $c ) = @_; + + my $area_id = $self->body_areas->first->area_id; + + my $children = mySociety::MaPit::call('area/children', $area_id, + type => $c->cobrand->area_types_children, + ); + + return $children; +} + =head2 get_cobrand_handler Get a cobrand object for this body, if there is one. diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm index cf1ba444d..562f29693 100644 --- a/perllib/FixMyStreet/DB/Result/Comment.pm +++ b/perllib/FixMyStreet/DB/Result/Comment.pm @@ -101,6 +101,7 @@ use Moo; use namespace::clean -except => [ 'meta' ]; with 'FixMyStreet::Roles::Abuser', + 'FixMyStreet::Roles::Extra', 'FixMyStreet::Roles::PhotoSet'; my $stz = sub { @@ -128,9 +129,10 @@ sub check_for_errors { unless $self->text =~ m/\S/; # Bromley Council custom character limit - if ( $self->text && $self->problem && $self->problem->bodies_str - && $self->problem->bodies_str eq '2482' && length($self->text) > 1750 ) { - $errors{update} = sprintf( _('Updates are limited to %s characters in length. Please shorten your update'), 1750 ); + if ( $self->text && $self->problem && $self->problem->bodies_str) { + if ($self->problem->to_body_named('Bromley') && length($self->text) > 1750) { + $errors{update} = sprintf( _('Updates are limited to %s characters in length. Please shorten your update'), 1750 ); + } } return \%errors; @@ -149,6 +151,11 @@ sub confirm { $self->confirmed( \'current_timestamp' ); } +sub url { + my $self = shift; + return "/report/" . $self->problem_id . '#update_' . $self->id; +} + sub photos { my $self = shift; my $photoset = $self->get_photoset; @@ -169,22 +176,6 @@ sub photos { return \@photos; } -=head2 problem_state_display - -Returns a string suitable for display lookup in the update meta section. -Removes the '- council/user' bit from fixed states. - -=cut - -sub problem_state_display { - my $self = shift; - - my $state = $self->problem_state; - $state =~ s/ -.*$//; - - return $state; -} - =head2 latest_moderation_log_entry Return most recent ModerationLog object @@ -236,8 +227,6 @@ sub meta_line { my $meta = ''; - $c->stash->{last_state} ||= ''; - if ($self->anonymous or !$self->name) { $meta = sprintf( _( 'Posted anonymously at %s' ), Utils::prettify_dt( $self->confirmed ) ) } elsif ($self->user->from_body) { @@ -248,68 +237,54 @@ sub meta_line { } elsif ($body eq 'Royal Borough of Greenwich') { $body = "$body <img src='/cobrands/greenwich/favicon.png' alt=''>"; } - if ($c->user_exists and $c->user->has_permission_to('view_body_contribute_details', $self->problem->bodies_str_ids)) { - $meta = sprintf( _( 'Posted by <strong>%s</strong> (%s) at %s' ), $body, $user_name, Utils::prettify_dt( $self->confirmed ) ); + my $can_view_contribute = $c->user_exists && $c->user->has_permission_to('view_body_contribute_details', $self->problem->bodies_str_ids); + if ($self->text) { + if ($can_view_contribute) { + $meta = sprintf( _( 'Posted by <strong>%s</strong> (%s) at %s' ), $body, $user_name, Utils::prettify_dt( $self->confirmed ) ); + } else { + $meta = sprintf( _( 'Posted by <strong>%s</strong> at %s' ), $body, Utils::prettify_dt( $self->confirmed ) ); + } } else { - $meta = sprintf( _( 'Posted by <strong>%s</strong> at %s' ), $body, Utils::prettify_dt( $self->confirmed ) ); + if ($can_view_contribute) { + $meta = sprintf( _( 'Updated by <strong>%s</strong> (%s) at %s' ), $body, $user_name, Utils::prettify_dt( $self->confirmed ) ); + } else { + $meta = sprintf( _( 'Updated by <strong>%s</strong> at %s' ), $body, Utils::prettify_dt( $self->confirmed ) ); + } } } else { $meta = sprintf( _( 'Posted by %s at %s' ), FixMyStreet::Template::html_filter($self->name), Utils::prettify_dt( $self->confirmed ) ) } + if ($self->get_extra_metadata('defect_raised')) { + $meta .= ', ' . _( 'and a defect raised' ); + } + + return $meta; +}; + +sub problem_state_display { + my ( $self, $c ) = @_; + my $update_state = ''; + my $cobrand = $c->cobrand->moniker; if ($self->mark_fixed) { - $update_state = _( 'marked as fixed' ); + return FixMyStreet::DB->resultset("State")->display('fixed', 1); } elsif ($self->mark_open) { - $update_state = _( 'reopened' ); + return FixMyStreet::DB->resultset("State")->display('confirmed', 1); } elsif ($self->problem_state) { - my $state = $self->problem_state_display; - - if ($state eq 'confirmed') { - if ($c->stash->{last_state}) { - $update_state = _( 'reopened' ) - } - } elsif ($state eq 'investigating') { - $update_state = _( 'marked as investigating' ) - } elsif ($state eq 'planned') { - $update_state = _( 'marked as planned' ) - } elsif ($state eq 'in progress') { - $update_state = _( 'marked as in progress' ) - } elsif ($state eq 'action scheduled') { - $update_state = _( 'marked as action scheduled' ) - } elsif ($state eq 'closed') { - $update_state = _( 'marked as closed' ) - } elsif ($state eq 'fixed') { - $update_state = _( 'marked as fixed' ) - } elsif ($state eq 'unable to fix') { - $update_state = _( 'marked as no further action' ) - } elsif ($state eq 'not responsible') { - $update_state = _( "marked as not the council's responsibility" ) - } elsif ($state eq 'duplicate') { - $update_state = _( 'closed as a duplicate report' ) - } elsif ($state eq 'internal referral') { - $update_state = _( 'marked as an internal referral' ) - } - - if ($c->cobrand->moniker eq 'bromley' || ( - $self->problem->bodies_str && - $self->problem->bodies_str eq '2482' - )) { - if ($state eq 'not responsible') { - $update_state = 'marked as third party responsibility' + my $state = $self->problem_state; + if ($state eq 'not responsible') { + $update_state = _( "not the council's responsibility" ); + if ($cobrand eq 'bromley' || $self->problem->to_body_named('Bromley')) { + $update_state = 'third party responsibility'; } + } else { + $update_state = FixMyStreet::DB->resultset("State")->display($state, 1); } - - } - - if ($update_state ne $c->stash->{last_state} and $update_state) { - $meta .= ", $update_state"; } - $c->stash->{last_state} = $update_state; - - return $meta; -}; + return $update_state; +} 1; diff --git a/perllib/FixMyStreet/DB/Result/Contact.pm b/perllib/FixMyStreet/DB/Result/Contact.pm index a620b7358..f9cbf1c44 100644 --- a/perllib/FixMyStreet/DB/Result/Contact.pm +++ b/perllib/FixMyStreet/DB/Result/Contact.pm @@ -11,8 +11,17 @@ use base 'DBIx::Class::Core'; __PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); __PACKAGE__->table("contacts"); __PACKAGE__->add_columns( + "id", + { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + sequence => "contacts_id_seq", + }, "body_id", { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, + "category", + { data_type => "text", default_value => "Other", is_nullable => 0 }, "email", { data_type => "text", is_nullable => 0 }, "editor", @@ -21,19 +30,6 @@ __PACKAGE__->add_columns( { data_type => "timestamp", is_nullable => 0 }, "note", { data_type => "text", is_nullable => 0 }, - "confirmed", - { data_type => "boolean", is_nullable => 0 }, - "category", - { data_type => "text", default_value => "Other", is_nullable => 0 }, - "deleted", - { data_type => "boolean", is_nullable => 0 }, - "id", - { - data_type => "integer", - is_auto_increment => 1, - is_nullable => 0, - sequence => "contacts_id_seq", - }, "extra", { data_type => "text", is_nullable => 1 }, "non_public", @@ -46,6 +42,8 @@ __PACKAGE__->add_columns( { data_type => "text", default_value => "", is_nullable => 1 }, "send_method", { data_type => "text", is_nullable => 1 }, + "state", + { data_type => "text", is_nullable => 0 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("contacts_body_id_category_idx", ["body_id", "category"]); @@ -75,8 +73,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-02-13 15:11:11 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:f9VepR/oPyr3z6PUpJ4w2A +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-08 20:45:04 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:t/VtPP11R8bbqPZdEVXffw __PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn"); __PACKAGE__->rabx_column('extra'); @@ -84,12 +82,18 @@ __PACKAGE__->rabx_column('extra'); use Moo; use namespace::clean -except => [ 'meta' ]; -with 'FixMyStreet::Roles::Extra'; +with 'FixMyStreet::Roles::Extra', + 'FixMyStreet::Roles::Translatable'; __PACKAGE__->many_to_many( response_templates => 'contact_response_templates', 'response_template' ); __PACKAGE__->many_to_many( response_priorities => 'contact_response_priorities', 'response_priority' ); __PACKAGE__->many_to_many( defect_types => 'contact_defect_types', 'defect_type' ); +sub category_display { + my $self = shift; + $self->translate_column('category'); +} + sub get_metadata_for_input { my $self = shift; my $id_field = $self->id_field; diff --git a/perllib/FixMyStreet/DB/Result/ContactsHistory.pm b/perllib/FixMyStreet/DB/Result/ContactsHistory.pm index 7126d91c9..c90bb9d66 100644 --- a/perllib/FixMyStreet/DB/Result/ContactsHistory.pm +++ b/perllib/FixMyStreet/DB/Result/ContactsHistory.pm @@ -26,22 +26,20 @@ __PACKAGE__->add_columns( { data_type => "text", default_value => "Other", is_nullable => 0 }, "email", { data_type => "text", is_nullable => 0 }, - "confirmed", - { data_type => "boolean", is_nullable => 0 }, - "deleted", - { data_type => "boolean", is_nullable => 0 }, "editor", { data_type => "text", is_nullable => 0 }, "whenedited", { data_type => "timestamp", is_nullable => 0 }, "note", { data_type => "text", is_nullable => 0 }, + "state", + { data_type => "text", is_nullable => 0 }, ); __PACKAGE__->set_primary_key("contacts_history_id"); -# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-12-12 16:37:16 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:sxflEBBn0Mn0s3MroWnWFA +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-08 20:45:04 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HTt0g29yXTM/WyHKN179FA # You can replace this text with custom code or comments, and it will be preserved on regeneration diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index 84db41490..3b622b561 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -206,6 +206,7 @@ my $IM = eval { with 'FixMyStreet::Roles::Abuser', 'FixMyStreet::Roles::Extra', + 'FixMyStreet::Roles::Translatable', 'FixMyStreet::Roles::PhotoSet'; =head2 @@ -219,15 +220,8 @@ HASHREF. =cut sub open_states { - my $states = { - 'confirmed' => 1, - 'investigating' => 1, - 'in progress' => 1, - 'planned' => 1, - 'action scheduled' => 1, - }; - - return wantarray ? keys %{$states} : $states; + my @states = map { $_->label } @{FixMyStreet::DB->resultset("State")->open}; + return wantarray ? @states : { map { $_ => 1 } @states }; } =head2 @@ -241,13 +235,9 @@ HASHREF. =cut sub fixed_states { - my $states = { - 'fixed' => 1, - 'fixed - user' => 1, - 'fixed - council' => 1, - }; - - return wantarray ? keys %{ $states } : $states; + my @states = map { $_->label } @{FixMyStreet::DB->resultset("State")->fixed}; + push @states, 'fixed - user', 'fixed - council' if @states; + return wantarray ? @states : { map { $_ => 1 } @states }; } =head2 @@ -261,18 +251,10 @@ HASHREF. =cut sub closed_states { - my $states = { - 'closed' => 1, - 'unable to fix' => 1, - 'not responsible' => 1, - 'duplicate' => 1, - 'internal referral' => 1, - }; - - return wantarray ? keys %{$states} : $states; + my @states = map { $_->label } @{FixMyStreet::DB->resultset("State")->closed}; + return wantarray ? @states : { map { $_ => 1 } @states }; } - =head2 @states = FixMyStreet::DB::Problem::all_states(); @@ -288,21 +270,10 @@ sub all_states { 'hidden' => 1, 'partial' => 1, 'unconfirmed' => 1, - 'confirmed' => 1, - 'investigating' => 1, - 'in progress' => 1, - 'planned' => 1, - 'action scheduled' => 1, - 'fixed' => 1, 'fixed - council' => 1, 'fixed - user' => 1, - 'unable to fix' => 1, - 'not responsible' => 1, - 'duplicate' => 1, - 'closed' => 1, - 'internal referral' => 1, }; - + map { $states->{$_->label} = 1 } @{FixMyStreet::DB->resultset("State")->states}; return wantarray ? keys %{$states} : $states; } @@ -322,75 +293,31 @@ my $hidden_states = { 'unconfirmed' => 1, }; -my $visible_states = { - map { - $hidden_states->{$_} ? () : ($_ => 1) - } all_states() -}; - ## e.g.: - # 'confirmed' => 1, - # 'investigating' => 1, - # 'in progress' => 1, - # 'planned' => 1, - # 'action scheduled' => 1, - # 'fixed' => 1, - # 'fixed - council' => 1, - # 'fixed - user' => 1, - # 'unable to fix' => 1, - # 'not responsible' => 1, - # 'duplicate' => 1, - # 'closed' => 1, - # 'internal referral' => 1, - sub hidden_states { return wantarray ? keys %{$hidden_states} : $hidden_states; } sub visible_states { - return wantarray ? keys %{$visible_states} : $visible_states; + my %visible_states = map { + $hidden_states->{$_} ? () : ($_ => 1) + } all_states(); + return wantarray ? keys %visible_states : \%visible_states; } sub visible_states_add { my ($self, @states) = @_; for my $state (@states) { delete $hidden_states->{$state}; - $visible_states->{$state} = 1; } } sub visible_states_remove { my ($self, @states) = @_; for my $state (@states) { - delete $visible_states->{$state}; $hidden_states->{$state} = 1; } } -=head2 - - @states = FixMyStreet::DB::Problem::council_states(); - -Get a list of states that are availble to council users. If called in -array context then returns an array of names, otherwise returns a -HASHREF. - -=cut -sub council_states { - my $states = { - 'confirmed' => 1, - 'investigating' => 1, - 'action scheduled' => 1, - 'in progress' => 1, - 'fixed - council' => 1, - 'unable to fix' => 1, - 'not responsible' => 1, - 'duplicate' => 1, - 'internal referral' => 1, - }; - - return wantarray ? keys %{$states} : $states; -} - my $stz = sub { my ( $orig, $self ) = ( shift, shift ); my $s = $self->$orig(@_); @@ -456,12 +383,6 @@ sub check_for_errors { $errors{category} = _('Please choose a category'); $self->category(undef); } - elsif ($self->category - && $self->category eq _('-- Pick a property type --') ) - { - $errors{category} = _('Please choose a property type'); - $self->category(undef); - } return \%errors; } @@ -489,6 +410,11 @@ sub confirm { return 1; } +sub category_display { + my $self = shift; + $self->translate_column('category'); +} + sub bodies_str_ids { my $self = shift; return [] unless $self->bodies_str; @@ -502,12 +428,36 @@ Returns a hashref of bodies to which a report was sent. =cut -sub bodies($) { +has bodies => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + return {} unless $self->bodies_str; + my $cache = $self->result_source->schema->cache; + return $cache->{bodies}{$self->bodies_str} if $cache->{bodies}{$self->bodies_str}; + + my $bodies = $self->bodies_str_ids; + my @bodies = $self->result_source->schema->resultset('Body')->search( + { id => $bodies }, + { prefetch => 'body_areas' }, + )->all; + $cache->{bodies}{$self->bodies_str} = { map { $_->id => $_ } @bodies }; + return $cache->{bodies}{$self->bodies_str}; + }, +); + +sub body_names($) { my $self = shift; - return {} unless $self->bodies_str; - my $bodies = $self->bodies_str_ids; - my @bodies = $self->result_source->schema->resultset('Body')->search({ id => $bodies })->all; - return { map { $_->id => $_ } @bodies }; + my $bodies = $self->bodies; + my @names = map { $_->name } values %$bodies; + return \@names; +} + +sub to_body_named($$) { + my ($self, $re) = @_; + my $names = join(',,', @{$self->body_names}); + $names =~ /$re/; } =head2 url @@ -609,19 +559,6 @@ sub is_visible { return exists $self->visible_states->{ $self->state } ? 1 : 0; } -=head2 state_display - -Returns a string suitable for display lookup in the update meta section. -Removes the '- council/user' bit from fixed states. - -=cut - -sub state_display { - my $self = shift; - (my $state = $self->state) =~ s/ -.*$//; - return $state; -} - =head2 meta_line Returns a string to be used on a problem report page, describing some of the @@ -635,7 +572,7 @@ sub meta_line { my $date_time = Utils::prettify_dt( $problem->confirmed ); my $meta = ''; - my $category = $problem->category; + my $category = $problem->category_display; $category = $c->cobrand->call_hook(change_category_text => $category) || $category; if ( $problem->anonymous ) { @@ -787,7 +724,7 @@ sub defect_types { # Note: this only makes sense when called on a problem that has been sent! sub can_display_external_id { my $self = shift; - if ($self->external_id && $self->send_method_used && $self->bodies_str =~ /(2237|2550)/) { + if ($self->external_id && $self->send_method_used && $self->to_body_named('Oxfordshire|Angus')) { return 1; } return 0; @@ -924,6 +861,7 @@ sub as_hashref { latitude => $self->latitude, longitude => $self->longitude, postcode => $self->postcode, + areas => $self->areas, state => $self->state, state_t => _( $self->state ), used_map => $self->used_map, @@ -953,15 +891,21 @@ sub photos { my $id = $self->id; my @photos = map { my $cachebust = substr($_, 0, 8); + # Some Varnish configurations (e.g. on mySociety infra) strip cookies from + # images, which means image requests will be redirected to the login page + # if LOGIN_REQUIRED is set. To stop this happening, Varnish should be + # configured to not strip cookies if the cookie_passthrough param is + # present, which this line ensures will be if LOGIN_REQUIRED is set. + my $extra = (FixMyStreet->config('LOGIN_REQUIRED')) ? "&cookie_passthrough=1" : ""; my ($hash, $format) = split /\./, $_; { id => $hash, - url_temp => "/photo/temp.$hash.$format", - url_temp_full => "/photo/fulltemp.$hash.$format", - url => "/photo/$id.$i.$format?$cachebust", - url_full => "/photo/$id.$i.full.$format?$cachebust", - url_tn => "/photo/$id.$i.tn.$format?$cachebust", - url_fp => "/photo/$id.$i.fp.$format?$cachebust", + url_temp => "/photo/temp.$hash.$format$extra", + url_temp_full => "/photo/fulltemp.$hash.$format$extra", + url => "/photo/$id.$i.$format?$cachebust$extra", + url_full => "/photo/$id.$i.full.$format?$cachebust$extra", + url_tn => "/photo/$id.$i.tn.$format?$cachebust$extra", + url_fp => "/photo/$id.$i.fp.$format?$cachebust$extra", idx => $i++, } } $photoset->all_ids; @@ -1013,13 +957,14 @@ has get_cobrand_logged => ( sub pin_data { my ($self, $c, $page, %opts) = @_; my $colour = $c->cobrand->pin_colour($self, $page); - + my $title = $opts{private} ? $self->title : $self->title_safe; + $title = $c->cobrand->call_hook(pin_hover_title => $self, $title) || $title; { latitude => $self->latitude, longitude => $self->longitude, colour => $colour, id => $self->id, - title => $opts{private} ? $self->title : $self->title_safe, + title => $title, problem => $self, type => $opts{type}, } @@ -1082,6 +1027,7 @@ sub static_map { if ($pin) { my $im = Image::Magick->new; $im->read(FixMyStreet->path_to('web', 'i', 'pin-yellow.png')); + $im->Scale( geometry => '48x64' ); $image->Composite(image => $im, gravity => 'NorthWest', x => $pin->{px} - 24, y => $pin->{py} - 64); } @@ -1113,6 +1059,16 @@ has shortlisted_user => ( }, ); +sub set_duplicate_of { + my ($self, $other_id) = @_; + $self->set_extra_metadata( duplicate_of => $other_id ); + my $dupe = $self->result_source->schema->resultset("Problem")->find($other_id); + my $dupes_duplicates = $dupe->get_extra_metadata('duplicates') || []; + push @$dupes_duplicates, $self->id; + $dupe->set_extra_metadata( duplicates => $dupes_duplicates ); + $dupe->update; +} + has duplicate_of => ( is => 'ro', lazy => 1, @@ -1130,8 +1086,9 @@ has duplicates => ( lazy => 1, default => sub { my $self = shift; - my $rabx_id = RABX::serialise( $self->id ); - my @duplicates = $self->result_source->schema->resultset('Problem')->search({ extra => { like => "\%duplicate_of,$rabx_id%" } })->all; + my $duplicates = $self->get_extra_metadata("duplicates") || []; + return [] unless $duplicates && @$duplicates; + my @duplicates = $self->result_source->schema->resultset('Problem')->search({ id => $duplicates })->all; return \@duplicates; }, ); diff --git a/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm b/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm new file mode 100644 index 000000000..27a6bd2c6 --- /dev/null +++ b/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm @@ -0,0 +1,45 @@ +use utf8; +package FixMyStreet::DB::Result::ReportExtraFields; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; +__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); +__PACKAGE__->table("report_extra_fields"); +__PACKAGE__->add_columns( + "id", + { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + sequence => "report_extra_fields_id_seq", + }, + "name", + { data_type => "text", is_nullable => 0 }, + "cobrand", + { data_type => "text", is_nullable => 1 }, + "language", + { data_type => "text", is_nullable => 1 }, + "extra", + { data_type => "text", is_nullable => 1 }, +); +__PACKAGE__->set_primary_key("id"); + + +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-28 09:51:34 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LkfbsUInnEyXowdcCEPjUQ + +__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn"); +__PACKAGE__->rabx_column('extra'); + +use Moo; +use namespace::clean -except => [ 'meta' ]; + +with 'FixMyStreet::Roles::Extra'; + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/perllib/FixMyStreet/DB/Result/ResponsePriority.pm b/perllib/FixMyStreet/DB/Result/ResponsePriority.pm index 44635d174..df54cfa08 100644 --- a/perllib/FixMyStreet/DB/Result/ResponsePriority.pm +++ b/perllib/FixMyStreet/DB/Result/ResponsePriority.pm @@ -28,6 +28,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "external_id", { data_type => "text", is_nullable => 1 }, + "is_default", + { data_type => "boolean", default_value => \"false", is_nullable => 0 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("response_priorities_body_id_name_key", ["body_id", "name"]); @@ -51,8 +53,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07035 @ 2016-12-14 17:12:09 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:glsO0fLK6fNvg4TmW1DMPg +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-09-12 09:32:53 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JBIHFnaLvXCAUjgwTSB3CQ __PACKAGE__->many_to_many( contacts => 'contact_response_priorities', 'contact' ); diff --git a/perllib/FixMyStreet/DB/Result/State.pm b/perllib/FixMyStreet/DB/Result/State.pm new file mode 100644 index 000000000..b8a35d42b --- /dev/null +++ b/perllib/FixMyStreet/DB/Result/State.pm @@ -0,0 +1,48 @@ +use utf8; +package FixMyStreet::DB::Result::State; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; +__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); +__PACKAGE__->table("state"); +__PACKAGE__->add_columns( + "id", + { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + sequence => "state_id_seq", + }, + "label", + { data_type => "text", is_nullable => 0 }, + "type", + { data_type => "text", is_nullable => 0 }, + "name", + { data_type => "text", is_nullable => 0 }, +); +__PACKAGE__->set_primary_key("id"); +__PACKAGE__->add_unique_constraint("state_label_key", ["label"]); +__PACKAGE__->add_unique_constraint("state_name_key", ["name"]); + + +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-08-22 15:17:43 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dvtAOpeYqEF9T3otHHgLqw + +use Moo; +use namespace::clean; + +with 'FixMyStreet::Roles::Translatable'; + +sub msgstr { + my $self = shift; + my $lang = $self->result_source->schema->lang; + return $self->name unless $lang && $self->translated->{name}{$lang}; + return $self->translated->{name}{$lang}{msgstr}; +} + +1; diff --git a/perllib/FixMyStreet/DB/Result/Translation.pm b/perllib/FixMyStreet/DB/Result/Translation.pm new file mode 100644 index 000000000..fafc7ccf1 --- /dev/null +++ b/perllib/FixMyStreet/DB/Result/Translation.pm @@ -0,0 +1,44 @@ +use utf8; +package FixMyStreet::DB::Result::Translation; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; +__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); +__PACKAGE__->table("translation"); +__PACKAGE__->add_columns( + "id", + { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + sequence => "translation_id_seq", + }, + "tbl", + { data_type => "text", is_nullable => 0 }, + "object_id", + { data_type => "integer", is_nullable => 0 }, + "col", + { data_type => "text", is_nullable => 0 }, + "lang", + { data_type => "text", is_nullable => 0 }, + "msgstr", + { data_type => "text", is_nullable => 0 }, +); +__PACKAGE__->set_primary_key("id"); +__PACKAGE__->add_unique_constraint( + "translation_tbl_object_id_col_lang_key", + ["tbl", "object_id", "col", "lang"], +); + + +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-14 23:24:32 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:///VNqg4BOuO29xKhnY8vw + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index cf6de9a76..19adf5d49 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -204,6 +204,27 @@ sub alert_for_problem { } ); } +=head2 create_alert + +Sign a user up to receive alerts on a given problem + +=cut + +sub create_alert { + my ( $self, $id, $options ) = @_; + my $alert = $self->alert_for_problem($id); + + unless ( $alert ) { + $alert = $self->alerts->create({ + %$options, + alert_type => 'new_updates', + parameter => $id, + }); + } + + $alert->confirm(); +} + sub body { my $self = shift; return '' unless $self->from_body; @@ -274,6 +295,16 @@ sub permissions { sub has_permission_to { my ($self, $permission_type, $body_ids) = @_; + # Nobody, including superusers, can have a permission which isn't available + # in the current cobrand. + my $cobrand = $self->result_source->schema->cobrand; + my $cobrand_perms = $cobrand->available_permissions; + my %available = map { %$_ } values %$cobrand_perms; + # The 'trusted' permission is never set in the cobrand's + # available_permissions (see note there in Default.pm) so include it here. + $available{trusted} = 1; + return 0 unless $available{$permission_type}; + return 1 if $self->is_superuser; return 0 if !$body_ids || (ref $body_ids && !@$body_ids); $body_ids = [ $body_ids ] unless ref $body_ids; @@ -391,9 +422,19 @@ sub active_planned_reports { $self->planned_reports->search({ removed => undef }); } +has active_user_planned_reports => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + [ $self->user_planned_reports->search({ removed => undef })->all ]; + }, +); + sub is_planned_report { my ($self, $problem) = @_; - return $self->active_planned_reports->find({ id => $problem->id }); + my $id = $problem->id; + return scalar grep { $_->report_id == $id } @{$self->active_user_planned_reports}; } sub update_reputation { |