@@ -, +, @@ content - Rename additional_contents.idnew with id - Create a new table additional_contents_localizations(id, additional_content_id, title, content, lang) that will contain the translated contents - Move the content to this new table - Remove title, content and lang columns from additional_contents - Replace the notice templates that are using ''" (should only be ISSUESLIP) and remove support for this syntax. Also add a warning in case other occurrences of uses of the old syntax exist. - We add a new Koha::AdditionalContentsLocalization[s] couple, and move some logic from Koha::AdditionalContent[s] to there. Note that, to prevent too much drastic changes in notice templates, and to make them easy to use, the different attributes of the content object is accessible from the translated content object (ie. Koha::AdditionalContentsLocatlization->library is available and return $self->additional_content->library). I think it's an elegant way to keep things simple. - No changes expected for "NewsLog" logging - Little behaviour changes for pages, see tools/page.pl changes. We are now passing the id of the content, and the desired language, instead of the mix of "page_id" or code and lang. Note that here we certainly need to rename "language" query param to not change the full interface language. a. Create notice templates that are using "<< additional_contents.code >>". This won't be replaced, but we want the update process to alert us. b. Create several news, additional contents, pages. Some with translated contents, some without. c. Make sure ISSUESLIP has the "" section. If you are using the sample data there is nothing to do here d. Turn on NewsLogs --- C4/Letters.pm | 10 +- C4/Members.pm | 24 +- Koha/AdditionalContent.pm | 62 ++++- Koha/AdditionalContents.pm | 61 ++--- Koha/AdditionalContentsLocalization.pm | 217 ++++++++++++++++++ Koha/AdditionalContentsLocalizations.pm | 52 +++++ .../prog/en/modules/intranet-main.tt | 6 +- .../en/modules/tools/additional-contents.tt | 37 +-- .../prog/en/modules/tools/page.tt | 2 +- .../bootstrap/en/modules/opac-main.tt | 2 +- .../bootstrap/en/modules/opac-news-rss.tt | 2 +- .../bootstrap/en/modules/opac-page.tt | 4 +- opac/opac-main.pl | 2 +- opac/opac-page.pl | 20 +- tools/additional-contents.pl | 209 ++++++++--------- tools/page.pl | 24 +- 16 files changed, 521 insertions(+), 213 deletions(-) create mode 100644 Koha/AdditionalContentsLocalization.pm create mode 100644 Koha/AdditionalContentsLocalizations.pm --- a/C4/Letters.pm +++ a/C4/Letters.pm @@ -762,7 +762,7 @@ sub _parseletter_sth { ($table eq 'subscription') ? "SELECT * FROM $table WHERE subscriptionid = ?" : ($table eq 'serial') ? "SELECT * FROM $table WHERE serialid = ?" : ($table eq 'problem_reports') ? "SELECT * FROM $table WHERE reportid = ?" : - ($table eq 'additional_contents' || $table eq 'opac_news') ? "SELECT * FROM additional_contents WHERE idnew = ?" : + ($table eq 'additional_contents' || $table eq 'opac_news') ? "SELECT * FROM additional_contents_localizations WHERE id = ?" : ($table eq 'recalls') ? "SELECT * FROM $table WHERE recall_id = ?" : undef ; unless ($query) { @@ -1730,16 +1730,16 @@ sub _get_tt_params { pk => 'itemnumber', }, additional_contents => { - module => 'Koha::AdditionalContents', + module => 'Koha::AdditionalContentsLocalizations', singular => 'additional_content', plural => 'additional_contents', - pk => 'idnew', + pk => 'id', }, opac_news => { - module => 'Koha::AdditionalContents', + module => 'Koha::AdditionalContentsLocalizations', singular => 'news', plural => 'news', - pk => 'idnew', + pk => 'id', }, aqorders => { module => 'Koha::Acquisition::Orders', --- a/C4/Members.pm +++ a/C4/Members.pm @@ -582,40 +582,24 @@ sub IssueSlip { issues => $all, }; } - my $news = Koha::AdditionalContents->search_for_display( + my @news_ids = Koha::AdditionalContents->search_for_display( { category => 'news', location => 'slip', lang => $patron->lang, library_id => $branch, } - ); - my @news; - while ( my $n = $news->next ) { - my $all = $n->unblessed_all_relateds; - - # FIXME We keep newdate and timestamp for backward compatibility (from GetNewsToDisplay) - # But we should remove them and adjust the existing templates in a db rev - # FIXME This must be formatted in the notice template - my $published_on_dt = output_pref({ dt => dt_from_string( $all->{published_on} ), dateonly => 1 }); - $all->{newdate} = $published_on_dt; - $all->{timestamp} = $published_on_dt; - - push @news, { - additional_contents => $all, - }; - } + )->get_column('id'); $letter_code = 'ISSUESLIP'; %repeat = ( checkedout => \@checkouts, overdue => \@overdues, - news => \@news, ); %loops = ( issues => [ map { $_->{issues}{itemnumber} } @checkouts ], overdues => [ map { $_->{issues}{itemnumber} } @overdues ], - opac_news => [ map { $_->{additional_contents}{idnew} } @news ], - additional_contents => [ map { $_->{additional_contents}{idnew} } @news ], + opac_news => \@news_ids, + additional_contents => \@news_ids, ); } --- a/Koha/AdditionalContent.pm +++ a/Koha/AdditionalContent.pm @@ -19,11 +19,11 @@ package Koha::AdditionalContent; use Modern::Perl; - use Koha::Database; use Koha::DateUtils qw( dt_from_string ); use Koha::Libraries; use Koha::Patrons; +use Koha::AdditionalContentsLocalizations; use base qw(Koha::Object); @@ -84,6 +84,66 @@ sub library { return Koha::Library->_new_from_dbic( $library_rs ); } +=head3 translated_contents + +my $translated_contents = $additional_content->translated_contents; +$additional_content->translated_contents(\@contents) + +=cut + +sub translated_contents { + my ($self, $localizations) = @_; + if ($localizations) { + my $schema = $self->_result->result_source->schema; + $schema->txn_do( + sub { + $self->translated_contents->delete; + + for my $localization (@$localizations) { + $self->_result->add_to_additional_contents_localizations($localization); + } + } + ); + } + + my $rs = $self->_result->additional_contents_localizations; + return Koha::AdditionalContentsLocalizations->_new_from_dbic($rs); +} + +=head3 default_localization + +my $default_content = $additional_content->default_localization; + +Return the default content. + +=cut + +sub default_localization { + my ($self) = @_; + my $rs = $self->_result->additional_contents_localizations->find({ lang => 'default'}); + return Koha::AdditionalContentsLocalization->_new_from_dbic($rs); +} + +=head3 translated_content + +my $translated_content = $additional_content->translated_content($lang); + +Return the translated content for a given language. The default is returned if none exist. + +=cut + +sub translated_content { + my ( $self, $lang ) = @_; + my $content = $self->translated_contents->search( + { + lang => [ 'default', ( $lang ? $lang : () ) ] + }, + { + ( $lang ? ( order_by => \[ "field(lang, '" . $lang . "', 'default')" ] ) : () ) + } + )->next; + return $content; +} =head3 _type --- a/Koha/AdditionalContents.pm +++ a/Koha/AdditionalContents.pm @@ -19,9 +19,12 @@ package Koha::AdditionalContents; use Modern::Perl; +use Array::Utils qw( array_minus ); + use Koha::Database; use Koha::Exceptions; use Koha::AdditionalContent; +use Koha::AdditionalContentsLocalizations; use base qw(Koha::Objects); @@ -70,44 +73,42 @@ sub search_for_display { my ( $self, $params ) = @_; my $search_params; - $search_params->{location} = $params->{location}; - $search_params->{branchcode} = $params->{library_id} ? [ $params->{library_id}, undef ] : undef; + $search_params->{location} = $params->{location}; + $search_params->{branchcode} = $params->{library_id} ? [ $params->{library_id}, undef ] : undef; $search_params->{published_on} = { '<=' => \'CAST(NOW() AS DATE)' }; - $search_params->{-or} = [ expirationdate => { '>=' => \'CAST(NOW() AS DATE)' }, - expirationdate => undef ]; + $search_params->{-or} = [ + expirationdate => { '>=' => \'CAST(NOW() AS DATE)' }, + expirationdate => undef + ]; $search_params->{category} = $params->{category} if $params->{category}; + my $contents = $self->SUPER::search( $search_params, { order_by => 'number' } ); + if ( $params->{lang} ) { - # FIXME I am failing to translate the following query - # SELECT a1.category, a1.code, COALESCE(a2.title, a1.title) - # FROM additional_contents a1 - # LEFT JOIN additional_contents a2 on a1.code=a2.code AND a2.lang="es-ES" - # WHERE a1.lang = 'default'; - - # So we are retrieving the code with a translated content, then the other ones - my $translated_contents = - $self->SUPER::search( { %$search_params, lang => $params->{lang} } ); - my $default_contents = $self->SUPER::search( + my $translated_contents = Koha::AdditionalContentsLocalizations->search( { - %$search_params, - lang => 'default', - code => - { '-not_in' => [ $translated_contents->get_column('code') ] } + additional_content_id => [$contents->get_column('id')], + lang => $params->{lang}, } ); - - return $self->SUPER::search( + my @all_content_id = $contents->get_column('id'); + my @translated_content_id = $translated_contents->get_column('additional_content_id'); + my $default_contents = Koha::AdditionalContentsLocalizations->search( + { + additional_content_id => [array_minus(@all_content_id, @translated_content_id)], + lang => 'default', + } + ); + return Koha::AdditionalContentsLocalizations->search( { - idnew => [ - $translated_contents->get_column('idnew'), - $default_contents->get_column('idnew') + id => [ + $translated_contents->get_column('id'), + $default_contents->get_column('id'), ] }, - { order_by => 'number' } ); } - - return $self->SUPER::search({%$search_params, lang => 'default'}, { order_by => 'number'}); + return $contents->search( { lang => 'default' }, { order_by => 'number' } )->translated_contents; } =head3 find_best_match @@ -127,13 +128,17 @@ sub find_best_match { my $library_id = $params->{library_id}; my $lang = $params->{lang}; - my $rs = $self->SUPER::search({ + my $contents = $self->SUPER::search({ category => $params->{category}, location => $params->{location}, - lang => [ $lang, 'default' ], branchcode => [ $library_id, undef ], }); + my $rs = Koha::AdditionalContentsLocalizations->search({ + additional_content_id => [ $contents->get_column('id') ], + lang => [ $lang, 'default' ], + }); + # Pick the best my ( $alt1, $alt2, $alt3 ); while( my $rec = $rs->next ) { --- a/Koha/AdditionalContentsLocalization.pm +++ a/Koha/AdditionalContentsLocalization.pm @@ -0,0 +1,217 @@ +package Koha::AdditionalContentsLocalization; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; +use Koha::AdditionalContents; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::AdditionalContentsLocalization - Koha Additional content localization object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 additional_content + + $c->additional_content; + +Return the Koha::AdditionalContent for this translated content. + +=cut + +sub additional_content { + my ( $self ) = @_; + my $rs = $self->_result->additional_content; + return Koha::AdditionalContent->_new_from_dbic($rs); +} + +=head3 author + + $c->author; + +Return the author of the content + +=cut + +sub author { + my ( $self, @params ) = @_; + return $self->additional_content->author(@params); +} + +=head3 is_expired + + $c->is_expired; + +Return $content->is_expired + +=cut + +sub is_expired { + my ( $self, @params ) = @_; + return $self->additional_content->is_expired(@params); +} + +=head3 library + + $c->library; + +Return the library of the content + +=cut + +sub library { + my ( $self, @params ) = @_; + return $self->additional_content->library(@params); +} + +=head3 category + + $c->category; + +Return the category of the content + +=cut + +sub category { + my ( $self, @params ) = @_; + return $self->additional_content->category; +} + +=head3 code + + $c->code; + +Return the code of the content + +=cut + +sub code { + my ( $self, @params ) = @_; + return $self->additional_content->code(@params); +} + +=head3 location + + $c->location; + +Return the location of the content + +=cut + +sub location { + my ( $self, @params ) = @_; + return $self->additional_content->location(@params); +} + +=head3 branchcode + + $c->branchcode; + +Return the branchcode of the content + +=cut + +sub branchcode { + my ( $self, @params ) = @_; + return $self->additional_content->branchcode(@params); +} + +=head3 published_on + + $c->published_on; + +Return the publication date of the content + +=cut + +sub published_on { + my ( $self, @params ) = @_; + return $self->additional_content->published_on(@params); +} + +=head3 updated_on + + $c->updated_on; + +Return the date of the last update of the content + +=cut + +sub updated_on { + my ( $self, @params ) = @_; + return $self->additional_content->updated_on(@params); +} + +=head3 expirationdate + + $c->expirationdate; + +Return the expiration date of the content + +=cut + +sub expirationdate { + my ( $self, @params ) = @_; + return $self->additional_content->expirationdate(@params); +} + +=head3 number + + $c->number; + +Return the number (order of display) of the content + +=cut + +sub number { + my ( $self, @params ) = @_; + return $self->additional_content->number(@params); +} + +=head3 borrowernumber + + $c->borrowernumber; + +Return the borrowernumber of the content + +=cut + +sub borrowernumber { + my ( $self, @params ) = @_; + return $self->additional_content->borrowernumber(@params); +} + +=head2 Class Methods + +=cut + +=head3 _type + +=cut + +sub _type { + return 'AdditionalContentsLocalization'; +} + +1; --- a/Koha/AdditionalContentsLocalizations.pm +++ a/Koha/AdditionalContentsLocalizations.pm @@ -0,0 +1,52 @@ +package Koha::AdditionalContentsLocalizations; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; +use Koha::Exceptions; +use Koha::AdditionalContentsLocalization; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::AdditionalContentLocalizations - Koha Additional content localization object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 _type + +=cut + +sub _type { + return 'AdditionalContentsLocalization'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::AdditionalContentsLocalization'; +} + +1; --- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt @@ -29,12 +29,12 @@

