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

(-)a/C4/Letters.pm (-68 / +83 lines)
Lines 124-130 sub GetLetterTemplates { Link Here
124
    my $dbh       = C4::Context->dbh;
124
    my $dbh       = C4::Context->dbh;
125
    my $letters   = $dbh->selectall_hashref(
125
    my $letters   = $dbh->selectall_hashref(
126
        q|
126
        q|
127
            SELECT module, code, branchcode, name, is_html, title, content, message_transport_type
127
            SELECT module, code, branchcode, name, is_html, title, content, message_transport_type, is_tt
128
            FROM letter
128
            FROM letter
129
            WHERE module = ?
129
            WHERE module = ?
130
            AND code = ?
130
            AND code = ?
Lines 642-730 sub GetPreparedLetter { Link Here
642
        or warn( "No $module $letter_code letter transported by " . $mtt ),
642
        or warn( "No $module $letter_code letter transported by " . $mtt ),
643
            return;
643
            return;
644
644
645
    my $tables = $params{tables};
645
    my $tables     = $params{tables};
646
    my $substitute = $params{substitute};
646
    my $substitute = $params{substitute};
647
    my $repeat = $params{repeat};
647
    my $repeat     = $params{repeat};
648
648
    $tables || $substitute || $repeat
649
    $tables || $substitute || $repeat
649
      or carp( "ERROR: nothing to substitute - both 'tables' and 'substitute' are empty" ),
650
      or carp( "ERROR: nothing to substitute - both 'tables' and 'substitute' are empty" ),
650
         return;
651
         return;
651
    my $want_librarian = $params{want_librarian};
652
652
653
    if ($substitute) {
653
    my $userenv = C4::Context->userenv;
654
        while ( my ($token, $val) = each %$substitute ) {
655
            if ( $token eq 'items.content' ) {
656
                $val =~ s|\n|<br/>|g if $letter->{is_html};
657
            }
658
654
659
            $letter->{title} =~ s/<<$token>>/$val/g;
655
    if ( $letter->{is_tt} ) {
660
            $letter->{content} =~ s/<<$token>>/$val/g;
656
        $letter->{content} = _process_tt(
661
       }
657
            {
658
                content => $letter->{content},
659
                tables  => $tables,
660
                tt_params  => {
661
                    today     => dt_from_string(),
662
                    librarian => {
663
                        firstname    => $userenv->{firstname},
664
                        surname      => $userenv->{surname},
665
                        emailaddress => $userenv->{emailaddress},
666
                    },
667
                }
668
            }
669
        );
662
    }
670
    }
671
    else {
672
        my $want_librarian = $params{want_librarian};
663
673
664
    my $OPACBaseURL = C4::Context->preference('OPACBaseURL');
674
        if ($substitute) {
665
    $letter->{content} =~ s/<<OPACBaseURL>>/$OPACBaseURL/go;
675
            while ( my ($token, $val) = each %$substitute ) {
676
                if ( $token eq 'items.content' ) {
677
                    $val =~ s|\n|<br/>|g if $letter->{is_html};
678
                }
666
679
667
    if ($want_librarian) {
680
                $letter->{title} =~ s/<<$token>>/$val/g;
668
        # parsing librarian name
681
                $letter->{content} =~ s/<<$token>>/$val/g;
669
        my $userenv = C4::Context->userenv;
682
           }
670
        $letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/go;
683
        }
671
        $letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/go;
672
        $letter->{content} =~ s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/go;
673
    }
674
684
675
    my ($repeat_no_enclosing_tags, $repeat_enclosing_tags);
685
        my $OPACBaseURL = C4::Context->preference('OPACBaseURL');
686
        $letter->{content} =~ s/<<OPACBaseURL>>/$OPACBaseURL/go;
676
687
677
    if ($repeat) {
688
        if ($want_librarian) {
678
        if (ref ($repeat) eq 'ARRAY' ) {
689
            # parsing librarian name
679
            $repeat_no_enclosing_tags = $repeat;
690
            $letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/go;
680
        } else {
691
            $letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/go;
681
            $repeat_enclosing_tags = $repeat;
692
            $letter->{content} =~ s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/go;
682
        }
693
        }
683
    }
684
694
685
    if ($repeat_enclosing_tags) {
695
        my ($repeat_no_enclosing_tags, $repeat_enclosing_tags);
686
        while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) {
696
687
            if ( $letter->{content} =~ m!<$tag>(.*)</$tag>!s ) {
697
        if ($repeat) {
688
                my $subcontent = $1;
698
            if (ref ($repeat) eq 'ARRAY' ) {
689
                my @lines = map {
699
                $repeat_no_enclosing_tags = $repeat;
690
                    my %subletter = ( title => '', content => $subcontent );
700
            } else {
691
                    _substitute_tables( \%subletter, $_ );
701
                $repeat_enclosing_tags = $repeat;
692
                    $subletter{content};
693
                } @$tag_tables;
694
                $letter->{content} =~ s!<$tag>.*</$tag>!join( "\n", @lines )!se;
695
            }
702
            }
696
        }
703
        }
697
    }
698
699
    if ($tables) {
700
        _substitute_tables( $letter, $tables );
701
    }
702
704
703
    if ($repeat_no_enclosing_tags) {
705
        if ($repeat_enclosing_tags) {
704
        if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) {
706
            while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) {
705
            my $line = $&;
707
                if ( $letter->{content} =~ m!<$tag>(.*)</$tag>!s ) {
706
            my $i = 1;
708
                    my $subcontent = $1;
707
            my @lines = map {
709
                    my @lines = map {
708
                my $c = $line;
710
                        my %subletter = ( title => '', content => $subcontent );
709
                $c =~ s/<<count>>/$i/go;
711
                        _substitute_tables( \%subletter, $_ );
710
                foreach my $field ( keys %{$_} ) {
712
                        $subletter{content};
711
                    $c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/;
713
                    } @$tag_tables;
714
                    $letter->{content} =~ s!<$tag>.*</$tag>!join( "\n", @lines )!se;
712
                }
715
                }
713
                $i++;
716
            }
714
                $c;
717
        }
715
            } @$repeat_no_enclosing_tags;
716
718
717
            my $replaceby = join( "\n", @lines );
719
        if ($tables) {
718
            $letter->{content} =~ s/\Q$line\E/$replaceby/s;
720
            _substitute_tables( $letter, $tables );
719
        }
721
        }
720
    }
721
722
722
    $letter->{content} = _process_tt(
723
        if ($repeat_no_enclosing_tags) {
723
        {
724
            if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) {
724
            content => $letter->{content},
725
                my $line = $&;
725
            tables  => $tables,
726
                my $i = 1;
727
                my @lines = map {
728
                    my $c = $line;
729
                    $c =~ s/<<count>>/$i/go;
730
                    foreach my $field ( keys %{$_} ) {
731
                        $c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/;
732
                    }
733
                    $i++;
734
                    $c;
735
                } @$repeat_no_enclosing_tags;
736
737
                my $replaceby = join( "\n", @lines );
738
                $letter->{content} =~ s/\Q$line\E/$replaceby/s;
739
            }
726
        }
740
        }
727
    );
741
742
    }
