aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/Roles
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/Roles')
-rw-r--r--perllib/FixMyStreet/Roles/ContactExtra.pm48
-rw-r--r--perllib/FixMyStreet/Roles/Extra.pm16
-rw-r--r--perllib/FixMyStreet/Roles/Translatable.pm116
3 files changed, 180 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/Roles/ContactExtra.pm b/perllib/FixMyStreet/Roles/ContactExtra.pm
new file mode 100644
index 000000000..55c055d99
--- /dev/null
+++ b/perllib/FixMyStreet/Roles/ContactExtra.pm
@@ -0,0 +1,48 @@
+package FixMyStreet::Roles::ContactExtra;
+
+use Moo::Role;
+use JSON::MaybeXS;
+
+requires 'join_table', 'map_extras';
+
+sub for_bodies {
+ my ($rs, $bodies, $category) = @_;
+ my $join_table = $rs->join_table();
+ my $attrs = {
+ 'me.body_id' => $bodies,
+ };
+ my $order = $rs->can('name_column') ? $rs->name_column() : 'name';
+ my $filters = {
+ order_by => $order,
+ join => { $join_table => 'contact' },
+ prefetch => $join_table,
+ distinct => 1,
+ };
+ if ($category) {
+ $attrs->{'contact.category'} = [ $category, undef ];
+ }
+ $rs->search($attrs, $filters);
+}
+
+sub by_categories {
+ my ($rs, $area_id, @contacts) = @_;
+ my %body_ids = map { $_->body_id => 1 } FixMyStreet::DB->resultset('BodyArea')->search({ area_id => $area_id });
+ my @body_ids = keys %body_ids;
+ my %extras = ();
+ my @results = $rs->for_bodies(\@body_ids, undef);
+ @contacts = grep { $body_ids{$_->body_id} } @contacts;
+
+ foreach my $contact (@contacts) {
+ my $join_table = $rs->join_table();
+ my @ts = grep {
+ $_->$join_table == 0 # There's no category at all on this defect type/template/priority
+ || (grep { $_->contact_id == $contact->get_column('id') } $_->$join_table)
+ } @results;
+ @ts = $rs->map_extras(@ts);
+ $extras{$contact->category} = encode_json(\@ts);
+ }
+
+ return \%extras;
+}
+
+1;
diff --git a/perllib/FixMyStreet/Roles/Extra.pm b/perllib/FixMyStreet/Roles/Extra.pm
index dc2e5c241..445f6d91c 100644
--- a/perllib/FixMyStreet/Roles/Extra.pm
+++ b/perllib/FixMyStreet/Roles/Extra.pm
@@ -175,4 +175,20 @@ sub get_extra {
return $extra;
}
+=head2 get_extra_field_value
+
+Return the value of a field stored in `_fields` in extra, or undefined if
+it's not present.
+
+=cut
+
+sub get_extra_field_value {
+ my ($self, $name) = @_;
+
+ my @fields = @{ $self->get_extra_fields() };
+
+ my ($field) = grep { $_->{name} eq $name } @fields;
+ return $field->{value};
+}
+
1;
diff --git a/perllib/FixMyStreet/Roles/Translatable.pm b/perllib/FixMyStreet/Roles/Translatable.pm
new file mode 100644
index 000000000..d39d97bf8
--- /dev/null
+++ b/perllib/FixMyStreet/Roles/Translatable.pm
@@ -0,0 +1,116 @@
+package FixMyStreet::Roles::Translatable;
+
+use Moo::Role;
+use FixMyStreet;
+
+has _translated => (is => 'rw');
+
+sub translated {
+ my $self = shift;
+ $self->_translated or $self->_translated({});
+}
+
+sub translate_around {
+ my ($orig, $self) = (shift, shift);
+ my $fallback = $self->$orig(@_);
+ (my $col = (caller(2))[3]) =~ s/.*:://;
+ $self->_translate($col, $fallback);
+}
+
+sub translate_column {
+ my ($self, $col) = (shift, shift);
+ my $fallback = $self->$col(@_);
+ $self->_translate($col, $fallback);
+}
+
+sub _translate {
+ my ($self, $col, $fallback) = @_;
+
+ my $langs = FixMyStreet->config('LANGUAGES');
+ return $fallback if !$langs || @$langs < 2;
+
+ my %cols = $self->get_columns;
+ return $cols{msgstr} if $cols{msgstr};
+
+ my $schema = $self->result_source->schema;
+ my $table = lc $self->result_source->source_name;
+ my $id = $self->id;
+ my $lang = $schema->lang || '';
+
+ my $translated = $self->translated->{$col}{$lang};
+ return $translated if $translated;
+
+ # Deal with the fact problem table has denormalized copy of category string
+ if ($table eq 'problem' && $col eq 'category') {
+ my $body_id = $self->bodies_str_ids->[0];
+ return $fallback unless $body_id && $body_id =~ /^[0-9]+$/;
+ my $contact = $schema->resultset("Contact")->find( {
+ body_id => $body_id,
+ category => $fallback,
+ } );
+ return $fallback unless $contact; # Shouldn't happen, but some tests
+ $table = 'contact';
+ $id = $contact->id;
+ }
+
+ if (ref $schema) {
+ my $translation = $schema->resultset('Translation')->find({
+ lang => $lang,
+ tbl => $table,
+ object_id => $id,
+ col => $col
+ });
+ $fallback = $translation->msgstr if $translation;
+ } else {
+ warn "Can't use translation on this call to $table.$col";
+ }
+ $self->translated->{$col}{$lang} = $fallback;
+ return $fallback;
+};
+
+# These next two functions (translation_for and and_translation_for) are
+# convenience methods for use in the translation interface in the admin.
+# They shouldn't be used else where as they don't take account of things
+# like denormalised strings (e.g report category)
+sub translation_for {
+ my ($self, $col, $lang) = @_;
+
+ my $schema = $self->result_source->schema;
+
+ my $props = {
+ tbl => lc $self->result_source->source_name,
+ object_id => $self->id,
+ col => $col
+ };
+
+ if ($lang) {
+ $props->{lang} = $lang;
+ }
+
+ my $translations = $schema->resultset('Translation')->search($props);
+
+ return $lang ? $translations->first : $translations;
+}
+
+sub add_translation_for {
+ my ($self, $col, $lang, $msgstr) = @_;
+
+ my $schema = $self->result_source->schema;
+
+ my $props = {
+ tbl => lc $self->result_source->source_name,
+ object_id => $self->id,
+ col => $col,
+ lang => $lang,
+ msgstr => $msgstr,
+ };
+
+ my $translation = $schema->resultset('Translation')->update_or_create(
+ $props,
+ { key => 'translation_tbl_object_id_col_lang_key' }
+ );
+
+ return $translation;
+}
+
+1;