Version Description
- Fix: Possible conflict with latest Subscriptions
- Fix: Load correct translations when admin user profile language is set to different locale
- Fix: Use file lock to prevent parallel processes creating the same attachment file
- Fix: Prevent notices for incorrectly loaded email classes
- Feature: Allow different invoice number column sorting methods by filter
- Feature: Filter for global prevention of creating specific document (
wpo_wcpdf_document_is_allowed
)
Download this release
Release Info
Developer | pomegranate |
Plugin | WooCommerce PDF Invoices & Packing Slips |
Version | 2.2.10 |
Comparing to | |
See all releases |
Code changes from version 2.2.9 to 2.2.10
includes/class-wcpdf-admin.php
CHANGED
@@ -169,13 +169,14 @@ class Admin {
|
|
169 |
$listing_actions = array();
|
170 |
$documents = WPO_WCPDF()->documents->get_documents();
|
171 |
foreach ($documents as $document) {
|
172 |
-
$document->
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
179 |
}
|
180 |
|
181 |
$listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );
|
@@ -272,6 +273,12 @@ class Admin {
|
|
272 |
* Resend order emails
|
273 |
*/
|
274 |
public function send_order_email_meta_box( $post ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
?>
|
276 |
<ul class="wpo_wcpdf_send_emails submitbox">
|
277 |
<li class="wide" id="actions">
|
@@ -313,13 +320,14 @@ class Admin {
|
|
313 |
$documents = WPO_WCPDF()->documents->get_documents();
|
314 |
$order = WCX::get_order( $post->ID );
|
315 |
foreach ($documents as $document) {
|
316 |
-
$document->
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
|
|
323 |
}
|
324 |
|
325 |
$meta_box_actions = apply_filters( 'wpo_wcpdf_meta_box_actions', $meta_box_actions, $post_id );
|
@@ -548,8 +556,8 @@ class Admin {
|
|
548 |
}
|
549 |
$orderby = $query->get( 'orderby');
|
550 |
if( 'pdf_invoice_number' == $orderby ) {
|
551 |
-
$query->set('meta_key','_wcpdf_invoice_number');
|
552 |
-
$query->set('orderby','meta_value');
|
553 |
}
|
554 |
}
|
555 |
|
@@ -564,7 +572,7 @@ class Admin {
|
|
564 |
if ( 'pdf_invoice_number' === $query_vars['orderby'] ) {
|
565 |
$query_vars = array_merge( $query_vars, array(
|
566 |
'meta_key' => '_wcpdf_invoice_number',
|
567 |
-
'orderby' => 'meta_value',
|
568 |
) );
|
569 |
}
|
570 |
}
|
169 |
$listing_actions = array();
|
170 |
$documents = WPO_WCPDF()->documents->get_documents();
|
171 |
foreach ($documents as $document) {
|
172 |
+
if ( $document = wcpdf_get_document( $document->get_type(), $order ) ) {
|
173 |
+
$listing_actions[$document->get_type()] = array(
|
174 |
+
'url' => wp_nonce_url( admin_url( "admin-ajax.php?action=generate_wpo_wcpdf&document_type={$document->get_type()}&order_ids=" . WCX_Order::get_id( $order ) ), 'generate_wpo_wcpdf' ),
|
175 |
+
'img' => !empty($document->icon) ? $document->icon : WPO_WCPDF()->plugin_url() . "/assets/images/generic_document.png",
|
176 |
+
'alt' => "PDF " . $document->get_title(),
|
177 |
+
'exists' => $document->exists(),
|
178 |
+
);
|
179 |
+
}
|
180 |
}
|
181 |
|
182 |
$listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );
|
273 |
* Resend order emails
|
274 |
*/
|
275 |
public function send_order_email_meta_box( $post ) {
|
276 |
+
global $theorder;
|
277 |
+
// This is used by some callbacks attached to hooks such as woocommerce_resend_order_emails_available
|
278 |
+
// which rely on the global to determine if emails should be displayed for certain orders.
|
279 |
+
if ( ! is_object( $theorder ) ) {
|
280 |
+
$theorder = wc_get_order( $post->ID );
|
281 |
+
}
|
282 |
?>
|
283 |
<ul class="wpo_wcpdf_send_emails submitbox">
|
284 |
<li class="wide" id="actions">
|
320 |
$documents = WPO_WCPDF()->documents->get_documents();
|
321 |
$order = WCX::get_order( $post->ID );
|
322 |
foreach ($documents as $document) {
|
323 |
+
if ( $document = wcpdf_get_document( $document->get_type(), $order ) ) {
|
324 |
+
$meta_box_actions[$document->get_type()] = array(
|
325 |
+
'url' => wp_nonce_url( admin_url( "admin-ajax.php?action=generate_wpo_wcpdf&document_type={$document->get_type()}&order_ids=" . $post_id ), 'generate_wpo_wcpdf' ),
|
326 |
+
'alt' => esc_attr( "PDF " . $document->get_title() ),
|
327 |
+
'title' => "PDF " . $document->get_title(),
|
328 |
+
'exists' => $document->exists(),
|
329 |
+
);
|
330 |
+
}
|
331 |
}
|
332 |
|
333 |
$meta_box_actions = apply_filters( 'wpo_wcpdf_meta_box_actions', $meta_box_actions, $post_id );
|
556 |
}
|
557 |
$orderby = $query->get( 'orderby');
|
558 |
if( 'pdf_invoice_number' == $orderby ) {
|
559 |
+
$query->set( 'meta_key', '_wcpdf_invoice_number' );
|
560 |
+
$query->set( 'orderby', apply_filters( 'wpo_wcpdf_invoice_number_column_orderby', 'meta_value' ) );
|
561 |
}
|
562 |
}
|
563 |
|
572 |
if ( 'pdf_invoice_number' === $query_vars['orderby'] ) {
|
573 |
$query_vars = array_merge( $query_vars, array(
|
574 |
'meta_key' => '_wcpdf_invoice_number',
|
575 |
+
'orderby' => apply_filters( 'wpo_wcpdf_invoice_number_column_orderby', 'meta_value' ),
|
576 |
) );
|
577 |
}
|
578 |
}
|
includes/class-wcpdf-main.php
CHANGED
@@ -89,6 +89,7 @@ class Main {
|
|
89 |
|
90 |
// reload translations because WC may have switched to site locale (by setting the plugin_locale filter to site locale in wc_switch_to_site_locale())
|
91 |
WPO_WCPDF()->translations();
|
|
|
92 |
|
93 |
$attach_to_document_types = $this->get_documents_for_email( $email_id, $order );
|
94 |
foreach ( $attach_to_document_types as $document_type ) {
|
@@ -109,15 +110,32 @@ class Main {
|
|
109 |
if ($filemtime = filemtime($pdf_path)) {
|
110 |
$time_difference = time() - $filemtime;
|
111 |
if ( $time_difference < apply_filters( 'wpo_wcpdf_reuse_attachment_age', 60 ) ) {
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
}
|
116 |
}
|
117 |
|
118 |
// get pdf data & store
|
119 |
$pdf_data = $document->get_pdf();
|
120 |
-
file_put_contents ( $pdf_path, $pdf_data );
|
121 |
$attachments[] = $pdf_path;
|
122 |
|
123 |
do_action( 'wpo_wcpdf_email_attachment', $pdf_path, $document_type, $document );
|
@@ -138,6 +156,18 @@ class Main {
|
|
138 |
return $attachments;
|
139 |
}
|
140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
public function get_documents_for_email( $email_id, $order ) {
|
142 |
$documents = WPO_WCPDF()->documents->get_documents();
|
143 |
|
89 |
|
90 |
// reload translations because WC may have switched to site locale (by setting the plugin_locale filter to site locale in wc_switch_to_site_locale())
|
91 |
WPO_WCPDF()->translations();
|
92 |
+
do_action( 'wpo_wcpdf_reload_attachment_translations' );
|
93 |
|
94 |
$attach_to_document_types = $this->get_documents_for_email( $email_id, $order );
|
95 |
foreach ( $attach_to_document_types as $document_type ) {
|
110 |
if ($filemtime = filemtime($pdf_path)) {
|
111 |
$time_difference = time() - $filemtime;
|
112 |
if ( $time_difference < apply_filters( 'wpo_wcpdf_reuse_attachment_age', 60 ) ) {
|
113 |
+
// check if file is still being written to
|
114 |
+
$fp = fopen($pdf_path, 'r+');
|
115 |
+
if ( $locked = $this->file_is_locked( $fp ) ) {
|
116 |
+
// optional delay (ms) to double check if the write process is finished
|
117 |
+
$delay = intval( apply_filters( 'wpo_wcpdf_attachment_locked_file_delay', 250 ) );
|
118 |
+
if ( $delay > 0 ) {
|
119 |
+
usleep( $delay * 1000 );
|
120 |
+
$locked = $this->file_is_locked( $fp );
|
121 |
+
}
|
122 |
+
}
|
123 |
+
fclose($fp);
|
124 |
+
|
125 |
+
if ( !$locked ) {
|
126 |
+
$attachments[] = $pdf_path;
|
127 |
+
continue;
|
128 |
+
} else {
|
129 |
+
// make sure this gets logged
|
130 |
+
throw new \Exception("Failed attachment, file locked");
|
131 |
+
}
|
132 |
}
|
133 |
}
|
134 |
}
|
135 |
|
136 |
// get pdf data & store
|
137 |
$pdf_data = $document->get_pdf();
|
138 |
+
file_put_contents ( $pdf_path, $pdf_data, LOCK_EX );
|
139 |
$attachments[] = $pdf_path;
|
140 |
|
141 |
do_action( 'wpo_wcpdf_email_attachment', $pdf_path, $document_type, $document );
|
156 |
return $attachments;
|
157 |
}
|
158 |
|
159 |
+
public function file_is_locked( $fp ) {
|
160 |
+
if (!flock($fp, LOCK_EX|LOCK_NB, $wouldblock)) {
|
161 |
+
if ($wouldblock) {
|
162 |
+
return true; // file is locked
|
163 |
+
} else {
|
164 |
+
return true; // can't lock for whatever reason (could be locked in Windows + PHP5.3)
|
165 |
+
}
|
166 |
+
} else {
|
167 |
+
return false; // not locked
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
public function get_documents_for_email( $email_id, $order ) {
|
172 |
$documents = WPO_WCPDF()->documents->get_documents();
|
173 |
|
includes/documents/abstract-wcpdf-order-document.php
CHANGED
@@ -278,6 +278,10 @@ abstract class Order_Document {
|
|
278 |
do_action( 'wpo_wcpdf_delete_document', $this );
|
279 |
}
|
280 |
|
|
|
|
|
|
|
|
|
281 |
public function exists() {
|
282 |
return !empty( $this->data['date'] );
|
283 |
}
|
@@ -724,6 +728,9 @@ abstract class Order_Document {
|
|
724 |
|
725 |
$emails = array();
|
726 |
foreach ($wc_emails as $class => $email) {
|
|
|
|
|
|
|
727 |
if ( !in_array( $email->id, $non_order_emails ) ) {
|
728 |
switch ($email->id) {
|
729 |
case 'new_order':
|
278 |
do_action( 'wpo_wcpdf_delete_document', $this );
|
279 |
}
|
280 |
|
281 |
+
public function is_allowed() {
|
282 |
+
return apply_filters( 'wpo_wcpdf_document_is_allowed', true, $this );
|
283 |
+
}
|
284 |
+
|
285 |
public function exists() {
|
286 |
return !empty( $this->data['date'] );
|
287 |
}
|
728 |
|
729 |
$emails = array();
|
730 |
foreach ($wc_emails as $class => $email) {
|
731 |
+
if ( !is_object( $email ) ) {
|
732 |
+
continue;
|
733 |
+
}
|
734 |
if ( !in_array( $email->id, $non_order_emails ) ) {
|
735 |
switch ($email->id) {
|
736 |
case 'new_order':
|
includes/documents/class-wcpdf-bulk-document.php
CHANGED
@@ -75,8 +75,9 @@ class Bulk_Document {
|
|
75 |
|
76 |
$order = WCX::get_order( $order_id );
|
77 |
|
78 |
-
$document = wcpdf_get_document( $this->get_type(), $order, true )
|
79 |
-
|
|
|
80 |
}
|
81 |
|
82 |
// get wrapper document & insert body content
|
75 |
|
76 |
$order = WCX::get_order( $order_id );
|
77 |
|
78 |
+
if ( $document = wcpdf_get_document( $this->get_type(), $order, true ) ) {
|
79 |
+
$html_content[ $key ] = $document->get_html( array( 'wrap_html_content' => false ) );
|
80 |
+
}
|
81 |
}
|
82 |
|
83 |
// get wrapper document & insert body content
|
includes/wcpdf-functions.php
CHANGED
@@ -46,11 +46,14 @@ function wcpdf_get_document( $document_type, $order, $init = false ) {
|
|
46 |
do_action( 'wpo_wcpdf_process_template_order', $document_type, WCX_Order::get_id( $order ) );
|
47 |
$document = WPO_WCPDF()->documents->get_document( $document_type, $order );
|
48 |
|
|
|
|
|
|
|
|
|
49 |
if ( $init && !$document->exists() ) {
|
50 |
$document->init();
|
51 |
$document->save();
|
52 |
}
|
53 |
-
// $document->read_data( $order ); // isn't data already read from construct?
|
54 |
return $document;
|
55 |
} else {
|
56 |
// order ids array changed, continue processing that array
|
@@ -74,6 +77,11 @@ function wcpdf_get_document( $document_type, $order, $init = false ) {
|
|
74 |
$order = WCX::get_order( $order_id );
|
75 |
|
76 |
$document = WPO_WCPDF()->documents->get_document( $document_type, $order );
|
|
|
|
|
|
|
|
|
|
|
77 |
if ( $init && !$document->exists() ) {
|
78 |
$document->init();
|
79 |
$document->save();
|
46 |
do_action( 'wpo_wcpdf_process_template_order', $document_type, WCX_Order::get_id( $order ) );
|
47 |
$document = WPO_WCPDF()->documents->get_document( $document_type, $order );
|
48 |
|
49 |
+
if ( !$document->is_allowed() ) {
|
50 |
+
return false;
|
51 |
+
}
|
52 |
+
|
53 |
if ( $init && !$document->exists() ) {
|
54 |
$document->init();
|
55 |
$document->save();
|
56 |
}
|
|
|
57 |
return $document;
|
58 |
} else {
|
59 |
// order ids array changed, continue processing that array
|
77 |
$order = WCX::get_order( $order_id );
|
78 |
|
79 |
$document = WPO_WCPDF()->documents->get_document( $document_type, $order );
|
80 |
+
|
81 |
+
if ( !$document->is_allowed() ) {
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
|
85 |
if ( $init && !$document->exists() ) {
|
86 |
$document->init();
|
87 |
$document->save();
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice,
|
|
5 |
Requires at least: 3.5
|
6 |
Tested up to: 5.1
|
7 |
Requires PHP: 5.3
|
8 |
-
Stable tag: 2.2.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -103,6 +103,14 @@ There's a setting on the Status tab of the settings page that allows you to togg
|
|
103 |
|
104 |
== Changelog ==
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
= 2.2.9 =
|
107 |
* Feature: Added customer note email to attachment options
|
108 |
* Fix: Prevent empty invoice dates from being saved as 1970 (fallback to current date/time)
|
5 |
Requires at least: 3.5
|
6 |
Tested up to: 5.1
|
7 |
Requires PHP: 5.3
|
8 |
+
Stable tag: 2.2.10
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
103 |
|
104 |
== Changelog ==
|
105 |
|
106 |
+
= 2.2.10 =
|
107 |
+
* Fix: Possible conflict with latest Subscriptions
|
108 |
+
* Fix: Load correct translations when admin user profile language is set to different locale
|
109 |
+
* Fix: Use file lock to prevent parallel processes creating the same attachment file
|
110 |
+
* Fix: Prevent notices for incorrectly loaded email classes
|
111 |
+
* Feature: Allow different invoice number column sorting methods by filter
|
112 |
+
* Feature: Filter for global prevention of creating specific document (`wpo_wcpdf_document_is_allowed`)
|
113 |
+
|
114 |
= 2.2.9 =
|
115 |
* Feature: Added customer note email to attachment options
|
116 |
* Fix: Prevent empty invoice dates from being saved as 1970 (fallback to current date/time)
|
woocommerce-pdf-invoices-packingslips.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: http://www.wpovernight.com
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
-
* Version: 2.2.
|
7 |
* Author: Ewout Fernhout
|
8 |
* Author URI: http://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.2.
|
25 |
public $plugin_basename;
|
26 |
public $legacy_mode;
|
27 |
|
@@ -72,7 +72,8 @@ class WPO_WCPDF {
|
|
72 |
* Note: the first-loaded translation file overrides any following ones if the same translation is present
|
73 |
*/
|
74 |
public function translations() {
|
75 |
-
$locale =
|
|
|
76 |
$dir = trailingslashit( WP_LANG_DIR );
|
77 |
|
78 |
$textdomains = array( 'woocommerce-pdf-invoices-packing-slips' );
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: http://www.wpovernight.com
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
+
* Version: 2.2.10
|
7 |
* Author: Ewout Fernhout
|
8 |
* Author URI: http://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
21 |
|
22 |
class WPO_WCPDF {
|
23 |
|
24 |
+
public $version = '2.2.10';
|
25 |
public $plugin_basename;
|
26 |
public $legacy_mode;
|
27 |
|
72 |
* Note: the first-loaded translation file overrides any following ones if the same translation is present
|
73 |
*/
|
74 |
public function translations() {
|
75 |
+
$locale = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
|
76 |
+
$locale = apply_filters( 'plugin_locale', $locale, 'woocommerce-pdf-invoices-packing-slips' );
|
77 |
$dir = trailingslashit( WP_LANG_DIR );
|
78 |
|
79 |
$textdomains = array( 'woocommerce-pdf-invoices-packing-slips' );
|