From 712ee570e8e2b83c442981a24e4226adaa905750 Mon Sep 17 00:00:00 2001
From: Jonathan Druart
Date: Tue, 27 Feb 2018 18:35:41 -0300
Subject: [PATCH] Bug 20307: Language overlay for authorised values
Signed-off-by: Martin Renvoize
Signed-off-by: Michal Denar
---
C4/Koha.pm | 47 +++++-------------
Koha/AuthorisedValue.pm | 56 ++++++++++++++++++++++
Koha/AuthorisedValues.pm | 30 +++++++++++-
Koha/Schema/Result/AuthorisedValue.pm | 17 ++++++-
Koha/Schema/Result/AuthorisedValueLocalization.pm | 32 +++++++++++++
admin/authorised_values.pl | 21 +++-----
admin/localization.pl | 16 ++-----
.../prog/en/modules/admin/authorised_values.tt | 47 ++++++++++++------
.../prog/en/modules/admin/localization.tt | 3 +-
svc/localization | 29 ++++++-----
10 files changed, 204 insertions(+), 94 deletions(-)
create mode 100644 Koha/Schema/Result/AuthorisedValueLocalization.pm
diff --git a/C4/Koha.pm b/C4/Koha.pm
index 9894a060cf..bfb47526ab 100644
--- a/C4/Koha.pm
+++ b/C4/Koha.pm
@@ -547,43 +547,22 @@ sub GetAuthorisedValues {
my $result = $cache->get_from_cache($cache_key);
return $result if $result;
+ # FIXME Need to deal with $opac
+ my $avs = Koha::AuthorisedValues->search_with_localization(
+ {
+ ( $category ? ( category => $category ) : () ),
+ ( $branch_limit ? ( branchcode => $branch_limit ) : () ),
+ }
+ );
my @results;
- my $dbh = C4::Context->dbh;
- my $query = qq{
- SELECT DISTINCT av.*
- FROM authorised_values av
- };
- $query .= qq{
- LEFT JOIN authorised_values_branches ON ( id = av_id )
- } if $branch_limit;
- my @where_strings;
- my @where_args;
- if($category) {
- push @where_strings, "category = ?";
- push @where_args, $category;
- }
- if($branch_limit) {
- push @where_strings, "( branchcode = ? OR branchcode IS NULL )";
- push @where_args, $branch_limit;
- }
- if(@where_strings > 0) {
- $query .= " WHERE " . join(" AND ", @where_strings);
- }
- $query .= ' ORDER BY category, ' . (
- $opac ? 'COALESCE(lib_opac, lib)'
- : 'lib, lib_opac'
- );
-
- my $sth = $dbh->prepare($query);
+ while ( my $av = $avs->next ) {
+ my $av_unblessed = $av->unblessed;
+ $av_unblessed->{translated_description} = $av->translated_description;
+ $av_unblessed->{lib} = $av->translated_description;
+ $av_unblessed->{lib_opac} = $av->translated_description;
+ push @results, $av_unblessed;
- $sth->execute( @where_args );
- while (my $data=$sth->fetchrow_hashref) {
- if ($opac && $data->{lib_opac}) {
- $data->{lib} = $data->{lib_opac};
- }
- push @results, $data;
}
- $sth->finish;
$cache->set_in_cache( $cache_key, \@results, { expiry => 5 } );
return \@results;
diff --git a/Koha/AuthorisedValue.pm b/Koha/AuthorisedValue.pm
index 423a0308e9..997ededbb7 100644
--- a/Koha/AuthorisedValue.pm
+++ b/Koha/AuthorisedValue.pm
@@ -21,7 +21,9 @@ use Modern::Perl;
use Carp;
+use C4::Languages;
use Koha::Database;
+use Koha::Localizations;
use base qw(Koha::Object Koha::Object::Limit::Library);
@@ -47,8 +49,62 @@ sub opac_description {
return $self->lib_opac() || $self->lib();
}
+
=head2 Internal methods
+=head3 translated_description
+
+=cut
+
+sub translated_description {
+ my ( $self, $lang ) = @_;
+ if ( my $translated_description = eval { $self->get_column('translated_description') } ) {
+ # If the value has already been fetched (eg. from sarch_with_localization),
+ # do not search for it again
+ # Note: This is a bit hacky but should be fast
+ return $translated_description
+ ? $translated_description
+ : $self->lib;
+ }
+ $lang ||= C4::Languages::getlanguage;
+ my $translated_description = Koha::Localizations->search({
+ code => $self->authorised_value,
+ entity => 'avs',
+ lang => $lang
+ })->next;
+ return $translated_description
+ ? $translated_description->translation
+ : $self->lib;
+}
+
+=head3 translated_descriptions
+
+=cut
+
+sub translated_descriptions {
+ my ( $self ) = @_;
+ my @translated_descriptions = Koha::Localizations->search(
+ { entity => 'avs',
+ code => $self->authorised_value,
+ }
+ );
+ return [ map {
+ {
+ lang => $_->lang,
+ translation => $_->translation,
+ }
+ } @translated_descriptions ];
+}
+
+=head3 image_location
+
+=cut
+
+sub image_location {
+ my ( $self, $interface ) = @_;
+ return C4::Koha::getitemtypeimagelocation( $interface, $self->SUPER::imageurl );
+}
+
=head3 _type
=cut
diff --git a/Koha/AuthorisedValues.pm b/Koha/AuthorisedValues.pm
index 5c73052802..bab3e0ce18 100644
--- a/Koha/AuthorisedValues.pm
+++ b/Koha/AuthorisedValues.pm
@@ -60,7 +60,10 @@ sub search {
]
}
: {};
- my $join = $branchcode ? { join => 'authorised_values_branches' } : {};
+
+ my @join = $attributes->{join} || ();
+ push @join, 'authorised_values_branches';
+ my $join = { join => \@join };
$attributes //= {};
$attributes = { %$attributes, %$join };
return $self->SUPER::search( { %$params, %$or, }, $attributes );
@@ -108,7 +111,7 @@ sub find_by_koha_field {
my $kohafield = $params->{kohafield};
my $authorised_value = $params->{authorised_value};
- my $av = $self->SUPER::search(
+ my $av = $self->search(
{ 'marc_subfield_structures.frameworkcode' => $frameworkcode,
'marc_subfield_structures.kohafield' => $kohafield,
'me.authorised_value' => $authorised_value,
@@ -175,6 +178,29 @@ sub categories {
return map $_->get_column('category'), $rs->all;
}
+=head3 search_with_localization
+
+my $avs = Koha::AuthorisedValues->search_with_localization
+
+=cut
+
+sub search_with_localization {
+ my ( $self, $params, $attributes ) = @_;
+
+ my $language = C4::Languages::getlanguage();
+ $Koha::Schema::Result::AuthorisedValue::LANGUAGE = $language;
+ $attributes->{order_by} = 'translated_description' unless exists $attributes->{order_by};
+ $attributes->{join} = 'localization';
+ $attributes->{'+select'} = [
+ {
+ coalesce => [qw( localization.translation me.lib )],
+ -as => 'translated_description'
+ }
+ ];
+ $self->search( $params, $attributes );
+}
+
+
=head3 type
=cut
diff --git a/Koha/Schema/Result/AuthorisedValue.pm b/Koha/Schema/Result/AuthorisedValue.pm
index 1a65d388c9..09acafc5e4 100644
--- a/Koha/Schema/Result/AuthorisedValue.pm
+++ b/Koha/Schema/Result/AuthorisedValue.pm
@@ -148,6 +148,21 @@ __PACKAGE__->has_many(
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2019-02-22 14:32:48
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hDlebhEn+f+thqwBo/LOqQ
+# Use the ItemtypeLocalization view to create the join on localization
+our $LANGUAGE;
+__PACKAGE__->has_many(
+ "localization" => "Koha::Schema::Result::AuthorisedValueLocalization",
+ sub {
+ my $args = shift;
+
+ die "no lang specified!" unless $LANGUAGE;
+
+ return ({
+ "$args->{self_alias}.authorised_value" => { -ident => "$args->{foreign_alias}.code" },
+ "$args->{foreign_alias}.lang" => $LANGUAGE,
+ });
+
+ }
+);
-# You can replace this text with custom code or comments, and it will be preserved on regeneration
1;
diff --git a/Koha/Schema/Result/AuthorisedValueLocalization.pm b/Koha/Schema/Result/AuthorisedValueLocalization.pm
new file mode 100644
index 0000000000..fa2c69662b
--- /dev/null
+++ b/Koha/Schema/Result/AuthorisedValueLocalization.pm
@@ -0,0 +1,32 @@
+package Koha::Schema::Result::AuthorisedValueLocalization;
+
+use base 'DBIx::Class::Core';
+
+use Modern::Perl;
+
+__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
+
+__PACKAGE__->table('authorised_value_localizations');
+__PACKAGE__->result_source_instance->is_virtual(1);
+__PACKAGE__->result_source_instance->view_definition(
+ "SELECT localization_id, code, lang, translation FROM localization WHERE entity='avs'"
+);
+
+__PACKAGE__->add_columns(
+ "localization_id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "code",
+ { data_type => "varchar", is_nullable => 0, size => 64 },
+ "lang",
+ { data_type => "varchar", is_nullable => 0, size => 25 },
+ "translation",
+ { data_type => "text", is_nullable => 1 },
+);
+
+__PACKAGE__->belongs_to(
+ "authorised_value",
+ "Koha::Schema::Result::AuthorisedValue",
+ { code => 'authorised_value' }
+);
+
+1;
diff --git a/admin/authorised_values.pl b/admin/authorised_values.pl
index 34540e1e20..8a6133890a 100755
--- a/admin/authorised_values.pl
+++ b/admin/authorised_values.pl
@@ -26,6 +26,7 @@ use C4::Auth;
use C4::Context;
use C4::Koha;
use C4::Output;
+use Carp::Always;
use Koha::AuthorisedValues;
use Koha::AuthorisedValueCategories;
@@ -92,8 +93,11 @@ if ($op eq 'add_form') {
imagesets => C4::Koha::getImageSets(),
);
}
+
+ my $translated_languages = C4::Languages::getTranslatedLanguages( undef , C4::Context->preference('template') );
$template->param(
branches_loop => \@branches_loop,
+ can_be_translated => ( scalar(@$translated_languages) > 1 ? 1 : 0 ),
);
} elsif ($op eq 'add') {
@@ -221,23 +225,10 @@ if ( $op eq 'list' ) {
$searchfield ||= $category_list[0];
- my @avs_by_category = Koha::AuthorisedValues->new->search( { category => $searchfield } );
- my @loop_data = ();
- # builds value list
- for my $av ( @avs_by_category ) {
- my %row_data; # get a fresh hash for the row data
- $row_data{category} = $av->category;
- $row_data{authorised_value} = $av->authorised_value;
- $row_data{lib} = $av->lib;
- $row_data{lib_opac} = $av->lib_opac;
- $row_data{imageurl} = getitemtypeimagelocation( 'intranet', $av->imageurl );
- $row_data{branches} = $av->library_limits ? $av->library_limits->as_list : [];
- $row_data{id} = $av->id;
- push(@loop_data, \%row_data);
- }
+ my $avs_by_category = Koha::AuthorisedValues->search_with_localization( { category => $searchfield } );
$template->param(
- loop => \@loop_data,
+ authorised_values => $avs_by_category,
category => $searchfield,
categories => \@category_list,
);
diff --git a/admin/localization.pl b/admin/localization.pl
index f8bc553c05..368a3f5292 100755
--- a/admin/localization.pl
+++ b/admin/localization.pl
@@ -40,25 +40,17 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
my $entity = $query->param('entity');
my $code = $query->param('code');
-my $rs = Koha::Localizations->search( { entity => $entity, code => $code } );
-my @translations;
-while ( my $s = $rs->next ) {
- push @translations,
- { id => $s->localization_id,
- entity => $s->entity,
- code => $s->code,
- lang => $s->lang,
- translation => $s->translation,
- };
-}
+my $interface = $query->param('interface');
+my $translations = Koha::Localizations->search( { entity => $entity, code => $code, interface => $interface } );
my $translated_languages = C4::Languages::getTranslatedLanguages( 'intranet', C4::Context->preference('template') );
$template->param(
- translations => \@translations,
+ translations => $translations,
languages => $translated_languages,
entity => $entity,
code => $code,
+ interface_side => $interface, # "interface" conflicts with existing variable's name
);
output_html_with_http_headers $query, $cookie, $template->output;
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/authorised_values.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/authorised_values.tt
index 0c8e1fccab..9567e78274 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/authorised_values.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/authorised_values.tt
@@ -74,11 +74,16 @@
-
+ [% IF can_be_translated %]
+ Translate into other languages
+ [% END %]
+ [% IF can_be_translated %]
+ Translate into other languages
+ [% END %]
- [% IF loop %]
+ [% IF authorised_values.count %]
@@ -219,16 +224,29 @@
Actions |
- [% FOREACH loo IN loop %]
+ [% FOREACH av IN authorised_values %]
- [% loo.authorised_value | html %] |
- [% loo.lib | html %] |
- [% loo.lib_opac | html %] |
- [% IF ( loo.imageurl ) %][% ELSE %] [% END %] |
+ [% av.authorised_value | html %] |
+ [% IF av.translated_descriptions.size %]
+ [% av.lib | html %] (default)
+ [% FOR description IN av.translated_descriptions %]
+ [% IF description.translation == av.translated_description %]
+ [% description.translation | html %]
+ [% ELSE %]
+ [% description.translation | html %] ([% description.lang | html %])
+ [% END %]
+
+ [% END %]
+ [% ELSE %]
+ [% av.lib |html %]
+ [% END %]
+
+ [% av.lib_opac | html %] |
+ [% IF ( av.imageurl ) %][% ELSE %] [% END %] |
- [% IF loo.branches.size > 0 %]
+ [% IF av.branch_limitations.size > 0 %]
[% branches_str = "" %]
- [% FOREACH branch IN loo.branches %]
+ [% FOREACH library IN av.library_limits %]
[%- IF loop.first -%]
[% branches_str = branch.branchname _ " (" _ branch.branchcode _ ")" %]
[% ELSE %]
@@ -236,17 +254,17 @@
[% END %]
[% END %]
- [% IF loo.branches.size > 1 %]
- [% loo.branches.size | html %] library limitations
+ [% IF av.library_limits.size > 1 %]
+ [% av.library_limits.size | html %] library limitations
[% ELSE %]
- [% loo.branches.size | html %] library limitation
+ [% av.library_limits.size | html %] library limitation
[% END %]
[% ELSE %]
No limitation
[% END %]
|
- Edit
- Delete |
+ Edit
+ Delete |
[% END # /FOREACH loop %]
@@ -301,6 +319,7 @@
[% MACRO jsinclude BLOCK %]
[% Asset.js("js/admin-menu.js") | $raw %]
+ [% INCLUDE 'greybox.inc' %]
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'columns_settings.inc' %]