From 53fccd5f59d845f6af9a157251db49980630c3b3 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Wed, 10 Feb 2016 15:18:49 +0000 Subject: [PATCH] Bug 14757 [QA Followup] - Make the use of TT a controllable switch, hide it behind a syspref Signed-off-by: Sean McGarvey --- C4/Letters.pm | 151 +++++++++++---------- installer/data/mysql/atomicupdate/bug_14757.sql | 4 + installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 1 + .../prog/en/modules/admin/preferences/labs.pref | 9 ++ .../intranet-tmpl/prog/en/modules/tools/letter.tt | 13 ++ t/db_dependent/Letters/TemplateToolkit.t | 2 +- tools/letter.pl | 10 +- 8 files changed, 118 insertions(+), 73 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_14757.sql diff --git a/C4/Letters.pm b/C4/Letters.pm index 1ca7663..166bce3 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -124,7 +124,7 @@ sub GetLetterTemplates { my $dbh = C4::Context->dbh; my $letters = $dbh->selectall_hashref( q| - SELECT module, code, branchcode, name, is_html, title, content, message_transport_type + SELECT module, code, branchcode, name, is_html, title, content, message_transport_type, is_tt FROM letter WHERE module = ? AND code = ? @@ -642,89 +642,104 @@ sub GetPreparedLetter { or warn( "No $module $letter_code letter transported by " . $mtt ), return; - my $tables = $params{tables}; + my $tables = $params{tables}; my $substitute = $params{substitute}; - my $repeat = $params{repeat}; + my $repeat = $params{repeat}; + $tables || $substitute || $repeat or carp( "ERROR: nothing to substitute - both 'tables' and 'substitute' are empty" ), return; - my $want_librarian = $params{want_librarian}; - if ($substitute) { - while ( my ($token, $val) = each %$substitute ) { - if ( $token eq 'items.content' ) { - $val =~ s|\n|
|g if $letter->{is_html}; - } + my $userenv = C4::Context->userenv; - $letter->{title} =~ s/<<$token>>/$val/g; - $letter->{content} =~ s/<<$token>>/$val/g; - } + if ( $letter->{is_tt} ) { + $letter->{content} = _process_tt( + { + content => $letter->{content}, + tables => $tables, + tt_params => { + today => dt_from_string(), + librarian => { + firstname => $userenv->{firstname}, + surname => $userenv->{surname}, + emailaddress => $userenv->{emailaddress}, + }, + } + } + ); } + else { + my $want_librarian = $params{want_librarian}; - my $OPACBaseURL = C4::Context->preference('OPACBaseURL'); - $letter->{content} =~ s/<>/$OPACBaseURL/go; + if ($substitute) { + while ( my ($token, $val) = each %$substitute ) { + if ( $token eq 'items.content' ) { + $val =~ s|\n|
|g if $letter->{is_html}; + } - if ($want_librarian) { - # parsing librarian name - my $userenv = C4::Context->userenv; - $letter->{content} =~ s/<>/$userenv->{firstname}/go; - $letter->{content} =~ s/<>/$userenv->{surname}/go; - $letter->{content} =~ s/<>/$userenv->{emailaddress}/go; - } + $letter->{title} =~ s/<<$token>>/$val/g; + $letter->{content} =~ s/<<$token>>/$val/g; + } + } - my ($repeat_no_enclosing_tags, $repeat_enclosing_tags); + my $OPACBaseURL = C4::Context->preference('OPACBaseURL'); + $letter->{content} =~ s/<>/$OPACBaseURL/go; - if ($repeat) { - if (ref ($repeat) eq 'ARRAY' ) { - $repeat_no_enclosing_tags = $repeat; - } else { - $repeat_enclosing_tags = $repeat; + if ($want_librarian) { + # parsing librarian name + $letter->{content} =~ s/<>/$userenv->{firstname}/go; + $letter->{content} =~ s/<>/$userenv->{surname}/go; + $letter->{content} =~ s/<>/$userenv->{emailaddress}/go; } - } - if ($repeat_enclosing_tags) { - while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) { - if ( $letter->{content} =~ m!<$tag>(.*)!s ) { - my $subcontent = $1; - my @lines = map { - my %subletter = ( title => '', content => $subcontent ); - _substitute_tables( \%subletter, $_ ); - $subletter{content}; - } @$tag_tables; - $letter->{content} =~ s!<$tag>.*!join( "\n", @lines )!se; + my ($repeat_no_enclosing_tags, $repeat_enclosing_tags); + + if ($repeat) { + if (ref ($repeat) eq 'ARRAY' ) { + $repeat_no_enclosing_tags = $repeat; + } else { + $repeat_enclosing_tags = $repeat; } } - } - - if ($tables) { - _substitute_tables( $letter, $tables ); - } - if ($repeat_no_enclosing_tags) { - if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) { - my $line = $&; - my $i = 1; - my @lines = map { - my $c = $line; - $c =~ s/<>/$i/go; - foreach my $field ( keys %{$_} ) { - $c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/; + if ($repeat_enclosing_tags) { + while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) { + if ( $letter->{content} =~ m!<$tag>(.*)!s ) { + my $subcontent = $1; + my @lines = map { + my %subletter = ( title => '', content => $subcontent ); + _substitute_tables( \%subletter, $_ ); + $subletter{content}; + } @$tag_tables; + $letter->{content} =~ s!<$tag>.*!join( "\n", @lines )!se; } - $i++; - $c; - } @$repeat_no_enclosing_tags; + } + } - my $replaceby = join( "\n", @lines ); - $letter->{content} =~ s/\Q$line\E/$replaceby/s; + if ($tables) { + _substitute_tables( $letter, $tables ); } - } - $letter->{content} = _process_tt( - { - content => $letter->{content}, - tables => $tables, + if ($repeat_no_enclosing_tags) { + if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) { + my $line = $&; + my $i = 1; + my @lines = map { + my $c = $line; + $c =~ s/<>/$i/go; + foreach my $field ( keys %{$_} ) { + $c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/; + } + $i++; + $c; + } @$repeat_no_enclosing_tags; + + my $replaceby = join( "\n", @lines ); + $letter->{content} =~ s/\Q$line\E/$replaceby/s; + } } - ); + + } $letter->{content} =~ s/<<\S*>>//go; #remove any stragglers @@ -1387,8 +1402,9 @@ sub _set_message_status { sub _process_tt { my ( $params ) = @_; - my $content = $params->{content}; - my $tables = $params->{tables}; + my $content = $params->{content}; + my $tables = $params->{tables}; + my $tt_params = $params->{tt_params}; my $use_template_cache = C4::Context->config('template_cache_dir') && defined $ENV{GATEWAY_INTERFACE}; my $template = Template->new( @@ -1403,7 +1419,8 @@ sub _process_tt { } ) or die Template->error(); - my $tt_params = _get_tt_params( $tables ); + my $tt_objects = _get_tt_params( $tables ); + $tt_params = { %$tt_params, %$tt_objects }; my $output; $template->process( \$content, $tt_params, \$output ) || croak "ERROR PROCESSING TEMPLATE: " . $template->error(); @@ -1524,8 +1541,6 @@ sub _get_tt_params { } } - $params->{today} = dt_from_string(); - return $params; } diff --git a/installer/data/mysql/atomicupdate/bug_14757.sql b/installer/data/mysql/atomicupdate/bug_14757.sql new file mode 100644 index 0000000..5cbe8c7 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_14757.sql @@ -0,0 +1,4 @@ +ALTER TABLE letter ADD is_tt TINYINT(1) NOT NULL DEFAULT 0 AFTER message_transport_type; + +INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES +('TemplateToolkitNotices',0,'','Enable the ability to use Template Toolkit syntax in slips and notices','YesNo'); diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index d4d2f5f..1488335 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1430,6 +1430,7 @@ CREATE TABLE `letter` ( -- table for all notice templates in Koha `title` varchar(200) NOT NULL default '', -- subject line of the notice `content` text, -- body text for the notice or slip `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice + `is_tt` TINYINT(1) NOT NULL DEFAULT 0, -- controls if notice should be processed as template toolkit syntax PRIMARY KEY (`module`,`code`, `branchcode`, `message_transport_type`), CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`) REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index e2e3ad2..71870aa 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -476,6 +476,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('TagsModeration','0','','Require tags from patrons to be approved before becoming visible.','YesNo'), ('TagsShowOnDetail','10','','Number of tags to display on detail page. 0 is off.','Integer'), ('TagsShowOnList','6','','Number of tags to display on search results list. 0 is off.','Integer'), +('TemplateToolkitNotices',0,'','Enable the ability to use Template Toolkit syntax in slips and notices','YesNo'), ('template','prog','','Define the preferred staff interface template','Themes'), ('ThingISBN','0','','Use with FRBRizeEditions. If ON, Koha will use the ThingISBN web service in the Editions tab on the detail pages.','YesNo'), ('TimeFormat','24hr','12hr|24hr','Defines the global time format for visual output.','Choice'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/labs.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/labs.pref index 34fb6cd..a06755b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/labs.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/labs.pref @@ -9,3 +9,12 @@ Labs: - the advanced cataloging editor. - "
NOTE:" - This feature is currently experimental, and may have bugs that cause corruption of records. It also does not include any support for UNIMARC or NORMARC fixed fields. Please help us test it and report any bugs, but do so at your own risk. + - + - pref: TemplateToolkitNotices + default: 0 + choices: + yes: Enable + no: "Don't enable" + - the ability to use Template Toolkit syntax in slips and notices. + - "
NOTE:" + - This feature is currently experimental, the specific variables available may be subject to change. diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 1f7ad2b..0ab869f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -394,12 +394,25 @@ $(document).ready(function() {
  1. + [% IF letter.is_html %] [% ELSE %] [% END %] + + [% IF Koha.Preference('TemplateToolkitNotices') %] +
    + + + [% IF letter.is_tt %] + + [% ELSE %] + + [% END %] + Enables the use of the new experimental Template Toolkit syntax parser instead of the current syntax parser. + [% END %]
  2. diff --git a/t/db_dependent/Letters/TemplateToolkit.t b/t/db_dependent/Letters/TemplateToolkit.t index 4005dbb..a9c7096 100644 --- a/t/db_dependent/Letters/TemplateToolkit.t +++ b/t/db_dependent/Letters/TemplateToolkit.t @@ -92,7 +92,7 @@ my $modification = Koha::Borrower::Modification->new( { verification_token => "T my $prepared_letter; my $sth = - $dbh->prepare(q{INSERT INTO letter (module, code, name, title, content) VALUES ('test',?,'Test','Test',?)}); + $dbh->prepare(q{INSERT INTO letter (module, code, name, title, is_tt, content) VALUES ('test',?,'Test','Test',1,?)}); $sth->execute( "TEST_PATRON", "[% borrower.id %]" ); $prepared_letter = GetPreparedLetter( diff --git a/tools/letter.pl b/tools/letter.pl index 293072f..e1833c3 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -170,6 +170,7 @@ sub add_form { push @letter_loop, { message_transport_type => $mtt, is_html => $letters->{$mtt}{is_html}, + is_tt => $letters->{$mtt}{is_tt}, title => $letters->{$mtt}{title}, content => $letters->{$mtt}{content}//'', }; @@ -259,6 +260,7 @@ sub add_validate { my @content = $input->param('content'); for my $mtt ( @mtt ) { my $is_html = $input->param("is_html_$mtt"); + my $is_tt = $input->param("is_tt_$mtt"); my $title = shift @title; my $content = shift @content; my $letter = C4::Letters::getletter( $oldmodule, $code, $branchcode, $mtt); @@ -277,18 +279,18 @@ sub add_validate { $dbh->do( q{ UPDATE letter - SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ? + SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?, is_tt = ? WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ? }, undef, - $branchcode || '', $module, $name, $is_html || 0, $title, $content, + $branchcode || '', $module, $name, $is_html || 0, $title, $content, $is_tt, $branchcode, $oldmodule, $code, $mtt ); } else { $dbh->do( - q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)}, + q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type,is_tt) VALUES (?,?,?,?,?,?,?,?,?)}, undef, - $branchcode || '', $module, $code, $name, $is_html || 0, $title, $content, $mtt + $branchcode || '', $module, $code, $name, $is_html || 0, $title, $content, $mtt, $is_tt ); } } -- 2.1.4