News

[% SET show_author = Koha.Preference('NewsAuthorDisplay') == 'staff' || Koha.Preference('NewsAuthorDisplay') == 'both' %] [% FOREACH koha_new IN koha_news %] -

[% koha_new.title | html %]

+

[% koha_new.title | html %]

[% koha_new.content | $raw %]

Posted on [% koha_new.published_on | $KohaDates %][% IF( show_author && koha_new.author ) %] by [% INCLUDE 'patron-title.inc' patron=koha_new.author %]
[% END %] [% IF ( CAN_user_tools_edit_additional_contents ) %] - Edit - | Delete + Edit + | Delete | New [% END %]

--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/additional-contents.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/additional-contents.tt @@ -64,7 +64,7 @@
  • - [% IF additional_content.idnew %] + [% IF additional_content.id %] Modify additional content [% ELSE %] Add additional content @@ -208,7 +208,7 @@ - +
    @@ -283,16 +283,18 @@ [% WRAPPER tab_panels %] [% FOR language IN languages %] + [% SET translated_content = translated_contents.item(language.lang) %] [% WRAPPER tab_panel tabname="lang_${language.lang}" %]
    1. - +
    2. - + +
    @@ -367,9 +369,10 @@ [% FOREACH c IN additional_contents%] + [% SET default_localization = c.default_localization %] [% IF ( c.is_expired ) %][% ELSE %][% END %] - + [% IF c.category == 'news' || c.category == 'pages' %] @@ -392,22 +395,22 @@ [% c.number | html %] [% c.published_on | $KohaDates %] [% c.expirationdate | $KohaDates %] [% IF ( c.is_expired ) %](expired)[% END %] - [% c.title | html %] + [% default_localization.title | html %] [% IF ( c.author) %][% INCLUDE 'patron-title.inc' patron=c.author %][% END %] [% IF category == 'pages' %] [% IF c.location == 'opac_only' OR c.location == 'staff_and_opac' %] OPAC: -
    Default + Default OR - Current language + Current language [% END %] [% IF c.location == 'staff_only' OR c.location == 'staff_and_opac' %] [% IF c.location == 'staff_and_opac' %]
    [% END %] Staff interface: - Default + Default OR - Current language + Current language [% END %] [% END %] @@ -419,10 +422,10 @@