Bugzilla – Attachment 191398 Details for
Bug 41601
Bug 38516 breaks PDF export for basket groups when using API2::PDF < 2.042
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41601: Create Koha::PDF::Loader wrapper for PDF::API2
Bug-41601-Create-KohaPDFLoader-wrapper-for-PDFAPI2.patch (text/plain), 13.00 KB, created by
David Cook
on 2026-01-14 02:29:43 UTC
(
hide
)
Description:
Bug 41601: Create Koha::PDF::Loader wrapper for PDF::API2
Filename:
MIME Type:
Creator:
David Cook
Created:
2026-01-14 02:29:43 UTC
Size:
13.00 KB
patch
obsolete
>From 148fb49bc7a8ef3881b00c0f926feb4bb01d8e91 Mon Sep 17 00:00:00 2001 >From: David Cook <dcook@prosentient.com.au> >Date: Wed, 14 Jan 2026 02:24:39 +0000 >Subject: [PATCH] Bug 41601: Create Koha::PDF::Loader wrapper for PDF::API2 > >This patch adds a wrapper around PDF::API2 so that we can >use the right method names depending on the version of PDF::API2 >being used when we're loading in PDF templates > >Test plan: >0. Apply the patch and koha-plack --restart kohadev >1. chmod 444 /kohadevbox/koha/koha-tmpl/intranet-tmpl/prog/pdf/*.pdf >2. Create a basket with a vendor >3. Add an order to the basket >4. Close basket (and attach the basket to a new basket group with the same name) >5. Go to "Closed" tab and click "Export as PDF" >6. Note that there's no error and your PDF opens fine >7. Repeat the "Export as PDF" process for every option of the >system preference "OrderPdfFormat". Every option should work >without errors. >8. Celebrate! >--- > Koha/PDF/Loader.pm | 120 +++++++++++++++++++++++++++++++ > Koha/pdfformat/layout1page.pm | 6 +- > Koha/pdfformat/layout2pages.pm | 6 +- > Koha/pdfformat/layout2pagesde.pm | 6 +- > Koha/pdfformat/layout3pages.pm | 6 +- > Koha/pdfformat/layout3pagesfr.pm | 6 +- > t/Koha/PDF/Loader.t | 77 ++++++++++++++++++++ > 7 files changed, 207 insertions(+), 20 deletions(-) > create mode 100644 Koha/PDF/Loader.pm > create mode 100755 t/Koha/PDF/Loader.t > >diff --git a/Koha/PDF/Loader.pm b/Koha/PDF/Loader.pm >new file mode 100644 >index 00000000000..4472f4302b3 >--- /dev/null >+++ b/Koha/PDF/Loader.pm >@@ -0,0 +1,120 @@ >+package Koha::PDF::Loader; >+ >+# >+# 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 <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use PDF::API2; >+ >+#NOTE: Support PDF::API2 methods before and after version 2.042 >+my $pdf_api2_methods = { >+ 'to_string' => 'to_string', >+ 'from_string' => 'from_string', >+}; >+ >+#NOTE: Initialise methods at module load time >+_init_methods(); >+ >+=head1 NAME >+ >+Koha::PDF::Loader - Koha class for loading PDFs >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+sub _init_methods { >+ if ( PDF::API2->can('to_string') ) { >+ __PACKAGE__->set_method_name( { method => 'to_string', name_to_use => 'to_string' } ); >+ } elsif ( PDF::API2->can('stringify') ) { >+ >+ #NOTE: Newer versions still contain the deprecated method name >+ __PACKAGE__->set_method_name( { method => 'to_string', name_to_use => 'stringify' } ); >+ } >+ if ( PDF::API2->can('from_string') ) { >+ __PACKAGE__->set_method_name( { method => 'from_string', name_to_use => 'from_string' } ); >+ } elsif ( PDF::API2->can('open_scalar') ) { >+ >+ #NOTE: Newer versions still contain the deprecated method name >+ __PACKAGE__->set_method_name( { method => 'from_string', name_to_use => 'open_scalar' } ); >+ } >+} >+ >+=head3 get_method_name >+ >+Get method name. Shouldn't be a need to use it outside of testing. >+ >+=cut >+ >+sub get_method_name { >+ my ( $class, $args ) = @_; >+ my $method = $args->{method}; >+ if ($method) { >+ if ( $pdf_api2_methods->{$method} ) { >+ return $pdf_api2_methods->{$method}; >+ } >+ } >+ return; >+} >+ >+=head3 set_method_name >+ >+Set method name. Shouldn't be be a need to use it outside of testing. >+ >+=cut >+ >+sub set_method_name { >+ my ( $class, $args ) = @_; >+ my $method = $args->{method}; >+ my $name_to_use = $args->{name_to_use}; >+ if ( $method && $name_to_use ) { >+ if ( $pdf_api2_methods->{$method} ) { >+ $pdf_api2_methods->{$method} = $name_to_use; >+ return 1; >+ } >+ } >+ return; >+} >+ >+=head3 load_pdf_from_template >+ >+Loads a PDF into memory from a template file in a backwards >+compatible way. >+ >+=cut >+ >+sub load_pdf_from_template { >+ my ( $class, $args ) = @_; >+ my $pdf; >+ my $method_to_string = __PACKAGE__->get_method_name( { method => 'to_string' } ); >+ my $method_from_string = __PACKAGE__->get_method_name( { method => 'from_string' } ); >+ my $pdf_template = $args->{pdf_template}; >+ if ($pdf_template) { >+ my $pdf_template_obj = PDF::API2->open($pdf_template); >+ if ($pdf_template_obj) { >+ my $pdf_template_str = $pdf_template_obj->$method_to_string(); >+ if ($pdf_template_str) { >+ $pdf = PDF::API2->$method_from_string($pdf_template_str); >+ } >+ } >+ } >+ return $pdf; >+} >+ >+1; >diff --git a/Koha/pdfformat/layout1page.pm b/Koha/pdfformat/layout1page.pm >index 6a78286d09c..f99400290fe 100644 >--- a/Koha/pdfformat/layout1page.pm >+++ b/Koha/pdfformat/layout1page.pm >@@ -37,7 +37,7 @@ use constant mm => 25.4 / 72; > use constant in => 1 / 72; > use constant pt => 1; > >-use PDF::API2; >+use Koha::PDF::Loader; > > #A4 paper specs > my ( $height, $width ) = ( 297, 210 ); >@@ -247,9 +247,7 @@ sub printpdf { > # open the default PDF that will be used for base (1st page already filled) > my $pdf_template = > C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout1page.pdf'; >- my $pdf_template_obj = PDF::API2->open($pdf_template); >- my $pdf_template_str = $pdf_template_obj->to_string(); >- my $pdf = PDF::API2->from_string($pdf_template_str); >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $pdf_template } ); > $pdf->pageLabel( > 0, > { >diff --git a/Koha/pdfformat/layout2pages.pm b/Koha/pdfformat/layout2pages.pm >index 1447d2b97f4..a2798e0711b 100644 >--- a/Koha/pdfformat/layout2pages.pm >+++ b/Koha/pdfformat/layout2pages.pm >@@ -40,7 +40,7 @@ use constant mm => 25.4 / 72; > use constant in => 1 / 72; > use constant pt => 1; > >-use PDF::API2; >+use Koha::PDF::Loader; > > #A4 paper specs > my ( $height, $width ) = ( 297, 210 ); >@@ -262,9 +262,7 @@ sub printpdf { > # open the default PDF that will be used for base (1st page already filled) > my $pdf_template = > C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout2pages.pdf'; >- my $pdf_template_obj = PDF::API2->open($pdf_template); >- my $pdf_template_str = $pdf_template_obj->to_string(); >- my $pdf = PDF::API2->from_string($pdf_template_str); >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $pdf_template } ); > $pdf->pageLabel( > 0, > { >diff --git a/Koha/pdfformat/layout2pagesde.pm b/Koha/pdfformat/layout2pagesde.pm >index da6a041fda0..2d044f518d2 100644 >--- a/Koha/pdfformat/layout2pagesde.pm >+++ b/Koha/pdfformat/layout2pagesde.pm >@@ -40,7 +40,7 @@ use constant mm => 25.4 / 72; > use constant in => 1 / 72; > use constant pt => 1; > >-use PDF::API2; >+use Koha::PDF::Loader; > > #A4 paper specs > my ( $height, $width ) = ( 297, 210 ); >@@ -264,9 +264,7 @@ sub printpdf { > # open the default PDF that will be used for base (1st page already filled) > my $pdf_template = > C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout2pagesde.pdf'; >- my $pdf_template_obj = PDF::API2->open($pdf_template); >- my $pdf_template_str = $pdf_template_obj->to_string(); >- my $pdf = PDF::API2->from_string($pdf_template_str); >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $pdf_template } ); > $pdf->pageLabel( > 0, > { >diff --git a/Koha/pdfformat/layout3pages.pm b/Koha/pdfformat/layout3pages.pm >index 7c16accd5ac..81ef6d9d4e1 100644 >--- a/Koha/pdfformat/layout3pages.pm >+++ b/Koha/pdfformat/layout3pages.pm >@@ -44,7 +44,7 @@ use constant mm => 25.4 / 72; > use constant in => 1 / 72; > use constant pt => 1; > >-use PDF::API2; >+use Koha::PDF::Loader; > > #A4 paper specs > my ( $height, $width ) = ( 297, 210 ); >@@ -455,9 +455,7 @@ sub printpdf { > # open the default PDF that will be used for base (1st page already filled) > my $pdf_template = > C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout3pages.pdf'; >- my $pdf_template_obj = PDF::API2->open($pdf_template); >- my $pdf_template_str = $pdf_template_obj->to_string(); >- my $pdf = PDF::API2->from_string($pdf_template_str); >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $pdf_template } ); > $pdf->pageLabel( > 0, > { >diff --git a/Koha/pdfformat/layout3pagesfr.pm b/Koha/pdfformat/layout3pagesfr.pm >index 7134d8d32cb..0a3dc0017a0 100644 >--- a/Koha/pdfformat/layout3pagesfr.pm >+++ b/Koha/pdfformat/layout3pagesfr.pm >@@ -43,7 +43,7 @@ use constant mm => 25.4 / 72; > use constant in => 1 / 72; > use constant pt => 1; > >-use PDF::API2; >+use Koha::PDF::Loader; > > #A4 paper specs > my ( $height, $width ) = ( 297, 210 ); >@@ -447,9 +447,7 @@ sub printpdf { > # open the default PDF that will be used for base (1st page already filled) > my $pdf_template = > C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout3pagesfr.pdf'; >- my $pdf_template_obj = PDF::API2->open($pdf_template); >- my $pdf_template_str = $pdf_template_obj->to_string(); >- my $pdf = PDF::API2->from_string($pdf_template_str); >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $pdf_template } ); > $pdf->pageLabel( > 0, > { >diff --git a/t/Koha/PDF/Loader.t b/t/Koha/PDF/Loader.t >new file mode 100755 >index 00000000000..2c6ce96203b >--- /dev/null >+++ b/t/Koha/PDF/Loader.t >@@ -0,0 +1,77 @@ >+#!/usr/bin/perl >+ >+# 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 <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use File::Temp; >+ >+use Test::NoWarnings; >+use Test::More tests => 4; >+ >+use Test::MockModule; >+use Test::Exception; >+ >+use t::lib::Mocks; >+ >+use_ok('Koha::PDF::Loader'); >+ >+subtest 'PDF loader tests' => sub { >+ plan tests => 4; >+ >+ #Create a self-destructing temporary file >+ my $tmpdir = File::Temp::tempdir( CLEANUP => 1 ); >+ my ( $fh, $filename ) = File::Temp::tempfile( DIR => $tmpdir, SUFFIX => '.pdf' ); >+ >+ #Create a blank PDF template for testing purposes using temporary file >+ my $template = PDF::API2->new(); >+ $template->save($filename); >+ >+ my $to_string = Koha::PDF::Loader->get_method_name( { method => 'to_string' } ); >+ my $from_string = Koha::PDF::Loader->get_method_name( { method => 'from_string' } ); >+ is( $to_string, 'to_string', 'to_string method name correct' ); >+ is( $from_string, 'from_string', 'from_string method name correct' ); >+ >+ #Load PDF object from PDF template >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $filename } ); >+ ok( $pdf, 'Koha::PDF::Loader loaded something' ); >+ ok( $pdf->isa('PDF::API2'), 'PDF object is a PDF::API2 object' ); >+}; >+ >+subtest 'PDF loader tests (legacy)' => sub { >+ plan tests => 4; >+ >+ #Create a self-destructing temporary file >+ my $tmpdir = File::Temp::tempdir( CLEANUP => 1 ); >+ my ( $fh, $filename ) = File::Temp::tempfile( DIR => $tmpdir, SUFFIX => '.pdf' ); >+ >+ #Create a blank PDF template for testing purposes using temporary file >+ my $template = PDF::API2->new(); >+ $template->save($filename); >+ >+ #Test the use of deprecated function names, which will be automatically used for older versions of PDF::API2 >+ Koha::PDF::Loader->set_method_name( { method => 'to_string', name_to_use => 'stringify' } ); >+ Koha::PDF::Loader->set_method_name( { method => 'from_string', name_to_use => 'open_scalar' } ); >+ >+ my $to_string = Koha::PDF::Loader->get_method_name( { method => 'to_string' } ); >+ my $from_string = Koha::PDF::Loader->get_method_name( { method => 'from_string' } ); >+ is( $to_string, 'stringify', 'to_string method name correct' ); >+ is( $from_string, 'open_scalar', 'from_string method name correct' ); >+ >+ #Load PDF object from PDF template >+ my $pdf = Koha::PDF::Loader->load_pdf_from_template( { pdf_template => $filename } ); >+ ok( $pdf, 'Koha::PDF::Loader loaded something using legacy method names' ); >+ ok( $pdf->isa('PDF::API2'), 'PDF object is a PDF::API2 object' ); >+}; >-- >2.39.5
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 41601
: 191398