728
743
729
    $letter->{content} =~ s/<<\S*>>//go; #remove any stragglers
744
    $letter->{content} =~ s/<<\S*>>//go; #remove any stragglers
730
745
Lines 1337-1344 sub _set_message_status { Link Here
1337
sub _process_tt {
1352
sub _process_tt {
1338
    my ( $params ) = @_;
1353
    my ( $params ) = @_;
1339
1354
1340
    my $content = $params->{content};
1355
    my $content   = $params->{content};
1341
    my $tables = $params->{tables};
1356
    my $tables    = $params->{tables};
1357
    my $tt_params = $params->{tt_params};
1342
1358
1343
    my $use_template_cache = C4::Context->config('template_cache_dir') && defined $ENV{GATEWAY_INTERFACE};
1359
    my $use_template_cache = C4::Context->config('template_cache_dir') && defined $ENV{GATEWAY_INTERFACE};
1344
    my $template           = Template->new(
1360
    my $template           = Template->new(
Lines 1353-1359 sub _process_tt { Link Here
1353
        }
1369
        }
1354
    ) or die Template->error();
1370
    ) or die Template->error();
1355
1371
1356
    my $tt_params = _get_tt_params( $tables );
1372
    my $tt_objects = _get_tt_params( $tables );
1373
    $tt_params = { %$tt_params, %$tt_objects };
1357
1374
1358
    my $output;
1375
    my $output;
1359
    $template->process( \$content, $tt_params, \$output ) || croak "ERROR PROCESSING TEMPLATE: " . $template->error();
1376
    $template->process( \$content, $tt_params, \$output ) || croak "ERROR PROCESSING TEMPLATE: " . $template->error();
Lines 1474-1481 sub _get_tt_params { Link Here
1474
        }
1491
        }
1475
    }
1492
    }
1476
1493
1477
    $params->{today} = dt_from_string();
1478
1479
    return $params;
1494
    return $params;
1480
}
1495
}
1481
1496
(-)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 1428-1433 CREATE TABLE `letter` ( -- table for all notice templates in Koha Link Here
1428
  `title` varchar(200) NOT NULL default '', -- subject line of the notice
1428
  `title` varchar(200) NOT NULL default '', -- subject line of the notice
1429
  `content` text, -- body text for the notice or slip
1429
  `content` text, -- body text for the notice or slip
1430
  `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice
1430
  `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice
1431
  `is_tt` TINYINT(1) NOT NULL DEFAULT 0, -- controls if notice should be processed as template toolkit syntax
1431
  PRIMARY KEY  (`module`,`code`, `branchcode`, `message_transport_type`),
1432
  PRIMARY KEY  (`module`,`code`, `branchcode`, `message_transport_type`),
1432
  CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`)
1433
  CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`)
1433
  REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE
1434
  REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 472-477 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
472
('TagsModeration','0','','Require tags from patrons to be approved before becoming visible.','YesNo'),
472
('TagsModeration','0','','Require tags from patrons to be approved before becoming visible.','YesNo'),
473
('TagsShowOnDetail','10','','Number of tags to display on detail page.  0 is off.','Integer'),
473
('TagsShowOnDetail','10','','Number of tags to display on detail page.  0 is off.','Integer'),
474
('TagsShowOnList','6','','Number of tags to display on search results list.  0 is off.','Integer'),
474
('TagsShowOnList','6','','Number of tags to display on search results list.  0 is off.','Integer'),
475
('TemplateToolkitNotices',0,'','Enable the ability to use Template Toolkit syntax in slips and notices','YesNo'),
475
('template','prog','','Define the preferred staff interface template','Themes'),
476
('template','prog','','Define the preferred staff interface template','Themes'),
476
('ThingISBN','0','','Use with FRBRizeEditions. If ON, Koha will use the ThingISBN web service in the Editions tab on the detail pages.','YesNo'),
477
('ThingISBN','0','','Use with FRBRizeEditions. If ON, Koha will use the ThingISBN web service in the Editions tab on the detail pages.','YesNo'),
477
('TimeFormat','24hr','12hr|24hr','Defines the global time format for visual output.','Choice'),
478
('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