PluginProbe
PostNL for WooCommerce / trunk
PostNL for WooCommerce vtrunk
5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 4.4.2 All 71 releases
woo-postnl / src / Library / CustomizedPDFMerger.php

CustomizedPDFMerger.php in PostNL for WooCommerce trunk, at src/Library/CustomizedPDFMerger.php

320 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class CustomizedPDFMerger file.
4 *
5 * @package PostNLWooCommerce\Library
6 */
7
8 namespace PostNLWooCommerce\Library;
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit;
12 }
13
14 use Exception;
15 use PostNLWooCommerce\Shipping_Method\Settings;
16 use PostNLWooCommerce\Utils;
17
18 class CustomizedPDFMerger {
19
20 /**
21 * Files to merge.
22 *
23 * @var array
24 */
25 private $_files; // ['form.pdf'] ["1,2,4, 5-19"]
26
27 /**
28 * Settings class instance.
29 *
30 * @var Settings
31 */
32 protected $settings;
33
34 public function __construct() {
35 $this->settings = Settings::get_instance();
36 }
37
38 /**
39 * Add a PDF for inclusion in the merge with a valid file path. Pages should be formatted: 1,3,6, 12-16.
40 *
41 * @param $filepath
42 * @param string $pages
43 * @param string|null $orientation
44 *
45 * @return CustomizedPDFMerger
46 * @throws Exception
47 */
48 public function addPDF( $filepath, $pages = 'all', $orientation = null ) {
49 if ( file_exists( $filepath ) ) {
50 if ( strtolower( $pages ) != 'all' ) {
51 $pages = $this->_rewritepages( $pages );
52 }
53
54 $this->_files[] = array( $filepath, $pages, $orientation );
55 } else {
56 throw new Exception( "Could not locate PDF on '$filepath'" );
57 }
58
59 return $this;
60 }
61
62 /**
63 * Merges your provided PDFs and outputs to specified location.
64 *
65 * @param string $outputmode
66 * @param string $outputpath
67 * @param string $orientation
68 * @param string $start_position
69 *
70 * @return string|bool
71 * @throws Exception
72 */
73 public function merge( $outputmode = 'browser', $outputpath = 'newfile.pdf', $orientation = 'A', $start_position = 'top-left' ) {
74 if ( ! isset( $this->_files ) || ! is_array( $this->_files ) ) {
75 throw new Exception( 'No PDFs to merge.' );
76 }
77
78 $fpdi = new PDF_Rotate();
79 $files = array();
80
81 // merger operations
82 foreach ( $this->_files as $file ) {
83 $filename = $file[0];
84 $filepages = $file[1];
85 $fileorientation = ( ! is_null( $file[2] ) ) ? $file[2] : $orientation;
86
87 $count = $fpdi->setSourceFile( $filename );
88
89 // add the pages
90 if ( $filepages == 'all' ) {
91 for ( $i = 1; $i <= $count; $i++ ) {
92 $template = $fpdi->importPage( $i );
93 $size = $fpdi->getTemplateSize( $template );
94 if ( $fileorientation === 'A' ) {
95 $fileorientation = ( $size['width'] > $size['height'] ) ? 'L' : 'P';
96 }
97
98 $files[ $filename ][] = array(
99 'template' => $template,
100 'size' => $size,
101 'orientation' => $fileorientation,
102 );
103 }
104 } else {
105 foreach ( $filepages as $page ) {
106 if ( ! $template = $fpdi->importPage( $page ) ) {
107 throw new Exception( "Could not load page '$page' in PDF '$filename'. Check that the page exists." );
108 }
109 $size = $fpdi->getTemplateSize( $template );
110
111 $files[ $filename ][] = array(
112 'template' => $template,
113 'size' => $size,
114 'orientation' => $fileorientation,
115 );
116 }
117 }
118 }
119
120 $label_number = 1;
121 $a4_size = Utils::get_paper_size( 'A4' );
122 $a6_size = Utils::get_paper_size( 'A6' );
123
124 $label_format = $this->settings->get_label_format();
125 $first_page = true;
126 $coordinate_map = array(
127 'top-left' => array(
128 1 => array( 0, 0 ),
129 2 => array( 148, 0 ),
130 3 => array( 0, 105 ),
131 4 => array( 148, 105 ),
132 ),
133 'top-right' => array(
134 1 => array( 148, 0 ),
135 2 => array( 0, 105 ),
136 3 => array( 148, 105 ),
137 4 => array( 148, 0 ), // this will be on a new page
138 ),
139 'bottom-left' => array(
140 1 => array( 0, 105 ),
141 2 => array( 148, 105 ),
142 3 => array( 0, 105 ), // this will be on a new page
143 4 => array( 148, 0 ), // this will be on a new page
144 ),
145 'bottom-right' => array(
146 1 => array( 148, 105 ),
147 2 => array( 0, 0 ), // this will be on a new page
148 3 => array( 148, 0 ), // this will be on a new page
149 4 => array( 0, 105 ), // this will be on a new page
150 ),
151 );
152
153 $new_page_condition_map = array(
154 'top-left' => 4,
155 'top-right' => 3,
156 'bottom-left' => 2,
157 'bottom-right' => 1,
158 );
159
160 foreach ( $files as $filename => $file_templates ) {
161 foreach ( $file_templates as $file_template ) {
162 $rotation_needed = false;
163 $tolerance = 5; // Tolerance in mm for A6 only.
164 $file_width = intval( $file_template['size']['width'] );
165 $file_height = intval( $file_template['size']['height'] );
166 $file_orientation = $file_template['size']['orientation'];
167 $is_cn23 = ( stripos( $filename, '-cn23-' ) !== false );
168
169 // Check if the file matches A6 dimensions (vertical or horizontal) within tolerance.
170 $isA6 = ( abs( $file_width - intval( $a6_size['height'] ) ) <= $tolerance &&
171 abs( $file_height - intval( $a6_size['width'] ) ) <= $tolerance )
172 || ( abs( $file_width - intval( $a6_size['width'] ) ) <= $tolerance &&
173 abs( $file_height - intval( $a6_size['height'] ) ) <= $tolerance );
174
175 if ( 'A6' === $label_format || $is_cn23 || ! $isA6 ) {
176 $fpdi->AddPage(
177 $file_orientation,
178 array(
179 $file_width,
180 $file_height,
181 )
182 );
183 $fpdi->useTemplate( $file_template['template'] );
184 $label_number = 1;
185 continue;
186 }
187
188 if (
189 $file_width <= ( intval( $a6_size['height'] ) + $tolerance ) &&
190 $file_height <= ( intval( $a6_size['width'] ) + $tolerance )
191 ) {
192 $rotation_needed = true;
193 }
194
195 $new_page_condition = $new_page_condition_map[ $start_position ];
196
197 if ( 1 === $label_number % $new_page_condition || $start_position == 'bottom-right' ) {
198 $fpdi->AddPage(
199 'L',
200 array(
201 $a4_size['width'],
202 $a4_size['height'],
203 )
204 );
205 $label_number = 1;
206
207 if ( $first_page ) {
208 // If it's the first page, use the given start_position.
209 $first_page = false;
210 } else {
211 // For other pages, always start from top-left.
212 $start_position = 'top-left';
213 }
214 }
215
216 $coords = $coordinate_map[ $start_position ][ $label_number ];
217
218 // Scale A6 PDF.
219 if ( $rotation_needed ) {
220 $scale_x = $a6_size['width'] / $file_height;
221 $scale_y = $a6_size['height'] / $file_width;
222 } else {
223 $scale_x = $a6_size['width'] / $file_width;
224 $scale_y = $a6_size['height'] / $file_height;
225 }
226
227 $scale = min( $scale_x, $scale_y );
228
229 if ( $rotation_needed ) {
230 $fpdi->Rotate( 90, 0, 0 );
231 $fpdi->useTemplate( $file_template['template'], - $file_template['size']['width'] - $coords[1], $coords[0], ( $file_template['size']['width'] * $scale ), ( $file_template['size']['height'] * $scale ) );
232
233 $fpdi->Rotate( 0 ); // Reset rotation
234 } else {
235 // Portrait - place as is
236 $fpdi->useTemplate( $file_template['template'], $coords[0], $coords[1], ( $file_template['size']['width'] * $scale ), ( $file_template['size']['height'] * $scale ), false );
237 }
238
239 ++$label_number;
240 }
241 }
242
243 // output operations
244 $mode = $this->_switchmode( $outputmode );
245
246 if ( $mode == 'S' ) {
247 return $fpdi->Output( $outputpath, 'S' );
248 } elseif ( $fpdi->Output( $outputpath, $mode ) == '' ) {
249 return true;
250 } else {
251 throw new Exception( "Error outputting PDF to '$outputmode'." );
252
253 return false;
254 }
255 }
256
257 /**
258 * FPDI uses single characters for specifying the output location. Change our more descriptive string into proper format.
259 *
260 * @param $mode
261 *
262 * @return string Character
263 */
264 private function _switchmode( $mode ) {
265 switch ( strtolower( $mode ) ) {
266 case 'download':
267 return 'D';
268 break;
269 case 'file':
270 return 'F';
271 break;
272 case 'string':
273 return 'S';
274 break;
275 default:
276 return 'I';
277 break;
278 }
279 }
280
281 /**
282 * Takes our provided pages in the form of 1,3,4,16-50 and creates an array of all pages
283 *
284 * @param $pages
285 *
286 * @return array
287 * @throws Exception
288 */
289 private function _rewritepages( $pages ) {
290 $pages = str_replace( ' ', '', $pages );
291 $part = explode( ',', $pages );
292
293 // parse hyphens
294 foreach ( $part as $i ) {
295 $ind = explode( '-', $i );
296
297 if ( count( $ind ) == 2 ) {
298 $x = $ind[0]; // start page
299 $y = $ind[1]; // end page
300
301 if ( $x > $y ) {
302 throw new Exception( "Starting page, '$x' is greater than ending page '$y'." );
303
304 return false;
305 }
306
307 // add middle pages
308 while ( $x <= $y ) {
309 $newpages[] = (int) $x;
310 ++$x;
311 }
312 } else {
313 $newpages[] = (int) $ind[0];
314 }
315 }
316
317 return $newpages;
318 }
319 }
320