View | Details | Raw Unified | Return to bug 14757
Collapse All | Expand All

(-)a/C4/Letters.pm (-68 / +83 lines)
Lines 122-128 sub GetLetterTemplates { Link Here
122
    my $dbh       = C4::Context->dbh;
122
    my $dbh       = C4::Context->dbh;
123
    my $letters   = $dbh->selectall_hashref(
123
    my $letters   = $dbh->selectall_hashref(
124
        q|
124
        q|
125
            SELECT module, code, branchcode, name, is_html, title, content, message_transport_type
125
            SELECT module, code, branchcode, name, is_html, title, content, message_transport_type, is_tt
126
            FROM letter
126
            FROM letter
127
            WHERE module = ?
127
            WHERE module = ?
128
            AND code = ?
128
            AND code = ?
Lines 640-728 sub GetPreparedLetter { Link Here
640
        or warn( "No $module $letter_code letter transported by " . $mtt ),
640
        or warn( "No $module $letter_code letter transported by " . $mtt ),
641
            return;
641
            return;
642
642
643
    my $tables = $params{tables};
643
    my $tables     = $params{tables};
644
    my $substitute = $params{substitute};
644
    my $substitute = $params{substitute};
645
    my $repeat = $params{repeat};
645
    my $repeat     = $params{repeat};
646
646
    $tables || $substitute || $repeat
647
    $tables || $substitute || $repeat
647
      or carp( "ERROR: nothing to substitute - both 'tables' and 'substitute' are empty" ),
648
      or carp( "ERROR: nothing to substitute - both 'tables' and 'substitute' are empty" ),
648
         return;
649
         return;
649
    my $want_librarian = $params{want_librarian};
650
650
651
    if ($substitute) {
651
    my $userenv = C4::Context->userenv;
652
        while ( my ($token, $val) = each %$substitute ) {
653
            if ( $token eq 'items.content' ) {
654
                $val =~ s|\n|<br/>|g if $letter->{is_html};
655
            }
656
652
657
            $letter->{title} =~ s/<<$token>>/$val/g;
653
    if ( $letter->{is_tt} ) {
658
            $letter->{content} =~ s/<<$token>>/$val/g;
654
        $letter->{content} = _process_tt(
659
       }
655
            {
656
                content => $letter->{content},
657
                tables  => $tables,
658
                tt_params  => {
659
                    today     => dt_from_string(),
660
                    librarian => {
661
                        firstname    => $userenv->{firstname},
662
                        surname      => $userenv->{surname},
663
                        emailaddress => $userenv->{emailaddress},
664
                    },
665
                }
666
            }
667
        );
660
    }
668
    }
669
    else {
670
        my $want_librarian = $params{want_librarian};
661
671
662
    my $OPACBaseURL = C4::Context->preference('OPACBaseURL');
672
        if ($substitute) {
663
    $letter->{content} =~ s/<<OPACBaseURL>>/$OPACBaseURL/go;
673
            while ( my ($token, $val) = each %$substitute ) {
674
                if ( $token eq 'items.content' ) {
675
                    $val =~ s|\n|<br/>|g if $letter->{is_html};
676
                }
664
677
665
    if ($want_librarian) {
678
                $letter->{title} =~ s/<<$token>>/$val/g;
666
        # parsing librarian name
679
                $letter->{content} =~ s/<<$token>>/$val/g;
667
        my $userenv = C4::Context->userenv;
680
           }
668
        $letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/go;
681
        }
669
        $letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/go;
670
        $letter->{content} =~ s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/go;
671
    }
672
682
673
    my ($repeat_no_enclosing_tags, $repeat_enclosing_tags);
683
        my $OPACBaseURL = C4::Context->preference('OPACBaseURL');
684
        $letter->{content} =~ s/<<OPACBaseURL>>/$OPACBaseURL/go;
674
685
675
    if ($repeat) {
686
        if ($want_librarian) {
676
        if (ref ($repeat) eq 'ARRAY' ) {
687
            # parsing librarian name
677
            $repeat_no_enclosing_tags = $repeat;
688
            $letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/go;
678
        } else {
689
            $letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/go;
679
            $repeat_enclosing_tags = $repeat;
690
            $letter->{content} =~ s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/go;
680
        }
691
        }
681
    }
682
692
683
    if ($repeat_enclosing_tags) {
693
        my ($repeat_no_enclosing_tags, $repeat_enclosing_tags);
684
        while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) {
694
685
            if ( $letter->{content} =~ m!<$tag>(.*)</$tag>!s ) {
695
        if ($repeat) {
686
                my $subcontent = $1;
696
            if (ref ($repeat) eq 'ARRAY' ) {
687
                my @lines = map {
697
                $repeat_no_enclosing_tags = $repeat;
688
                    my %subletter = ( title => '', content => $subcontent );
698
            } else {
689
                    _substitute_tables( \%subletter, $_ );
699
                $repeat_enclosing_tags = $repeat;
690
                    $subletter{content};
691
                } @$tag_tables;
692
                $letter->{content} =~ s!<$tag>.*</$tag>!join( "\n", @lines )!se;
693
            }
700
            }
694
        }
701
        }
695
    }
696
697
    if ($tables) {
698
        _substitute_tables( $letter, $tables );
699
    }
700
702
701
    if ($repeat_no_enclosing_tags) {
703
        if ($repeat_enclosing_tags) {
702
        if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) {
704
            while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) {
703
            my $line = $&;
705
                if ( $letter->{content} =~ m!<$tag>(.*)</$tag>!s ) {
704
            my $i = 1;
706
                    my $subcontent = $1;
705
            my @lines = map {
707
                    my @lines = map {
706
                my $c = $line;
708
                        my %subletter = ( title => '', content => $subcontent );
707
                $c =~ s/<<count>>/$i/go;
709
                        _substitute_tables( \%subletter, $_ );
708
                foreach my $field ( keys %{$_} ) {
710
                        $subletter{content};
709
                    $c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/;
711
                    } @$tag_tables;
712
                    $letter->{content} =~ s!<$tag>.*</$tag>!join( "\n", @lines )!se;
710
                }
713
                }
711
                $i++;
714
            }
712
                $c;
715
        }
713
            } @$repeat_no_enclosing_tags;
714
716
715
            my $replaceby = join( "\n", @lines );
717
        if ($tables) {
716
            $letter->{content} =~ s/\Q$line\E/$replaceby/s;
718
            _substitute_tables( $letter, $tables );
717
        }
719
        }
718
    }
719
720
720
    $letter->{content} = _process_tt(
721
        if ($repeat_no_enclosing_tags) {
721
        {
722
            if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) {
722
            content => $letter->{content},
723
                my $line = $&;
723
            tables  => $tables,
724
                my $i = 1;
725
                my @lines = map {
726
                    my $c = $line;
727
                    $c =~ s/<<count>>/$i/go;
728
                    foreach my $field ( keys %{$_} ) {
729
                        $c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/;
730
                    }
731
                    $i++;
732
                    $c;
733
                } @$repeat_no_enclosing_tags;
734
735
                my $replaceby = join( "\n", @lines );
736
                $letter->{content} =~ s/\Q$line\E/$replaceby/s;
737
            }
724
        }
738
        }
725
    );
739
740
    }
