Bugzilla – Attachment 38727 Details for
Bug 14100
Add base to make item types, branch names, sysprefs values and authorised values translatable
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14100: [POC] Generic solution for language overlay
Bug-14100-POC-Generic-solution-for-language-overla.patch (text/plain), 24.02 KB, created by
Jonathan Druart
on 2015-04-30 15:59:26 UTC
(
hide
)
Description:
Bug 14100: [POC] Generic solution for language overlay
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2015-04-30 15:59:26 UTC
Size:
24.02 KB
patch
obsolete
>From a3988d9826253a630437269b9b25dd90c9a0b0a3 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@biblibre.com> >Date: Thu, 30 Apr 2015 17:30:47 +0200 >Subject: [PATCH] Bug 14100: [POC] Generic solution for language overlay > >This is a proof of concept! > >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. > >Think further / Todo: >1/ Update all occurrences of the item type's description >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). >--- > C4/Koha.pm | 23 ++- > Koha/Localization.pm | 13 ++ > Koha/Localizations.pm | 19 ++ > admin/itemtypes.pl | 40 ++-- > admin/localization.pl | 54 ++++++ > .../Bug_14100-add_table_localization.sql | 8 + > installer/data/mysql/kohastructure.sql | 14 ++ > .../prog/en/modules/admin/itemtypes.tt | 9 +- > .../prog/en/modules/admin/localization.tt | 206 +++++++++++++++++++++ > svc/localization | 92 +++++++++ > 10 files changed, 456 insertions(+), 22 deletions(-) > create mode 100644 Koha/Localization.pm > create mode 100644 Koha/Localizations.pm > create mode 100755 admin/localization.pl > create mode 100644 installer/data/mysql/atomicupdate/Bug_14100-add_table_localization.sql > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt > create mode 100755 svc/localization > >diff --git a/C4/Koha.pm b/C4/Koha.pm >index 23fbfee..04fb5c4 100644 >--- a/C4/Koha.pm >+++ b/C4/Koha.pm >@@ -253,15 +253,32 @@ sub GetItemTypes { > my ( %params ) = @_; > my $style = defined( $params{'style'} ) ? $params{'style'} : 'hash'; > >+ my $language = C4::Languages::getlanguage(); >+ $language =~ s|^(.*)-.*$|$1|; > # 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.gstrate, >+ 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 ) { >diff --git a/Koha/Localization.pm b/Koha/Localization.pm >new file mode 100644 >index 0000000..40a3f62 >--- /dev/null >+++ b/Koha/Localization.pm >@@ -0,0 +1,13 @@ >+package Koha::Localization; >+ >+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 >new file mode 100644 >index 0000000..aa3e183 >--- /dev/null >+++ b/Koha/Localizations.pm >@@ -0,0 +1,19 @@ >+package Koha::Localizations; >+ >+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/admin/itemtypes.pl b/admin/itemtypes.pl >index 9effa7e..8d9b4f9 100755 >--- a/admin/itemtypes.pl >+++ b/admin/itemtypes.pl >@@ -52,19 +52,6 @@ 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() ... ] >-} >- > my $input = new CGI; > my $searchfield = $input->param('description'); > my $script_name = "/cgi-bin/koha/admin/itemtypes.pl"; >@@ -100,8 +87,28 @@ 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.gstrate, >+ 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(); >+ $language =~ s|^(.*)-.*$|$1|; >+ $sth->execute($language, $itemtype); > $data = $sth->fetchrow_hashref; > } > >@@ -245,7 +252,8 @@ elsif ( $op eq 'delete_confirmed' ) { > ################## DEFAULT ################################## > } > else { # DEFAULT >- my ($results) = StringSearch( $searchfield, 'web' ); >+ my $results = C4::Koha::GetItemTypes( style => 'array' ); >+ warn Data::Dumper::Dumper $results; > my @loop; > foreach my $itemtype ( @{$results} ) { > $itemtype->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtype->{imageurl} ); >diff --git a/admin/localization.pl b/admin/localization.pl >new file mode 100755 >index 0000000..93dc4a8 >--- /dev/null >+++ b/admin/localization.pl >@@ -0,0 +1,54 @@ >+#!/usr/bin/perl >+ >+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 $languages = [ map { >+ { >+ lang => $_->{subtag}, >+ description => ($_->{language_description} or $_->{description} or $_->{language}), >+ } >+} @{ C4::Languages::getAllLanguages() } ]; >+ >+$template->param( >+ translations => \@translations, >+ languages => $languages, >+ entity => $entity, >+ code => $code, >+); >+ >+output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/installer/data/mysql/atomicupdate/Bug_14100-add_table_localization.sql b/installer/data/mysql/atomicupdate/Bug_14100-add_table_localization.sql >new file mode 100644 >index 0000000..83bdb9d >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/Bug_14100-add_table_localization.sql >@@ -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; >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index efb2f9a..e1882d4 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -3505,6 +3505,20 @@ CREATE TABLE items_search_fields ( > ON DELETE SET NULL 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 */; >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 2e61a16..ebbce22 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt >@@ -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[ >@@ -108,7 +109,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> > [% 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> >@@ -237,7 +240,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"> >@@ -273,7 +276,7 @@ Item types administration > [% loo.itemtype %] > </a> > </td> >- <td>[% loo.description %]</td> >+ <td>[% loo.translated_description %]</td> > <td>[% IF ( loo.notforloan ) %]Yes[% ELSE %] [% END %]</td> > <td> > [% UNLESS ( loo.notforloan ) %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt >new file mode 100644 >index 0000000..fd4846a >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/localization.tt >@@ -0,0 +1,206 @@ >+[% 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 %] >+ <option value="[% language.lang %]">[% language.description %]</option> >+ [% END %] >+ </select> >+ Translation: <input type="text" name="translation" /> >+ <input type="submit" value="Add" /> >+</form> >+<div id="messages"></div> >+</div> >+</body> >+</html> >diff --git a/svc/localization b/svc/localization >new file mode 100755 >index 0000000..ebec0e2 >--- /dev/null >+++ b/svc/localization >@@ -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 ], >+); >-- >2.1.0
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 14100
:
38727
|
40917
|
40965
|
41654
|
41659
|
41660
|
42525
|
42526
|
43110
|
43111
|
43365
|
43366
|
43367
|
43368
|
43369
|
43370
|
43394
|
43395
|
43396
|
43577
|
43602
|
43603
|
43604
|
43605
|
43606
|
43613
|
44085
|
44086
|
44087
|
44088
|
44089
|
44090
|
44094
|
44108
|
44109
|
44119
|
44151