From 0f94572e013a336eabbddddecf6af7fabd64777f Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Wed, 25 Mar 2020 11:33:26 +0100 Subject: [PATCH] Bug 24975: Refactor database translations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an attempt to make the process of translating database strings (like itemtype descriptions) easier for developers and translators. For developers by reducing the amount of code needed to enable translations for a new kind of object (authorised values, letters, news, ...). For translators by providing a single entry point for all translatable strings Table `localization` is replaced by two new tables `l10n_source` and `l10n_target`. `l10n_source` contains the original text while `l10n_target` contains the corresponding translations `l10n_source` is automatically updated whenever an itemtype is inserted, updated, or deleted, so it is always up to date (this is done in Koha::Schema::Result::ItemType). It means that if you delete an itemtype, translations get deleted too. It also means that if you change an itemtype's description, translations are lost (not sure if this should be fixed, since if description changes, translations should probably be changed too) It adds a new subroutine in Koha::I18N, `db_t`, which returns the translation for a given context and string, according to the current language. Translations are stored in memcached (if enabled). So instead of having to declare a new subroutine Koha::ItemType::translated_description, you can write db_t('itemtype', $itemtype->description) In templates you can write [% ItemTypes.t(itemtype.description) %] There's also a new page, accessible from the administration main page, "Localization". It displays all translatable strings and allow to translate them for all enabled languages. Test plan: 1. Before applying the patch, make sure you have translated some itemtypes. Translations should be kept by the updatedatabase script. Before applying the updatedatabase you may want to comment the 'DROP TABLE localization' statement if you want to keep this table 2. Apply patch, run updatedatabase.pl, run update_dbix_class_files.pl and reload starman 3. Go to Admin ยป Localization, verify that you have your itemtypes and their translations. 4. Verify that the filter is working (it filters on the source column only). 5. Translate some strings by clicking on one of the 'Translate' link, entering some text and clicking on the 'Save' button. You can remove a translation by emptying the text box. 6. Add a new item type. Verify that it appears in the Localization page 7. Change the description of this item type. Verify that the new description appears in Localization page and that the old description is gone 8. Delete this item type and verify that its description no longer appears in Localization page 9. Navigate through Koha (intranet and opac) in multiple languages and verify that item types are translated (if not, please verify in master too, not all occurrences were translated) Signed-off-by: Martin Renvoize --- C4/Biblio.pm | 3 +- C4/Items.pm | 5 +- C4/Search.pm | 11 +- Koha/DBIx/Component/L10nSource.pm | 73 ++++ Koha/I18N.pm | 49 +++ Koha/ItemType.pm | 51 +-- Koha/ItemTypes.pm | 31 -- Koha/Localization.pm | 73 ---- Koha/Localizations.pm | 34 -- Koha/Schema/Result/Itemtype.pm | 54 ++- Koha/Schema/Result/ItemtypeLocalization.pm | 32 -- Koha/Template/Plugin/ItemTypes.pm | 29 +- acqui/orderreceive.pl | 1 + admin/itemtypes.pl | 4 +- admin/localization.pl | 20 - admin/smart-rules.pl | 32 +- authorities/authorities.pl | 8 +- catalogue/getitem-ajax.pl | 3 +- catalogue/itemsearch.pl | 9 +- catalogue/moredetail.pl | 6 +- catalogue/search.pl | 18 +- cataloguing/addbiblio.pl | 5 +- cataloguing/additem.pl | 2 +- circ/transferstoreceive.pl | 3 +- course_reserves/add_items.pl | 2 +- .../data/mysql/atomicupdate/bug-24975.perl | 48 +++ installer/data/mysql/kohastructure.sql | 22 ++ .../prog/en/includes/admin-menu.inc | 1 + .../prog/en/includes/html_helpers.inc | 3 +- .../prog/en/modules/admin/admin-home.tt | 3 + .../prog/en/modules/admin/itemtypes.tt | 6 +- .../prog/en/modules/admin/localization.tt | 372 ++++++------------ .../prog/en/modules/admin/smart-rules.tt | 14 +- .../prog/en/modules/catalogue/advsearch.tt | 3 +- .../prog/en/modules/catalogue/detail.tt | 5 +- .../course_reserves/add_items-step2.tt | 5 +- .../course_reserves/batch_add_items.tt | 2 +- .../en/modules/reports/acquisitions_stats.tt | 3 +- .../prog/en/modules/reports/bor_issues_top.tt | 2 +- .../prog/en/modules/reports/cat_issues_top.tt | 3 +- .../prog/en/modules/reports/catalogue_out.tt | 2 +- .../en/modules/reports/catalogue_stats.tt | 3 +- .../en/modules/reports/issues_avg_stats.tt | 3 +- .../prog/en/modules/reports/issues_stats.tt | 3 +- .../prog/en/modules/reports/itemslost.tt | 2 +- .../prog/en/modules/reports/reserves_stats.tt | 3 +- .../en/modules/serials/subscription-add.tt | 9 +- .../modules/serials/subscription-batchedit.tt | 2 +- .../serials/subscription-bib-search.tt | 3 +- .../prog/en/modules/tools/export.tt | 3 +- .../prog/en/modules/virtualshelves/shelves.tt | 5 +- .../bootstrap/en/includes/opac-topissues.inc | 3 +- .../en/modules/opac-readingrecord.tt | 3 +- .../bootstrap/en/modules/opac-reserve.tt | 4 +- .../bootstrap/en/modules/opac-shelves.tt | 5 +- labels/label-item-search.pl | 13 - opac/opac-detail.pl | 9 +- opac/opac-readingrecord.pl | 5 +- opac/opac-reserve.pl | 9 +- opac/opac-search.pl | 14 +- opac/opac-shelves.pl | 2 +- opac/opac-user.pl | 2 +- reports/acquisitions_stats.pl | 2 +- reports/bor_issues_top.pl | 2 +- reports/cat_issues_top.pl | 2 +- reports/catalogue_out.pl | 2 +- reports/catalogue_stats.pl | 2 +- reports/issues_avg_stats.pl | 2 +- reports/issues_stats.pl | 7 +- reports/itemslost.pl | 2 +- reports/reserves_stats.pl | 5 +- reserve/request.pl | 2 +- serials/subscription-add.pl | 3 +- serials/subscription-bib-search.pl | 3 +- svc/bib_profile | 2 +- svc/checkouts | 3 +- svc/holds | 3 +- svc/localization | 129 +++--- t/db_dependent/Koha/ItemTypes.t | 44 +-- tools/batchMod.pl | 1 + tools/export.pl | 2 +- virtualshelves/shelves.pl | 2 +- 82 files changed, 589 insertions(+), 788 deletions(-) create mode 100644 Koha/DBIx/Component/L10nSource.pm delete mode 100644 Koha/Localization.pm delete mode 100644 Koha/Localizations.pm delete mode 100644 Koha/Schema/Result/ItemtypeLocalization.pm create mode 100644 installer/data/mysql/atomicupdate/bug-24975.perl diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 7a49f47df7c..9e95184e64f 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -107,6 +107,7 @@ use Koha::Acquisition::Currencies; use Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue; use Koha::Biblio::Metadatas; use Koha::Holds; +use Koha::I18N; use Koha::ItemTypes; use Koha::MarcOverlayRules; use Koha::Plugins; @@ -1413,7 +1414,7 @@ sub GetAuthorisedValueDesc { my $itypes = $cache->get_from_cache( $cache_key, { unsafe => 1 } ); if ( !$itypes ) { $itypes = - { map { $_->itemtype => $_->translated_description } + { map { $_->itemtype => db_t('itemtype', $itemtype->description) } Koha::ItemTypes->search()->as_list }; $cache->set_in_cache( $cache_key, $itypes ); } diff --git a/C4/Items.pm b/C4/Items.pm index de776d5dfe5..e3f37c2c7d5 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -61,6 +61,7 @@ use Koha::Database; use Koha::Biblios; use Koha::Biblioitems; +use Koha::I18N; use Koha::Items; use Koha::ItemTypes; use Koha::SearchEngine; @@ -1459,11 +1460,11 @@ sub PrepareItemrecordDisplay { #----- itemtypes } elsif ( $subfield->{authorised_value} eq "itemtypes" ) { - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; push @authorised_values, ""; while ( my $itemtype = $itemtypes->next ) { push @authorised_values, $itemtype->itemtype; - $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description; + $authorised_lib{$itemtype->itemtype} = db_t('itemtype', $itemtype->description); } if ($defaultvalues && $defaultvalues->{'itemtype'}) { $defaultvalue = $defaultvalues->{'itemtype'}; diff --git a/C4/Search.pm b/C4/Search.pm index 5985db2edb2..f25de056966 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -28,6 +28,7 @@ use C4::XSLT qw( XSLTParse4Display ); use C4::Reserves qw( GetReserveStatus ); use C4::Charset qw( SetUTF8Flag ); use Koha::AuthorisedValues; +use Koha::I18N; use Koha::ItemTypes; use Koha::Libraries; use Koha::Logger; @@ -538,9 +539,7 @@ sub getRecords { && ref( $itemtypes->{$one_facet} ) eq "HASH" ) { - $facet_label_value = - $itemtypes->{$one_facet} - ->{translated_description}; + $facet_label_value = db_t('itemtype', $itemtypes->{$one_facet}->{description}); } } @@ -1670,7 +1669,7 @@ sub searchResults { my $notforloan_authorised_value = $av->count ? $av->next->authorised_value : undef; #Get itemtype hash - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; my %itemtypes = map { $_->{itemtype} => $_ } @{ $itemtypes->unblessed }; #search item field code @@ -1752,7 +1751,7 @@ sub searchResults { # add imageurl to itemtype if there is one $oldbiblio->{imageurl} = $itemtype ? getitemtypeimagelocation( $search_context->{'interface'}, $itemtype->{imageurl} ) : q{}; # Build summary if there is one (the summary is defined in the itemtypes table) - $oldbiblio->{description} = $itemtype ? $itemtype->{translated_description} : q{}; + $oldbiblio->{description} = $itemtype ? db_t('itemtype', $itemtype->{description}) : q{}; # Pull out the items fields my @fields = $marcrecord->field($itemtag); @@ -1824,7 +1823,7 @@ sub searchResults { next; } - $item->{description} = $itemtypes{ $item->{itype} }{translated_description} if $item->{itype}; + $item->{description} = db_t('itemtype', $itemtypes{ $item->{itype} }{description}) if $item->{itype}; # OPAC hidden items if ($is_opac) { diff --git a/Koha/DBIx/Component/L10nSource.pm b/Koha/DBIx/Component/L10nSource.pm new file mode 100644 index 00000000000..9d4ea398d93 --- /dev/null +++ b/Koha/DBIx/Component/L10nSource.pm @@ -0,0 +1,73 @@ +package Koha::DBIx::Component::L10nSource; + +use Modern::Perl; +use base 'DBIx::Class'; + +=head1 NAME + +Koha::DBIx::Component::L10nSource + +=head1 SYNOPSIS + + __PACKAGE__->load_components('+Koha::DBIx::Component::L10nSource') + + sub insert { + my $self = shift; + my $result = $self->next::method(@_); + my @sources = $self->result_source->resultset->get_column('label')->all; + $self->update_l10n_source('somecontext', @sources); + return $result; + } + + sub update { + my $self = shift; + my $is_column_changed = $self->is_column_changed('label'); + my $result = $self->next::method(@_); + if ($is_column_changed) { + my @sources = $self->result_source->resultset->get_column('label')->all; + $self->update_l10n_source('somecontext', @sources); + } + return $result; + } + + sub delete { + my $self = shift; + my $result = $self->next::method(@_); + my @sources = $self->result_source->resultset->get_column('label')->all; + $self->update_l10n_source('somecontext', @sources); + return $result; + } + +=head1 METHODS + +=head2 update_l10n_source + + $self->update_l10n_source($context, @sources) + +Ensure that all sources in C<@sources>and only them are present in l10n_source +for a given C<$context> + +=cut + +sub update_l10n_source { + my ($self, $context, @sources) = @_; + + my $l10n_source_rs = $self->result_source->schema->resultset('L10nSource')->search({ context => $context }); + + # Insert missing l10n_source rows + foreach my $source (@sources) { + my $count = $l10n_source_rs->search({ source => $source })->count; + if ($count == 0) { + $l10n_source_rs->create({ source => $source }); + } + } + + # Remove l10n_source rows that do not match an existing source + my %sources = map { $_ => undef } @sources; + my @l10n_sources = grep { !exists $sources{$_->source} } $l10n_source_rs->all; + foreach my $l10n_source (@l10n_sources) { + $l10n_source->delete; + } +} + +1; diff --git a/Koha/I18N.pm b/Koha/I18N.pm index 3f09673c74c..a2405dd38c2 100644 --- a/Koha/I18N.pm +++ b/Koha/I18N.pm @@ -35,6 +35,8 @@ use Locale::Messages qw( ); use POSIX qw(); use Koha::Cache::Memory::Lite; +use Koha::Caches; +use Koha::Database; use parent 'Exporter'; our @EXPORT = qw( @@ -51,6 +53,8 @@ our @EXPORT = qw( N__n N__p N__np + + db_t ); our $textdomain = 'Koha'; @@ -222,4 +226,49 @@ sub _expand { return $text; } +=head2 db_t + + db_t($context, $source) + db_t('itemtype', $itemtype->description) + +Search for a translation in l10n_target table and return it if found +Return source string otherwise + +=cut + +sub db_t { + my ($context, $source) = @_; + + my $cache = Koha::Caches->get_instance(); + my $language = C4::Languages::getlanguage(); + my $cache_key = sprintf('%s:%s', $context, $language); + + my $translations = $cache->get_from_cache($cache_key); + unless ($translations) { + my $schema = Koha::Database->new->schema; + my $rs = $schema->resultset('L10nTarget'); + + my @targets = $rs->search( + { + 'l10n_source.context' => $context, + language => $language, + }, + { + join => 'l10n_source', + prefetch => 'l10n_source', + result_class => 'DBIx::Class::ResultClass::HashRefInflator', + }, + ); + $translations = { map { $_->{l10n_source}->{source} => $_->{translation} } @targets }; + + $cache->set_in_cache($cache_key, $translations); + } + + if (exists $translations->{$source}) { + return $translations->{$source}; + } + + return $source; +} + 1; diff --git a/Koha/ItemType.pm b/Koha/ItemType.pm index dbbae3fbfcf..0d21eb1334a 100644 --- a/Koha/ItemType.pm +++ b/Koha/ItemType.pm @@ -23,7 +23,6 @@ use C4::Languages; use Koha::Caches; use Koha::Database; use Koha::CirculationRules; -use Koha::Localizations; use base qw(Koha::Object Koha::Object::Limit::Library); @@ -89,50 +88,6 @@ sub image_location { return C4::Koha::getitemtypeimagelocation( $interface, $self->SUPER::imageurl ); } -=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->description; - } - $lang ||= C4::Languages::getlanguage; - my $translated_description = Koha::Localizations->search({ - code => $self->itemtype, - entity => 'itemtypes', - lang => $lang - })->next; - return $translated_description - ? $translated_description->translation - : $self->description; -} - -=head3 translated_descriptions - -=cut - -sub translated_descriptions { - my ( $self ) = @_; - my @translated_descriptions = Koha::Localizations->search( - { entity => 'itemtypes', - code => $self->itemtype, - } - )->as_list; - return [ map { - { - lang => $_->lang, - translation => $_->translation, - } - } @translated_descriptions ]; -} - =head3 can_be_deleted my $can_be_deleted = Koha::ItemType->can_be_deleted(); @@ -196,15 +151,15 @@ sub parent { } -=head3 children_with_localization +=head3 children Returns the ItemType objects of the children of this type or undef. =cut -sub children_with_localization { +sub children { my ( $self ) = @_; - return Koha::ItemTypes->search_with_localization({ parent_type => $self->itemtype }); + return Koha::ItemTypes->search({ parent_type => $self->itemtype }); } =head3 type diff --git a/Koha/ItemTypes.pm b/Koha/ItemTypes.pm index 13caa648a81..5cc28842b6d 100644 --- a/Koha/ItemTypes.pm +++ b/Koha/ItemTypes.pm @@ -31,37 +31,6 @@ Koha::ItemTypes - Koha ItemType Object set class =head1 API -=head2 Class methods - -=cut - -=head3 search_with_localization - -my $itemtypes = Koha::ItemTypes->search_with_localization - -=cut - -sub search_with_localization { - my ( $self, $params, $attributes ) = @_; - - my $language = C4::Languages::getlanguage(); - $Koha::Schema::Result::Itemtype::LANGUAGE = $language; - $attributes->{order_by} = 'translated_description' unless exists $attributes->{order_by}; - $attributes->{join} = 'localization'; - $attributes->{'+select'} = [ - { - coalesce => [qw( localization.translation me.description )], - -as => 'translated_description' - } - ]; - if(defined $params->{branchcode}) { - my $branchcode = delete $params->{branchcode}; - $self->search_with_library_limits( $params, $attributes, $branchcode ); - } else { - $self->SUPER::search( $params, $attributes ); - } -} - =head2 Internal methods =head3 type diff --git a/Koha/Localization.pm b/Koha/Localization.pm deleted file mode 100644 index 90201b88702..00000000000 --- a/Koha/Localization.pm +++ /dev/null @@ -1,73 +0,0 @@ -package Koha::Localization; - -# This file is part of Koha. -# -# Koha is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# Koha is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Koha; if not, see . - -use Modern::Perl; - -use Koha::Database; - -use base qw(Koha::Object); - -my $cache = Koha::Caches->get_instance(); - -=head1 NAME - -Koha::Localization - Koha Localization type Object class - -=head1 API - -=head2 Class methods - -=cut - -=head3 store - -Localization specific store to ensure relevant caches are flushed on change - -=cut - -sub store { - my ($self) = @_; - $self = $self->SUPER::store; - - if ($self->entity eq 'itemtypes') { - my $key = "itemtype:description:".$self->lang; - $cache->clear_from_cache($key); - } - - return $self; -} - -=head2 delete - -Localization specific C to clear relevant caches on delete. - -=cut - -sub delete { - my $self = shift @_; - if ($self->entity eq 'itemtypes') { - my $key = "itemtype:description:".$self->lang; - $cache->clear_from_cache($key); - } - $self->SUPER::delete(@_); -} - -sub _type { - return 'Localization'; -} - -1; diff --git a/Koha/Localizations.pm b/Koha/Localizations.pm deleted file mode 100644 index 8720334acd4..00000000000 --- a/Koha/Localizations.pm +++ /dev/null @@ -1,34 +0,0 @@ -package Koha::Localizations; - -# This file is part of Koha. -# -# Koha is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# Koha is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Koha; if not, see . - -use Modern::Perl; - -use Koha::Database; - -use Koha::Localization; - -use base qw(Koha::Objects); - -sub _type { - return 'Localization'; -} - -sub object_class { - return 'Koha::Localization'; -} - -1; diff --git a/Koha/Schema/Result/Itemtype.pm b/Koha/Schema/Result/Itemtype.pm index 99fb6de5a58..951128d30cc 100644 --- a/Koha/Schema/Result/Itemtype.pm +++ b/Koha/Schema/Result/Itemtype.pm @@ -342,22 +342,7 @@ __PACKAGE__->add_columns( '+automatic_checkin' => { is_boolean => 1 }, ); -# Use the ItemtypeLocalization view to create the join on localization -our $LANGUAGE; -__PACKAGE__->has_many( - "localization" => "Koha::Schema::Result::ItemtypeLocalization", - sub { - my $args = shift; - - die "no lang specified!" unless $LANGUAGE; - - return ({ - "$args->{self_alias}.itemtype" => { -ident => "$args->{foreign_alias}.code" }, - "$args->{foreign_alias}.lang" => $LANGUAGE, - }); - - } -); +__PACKAGE__->load_components('+Koha::DBIx::Component::L10nSource'); sub koha_object_class { 'Koha::ItemType'; @@ -366,4 +351,41 @@ sub koha_objects_class { 'Koha::ItemTypes'; } +sub insert { + my $self = shift; + + my $result = $self->next::method(@_); + + my @sources = $self->result_source->resultset->get_column('description')->all; + $self->update_l10n_source('itemtype', @sources); + + return $result; +} + +sub update { + my $self = shift; + + my $is_description_changed = $self->is_column_changed('description'); + + my $result = $self->next::method(@_); + + if ($is_description_changed) { + my @sources = $self->result_source->resultset->get_column('description')->all; + $self->update_l10n_source('itemtype', @sources); + } + + return $result; +} + +sub delete { + my $self = shift; + + my $result = $self->next::method(@_); + + my @sources = $self->result_source->resultset->get_column('description')->all; + $self->update_l10n_source('itemtype', @sources); + + return $result; +} + 1; diff --git a/Koha/Schema/Result/ItemtypeLocalization.pm b/Koha/Schema/Result/ItemtypeLocalization.pm deleted file mode 100644 index d5966128c36..00000000000 --- a/Koha/Schema/Result/ItemtypeLocalization.pm +++ /dev/null @@ -1,32 +0,0 @@ -package Koha::Schema::Result::ItemtypeLocalization; - -use base 'DBIx::Class::Core'; - -use Modern::Perl; - -__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); - -__PACKAGE__->table('itemtype_localizations'); -__PACKAGE__->result_source_instance->is_virtual(1); -__PACKAGE__->result_source_instance->view_definition( - "SELECT localization_id, code, lang, translation FROM localization WHERE entity='itemtypes'" -); - -__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( - "itemtype", - "Koha::Schema::Result::Itemtype", - { code => 'itemtype' } -); - -1; diff --git a/Koha/Template/Plugin/ItemTypes.pm b/Koha/Template/Plugin/ItemTypes.pm index d2184f8fa7c..57379fa2f6a 100644 --- a/Koha/Template/Plugin/ItemTypes.pm +++ b/Koha/Template/Plugin/ItemTypes.pm @@ -23,35 +23,26 @@ use Template::Plugin; use base qw( Template::Plugin ); use Koha::Cache::Memory::Lite; +use Koha::I18N; use Koha::ItemTypes; sub GetDescription { my ( $self, $itemtypecode, $want_parent ) = @_; - return q{} unless defined $itemtypecode; - - my $memory_cache = Koha::Cache::Memory::Lite->get_instance; - my $cache_key = $want_parent ? "Itemtype_parent_description:".$itemtypecode : "Itemtype_description:" . $itemtypecode; - - my $cached = $memory_cache->get_from_cache($cache_key); - return $cached if $cached; - my $itemtype = Koha::ItemTypes->find( $itemtypecode ); - unless ($itemtype) { - $memory_cache->set_in_cache( $cache_key, q{} ); - return q{}; - } - + return q{} unless defined $itemtype; my $parent; $parent = $itemtype->parent if $want_parent; - - my $description = $parent ? $parent->translated_description . "->" . $itemtype->translated_description : $itemtype->translated_description; - $memory_cache->set_in_cache( $cache_key, $description ); - - return $description; + return $parent ? $self->t($parent->description) . "->" . $self->t($itemtype->description) : $self->t($itemtype->description); } sub Get { - return Koha::ItemTypes->search_with_localization->unblessed; + return Koha::ItemTypes->search->unblessed; +} + +sub t { + my ($self, $description) = @_; + + return db_t('itemtype', $description); } 1; diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl index 17c7280ea37..5f5b66b89e6 100755 --- a/acqui/orderreceive.pl +++ b/acqui/orderreceive.pl @@ -74,6 +74,7 @@ use Koha::Acquisition::Booksellers; use Koha::Acquisition::Currencies qw( get_active ); use Koha::Acquisition::Orders; use Koha::DateUtils qw( dt_from_string ); +use Koha::I18N; use Koha::ItemTypes; use Koha::Patrons; diff --git a/admin/itemtypes.pl b/admin/itemtypes.pl index 44e9ad54459..6063348b9e5 100755 --- a/admin/itemtypes.pl +++ b/admin/itemtypes.pl @@ -32,7 +32,6 @@ use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); use Koha::ItemTypes; use Koha::ItemType; -use Koha::Localizations; my $input = CGI->new; my $searchfield = $input->param('description'); @@ -60,7 +59,6 @@ if ( $op eq 'add_form' ) { my $parent_types = Koha::ItemTypes->search({parent_type=>undef,itemtype => {'!='=>$itemtype_code}}); my $imagesets = C4::Koha::getImageSets( checked => ( $itemtype ? $itemtype->imageurl : undef ) ); my $searchcategory = GetAuthorisedValues("ITEMTYPECAT"); - my $translated_languages = C4::Languages::getTranslatedLanguages( "both", C4::Context->preference('template') ); $template->param( itemtype => $itemtype, parent_type => $parent_type, @@ -68,7 +66,7 @@ if ( $op eq 'add_form' ) { is_a_parent => $itemtype ? Koha::ItemTypes->search({parent_type=>$itemtype_code})->count : 0, imagesets => $imagesets, searchcategory => $searchcategory, - can_be_translated => ( scalar(@$translated_languages) > 1 ? 1 : 0 ), + branches_loop => \@branches_loop, ); } elsif ( $op eq 'add_validate' ) { my $is_a_modif = $input->param('is_a_modif'); diff --git a/admin/localization.pl b/admin/localization.pl index 58205d8df7c..61fd116c05d 100755 --- a/admin/localization.pl +++ b/admin/localization.pl @@ -21,9 +21,6 @@ use Modern::Perl; use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); -use Koha::Localization; -use Koha::Localizations; - use CGI qw( -utf8 ); my $query = CGI->new; @@ -36,27 +33,10 @@ 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 $translated_languages = C4::Languages::getTranslatedLanguages( 'intranet', C4::Context->preference('template') ); $template->param( - translations => \@translations, languages => $translated_languages, - entity => $entity, - code => $code, ); output_html_with_http_headers $query, $cookie, $template->output; diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index b74a0ceeaba..7e654a5dabb 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -727,7 +727,7 @@ $template->param( my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] }); -my $itemtypes = Koha::ItemTypes->search_with_localization; +my $itemtypes = Koha::ItemTypes->search; my $humanbranch = ( $branch ne '*' ? $branch : undef ); @@ -754,36 +754,6 @@ output_html_with_http_headers $input, $cookie, $template->output; exit 0; -# sort by patron category, then item type, putting -# default entries at the bottom -sub by_category_and_itemtype { - unless (by_category($a, $b)) { - return by_itemtype($a, $b); - } -} - -sub by_category { - my ($a, $b) = @_; - if ($a->{'default_humancategorycode'}) { - return ($b->{'default_humancategorycode'} ? 0 : 1); - } elsif ($b->{'default_humancategorycode'}) { - return -1; - } else { - return $a->{'humancategorycode'} cmp $b->{'humancategorycode'}; - } -} - -sub by_itemtype { - my ($a, $b) = @_; - if ($a->{default_translated_description}) { - return ($b->{'default_translated_description'} ? 0 : 1); - } elsif ($b->{'default_translated_description'}) { - return -1; - } else { - return lc $a->{'translated_description'} cmp lc $b->{'translated_description'}; - } -} - sub strip_non_numeric { my $string = shift; $string =~ s/\s//g; diff --git a/authorities/authorities.pl b/authorities/authorities.pl index 501a012d241..57f7f3d7e98 100755 --- a/authorities/authorities.pl +++ b/authorities/authorities.pl @@ -32,6 +32,7 @@ use C4::Biblio qw( TransformHtmlToMarc ); use Koha::Authority::Types; use Koha::Import::Records; use Koha::ItemTypes; +use Koha::I18N; use vars qw( $tagslib); use vars qw( $authorised_values_sth); use vars qw( $is_a_modif ); @@ -66,10 +67,13 @@ sub build_authorized_values_list { } } elsif ( $category eq "itemtypes" ) { - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; while ( my $itemtype = $itemtypes->next ) { + push @authorised_values, "" + unless ( $tagslib->{$tag}->{$subfield}->{mandatory} + && ( $value || $tagslib->{$tag}->{$subfield}->{defaultvalue} ) ); push @authorised_values, $itemtype->itemtype; - $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description; + $authorised_lib{$itemtype->itemtype} = db_t('itemtype', $itemtype->description); } } else { # "true" authorised value diff --git a/catalogue/getitem-ajax.pl b/catalogue/getitem-ajax.pl index 9dad680e0c5..43e5a0945c6 100755 --- a/catalogue/getitem-ajax.pl +++ b/catalogue/getitem-ajax.pl @@ -27,6 +27,7 @@ use C4::Output qw( output_with_http_headers ); use Koha::Libraries; use Koha::AuthorisedValues; +use Koha::I18N; use Koha::Items; use Koha::ItemTypes; @@ -75,7 +76,7 @@ if($itemnumber) { my $itemtype = Koha::ItemTypes->find( $item->effective_itemtype ); # We should not do that here, but call ->itemtype->description when needed instea - $item_unblessed->{itemtype} = $itemtype->description; # FIXME Should not it be translated_description? + $item_unblessed->{itemtype} = db_t('itemtype', $itemtype->description); } my $json_text = to_json( $item_unblessed, { utf8 => 1 } ); diff --git a/catalogue/itemsearch.pl b/catalogue/itemsearch.pl index 72074a8fdf8..75e071b659b 100755 --- a/catalogue/itemsearch.pl +++ b/catalogue/itemsearch.pl @@ -28,6 +28,7 @@ use C4::Koha qw( GetAuthorisedValues ); use Koha::AuthorisedValues; use Koha::Biblios; +use Koha::I18N; use Koha::Item::Search::Field qw(GetItemSearchFields); use Koha::ItemTypes; use Koha::Libraries; @@ -278,7 +279,13 @@ if ( defined $format ) { # Display the search form my @branches = map { value => $_->branchcode, label => $_->branchname }, Koha::Libraries->search( {}, { order_by => 'branchname' } )->as_list; -my @itemtypes = map { value => $_->itemtype, label => $_->translated_description }, Koha::ItemTypes->search_with_localization->as_list; +my @itemtypes; +foreach my $itemtype ( Koha::ItemTypes->search->as_list ) { + push @itemtypes, { + value => $itemtype->itemtype, + label => db_t('itemtype', $itemtype->description), + }; +} my @ccodes = Koha::AuthorisedValues->get_descriptions_by_koha_field({ kohafield => 'items.ccode' }); foreach my $ccode (@ccodes) { diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl index 787bac26b3d..9fdb2fb91da 100755 --- a/catalogue/moredetail.pl +++ b/catalogue/moredetail.pl @@ -35,6 +35,7 @@ use Koha::AuthorisedValues; use Koha::Biblios; use Koha::Items; use Koha::Patrons; +use Koha::I18N; my $query=CGI->new; @@ -138,9 +139,9 @@ my $ccodes = my $copynumbers = { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => $fw, kohafield => 'items.copynumber' } ) }; -my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; -$data->{'itemtypename'} = $itemtypes->{ $data->{'itemtype'} }->{'translated_description'} +$data->{'itemtypename'} = db_t('itemtype', $itemtypes->{ $data->{'itemtype'} }->{description}); if $data->{itemtype} && exists $itemtypes->{ $data->{itemtype} }; foreach ( keys %{$data} ) { $template->param( "$_" => defined $data->{$_} ? $data->{$_} : '' ); @@ -155,6 +156,7 @@ foreach my $item (@items){ my $item_info = $item->unblessed; $item_info->{object} = $item; $item_info->{itype} = $itemtypes->{ $item->itype }->{'translated_description'} if exists $itemtypes->{ $item->itype }; + $item_info->{itype} = db_t('itemtype', $itemtypes->{ $item_info->{itype} }->{description}) if exists $itemtypes->{ $item_info->{itype} }; $item_info->{effective_itemtype} = $itemtypes->{$item->effective_itemtype}; $item_info->{'ccode'} = $ccodes->{ $item->ccode } if $ccodes && $item->ccode && exists $ccodes->{ $item->ccode }; if ( defined $item->copynumber ) { diff --git a/catalogue/search.pl b/catalogue/search.pl index bf225911ef9..9456d44505b 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -158,6 +158,7 @@ use Koha::SearchEngine::QueryBuilder; use Koha::Virtualshelves; use Koha::SearchFields; use Koha::SearchFilters; +use Koha::I18N; use URI::Escape; use JSON qw( decode_json encode_json ); @@ -542,7 +543,7 @@ my $facets; # this object stores the faceted results that display on the left-ha my $results_hashref; eval { - my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; ( $error, $results_hashref, $facets ) = $searcher->search_compat( $query, $simple_query, \@sort_by, \@servers, $results_per_page, $offset, undef, $itemtypes, @@ -810,7 +811,14 @@ sub prepare_adv_search_types { # the index parameter is different for item-level itemtypes my $itype_or_itemtype = ( C4::Context->preference("item-level_itypes") ) ? 'itype' : 'itemtype'; - my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + my $itemtypes = { + map { + $_->{itemtype} => { + %$_, + description => db_t( 'itemtype', $_->{description} ), + } + } @{ Koha::ItemTypes->search->unblessed } + }; my ( $cnt, @result ); foreach my $advanced_srch_type (@advanced_search_types) { @@ -822,8 +830,8 @@ sub prepare_adv_search_types { my @itypesloop; foreach my $thisitemtype ( sort { - $itemtypes->{$a}->{'translated_description'} - cmp $itemtypes->{$b}->{'translated_description'} + $itemtypes->{$a}->{'description'} + cmp $itemtypes->{$b}->{'description'} } keys %$itemtypes ) { @@ -831,7 +839,7 @@ sub prepare_adv_search_types { number => $cnt++, ccl => "$itype_or_itemtype,phr", code => $thisitemtype, - description => $itemtypes->{$thisitemtype}->{'translated_description'}, + description => $itemtypes->{$thisitemtype}->{'description'}, imageurl => getitemtypeimagelocation( 'intranet', $itemtypes->{$thisitemtype}->{'imageurl'} ), diff --git a/cataloguing/addbiblio.pl b/cataloguing/addbiblio.pl index 815e2a80d4d..7cb8d816350 100755 --- a/cataloguing/addbiblio.pl +++ b/cataloguing/addbiblio.pl @@ -57,6 +57,7 @@ use Koha::Patrons; use MARC::File::USMARC; use MARC::File::XML; use URI::Escape qw( uri_escape_utf8 ); +use Koha::I18N; if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { MARC::File::XML->default_record_format('UNIMARC'); @@ -197,10 +198,10 @@ sub build_authorized_values_list { push @authorised_values, ""; my $itemtype; - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; while ( $itemtype = $itemtypes->next ) { push @authorised_values, $itemtype->itemtype; - $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description; + $authorised_lib{$itemtype->itemtype} = db_t('itemtype', $itemtype->description); } $value = $itemtype unless ($value); } diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl index 5ba7ab51999..cf571f10aaa 100755 --- a/cataloguing/additem.pl +++ b/cataloguing/additem.pl @@ -34,9 +34,9 @@ use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_htt use C4::Search qw( enabled_staff_search_views ); use Koha::Biblios; use Koha::Item::Templates; +use Koha::I18N; use Koha::ItemTypes; use Koha::Items; -use Koha::Items; use Koha::Libraries; use Koha::Patrons; use Koha::SearchEngine::Indexer; diff --git a/circ/transferstoreceive.pl b/circ/transferstoreceive.pl index 0116278145e..9edb0e43a0d 100755 --- a/circ/transferstoreceive.pl +++ b/circ/transferstoreceive.pl @@ -28,6 +28,7 @@ use C4::Members; use Date::Calc qw( Add_Delta_Days Date_to_Days Today ); use C4::Reserves; +use Koha::I18N; use Koha::Items; use Koha::ItemTypes; use Koha::Libraries; @@ -87,7 +88,7 @@ while ( my $library = $libraries->next ) { my $itemtype = Koha::ItemTypes->find( $item->effective_itemtype ); $getransf{'datetransfer'} = $num->{'datesent'}; - $getransf{'itemtype'} = $itemtype->description; # FIXME Should not it be translated_description? + $getransf{'itemtype'} = db_t('itemtype', $itemtype->description); %getransf = ( %getransf, title => $biblio->title, diff --git a/course_reserves/add_items.pl b/course_reserves/add_items.pl index d430cf58daf..7b727a87660 100755 --- a/course_reserves/add_items.pl +++ b/course_reserves/add_items.pl @@ -99,7 +99,7 @@ if ( $action eq 'lookup' and $item ) { ccodes => GetAuthorisedValues('CCODE'), locations => GetAuthorisedValues('LOC'), - itypes => $itemtypes, # FIXME We certainly want to display the translated_description in the template + itypes => $itemtypes, return => $return, ); diff --git a/installer/data/mysql/atomicupdate/bug-24975.perl b/installer/data/mysql/atomicupdate/bug-24975.perl new file mode 100644 index 00000000000..748b9b7b8f0 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug-24975.perl @@ -0,0 +1,48 @@ +$DBversion = 'XXX'; +if( CheckVersion( $DBversion ) ) { + $dbh->do(q{ + CREATE TABLE IF NOT EXISTS l10n_source ( + l10n_source_id INT(11) NOT NULL AUTO_INCREMENT, + context VARCHAR(100) NULL DEFAULT NULL, + source TEXT NOT NULL, + PRIMARY KEY (l10n_source_id), + KEY context_source (context, source(60)) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + }); + + $dbh->do(q{ + CREATE TABLE IF NOT EXISTS l10n_target ( + l10n_target_id INT(11) NOT NULL AUTO_INCREMENT, + l10n_source_id INT(11) NOT NULL, + language VARCHAR(10) NOT NULL, + translation TEXT NOT NULL, + PRIMARY KEY (l10n_target_id), + UNIQUE KEY l10n_source_language (l10n_source_id, language), + FOREIGN KEY l10n_source (l10n_source_id) REFERENCES l10n_source (l10n_source_id) + ON DELETE CASCADE ON UPDATE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + }); + + # Populate l10n_source and l10n_target for itemtypes + $dbh->do(q{ + INSERT INTO l10n_source (context, source) + SELECT DISTINCT 'itemtype', description FROM itemtypes + }); + + if (TableExists('localization')) { + $dbh->do(q{ + INSERT INTO l10n_target (l10n_source_id, language, translation) + SELECT DISTINCT l10n_source_id, lang, translation + FROM localization + JOIN itemtypes ON (localization.code = itemtypes.itemtype) + JOIN l10n_source ON (itemtypes.description = l10n_source.source AND l10n_source.context = 'itemtype') + WHERE entity = 'itemtypes' + }); + + $dbh->do('DROP TABLE localization'); + } + + + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 24975 - l10n_source, l10n_target)\n"; +} diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index cba889d5e0f..0a9cb3fce0b 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3754,6 +3754,28 @@ CREATE TABLE `keyboard_shortcuts` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; + +DROP TABLE IF EXISTS l10n_source; +CREATE TABLE l10n_source ( + l10n_source_id INT(11) NOT NULL AUTO_INCREMENT, + context VARCHAR(100) NULL DEFAULT NULL, + source TEXT NOT NULL, + PRIMARY KEY (l10n_source_id), + KEY context_source (context, source(60)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +DROP TABLE IF EXISTS l10n_target; +CREATE TABLE l10n_target ( + l10n_target_id INT(11) NOT NULL AUTO_INCREMENT, + l10n_source_id INT(11) NOT NULL, + language VARCHAR(10) NOT NULL, + translation TEXT NOT NULL, + PRIMARY KEY (l10n_target_id), + UNIQUE KEY l10n_source_language (l10n_source_id, language), + FOREIGN KEY l10n_source (l10n_source_id) REFERENCES l10n_source (l10n_source_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + -- -- Table structure for table `language_descriptions` -- diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc index 9c9a24c545d..ea7ff1b8ba2 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc @@ -177,6 +177,7 @@ [% IF ( Koha.Preference('EnableAdvancedCatalogingEditor') && CAN_user_parameters_manage_keyboard_shortcuts ) %]
  • Keyboard shortcuts
  • [% END %] +
  • Localization
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc index f0d695bc9c0..c8d655b03ce 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc @@ -1,3 +1,4 @@ +[% USE ItemTypes %] [% BLOCK options_for_libraries %] [% FOREACH l IN libraries %] [% IF l.selected %] @@ -64,7 +65,7 @@ [% ELSE %] [% END %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt index 1ba35ac9196..180261859c7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -282,6 +282,9 @@
    Keyboard shortcuts
    Define which keys trigger actions in the advanced cataloging editor
    [% END %] + +
    Localization
    +
    Translate user-defined strings
    [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt index f206f8fee4d..d4ffee933f7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt @@ -1,5 +1,6 @@ [% USE raw %] [% USE Asset %] +[% USE ItemTypes %] [% USE Koha %] [% USE Branches %] [% USE AuthorisedValues %] @@ -183,9 +184,6 @@ Item types › Administration › Koha
  • Required - [% IF can_be_translated %] - Translate into other languages - [% END %]
  • @@ -426,7 +424,7 @@ Item types › Administration › Koha Item type [% itemtype.itemtype | html %] - Description[% itemtype.translated_description | html %] + Description[% ItemTypes.t(itemtype.description) | html %] [% UNLESS Koha.Preference('noItemTypeImages') && Koha.Preference('OpacNoItemTypeImages') %] Image diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt index dde2683174e..1cde049e106 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt @@ -1,278 +1,162 @@ -[% USE raw %] -[% USE Asset %] +[% USE JSON.Escape %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] Localization › Koha -[% INCLUDE 'doc-head-close.inc' popup => 1 %] - +[% INCLUDE 'doc-head-close.inc' %] + -
    -
    -
    -

    Localization

    -
    - - - -
    -
      -
    1. - Authorized value: - [% code | html %] -
    2. -
    3. - - -
    4. -
    5. - - -
    6. -
    7. -   - -
    8. -
    -
    -
    -
    -
    + [% INCLUDE 'header.inc' %] + [% INCLUDE 'prefs-admin-search.inc' %] -
    -
    -
    -
    -
    + + +
    -
    - - - - - - - - - - - - - [% FOR t IN translations %] - - - - - - - - - [% END %] - -
    IdEntityCodeLanguageTranslation 
    [% t.id | html %][% t.entity | html %][% t.code | html %][% t.lang | html %][% t.translation | html %] Delete
    -
    -
    -
    +
    +
    +

    Localization

    + + + + + + + + + + + +
    ContextSourceTranslations
    +
    +
    + +
    + +
    +
    + [% MACRO jsinclude BLOCK %] [% INCLUDE 'datatables.inc' %] [% END %] -[% INCLUDE 'popup-bottom.inc' %] +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index f91a10029d5..fdda51e14bc 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -414,16 +414,16 @@ [% FOREACH itemtypeloo IN itemtypeloop %] [% NEXT IF itemtypeloo.parent_type %] - [% SET children = itemtypeloo.children_with_localization %] + [% SET children = itemtypeloo.children %] [% IF children.count %] - - + + [% FOREACH child IN children %] - + [% END %] [% ELSE %] - + [% END %] [% END %] @@ -1285,7 +1285,7 @@ [% IF holdallowed || hold_fulfillment_policy || returnbranch %] - [% i.translated_description | html %] + [% ItemTypes.t(i.description) | html %] [% IF holdallowed == 'from_any_library' %] @@ -1330,7 +1330,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt index 547f5b1794d..14bdfe7a184 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt @@ -1,4 +1,5 @@ [% USE raw %] +[% USE ItemTypes %] [% USE Koha %] [% USE Asset %] [% USE Branches %] @@ -239,7 +240,7 @@ [% END %]   [% END %] - [% itemtypeloo.description | html %] + [% ItemTypes.t(itemtypeloo.description) | html %] [% IF ( loop.last ) %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index 1fdb6fe7eb7..31c819abaf5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -1,5 +1,6 @@ [% USE raw %] [% USE Asset %] +[% USE ItemTypes %] [% USE Koha %] [% USE KohaDates %] [% USE KohaPlugins %] @@ -402,9 +403,9 @@ [% SET itemtype = item.itemtype %] [% IF !noItemTypeImages && itemtype.image_location('intranet') %] - [% itemtype.translated_description | html %] + [% ItemTypes.t(itemtype.description) | html %] [% END %] - [% itemtype.translated_description | html %] + [% ItemTypes.t(item.description) | html %] [% END %] [% UNLESS ( singlebranchmode ) %][% Branches.GetName( item.holdingbranch ) | html %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt index ba14d8f2d93..3ada0cc7d61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt @@ -1,6 +1,7 @@ [% USE raw %] [% USE HtmlTags %] [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] [% PROCESS 'i18n.inc' %] @@ -88,9 +89,9 @@ [% FOREACH it IN itypes %] [% IF it.itemtype == course_item.itype %] - + [% ELSE %] - + [% END %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/batch_add_items.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/batch_add_items.tt index eb4e674a247..5b213a3c110 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/batch_add_items.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/batch_add_items.tt @@ -57,7 +57,7 @@ [% FOREACH it IN ItemTypes.Get() %] - + [% END %]
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/acquisitions_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/acquisitions_stats.tt index 557507594a7..cc103edfb72 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/acquisitions_stats.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/acquisitions_stats.tt @@ -1,4 +1,5 @@ [% USE raw %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] [% IF ( do_it ) %]Acquisitions statistics › Results[% ELSE %]Acquisitions statistics[% END %] › Reports › Koha @@ -213,7 +214,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/bor_issues_top.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/bor_issues_top.tt index 9c0fcdfac1a..b4990889075 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/bor_issues_top.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/bor_issues_top.tt @@ -139,7 +139,7 @@
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/cat_issues_top.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/cat_issues_top.tt index f8d08f3b039..16014bf81ed 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/cat_issues_top.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/cat_issues_top.tt @@ -1,4 +1,5 @@ [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] Most-circulated items[% IF ( do_it ) %] › Results[% END %] › Reports › Koha @@ -117,7 +118,7 @@
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_out.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_out.tt index bd43607fe34..c13c5330506 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_out.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_out.tt @@ -169,7 +169,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_stats.tt index 5884eb6f782..32dbffa5491 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_stats.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_stats.tt @@ -1,4 +1,5 @@ [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] [% IF ( do_it ) %]Catalog statistics › Results[% ELSE %]Catalog statistics[% END %] › Reports › Koha @@ -137,7 +138,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_avg_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_avg_stats.tt index c34667db641..5f2447887b5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_avg_stats.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_avg_stats.tt @@ -1,4 +1,5 @@ [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] Average loan time › Reports › Koha @@ -173,7 +174,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt index 57f62314a5c..c6b7095a0e4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt @@ -1,4 +1,5 @@ [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] Circulation statistics[% IF ( do_it ) %] › Results[% END %] › Reports › Koha @@ -198,7 +199,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt index 7251adb3976..0c34d76114f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt @@ -158,7 +158,7 @@
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tt index f7f3023a389..52ebc49495c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tt @@ -1,4 +1,5 @@ [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] Holds statistics[% IF ( do_it ) %] › Results[% END %] › Reports › Koha @@ -201,7 +202,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt index e6918de53f7..fd52871f488 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt @@ -1,6 +1,7 @@ [% USE raw %] [% USE To %] [% USE Asset %] +[% USE ItemTypes %] [% USE KohaDates %] [% USE Branches %] [% USE Koha %] @@ -227,9 +228,9 @@ fieldset.rows table { clear: none; margin: 0; } [% FOREACH type IN typeloop %] [% IF ( type.selected ) %] - + [% ELSE %] - + [% END %] [% END %] @@ -241,9 +242,9 @@ fieldset.rows table { clear: none; margin: 0; } [% FOREACH previous IN previoustypeloop %] [% IF ( previous.selected ) %] - + [% ELSE %] - + [% END %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-batchedit.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-batchedit.tt index 6b38351a52e..f3868da1856 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-batchedit.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-batchedit.tt @@ -122,7 +122,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-bib-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-bib-search.tt index b1557da4a55..7b87cc75d2c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-bib-search.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-bib-search.tt @@ -1,3 +1,4 @@ +[% USE ItemTypes %] [% INCLUDE 'doc-head-open.inc' %] Catalog search › Serials › Koha [% INCLUDE 'doc-head-close.inc' %] @@ -25,7 +26,7 @@ [%- FOREACH itemtypeloo IN itemtypeloop %] [%- END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt index 3f2a384aee5..0b832bd2502 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt @@ -1,6 +1,7 @@ [% USE raw %] [% USE Asset %] [% USE Branches %] +[% USE ItemTypes %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] Export data › Cataloging › Koha @@ -87,7 +88,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt index 09ec20c8211..0c679e3ce9c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt @@ -1,5 +1,6 @@ [% USE raw %] [% USE Asset %] +[% USE ItemTypes %] [% USE Koha %] [% USE KohaDates %] [% USE AuthorisedValues %] @@ -331,9 +332,9 @@ [% UNLESS ( item_level_itypes ) %] [% UNLESS ( noItemTypeImages || !itemsloo.imageurl ) %] - [% itemsloo.description | html %] + [% ItemTypes.t(itemsloo.description) | html %] [% END %] - [% itemsloo.description | html %] + [% ItemTypes.t(itemsloo.description) | html %] [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-topissues.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-topissues.inc index 2deef2e69b0..d6a52e51b2c 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-topissues.inc +++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-topissues.inc @@ -1,3 +1,4 @@ +[% USE ItemTypes %] [% USE Koha %] [% USE Branches %] [% PROCESS 'html_helpers.inc' %] @@ -37,7 +38,7 @@ [% ELSE %] [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-readingrecord.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-readingrecord.tt index 52140ce12d9..66d9c7c1c9a 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-readingrecord.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-readingrecord.tt @@ -1,4 +1,5 @@ [% USE raw %] +[% USE ItemTypes %] [% USE Koha %] [% USE KohaDates %] [% USE TablesSettings %] @@ -168,7 +169,7 @@ [% END %] [% END %] Item type: - [% issue.translated_description | html %] + [% ItemTypes.t(issue.description) | html %] Call number: [% issue.itemcallnumber | html %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt index 9a6a452a089..031f7bf4bbb 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt @@ -232,7 +232,7 @@
  • Item type: [% IF ( bibitemloo.imageurl ) %][% END %] - [% bibitemloo.translated_description | html %] + [% ItemTypes.t(bibitemloo.description) | html %]
  • [% END %] @@ -421,7 +421,7 @@ [% END %] [% END %] - [% itemLoo.translated_description | html %] + [% ItemTypes.t(itemLoo.description) | html %] [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt index 627e9373b0d..16b2b52d2d6 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt @@ -1,5 +1,6 @@ [% USE raw %] [% USE Asset %] +[% USE ItemTypes %] [% USE Koha %] [% USE AdditionalContents %] [% SET OpacNav = AdditionalContents.get( location => "OpacNav", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %] @@ -397,9 +398,9 @@ [% UNLESS ( item_level_itypes ) %] [% UNLESS ( Koha.Preference('OpacNoItemTypeImages') ) %] - [% itemsloo.description | html %] + [% ItemTypes.t(itemsloo.description) | html %] [% END %] - [% itemsloo.description | html %] + [% ItemTypes.t(itemsloo.description) | html %] [% END %] diff --git a/labels/label-item-search.pl b/labels/label-item-search.pl index 4dba30276d6..04313db5434 100755 --- a/labels/label-item-search.pl +++ b/labels/label-item-search.pl @@ -206,20 +206,7 @@ else { flagsrequired => { catalogue => 1 }, } ); - my $itemtypes = Koha::ItemTypes->search; - my @itemtypeloop; - while ( my $itemtype = $itemtypes->next ) { - # FIXME This must be improved: - # - pass the iterator to the template - # - display the translated_description - my %row = ( - value => $itemtype->itemtype, - description => $itemtype->description, - ); - push @itemtypeloop, \%row; - } $template->param( - itemtypeloop => \@itemtypeloop, batch_id => $batch_id, type => $type, ); diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 98c4f94a8cb..b5a83f40f8c 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -71,6 +71,7 @@ use Koha::Biblios; use Koha::RecordProcessor; use Koha::AuthorisedValues; use Koha::CirculationRules; +use Koha::I18N; use Koha::Items; use Koha::ItemTypes; use Koha::Acquisition::Orders; @@ -232,7 +233,7 @@ if ($session->param('busc')) { { my ($arrParamsBusc, $offset, $results_per_page, $patron) = @_; - my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; my @servers; @servers = @{$arrParamsBusc->{'server'}} if $arrParamsBusc->{'server'}; @servers = ("biblioserver") unless (@servers); @@ -507,12 +508,12 @@ my $HideMARC = $record_processor->filters->[0]->should_hide_marc( interface => 'opac', } ); -my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; # imageurl: my $itemtype = $dat->{'itemtype'}; if ( $itemtype ) { $dat->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{$itemtype}->{'imageurl'} ); - $dat->{'description'} = $itemtypes->{$itemtype}->{translated_description}; + $dat->{'description'} = db_t('itemtype', $itemtypes->{$itemtype}->{description}); } my $shelflocations = @@ -708,7 +709,7 @@ else { $item_info->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{ $itemtype->itemtype }->{'imageurl'} ); $item_info->{'description'} = - $itemtypes->{ $itemtype->itemtype }->{translated_description}; + db_t('itemtype', $itemtypes->{ $itemtype->itemtype }->{description}); foreach my $field ( qw(ccode materials enumchron copynumber itemnotes location_description uri) diff --git a/opac/opac-readingrecord.pl b/opac/opac-readingrecord.pl index 55981483e98..f0d2a12a2a4 100755 --- a/opac/opac-readingrecord.pl +++ b/opac/opac-readingrecord.pl @@ -54,7 +54,7 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); -my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; # get the record my $order = $query->param('order') || ''; @@ -83,8 +83,7 @@ my $opac_summary_html = C4::Context->preference('OPACMySummaryHTML'); foreach my $issue ( @{$issues} ) { $issue->{normalized_isbn} = GetNormalizedISBN( $issue->{isbn} ); if ( $issue->{$itype_attribute} ) { - $issue->{translated_description} = - $itemtypes->{ $issue->{$itype_attribute} }->{translated_description}; + $issue->{description} = $itemtypes->{ $issue->{$itype_attribute} }->{description}; $issue->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes->{ $issue->{$itype_attribute} }->{imageurl} ); diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 07440efa6af..981b81c3ded 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -72,7 +72,7 @@ unless ( $can_place_hold_if_available_at_pickup ) { } } -my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; # There are two ways of calling this script, with a single biblio num # or multiple biblio nums. @@ -413,12 +413,11 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{object} = $biblio; if (!$itemLevelTypes && $biblioData->{itemtype}) { - $biblioLoopIter{translated_description} = $itemtypes->{$biblioData->{itemtype}}{translated_description}; + $biblioLoopIter{description} = $itemtypes->{$biblioData->{itemtype}}{description}; $biblioLoopIter{imageurl} = getitemtypeimagesrc() . "/". $itemtypes->{$biblioData->{itemtype}}{imageurl}; } - $biblioLoopIter{itemLoop} = []; my $numCopiesAvailable = 0; my $numCopiesOPACAvailable = 0; @@ -437,8 +436,8 @@ foreach my $biblioNum (@biblionumbers) { my $itemtype = $item->itemtype; $item_info->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{ $itemtype->itemtype }->{'imageurl'} ); - $item_info->{'translated_description'} = - $itemtypes->{ $itemtype->itemtype }->{translated_description}; + $item_info->{'description'} = + db_t('itemtype', $itemtypes->{ $itemtype->itemtype }->{description}); } # checking for holds diff --git a/opac/opac-search.pl b/opac/opac-search.pl index 65904676d15..3e26bf07e73 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -57,6 +57,7 @@ use C4::External::BakerTaylor qw( image_url link_url ); use Koha::CirculationRules; use Koha::Libraries; +use Koha::I18N; use Koha::ItemTypes; use Koha::Ratings; use Koha::Virtualshelves; @@ -234,14 +235,13 @@ $template->param(search_languages_loop => $languages_limit_loop,); # load the Type stuff my $itemtypes = GetItemTypesCategorized; -# add translated_description to itemtypes foreach my $itemtype ( keys %{$itemtypes} ) { # Itemtypes search categories don't have (yet) translated descriptions, they are auth values (and could still have no descriptions too BZ 18400) # If 'iscat' (see ITEMTYPECAT) then there is no itemtype and the description is not translated - my $translated_description = $itemtypes->{$itemtype}->{iscat} + my $description = $itemtypes->{$itemtype}->{iscat} ? $itemtypes->{$itemtype}->{description} - : Koha::ItemTypes->find($itemtype)->translated_description; - $itemtypes->{$itemtype}->{translated_description} = $translated_description || $itemtypes->{$itemtype}->{description} || q{}; + : db_t('itemtype', Koha::ItemTypes->find($itemtype)->description); + $itemtypes->{$itemtype}->{description} = $description || $itemtypes->{$itemtype}->{description} || q{}; } # the index parameter is different for item-level itemtypes @@ -253,7 +253,7 @@ my @advanced_search_types = split(/\|/, $advanced_search_types); my $hidingrules = C4::Context->yaml_preference('OpacHiddenItems') // {}; -my @sorted_itemtypes = sort { $itemtypes->{$a}->{translated_description} cmp $itemtypes->{$b}->{translated_description} } keys %$itemtypes; +my @sorted_itemtypes = sort { $itemtypes->{$a}->{description} cmp $itemtypes->{$b}->{description} } keys %$itemtypes; foreach my $advanced_srch_type (@advanced_search_types) { $advanced_srch_type =~ s/^\s*//; $advanced_srch_type =~ s/\s*$//; @@ -266,7 +266,7 @@ foreach my $advanced_srch_type (@advanced_search_types) { my %row =( number=>$cnt++, ccl => "$itype_or_itemtype,phr", code => $thisitemtype, - description => $itemtypes->{$thisitemtype}->{translated_description}, + description => $itemtypes->{$thisitemtype}->{description}, imageurl=> getitemtypeimagelocation( 'opac', $itemtypes->{$thisitemtype}->{'imageurl'} ), cat => $itemtypes->{$thisitemtype}->{'iscat'}, hideinopac => $itemtypes->{$thisitemtype}->{'hideinopac'}, @@ -577,7 +577,7 @@ if ($tag) { $pasarParams .= '&count=' . uri_escape_utf8($results_per_page); $pasarParams .= '&simple_query=' . uri_escape_utf8($simple_query); $pasarParams .= '&query_type=' . uri_escape_utf8($query_type) if ($query_type); - my $itemtypes_nocategory = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + my $itemtypes_nocategory = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; eval { ($error, $results_hashref, $facets) = $searcher->search_compat($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,undef,$itemtypes_nocategory,$query_type,$scan,1); }; diff --git a/opac/opac-shelves.pl b/opac/opac-shelves.pl index a7be90ba58b..536d01fcec1 100755 --- a/opac/opac-shelves.pl +++ b/opac/opac-shelves.pl @@ -368,7 +368,7 @@ if ( $op eq 'view' ) { $itemtype = Koha::ItemTypes->find( $itemtype ); if( $itemtype ) { $this_item->{imageurl} = C4::Koha::getitemtypeimagelocation( 'opac', $itemtype->imageurl ); - $this_item->{description} = $itemtype->description; #FIXME Should not it be translated_description? + $this_item->{description} = $itemtype->description; $this_item->{notforloan} = $itemtype->notforloan; } $this_item->{'coins'} = $biblio->get_coins; diff --git a/opac/opac-user.pl b/opac/opac-user.pl index 494f481224d..acb69bede56 100755 --- a/opac/opac-user.pl +++ b/opac/opac-user.pl @@ -192,7 +192,7 @@ my $count = 0; my $overdues_count = 0; my @overdues; my @issuedat; -my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; my $pending_checkouts = $patron->pending_checkouts->search({}, { order_by => [ { -desc => 'date_due' }, { -asc => 'issue_id' } ] }); my $are_renewable_items = 0; if ( $pending_checkouts->count ) { # Useless test diff --git a/reports/acquisitions_stats.pl b/reports/acquisitions_stats.pl index 2c90fe32cca..4ee2073e2c7 100755 --- a/reports/acquisitions_stats.pl +++ b/reports/acquisitions_stats.pl @@ -181,7 +181,7 @@ else { $ccode_avlist = GetAuthorisedValues($ccode_subfield_structure->{authorised_value}); } - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; $template->param( booksellers => $booksellers, itemtypes => $itemtypes, # FIXME Should use the TT plugin instead diff --git a/reports/bor_issues_top.pl b/reports/bor_issues_top.pl index 439db23810f..8b2f2e59340 100755 --- a/reports/bor_issues_top.pl +++ b/reports/bor_issues_top.pl @@ -97,7 +97,7 @@ my @mime = ( map { {type =>$_} } (split /[;:]/, 'CSV') ); # FIXME translation my $delims = GetDelimiterChoices; my $patron_categories = Koha::Patron::Categories->search_with_library_limits({}, {order_by => ['categorycode']}); -my $itemtypes = Koha::ItemTypes->search_with_localization; +my $itemtypes = Koha::ItemTypes->search; $template->param( mimeloop => \@mime, CGIseplist => $delims, diff --git a/reports/cat_issues_top.pl b/reports/cat_issues_top.pl index d3d1e067b99..2cf07002048 100755 --- a/reports/cat_issues_top.pl +++ b/reports/cat_issues_top.pl @@ -98,7 +98,7 @@ if ($do_it) { my $CGIsepChoice=GetDelimiterChoices; #doctype - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; #ccode my $ccodes = GetAuthorisedValues('CCODE'); diff --git a/reports/catalogue_out.pl b/reports/catalogue_out.pl index c03dcb2d803..c49a179c599 100755 --- a/reports/catalogue_out.pl +++ b/reports/catalogue_out.pl @@ -54,7 +54,7 @@ if ($do_it) { exit; # in either case, exit after do_it } -my $itemtypes = Koha::ItemTypes->search_with_localization; +my $itemtypes = Koha::ItemTypes->search; $template->param( itemtypes => $itemtypes, ); diff --git a/reports/catalogue_stats.pl b/reports/catalogue_stats.pl index b4d72a384be..2cc0ba4707c 100755 --- a/reports/catalogue_stats.pl +++ b/reports/catalogue_stats.pl @@ -112,7 +112,7 @@ if ($do_it) { my $dbh = C4::Context->dbh; my $count=0; - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; my @authvals = map { { code => $_->{authorised_value}, description => $_->{lib} } } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.ccode' }, { order_by => ['description'] } ); my @locations = map { { code => $_->{authorised_value}, description => $_->{lib} } } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.location' }, { order_by => ['description'] } ); diff --git a/reports/issues_avg_stats.pl b/reports/issues_avg_stats.pl index e1270c9b7c2..66654e99c74 100755 --- a/reports/issues_avg_stats.pl +++ b/reports/issues_avg_stats.pl @@ -105,7 +105,7 @@ if ($do_it) { } else { my $patron_categories = Koha::Patron::Categories->search({}, {order_by => ['description']}); - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; my $dbh = C4::Context->dbh; my $req = $dbh->prepare("select distinctrow sort1 from borrowers where sort1 is not null order by sort1"); diff --git a/reports/issues_stats.pl b/reports/issues_stats.pl index 52e904ed5f5..f305554735d 100755 --- a/reports/issues_stats.pl +++ b/reports/issues_stats.pl @@ -28,6 +28,7 @@ use C4::Output qw( output_html_with_http_headers ); use C4::Reports qw( GetDelimiterChoices ); use Koha::AuthorisedValues; +use Koha::I18N; use Koha::ItemTypes; use Koha::Patron::Attribute::Types; @@ -74,7 +75,7 @@ our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param(do_it => $do_it, ); -our $itemtypes = Koha::ItemTypes->search_with_localization->unblessed; +our $itemtypes = Koha::ItemTypes->search->unblessed; our @patron_categories = Koha::Patron::Categories->search_with_library_limits({}, {order_by => ['description']})->as_list; @@ -339,7 +340,7 @@ sub calculate { $cell{rowtitle_display} = ( $line =~ /ccode/ ) ? $ccodes->{$celvalue} : ( $line =~ /location/ ) ? $locations->{$celvalue} - : ( $line =~ /itemtype/ ) ? $itemtypes_map->{$celvalue}->{translated_description} + : ( $line =~ /itemtype/ ) ? db_t('itemtype', $itemtypes_map->{$celvalue}->{description}) : $celvalue; # default fallback if ( $line =~ /sort1/ ) { foreach (@$Bsort1) { @@ -428,7 +429,7 @@ sub calculate { $cell{coltitle_display} = ( $column =~ /ccode/ ) ? $ccodes->{$celvalue} : ( $column =~ /location/ ) ? $locations->{$celvalue} - : ( $column =~ /itemtype/ ) ? $itemtypes_map->{$celvalue}->{translated_description} + : ( $column =~ /itemtype/ ) ? db_t('itemtype', $itemtypes_map->{$celvalue}->{description}); : $celvalue; # default fallback if ( $column =~ /sort1/ ) { foreach (@$Bsort1) { diff --git a/reports/itemslost.pl b/reports/itemslost.pl index f9d633251df..50c53615149 100755 --- a/reports/itemslost.pl +++ b/reports/itemslost.pl @@ -149,7 +149,7 @@ if ( $op eq 'export' ) { } # getting all itemtypes -my $itemtypes = Koha::ItemTypes->search_with_localization; +my $itemtypes = Koha::ItemTypes->search; my $csv_profiles = Koha::CsvProfiles->search({ type => 'sql', used_for => 'export_lost_items' }); diff --git a/reports/reserves_stats.pl b/reports/reserves_stats.pl index af4e0ab379f..0f5602b834f 100755 --- a/reports/reserves_stats.pl +++ b/reports/reserves_stats.pl @@ -28,6 +28,7 @@ use C4::Output qw( output_html_with_http_headers ); use C4::Reports qw( GetDelimiterChoices ); use C4::Members; use Koha::AuthorisedValues; +use Koha::I18N; use Koha::ItemTypes; use Koha::Libraries; use Koha::Patron::Categories; @@ -120,7 +121,7 @@ if ($do_it) { my $dbh = C4::Context->dbh; -my $itemtypes = Koha::ItemTypes->search_with_localization; +my $itemtypes = Koha::ItemTypes->search; # location list my @locations; @@ -298,7 +299,7 @@ sub display_value { my $display_value = ( $crit =~ /ccode/ ) ? $ccodes->{$value} : ( $crit =~ /location/ ) ? $locations->{$value} - : ( $crit =~ /itemtype/ ) ? Koha::ItemTypes->find( $value )->translated_description + : ( $crit =~ /itemtype/ ) ? db_t('itemtype', Koha::ItemTypes->find( $value )->description) : ( $crit =~ /branch/ ) ? Koha::Libraries->find($value)->branchname : ( $crit =~ /reservestatus/ ) ? reservestatushuman($value) : $value; # default fallback diff --git a/reserve/request.pl b/reserve/request.pl index fce3a6e5b0b..1f7d21e0ad7 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -71,7 +71,7 @@ my $itemtypes = { map { $_->itemtype => { %{ $_->unblessed }, image_location => $_->image_location('intranet'), notforloan => $_->notforloan } - } Koha::ItemTypes->search_with_localization->as_list + } Koha::ItemTypes->search->as_list }; # Select borrowers infos diff --git a/serials/subscription-add.pl b/serials/subscription-add.pl index c08142b8973..e6d929262cb 100755 --- a/serials/subscription-add.pl +++ b/serials/subscription-add.pl @@ -145,9 +145,8 @@ $template->param( additional_field_values => \%additional_field_values, ); -my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; -# FIXME We should use the translated_description for item types my @typearg = map { { code => $_, value => $typeloop->{$_}{'description'}, selected => ( ( $subs->{itemtype} and $_ eq $subs->{itemtype} ) ? "selected=\"selected\"" : "" ), } } sort keys %{$typeloop}; my @previoustypearg = diff --git a/serials/subscription-bib-search.pl b/serials/subscription-bib-search.pl index 2853404bcb3..52293e8f53d 100755 --- a/serials/subscription-bib-search.pl +++ b/serials/subscription-bib-search.pl @@ -193,10 +193,9 @@ else { ); # load the itemtypes - my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; my @itemtypesloop; # FIXME This is uselessly complex, the iterator should be send to the template - # FIXME The translated_description should be used foreach my $thisitemtype ( sort { $itemtypes->{$a}->{'description'} diff --git a/svc/bib_profile b/svc/bib_profile index 46ebe379635..b459e5743df 100755 --- a/svc/bib_profile +++ b/svc/bib_profile @@ -113,7 +113,7 @@ sub _get_bib_number_tag { sub _get_biblioitem_itemtypes { my $result = shift; - my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; my $sth = $dbh->prepare_cached("SELECT tagfield, tagsubfield FROM marc_subfield_structure WHERE frameworkcode = '' diff --git a/svc/checkouts b/svc/checkouts index b8e84f4704c..aec48d978a3 100755 --- a/svc/checkouts +++ b/svc/checkouts @@ -30,6 +30,7 @@ use C4::Context; use Koha::AuthorisedValues; use Koha::DateUtils qw( dt_from_string output_pref ); use Koha::Items; +use Koha::I18N; use Koha::ItemTypes; my $input = CGI->new; @@ -146,7 +147,7 @@ my $item_level_itypes = C4::Context->preference('item-level_itypes'); my $claims_returned_lost_value = C4::Context->preference('ClaimReturnedLostValue'); my $confirm_parts_required = C4::Context->preference("CircConfirmItemParts"); -my $itemtypes = { map { $_->{itemtype} => $_->{translated_description} } @{ Koha::ItemTypes->search_with_localization->unblessed } }; +my $itemtypes = { map { $_->{itemtype} => db_t('itemtypes', $_->{itemtype}) } @{ Koha::ItemTypes->search->unblessed } }; my @checkouts_today; my @checkouts_previous; diff --git a/svc/holds b/svc/holds index 8043297573a..77e111f6155 100755 --- a/svc/holds +++ b/svc/holds @@ -28,6 +28,7 @@ use C4::Context; use Koha::DateUtils qw( dt_from_string output_pref ); use Koha::Holds; +use Koha::I18N; use Koha::ItemTypes; use Koha::Libraries; @@ -81,7 +82,7 @@ while ( my $h = $holds_rs->next() ) { my $itemtype_limit; if ( $h->itemtype ) { my $itemtype = Koha::ItemTypes->find( $h->itemtype ); - $itemtype_limit = $itemtype->translated_description; + $itemtype_limit = db_t('itemtype', $itemtype->description); } my $libraries = Koha::Libraries->search({}, { order_by => ['branchname'] })->unblessed; diff --git a/svc/localization b/svc/localization index 6eed60632c9..89728576253 100755 --- a/svc/localization +++ b/svc/localization @@ -4,101 +4,82 @@ use Modern::Perl; use Encode qw( encode ); use C4::Service; -use Koha::Localizations; +use Koha::Caches; +use Koha::Database; -our ( $query, $response ) = C4::Service->init( parameters => 'manage_itemtypes' ); +our ( $query, $response ) = C4::Service->init( parameters => 'parameters_remaining_permissions' ); sub get_translations { - my $rs = Koha::Localizations->search({ entity => $query->param('entity'), code => $query->param('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, - } - } - $response->param( translations => \@translations ); - C4::Service->return_success( $response ); -} + my $draw = $query->param('draw'); + my $start = $query->param('start'); + my $length = $query->param('length'); + my $search = $query->param('search[value]'); -sub update_translation { - my $id = $query->param('id'); - my $translation = $query->param('translation'); - my $lang = $query->param('lang'); + my $schema = Koha::Database->new->schema; + my $rs = $schema->resultset('L10nSource'); + my $recordsTotal = $rs->count; - my $localization = Koha::Localizations->find( $id ); - if ( defined $lang and $localization->lang ne $lang ) { - $localization->lang( $lang ) - } - if ( defined $translation and $localization->translation ne $translation ) { - $localization->translation( $translation ) - } - my %params; - my $is_changed; - if ( $localization->is_changed ) { - $is_changed = 1; - unless ( Koha::Localizations->search( { entity => $localization->entity, code => $localization->code, lang => $lang, localization_id => { '!=' => $localization->localization_id }, } )->count ) { - $localization->store; - } else { - $params{error} = 1; - $params{error_code} = 'already_exists'; + my $cond = {}; + if ($search) { + my @and; + my @words = split /\s+/, $search; + foreach my $word (@words) { + push @and, \['source LIKE ? COLLATE utf8mb4_unicode_ci', "%$word%"]; } + $cond->{-and} = \@and; } + + $rs = $rs->search($cond); + my $recordsFiltered = $rs->count; + + my @sources = $rs->search({}, { + prefetch => 'l10n_targets', + result_class => 'DBIx::Class::ResultClass::HashRefInflator', + rows => $length, + offset => $start, + order_by => { -asc => ['context', 'source'] }, + }); + $response->param( - %params, - id => $localization->localization_id, - entity => $localization->entity, - code => $localization->code, - lang => $localization->lang, - translation => $localization->translation, - is_changed => $is_changed, + draw => $draw, + recordsTotal => $recordsTotal, + recordsFiltered => $recordsFiltered, + data => \@sources, ); C4::Service->return_success( $response ); } -sub add_translation { - my $entity = $query->param('entity'); - my $code = $query->param('code'); - my $lang = $query->param('lang'); +sub update_translation { + my $id = $query->param('id'); my $translation = $query->param('translation'); + my $lang = $query->param('lang'); - unless ( Koha::Localizations->search({entity => $entity, code => $code, lang => $lang, })->count ) { - my $localization = Koha::Localization->new( - { - entity => $entity, - code => $code, - lang => $lang, - translation => $translation, - } - ); - $localization->store; - $response->param( - id => $localization->localization_id, - entity => $localization->entity, - code => $localization->code, - lang => $localization->lang, - translation => $localization->translation, - ); + my $schema = Koha::Database->new->schema; + my $rs = $schema->resultset('L10nTarget'); + if (defined $translation && $translation ne '') { + $rs->update_or_create({ + l10n_source_id => $id, + language => $lang, + translation => $translation, + }, { + key => 'l10n_source_language', + }); } else { - $response->param( error => 1, error_code => 'already_exists', ); + $rs->search({ + l10n_source_id => $id, + language => $lang, + })->delete; } - C4::Service->return_success( $response ); -} -sub delete_translation { - my $id = $query->param('id'); - Koha::Localizations->find($id)->delete; - $response->param( id => $id ); + my $source = $schema->resultset('L10nSource')->find($id); + my $cache_key = sprintf('%s:%s', $source->context, $lang); + Koha::Caches->get_instance()->clear_from_cache($cache_key); + C4::Service->return_success( $response ); } C4::Service->dispatch( - [ 'GET /', [ 'id' ], \&get_translations ], + [ 'GET /', [], \&get_translations ], [ 'PUT /', [ 'id' ], \&update_translation ], - [ 'POST /', [ 'entity', 'code', 'lang', 'translation' ], \&add_translation ], - [ 'DELETE /', ['id'], \&delete_translation ], ); diff --git a/t/db_dependent/Koha/ItemTypes.t b/t/db_dependent/Koha/ItemTypes.t index aecd8d971b5..3b3e5c19de5 100755 --- a/t/db_dependent/Koha/ItemTypes.t +++ b/t/db_dependent/Koha/ItemTypes.t @@ -67,31 +67,6 @@ my $child3 = $builder->build_object({ } }); -Koha::Localization->new( - { - entity => 'itemtypes', - code => $child1->itemtype, - lang => 'en', - translation => 'b translated itemtype desc' - } -)->store; -Koha::Localization->new( - { - entity => 'itemtypes', - code => $child2->itemtype, - lang => 'en', - translation => 'a translated itemtype desc' - } -)->store; -Koha::Localization->new( - { - entity => 'something_else', - code => $child2->itemtype, - lang => 'en', - translation => 'another thing' - } -)->store; - my $type = Koha::ItemTypes->find($child1->itemtype); ok( defined($type), 'first result' ); is_deeply( $type->unblessed, $child1->unblessed, "We got back the same object" ); @@ -103,22 +78,11 @@ is_deeply( $type->unblessed, $child2->unblessed, "We got back the same object" ) t::lib::Mocks::mock_preference('language', 'en'); t::lib::Mocks::mock_preference('OPACLanguages', 'en'); -my $itemtypes = Koha::ItemTypes->search_with_localization; +my $itemtypes = Koha::ItemTypes->search; is( $itemtypes->count, $initial_count + 4, 'We added 4 item types' ); -my $first_itemtype = $itemtypes->next; -is( - $first_itemtype->translated_description, - 'a translated itemtype desc', - 'item types should be sorted by translated description' -); - -my $children = $parent1->children_with_localization; -my $first_child = $children->next; -is( - $first_child->translated_description, - 'a translated itemtype desc', - 'item types should be sorted by translated description' -); + +my $children = $parent1->children; +is ($children->count, 3, 'parent type has 3 children'); my $item_type = $builder->build_object({ class => 'Koha::ItemTypes' }); diff --git a/tools/batchMod.pl b/tools/batchMod.pl index 6c252ff8494..d64f8915d5e 100755 --- a/tools/batchMod.pl +++ b/tools/batchMod.pl @@ -31,6 +31,7 @@ use List::MoreUtils qw( uniq ); use Encode qw( encode_utf8 ); use Koha::Database; +use Koha::I18N; use Koha::Exception; use Koha::Biblios; use Koha::Items; diff --git a/tools/export.pl b/tools/export.pl index 345158eedd0..c3809a40dc6 100755 --- a/tools/export.pl +++ b/tools/export.pl @@ -270,7 +270,7 @@ if ( $op eq "export" ) { else { - my $itemtypes = Koha::ItemTypes->search_with_localization; + my $itemtypes = Koha::ItemTypes->search; my $authority_types = Koha::Authority::Types->search( {}, { order_by => ['authtypecode'] } ); diff --git a/virtualshelves/shelves.pl b/virtualshelves/shelves.pl index fa92cfcd6eb..72348d7b97a 100755 --- a/virtualshelves/shelves.pl +++ b/virtualshelves/shelves.pl @@ -307,7 +307,7 @@ if ( $op eq 'view' ) { $this_item->{author} = $biblio->author; $this_item->{dateadded} = $content->dateadded; $this_item->{imageurl} = $itemtype ? C4::Koha::getitemtypeimagelocation( 'intranet', $itemtype->imageurl ) : q{}; - $this_item->{description} = $itemtype ? $itemtype->description : q{}; #FIXME Should this be translated_description ? + $this_item->{description} = $itemtype ? $itemtype->description : q{}; $this_item->{notforloan} = $itemtype->notforloan if $itemtype; $this_item->{'coins'} = $biblio->get_coins; $this_item->{'normalized_upc'} = GetNormalizedUPC( $record, $marcflavour ); -- 2.25.1