726
741
727
    $letter->{content} =~ s/<<\S*>>//go; #remove any stragglers
742
    $letter->{content} =~ s/<<\S*>>//go; #remove any stragglers
728
743
Lines 1327-1334 sub _set_message_status { Link Here
1327
sub _process_tt {
1342
sub _process_tt {
1328
    my ( $params ) = @_;
1343
    my ( $params ) = @_;
1329
1344
1330
    my $content = $params->{content};
1345
    my $content   = $params->{content};
1331
    my $tables = $params->{tables};
1346
    my $tables    = $params->{tables};
1347
    my $tt_params = $params->{tt_params};
1332
1348
1333
    my $use_template_cache = C4::Context->config('template_cache_dir') && defined $ENV{GATEWAY_INTERFACE};
1349
    my $use_template_cache = C4::Context->config('template_cache_dir') && defined $ENV{GATEWAY_INTERFACE};
1334
    my $template           = Template->new(
1350
    my $template           = Template->new(
Lines 1343-1349 sub _process_tt { Link Here
1343
        }
1359
        }
1344
    ) or die Template->error();
1360
    ) or die Template->error();
1345
1361
1346
    my $tt_params = _get_tt_params( $tables );
1362
    my $tt_objects = _get_tt_params( $tables );
1363
    $tt_params = { %$tt_params, %$tt_objects };
1347
1364
1348
    my $output;
1365
    my $output;
1349
    $template->process( \$content, $tt_params, \$output ) || croak "ERROR PROCESSING TEMPLATE: " . $template->error();
1366
    $template->process( \$content, $tt_params, \$output ) || croak "ERROR PROCESSING TEMPLATE: " . $template->error();
Lines 1464-1471 sub _get_tt_params { Link Here
1464
        }
1481
        }
1465
    }
