Bugzilla – Attachment 149941 Details for
Bug 24975
Refactor database translations
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24975: Refactor database translations
Bug-24975-Refactor-database-translations.patch (text/plain), 126.61 KB, created by
Jonathan Druart
on 2023-04-20 12:44:18 UTC
(
hide
)
Description:
Bug 24975: Refactor database translations
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2023-04-20 12:44:18 UTC
Size:
126.61 KB
patch
obsolete
>From 0f94572e013a336eabbddddecf6af7fabd64777f Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >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 <martin.renvoize@ptfs-europe.com> >--- > 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 <http://www.gnu.org/licenses>. >- >-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<delete> 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 <http://www.gnu.org/licenses>. >- >-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 ) %] > <li><a href="/cgi-bin/koha/admin/adveditorshortcuts.pl">Keyboard shortcuts</a></li> > [% END %] >+ <li><a href="/cgi-bin/koha/admin/localization.pl">Localization</a></li> > </ul> > [% END %] > </div> >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 %] > <option value="[% itemtype.itemtype | html %]"> > [% END %] >- [% itemtype.translated_description | html %] >+ [% ItemTypes.t(itemtype.description) | html %] > </option> > [% 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 @@ > <dt><a href="/cgi-bin/koha/admin/adveditorshortcuts.pl">Keyboard shortcuts</a></dt> > <dd>Define which keys trigger actions in the advanced cataloging editor</dd> > [% END %] >+ >+ <dt><a href="/cgi-bin/koha/admin/localization.pl">Localization</a></dt> >+ <dd>Translate user-defined strings</dd> > </dl> > [% END %] > </div> >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 > <li> > <label for="description" class="required">Description: </label> > <input type="text" id="description" name="description" size="48" value="[% itemtype.description | html %]" required="required" /> <span class="required">Required</span> >- [% IF can_be_translated %] >- <a href="/cgi-bin/koha/admin/localization.pl?entity=itemtypes&code=[% itemtype.itemtype | uri %]" title="Translate item type [% itemtype.itemtype | html %]" rel="gb_page_center[600,500]"><i class="fa fa-pencil"></i> Translate into other languages</a> >- [% END %] > </li> > <li> > <label for="searchcategory">Search category: </label> >@@ -426,7 +424,7 @@ Item types › Administration › Koha > <th scope="row">Item type</th> > <td>[% itemtype.itemtype | html %]</td> > </tr> >- <tr><th scope="row">Description</th><td>[% itemtype.translated_description | html %]</td></tr> >+ <tr><th scope="row">Description</th><td>[% ItemTypes.t(itemtype.description) | html %]</td></tr> > [% UNLESS Koha.Preference('noItemTypeImages') && Koha.Preference('OpacNoItemTypeImages') %] > <tr> > <th scope="row">Image</th> >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' %] > <title>Localization › Koha</title> >-[% INCLUDE 'doc-head-close.inc' popup => 1 %] >-<style>#localization { margin-top: 1em; }</style> >+[% INCLUDE 'doc-head-close.inc' %] >+<style> >+ #localization { margin-top: 1em; } >+ >+ .add-translation-block { >+ margin-bottom: 5px; >+ } >+ >+ .add-translation-block form { >+ display: inline-flex; >+ align-items: center; >+ } >+ code { >+ background-color: lightgrey; >+ font-weight: bold; >+ display: inline-block; >+ padding: 2px 4px; >+ } >+</style> > </head> > > <body id="admin_localization" class="admin"> >- <div class="container-fluid"> >- <div class="row"> >- <div class="col-sm-12"> >- <h1>Localization</h1> >-<form id="add_translation" method="post"> >- <input type="hidden" name="entity" value="[% entity | html %]" /> >- <input type="hidden" name="code" value="[% code | html %]" /> >- <input type="hidden" name="interface" value="[% interface_side | html %]" /> >- <fieldset class="rows clearfix"> >- <ol> >- <li> >- <span class="label">Authorized value:</span> >- [% code | html %] >- </li> >- <li> >- <label for="lang">Language:</label> >- <select name="lang" id="lang"> >- [% FOR language IN languages %] >- [% FOR sublanguage IN language.sublanguages_loop %] >- [% IF language.plural %] >- <option value="[% sublanguage.rfc4646_subtag | html %]">[% sublanguage.native_description | html %] [% sublanguage.region_description | html %] ([% sublanguage.rfc4646_subtag | html %])</option> >- [% ELSE %] >- <option value="[% sublanguage.rfc4646_subtag | html %]">[% sublanguage.native_description | html %] ([% sublanguage.rfc4646_subtag | html %])</option> >- [% END %] >- [% END %] >- [% END %] >- </select> >- </li> >- <li> >- <label for="translation">Translation:</label> >- <input type="text" size="40" name="translation" id="translation" /> >- </li> >- <li> >- <span class="label"> </span> >- <input type="submit" class="btn btn-primary" value="Add" /> >- </li> >- </ol> >- </fieldset> >-</form> >- </div> <!-- /.col-sm-12 --> >- </div> <!-- /.row --> >+ [% INCLUDE 'header.inc' %] >+ [% INCLUDE 'prefs-admin-search.inc' %] > >- <div class="row"> >- <div class="col-sm-12"> >-<div id="messages"></div> >- </div> <!-- /.col-sm-12 --> >- </div> <!-- /.row --> >+ <div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › >+ <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> >+ › >+ Localization >+ </div> >+ >+ <div class="main container-fluid"> > > <div class="row"> >- <div class="col-sm-12"> >-<table id="localization"> >- <thead> >- <tr> >- <th>Id</th> >- <th>Entity</th> >- <th>Code</th> >- <th>Language</th> >- <th>Translation</th> >- <th class="NoSort"> </th> >- </tr> >- </thead> >- <tbody> >- [% FOR t IN translations %] >- <tr id="row_id_[% t.id | html %]" data-id="[% t.id | html %]"> >- <td>[% t.id | html %]</td> >- <td>[% t.entity | html %]</td> >- <td>[% t.code | html %]</td> >- <td class="lang">[% t.lang | html %]</td> >- <td class="translation" contenteditable="true">[% t.translation | html %]</td> >- <td class="actions"><a href="#" class="delete"><i class="fa fa-trash"></i> Delete</a></td> >- </tr> >- [% END %] >- </tbody> >-</table> >- </div> <!-- /.col-sm-12 --> >- </div> <!-- /.row --> >- </div> <!-- /.container-fluid --> >+ <div class="col-sm-10 col-sm-push-2"> >+ <main> >+ <h2>Localization</h2> >+ >+ <table id="localization"> >+ <thead> >+ <tr> >+ <th>Context</th> >+ <th>Source</th> >+ <th>Translations</th> >+ </tr> >+ </thead> >+ <tbody> >+ </tbody> >+ </table> >+ </main> >+ </div> >+ >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'admin-menu.inc' %] >+ </aside> >+ </div> >+ </div> >+ </div> > > [% MACRO jsinclude BLOCK %] > [% INCLUDE 'datatables.inc' %] > <script> > >- function show_message( params ) { >- var type = params.type; >- var data = params.data; >- var messages = $("#messages"); >- var message; >- if ( type == 'success_on_update' ) { >- message = $('<div class="dialog message"></div>'); >- message.text(_("Entity %s (code %s) for lang %s has correctly been updated with '%s'").format(data.entity, data.code, data.lang, data.translation)); >- } else if ( type == 'error_on_update' ) { >- message = $('<div class="dialog alert"></div>'); >- if ( data.error_code == 'already_exists' ) { >- message.text(_("A translation already exists for this language.")); >- } else { >- message.text(_("An error occurred when updating this translation.")); >- } >- } else if ( type == 'success_on_delete' ) { >- message = $('<div class="dialog message"></div>'); >- message.text(_("The translation (id %s) has been removed successfully").format(data.id)); >- } else if ( type == 'error_on_delete' ) { >- message = $('<div class="dialog alert"></div>'); >- message.text(_("An error occurred when deleting this translation")); >- } else if ( type == 'success_on_insert' ) { >- message = $('<div class="dialog message"></div>'); >- message.text(_("Translation (id %s) has been added successfully").format(data.id)); >- } else if ( type == 'error_on_insert' ) { >- message = $('<div class="dialog alert"></div>'); >- if ( data.error_code == 'already_exists' ) { >- message.text(_("A translation already exists for this language.")); >- } else { >- message.text(_("An error occurred when adding this translation")); >- } >- } >- >- $(messages).append(message); >- >- setTimeout(function(){ >- message.hide() >- }, 3000); >- } >- > function send_update_request( data, cell ) { > $.ajax({ > data: data, > type: 'PUT', > url: '/cgi-bin/koha/svc/localization', > success: function (data) { >- if ( data.error ) { >- $(cell).css('background-color', '#FF0000'); >- show_message({ type: 'error_on_update', data: data }); >- } else if ( data.is_changed == 1 ) { >- $(cell).css('background-color', '#00FF00'); >- show_message({ type: 'success_on_update', data: data }); >- } >- >- if ( $(cell).hasClass('lang') ) { >- $(cell).text(data.lang) >- } else if ( $(cell).hasClass('translation') ) { >- $(cell).text(data.translation) >- } >- }, >- error: function (data) { >- $(cell).css('background-color', '#FF9090'); >- if ( $(cell).hasClass('lang') ) { >- $(cell).text(data.lang) >- } else if ( $(cell).hasClass('translation') ) { >- $(cell).text(data.translation) >- } >- show_message({ type: 'error_on_update', data: data }); >- }, >- }); >- } >- >- function send_delete_request( id, cell ) { >- $.ajax({ >- type: 'DELETE', >- url: '/cgi-bin/koha/svc/localization/?id='+id, >- success: function (data) { >- $("#localization").DataTable().row( '#row_id_' + id ).remove().draw(); >- show_message({ type: 'success_on_delete', data: data }); >- }, >- error: function (data) { >- $(cell).css('background-color', '#FF9090'); >- show_message({ type: 'error_on_delete', data: data }); >+ $("#localization").DataTable().draw(false); > }, > }); > } > > $(document).ready(function() { >- $(".dialog").hide(); >- > var table = $("#localization").DataTable($.extend(true, {}, dataTablesDefaults, { >- "dom": 't', >- "columnDefs": [ >- { 'sortable': false, 'targets': [ 'NoSort' ] } >- ], >- 'bPaginate': false, >- 'autoWidth': false, >- })); >- >- var languages_select = $('<select name="lang" id="lang"></select>'); >- [% FOR language IN languages %] >- [% FOR sublanguage IN language.sublanguages_loop %] >- var option; >- [% IF language.plural %] >- option = $('<option value="[% sublanguage.rfc4646_subtag | html %]">[% sublanguage.native_description | html %] [% sublanguage.region_description | html %] ([% sublanguage.rfc4646_subtag | html %])</option>'); >- $(languages_select).append(option); >- [% ELSE %] >- option = $('<option value="[% sublanguage.rfc4646_subtag | html %]">[% sublanguage.native_description | html %] ([% sublanguage.rfc4646_subtag | html %])</option>'); >- [% END %] >- $(languages_select).append(option); >- [% END %] >- [% END %] >- >- $("td.translation").on('focus', function(){ >- $(this).css('background-color', ''); >- }); >- $("td.lang").on('click', function(){ >- var td = this; >- var lang = $(td).text(); >- $(td).css('background-color', ''); >- var my_select = $(languages_select).clone(); >- $(my_select).find('option[value="' + lang + '"]').attr('selected', 'selected'); >- $(my_select).on('click', function(e){ >- e.stopPropagation(); >- }); >- $(my_select).on('change', function(){ >- var tr = $(this).parent().parent(); >- var id = $(tr).data('id'); >- var lang = $(this).find('option:selected').val(); >- var data = "id=" + encodeURIComponent(id) + "&lang=" + encodeURIComponent(lang); >- send_update_request( data, td ); >- }); >- $(my_select).on('blur', function(){ >- $(td).html(lang); >- }); >- $(this).html(my_select); >- }); >- >- $("td.translation").on('blur', function(){ >- var tr = $(this).parent(); >- var id = $(tr).data('id'); >- var translation = $(this).text(); >- var data = "id=" + encodeURIComponent(id) + "&translation=" + encodeURIComponent(translation); >- send_update_request( data, this ); >- }); >- >- $("body").on("click", "a.delete", function(e){ >- e.preventDefault(); >- if ( confirm(_("Are you sure you want to delete this translation?")) ) { >- var td = $(this).parent(); >- var tr = $(td).parent(); >- var id = $(tr).data('id'); >- send_delete_request( id, td ); >- } >- }); >- >- $("#add_translation").on('submit', function(e){ >- e.preventDefault(); >- var entity = $(this).find('input[name="entity"]').val(); >- var code = $(this).find('input[name="code"]').val(); >- var lang = $(this).find('select[name="lang"] option:selected').val(); >- var translation = $(this).find('input[name="translation"]').val(); >- var data = "entity=" + encodeURIComponent(entity) + "&code=" + encodeURIComponent(code) + "&lang=" + encodeURIComponent(lang) + "&translation=" + encodeURIComponent(translation); >- $.ajax({ >- data: data, >- type: 'POST', >+ autoWidth: true, >+ serverSide: true, >+ ordering: false, >+ ajax: { > url: '/cgi-bin/koha/svc/localization', >- success: function (data) { >- if ( data.error ) { >- show_message({ type: 'error_on_insert', data: data }); >- } else { >- var new_row = table.row.add( [ data.id, data.entity, data.code, data.lang, data.translation, "<a href=\"#\" class=\"delete\"><i class=\"fa fa-trash\"></i> Delete</a>" ] ).draw().node(); >- $( new_row ).attr("id", "row_id_" + data.id ).data("id", data.id ); >- show_message({ type: 'success_on_insert', data: data }); >- } >+ }, >+ columns: [ >+ { >+ name: 'context', >+ data: 'context', >+ }, >+ { >+ name: 'source', >+ data: 'source', > }, >- error: function (data) { >- show_message({ type: 'error_on_insert', data: data }); >+ { >+ name: 'targets', >+ data: 'l10n_targets', >+ render: function (data, type, row, meta) { >+ const languages = [% languages.json %]; >+ const translations = Object.fromEntries(data.map(translation => [translation.language, translation])); >+ let output = ''; >+ for (const language of languages) { >+ const div = $('<div>'); >+ div.addClass('add-translation-block'); >+ const languageCode = $('<code>').text(language.rfc4646_subtag); >+ const translationSpan = $('<span>'); >+ if (translations[language.rfc4646_subtag]) { >+ const translation = translations[language.rfc4646_subtag].translation; >+ translationSpan.text(translation); >+ } else { >+ languageCode.html('<del>' + languageCode.text() + '</del>'); >+ } >+ const translateLink = $('<a>'); >+ translateLink.text('Translate'); >+ translateLink.addClass('add-translation'); >+ translateLink.attr('href', '#'); >+ translateLink.attr('data-l10n-source-id', row.l10n_source_id); >+ translateLink.attr('data-language', language.rfc4646_subtag); >+ translateLink.attr('data-source', row.source); >+ if (translations[language.rfc4646_subtag]) { >+ translateLink.attr('data-translation', translations[language.rfc4646_subtag].translation); >+ } >+ >+ div.append(languageCode, ' ', translationSpan, ' ', translateLink); >+ >+ output += ' ' + div[0].outerHTML; >+ } >+ >+ return output; >+ }, > }, >+ ], >+ })); >+ >+ $('#localization').on('click', '.add-translation', function (ev) { >+ ev.preventDefault(); >+ const form = $('<form>'); >+ const textarea = $('<textarea>').attr('rows', '1'); >+ textarea.text(ev.target.getAttribute('data-translation')); >+ form.append(textarea); >+ form.append('<button type="submit">Save</button>'); >+ const l10n_source_id = ev.target.getAttribute('data-l10n-source-id'); >+ const language = ev.target.getAttribute('data-language'); >+ form.on('submit', function (ev) { >+ ev.preventDefault(); >+ send_update_request({ >+ id: l10n_source_id, >+ lang: language, >+ translation: textarea.val(), >+ }); > }); >+ $(ev.target).hide(); >+ $(ev.target).after(form); > }); >- > }); > </script> > [% 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 @@ > <option value="*">All</option> > [% FOREACH itemtypeloo IN itemtypeloop %] > [% NEXT IF itemtypeloo.parent_type %] >- [% SET children = itemtypeloo.children_with_localization %] >+ [% SET children = itemtypeloo.children %] > [% IF children.count %] >- <optgroup label="[% itemtypeloo.translated_description | html %]"> >- <option value="[% itemtypeloo.itemtype | html %]">[% itemtypeloo.translated_description | html %] (All)</option> >+ <optgroup label="[% ItemTypes.t(itemtypeloo.description) | html %]"> >+ <option value="[% itemtypeloo.itemtype | html %]">[% ItemTypes.t(itemtypeloo.description) | html %] (All)</option> > [% FOREACH child IN children %] >- <option value="[% child.itemtype | html %]">[% child.translated_description | html %]</option> >+ <option value="[% child.itemtype | html %]">[% ItemTypes.t(child.description) | html %]</option> > [% END %] > </optgroup> > [% ELSE %] >- <option value="[% itemtypeloo.itemtype | html %]">[% itemtypeloo.translated_description | html %]</option> >+ <option value="[% itemtypeloo.itemtype | html %]">[% ItemTypes.t(itemtypeloo.description) | html %]</option> > [% END %] > [% END %] > </select> >@@ -1285,7 +1285,7 @@ > [% IF holdallowed || hold_fulfillment_policy || returnbranch %] > <tr> > <td> >- [% i.translated_description | html %] >+ [% ItemTypes.t(i.description) | html %] > </td> > <td> > [% IF holdallowed == 'from_any_library' %] >@@ -1330,7 +1330,7 @@ > <td> > <select name="itemtype"> > [% FOREACH itemtypeloo IN itemtypeloop %] >- <option value="[% itemtypeloo.itemtype | html %]">[% itemtypeloo.translated_description | html %]</option> >+ <option value="[% itemtypeloo.itemtype | html %]">[% ItemTypes.t(itemtypeloo.description) | html %]</option> > [% END %] > </select> > </td> >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 %] >- <span class="itypetext">[% itemtypeloo.description | html %]</span> >+ <span class="itypetext">[% ItemTypes.t(itemtypeloo.description) | html %]</span> > </label> > </td> > [% 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 @@ > <td class="itype"> > [% SET itemtype = item.itemtype %] > [% IF !noItemTypeImages && itemtype.image_location('intranet') %] >- <img src="[% itemtype.image_location('intranet') | html %]" alt="[% itemtype.translated_description | html %]" title="[% itemtype.translated_description | html %]" /> >+ <img src="[% itemtype.image_location('intranet') | html %]" alt="[% ItemTypes.t(itemtype.description) | html %]" title="[% ItemTypes.t(itemtype.description) | html %]" /> > [% END %] >- <span class="itypedesc itypetext">[% itemtype.translated_description | html %]</span> >+ <span class="itypedesc itypetext">[% ItemTypes.t(item.description) | html %]</span> > </td> > [% END %] > <td class="location">[% UNLESS ( singlebranchmode ) %][% Branches.GetName( item.holdingbranch ) | html %] [% END %]</td> >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 @@ > <option value=""></option> > [% FOREACH it IN itypes %] > [% IF it.itemtype == course_item.itype %] >- <option value="[% it.itemtype | html %]" selected="selected">[% it.description | html %]</option> >+ <option value="[% it.itemtype | html %]" selected="selected">[% ItemTypes.t(it.description) | html %]</option> > [% ELSE %] >- <option value="[% it.itemtype | html %]">[% it.description | html %]</option> >+ <option value="[% it.itemtype | html %]">[% ItemTypes.t(it.description) | html %]</option> > [% END %] > [% END %] > </select> >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 @@ > <option value=""></option> > > [% FOREACH it IN ItemTypes.Get() %] >- <option value="[% it.itemtype | html %]">[% it.description | html %]</option> >+ <option value="[% it.itemtype | html %]">[% ItemTypes.t(it.description) | html %]</option> > [% END %] > </select> > </li> >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' %] > <title>[% IF ( do_it ) %]Acquisitions statistics › Results[% ELSE %]Acquisitions statistics[% END %] › Reports › Koha</title> >@@ -213,7 +214,7 @@ > <select name="Filter" id="itemtypes"> > <option value="">All item types</option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </td> >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 @@ > <li> > <label for="documenttype">Item type: </label><select name="Filter" id="documenttype"><option value="" > Any item type</option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]" >[% itemtype.translated_description | html %] </option> >+ <option value="[% itemtype.itemtype | html %]" >[% ItemTypes.t(itemtype.description) | html %] </option> > [% END %] > </select> > </li> >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' %] > <title>Most-circulated items[% IF ( do_it ) %] › Results[% END %] › Reports › Koha</title> >@@ -117,7 +118,7 @@ > <li> > <label for="documenttype">Item type: </label><select name="Filter" id="documenttype"><option value="" > Any item type</option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]" >[% itemtype.translated_description | html %] </option> >+ <option value="[% itemtype.itemtype | html %]" >[% ItemTypes.t(itemtype.description) | html %] </option> > [% END %] > </select> > </li> >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 @@ > <select name="Filter" id="documenttype"> > <option value="">Any item type</option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </li> >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' %] > <title>[% IF ( do_it ) %]Catalog statistics › Results[% ELSE %]Catalog statistics[% END %] › Reports › Koha</title> >@@ -137,7 +138,7 @@ > <td><select name="Filter" id="[% item_itype | html %]"> > <option value=""> </option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </td> >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' %] > <title>Average loan time › Reports › Koha</title> >@@ -173,7 +174,7 @@ > <select name="Filter" id="itemtypes"> > <option value=""></option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[%- itemtype.itemtype | html -%]">[%- itemtype.translated_description | html -%]</option> >+ <option value="[%- itemtype.itemtype | html -%]">[%- ItemTypes.t(itemtype.description) | html -%]</option> > [% END %] > </select> > </td> >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' %] > <title>Circulation statistics[% IF ( do_it ) %] › Results[% END %] › Reports › Koha</title> >@@ -198,7 +199,7 @@ > <td><select name="Filter" id="itemtype"> > <option value=""> </option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </td> >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 @@ > <li><label for="itemtypesfilter">Item type: </label><select name="itemtypesfilter" id="itemtypesfilter"> > <option value="">All</option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select></li> > >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' %] > <title>Holds statistics[% IF ( do_it ) %] › Results[% END %] › Reports › Koha</title> >@@ -201,7 +202,7 @@ > <td><select name="filter_items.itype" id="itype"> > <option value=""> </option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </td> >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; } > <option value=""></option> > [% FOREACH type IN typeloop %] > [% IF ( type.selected ) %] >- <option value="[% type.code | html %]" selected="selected">[% type.value | html %]</option> >+ <option value="[% type.code | html %]" selected="selected">[% ItemTypes.t(type.value) | html %]</option> > [% ELSE %] >- <option value="[% type.code | html %]">[% type.value | html %]</option> >+ <option value="[% type.code | html %]">[% ItemTypes.t(type.value) | html %]</option> > [% END %] > [% END %] > </select> >@@ -241,9 +242,9 @@ fieldset.rows table { clear: none; margin: 0; } > <option value=""></option> > [% FOREACH previous IN previoustypeloop %] > [% IF ( previous.selected ) %] >- <option value="[% previous.code | html %]" selected="selected">[% previous.value | html %]</option> >+ <option value="[% previous.code | html %]" selected="selected">[% ItemTypes.t(previous.value) | html %]</option> > [% ELSE %] >- <option value="[% previous.code | html %]">[% previous.value | html %]</option> >+ <option value="[% previous.code | html %]">[% ItemTypes.t(previous.value) | html %]</option> > [% END %] > [% END %] > </select> >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 @@ > <select id="itemtype" name="itemtype"> > <option value="">No change</option> > [% FOREACH itemtype IN ItemTypes.Get() %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </li> >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' %] > <title>Catalog search › Serials › Koha</title> > [% INCLUDE 'doc-head-close.inc' %] >@@ -25,7 +26,7 @@ > <option value="">All</option> > [%- FOREACH itemtypeloo IN itemtypeloop %] > <option value="[% itemtypeloo.code | html %]"> >- [% itemtypeloo.description | html %] >+ [% ItemTypes.t(itemtypeloo.description) | html %] > </option> > [%- END %] > </select> >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' %] > <title>Export data › Cataloging › Koha</title> >@@ -87,7 +88,7 @@ > <select name="itemtype" id="itemtype" multiple> > <option value="">-- All --</option> > [% FOREACH itemtype IN itemtypes %] >- <option value="[% itemtype.itemtype | html %]">[% itemtype.translated_description | html %]</option> >+ <option value="[% itemtype.itemtype | html %]">[% ItemTypes.t(itemtype.description) | html %]</option> > [% END %] > </select> > </li> >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 ) %] > <td> > [% UNLESS ( noItemTypeImages || !itemsloo.imageurl ) %] >- <img src="[% itemsloo.imageurl | html %]" alt="[% itemsloo.description | html %]" title="[% itemsloo.description | html %]" /> >+ <img src="[% itemsloo.imageurl | html %]" alt="[% ItemTypes.t(itemsloo.description) | html %]" title="[% ItemTypes.t(itemsloo.description) | html %]" /> > [% END %] >- <span class="itypetext">[% itemsloo.description | html %]</span> >+ <span class="itypetext">[% ItemTypes.t(itemsloo.description) | html %]</span> > </td> > [% END %] > <td> >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 %] > <option value="[% itemtype.itemtype | html %]"> > [% END %] >- [% itemtype.translated_description | html %] >+ [% ItemTypes.t(itemtype.description) | html %] > </option> > [% END %] > </select> >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 %] > <span class="itypetext"><span class="tdlabel">Item type:</span> >- [% issue.translated_description | html %]</span></td> >+ [% ItemTypes.t(issue.description) | html %]</span></td> > <td> > <span class="tdlabel">Call number:</span> > [% 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 @@ > <li class="itype"> > <span class="label">Item type: </span> > [% IF ( bibitemloo.imageurl ) %]<img src="[% bibitemloo.imageurl | html %]" alt="" />[% END %] >- <span class="itypetext">[% bibitemloo.translated_description | html %]</span> >+ <span class="itypetext">[% ItemTypes.t(bibitemloo.description) | html %]</span> > </li> > [% END %] > >@@ -421,7 +421,7 @@ > <img src="[% itemLoo.imageurl | html %]" alt="" /> > [% END %] > [% END %] >- <span class="itypetext">[% itemLoo.translated_description | html %]</span> >+ <span class="itypetext">[% ItemTypes.t(itemLoo.description) | html %]</span> > </td> > [% 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 ) %] > <td> > [% UNLESS ( Koha.Preference('OpacNoItemTypeImages') ) %] >- <img src="[% itemsloo.imageurl | html %]" alt="[% itemsloo.description | html %]" title="[% itemsloo.description | html %]" /> >+ <img src="[% itemsloo.imageurl | html %]" alt="[% ItemTypes.t(itemsloo.description) | html %]" title="[% ItemTypes.t(itemsloo.description) | html %]" /> > [% END %] >- <span class="itypetext">[% itemsloo.description | html %]</span> >+ <span class="itypetext">[% ItemTypes.t(itemsloo.description) | html %]</span> > </td> > [% END %] > <td> >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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 24975
:
101703
|
101786
|
102387
|
102388
|
102513
|
102514
|
102688
|
102701
|
132388
|
132508
|
132509
|
132510
|
132511
|
132512
|
132513
|
132514
|
132515
|
132516
|
132517
|
132518
|
132519
|
132520
|
132521
|
132522
|
132523
|
132524
|
132525
|
132526
|
132527
|
132528
|
132529
|
132530
|
132531
|
132532
|
132533
|
132546
|
132562
|
132563
|
132564
|
132565
|
132566
|
132567
|
132568
|
132569
|
132570
|
132571
|
132572
|
132573
|
132574
|
132575
| 149941 |
149942
|
149943
|
149944
|
149945
|
149946
|
149947
|
149948
|
149949
|
149950
|
149951
|
149952
|
149953
|
149954
|
149956
|
149957
|
150015
|
150033
|
150034