Bug 14100: Generic solution for language overlay - Item types
Test plan: 1/ update the Schema (misc/devel/update_dbix_class_files.pl) 2/ Translate templates for some languages (es-DE, de-DE for instance) 3/ Enable them in the pref (search for 'lang') for the staff interface 4/ Go on the item type admin page (admin/itemtypes.pl) 5/ Edit one 6/ Click on the 'translate for other languages' link 7/ You are now on the interface to translate the item type's description in the languages you want. So translate some :) 8/ Go back on the item type list view (admin/itemtypes.pl) 9/ You should see the original description (non translated) 10/ Switch the language 11/ You should see the translated description in the correct language. If the description is non translated, the original description is displayed. 12/ On the different page where the item type is displayed, confirm that the translated description appears. Think further / Todo: 1/ Update all occurrences of the item type's description (DONE) 2/ Implement for authorised values 3/ Implement for syspref value (at least textarea) 4/ Implement for branch names 5/ Centralize all the translation on a single page in the admin area ... N/ Implement a webservice to centralize all the translations and give the ability to sync the item types/authorised values description with the rest of the world (push and pull). Signed-off-by: Josef Moravec <josef.moravec@gmail.com> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
66e9384df9
commit
0f63f89f66
|
|
@ -3027,13 +3027,12 @@ sub PrepareItemrecordDisplay {
|
|||
|
||||
#----- itemtypes
|
||||
} elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
|
||||
my $sth = $dbh->prepare( "SELECT itemtype,description FROM itemtypes ORDER BY description" );
|
||||
$sth->execute;
|
||||
my $itemtypes = GetItemTypes( style => 'array' );
|
||||
push @authorised_values, ""
|
||||
unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
|
||||
while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
|
||||
push @authorised_values, $itemtype;
|
||||
$authorised_lib{$itemtype} = $description;
|
||||
for my $itemtype ( @$itemtypes ) {
|
||||
push @authorised_values, $itemtype->{itemtype};
|
||||
$authorised_lib{$itemtype->{itemtype}} = $itemtype->{translated_description};
|
||||
}
|
||||
#---- class_sources
|
||||
} elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
|
||||
|
|
|
|||
49
C4/Koha.pm
49
C4/Koha.pm
|
|
@ -254,15 +254,30 @@ sub GetItemTypes {
|
|||
my ( %params ) = @_;
|
||||
my $style = defined( $params{'style'} ) ? $params{'style'} : 'hash';
|
||||
|
||||
my $language = C4::Languages::getlanguage();
|
||||
# returns a reference to a hash of references to itemtypes...
|
||||
my %itemtypes;
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $query = qq|
|
||||
SELECT *
|
||||
my $query = q|
|
||||
SELECT
|
||||
itemtypes.itemtype,
|
||||
itemtypes.description,
|
||||
itemtypes.rentalcharge,
|
||||
itemtypes.notforloan,
|
||||
itemtypes.imageurl,
|
||||
itemtypes.summary,
|
||||
itemtypes.checkinmsg,
|
||||
itemtypes.checkinmsgtype,
|
||||
itemtypes.sip_media_type,
|
||||
COALESCE( localization.translation, itemtypes.description ) AS translated_description
|
||||
FROM itemtypes
|
||||
LEFT JOIN localization ON itemtypes.itemtype = localization.code
|
||||
AND localization.entity = 'itemtypes'
|
||||
AND localization.lang = ?
|
||||
ORDER BY itemtype
|
||||
|;
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute;
|
||||
$sth->execute( $language );
|
||||
|
||||
if ( $style eq 'hash' ) {
|
||||
while ( my $IT = $sth->fetchrow_hashref ) {
|
||||
|
|
@ -540,14 +555,30 @@ Defaults to intranet.
|
|||
|
||||
sub getitemtypeinfo {
|
||||
my ($itemtype, $interface) = @_;
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $sth = $dbh->prepare("select * from itemtypes where itemtype=?");
|
||||
$sth->execute($itemtype);
|
||||
my $res = $sth->fetchrow_hashref;
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $language = C4::Languages::getlanguage();
|
||||
my $it = $dbh->selectrow_hashref(q|
|
||||
SELECT
|
||||
itemtypes.itemtype,
|
||||
itemtypes.description,
|
||||
itemtypes.rentalcharge,
|
||||
itemtypes.notforloan,
|
||||
itemtypes.imageurl,
|
||||
itemtypes.summary,
|
||||
itemtypes.checkinmsg,
|
||||
itemtypes.checkinmsgtype,
|
||||
itemtypes.sip_media_type,
|
||||
COALESCE( localization.translation, itemtypes.description ) AS translated_description
|
||||
FROM itemtypes
|
||||
LEFT JOIN localization ON itemtypes.itemtype = localization.code
|
||||
AND localization.entity = 'itemtypes'
|
||||
AND localization.lang = ?
|
||||
WHERE itemtypes.itemtype = ?
|
||||
|, undef, $language, $itemtype );
|
||||
|
||||
$res->{imageurl} = getitemtypeimagelocation( ( ( defined $interface && $interface eq 'opac' ) ? 'opac' : 'intranet' ), $res->{imageurl} );
|
||||
$it->{imageurl} = getitemtypeimagelocation( ( ( defined $interface && $interface eq 'opac' ) ? 'opac' : 'intranet' ), $it->{imageurl} );
|
||||
|
||||
return $res;
|
||||
return $it;
|
||||
}
|
||||
|
||||
=head2 getitemtypeimagedir
|
||||
|
|
|
|||
12
C4/Search.pm
12
C4/Search.pm
|
|
@ -1873,15 +1873,9 @@ sub searchResults {
|
|||
#Build itemtype hash
|
||||
#find itemtype & itemtype image
|
||||
my %itemtypes;
|
||||
$bsth =
|
||||
$dbh->prepare(
|
||||
"SELECT itemtype,description,imageurl,summary,notforloan FROM itemtypes"
|
||||
);
|
||||
$bsth->execute();
|
||||
while ( my $bdata = $bsth->fetchrow_hashref ) {
|
||||
foreach (qw(description imageurl summary notforloan)) {
|
||||
$itemtypes{ $bdata->{'itemtype'} }->{$_} = $bdata->{$_};
|
||||
}
|
||||
my $itemtypes = GetItemTypes( style => 'array' );
|
||||
for my $itemtype ( @$itemtypes ) {
|
||||
$itemtypes{ $itemtype->{itemtype} } = $itemtype;
|
||||
}
|
||||
|
||||
#search item field code
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
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, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Koha::Database;
|
||||
|
||||
use base qw(Koha::Object);
|
||||
|
||||
sub type {
|
||||
return 'Localization';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
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, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
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;
|
||||
|
|
@ -27,11 +27,8 @@ use C4::Koha;
|
|||
sub GetDescription {
|
||||
my ( $self, $itemtype ) = @_;
|
||||
|
||||
my $query = "SELECT description FROM itemtypes WHERE itemtype = ?";
|
||||
my $sth = C4::Context->dbh->prepare($query);
|
||||
$sth->execute($itemtype);
|
||||
my $d = $sth->fetchrow_hashref();
|
||||
return $d->{description}
|
||||
my $itemtype = C4::Koha::getitemtypeinfo( $itemtype );
|
||||
return $itemtype->{translated_description};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,18 +52,7 @@ use C4::Context;
|
|||
use C4::Auth;
|
||||
use C4::Output;
|
||||
|
||||
sub StringSearch {
|
||||
my ( $searchstring, $type ) = @_;
|
||||
my $dbh = C4::Context->dbh;
|
||||
$searchstring =~ s/\'/\\\'/g;
|
||||
my @data = split( ' ', $searchstring );
|
||||
my $sth = $dbh->prepare(
|
||||
"SELECT * FROM itemtypes WHERE (description LIKE ?) ORDER BY itemtype"
|
||||
);
|
||||
$sth->execute("$data[0]%");
|
||||
return $sth->fetchall_arrayref({}); # return ref-to-array of ref-to-hashes
|
||||
# like [ fetchrow_hashref(), fetchrow_hashref() ... ]
|
||||
}
|
||||
use Koha::Localizations;
|
||||
|
||||
my $input = new CGI;
|
||||
my $searchfield = $input->param('description');
|
||||
|
|
@ -99,8 +88,26 @@ if ( $op eq 'add_form' ) {
|
|||
#---- if primkey exists, it's a modify action, so read values to modify...
|
||||
my $data;
|
||||
if ($itemtype) {
|
||||
my $sth = $dbh->prepare("select * from itemtypes where itemtype=?");
|
||||
$sth->execute($itemtype);
|
||||
my $sth = $dbh->prepare(q|
|
||||
SELECT
|
||||
itemtypes.itemtype,
|
||||
itemtypes.description,
|
||||
itemtypes.rentalcharge,
|
||||
itemtypes.notforloan,
|
||||
itemtypes.imageurl,
|
||||
itemtypes.summary,
|
||||
itemtypes.checkinmsg,
|
||||
itemtypes.checkinmsgtype,
|
||||
itemtypes.sip_media_type,
|
||||
COALESCE( localization.translation, itemtypes.description ) AS translated_description
|
||||
FROM itemtypes
|
||||
LEFT JOIN localization ON itemtypes.itemtype = localization.code
|
||||
AND localization.entity='itemtypes'
|
||||
AND localization.lang = ?
|
||||
WHERE itemtype = ?
|
||||
|);
|
||||
my $language = C4::Languages::getlanguage();
|
||||
$sth->execute($language, $itemtype);
|
||||
$data = $sth->fetchrow_hashref;
|
||||
}
|
||||
|
||||
|
|
@ -259,11 +266,24 @@ elsif ( $op eq 'delete_confirmed' ) {
|
|||
}
|
||||
|
||||
if ( $op eq 'list' ) {
|
||||
my ($results) = StringSearch( $searchfield, 'web' );
|
||||
my $results = C4::Koha::GetItemTypes( style => 'array' );
|
||||
my @loop;
|
||||
foreach my $itemtype ( @{$results} ) {
|
||||
$itemtype->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtype->{imageurl} );
|
||||
$itemtype->{rentalcharge} = sprintf( '%.2f', $itemtype->{rentalcharge} );
|
||||
|
||||
my @translated_descriptions = Koha::Localizations->search(
|
||||
{ entity => 'itemtypes',
|
||||
code => $itemtype->{itemtype},
|
||||
}
|
||||
);
|
||||
$itemtype->{translated_descriptions} = [ map {
|
||||
{
|
||||
lang => $_->lang,
|
||||
translation => $_->translation,
|
||||
}
|
||||
} @translated_descriptions ];
|
||||
|
||||
push( @loop, $itemtype );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# 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 C4::Auth;
|
||||
use C4::Output;
|
||||
|
||||
use Koha::Localization;
|
||||
use Koha::Localizations;
|
||||
|
||||
use CGI qw( -utf8 );
|
||||
|
||||
my $query = new CGI;
|
||||
|
||||
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
|
||||
{ template_name => "admin/localization.tt",
|
||||
authnotrequired => 0,
|
||||
flagsrequired => { parameters => 'parameters_remaining_permissions' },
|
||||
query => $query,
|
||||
type => "intranet",
|
||||
debug => 1,
|
||||
}
|
||||
);
|
||||
|
||||
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;
|
||||
|
|
@ -83,23 +83,17 @@ sub build_authorized_values_list {
|
|||
push @authorised_values, $branchcode;
|
||||
$authorised_lib{$branchcode} = $branchname;
|
||||
}
|
||||
|
||||
#----- itemtypes
|
||||
}
|
||||
elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
|
||||
my $sth =
|
||||
$dbh->prepare(
|
||||
"select itemtype,description from itemtypes order by description");
|
||||
$sth->execute;
|
||||
push @authorised_values, ""
|
||||
unless ( $tagslib->{$tag}->{$subfield}->{mandatory}
|
||||
&& ( $value || $tagslib->{$tag}->{$subfield}->{defaultvalue} ) );
|
||||
|
||||
|
||||
my $itemtype;
|
||||
|
||||
while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
|
||||
push @authorised_values, $itemtype;
|
||||
$authorised_lib{$itemtype} = $description;
|
||||
my $itemtypes = GetItemTypes( style => 'array' );
|
||||
for my $itemtype ( @$itemtypes ) {
|
||||
push @authorised_values, $itemtype->{itemtype};
|
||||
$authorised_lib{$itemtype->{itemtype}} = $itemtype->{translated_description};
|
||||
}
|
||||
$value = $itemtype unless ($value);
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ foreach my $advanced_srch_type (@advanced_search_types) {
|
|||
my %row =( number=>$cnt++,
|
||||
ccl => "$itype_or_itemtype,phr",
|
||||
code => $thisitemtype,
|
||||
description => $itemtypes->{$thisitemtype}->{'description'},
|
||||
description => $itemtypes->{$thisitemtype}->{translated_description},
|
||||
imageurl=> getitemtypeimagelocation( 'intranet', $itemtypes->{$thisitemtype}->{'imageurl'} ),
|
||||
);
|
||||
push @itypesloop, \%row;
|
||||
|
|
|
|||
|
|
@ -184,26 +184,19 @@ sub build_authorized_values_list {
|
|||
$authorised_lib{$thisbranch} = $branches->{$thisbranch}->{'branchname'};
|
||||
}
|
||||
|
||||
#----- itemtypes
|
||||
}
|
||||
elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
|
||||
my $sth =
|
||||
$dbh->prepare(
|
||||
"select itemtype,description from itemtypes order by description");
|
||||
$sth->execute;
|
||||
push @authorised_values, ""
|
||||
unless ( $tagslib->{$tag}->{$subfield}->{mandatory}
|
||||
&& ( $value || $tagslib->{$tag}->{$subfield}->{defaultvalue} ) );
|
||||
|
||||
|
||||
my $itemtype;
|
||||
|
||||
while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
|
||||
push @authorised_values, $itemtype;
|
||||
$authorised_lib{$itemtype} = $description;
|
||||
my $itemtypes = GetItemTypes( style => 'array' );
|
||||
for my $itemtype ( @$itemtypes ) {
|
||||
push @authorised_values, $itemtype->{itemtype};
|
||||
$authorised_lib{$itemtype->{itemtype}} = $itemtype->{translated_description};
|
||||
}
|
||||
$value = $itemtype unless ($value);
|
||||
|
||||
#---- class_sources
|
||||
}
|
||||
elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
|
||||
push @authorised_values, ""
|
||||
|
|
|
|||
|
|
@ -177,13 +177,12 @@ sub generate_subfield_form {
|
|||
}
|
||||
elsif ( $subfieldlib->{authorised_value} eq "itemtypes" ) {
|
||||
push @authorised_values, "" unless ( $subfieldlib->{mandatory} );
|
||||
my $sth = $dbh->prepare("SELECT itemtype,description FROM itemtypes ORDER BY description");
|
||||
$sth->execute;
|
||||
while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
|
||||
push @authorised_values, $itemtype;
|
||||
$authorised_lib{$itemtype} = $description;
|
||||
my $itemtypes = GetItemTypes( style => 'array' );
|
||||
for my $itemtype ( @$itemtypes ) {
|
||||
push @authorised_values, $itemtype->{itemtype};
|
||||
$authorised_lib{$itemtype->{itemtype}} = $itemtype->{translated_description};
|
||||
}
|
||||
|
||||
|
||||
unless ( $value ) {
|
||||
my $itype_sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?");
|
||||
$itype_sth->execute( $biblionumber );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE `localization` (
|
||||
localization_id int(11) NOT NULL AUTO_INCREMENT,
|
||||
entity varchar(16) COLLATE utf8_unicode_ci NOT NULL,
|
||||
code varchar(64) COLLATE utf8_unicode_ci NOT NULL,
|
||||
lang varchar(25) COLLATE utf8_unicode_ci NOT NULL,
|
||||
translation text COLLATE utf8_unicode_ci,
|
||||
PRIMARY KEY (localization_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
|
@ -3563,6 +3563,20 @@ 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=utf8 COLLATE=utf8_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 utf8_unicode_ci NOT NULL,
|
||||
code varchar(64) COLLATE utf8_unicode_ci NOT NULL,
|
||||
lang varchar(25) COLLATE utf8_unicode_ci NOT NULL, --could be a foreign key
|
||||
translation text COLLATE utf8_unicode_ci,
|
||||
PRIMARY KEY (localization_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ Data deleted
|
|||
</title>
|
||||
[% INCLUDE 'doc-head-close.inc' %]
|
||||
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
|
||||
[% INCLUDE 'greybox.inc' %]
|
||||
[% INCLUDE 'datatables.inc' %]
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
|
@ -124,7 +125,9 @@ Item types administration
|
|||
</li>
|
||||
[% END %]
|
||||
<li>
|
||||
<label for="description" class="required">Description: </label><input type="text" id="description" name="description" size="48" value="[% description |html %]" required="required" /> <span class="required">Required</span></li>
|
||||
<label for="description" class="required">Description: </label><input type="text" id="description" name="description" size="48" value="[% description |html %]" required="required" /> <span class="required">Required</span>
|
||||
<a href="/cgi-bin/koha/admin/localization.pl?entity=itemtypes&code=[% itemtype %]" title="Translate" rel="gb_page_center[600,500]"><i class="icon-edit"></i> Translate for other languages</a>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label">Search category</span>
|
||||
<select id="searchcategory" name="searchcategory">
|
||||
|
|
@ -143,7 +146,6 @@ Item types administration
|
|||
</select>
|
||||
(Options are defined as the authorized values for the ITEMTYPECAT category)
|
||||
</li>
|
||||
|
||||
[% IF ( noItemTypeImages ) %]
|
||||
<li><span class="label">Image: </span>Item type images are disabled. To enable them, turn off the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=noItemTypeImages">noItemTypeImages system preference</a></li></ol>
|
||||
[% ELSE %]</ol>
|
||||
|
|
@ -281,7 +283,7 @@ Item types administration
|
|||
<td>[% itemtype %]</td>
|
||||
</tr>
|
||||
|
||||
<tr><th scope="row">Description</th><td>[% description %]</td></tr>
|
||||
<tr><th scope="row">Description</th><td>[% translated_description %]</td></tr>
|
||||
<tr><th scope="row">Loan length</th><td>[% loanlength %]</td></tr>
|
||||
<tr><th scope="row">Rental charge</th><td>[% rentalcharge %]</td></tr></table>
|
||||
<form action="[% script_name %]" method="post">
|
||||
|
|
@ -319,7 +321,21 @@ Item types administration
|
|||
[% loo.itemtype %]
|
||||
</a>
|
||||
</td>
|
||||
<td>[% loo.description %]</td>
|
||||
<td>
|
||||
[% IF loo.translated_descriptions.size %]
|
||||
[% loo.description %] (default)<br/>
|
||||
[% FOR description IN loo.translated_descriptions %]
|
||||
[% IF description.translation == loo.translated_description %]
|
||||
<b>[% description.translation %]</b>
|
||||
[% ELSE %]
|
||||
[% description.translation %] ([% description.lang %])
|
||||
[% END %]
|
||||
<br/>
|
||||
[% END %]
|
||||
[% ELSE %]
|
||||
[% loo.description %]
|
||||
[% END %]
|
||||
</td>
|
||||
<td>[% loo.searchcategory %]</td>
|
||||
<td>[% IF ( loo.notforloan ) %]Yes[% ELSE %] [% END %]</td>
|
||||
<td>[% IF ( loo.hideinopac ) %]Yes[% ELSE %] [% END %]</td>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,212 @@
|
|||
[% INCLUDE 'doc-head-open.inc' %]
|
||||
<title>Koha › Localization</title>
|
||||
[% INCLUDE 'doc-head-close.inc' %]
|
||||
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
|
||||
[% INCLUDE 'greybox.inc' %]
|
||||
[% INCLUDE 'datatables.inc' %]
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
||||
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>');
|
||||
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>');
|
||||
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.is_changed ) {
|
||||
$(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', '#FF0000');
|
||||
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', '#FF0000');
|
||||
show_message({ type: 'error_on_delete', data: data });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$(".dialog").hide();
|
||||
|
||||
var table = $("#localization").DataTable($.extend(true, {}, dataTablesDefaults, {
|
||||
'bPaginate': false,
|
||||
}));
|
||||
|
||||
var languages_select = $('<select name="lang"></select>');
|
||||
[% FOR language IN languages %]
|
||||
var option = $('<option value="[% language.lang %]">[% language.description %]</option>');
|
||||
$(languages_select).append(option);
|
||||
[% 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 );
|
||||
});
|
||||
|
||||
$("a.delete").on('click', function(){
|
||||
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',
|
||||
url: '/cgi-bin/koha/svc/localization',
|
||||
success: function (data) {
|
||||
// FIXME Should append the delete link
|
||||
table.row.add( [ data.id, data.entity, data.code, data.lang, data.translation, "" ] ).draw();
|
||||
show_message({ type: 'success_on_insert', data: data });
|
||||
},
|
||||
error: function (data) {
|
||||
show_message({ type: 'error_on_insert', data: data });
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
</head>
|
||||
<body id="admin_localization" class="admin">
|
||||
<div id="main">
|
||||
<table id="localization">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Entity</th>
|
||||
<th>Code</th>
|
||||
<th>Lang</th>
|
||||
<th>Translation</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
[% FOR t IN translations %]
|
||||
<tr id="row_id_[% t.id %]" data-id="[% t.id %]">
|
||||
<td>[% t.id %]</td>
|
||||
<td>[% t.entity %]</td>
|
||||
<td>[% t.code %]</td>
|
||||
<td class="lang">[% t.lang %]</td>
|
||||
<td class="translation" contenteditable="true">[% t.translation %]</td>
|
||||
<td><a class="delete" title="Delete this translation"><i class="icon-remove"></i></a</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
<form id="add_translation" method="post">
|
||||
<input type="hidden" name="entity" value="[% entity %]" />
|
||||
<input type="hidden" name="code" value="[% code %]" />
|
||||
Lang: <select name="lang">
|
||||
[% FOR language IN languages %]
|
||||
[% FOR sublanguage IN language.sublanguages_loop %]
|
||||
[% IF language.plural %]
|
||||
<option value="[% sublanguage.rfc4646_subtag %]">[% sublanguage.native_description %] [% sublanguage.region_description %] ([% sublanguage.rfc4646_subtag %])</option>
|
||||
[% ELSE %]
|
||||
<option value="[% sublanguage.rfc4646_subtag %]">[% sublanguage.native_description %] ([% sublanguage.rfc4646_subtag %])</option>
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
</select>
|
||||
Translation: <input type="text" name="translation" />
|
||||
<input type="submit" value="Add" />
|
||||
</form>
|
||||
<div id="messages"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -83,9 +83,7 @@ my $sql = '
|
|||
branchname,
|
||||
|
||||
items.itype,
|
||||
itemtype_item.description AS itype_description,
|
||||
biblioitems.itemtype,
|
||||
itemtype_bib.description AS itemtype_description,
|
||||
|
||||
borrowernumber,
|
||||
surname,
|
||||
|
|
@ -103,8 +101,6 @@ my $sql = '
|
|||
LEFT JOIN biblioitems USING ( biblionumber )
|
||||
LEFT JOIN borrowers USING ( borrowernumber )
|
||||
LEFT JOIN branches ON ( issues.branchcode = branches.branchcode )
|
||||
LEFT JOIN itemtypes itemtype_bib ON ( biblioitems.itemtype = itemtype_bib.itemtype )
|
||||
LEFT JOIN itemtypes itemtype_item ON ( items.itype = itemtype_item.itemtype )
|
||||
WHERE borrowernumber
|
||||
';
|
||||
|
||||
|
|
@ -145,13 +141,14 @@ while ( my $c = $sth->fetchrow_hashref() ) {
|
|||
my ( $renewals_count, $renewals_allowed, $renewals_remaining ) =
|
||||
GetRenewCount( $c->{borrowernumber}, $c->{itemnumber} );
|
||||
|
||||
my $itemtype = C4::Koha::getitemtypeinfo( $item_level_itypes ? $c->{itype} : $c->{itemtype} );
|
||||
my $checkout = {
|
||||
DT_RowId => $c->{itemnumber} . '-' . $c->{borrowernumber},
|
||||
title => $c->{title},
|
||||
author => $c->{author},
|
||||
barcode => $c->{barcode},
|
||||
itemtype => $item_level_itypes ? $c->{itype} : $c->{itemtype},
|
||||
itemtype_description => $item_level_itypes ? $c->{itype_description} : $c->{itemtype_description},
|
||||
itemtype_description => $itemtype->{translated_description},
|
||||
location => $c->{location} ? GetAuthorisedValueByCode( 'LOC', $c->{location} ) : q{},
|
||||
itemnotes => $c->{itemnotes},
|
||||
branchcode => $c->{branchcode},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use C4::Service;
|
||||
use Koha::Localizations;
|
||||
|
||||
our ( $query, $response ) = C4::Service->init( parameters => 'parameters_remaining_permissions' );
|
||||
|
||||
sub get_translations {
|
||||
my $rs = Koha::Localizations->search({ type => $query->param('type'), code => $query->param('code') });
|
||||
my @translations;
|
||||
while ( my $s = $rs->next ) {
|
||||
push @translations, {
|
||||
id => $s->localization_id,
|
||||
type => $s->type,
|
||||
code => $s->code,
|
||||
lang => $s->lang,
|
||||
translation => $s->translation,
|
||||
}
|
||||
}
|
||||
$response->param( translations => \@translations );
|
||||
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 $is_changed;
|
||||
if ( $localization->is_changed ) {
|
||||
$is_changed = 1;
|
||||
$localization->store;
|
||||
}
|
||||
$response->param(
|
||||
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');
|
||||
my $localization = Koha::Localization->new(
|
||||
{
|
||||
entity => $entity,
|
||||
code => $code,
|
||||
lang => $lang,
|
||||
translation => $translation,
|
||||
}
|
||||
);
|
||||
$localization->store;
|
||||
$localization->localization_id;
|
||||
$response->param(
|
||||
id => $localization->localization_id,
|
||||
entity => $localization->entity,
|
||||
code => $localization->code,
|
||||
lang => $localization->lang,
|
||||
translation => $localization->translation,
|
||||
);
|
||||
|
||||
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 /', [ 'id' ], \&get_translations ],
|
||||
[ 'PUT /', [ 'id' ], \&update_translation ],
|
||||
[ 'POST /', [ 'entity', 'code', 'lang', 'translation' ], \&add_translation ],
|
||||
[ 'DELETE /', ['id'], \&delete_translation ],
|
||||
);
|
||||
|
|
@ -355,14 +355,13 @@ foreach my $tag (sort keys %{$tagslib}) {
|
|||
}
|
||||
$value = "";
|
||||
}
|
||||
elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
|
||||
push @authorised_values, "";
|
||||
my $sth = $dbh->prepare("select itemtype,description from itemtypes order by description");
|
||||
$sth->execute;
|
||||
while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
|
||||
push @authorised_values, $itemtype;
|
||||
$authorised_lib{$itemtype} = $description;
|
||||
}
|
||||
elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
|
||||
push @authorised_values, "";
|
||||
my $itemtypes = GetItemTypes( style => 'array' );
|
||||
for my $itemtype ( @$itemtypes ) {
|
||||
push @authorised_values, $itemtype->{itemtype};
|
||||
$authorised_lib{$itemtype->{itemtype}} = $itemtype->{translated_description};
|
||||
}
|
||||
$value = "";
|
||||
|
||||
#---- class_sources
|
||||
|
|
|
|||
Loading…
Reference in New Issue