1482
    }
1466
1483
1467
    $params->{today} = dt_from_string();
1468
1469
    return $params;
1484
    return $params;
1470
}
1485
}
1471
1486
(-)a/installer/data/mysql/atomicupdate/bug_14757.sql (+4 lines)
Line 0 Link Here
1
ALTER TABLE letter ADD is_tt TINYINT(1) NOT NULL DEFAULT 0 AFTER message_transport_type;
2
3
INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
4
('TemplateToolkitNotices',0,'','Enable the ability to use Template Toolkit syntax in slips and notices','YesNo');
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 1423-1428 CREATE TABLE `letter` ( -- table for all notice templates in Koha Link Here
1423
  `title` varchar(200) NOT NULL default '', -- subject line of the notice
1423
  `title` varchar(200) NOT NULL default '', -- subject line of the notice
1424
  `content` text, -- body text for the notice or slip
1424
  `content` text, -- body text for the notice or slip
1425
  `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice
1425
  `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice
1426
  `is_tt` TINYINT(1) NOT NULL DEFAULT 0, -- controls if notice should be processed as template toolkit syntax
1426
  PRIMARY KEY  (`module`,`code`, `branchcode`, `message_transport_type`),
1427
  PRIMARY KEY  (`module`,`code`, `branchcode`, `message_transport_type`),
1427
  CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`)
1428
  CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`)
1428
  REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE
1429
  REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 469-474 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
