Version Description
- New: include dompdf temporary folder in cleanup procedure
- New: Add CSS row classes for WPC Product Bundles
- New: filter to override
wc_display_item_meta
arguments - Fix: Prevent errors when server doesn't support
.webp
image rendering - Fix: change invalid default date 0000-00-00 00:00:00 on number store tables
- Tweak: Don't store non-historical document settings in order meta
- Templates: New action hook before the document label (
wpo_wcpdf_before_document_label
) - Libraries: updated dompdf to 1.2.0
- Marked tested up to WP5.9
Download this release
Release Info
Developer | pomegranate |
Plugin | WooCommerce PDF Invoices & Packing Slips |
Version | 2.13.0 |
Comparing to | |
See all releases |
Code changes from version 2.12.1 to 2.13.0
- composer.json +1 -1
- composer.lock +12 -14
- includes/class-wcpdf-install.php +26 -0
- includes/class-wcpdf-main.php +75 -19
- includes/class-wcpdf-settings-callbacks.php +12 -0
- includes/class-wcpdf-settings-debug.php +4 -36
- includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php +39 -6
- includes/documents/abstract-wcpdf-order-document-methods.php +14 -3
- includes/documents/abstract-wcpdf-order-document.php +8 -3
- includes/documents/class-wcpdf-invoice.php +2 -1
- includes/documents/class-wcpdf-sequential-number-store.php +6 -3
- includes/views/dompdf-status.php +6 -0
- includes/wcpdf-functions.php +47 -0
- readme.txt +14 -3
- templates/Simple/invoice.php +2 -0
- templates/Simple/packing-slip.php +2 -0
- vendor/composer/installed.json +7 -7
- vendor/composer/installed.php +5 -5
- vendor/dompdf/dompdf/VERSION +1 -1
- vendor/dompdf/dompdf/lib/Cpdf.php +5 -5
- vendor/dompdf/dompdf/src/Frame/FrameListIterator.php +31 -19
- vendor/dompdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.php +0 -7
- vendor/dompdf/dompdf/src/FrameDecorator/Page.php +10 -15
- vendor/dompdf/dompdf/src/FrameDecorator/Table.php +18 -0
- vendor/dompdf/dompdf/src/FrameReflower/Block.php +6 -8
- vendor/dompdf/dompdf/src/FrameReflower/Inline.php +0 -6
- vendor/dompdf/dompdf/src/FrameReflower/Page.php +4 -2
- vendor/dompdf/dompdf/src/FrameReflower/Table.php +4 -5
- vendor/dompdf/dompdf/src/FrameReflower/TableCell.php +5 -5
- vendor/dompdf/dompdf/src/FrameReflower/TableRow.php +4 -4
- vendor/dompdf/dompdf/src/FrameReflower/TableRowGroup.php +4 -5
- vendor/dompdf/dompdf/src/FrameReflower/Text.php +4 -3
- vendor/dompdf/dompdf/src/Helpers.php +63 -0
- vendor/dompdf/dompdf/src/Positioner/Inline.php +3 -1
- vendor/dompdf/dompdf/src/Renderer/AbstractRenderer.php +5 -5
- woocommerce-pdf-invoices-packingslips.php +2 -2
composer.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
{
|
2 |
"require": {
|
3 |
-
"dompdf/dompdf": "
|
4 |
"symfony/polyfill-mbstring": "1.20",
|
5 |
"symfony/polyfill-iconv": "1.20.0"
|
6 |
},
|
1 |
{
|
2 |
"require": {
|
3 |
+
"dompdf/dompdf": "^1.2",
|
4 |
"symfony/polyfill-mbstring": "1.20",
|
5 |
"symfony/polyfill-iconv": "1.20.0"
|
6 |
},
|
composer.lock
CHANGED
@@ -4,20 +4,20 @@
|
|
4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
-
"content-hash": "
|
8 |
"packages": [
|
9 |
{
|
10 |
"name": "dompdf/dompdf",
|
11 |
-
"version": "
|
12 |
"source": {
|
13 |
"type": "git",
|
14 |
"url": "https://github.com/dompdf/dompdf.git",
|
15 |
-
"reference": "
|
16 |
},
|
17 |
"dist": {
|
18 |
"type": "zip",
|
19 |
-
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/
|
20 |
-
"reference": "
|
21 |
"shasum": ""
|
22 |
},
|
23 |
"require": {
|
@@ -69,9 +69,9 @@
|
|
69 |
"homepage": "https://github.com/dompdf/dompdf",
|
70 |
"support": {
|
71 |
"issues": "https://github.com/dompdf/dompdf/issues",
|
72 |
-
"source": "https://github.com/dompdf/dompdf/tree/
|
73 |
},
|
74 |
-
"time": "2022-
|
75 |
},
|
76 |
{
|
77 |
"name": "phenx/php-font-lib",
|
@@ -247,12 +247,12 @@
|
|
247 |
}
|
248 |
},
|
249 |
"autoload": {
|
250 |
-
"psr-4": {
|
251 |
-
"Symfony\\Polyfill\\Iconv\\": ""
|
252 |
-
},
|
253 |
"files": [
|
254 |
"bootstrap.php"
|
255 |
-
]
|
|
|
|
|
|
|
256 |
},
|
257 |
"notification-url": "https://packagist.org/downloads/",
|
258 |
"license": [
|
@@ -380,9 +380,7 @@
|
|
380 |
"packages-dev": [],
|
381 |
"aliases": [],
|
382 |
"minimum-stability": "stable",
|
383 |
-
"stability-flags":
|
384 |
-
"dompdf/dompdf": 20
|
385 |
-
},
|
386 |
"prefer-stable": false,
|
387 |
"prefer-lowest": false,
|
388 |
"platform": [],
|
4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
+
"content-hash": "8a62b914f789a38ee769610fd975c124",
|
8 |
"packages": [
|
9 |
{
|
10 |
"name": "dompdf/dompdf",
|
11 |
+
"version": "v1.2.0",
|
12 |
"source": {
|
13 |
"type": "git",
|
14 |
"url": "https://github.com/dompdf/dompdf.git",
|
15 |
+
"reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd"
|
16 |
},
|
17 |
"dist": {
|
18 |
"type": "zip",
|
19 |
+
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/60b704331479a69e9bcdb3496da2315b5c4f94fd",
|
20 |
+
"reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd",
|
21 |
"shasum": ""
|
22 |
},
|
23 |
"require": {
|
69 |
"homepage": "https://github.com/dompdf/dompdf",
|
70 |
"support": {
|
71 |
"issues": "https://github.com/dompdf/dompdf/issues",
|
72 |
+
"source": "https://github.com/dompdf/dompdf/tree/v1.2.0"
|
73 |
},
|
74 |
+
"time": "2022-02-07T13:02:10+00:00"
|
75 |
},
|
76 |
{
|
77 |
"name": "phenx/php-font-lib",
|
247 |
}
|
248 |
},
|
249 |
"autoload": {
|
|
|
|
|
|
|
250 |
"files": [
|
251 |
"bootstrap.php"
|
252 |
+
],
|
253 |
+
"psr-4": {
|
254 |
+
"Symfony\\Polyfill\\Iconv\\": ""
|
255 |
+
}
|
256 |
},
|
257 |
"notification-url": "https://packagist.org/downloads/",
|
258 |
"license": [
|
380 |
"packages-dev": [],
|
381 |
"aliases": [],
|
382 |
"minimum-stability": "stable",
|
383 |
+
"stability-flags": [],
|
|
|
|
|
384 |
"prefer-stable": false,
|
385 |
"prefer-lowest": false,
|
386 |
"platform": [],
|
includes/class-wcpdf-install.php
CHANGED
@@ -372,6 +372,32 @@ class Install {
|
|
372 |
@unlink( trailingslashit( $font_path ) . 'dompdf_font_family_cache.dist.php' );
|
373 |
@unlink( trailingslashit( $font_path ) . 'mustRead.html' );
|
374 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
|
376 |
}
|
377 |
|
372 |
@unlink( trailingslashit( $font_path ) . 'dompdf_font_family_cache.dist.php' );
|
373 |
@unlink( trailingslashit( $font_path ) . 'mustRead.html' );
|
374 |
}
|
375 |
+
|
376 |
+
// 2.12.2-dev-1: change 'date' database table default value to '1000-01-01 00:00:00'
|
377 |
+
if ( version_compare( $installed_version, '2.12.2-dev-1', '<' ) ) {
|
378 |
+
global $wpdb;
|
379 |
+
$documents = WPO_WCPDF()->documents->get_documents( 'all' );
|
380 |
+
foreach ( $documents as $document ) {
|
381 |
+
if ( is_callable( array( $document, 'get_sequential_number_store' ) ) ) {
|
382 |
+
$number_store = $document->get_sequential_number_store();
|
383 |
+
if ( ! empty( $number_store ) ) {
|
384 |
+
$column_name = 'date';
|
385 |
+
$query = $wpdb->query( "ALTER TABLE {$number_store->table_name} ALTER {$column_name} SET DEFAULT '1000-01-01 00:00:00'" );
|
386 |
+
if ( $query ) {
|
387 |
+
wcpdf_log_error(
|
388 |
+
"Default value changed for 'date' column to '1000-01-01 00:00:00' on database table: {$number_store->table_name}",
|
389 |
+
'info'
|
390 |
+
);
|
391 |
+
} else {
|
392 |
+
wcpdf_log_error(
|
393 |
+
"An error occurred! The default value for 'date' column couldn't be changed to '1000-01-01 00:00:00' on database table: {$number_store->table_name}",
|
394 |
+
'critical'
|
395 |
+
);
|
396 |
+
}
|
397 |
+
}
|
398 |
+
}
|
399 |
+
}
|
400 |
+
}
|
401 |
|
402 |
}
|
403 |
|
includes/class-wcpdf-main.php
CHANGED
@@ -42,7 +42,7 @@ class Main {
|
|
42 |
add_filter( 'wpo_wcpdf_html_filters', array( $this, 'html_currency_filters' ) );
|
43 |
|
44 |
// scheduled attachments cleanup (following settings on Status tab)
|
45 |
-
add_action( 'wp_scheduled_delete', array( $this, '
|
46 |
|
47 |
// remove private data
|
48 |
add_action( 'woocommerce_privacy_remove_order_personal_data_meta', array( $this, 'remove_order_personal_data_meta' ), 10, 1 );
|
@@ -641,9 +641,13 @@ class Main {
|
|
641 |
|
642 |
global $wp_filesystem;
|
643 |
|
644 |
-
|
|
|
|
|
|
|
645 |
if ( ! WP_Filesystem() ) {
|
646 |
-
WP_Filesystem
|
|
|
647 |
}
|
648 |
|
649 |
// we have the directories, let's try to copy
|
@@ -847,35 +851,87 @@ class Main {
|
|
847 |
}
|
848 |
|
849 |
/**
|
850 |
-
*
|
851 |
*/
|
852 |
-
public function
|
853 |
-
if ( !
|
854 |
-
// glob is required
|
855 |
return;
|
856 |
}
|
857 |
|
858 |
-
|
859 |
-
|
860 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
}
|
862 |
|
|
|
|
|
|
|
863 |
|
864 |
-
$
|
865 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
866 |
|
867 |
-
|
|
|
|
|
868 |
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
if (
|
874 |
-
|
|
|
|
|
|
|
|
|
875 |
}
|
876 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
877 |
}
|
|
|
|
|
878 |
}
|
|
|
|
|
879 |
}
|
880 |
|
881 |
/**
|
42 |
add_filter( 'wpo_wcpdf_html_filters', array( $this, 'html_currency_filters' ) );
|
43 |
|
44 |
// scheduled attachments cleanup (following settings on Status tab)
|
45 |
+
add_action( 'wp_scheduled_delete', array( $this, 'schedule_temporary_files_cleanup' ) );
|
46 |
|
47 |
// remove private data
|
48 |
add_action( 'woocommerce_privacy_remove_order_personal_data_meta', array( $this, 'remove_order_personal_data_meta' ), 10, 1 );
|
641 |
|
642 |
global $wp_filesystem;
|
643 |
|
644 |
+
if ( ! function_exists( 'WP_Filesystem' ) ) {
|
645 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
646 |
+
}
|
647 |
+
|
648 |
if ( ! WP_Filesystem() ) {
|
649 |
+
wcpdf_log_error( "WP_Filesystem couldn't be initiated! Unable to copy directory contents.", 'critical' );
|
650 |
+
return;
|
651 |
}
|
652 |
|
653 |
// we have the directories, let's try to copy
|
851 |
}
|
852 |
|
853 |
/**
|
854 |
+
* Schedule temporary files cleanup from paths older than 1 week (daily, hooked into wp_scheduled_delete )
|
855 |
*/
|
856 |
+
public function schedule_temporary_files_cleanup() {
|
857 |
+
if ( ! isset( WPO_WCPDF()->settings->debug_settings['enable_cleanup'] ) ) {
|
|
|
858 |
return;
|
859 |
}
|
860 |
|
861 |
+
$cleanup_age_days = isset( WPO_WCPDF()->settings->debug_settings['cleanup_days'] ) ? floatval( WPO_WCPDF()->settings->debug_settings['cleanup_days'] ) : 7.0;
|
862 |
+
$delete_timestamp = time() - ( intval ( DAY_IN_SECONDS * $cleanup_age_days ) );
|
863 |
+
$this->temporary_files_cleanup( $delete_timestamp );
|
864 |
+
}
|
865 |
+
|
866 |
+
/**
|
867 |
+
* Temporary files cleanup from paths
|
868 |
+
* @param int $delete_timestamp timestamp of the date/time before which to clean up files
|
869 |
+
*
|
870 |
+
* @return array Output message
|
871 |
+
*/
|
872 |
+
public function temporary_files_cleanup( $delete_timestamp = 0 ) {
|
873 |
+
global $wp_filesystem;
|
874 |
+
|
875 |
+
$delete_before = ! empty( $delete_timestamp ) ? intval( $delete_timestamp ) : time();
|
876 |
+
|
877 |
+
if ( ! function_exists( 'WP_Filesystem' ) ) {
|
878 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
879 |
}
|
880 |
|
881 |
+
if ( ! WP_Filesystem() ) {
|
882 |
+
return array( 'error' => esc_html__( "WP_Filesystem couldn't be initiated!", 'woocommerce-pdf-invoices-packing-slips' ) );
|
883 |
+
}
|
884 |
|
885 |
+
$paths_to_cleanup = apply_filters( 'wpo_wcpdf_cleanup_tmp_paths', array(
|
886 |
+
$this->get_tmp_path( 'attachments' ),
|
887 |
+
$this->get_tmp_path( 'dompdf' ),
|
888 |
+
) );
|
889 |
+
$excluded_files = apply_filters( 'wpo_wcpdf_cleanup_excluded_files', array(
|
890 |
+
'index.php',
|
891 |
+
'.htaccess',
|
892 |
+
) );
|
893 |
+
$folders_level = apply_filters( 'wpo_wcpdf_cleanup_folders_level', 3 );
|
894 |
+
$files = array();
|
895 |
+
$success = 0;
|
896 |
+
$error = 0;
|
897 |
+
$output = array();
|
898 |
+
|
899 |
+
foreach ( $paths_to_cleanup as $path ) {
|
900 |
+
$files = array_merge( $files, list_files( $path, $folders_level ) );
|
901 |
+
}
|
902 |
|
903 |
+
if ( ! empty( $files ) ) {
|
904 |
+
foreach ( $files as $file ) {
|
905 |
+
$basename = wp_basename( $file );
|
906 |
|
907 |
+
if ( ! in_array( $basename, $excluded_files ) && $wp_filesystem->exists( $file ) ) {
|
908 |
+
$file_timestamp = $wp_filesystem->mtime( $file );
|
909 |
+
|
910 |
+
// delete file
|
911 |
+
if ( $file_timestamp < $delete_before ) {
|
912 |
+
if ( $wp_filesystem->delete( $file, true ) ) {
|
913 |
+
$success++;
|
914 |
+
} else {
|
915 |
+
$error++;
|
916 |
+
}
|
917 |
}
|
918 |
}
|
919 |
+
|
920 |
+
if ( $error > 0 ) {
|
921 |
+
/* translators: 1,2. file count */
|
922 |
+
$message = sprintf( esc_html__( 'Unable to delete %1$d files! (deleted %2$d)', 'woocommerce-pdf-invoices-packing-slips' ), $error, $success );
|
923 |
+
$output['error'] = $message;
|
924 |
+
} else {
|
925 |
+
/* translators: file count */
|
926 |
+
$message = sprintf( esc_html__( 'Successfully deleted %d files!', 'woocommerce-pdf-invoices-packing-slips' ), $success );
|
927 |
+
$output['success'] = $message;
|
928 |
+
}
|
929 |
}
|
930 |
+
} else {
|
931 |
+
$output['success'] = esc_html__( 'Nothing to delete!', 'woocommerce-pdf-invoices-packing-slips' );
|
932 |
}
|
933 |
+
|
934 |
+
return $output;
|
935 |
}
|
936 |
|
937 |
/**
|
includes/class-wcpdf-settings-callbacks.php
CHANGED
@@ -122,6 +122,7 @@ class Settings_Callbacks {
|
|
122 |
'size' => isset( $args['text_input_size'] ) ? $args['text_input_size'] : NULL,
|
123 |
) + $args;
|
124 |
unset( $input_args['current'] );
|
|
|
125 |
|
126 |
ob_start();
|
127 |
$this->text_input( $input_args );
|
@@ -390,6 +391,17 @@ class Settings_Callbacks {
|
|
390 |
// don't display resolution
|
391 |
}
|
392 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
printf( '<img src="%1$s" style="display:block" id="img-%2$s"/>', esc_attr( $attachment_src ), esc_attr( $id ) );
|
394 |
if ( ! empty( $attachment_height ) && ! empty( $in_height ) ) {
|
395 |
$attachment_resolution = round( absint( $attachment_height ) / $in_height );
|
122 |
'size' => isset( $args['text_input_size'] ) ? $args['text_input_size'] : NULL,
|
123 |
) + $args;
|
124 |
unset( $input_args['current'] );
|
125 |
+
unset( $input_args['setting_name'] );
|
126 |
|
127 |
ob_start();
|
128 |
$this->text_input( $input_args );
|
391 |
// don't display resolution
|
392 |
}
|
393 |
|
394 |
+
/*
|
395 |
+
* .webp support can be disabled but still showing the image in settings.
|
396 |
+
* We should add a notice because this will display an error when redering the PDF using DOMPDF.
|
397 |
+
*/
|
398 |
+
if ( 'webp' === wp_check_filetype( $attachment_src )['ext'] && ! function_exists( 'imagecreatefromwebp' ) ) {
|
399 |
+
printf(
|
400 |
+
'<div class="notice notice-warning inline" style="display:inline-block; width:auto;"><p>%s</p></div>',
|
401 |
+
wp_kses_post( 'File type <strong>webp</strong> is not supported by your server! Please check your <strong>System Configurations</strong> under the <strong>Status</strong> tab.', 'woocommerce-pdf-invoices-packing-slips' )
|
402 |
+
);
|
403 |
+
}
|
404 |
+
|
405 |
printf( '<img src="%1$s" style="display:block" id="img-%2$s"/>', esc_attr( $attachment_src ), esc_attr( $id ) );
|
406 |
if ( ! empty( $attachment_height ) && ! empty( $in_height ) ) {
|
407 |
$attachment_resolution = round( absint( $attachment_height ) / $in_height );
|
includes/class-wcpdf-settings-debug.php
CHANGED
@@ -102,39 +102,10 @@ class Settings_Debug {
|
|
102 |
if ( ! check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
|
103 |
return;
|
104 |
}
|
105 |
-
$tmp_path = WPO_WCPDF()->main->get_tmp_path( 'attachments' );
|
106 |
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
} else {
|
111 |
-
$success = 0;
|
112 |
-
$error = 0;
|
113 |
-
if ( $files = glob( $tmp_path.'*.pdf' ) ) { // get all pdf files
|
114 |
-
foreach( $files as $file ) {
|
115 |
-
if( is_file( $file ) ) {
|
116 |
-
// delete file
|
117 |
-
if ( unlink( $file ) === true ) {
|
118 |
-
$success++;
|
119 |
-
} else {
|
120 |
-
$error++;
|
121 |
-
}
|
122 |
-
}
|
123 |
-
}
|
124 |
-
|
125 |
-
if ( $error > 0 ) {
|
126 |
-
/* translators: 1,2. file count */
|
127 |
-
$message = sprintf( esc_html__( 'Unable to delete %1$d files! (deleted %2$d)', 'woocommerce-pdf-invoices-packing-slips' ), $error, $success );
|
128 |
-
printf( '<div class="notice notice-error"><p>%s</p></div>', $message );
|
129 |
-
} else {
|
130 |
-
/* translators: file count */
|
131 |
-
$message = sprintf( esc_html__( 'Successfully deleted %d files!', 'woocommerce-pdf-invoices-packing-slips' ), $success );
|
132 |
-
printf( '<div class="notice notice-success"><p>%s</p></div>', $message );
|
133 |
-
}
|
134 |
-
} else {
|
135 |
-
printf( '<div class="notice notice-success"><p>%s</p></div>', esc_html__( 'Nothing to delete!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
136 |
-
}
|
137 |
-
}
|
138 |
}
|
139 |
?>
|
140 |
</form>
|
@@ -263,15 +234,12 @@ class Settings_Debug {
|
|
263 |
'args' => array(
|
264 |
'option_name' => $option_name,
|
265 |
'id' => 'enable_cleanup',
|
266 |
-
'disabled' => ( !function_exists("glob") || !function_exists('filemtime') ) ? 1 : NULL,
|
267 |
/* translators: number of days */
|
268 |
'text_input_wrap' => __( "every %s days", 'woocommerce-pdf-invoices-packing-slips' ),
|
269 |
'text_input_size' => 4,
|
270 |
'text_input_id' => 'cleanup_days',
|
271 |
'text_input_default'=> 7,
|
272 |
-
'description' => (
|
273 |
-
__( "Automatically clean up PDF files stored in the temporary folder (used for email attachments)", 'woocommerce-pdf-invoices-packing-slips' ) :
|
274 |
-
__( '<b>Disabled:</b> The PHP functions glob and filemtime are required for automatic cleanup but not enabled on your server.', 'woocommerce-pdf-invoices-packing-slips' ),
|
275 |
)
|
276 |
),
|
277 |
array(
|
102 |
if ( ! check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
|
103 |
return;
|
104 |
}
|
|
|
105 |
|
106 |
+
// clean files
|
107 |
+
$output = WPO_WCPDF()->main->temporary_files_cleanup( time() );
|
108 |
+
printf( '<div class="notice notice-%1$s"><p>%2$s</p></div>', key( $output ), reset( $output ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
}
|
110 |
?>
|
111 |
</form>
|
234 |
'args' => array(
|
235 |
'option_name' => $option_name,
|
236 |
'id' => 'enable_cleanup',
|
|
|
237 |
/* translators: number of days */
|
238 |
'text_input_wrap' => __( "every %s days", 'woocommerce-pdf-invoices-packing-slips' ),
|
239 |
'text_input_size' => 4,
|
240 |
'text_input_id' => 'cleanup_days',
|
241 |
'text_input_default'=> 7,
|
242 |
+
'description' => __( "Automatically clean up PDF files stored in the temporary folder (used for email attachments)", 'woocommerce-pdf-invoices-packing-slips' ),
|
|
|
|
|
243 |
)
|
244 |
),
|
245 |
array(
|
includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php
CHANGED
@@ -30,6 +30,9 @@ class Third_Party_Plugins {
|
|
30 |
// WooCommerce Product Bundles compatibility (add row classes)
|
31 |
add_filter( 'wpo_wcpdf_item_row_class', array( $this, 'add_product_bundles_classes' ), 10, 4 );
|
32 |
|
|
|
|
|
|
|
33 |
// WooCommerce Chained Products compatibility (add row classes)
|
34 |
add_filter( 'wpo_wcpdf_item_row_class', array( $this, 'add_chained_product_class' ), 10, 4 );
|
35 |
|
@@ -117,13 +120,13 @@ class Third_Party_Plugins {
|
|
117 |
* @param object $order WC_Order order
|
118 |
* @param int $item_id WooCommerce Item ID
|
119 |
*/
|
120 |
-
public function add_product_bundles_classes ( $classes, $document_type, $order, $item_id =
|
121 |
if ( !class_exists('WC_Bundles') ) {
|
122 |
return $classes;
|
123 |
}
|
124 |
|
125 |
-
$item_id = !empty($item_id) ? $item_id : $this->get_item_id_from_classes( $classes );
|
126 |
-
if ( empty($item_id) ) {
|
127 |
return $classes;
|
128 |
}
|
129 |
|
@@ -144,13 +147,43 @@ class Third_Party_Plugins {
|
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
* @param string $classes CSS classes for item row (tr)
|
149 |
* @param string $document_type PDF Document type
|
150 |
* @param object $order WC_Order order
|
151 |
* @param int $item_id WooCommerce Item ID
|
152 |
*/
|
153 |
-
public function add_chained_product_class ( $classes, $document_type, $order, $item_id =
|
154 |
if ( !class_exists('SA_WC_Chained_Products') && !class_exists('WC_Chained_Products') ) {
|
155 |
return $classes;
|
156 |
}
|
@@ -174,7 +207,7 @@ class Third_Party_Plugins {
|
|
174 |
* @param object $order WC_Order order
|
175 |
* @param int $item_id WooCommerce Item ID
|
176 |
*/
|
177 |
-
public function add_composite_product_class ( $classes, $document_type, $order, $item_id =
|
178 |
if ( !function_exists('wc_cp_is_composited_order_item') || !function_exists('wc_cp_is_composite_container_order_item') ) {
|
179 |
return $classes;
|
180 |
}
|
30 |
// WooCommerce Product Bundles compatibility (add row classes)
|
31 |
add_filter( 'wpo_wcpdf_item_row_class', array( $this, 'add_product_bundles_classes' ), 10, 4 );
|
32 |
|
33 |
+
// WPC Bundles compatibility (add row classes)
|
34 |
+
add_filter( 'wpo_wcpdf_item_row_class', array( $this, 'add_wpc_product_bundles_classes' ), 10, 4 );
|
35 |
+
|
36 |
// WooCommerce Chained Products compatibility (add row classes)
|
37 |
add_filter( 'wpo_wcpdf_item_row_class', array( $this, 'add_chained_product_class' ), 10, 4 );
|
38 |
|
120 |
* @param object $order WC_Order order
|
121 |
* @param int $item_id WooCommerce Item ID
|
122 |
*/
|
123 |
+
public function add_product_bundles_classes ( $classes, $document_type, $order, $item_id = 0 ) {
|
124 |
if ( !class_exists('WC_Bundles') ) {
|
125 |
return $classes;
|
126 |
}
|
127 |
|
128 |
+
$item_id = ! empty( $item_id ) ? $item_id : $this->get_item_id_from_classes( $classes );
|
129 |
+
if ( empty( $item_id ) ) {
|
130 |
return $classes;
|
131 |
}
|
132 |
|
147 |
}
|
148 |
|
149 |
/**
|
150 |
+
* WPC Product Bundles
|
151 |
+
* @param string $classes CSS classes for item row (tr)
|
152 |
+
* @param string $document_type PDF Document type
|
153 |
+
* @param object $order WC_Order order
|
154 |
+
* @param int $item_id WooCommerce Item ID
|
155 |
+
*/
|
156 |
+
public function add_wpc_product_bundles_classes ( $classes, $document_type, $order, $item_id = 0 ) {
|
157 |
+
if ( ! class_exists( 'WPCleverWoosb' ) ) {
|
158 |
+
return $classes;
|
159 |
+
}
|
160 |
+
|
161 |
+
$item_id = ! empty( $item_id ) ? $item_id : $this->get_item_id_from_classes( $classes );
|
162 |
+
if ( empty( $item_id ) ) {
|
163 |
+
return $classes;
|
164 |
+
}
|
165 |
+
|
166 |
+
// Add row classes
|
167 |
+
$refunded_item_id = WCX_Order::get_item_meta( $order, $item_id, '_refunded_item_id', true );
|
168 |
+
$class_item_id = ! empty( $refunded_item_id ) ? $refunded_item_id : $item_id;
|
169 |
+
|
170 |
+
if ( $bundled_by = WCX_Order::get_item_meta( $order, $class_item_id, '_woosb_parent_id', true ) ) {
|
171 |
+
$classes = $classes . ' bundled-item';
|
172 |
+
} elseif ( $bundled_items = WCX_Order::get_item_meta( $order, $class_item_id, '_woosb_ids', true ) ) {
|
173 |
+
$classes = $classes . ' product-bundle';
|
174 |
+
}
|
175 |
+
|
176 |
+
return $classes;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* WooCommerce Chained Products
|
181 |
* @param string $classes CSS classes for item row (tr)
|
182 |
* @param string $document_type PDF Document type
|
183 |
* @param object $order WC_Order order
|
184 |
* @param int $item_id WooCommerce Item ID
|
185 |
*/
|
186 |
+
public function add_chained_product_class ( $classes, $document_type, $order, $item_id = 0 ) {
|
187 |
if ( !class_exists('SA_WC_Chained_Products') && !class_exists('WC_Chained_Products') ) {
|
188 |
return $classes;
|
189 |
}
|
207 |
* @param object $order WC_Order order
|
208 |
* @param int $item_id WooCommerce Item ID
|
209 |
*/
|
210 |
+
public function add_composite_product_class ( $classes, $document_type, $order, $item_id = 0 ) {
|
211 |
if ( !function_exists('wc_cp_is_composited_order_item') || !function_exists('wc_cp_is_composite_container_order_item') ) {
|
212 |
return $classes;
|
213 |
}
|
includes/documents/abstract-wcpdf-order-document-methods.php
CHANGED
@@ -622,9 +622,9 @@ abstract class Order_Document_Methods extends Order_Document {
|
|
622 |
|
623 |
// Set item meta
|
624 |
if (function_exists('wc_display_item_meta')) { // WC3.0+
|
625 |
-
$data['meta'] = wc_display_item_meta( $item, array(
|
626 |
'echo' => false,
|
627 |
-
) );
|
628 |
} else {
|
629 |
if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) ) {
|
630 |
$meta = new \WC_Order_Item_Meta( $item['item_meta'], $product );
|
@@ -862,7 +862,7 @@ abstract class Order_Document_Methods extends Order_Document {
|
|
862 |
$contextless_site_url = str_replace(array('http://','https://'), '', trailingslashit(WP_CONTENT_URL));
|
863 |
}
|
864 |
$thumbnail_path = str_replace( $contextless_site_url, trailingslashit( $forwardslash_basepath ), $contextless_thumbnail_url);
|
865 |
-
|
866 |
// fallback if thumbnail file doesn't exist
|
867 |
if (apply_filters('wpo_wcpdf_use_path', true) && !file_exists($thumbnail_path)) {
|
868 |
if ($thumbnail_id = $this->get_thumbnail_id( $product ) ) {
|
@@ -887,6 +887,17 @@ abstract class Order_Document_Methods extends Order_Document {
|
|
887 |
$thumbnail = $thumbnail_img_tag_url;
|
888 |
}
|
889 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
890 |
// die($thumbnail);
|
891 |
return $thumbnail;
|
892 |
}
|
622 |
|
623 |
// Set item meta
|
624 |
if (function_exists('wc_display_item_meta')) { // WC3.0+
|
625 |
+
$data['meta'] = wc_display_item_meta( $item, apply_filters( 'wpo_wcpdf_display_item_meta_args', array(
|
626 |
'echo' => false,
|
627 |
+
), $this ) );
|
628 |
} else {
|
629 |
if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) ) {
|
630 |
$meta = new \WC_Order_Item_Meta( $item['item_meta'], $product );
|
862 |
$contextless_site_url = str_replace(array('http://','https://'), '', trailingslashit(WP_CONTENT_URL));
|
863 |
}
|
864 |
$thumbnail_path = str_replace( $contextless_site_url, trailingslashit( $forwardslash_basepath ), $contextless_thumbnail_url);
|
865 |
+
|
866 |
// fallback if thumbnail file doesn't exist
|
867 |
if (apply_filters('wpo_wcpdf_use_path', true) && !file_exists($thumbnail_path)) {
|
868 |
if ($thumbnail_id = $this->get_thumbnail_id( $product ) ) {
|
887 |
$thumbnail = $thumbnail_img_tag_url;
|
888 |
}
|
889 |
|
890 |
+
/*
|
891 |
+
* PHP GD library can be installed but 'webp' support could be disabled,
|
892 |
+
* which turns the function 'imagecreatefromwebp()' inexistent,
|
893 |
+
* leading to display an error in DOMPDF.
|
894 |
+
*
|
895 |
+
* Check 'System configuration' in the Status tab for 'webp' support.
|
896 |
+
*/
|
897 |
+
if ( 'webp' === wp_check_filetype( $thumbnail_path )['ext'] && ! function_exists( 'imagecreatefromwebp' ) ) {
|
898 |
+
$thumbnail = '';
|
899 |
+
}
|
900 |
+
|
901 |
// die($thumbnail);
|
902 |
return $thumbnail;
|
903 |
}
|
includes/documents/abstract-wcpdf-order-document.php
CHANGED
@@ -151,7 +151,8 @@ abstract class Order_Document {
|
|
151 |
if ( $this->storing_settings_enabled() && empty( $order_settings ) && !empty( $this->order ) ) {
|
152 |
// this is either the first time the document is generated, or historical settings are disabled
|
153 |
// in both cases, we store the document settings
|
154 |
-
|
|
|
155 |
}
|
156 |
|
157 |
// display date & display number were checkbox settings but now a select setting that could be set but empty - should behave as 'unchecked'
|
@@ -174,8 +175,8 @@ abstract class Order_Document {
|
|
174 |
return apply_filters( 'wpo_wcpdf_document_store_settings', false, $this );
|
175 |
}
|
176 |
|
177 |
-
public function
|
178 |
-
|
179 |
'enabled',
|
180 |
'attach_to_email_ids',
|
181 |
'disable_for_statuses',
|
@@ -186,6 +187,10 @@ abstract class Order_Document {
|
|
186 |
'paper_size',
|
187 |
'font_subsetting',
|
188 |
), $this );
|
|
|
|
|
|
|
|
|
189 |
if ( in_array( $key, $non_historical_settings ) && isset( $this->latest_settings ) ) {
|
190 |
$setting = isset( $this->latest_settings[$key] ) ? $this->latest_settings[$key] : $default;
|
191 |
} else {
|
151 |
if ( $this->storing_settings_enabled() && empty( $order_settings ) && !empty( $this->order ) ) {
|
152 |
// this is either the first time the document is generated, or historical settings are disabled
|
153 |
// in both cases, we store the document settings
|
154 |
+
// exclude non historical settings from being saved in order meta
|
155 |
+
WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", array_diff_key( $settings, array_flip( $this->get_non_historical_settings() ) ) );
|
156 |
}
|
157 |
|
158 |
// display date & display number were checkbox settings but now a select setting that could be set but empty - should behave as 'unchecked'
|
175 |
return apply_filters( 'wpo_wcpdf_document_store_settings', false, $this );
|
176 |
}
|
177 |
|
178 |
+
public function get_non_historical_settings() {
|
179 |
+
return apply_filters( 'wpo_wcpdf_non_historical_settings', array(
|
180 |
'enabled',
|
181 |
'attach_to_email_ids',
|
182 |
'disable_for_statuses',
|
187 |
'paper_size',
|
188 |
'font_subsetting',
|
189 |
), $this );
|
190 |
+
}
|
191 |
+
|
192 |
+
public function get_setting( $key, $default = '' ) {
|
193 |
+
$non_historical_settings = $this->get_non_historical_settings();
|
194 |
if ( in_array( $key, $non_historical_settings ) && isset( $this->latest_settings ) ) {
|
195 |
$setting = isset( $this->latest_settings[$key] ) ? $this->latest_settings[$key] : $default;
|
196 |
} else {
|
includes/documents/class-wcpdf-invoice.php
CHANGED
@@ -62,7 +62,8 @@ class Invoice extends Order_Document_Methods {
|
|
62 |
$common_settings = WPO_WCPDF()->settings->get_common_document_settings();
|
63 |
$document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
|
64 |
$settings = (array) $document_settings + (array) $common_settings;
|
65 |
-
|
|
|
66 |
}
|
67 |
|
68 |
if ( isset( $this->settings['display_date'] ) && $this->settings['display_date'] == 'order_date' && !empty( $this->order ) ) {
|
62 |
$common_settings = WPO_WCPDF()->settings->get_common_document_settings();
|
63 |
$document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
|
64 |
$settings = (array) $document_settings + (array) $common_settings;
|
65 |
+
// exclude non historical settings from being saved in order meta
|
66 |
+
WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", array_diff_key( $settings, array_flip( $this->get_non_historical_settings() ) ) );
|
67 |
}
|
68 |
|
69 |
if ( isset( $this->settings['display_date'] ) && $this->settings['display_date'] == 'order_date' && !empty( $this->order ) ) {
|
includes/documents/class-wcpdf-sequential-number-store.php
CHANGED
@@ -73,15 +73,18 @@ class Sequential_Number_Store {
|
|
73 |
$sql = "CREATE TABLE {$this->table_name} (
|
74 |
id int(16) NOT NULL AUTO_INCREMENT,
|
75 |
order_id int(16),
|
76 |
-
date datetime DEFAULT '
|
77 |
calculated_number int (16),
|
78 |
PRIMARY KEY (id)
|
79 |
) $charset_collate;";
|
80 |
|
81 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
return
|
85 |
}
|
86 |
|
87 |
/**
|
73 |
$sql = "CREATE TABLE {$this->table_name} (
|
74 |
id int(16) NOT NULL AUTO_INCREMENT,
|
75 |
order_id int(16),
|
76 |
+
date datetime DEFAULT '1000-01-01 00:00:00' NOT NULL,
|
77 |
calculated_number int (16),
|
78 |
PRIMARY KEY (id)
|
79 |
) $charset_collate;";
|
80 |
|
81 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
82 |
+
dbDelta( $sql );
|
83 |
+
|
84 |
+
// catch mysql errors
|
85 |
+
wcpdf_catch_db_object_errors( $wpdb );
|
86 |
|
87 |
+
return;
|
88 |
}
|
89 |
|
90 |
/**
|
includes/views/dompdf-status.php
CHANGED
@@ -29,6 +29,12 @@ $server_configs = apply_filters( 'wpo_wcpdf_server_configs' , array(
|
|
29 |
'result' => function_exists('imagecreate'),
|
30 |
'fallback' => __( 'Required if you have images in your documents', 'woocommerce-pdf-invoices-packing-slips' ),
|
31 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
// "PCRE" => array(
|
33 |
// "required" => true,
|
34 |
// "value" => phpversion("pcre"),
|
29 |
'result' => function_exists('imagecreate'),
|
30 |
'fallback' => __( 'Required if you have images in your documents', 'woocommerce-pdf-invoices-packing-slips' ),
|
31 |
),
|
32 |
+
'WebP Support' => array(
|
33 |
+
'required' => __( 'Required when using .webp images', 'woocommerce-pdf-invoices-packing-slips' ),
|
34 |
+
'value' => null,
|
35 |
+
'result' => function_exists('imagecreatefromwebp'),
|
36 |
+
'fallback' => __( 'Required if you have .webp images in your documents', 'woocommerce-pdf-invoices-packing-slips' ),
|
37 |
+
),
|
38 |
// "PCRE" => array(
|
39 |
// "required" => true,
|
40 |
// "value" => phpversion("pcre"),
|
includes/wcpdf-functions.php
CHANGED
@@ -241,4 +241,51 @@ function wcpdf_output_error( $message, $level = 'error', $e = null ) {
|
|
241 |
*/
|
242 |
function wcpdf_date_format( $document = null, $date_type = null ) {
|
243 |
return apply_filters( 'wpo_wcpdf_date_format', wc_date_format(), $document, $date_type );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
}
|
241 |
*/
|
242 |
function wcpdf_date_format( $document = null, $date_type = null ) {
|
243 |
return apply_filters( 'wpo_wcpdf_date_format', wc_date_format(), $document, $date_type );
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Catch MySQL errors
|
248 |
+
*
|
249 |
+
* Inspired from here: https://github.com/johnbillion/query-monitor/blob/d5b622b91f18552e7105e62fa84d3102b08975a4/collectors/db_queries.php#L125-L280
|
250 |
+
*
|
251 |
+
* With SAVEQUERIES constant defined as 'false', '$wpdb->queries' is empty and '$EZSQL_ERROR' is used instead.
|
252 |
+
* Using the Query Monitor plugin, the SAVEQUERIES constant is defined as 'true'
|
253 |
+
* More info about this constant can be found here: https://wordpress.org/support/article/debugging-in-wordpress/#savequeries
|
254 |
+
*
|
255 |
+
* @param object $wpdb
|
256 |
+
* @return array errors found
|
257 |
+
*/
|
258 |
+
function wcpdf_catch_db_object_errors( $wpdb ) {
|
259 |
+
global $EZSQL_ERROR;
|
260 |
+
|
261 |
+
$errors = array();
|
262 |
+
|
263 |
+
// using '$wpdb->queries'
|
264 |
+
if ( ! empty( $wpdb->queries ) && is_array( $wpdb->queries ) ) {
|
265 |
+
foreach ( $wpdb->queries as $query ) {
|
266 |
+
$result = isset( $query['result'] ) ? $query['result'] : null;
|
267 |
+
|
268 |
+
if ( is_wp_error( $result ) && is_array( $result->errors ) ) {
|
269 |
+
foreach ( $result->errors as $error ) {
|
270 |
+
$errors[] = reset( $error );
|
271 |
+
}
|
272 |
+
}
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
// fallback to '$EZSQL_ERROR'
|
277 |
+
if ( empty( $errors ) && ! empty( $EZSQL_ERROR ) && is_array( $EZSQL_ERROR ) ) {
|
278 |
+
foreach ( $EZSQL_ERROR as $error ) {
|
279 |
+
$errors[] = $error['error_str'];
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
// log errors
|
284 |
+
if ( ! empty( $errors ) ) {
|
285 |
+
foreach ( $errors as $error_message ) {
|
286 |
+
wcpdf_log_error( $error_message, 'critical' );
|
287 |
+
}
|
288 |
+
}
|
289 |
+
|
290 |
+
return $errors;
|
291 |
}
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@ Contributors: pomegranate, alexmigf, yordansoares, kluver, dpeyou
|
|
3 |
Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
|
4 |
Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
|
5 |
Requires at least: 3.5
|
6 |
-
Tested up to: 5.
|
7 |
Requires PHP: 7.1
|
8 |
-
Stable tag: 2.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -27,7 +27,7 @@ This WooCommerce extension automatically adds a PDF invoice to the order confirm
|
|
27 |
In addition to this, we offer several premium extensions:
|
28 |
|
29 |
* Create/email PDF Proforma Invoices, Credit Notes (for Refunds), email Packing Slips, automatic upload to Dropbox & more with [WooCommerce PDF Invoices & Packing Slips Professional](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
|
30 |
-
* Automatically send new orders or packing slips to your printer, as soon as the customer orders! [WooCommerce Automatic Order Printing](https://www.simbahosting.co.uk/s3/product/woocommerce-automatic-order-printing/?affiliates=2) (from our partners at Simba Hosting)
|
31 |
* More advanced & stylish templates with [WooCommerce PDF Invoices & Packing Slips Premium Templates](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)
|
32 |
|
33 |
= Fully customizable =
|
@@ -102,6 +102,17 @@ There's a setting on the Status tab of the settings page that allows you to togg
|
|
102 |
|
103 |
== Changelog ==
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
= 2.12.1 =
|
106 |
* Fix: Show a feedback notice after saving settings
|
107 |
* Fix: images with min-width/min-height styles rendered tables incorrectly (dompdf patch)
|
3 |
Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
|
4 |
Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
|
5 |
Requires at least: 3.5
|
6 |
+
Tested up to: 5.9
|
7 |
Requires PHP: 7.1
|
8 |
+
Stable tag: 2.13.0
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
27 |
In addition to this, we offer several premium extensions:
|
28 |
|
29 |
* Create/email PDF Proforma Invoices, Credit Notes (for Refunds), email Packing Slips, automatic upload to Dropbox & more with [WooCommerce PDF Invoices & Packing Slips Professional](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
|
30 |
+
* Automatically send new orders or packing slips to your printer, as soon as the customer orders! [WooCommerce Automatic Order Printing](https://www.simbahosting.co.uk/s3/product/woocommerce-printnode-automatic-order-printing/?affiliates=2) (from our partners at Simba Hosting)
|
31 |
* More advanced & stylish templates with [WooCommerce PDF Invoices & Packing Slips Premium Templates](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)
|
32 |
|
33 |
= Fully customizable =
|
102 |
|
103 |
== Changelog ==
|
104 |
|
105 |
+
= 2.13.0 =
|
106 |
+
* New: include dompdf temporary folder in cleanup procedure
|
107 |
+
* New: Add CSS row classes for WPC Product Bundles
|
108 |
+
* New: filter to override `wc_display_item_meta` arguments
|
109 |
+
* Fix: Prevent errors when server doesn't support `.webp` image rendering
|
110 |
+
* Fix: change invalid default date 0000-00-00 00:00:00 on number store tables
|
111 |
+
* Tweak: Don't store non-historical document settings in order meta
|
112 |
+
* Templates: New action hook before the document label (`wpo_wcpdf_before_document_label`)
|
113 |
+
* Libraries: updated dompdf to 1.2.0
|
114 |
+
* Marked tested up to WP5.9
|
115 |
+
|
116 |
= 2.12.1 =
|
117 |
* Fix: Show a feedback notice after saving settings
|
118 |
* Fix: images with min-width/min-height styles rendered tables incorrectly (dompdf patch)
|
templates/Simple/invoice.php
CHANGED
@@ -24,6 +24,8 @@
|
|
24 |
</tr>
|
25 |
</table>
|
26 |
|
|
|
|
|
27 |
<h1 class="document-type-label">
|
28 |
<?php if ( $this->has_header_logo() ) echo $this->get_title(); ?>
|
29 |
</h1>
|
24 |
</tr>
|
25 |
</table>
|
26 |
|
27 |
+
<?php do_action( 'wpo_wcpdf_before_document_label', $this->get_type(), $this->order ); ?>
|
28 |
+
|
29 |
<h1 class="document-type-label">
|
30 |
<?php if ( $this->has_header_logo() ) echo $this->get_title(); ?>
|
31 |
</h1>
|
templates/Simple/packing-slip.php
CHANGED
@@ -24,6 +24,8 @@
|
|
24 |
</tr>
|
25 |
</table>
|
26 |
|
|
|
|
|
27 |
<h1 class="document-type-label">
|
28 |
<?php if ( $this->has_header_logo() ) echo $this->get_title(); ?>
|
29 |
</h1>
|
24 |
</tr>
|
25 |
</table>
|
26 |
|
27 |
+
<?php do_action( 'wpo_wcpdf_before_document_label', $this->get_type(), $this->order ); ?>
|
28 |
+
|
29 |
<h1 class="document-type-label">
|
30 |
<?php if ( $this->has_header_logo() ) echo $this->get_title(); ?>
|
31 |
</h1>
|
vendor/composer/installed.json
CHANGED
@@ -2,17 +2,17 @@
|
|
2 |
"packages": [
|
3 |
{
|
4 |
"name": "dompdf/dompdf",
|
5 |
-
"version": "
|
6 |
-
"version_normalized": "
|
7 |
"source": {
|
8 |
"type": "git",
|
9 |
"url": "https://github.com/dompdf/dompdf.git",
|
10 |
-
"reference": "
|
11 |
},
|
12 |
"dist": {
|
13 |
"type": "zip",
|
14 |
-
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/
|
15 |
-
"reference": "
|
16 |
"shasum": ""
|
17 |
},
|
18 |
"require": {
|
@@ -33,7 +33,7 @@
|
|
33 |
"ext-imagick": "Improves image processing performance",
|
34 |
"ext-zlib": "Needed for pdf stream compression"
|
35 |
},
|
36 |
-
"time": "2022-
|
37 |
"type": "library",
|
38 |
"installation-source": "dist",
|
39 |
"autoload": {
|
@@ -66,7 +66,7 @@
|
|
66 |
"homepage": "https://github.com/dompdf/dompdf",
|
67 |
"support": {
|
68 |
"issues": "https://github.com/dompdf/dompdf/issues",
|
69 |
-
"source": "https://github.com/dompdf/dompdf/tree/
|
70 |
},
|
71 |
"install-path": "../dompdf/dompdf"
|
72 |
},
|
2 |
"packages": [
|
3 |
{
|
4 |
"name": "dompdf/dompdf",
|
5 |
+
"version": "v1.2.0",
|
6 |
+
"version_normalized": "1.2.0.0",
|
7 |
"source": {
|
8 |
"type": "git",
|
9 |
"url": "https://github.com/dompdf/dompdf.git",
|
10 |
+
"reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd"
|
11 |
},
|
12 |
"dist": {
|
13 |
"type": "zip",
|
14 |
+
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/60b704331479a69e9bcdb3496da2315b5c4f94fd",
|
15 |
+
"reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd",
|
16 |
"shasum": ""
|
17 |
},
|
18 |
"require": {
|
33 |
"ext-imagick": "Improves image processing performance",
|
34 |
"ext-zlib": "Needed for pdf stream compression"
|
35 |
},
|
36 |
+
"time": "2022-02-07T13:02:10+00:00",
|
37 |
"type": "library",
|
38 |
"installation-source": "dist",
|
39 |
"autoload": {
|
66 |
"homepage": "https://github.com/dompdf/dompdf",
|
67 |
"support": {
|
68 |
"issues": "https://github.com/dompdf/dompdf/issues",
|
69 |
+
"source": "https://github.com/dompdf/dompdf/tree/v1.2.0"
|
70 |
},
|
71 |
"install-path": "../dompdf/dompdf"
|
72 |
},
|
vendor/composer/installed.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
'type' => 'library',
|
6 |
'install_path' => __DIR__ . '/../../',
|
7 |
'aliases' => array(),
|
8 |
-
'reference' => '
|
9 |
'name' => '__root__',
|
10 |
'dev' => true,
|
11 |
),
|
@@ -16,16 +16,16 @@
|
|
16 |
'type' => 'library',
|
17 |
'install_path' => __DIR__ . '/../../',
|
18 |
'aliases' => array(),
|
19 |
-
'reference' => '
|
20 |
'dev_requirement' => false,
|
21 |
),
|
22 |
'dompdf/dompdf' => array(
|
23 |
-
'pretty_version' => '
|
24 |
-
'version' => '
|
25 |
'type' => 'library',
|
26 |
'install_path' => __DIR__ . '/../dompdf/dompdf',
|
27 |
'aliases' => array(),
|
28 |
-
'reference' => '
|
29 |
'dev_requirement' => false,
|
30 |
),
|
31 |
'phenx/php-font-lib' => array(
|
5 |
'type' => 'library',
|
6 |
'install_path' => __DIR__ . '/../../',
|
7 |
'aliases' => array(),
|
8 |
+
'reference' => '655ed247e8fdfed995edd036e8ae37cc61e08b3a',
|
9 |
'name' => '__root__',
|
10 |
'dev' => true,
|
11 |
),
|
16 |
'type' => 'library',
|
17 |
'install_path' => __DIR__ . '/../../',
|
18 |
'aliases' => array(),
|
19 |
+
'reference' => '655ed247e8fdfed995edd036e8ae37cc61e08b3a',
|
20 |
'dev_requirement' => false,
|
21 |
),
|
22 |
'dompdf/dompdf' => array(
|
23 |
+
'pretty_version' => 'v1.2.0',
|
24 |
+
'version' => '1.2.0.0',
|
25 |
'type' => 'library',
|
26 |
'install_path' => __DIR__ . '/../dompdf/dompdf',
|
27 |
'aliases' => array(),
|
28 |
+
'reference' => '60b704331479a69e9bcdb3496da2315b5c4f94fd',
|
29 |
'dev_requirement' => false,
|
30 |
),
|
31 |
'phenx/php-font-lib' => array(
|
vendor/dompdf/dompdf/VERSION
CHANGED
@@ -1 +1 @@
|
|
1 |
-
|
1 |
+
1.2.0
|
vendor/dompdf/dompdf/lib/Cpdf.php
CHANGED
@@ -5637,7 +5637,7 @@ EOT;
|
|
5637 |
protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte)
|
5638 |
{
|
5639 |
// generate images
|
5640 |
-
$img = imagecreatefrompng($file);
|
5641 |
|
5642 |
if ($img === false) {
|
5643 |
return;
|
@@ -5686,7 +5686,7 @@ EOT;
|
|
5686 |
$alpha_channel->writeimage($tempfile_alpha);
|
5687 |
|
5688 |
// Cast to 8bit+palette
|
5689 |
-
$imgalpha_ = imagecreatefrompng($tempfile_alpha);
|
5690 |
imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx);
|
5691 |
imagedestroy($imgalpha_);
|
5692 |
imagepng($imgalpha, $tempfile_alpha);
|
@@ -5699,7 +5699,7 @@ EOT;
|
|
5699 |
$color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYBLUE, 0, 0);
|
5700 |
$color_channels->writeimage($tempfile_plain);
|
5701 |
|
5702 |
-
$imgplain = imagecreatefrompng($tempfile_plain);
|
5703 |
}
|
5704 |
// Use PECL imagick + ImageMagic to process transparent PNG images
|
5705 |
elseif (extension_loaded("imagick")) {
|
@@ -5732,7 +5732,7 @@ EOT;
|
|
5732 |
$alpha_channel->writeImage($tempfile_alpha);
|
5733 |
|
5734 |
// Cast to 8bit+palette
|
5735 |
-
$imgalpha_ = imagecreatefrompng($tempfile_alpha);
|
5736 |
imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx);
|
5737 |
imagedestroy($imgalpha_);
|
5738 |
imagepng($imgalpha, $tempfile_alpha);
|
@@ -5748,7 +5748,7 @@ EOT;
|
|
5748 |
$color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYBLUE, 0, 0);
|
5749 |
$color_channels->writeImage($tempfile_plain);
|
5750 |
|
5751 |
-
$imgplain = imagecreatefrompng($tempfile_plain);
|
5752 |
} else {
|
5753 |
// allocated colors cache
|
5754 |
$allocated_colors = [];
|
5637 |
protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte)
|
5638 |
{
|
5639 |
// generate images
|
5640 |
+
$img = @imagecreatefrompng($file);
|
5641 |
|
5642 |
if ($img === false) {
|
5643 |
return;
|
5686 |
$alpha_channel->writeimage($tempfile_alpha);
|
5687 |
|
5688 |
// Cast to 8bit+palette
|
5689 |
+
$imgalpha_ = @imagecreatefrompng($tempfile_alpha);
|
5690 |
imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx);
|
5691 |
imagedestroy($imgalpha_);
|
5692 |
imagepng($imgalpha, $tempfile_alpha);
|
5699 |
$color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYBLUE, 0, 0);
|
5700 |
$color_channels->writeimage($tempfile_plain);
|
5701 |
|
5702 |
+
$imgplain = @imagecreatefrompng($tempfile_plain);
|
5703 |
}
|
5704 |
// Use PECL imagick + ImageMagic to process transparent PNG images
|
5705 |
elseif (extension_loaded("imagick")) {
|
5732 |
$alpha_channel->writeImage($tempfile_alpha);
|
5733 |
|
5734 |
// Cast to 8bit+palette
|
5735 |
+
$imgalpha_ = @imagecreatefrompng($tempfile_alpha);
|
5736 |
imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx);
|
5737 |
imagedestroy($imgalpha_);
|
5738 |
imagepng($imgalpha, $tempfile_alpha);
|
5748 |
$color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYBLUE, 0, 0);
|
5749 |
$color_channels->writeImage($tempfile_plain);
|
5750 |
|
5751 |
+
$imgplain = @imagecreatefrompng($tempfile_plain);
|
5752 |
} else {
|
5753 |
// allocated colors cache
|
5754 |
$allocated_colors = [];
|
vendor/dompdf/dompdf/src/Frame/FrameListIterator.php
CHANGED
@@ -7,44 +7,48 @@ use Dompdf\Frame;
|
|
7 |
/**
|
8 |
* Linked-list Iterator
|
9 |
*
|
10 |
-
* Returns children in order and allows for list to change during iteration,
|
11 |
-
* provided the changes occur to or after the current element
|
12 |
*
|
13 |
* @access private
|
14 |
* @package dompdf
|
15 |
*/
|
16 |
class FrameListIterator implements Iterator
|
17 |
{
|
18 |
-
|
19 |
/**
|
20 |
* @var Frame
|
21 |
*/
|
22 |
-
protected $
|
23 |
|
24 |
/**
|
25 |
-
* @var Frame
|
|
|
|
|
|
|
|
|
|
|
26 |
*/
|
27 |
-
protected $
|
28 |
|
29 |
/**
|
30 |
* @var int
|
31 |
*/
|
32 |
-
protected $
|
33 |
|
34 |
/**
|
35 |
* @param Frame $frame
|
36 |
*/
|
37 |
public function __construct(Frame $frame)
|
38 |
{
|
39 |
-
$this->
|
40 |
-
$this->
|
41 |
-
$this->_num = 0;
|
42 |
}
|
43 |
|
44 |
public function rewind(): void
|
45 |
{
|
46 |
-
$this->
|
47 |
-
$this->
|
|
|
48 |
}
|
49 |
|
50 |
/**
|
@@ -52,7 +56,7 @@ class FrameListIterator implements Iterator
|
|
52 |
*/
|
53 |
public function valid(): bool
|
54 |
{
|
55 |
-
return
|
56 |
}
|
57 |
|
58 |
/**
|
@@ -60,7 +64,7 @@ class FrameListIterator implements Iterator
|
|
60 |
*/
|
61 |
public function key(): int
|
62 |
{
|
63 |
-
return $this->
|
64 |
}
|
65 |
|
66 |
/**
|
@@ -68,17 +72,25 @@ class FrameListIterator implements Iterator
|
|
68 |
*/
|
69 |
public function current(): ?Frame
|
70 |
{
|
71 |
-
return $this->
|
72 |
}
|
73 |
|
74 |
public function next(): void
|
75 |
{
|
76 |
-
|
77 |
-
if (!$ret) {
|
78 |
return;
|
79 |
}
|
80 |
|
81 |
-
$this->
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
}
|
84 |
}
|
7 |
/**
|
8 |
* Linked-list Iterator
|
9 |
*
|
10 |
+
* Returns children in order and allows for the list to change during iteration,
|
11 |
+
* provided the changes occur to or after the current element.
|
12 |
*
|
13 |
* @access private
|
14 |
* @package dompdf
|
15 |
*/
|
16 |
class FrameListIterator implements Iterator
|
17 |
{
|
|
|
18 |
/**
|
19 |
* @var Frame
|
20 |
*/
|
21 |
+
protected $parent;
|
22 |
|
23 |
/**
|
24 |
+
* @var Frame|null
|
25 |
+
*/
|
26 |
+
protected $cur;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var Frame|null
|
30 |
*/
|
31 |
+
protected $prev;
|
32 |
|
33 |
/**
|
34 |
* @var int
|
35 |
*/
|
36 |
+
protected $num;
|
37 |
|
38 |
/**
|
39 |
* @param Frame $frame
|
40 |
*/
|
41 |
public function __construct(Frame $frame)
|
42 |
{
|
43 |
+
$this->parent = $frame;
|
44 |
+
$this->rewind();
|
|
|
45 |
}
|
46 |
|
47 |
public function rewind(): void
|
48 |
{
|
49 |
+
$this->cur = $this->parent->get_first_child();
|
50 |
+
$this->prev = null;
|
51 |
+
$this->num = 0;
|
52 |
}
|
53 |
|
54 |
/**
|
56 |
*/
|
57 |
public function valid(): bool
|
58 |
{
|
59 |
+
return $this->cur !== null;
|
60 |
}
|
61 |
|
62 |
/**
|
64 |
*/
|
65 |
public function key(): int
|
66 |
{
|
67 |
+
return $this->num;
|
68 |
}
|
69 |
|
70 |
/**
|
72 |
*/
|
73 |
public function current(): ?Frame
|
74 |
{
|
75 |
+
return $this->cur;
|
76 |
}
|
77 |
|
78 |
public function next(): void
|
79 |
{
|
80 |
+
if ($this->cur === null) {
|
|
|
81 |
return;
|
82 |
}
|
83 |
|
84 |
+
if ($this->cur->get_parent() === $this->parent) {
|
85 |
+
$this->prev = $this->cur;
|
86 |
+
$this->cur = $this->cur->get_next_sibling();
|
87 |
+
$this->num++;
|
88 |
+
} else {
|
89 |
+
// Continue from the previous child if the current frame has been
|
90 |
+
// moved to another parent
|
91 |
+
$this->cur = $this->prev !== null
|
92 |
+
? $this->prev->get_next_sibling()
|
93 |
+
: $this->parent->get_first_child();
|
94 |
+
}
|
95 |
}
|
96 |
}
|
vendor/dompdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.php
CHANGED
@@ -725,13 +725,6 @@ abstract class AbstractFrameDecorator extends Frame
|
|
725 |
$iter = $iter->get_next_sibling();
|
726 |
$frame->reset();
|
727 |
$split->append_child($frame);
|
728 |
-
|
729 |
-
// recalculate the float offsets
|
730 |
-
if ($frame instanceof Block) {
|
731 |
-
foreach ($frame->get_line_boxes() as $line_box) {
|
732 |
-
$line_box->get_float_offsets();
|
733 |
-
}
|
734 |
-
}
|
735 |
}
|
736 |
|
737 |
$this->get_parent()->split($split, $page_break, $forced);
|
725 |
$iter = $iter->get_next_sibling();
|
726 |
$frame->reset();
|
727 |
$split->append_child($frame);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
728 |
}
|
729 |
|
730 |
$this->get_parent()->split($split, $page_break, $forced);
|
vendor/dompdf/dompdf/src/FrameDecorator/Page.php
CHANGED
@@ -94,22 +94,16 @@ class Page extends AbstractFrameDecorator
|
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
-
*
|
98 |
-
*
|
99 |
-
* @param float $x
|
100 |
-
* @param float $y
|
101 |
-
* @param float $w
|
102 |
-
* @param float $h
|
103 |
*/
|
104 |
-
function
|
105 |
{
|
106 |
-
|
|
|
|
|
107 |
|
108 |
-
|
109 |
-
$style = $this->get_style();
|
110 |
-
$margin_bottom = (float) $style->length_in_pt($style->margin_bottom, $h);
|
111 |
-
$this->bottom_page_edge = $h - $margin_bottom;
|
112 |
-
}
|
113 |
}
|
114 |
|
115 |
/**
|
@@ -258,7 +252,8 @@ class Page extends AbstractFrameDecorator
|
|
258 |
$style->padding_top
|
259 |
], $cbw);
|
260 |
|
261 |
-
return $childPos
|
|
|
262 |
}
|
263 |
|
264 |
/**
|
@@ -580,7 +575,7 @@ class Page extends AbstractFrameDecorator
|
|
580 |
}
|
581 |
|
582 |
// Check if $frame flows off the page
|
583 |
-
if ($max_y
|
584 |
// no: do nothing
|
585 |
return false;
|
586 |
}
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
+
* Calculate the bottom edge of the page area after margins have been
|
98 |
+
* applied for the current page.
|
|
|
|
|
|
|
|
|
99 |
*/
|
100 |
+
public function calculate_bottom_page_edge(): void
|
101 |
{
|
102 |
+
[, , , $cbh] = $this->get_containing_block();
|
103 |
+
$style = $this->get_style();
|
104 |
+
$margin_bottom = (float) $style->length_in_pt($style->margin_bottom, $cbh);
|
105 |
|
106 |
+
$this->bottom_page_edge = $cbh - $margin_bottom;
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
|
109 |
/**
|
252 |
$style->padding_top
|
253 |
], $cbw);
|
254 |
|
255 |
+
return Helpers::lengthGreater($childPos, $contentEdge)
|
256 |
+
&& Helpers::lengthLessOrEqual($contentEdge, $this->bottom_page_edge);
|
257 |
}
|
258 |
|
259 |
/**
|
575 |
}
|
576 |
|
577 |
// Check if $frame flows off the page
|
578 |
+
if (Helpers::lengthLessOrEqual($max_y, $this->bottom_page_edge)) {
|
579 |
// no: do nothing
|
580 |
return false;
|
581 |
}
|
vendor/dompdf/dompdf/src/FrameDecorator/Table.php
CHANGED
@@ -305,6 +305,12 @@ class Table extends AbstractFrameDecorator
|
|
305 |
$tbody->append_child($child);
|
306 |
}
|
307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
foreach ($this->get_children() as $child) {
|
309 |
$display = $child->get_style()->display;
|
310 |
|
@@ -343,6 +349,12 @@ class Table extends AbstractFrameDecorator
|
|
343 |
$tr->append_child($child);
|
344 |
}
|
345 |
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
foreach ($frame->get_children() as $child) {
|
347 |
$this->normalizeRow($child);
|
348 |
}
|
@@ -376,6 +388,12 @@ class Table extends AbstractFrameDecorator
|
|
376 |
|
377 |
$td->append_child($child);
|
378 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
}
|
380 |
|
381 |
//........................................................................
|
305 |
$tbody->append_child($child);
|
306 |
}
|
307 |
|
308 |
+
// Handle empty table: Make sure there is at least one row group
|
309 |
+
if (!$this->get_first_child()) {
|
310 |
+
$tbody = $this->create_anonymous_child("tbody", "table-row-group");
|
311 |
+
$this->append_child($tbody);
|
312 |
+
}
|
313 |
+
|
314 |
foreach ($this->get_children() as $child) {
|
315 |
$display = $child->get_style()->display;
|
316 |
|
349 |
$tr->append_child($child);
|
350 |
}
|
351 |
|
352 |
+
// Handle empty row group: Make sure there is at least one row
|
353 |
+
if (!$frame->get_first_child()) {
|
354 |
+
$tr = $frame->create_anonymous_child("tr", "table-row");
|
355 |
+
$frame->append_child($tr);
|
356 |
+
}
|
357 |
+
|
358 |
foreach ($frame->get_children() as $child) {
|
359 |
$this->normalizeRow($child);
|
360 |
}
|
388 |
|
389 |
$td->append_child($child);
|
390 |
}
|
391 |
+
|
392 |
+
// Handle empty row: Make sure there is at least one cell
|
393 |
+
if (!$frame->get_first_child()) {
|
394 |
+
$td = $frame->create_anonymous_child("td", "table-cell");
|
395 |
+
$frame->append_child($td);
|
396 |
+
}
|
397 |
}
|
398 |
|
399 |
//........................................................................
|
vendor/dompdf/dompdf/src/FrameReflower/Block.php
CHANGED
@@ -860,19 +860,17 @@ class Block extends AbstractFrameReflower
|
|
860 |
|
861 |
// Set the containing blocks and reflow each child
|
862 |
foreach ($this->_frame->get_children() as $child) {
|
863 |
-
// Bail out if the page is full
|
864 |
-
if ($page->is_full()) {
|
865 |
-
break;
|
866 |
-
}
|
867 |
-
|
868 |
$child->set_containing_block($cb_x, $cb_y, $width, $height);
|
869 |
-
|
870 |
$this->process_clear($child);
|
871 |
-
|
872 |
$child->reflow($this->_frame);
|
873 |
|
|
|
|
|
|
|
874 |
// Don't add the child to the line if a page break has occurred
|
875 |
-
|
|
|
|
|
876 |
break;
|
877 |
}
|
878 |
|
860 |
|
861 |
// Set the containing blocks and reflow each child
|
862 |
foreach ($this->_frame->get_children() as $child) {
|
|
|
|
|
|
|
|
|
|
|
863 |
$child->set_containing_block($cb_x, $cb_y, $width, $height);
|
|
|
864 |
$this->process_clear($child);
|
|
|
865 |
$child->reflow($this->_frame);
|
866 |
|
867 |
+
// Check for a page break before the child
|
868 |
+
$page->check_page_break($child);
|
869 |
+
|
870 |
// Don't add the child to the line if a page break has occurred
|
871 |
+
// before it (possibly via a descendant), in which case it has been
|
872 |
+
// reset, including its position
|
873 |
+
if ($page->is_full() && $child->get_position("x") === null) {
|
874 |
break;
|
875 |
}
|
876 |
|
vendor/dompdf/dompdf/src/FrameReflower/Inline.php
CHANGED
@@ -157,12 +157,6 @@ class Inline extends AbstractFrameReflower
|
|
157 |
foreach ($frame->get_children() as $child) {
|
158 |
$child->set_containing_block($cb);
|
159 |
$child->reflow($block);
|
160 |
-
|
161 |
-
// Stop reflow of subsequent children if the frame was split within
|
162 |
-
// child reflow
|
163 |
-
if ($child->get_parent() !== $frame) {
|
164 |
-
break;
|
165 |
-
}
|
166 |
}
|
167 |
|
168 |
// Assume the position of the first child
|
157 |
foreach ($frame->get_children() as $child) {
|
158 |
$child->set_containing_block($cb);
|
159 |
$child->reflow($block);
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
}
|
161 |
|
162 |
// Assume the position of the first child
|
vendor/dompdf/dompdf/src/FrameReflower/Page.php
CHANGED
@@ -44,8 +44,8 @@ class Page extends AbstractFrameReflower
|
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
-
* @param
|
48 |
-
* @param $page_number
|
49 |
*/
|
50 |
function apply_page_style(Frame $frame, $page_number)
|
51 |
{
|
@@ -83,6 +83,8 @@ class Page extends AbstractFrameReflower
|
|
83 |
|
84 |
$frame->set_style($style);
|
85 |
}
|
|
|
|
|
86 |
}
|
87 |
|
88 |
/**
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
+
* @param PageFrameDecorator $frame
|
48 |
+
* @param int $page_number
|
49 |
*/
|
50 |
function apply_page_style(Frame $frame, $page_number)
|
51 |
{
|
83 |
|
84 |
$frame->set_style($style);
|
85 |
}
|
86 |
+
|
87 |
+
$frame->calculate_bottom_page_edge();
|
88 |
}
|
89 |
|
90 |
/**
|
vendor/dompdf/dompdf/src/FrameReflower/Table.php
CHANGED
@@ -412,17 +412,16 @@ class Table extends AbstractFrameReflower
|
|
412 |
|
413 |
// Set the containing block of each child & reflow
|
414 |
foreach ($frame->get_children() as $child) {
|
415 |
-
// Bail if the page is full
|
416 |
-
if (!$page->in_nested_table() && $page->is_full()) {
|
417 |
-
break;
|
418 |
-
}
|
419 |
-
|
420 |
$child->set_containing_block($content_x, $content_y, $width, $h);
|
421 |
$child->reflow();
|
422 |
|
423 |
if (!$page->in_nested_table()) {
|
424 |
// Check if a split has occurred
|
425 |
$page->check_page_break($child);
|
|
|
|
|
|
|
|
|
426 |
}
|
427 |
}
|
428 |
|
412 |
|
413 |
// Set the containing block of each child & reflow
|
414 |
foreach ($frame->get_children() as $child) {
|
|
|
|
|
|
|
|
|
|
|
415 |
$child->set_containing_block($content_x, $content_y, $width, $h);
|
416 |
$child->reflow();
|
417 |
|
418 |
if (!$page->in_nested_table()) {
|
419 |
// Check if a split has occurred
|
420 |
$page->check_page_break($child);
|
421 |
+
|
422 |
+
if ($page->is_full()) {
|
423 |
+
break;
|
424 |
+
}
|
425 |
}
|
426 |
}
|
427 |
|
vendor/dompdf/dompdf/src/FrameReflower/TableCell.php
CHANGED
@@ -90,14 +90,14 @@ class TableCell extends Block
|
|
90 |
|
91 |
// Set the containing blocks and reflow each child
|
92 |
foreach ($this->_frame->get_children() as $child) {
|
93 |
-
if ($page->is_full()) {
|
94 |
-
break;
|
95 |
-
}
|
96 |
-
|
97 |
$child->set_containing_block($content_x, $content_y, $cb_w, $h);
|
98 |
$this->process_clear($child);
|
99 |
$child->reflow($this->_frame);
|
100 |
-
$this->process_float($child, $
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
|
103 |
// Determine our height
|
90 |
|
91 |
// Set the containing blocks and reflow each child
|
92 |
foreach ($this->_frame->get_children() as $child) {
|
|
|
|
|
|
|
|
|
93 |
$child->set_containing_block($content_x, $content_y, $cb_w, $h);
|
94 |
$this->process_clear($child);
|
95 |
$child->reflow($this->_frame);
|
96 |
+
$this->process_float($child, $content_x, $cb_w);
|
97 |
+
|
98 |
+
if ($page->is_full()) {
|
99 |
+
break;
|
100 |
+
}
|
101 |
}
|
102 |
|
103 |
// Determine our height
|
vendor/dompdf/dompdf/src/FrameReflower/TableRow.php
CHANGED
@@ -53,12 +53,12 @@ class TableRow extends AbstractFrameReflower
|
|
53 |
$cb = $this->_frame->get_containing_block();
|
54 |
|
55 |
foreach ($this->_frame->get_children() as $child) {
|
56 |
-
if ($page->is_full()) {
|
57 |
-
return;
|
58 |
-
}
|
59 |
-
|
60 |
$child->set_containing_block($cb);
|
61 |
$child->reflow();
|
|
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
if ($page->is_full()) {
|
53 |
$cb = $this->_frame->get_containing_block();
|
54 |
|
55 |
foreach ($this->_frame->get_children() as $child) {
|
|
|
|
|
|
|
|
|
56 |
$child->set_containing_block($cb);
|
57 |
$child->reflow();
|
58 |
+
|
59 |
+
if ($page->is_full()) {
|
60 |
+
break;
|
61 |
+
}
|
62 |
}
|
63 |
|
64 |
if ($page->is_full()) {
|
vendor/dompdf/dompdf/src/FrameReflower/TableRowGroup.php
CHANGED
@@ -44,16 +44,15 @@ class TableRowGroup extends AbstractFrameReflower
|
|
44 |
$cb = $frame->get_containing_block();
|
45 |
|
46 |
foreach ($frame->get_children() as $child) {
|
47 |
-
// Bail if the page is full
|
48 |
-
if ($page->is_full()) {
|
49 |
-
break;
|
50 |
-
}
|
51 |
-
|
52 |
$child->set_containing_block($cb["x"], $cb["y"], $cb["w"], $cb["h"]);
|
53 |
$child->reflow();
|
54 |
|
55 |
// Check if a split has occurred
|
56 |
$page->check_page_break($child);
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
|
59 |
$table = TableFrameDecorator::find_parent_table($frame);
|
44 |
$cb = $frame->get_containing_block();
|
45 |
|
46 |
foreach ($frame->get_children() as $child) {
|
|
|
|
|
|
|
|
|
|
|
47 |
$child->set_containing_block($cb["x"], $cb["y"], $cb["w"], $cb["h"]);
|
48 |
$child->reflow();
|
49 |
|
50 |
// Check if a split has occurred
|
51 |
$page->check_page_break($child);
|
52 |
+
|
53 |
+
if ($page->is_full()) {
|
54 |
+
break;
|
55 |
+
}
|
56 |
}
|
57 |
|
58 |
$table = TableFrameDecorator::find_parent_table($frame);
|
vendor/dompdf/dompdf/src/FrameReflower/Text.php
CHANGED
@@ -158,7 +158,7 @@ class Text extends AbstractFrameReflower
|
|
158 |
], $line_width);
|
159 |
$frame_width = $text_width + $mbp_width;
|
160 |
|
161 |
-
if ($frame_width
|
162 |
return false;
|
163 |
}
|
164 |
|
@@ -181,8 +181,9 @@ class Text extends AbstractFrameReflower
|
|
181 |
$sep = $words[$i + 1] ?? "";
|
182 |
$word = $sep === " " ? $words[$i] : $words[$i] . $sep;
|
183 |
$word_width = $fontMetrics->getTextWidth($word, $font, $size, $word_spacing, $char_spacing);
|
|
|
184 |
|
185 |
-
if ($
|
186 |
// If the previous split happened by soft hyphen, we have to
|
187 |
// append its width again because the last hyphen of a line
|
188 |
// won't be removed
|
@@ -225,7 +226,7 @@ class Text extends AbstractFrameReflower
|
|
225 |
$c = mb_substr($word, $j, 1);
|
226 |
$w = $fontMetrics->getTextWidth($s . $c, $font, $size, $word_spacing, $char_spacing);
|
227 |
|
228 |
-
if ($w
|
229 |
break;
|
230 |
}
|
231 |
|
158 |
], $line_width);
|
159 |
$frame_width = $text_width + $mbp_width;
|
160 |
|
161 |
+
if (Helpers::lengthLessOrEqual($frame_width, $available_width)) {
|
162 |
return false;
|
163 |
}
|
164 |
|
181 |
$sep = $words[$i + 1] ?? "";
|
182 |
$word = $sep === " " ? $words[$i] : $words[$i] . $sep;
|
183 |
$word_width = $fontMetrics->getTextWidth($word, $font, $size, $word_spacing, $char_spacing);
|
184 |
+
$used_width = $width + $word_width + $mbp_width;
|
185 |
|
186 |
+
if (Helpers::lengthGreater($used_width, $available_width)) {
|
187 |
// If the previous split happened by soft hyphen, we have to
|
188 |
// append its width again because the last hyphen of a line
|
189 |
// won't be removed
|
226 |
$c = mb_substr($word, $j, 1);
|
227 |
$w = $fontMetrics->getTextWidth($s . $c, $font, $size, $word_spacing, $char_spacing);
|
228 |
|
229 |
+
if (Helpers::lengthGreater($w, $available_width)) {
|
230 |
break;
|
231 |
}
|
232 |
|
vendor/dompdf/dompdf/src/Helpers.php
CHANGED
@@ -962,4 +962,67 @@ class Helpers
|
|
962 |
|
963 |
return $str;
|
964 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
965 |
}
|
962 |
|
963 |
return $str;
|
964 |
}
|
965 |
+
|
966 |
+
/**
|
967 |
+
* Check whether two lengths should be considered equal, accounting for
|
968 |
+
* inaccuracies in float computation.
|
969 |
+
*
|
970 |
+
* The implementation relies on the fact that we are neither dealing with
|
971 |
+
* very large, nor with very small numbers in layout. Adapted from
|
972 |
+
* https://floating-point-gui.de/errors/comparison/.
|
973 |
+
*
|
974 |
+
* @param float $a
|
975 |
+
* @param float $b
|
976 |
+
*
|
977 |
+
* @return bool
|
978 |
+
*/
|
979 |
+
public static function lengthEqual(float $a, float $b): bool
|
980 |
+
{
|
981 |
+
// The epsilon results in a precision of at least:
|
982 |
+
// * 7 decimal digits at around 1
|
983 |
+
// * 4 decimal digits at around 1000 (around the size of common paper formats)
|
984 |
+
// * 2 decimal digits at around 100,000 (100,000pt ~ 35.28m)
|
985 |
+
static $epsilon = 1e-8;
|
986 |
+
static $almostZero = 1e-12;
|
987 |
+
|
988 |
+
$diff = abs($a - $b);
|
989 |
+
|
990 |
+
if ($a === $b || $diff < $almostZero) {
|
991 |
+
return true;
|
992 |
+
}
|
993 |
+
|
994 |
+
return $diff < $epsilon * max(abs($a), abs($b));
|
995 |
+
}
|
996 |
+
|
997 |
+
/**
|
998 |
+
* Check `$a < $b`, accounting for inaccuracies in float computation.
|
999 |
+
*/
|
1000 |
+
public static function lengthLess(float $a, float $b): bool
|
1001 |
+
{
|
1002 |
+
return $a < $b && !self::lengthEqual($a, $b);
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
/**
|
1006 |
+
* Check `$a <= $b`, accounting for inaccuracies in float computation.
|
1007 |
+
*/
|
1008 |
+
public static function lengthLessOrEqual(float $a, float $b): bool
|
1009 |
+
{
|
1010 |
+
return $a <= $b || self::lengthEqual($a, $b);
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
/**
|
1014 |
+
* Check `$a > $b`, accounting for inaccuracies in float computation.
|
1015 |
+
*/
|
1016 |
+
public static function lengthGreater(float $a, float $b): bool
|
1017 |
+
{
|
1018 |
+
return $a > $b && !self::lengthEqual($a, $b);
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
/**
|
1022 |
+
* Check `$a >= $b`, accounting for inaccuracies in float computation.
|
1023 |
+
*/
|
1024 |
+
public static function lengthGreaterOrEqual(float $a, float $b): bool
|
1025 |
+
{
|
1026 |
+
return $a >= $b || self::lengthEqual($a, $b);
|
1027 |
+
}
|
1028 |
}
|
vendor/dompdf/dompdf/src/Positioner/Inline.php
CHANGED
@@ -11,6 +11,7 @@ namespace Dompdf\Positioner;
|
|
11 |
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
12 |
use Dompdf\FrameDecorator\Inline as InlineFrameDecorator;
|
13 |
use Dompdf\Exception;
|
|
|
14 |
|
15 |
/**
|
16 |
* Positions inline frames
|
@@ -40,8 +41,9 @@ class Inline extends AbstractPositioner
|
|
40 |
// Atomic inline boxes and replaced inline elements
|
41 |
// (inline-block, inline-table, img etc.)
|
42 |
$width = $frame->get_margin_width();
|
|
|
43 |
|
44 |
-
if ($width
|
45 |
$block->add_line();
|
46 |
$line = $block->get_current_line_box();
|
47 |
}
|
11 |
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
12 |
use Dompdf\FrameDecorator\Inline as InlineFrameDecorator;
|
13 |
use Dompdf\Exception;
|
14 |
+
use Dompdf\Helpers;
|
15 |
|
16 |
/**
|
17 |
* Positions inline frames
|
41 |
// Atomic inline boxes and replaced inline elements
|
42 |
// (inline-block, inline-table, img etc.)
|
43 |
$width = $frame->get_margin_width();
|
44 |
+
$available_width = $cb["w"] - $line->left - $line->w - $line->right;
|
45 |
|
46 |
+
if (Helpers::lengthGreater($width, $available_width)) {
|
47 |
$block->add_line();
|
48 |
$line = $block->get_current_line_box();
|
49 |
}
|
vendor/dompdf/dompdf/src/Renderer/AbstractRenderer.php
CHANGED
@@ -278,23 +278,23 @@ abstract class AbstractRenderer
|
|
278 |
$cpdfFromGd = false;
|
279 |
imagesavealpha($bg, true);
|
280 |
imagealphablending($bg, false);
|
281 |
-
$src = imagecreatefrompng($img);
|
282 |
break;
|
283 |
|
284 |
case "jpeg":
|
285 |
-
$src = imagecreatefromjpeg($img);
|
286 |
break;
|
287 |
|
288 |
case "webp":
|
289 |
-
$src = imagecreatefromwebp($img);
|
290 |
break;
|
291 |
|
292 |
case "gif":
|
293 |
-
$src = imagecreatefromgif($img);
|
294 |
break;
|
295 |
|
296 |
case "bmp":
|
297 |
-
$src = Helpers::imagecreatefrombmp($img);
|
298 |
break;
|
299 |
|
300 |
default:
|
278 |
$cpdfFromGd = false;
|
279 |
imagesavealpha($bg, true);
|
280 |
imagealphablending($bg, false);
|
281 |
+
$src = @imagecreatefrompng($img);
|
282 |
break;
|
283 |
|
284 |
case "jpeg":
|
285 |
+
$src = @imagecreatefromjpeg($img);
|
286 |
break;
|
287 |
|
288 |
case "webp":
|
289 |
+
$src = @imagecreatefromwebp($img);
|
290 |
break;
|
291 |
|
292 |
case "gif":
|
293 |
+
$src = @imagecreatefromgif($img);
|
294 |
break;
|
295 |
|
296 |
case "bmp":
|
297 |
+
$src = @Helpers::imagecreatefrombmp($img);
|
298 |
break;
|
299 |
|
300 |
default:
|
woocommerce-pdf-invoices-packingslips.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
-
* Version: 2.
|
7 |
* Author: WP Overnight
|
8 |
* Author URI: https://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
@@ -21,7 +21,7 @@ if ( !class_exists( 'WPO_WCPDF' ) ) :
|
|
21 |
|
22 |
class WPO_WCPDF {
|
23 |
|
24 |
-
public $version = '2.
|
25 |
public $plugin_basename;
|
26 |
public $legacy_mode;
|
27 |
public $legacy_textdomain;
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
+
* Version: 2.13.0
|
7 |
* Author: WP Overnight
|
8 |
* Author URI: https://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
21 |
|
22 |
class WPO_WCPDF {
|
23 |
|
24 |
+
public $version = '2.13.0';
|
25 |
public $plugin_basename;
|
26 |
public $legacy_mode;
|
27 |
public $legacy_textdomain;
|