Bugzilla – Attachment 102513 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), 132.56 KB, created by
Jonathan Druart
on 2020-04-07 12:37:13 UTC
(
hide
)
Description:
Bug 24975: Refactor database translations
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2020-04-07 12:37:13 UTC
Size:
132.56 KB
patch
obsolete
>From 44aa930b5729779d63655bc48a6eebc476a31c9f 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 | 11 +- > C4/Search.pm | 11 +- > Koha/DBIx/Component/L10nSource.pm | 73 ++++ > Koha/I18N.pm | 49 +++ > Koha/ItemType.pm | 45 --- > Koha/ItemTypes.pm | 31 -- > Koha/Localization.pm | 28 -- > Koha/Localizations.pm | 34 -- > Koha/Schema/Result/Itemtype.pm | 54 ++- > Koha/Schema/Result/ItemtypeLocalization.pm | 32 -- > Koha/Schema/Result/Localization.pm | 106 ----- > Koha/Template/Plugin/ItemTypes.pm | 11 +- > acqui/orderreceive.pl | 3 +- > admin/itemtypes.pl | 3 - > admin/localization.pl | 20 - > admin/smart-rules.pl | 32 +- > authorities/authorities.pl | 5 +- > catalogue/getitem-ajax.pl | 3 +- > catalogue/itemsearch.pl | 3 +- > catalogue/moredetail.pl | 7 +- > catalogue/search.pl | 31 +- > cataloguing/addbiblio.pl | 5 +- > cataloguing/additem.pl | 7 +- > circ/transferstoreceive.pl | 3 +- > course_reserves/add_items.pl | 2 +- > .../data/mysql/atomicupdate/bug-24975.perl | 48 +++ > installer/data/mysql/kohastructure.sql | 33 +- > .../prog/en/includes/admin-menu.inc | 1 + > .../prog/en/includes/html_helpers.inc | 3 +- > .../prog/en/modules/admin/admin-home.tt | 5 + > .../prog/en/modules/admin/itemtypes.tt | 20 +- > .../prog/en/modules/admin/localization.tt | 369 ++++++------------ > .../prog/en/modules/admin/smart-rules.tt | 6 +- > .../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 | 3 +- > .../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 | 3 +- > .../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 | 8 +- > 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 | 7 +- > svc/holds | 3 +- > svc/localization | 129 +++--- > svc/split_callnumbers | 72 ---- > t/db_dependent/Koha/ItemTypes.t | 35 +- > tools/batchMod.pl | 5 +- > tools/export.pl | 2 +- > virtualshelves/shelves.pl | 2 +- > 84 files changed, 586 insertions(+), 930 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 > delete mode 100644 Koha/Schema/Result/Localization.pm > create mode 100644 installer/data/mysql/atomicupdate/bug-24975.perl > >diff --git a/C4/Biblio.pm b/C4/Biblio.pm >index d8a96a6062..2244e25e78 100644 >--- a/C4/Biblio.pm >+++ b/C4/Biblio.pm >@@ -101,6 +101,7 @@ use Koha::Authority::Types; > use Koha::Acquisition::Currencies; > use Koha::Biblio::Metadatas; > use Koha::Holds; >+use Koha::I18N; > use Koha::ItemTypes; > use Koha::Plugins; > use Koha::SearchEngine; >@@ -1383,7 +1384,7 @@ sub GetAuthorisedValueDesc { > #---- itemtypes > if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "itemtypes" ) { > my $itemtype = Koha::ItemTypes->find( $value ); >- return $itemtype ? $itemtype->translated_description : q||; >+ return $itemtype ? db_t('itemtype', $itemtype->description) : q||; > } > > #---- "true" authorized value >diff --git a/C4/Items.pm b/C4/Items.pm >index 94808084ac..3325773571 100644 >--- a/C4/Items.pm >+++ b/C4/Items.pm >@@ -67,6 +67,7 @@ use Koha::DateUtils qw(dt_from_string); > use Koha::Database; > > use Koha::Biblioitems; >+use Koha::I18N; > use Koha::Items; > use Koha::ItemTypes; > use Koha::SearchEngine; >@@ -668,7 +669,6 @@ sub GetItemsInfo { > serial.serialseq, > serial.publisheddate, > itemtypes.description, >- COALESCE( localization.translation, itemtypes.description ) AS translated_description, > itemtypes.notforloan as notforloan_per_itemtype, > holding.branchurl, > holding.branchcode, >@@ -689,14 +689,11 @@ sub GetItemsInfo { > . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype'); > $query .= q| > LEFT JOIN tmp_holdsqueue USING (itemnumber) >- LEFT JOIN localization ON itemtypes.itemtype = localization.code >- AND localization.entity = 'itemtypes' >- AND localization.lang = ? > |; > > $query .= " WHERE items.biblionumber = ? ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ; > my $sth = $dbh->prepare($query); >- $sth->execute($language, $biblionumber); >+ $sth->execute($biblionumber); > my $i = 0; > my @results; > my $serial; >@@ -1667,12 +1664,12 @@ sub PrepareItemrecordDisplay { > > #----- itemtypes > } elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) { >- my $itemtypes = Koha::ItemTypes->search_with_localization; >+ my $itemtypes = Koha::ItemTypes->search; > push @authorised_values, "" > unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); > 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 a10e50f2b6..0a58c8ad93 100644 >--- a/C4/Search.pm >+++ b/C4/Search.pm >@@ -30,6 +30,7 @@ use C4::Reserves; # GetReserveStatus > use C4::Debug; > use C4::Charset; > use Koha::AuthorisedValues; >+use Koha::I18N; > use Koha::ItemTypes; > use Koha::Libraries; > use Koha::Patrons; >@@ -539,9 +540,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}); > } > } > >@@ -1704,7 +1703,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 >@@ -1797,7 +1796,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{}; > > # FIXME: this is only used in the deprecated non-XLST opac results > if ( !$xslfile && $is_opac && $itemtype && $itemtype->{summary} ) { >@@ -1906,7 +1905,7 @@ sub searchResults { > foreach my $code ( keys %subfieldstosearch ) { > $item->{$code} = $field->subfield( $subfieldstosearch{$code} ); > } >- $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 0000000000..9d4ea398d9 >--- /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 72062239d8..d896471131 100644 >--- a/Koha/I18N.pm >+++ b/Koha/I18N.pm >@@ -27,6 +27,8 @@ use Encode; > use Locale::Messages qw(:locale_h LC_MESSAGES); > use POSIX qw( setlocale ); > use Koha::Cache::Memory::Lite; >+use Koha::Caches; >+use Koha::Database; > > use parent 'Exporter'; > our @EXPORT = qw( >@@ -43,6 +45,8 @@ our @EXPORT = qw( > N__n > N__p > N__np >+ >+ db_t > ); > > our $textdomain = 'Koha'; >@@ -201,4 +205,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 d1eaf916d4..caf8c2deb8 100644 >--- a/Koha/ItemType.pm >+++ b/Koha/ItemType.pm >@@ -23,7 +23,6 @@ use C4::Koha; > use C4::Languages; > use Koha::Database; > use Koha::CirculationRules; >-use Koha::Localizations; > > use base qw(Koha::Object Koha::Object::Limit::Library); > >@@ -46,50 +45,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, >- } >- ); >- return [ map { >- { >- lang => $_->lang, >- translation => $_->translation, >- } >- } @translated_descriptions ]; >-} >- > =head3 can_be_deleted > > my $can_be_deleted = Koha::ItemType->can_be_deleted(); >diff --git a/Koha/ItemTypes.pm b/Koha/ItemTypes.pm >index 746bbb23ea..1fdc3f5627 100644 >--- a/Koha/ItemTypes.pm >+++ b/Koha/ItemTypes.pm >@@ -32,37 +32,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 3f698303c4..0000000000 >--- a/Koha/Localization.pm >+++ /dev/null >@@ -1,28 +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); >- >-sub _type { >- return 'Localization'; >-} >- >-1; >diff --git a/Koha/Localizations.pm b/Koha/Localizations.pm >deleted file mode 100644 >index 8720334acd..0000000000 >--- 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 b180a90c49..fd045eb8b7 100644 >--- a/Koha/Schema/Result/Itemtype.pm >+++ b/Koha/Schema/Result/Itemtype.pm >@@ -251,22 +251,7 @@ __PACKAGE__->add_columns( > '+rentalcharge_daily_calendar' => { 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'; >@@ -275,4 +260,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 d5966128c3..0000000000 >--- 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/Schema/Result/Localization.pm b/Koha/Schema/Result/Localization.pm >deleted file mode 100644 >index dec7ebff50..0000000000 >--- a/Koha/Schema/Result/Localization.pm >+++ /dev/null >@@ -1,106 +0,0 @@ >-use utf8; >-package Koha::Schema::Result::Localization; >- >-# Created by DBIx::Class::Schema::Loader >-# DO NOT MODIFY THE FIRST PART OF THIS FILE >- >-=head1 NAME >- >-Koha::Schema::Result::Localization >- >-=cut >- >-use strict; >-use warnings; >- >-use base 'DBIx::Class::Core'; >- >-=head1 TABLE: C<localization> >- >-=cut >- >-__PACKAGE__->table("localization"); >- >-=head1 ACCESSORS >- >-=head2 localization_id >- >- data_type: 'integer' >- is_auto_increment: 1 >- is_nullable: 0 >- >-=head2 entity >- >- data_type: 'varchar' >- is_nullable: 0 >- size: 16 >- >-=head2 code >- >- data_type: 'varchar' >- is_nullable: 0 >- size: 64 >- >-=head2 lang >- >- data_type: 'varchar' >- is_nullable: 0 >- size: 25 >- >-=head2 translation >- >- data_type: 'mediumtext' >- is_nullable: 1 >- >-=cut >- >-__PACKAGE__->add_columns( >- "localization_id", >- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, >- "entity", >- { data_type => "varchar", is_nullable => 0, size => 16 }, >- "code", >- { data_type => "varchar", is_nullable => 0, size => 64 }, >- "lang", >- { data_type => "varchar", is_nullable => 0, size => 25 }, >- "translation", >- { data_type => "mediumtext", is_nullable => 1 }, >-); >- >-=head1 PRIMARY KEY >- >-=over 4 >- >-=item * L</localization_id> >- >-=back >- >-=cut >- >-__PACKAGE__->set_primary_key("localization_id"); >- >-=head1 UNIQUE CONSTRAINTS >- >-=head2 C<entity_code_lang> >- >-=over 4 >- >-=item * L</entity> >- >-=item * L</code> >- >-=item * L</lang> >- >-=back >- >-=cut >- >-__PACKAGE__->add_unique_constraint("entity_code_lang", ["entity", "code", "lang"]); >- >- >-# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:54 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4642LmshpGd3JW7YxM5pIA >- >- >-# You can replace this text with custom code or comments, and it will be preserved on regeneration >-1; >diff --git a/Koha/Template/Plugin/ItemTypes.pm b/Koha/Template/Plugin/ItemTypes.pm >index 20910562b0..8830d1f8a0 100644 >--- a/Koha/Template/Plugin/ItemTypes.pm >+++ b/Koha/Template/Plugin/ItemTypes.pm >@@ -22,16 +22,23 @@ use Modern::Perl; > use Template::Plugin; > use base qw( Template::Plugin ); > >+use Koha::I18N; > use Koha::ItemTypes; > > sub GetDescription { > my ( $self, $itemtypecode ) = @_; > my $itemtype = Koha::ItemTypes->find( $itemtypecode ); >- return $itemtype ? $itemtype->translated_description : q{}; >+ return $itemtype ? $self->t($itemtype->description) : q{}; > } > > 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 f676ae81f8..556579e2e8 100755 >--- a/acqui/orderreceive.pl >+++ b/acqui/orderreceive.pl >@@ -76,6 +76,7 @@ use Koha::Acquisition::Booksellers; > use Koha::Acquisition::Currencies; > use Koha::Acquisition::Orders; > use Koha::DateUtils qw( dt_from_string ); >+use Koha::I18N; > use Koha::ItemTypes; > use Koha::Patrons; > >@@ -154,7 +155,7 @@ if ($AcqCreateItem eq 'receiving') { > my $itemtype = Koha::ItemTypes->find($i->effective_itemtype); > if (defined $itemtype) { > # We should not do that here, but call ->itemtype->description when needed instead >- $item->{itemtype} = $itemtype->description; # FIXME Should not it be translated_description? >+ $item->{itemtype} = db_t('itemtype', $itemtype->description); > } > push @items, $item; > } >diff --git a/admin/itemtypes.pl b/admin/itemtypes.pl >index 7b13dac7b7..446ccbeae0 100755 >--- a/admin/itemtypes.pl >+++ b/admin/itemtypes.pl >@@ -33,7 +33,6 @@ use C4::Auth; > use C4::Output; > use Koha::ItemTypes; > use Koha::ItemType; >-use Koha::Localizations; > > my $input = new CGI; > my $searchfield = $input->param('description'); >@@ -73,12 +72,10 @@ if ( $op eq 'add_form' ) { > > my $imagesets = C4::Koha::getImageSets( checked => ( $itemtype ? $itemtype->imageurl : undef ) ); > my $searchcategory = GetAuthorisedValues("ITEMTYPECAT"); >- my $translated_languages = C4::Languages::getTranslatedLanguages( undef , C4::Context->preference('template') ); > $template->param( > itemtype => $itemtype, > imagesets => $imagesets, > searchcategory => $searchcategory, >- can_be_translated => ( scalar(@$translated_languages) > 1 ? 1 : 0 ), > branches_loop => \@branches_loop, > ); > } elsif ( $op eq 'add_validate' ) { >diff --git a/admin/localization.pl b/admin/localization.pl >index f8bc553c05..4309945581 100755 >--- a/admin/localization.pl >+++ b/admin/localization.pl >@@ -21,9 +21,6 @@ use Modern::Perl; > use C4::Auth; > use C4::Output; > >-use Koha::Localization; >-use Koha::Localizations; >- > use CGI qw( -utf8 ); > > my $query = new CGI; >@@ -38,27 +35,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 6bea920dd9..73c00aab92 100755 >--- a/admin/smart-rules.pl >+++ b/admin/smart-rules.pl >@@ -556,7 +556,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 ); > >@@ -583,36 +583,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 e422cafb36..701a64784b 100755 >--- a/authorities/authorities.pl >+++ b/authorities/authorities.pl >@@ -33,6 +33,7 @@ use MARC::File::XML; > use C4::Biblio; > use Koha::Authority::Types; > use Koha::ItemTypes; >+use Koha::I18N; > use vars qw( $tagslib); > use vars qw( $authorised_values_sth); > use vars qw( $is_a_modif ); >@@ -92,10 +93,10 @@ sub build_authorized_values_list { > && ( $value || $tagslib->{$tag}->{$subfield}->{defaultvalue} ) ); > > 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/catalogue/getitem-ajax.pl b/catalogue/getitem-ajax.pl >index 80c4f615cf..0b9a2679ea 100755 >--- a/catalogue/getitem-ajax.pl >+++ b/catalogue/getitem-ajax.pl >@@ -29,6 +29,7 @@ use C4::Output; > use Koha::Libraries; > > use Koha::AuthorisedValues; >+use Koha::I18N; > use Koha::Items; > use Koha::ItemTypes; > >@@ -77,7 +78,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 2c68bfe35f..bb56f04723 100755 >--- a/catalogue/itemsearch.pl >+++ b/catalogue/itemsearch.pl >@@ -29,6 +29,7 @@ use C4::Koha; > > use Koha::AuthorisedValues; > use Koha::Biblios; >+use Koha::I18N; > use Koha::Item::Search::Field qw(GetItemSearchFields); > use Koha::ItemTypes; > use Koha::Libraries; >@@ -259,7 +260,7 @@ my @itemtypes; > foreach my $itemtype ( Koha::ItemTypes->search ) { > push @itemtypes, { > value => $itemtype->itemtype, >- label => $itemtype->translated_description, >+ label => db_t('itemtype', $itemtype->description), > }; > } > >diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl >index a736c30c8c..088ab2f0cc 100755 >--- a/catalogue/moredetail.pl >+++ b/catalogue/moredetail.pl >@@ -37,6 +37,7 @@ use Koha::Biblios; > use Koha::DateUtils; > use Koha::Items; > use Koha::Patrons; >+use Koha::I18N; > > my $query=new CGI; > >@@ -132,9 +133,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->{$_} : '' ); >@@ -144,7 +145,7 @@ foreach ( keys %{$data} ) { > foreach my $item (@items){ > $item->{object} = Koha::Items->find( $item->{itemnumber} ); > $item->{'collection'} = $ccodes->{ $item->{ccode} } if $ccodes && $item->{ccode} && exists $ccodes->{ $item->{ccode} }; >- $item->{'itype'} = $itemtypes->{ $item->{'itype'} }->{'translated_description'} if exists $itemtypes->{ $item->{'itype'} }; >+ $item->{'itype'} = db_t('itemtype', $itemtypes->{ $item->{'itype'} }->{description}) if exists $itemtypes->{ $item->{'itype'} }; > $item->{'replacementprice'} = $item->{'replacementprice'}; > if ( defined $item->{'copynumber'} ) { > $item->{'displaycopy'} = 1; >diff --git a/catalogue/search.pl b/catalogue/search.pl >index 6e5d929413..4ae1d10ba9 100755 >--- a/catalogue/search.pl >+++ b/catalogue/search.pl >@@ -156,6 +156,7 @@ use Koha::SearchEngine::Search; > use Koha::SearchEngine::QueryBuilder; > use Koha::Virtualshelves; > use Koha::SearchFields; >+use Koha::I18N; > > use URI::Escape; > >@@ -237,7 +238,14 @@ $template->param( > ); > > # load the Type stuff >-my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; >+my $itemtypes = { >+ map { >+ $_->{itemtype} => { >+ %$_, >+ description => db_t( 'itemtype', $_->{description} ), >+ } >+ } @{ Koha::ItemTypes->search->unblessed } >+}; > # the index parameter is different for item-level itemtypes > my $itype_or_itemtype = (C4::Context->preference("item-level_itypes"))?'itype':'itemtype'; > my @advancedsearchesloop; >@@ -251,11 +259,11 @@ foreach my $advanced_srch_type (@advanced_search_types) { > if ($advanced_srch_type eq 'itemtypes') { > # itemtype is a special case, since it's not defined in authorized values > my @itypesloop; >- foreach my $thisitemtype ( sort {$itemtypes->{$a}->{translated_description} cmp $itemtypes->{$b}->{translated_description} } keys %$itemtypes ) { >+ foreach my $thisitemtype ( sort {$itemtypes->{$a}->{description} cmp $itemtypes->{$b}->{description} } keys %$itemtypes ) { > my %row =( number=>$cnt++, > ccl => "$itype_or_itemtype,phr", > code => $thisitemtype, >- description => $itemtypes->{$thisitemtype}->{translated_description}, >+ description => $itemtypes->{$thisitemtype}->{description}, > imageurl=> getitemtypeimagelocation( 'intranet', $itemtypes->{$thisitemtype}->{'imageurl'} ), > ); > push @itypesloop, \%row; >@@ -546,7 +554,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, >@@ -818,7 +826,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) { >@@ -830,8 +845,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 > ) > { >@@ -839,7 +854,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 cd53c66e70..be3761fa7e 100755 >--- a/cataloguing/addbiblio.pl >+++ b/cataloguing/addbiblio.pl >@@ -46,6 +46,7 @@ use Date::Calc qw(Today); > use MARC::File::USMARC; > use MARC::File::XML; > use URI::Escape; >+use Koha::I18N; > > if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { > MARC::File::XML->default_record_format('UNIMARC'); >@@ -181,10 +182,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 ec27c1a426..b31b04079e 100755 >--- a/cataloguing/additem.pl >+++ b/cataloguing/additem.pl >@@ -31,6 +31,7 @@ use C4::Circulation; > use C4::Koha; > use C4::ClassSource; > use Koha::DateUtils; >+use Koha::I18N; > use Koha::Items; > use Koha::ItemTypes; > use Koha::Libraries; >@@ -182,13 +183,13 @@ sub generate_subfield_form { > my $branch_limit = C4::Context->userenv && C4::Context->userenv->{"branch"}; > my $itemtypes; > if($branch_limit) { >- $itemtypes = Koha::ItemTypes->search_with_localization({branchcode => $branch_limit}); >+ $itemtypes = Koha::ItemTypes->search({branchcode => $branch_limit}); > } else { >- $itemtypes = Koha::ItemTypes->search_with_localization; >+ $itemtypes = Koha::ItemTypes->search; > } > 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); > } > > unless ( $value ) { >diff --git a/circ/transferstoreceive.pl b/circ/transferstoreceive.pl >index b9123f6c01..842f519a9f 100755 >--- a/circ/transferstoreceive.pl >+++ b/circ/transferstoreceive.pl >@@ -34,6 +34,7 @@ use Date::Calc qw( > > use C4::Koha; > use C4::Reserves; >+use Koha::I18N; > use Koha::Items; > use Koha::ItemTypes; > use Koha::Libraries; >@@ -95,7 +96,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 42416b3a63..da1cafe66a 100755 >--- a/course_reserves/add_items.pl >+++ b/course_reserves/add_items.pl >@@ -84,7 +84,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 0000000000..748b9b7b8f >--- /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 af10ac5317..e785c12ca1 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -3711,20 +3711,27 @@ CREATE TABLE `additional_field_values` ( > CONSTRAINT `afv_fk` FOREIGN KEY (`field_id`) REFERENCES `additional_fields` (`id`) ON DELETE CASCADE ON UPDATE CASCADE > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; > >--- >--- Table structure for table 'localization' >--- > >-DROP TABLE IF EXISTS localization; >-CREATE TABLE `localization` ( >- localization_id int(11) NOT NULL AUTO_INCREMENT, >- entity varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL, >- code varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, >- lang varchar(25) COLLATE utf8mb4_unicode_ci NOT NULL, -- could be a foreign key >- translation MEDIUMTEXT COLLATE utf8mb4_unicode_ci, >- PRIMARY KEY (localization_id), >- UNIQUE KEY `entity_code_lang` (`entity`,`code`,`lang`) >-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; >+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 'audio_alerts' >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 c5bd432b9e..60553322a9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc >@@ -154,6 +154,7 @@ > [% IF ( Koha.Preference('OPACReportProblem') && CAN_user_problem_reports ) %] > <li><a href="/cgi-bin/koha/admin/problem-reports.pl">OPAC problem reports</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 b7616886d4..c656118b2f 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 %] >@@ -25,7 +26,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 fded276005..9ff1c6e75e 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 >@@ -238,10 +238,15 @@ > <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 %] >+ > [% IF ( Koha.Preference('OPACReportProblem') && CAN_user_problem_reports ) %] > <dt><a href="/cgi-bin/koha/admin/problem-reports.pl">OPAC problem reports</a></dt> > <dd>Manage OPAC problem reports submitted by patrons</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 9045f6c712..12f3259ca2 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 AuthorisedValues %] > [% USE Price %] >@@ -118,9 +119,6 @@ Item types administration > <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> > <span class="label">Search category</span> >@@ -341,7 +339,7 @@ Item types administration > <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> >@@ -397,19 +395,7 @@ Item types administration > </a> > </td> > <td> >- [% IF itemtype.translated_descriptions.size %] >- [% itemtype.description | html %] (default)<br/> >- [% FOR description IN itemtype.translated_descriptions %] >- [% IF description.translation == itemtype.translated_description %] >- <b>[% description.translation | html %]</b> >- [% ELSE %] >- [% description.translation | html %] ([% description.lang | html %]) >- [% END %] >- <br/> >- [% END %] >- [% ELSE %] >- [% itemtype.description | html %] >- [% END %] >+ [% itemtype.description | html %] > </td> > <td>[% itemtype.searchcategory | html %]</td> > <td>[% IF ( itemtype.notforloan ) %]Yes[% ELSE %] [% END %]</td> >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 95d2810d52..2cf521ad88 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt >@@ -1,277 +1,160 @@ >-[% USE raw %] >-[% USE Asset %] >+[% USE JSON.Escape %] > [% SET footerjs = 1 %] > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Localization</title> >-[% INCLUDE 'doc-head-close.inc' popup => 1 %] >-<style>#localization { margin-top: 1em; }</style> >+[% INCLUDE 'doc-head-close.inc' %] >+<style> >+ .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"> >-<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" 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 5ae3bb94e1..e2587590ad 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 >@@ -322,7 +322,7 @@ > <select name="itemtype" id="matrixitemtype" style="width:13em;"> > <option value="*">All</option> > [% 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> >@@ -818,7 +818,7 @@ > [% IF holdallowed || hold_fulfillment_policy || returnbranch %] > <tr> > <td> >- [% i.translated_description | html %] >+ [% ItemTypes.t(i.description) | html %] > </td> > <td> > [% IF holdallowed == 2 %] >@@ -863,7 +863,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 9eb252d68b..31d99af616 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 %] >@@ -143,7 +144,7 @@ > <tr> > [% FOREACH itemtypeloo IN advsearchloo.code_loop %] > <td><input type="checkbox" id="[% itemtypeloo.ccl FILTER remove(',') | html %]-[% itemtypeloo.number | html %]" name="limit" value="mc-[% itemtypeloo.ccl | html %]:[% itemtypeloo.code | html %]"/><label for="[% itemtypeloo.ccl FILTER remove(',') | html %]-[% itemtypeloo.number | html %]">[% UNLESS ( Koha.Preference('OpacNoItemTypeImages') ) %][% IF ( itemtypeloo.imageurl ) %]<img src="[% itemtypeloo.imageurl | html %]" alt="[% itemtypeloo.description | html %]" />[% END %] [% END %] >- [% itemtypeloo.description | html %]</label></td> >+ [% ItemTypes.t(itemtypeloo.description) | html %]</label></td> > [% IF ( loop.last ) %]</tr>[% ELSE %][% UNLESS ( loop.count % 5 ) %]</tr><tr>[% END %][% END %] > [% END %] > </table> >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 6ef518489b..d05b2a1ace 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 AuthorisedValues %] >@@ -264,9 +265,9 @@ > [% IF ( item_level_itypes ) %] > <td class="itype"> > [% IF !noItemTypeImages && item.imageurl %] >- <img src="[% item.imageurl | html %]" alt="[% item.translated_description | html %]" title="[% item.translated_description | html %]" /> >+ <img src="[% item.imageurl | html %]" alt="[% ItemTypes.t(item.description) | html %]" title="[% ItemTypes.t(item.description) | html %]" /> > [% END %] >- [% item.translated_description | html %] >+ [% ItemTypes.t(item.description) | html %] > </td> > [% END %] > <td class="location">[% UNLESS ( singlebranchmode ) %][% Branches.GetName( item.branchcode ) | 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 919c7d57c6..83fced39a4 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,4 +1,5 @@ > [% USE Branches %] >+[% USE ItemTypes %] > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Course reserves ›[% IF is_edit || course_reserve %] Edit item[% ELSE %] Add items[% END %]</title> > [% INCLUDE 'doc-head-close.inc' %] >@@ -44,9 +45,9 @@ > > [% FOREACH it IN itypes %] > [% IF course_item.itype.defined && ( ( course.enabled == 'yes' && it.itemtype == item.itype ) || ( course.enabled == 'no' && 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 ce67aab3ff..800cca3d10 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 >@@ -39,7 +39,7 @@ > <option value="">LEAVE UNCHANGED</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 c1ad99bfa4..9dd637ce1e 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,3 +1,4 @@ >+[% USE ItemTypes %] > [% SET footerjs = 1 %] > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Reports [% IF ( do_it ) %]› Acquisitions statistics › Results[% ELSE %]› Acquisitions statistics[% END %]</title> >@@ -191,7 +192,7 @@ > <select name="Filter" size="1" 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 0f20ba3d2a..f5298584e4 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 >@@ -108,7 +108,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 6cef6f1438..dd26732e54 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>Koha › Reports › Most-circulated items[% IF ( do_it ) %] › Results[% END %]</title> >@@ -85,7 +86,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 92c5ce19ca..acc46a381f 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 >@@ -1,4 +1,5 @@ > [% USE Branches %] >+[% USE ItemTypes %] > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Reports › Items with no checkouts</title> > [% INCLUDE 'doc-head-close.inc' %] >@@ -98,7 +99,7 @@ > <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_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_stats.tt >index c741b54f8b..aecf75e630 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>Koha › Reports [% IF ( do_it ) %]› Catalog statistics › Results[% ELSE %]› Catalog statistics[% END %]</title> >@@ -103,7 +104,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 6a61633de9..181accc743 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>Koha › Reports › Average loan time</title> >@@ -137,7 +138,7 @@ > <select name="Filter" size="1" 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 c39a606683..29ef56ccdf 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>Koha › Reports › Circulation statistics [% IF ( do_it ) %]› Results[% END %]</title> >@@ -168,7 +169,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 0b2dc2e1fb..34c0a63a10 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt >@@ -137,7 +137,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 0ee58a9ee9..b59fa201af 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>Koha › Reports › Holds statistics [% IF ( do_it ) %]› Results[% END %]</title> >@@ -153,7 +154,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 fd603e167a..f0100c8be5 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 %] >@@ -176,9 +177,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> >@@ -190,9 +191,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 327e08f7ba..5e8aa90bc8 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 >@@ -111,7 +111,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 59a88ecc00..55f7cca800 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>Koha › Serials › Catalog search</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 bfd7809a6d..8e3412178e 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>Koha › Tools › Export data</title> >@@ -66,7 +67,7 @@ > <select name="itemtype" id="itemtype"> > <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 5beada8871..146e16fd6b 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 %] > [% SET PRIVATE = 1 %] >@@ -203,7 +204,7 @@ > </td> > [% END %] > [% UNLESS ( item_level_itypes ) %]<td> >- [% UNLESS ( noItemTypeImages || !itemsloo.imageurl ) %]<img src="[% itemsloo.imageurl | html %]" alt="[% itemsloo.description | html %]" title="[% itemsloo.description | html %]" />[% END %][% itemsloo.description | html %] >+ [% UNLESS ( noItemTypeImages || !itemsloo.imageurl ) %]<img src="[% itemsloo.imageurl | html %]" alt="[% ItemTypes.t(itemsloo.description) | html %]" title="[% ItemTypes.t(itemsloo.description) | html %]" />[% END %][% ItemTypes.t(itemsloo.description) | html %] > </td>[% END %] > <td> > [% IF ( itemsloo.XSLTBloc ) %] >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 6f08f1cd2d..dc8734a8a3 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 91da402058..961e0416f5 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 %] > [% INCLUDE 'doc-head-open.inc' %] >@@ -172,7 +173,7 @@ > [% END %] > [% END %] > <span class="tdlabel">Item type:</span> >- [% issue.translated_description | html %]</td> >+ [% ItemTypes.t(issue.description) | html %]</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 0981abe172..d6b7ffe3cc 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt >@@ -214,7 +214,7 @@ > <li class="itype"> > <span class="label">Item type: </span> > [% IF ( bibitemloo.imageurl ) %]<img src="[% bibitemloo.imageurl | html %]" alt="" />[% END %] >- [% bibitemloo.translated_description | html %] >+ [% ItemTypes.t(bibitemloo.description) | html %] > </li> > [% END %] > >@@ -380,7 +380,7 @@ > <img src="[% itemLoo.imageurl | html %]" alt="" /> > [% END %] > [% END %] >- [% itemLoo.translated_description | html %] >+ [% ItemTypes.t(itemLoo.description) | html %] > </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 4673581146..08a5735d51 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 %] > [% SET PRIVATE = 1 %] > [% SET PUBLIC = 2 %] >@@ -315,9 +316,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 %] >- [% itemsloo.description | html %] >+ [% ItemTypes.t(itemsloo.description) | html %] > </td> > [% END %] > <td> >diff --git a/labels/label-item-search.pl b/labels/label-item-search.pl >index fdade75a4e..0fd69c4e3f 100755 >--- a/labels/label-item-search.pl >+++ b/labels/label-item-search.pl >@@ -231,20 +231,7 @@ else { > debug => 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 f1100878bd..42629ca446 100755 >--- a/opac/opac-detail.pl >+++ b/opac/opac-detail.pl >@@ -54,6 +54,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; >@@ -220,7 +221,7 @@ if ($session->param('busc')) { > { > my ($arrParamsBusc, $offset, $results_per_page) = @_; > >- 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); >@@ -557,12 +558,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 = >@@ -696,7 +697,7 @@ if ( not $viewallitems and @items > $max_items_to_display ) { > } > if (exists $itm->{itype} && defined($itm->{itype}) && exists $itemtypes->{ $itm->{itype} }) { > $itm->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{ $itm->{itype} }->{'imageurl'} ); >- $itm->{'description'} = $itemtypes->{ $itm->{itype} }->{translated_description}; >+ $itm->{'description'} = db_t('itemtype', $itemtypes->{ $itm->{itype} }->{description}); > } > foreach (qw(ccode enumchron copynumber itemnotes location_description uri)) { > $itemfields{$_} = 1 if ($itm->{$_}); >diff --git a/opac/opac-readingrecord.pl b/opac/opac-readingrecord.pl >index c13faacaa3..cd1b38383d 100755 >--- a/opac/opac-readingrecord.pl >+++ b/opac/opac-readingrecord.pl >@@ -58,7 +58,7 @@ my $borr = Koha::Patrons->find( $borrowernumber )->unblessed; > > $template->param(%{$borr}); > >-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') || ''; >@@ -87,8 +87,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 2a11ad48e5..c55a52c167 100755 >--- a/opac/opac-reserve.pl >+++ b/opac/opac-reserve.pl >@@ -100,7 +100,7 @@ if ( $reservefee > 0){ > $template->param( RESERVE_CHARGE => $reservefee); > } > >-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. >@@ -444,13 +444,13 @@ foreach my $biblioNum (@biblionumbers) { > $biblioLoopIter{reqholdnotes}=0; #TODO: For future use > > 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}; > } > > foreach my $itemInfo (@{$biblioData->{itemInfos}}) { > if ($itemLevelTypes && $itemInfo->{itype}) { >- $itemInfo->{translated_description} = $itemtypes->{$itemInfo->{itype}}{translated_description}; >+ $itemInfo->{description} = $itemtypes->{$itemInfo->{itype}}{description}; > $itemInfo->{imageurl} = getitemtypeimagesrc() . "/". $itemtypes->{$itemInfo->{itype}}{imageurl}; > } > >@@ -478,7 +478,7 @@ foreach my $biblioNum (@biblionumbers) { > $itemLoopIter->{ccode} = $itemInfo->{ccode}; > $itemLoopIter->{copynumber} = $itemInfo->{copynumber}; > if ($itemLevelTypes) { >- $itemLoopIter->{translated_description} = $itemInfo->{translated_description}; >+ $itemLoopIter->{description} = $itemInfo->{description}; > $itemLoopIter->{itype} = $itemInfo->{itype}; > $itemLoopIter->{imageurl} = $itemInfo->{imageurl}; > } >diff --git a/opac/opac-search.pl b/opac/opac-search.pl >index 01887f283a..7d60b30583 100755 >--- a/opac/opac-search.pl >+++ b/opac/opac-search.pl >@@ -55,6 +55,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; >@@ -225,14 +226,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 >@@ -254,7 +254,7 @@ if ( $yaml =~ /\S/ ) { > } > } > >-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*$//; >@@ -267,7 +267,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'}, >@@ -628,7 +628,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 c0140c7a75..71d0401f51 100755 >--- a/opac/opac-shelves.pl >+++ b/opac/opac-shelves.pl >@@ -326,7 +326,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 d94d3d0e2b..692c71f8a1 100755 >--- a/opac/opac-user.pl >+++ b/opac/opac-user.pl >@@ -188,7 +188,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' } ] }); > if ( $pending_checkouts->count ) { # Useless test > while ( my $c = $pending_checkouts->next ) { >diff --git a/reports/acquisitions_stats.pl b/reports/acquisitions_stats.pl >index d7dea6a85f..683c59760b 100755 >--- a/reports/acquisitions_stats.pl >+++ b/reports/acquisitions_stats.pl >@@ -194,7 +194,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 84a46a36a2..3476915e80 100755 >--- a/reports/bor_issues_top.pl >+++ b/reports/bor_issues_top.pl >@@ -111,7 +111,7 @@ my @mime = ( map { {type =>$_} } (split /[;:]/, 'CSV') ); # FIXME translation > my $delims = GetDelimiterChoices; > > my $patron_categories = Koha::Patron::Categories->search_limited({}, {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 604258e9c9..a63b876919 100755 >--- a/reports/cat_issues_top.pl >+++ b/reports/cat_issues_top.pl >@@ -107,7 +107,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 3b0fdd8f74..08d347be4e 100755 >--- a/reports/catalogue_out.pl >+++ b/reports/catalogue_out.pl >@@ -58,7 +58,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 b7bd98a024..422ee804ea 100755 >--- a/reports/catalogue_stats.pl >+++ b/reports/catalogue_stats.pl >@@ -120,7 +120,7 @@ if ($do_it) { > my $req; > my @select; > >- 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 cea969e5b0..511fa718ea 100755 >--- a/reports/issues_avg_stats.pl >+++ b/reports/issues_avg_stats.pl >@@ -120,7 +120,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 16a8f77bfc..15aa08d7a2 100755 >--- a/reports/issues_stats.pl >+++ b/reports/issues_stats.pl >@@ -33,6 +33,7 @@ use C4::Members; > > use Koha::AuthorisedValues; > use Koha::DateUtils; >+use Koha::I18N; > use Koha::ItemTypes; > use Koha::Patron::Attribute::Types; > >@@ -87,7 +88,7 @@ $sep = "\t" if ($sep eq 'tabulation'); > $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_limited({}, {order_by => ['description']}); > >@@ -361,7 +362,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) { >@@ -450,7 +451,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 cd5fbe4b95..bb614a2864 100755 >--- a/reports/itemslost.pl >+++ b/reports/itemslost.pl >@@ -150,7 +150,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 b6afa0fe2c..e7463f0bc5 100755 >--- a/reports/reserves_stats.pl >+++ b/reports/reserves_stats.pl >@@ -30,6 +30,7 @@ use C4::Reports; > use C4::Members; > use Koha::AuthorisedValues; > use Koha::DateUtils; >+use Koha::I18N; > use Koha::ItemTypes; > use Koha::Libraries; > use Koha::Patron::Categories; >@@ -130,7 +131,7 @@ my @values; > my %labels; > my %select; > >-my $itemtypes = Koha::ItemTypes->search_with_localization; >+my $itemtypes = Koha::ItemTypes->search; > > # location list > my @locations; >@@ -320,7 +321,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 61f853d085..d74821a6e8 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -70,7 +70,7 @@ my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user( > my $showallitems = $input->param('showallitems'); > my $pickup = $input->param('pickup') || C4::Context->userenv->{'branch'}; > >-my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; >+my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } }; > > # Select borrowers infos > my $findborrower = $input->param('findborrower'); >diff --git a/serials/subscription-add.pl b/serials/subscription-add.pl >index a7b483be18..227024430a 100755 >--- a/serials/subscription-add.pl >+++ b/serials/subscription-add.pl >@@ -158,9 +158,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 743fe512f6..856a7ad3bd 100755 >--- a/serials/subscription-bib-search.pl >+++ b/serials/subscription-bib-search.pl >@@ -199,10 +199,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 7203f0ce9d..3b929ca063 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 fa470b3a2a..2a5c051239 100755 >--- a/svc/checkouts >+++ b/svc/checkouts >@@ -29,6 +29,7 @@ use C4::Context; > > use Koha::AuthorisedValues; > use Koha::DateUtils; >+use Koha::I18N; > use Koha::ItemTypes; > > my $input = new CGI; >@@ -196,9 +197,9 @@ while ( my $c = $sth->fetchrow_hashref() ) { > part_name => $c->{part_name} // '', > author => $c->{author}, > barcode => $c->{barcode}, >- type_for_stat => $type_for_stat ? $type_for_stat->translated_description : q{}, >- itemtype_description => $itemtype ? $itemtype->translated_description : q{}, >- recordtype_description => $recordtype ? $recordtype->translated_description : q{}, >+ type_for_stat => $type_for_stat ? db_t('itemtype', $type_for_stat->description) : q{}, >+ itemtype_description => $itemtype ? db_t('itemtype', $itemtype->description) : q{}, >+ recordtype_description => $recordtype ? db_t('itemtype', $recordtype->description) : q{}, > collection => $collection, > location => $location, > homebranch => $c->{homebranch}, >diff --git a/svc/holds b/svc/holds >index af1b033063..692b76fb8e 100755 >--- a/svc/holds >+++ b/svc/holds >@@ -29,6 +29,7 @@ use C4::Context; > > use Koha::DateUtils; > use Koha::Holds; >+use Koha::I18N; > use Koha::ItemTypes; > use Koha::Libraries; > >@@ -76,7 +77,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 6eed60632c..8972857625 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/svc/split_callnumbers b/svc/split_callnumbers >index 8c85a58546..31408098fa 100755 >--- a/svc/split_callnumbers >+++ b/svc/split_callnumbers >@@ -20,78 +20,6 @@ sub get_split_callnumbers { > C4::Service->return_success( $response ); > } > >-sub update_translation { >- my $id = $query->param('id'); >- my $translation = $query->param('translation'); >- my $lang = $query->param('lang'); >- >- 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'; >- } >- } >- $response->param( >- %params, >- id => $localization->localization_id, >- entity => $localization->entity, >- code => $localization->code, >- lang => $localization->lang, >- translation => $localization->translation, >- is_changed => $is_changed, >- ); >- C4::Service->return_success( $response ); >-} >- >-sub add_translation { >- my $entity = $query->param('entity'); >- my $code = $query->param('code'); >- my $lang = $query->param('lang'); >- my $translation = $query->param('translation'); >- >- 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, >- ); >- >- } else { >- $response->param( error => 1, error_code => 'already_exists', ); >- } >- C4::Service->return_success( $response ); >-} >- >-sub delete_translation { >- my $id = $query->param('id'); >- Koha::Localizations->find($id)->delete; >- $response->param( id => $id ); >- C4::Service->return_success( $response ); >-} >- > C4::Service->dispatch( > [ 'GET /', [ 'callnumbers', 'regexs' ], \&get_split_callnumbers ], > ); >diff --git a/t/db_dependent/Koha/ItemTypes.t b/t/db_dependent/Koha/ItemTypes.t >index 8645229db4..327a7d0074 100755 >--- a/t/db_dependent/Koha/ItemTypes.t >+++ b/t/db_dependent/Koha/ItemTypes.t >@@ -20,7 +20,7 @@ > use Modern::Perl; > > use Data::Dumper; >-use Test::More tests => 24; >+use Test::More tests => 22; > > use t::lib::Mocks; > use t::lib::TestBuilder; >@@ -84,31 +84,6 @@ Koha::ItemType->new( > } > )->store; > >-Koha::Localization->new( >- { >- entity => 'itemtypes', >- code => 'type1', >- lang => 'en', >- translation => 'b translated itemtype desc' >- } >-)->store; >-Koha::Localization->new( >- { >- entity => 'itemtypes', >- code => 'type2', >- lang => 'en', >- translation => 'a translated itemtype desc' >- } >-)->store; >-Koha::Localization->new( >- { >- entity => 'something_else', >- code => 'type2', >- lang => 'en', >- translation => 'another thing' >- } >-)->store; >- > my $type = Koha::ItemTypes->find('type1'); > ok( defined($type), 'first result' ); > is( $type->itemtype, 'type1', 'itemtype/code' ); >@@ -131,14 +106,6 @@ is( $type->checkinmsgtype, 'checkinmsgtype', 'checkinmsgtype' ); > > t::lib::Mocks::mock_preference('language', 'en'); > t::lib::Mocks::mock_preference('opaclanguages', 'en'); >-my $itemtypes = Koha::ItemTypes->search_with_localization; >-is( $itemtypes->count, 3, 'There are 3 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 $builder = t::lib::TestBuilder->new; > my $item_type = $builder->build_object({ class => 'Koha::ItemTypes' }); >diff --git a/tools/batchMod.pl b/tools/batchMod.pl >index 8b13257e5d..f0edba4401 100755 >--- a/tools/batchMod.pl >+++ b/tools/batchMod.pl >@@ -37,6 +37,7 @@ use List::MoreUtils qw/uniq/; > use Koha::AuthorisedValues; > use Koha::Biblios; > use Koha::DateUtils; >+use Koha::I18N; > use Koha::Items; > use Koha::ItemTypes; > use Koha::Patrons; >@@ -420,10 +421,10 @@ foreach my $tag (sort keys %{$tagslib}) { > } > elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) { > push @authorised_values, ""; >- my $itemtypes = Koha::ItemTypes->search_with_localization; >+ my $itemtypes = Koha::ItemTypes->search; > 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); > } > $value = ""; > >diff --git a/tools/export.pl b/tools/export.pl >index 97ff255da0..b57c07aec9 100755 >--- a/tools/export.pl >+++ b/tools/export.pl >@@ -271,7 +271,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 aeb65c9496..275cc90240 100755 >--- a/virtualshelves/shelves.pl >+++ b/virtualshelves/shelves.pl >@@ -281,7 +281,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.20.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