469
('TagsModeration','0','','Require tags from patrons to be approved before becoming visible.','YesNo'),
469
('TagsModeration','0','','Require tags from patrons to be approved before becoming visible.','YesNo'),
470
('TagsShowOnDetail','10','','Number of tags to display on detail page.  0 is off.','Integer'),
470
('TagsShowOnDetail','10','','Number of tags to display on detail page.  0 is off.','Integer'),
471
('TagsShowOnList','6','','Number of tags to display on search results list.  0 is off.','Integer'),
471
('TagsShowOnList','6','','Number of tags to display on search results list.  0 is off.','Integer'),
472
('TemplateToolkitNotices',0,'','Enable the ability to use Template Toolkit syntax in slips and notices','YesNo'),
472
('template','prog','','Define the preferred staff interface template','Themes'),
473
('template','prog','','Define the preferred staff interface template','Themes'),
473
('ThingISBN','0','','Use with FRBRizeEditions. If ON, Koha will use the ThingISBN web service in the Editions tab on the detail pages.','YesNo'),
474
('ThingISBN','0','','Use with FRBRizeEditions. If ON, Koha will use the ThingISBN web service in the Editions tab on the detail pages.','YesNo'),
474
('TimeFormat','24hr','12hr|24hr','Defines the global time format for visual output.','Choice'),
475
('TimeFormat','24hr','12hr|24hr','Defines the global time format for visual output.','Choice'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/labs.pref (+9 lines)
Lines 9-11 Labs: Link Here
9
            - the advanced cataloging editor.
9
            - the advanced cataloging editor.
10
            - "<br/> NOTE:"
10
            - "<br/> NOTE:"
11
            - 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.
11
            - 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.
12
        -
13
            - pref: TemplateToolkitNotices
14
              default: 0
15
              choices:
16
                  yes: Enable
17
                  no: "Don't enable"
18
            - the ability to use Template Toolkit syntax in slips and notices.
19
            - "<br/> NOTE:"
20
            - This feature is currently experimental, the specific variables available may be subject to change.
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt (+13 lines)
Lines 394-405 $(document).ready(function() { Link Here
394
              <ol>
394
              <ol>
395
                <li>
395
                <li>
396
                  <input type="hidden" name="message_transport_type" value="[% letter.message_transport_type %]" />
396
                  <input type="hidden" name="message_transport_type" value="[% letter.message_transport_type %]" />
397
397
                  <label for="is_html_[% letter.message_transport_type %]">HTML message:</label>
398
                  <label for="is_html_[% letter.message_transport_type %]">HTML message:</label>
398
                  [% IF letter.is_html %]
399
                  [% IF letter.is_html %]
399
                    <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" checked="checked" />
400
                    <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" checked="checked" />
400
                  [% ELSE %]
401
                  [% ELSE %]
401
                    <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" />
402
                    <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" />
402
                  [% END %]
403
                  [% END %]
404
405
                  [% IF Koha.Preference('TemplateToolkitNotices') %]
406
                      <br />
407
408
                      <label for="is_tt_[% letter.message_transport_type %]">Template Toolkit:</label>
409
                      [% IF letter.is_tt %]
410
                        <input type="checkbox" name="is_tt_[% letter.message_transport_type %]" id="is_tt_[% letter.message_transport_type %]" value="1" checked="checked" />
411
                      [% ELSE %]
412
                        <input type="checkbox" name="is_tt_[% letter.message_transport_type %]" id="is_tt_[% letter.message_transport_type %]" value="1" />
413
                      [% END %]
414
                      <i>Enables the use of the new experimental Template Toolkit syntax parser instead of the current syntax parser.</i>
415
                  [% END %]
403
                </li>
416
                </li>
404
                <li>
417
                <li>
405
                  <label for="title_[% letter.message_transport_type %]">Message subject:</label><input type="text" id="title_[% letter.message_transport_type %]" name="title" size="60" value="[% letter.title %]" />
418
                  <label for="title_[% letter.message_transport_type %]">Message subject:</label><input type="text" id="title_[% letter.message_transport_type %]" name="title" size="60" value="[% letter.title %]" />
(-)a/t/db_dependent/Letters/TemplateToolkit.t (-1 / +1 lines)
Lines 92-98 my $modification = Koha::Borrower::Modification->new( { verification_token => "T Link Here
92
my $prepared_letter;
92
my $prepared_letter;
93
93
94
my $sth =
94
my $sth =
95
  $dbh->prepare(q{INSERT INTO letter (module, code, name, title, content) VALUES ('test',?,'Test','Test',?)});
95
  $dbh->prepare(q{INSERT INTO letter (module, code, name, title, is_tt, content) VALUES ('test',?,'Test','Test',1,?)});
96
96
97
$sth->execute( "TEST_PATRON", "[% borrower.id %]" );
97
$sth->execute( "TEST_PATRON", "[% borrower.id %]" );
98
$prepared_letter = GetPreparedLetter(
98
$prepared_letter = GetPreparedLetter(
(-)a/tools/letter.pl (-5 / +6 lines)
Lines 170-175 sub add_form { Link Here
170
            push @letter_loop, {
170
            push @letter_loop, {
171
                message_transport_type => $mtt,
171
                message_transport_type => $mtt,
172
                is_html    => $letters->{$mtt}{is_html},
172
                is_html    => $letters->{$mtt}{is_html},
173
                is_tt      => $letters->{$mtt}{is_tt},
173
                title      => $letters->{$mtt}{title},
174
                title      => $letters->{$mtt}{title},
174
                content    => $letters->{$mtt}{content}//'',
175
                content    => $letters->{$mtt}{content}//'',
175
            };
176
            };
Lines 259-264 sub add_validate { Link Here
259
    my @content       = $input->param('content');
260
    my @content       = $input->param('content');
260
    for my $mtt ( @mtt ) {
261
    for my $mtt ( @mtt ) {
261
        my $is_html = $input->param("is_html_$mtt");
262
        my $is_html = $input->param("is_html_$mtt");
263
        my $is_tt = $input->param("is_tt_$mtt");
262
        my $title   = shift @title;
264
        my $title   = shift @title;
263
        my $content = shift @content;
265
        my $content = shift @content;
264
        my $letter = C4::Letters::getletter( $oldmodule, $code, $branchcode, $mtt);
266
        my $letter = C4::Letters::getletter( $oldmodule, $code, $branchcode, $mtt);
Lines 277-294 sub add_validate { Link Here
277
            $dbh->do(
279
            $dbh->do(
278
                q{
280
                q{
279
                    UPDATE letter
281
                    UPDATE letter
280
                    SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?
282
                    SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?, is_tt = ?
281
                    WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?
283
                    WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?
282
                },
284
                },
283
                undef,
285
                undef,
284
                $branchcode || '', $module, $name, $is_html || 0, $title, $content,
286
                $branchcode || '', $module, $name, $is_html || 0, $title, $content, $is_tt,
285
                $branchcode, $oldmodule, $code, $mtt
287
                $branchcode, $oldmodule, $code, $mtt
286
            );
288
            );
287
        } else {
289
        } else {
288
            $dbh->do(
290
            $dbh->do(
289
                q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)},
291
                q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type,is_tt) VALUES (?,?,?,?,?,?,?,?,?)},
290
                undef,
292
                undef,
291
                $branchcode || '', $module, $code, $name, $is_html || 0, $title, $content, $mtt
293
                $branchcode || '', $module, $code, $name, $is_html || 0, $title, $content, $mtt, $is_tt
292
            );
294
            );
293
        }
295
        }
294
    }
296
    }
295
- 

Return to bug 14757