/includes/class-wcpdf-writepanels.php

  1. <?php 
  2. use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX; 
  3. use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order; 
  4. use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product; 
  5.  
  6. defined( 'ABSPATH' ) or exit; 
  7.  
  8. /** 
  9. * Writepanel class 
  10. */ 
  11. if ( !class_exists( 'WooCommerce_PDF_Invoices_Writepanels' ) ) { 
  12.  
  13. class WooCommerce_PDF_Invoices_Writepanels { 
  14. public $bulk_actions; 
  15.  
  16. /** 
  17. * Constructor 
  18. */ 
  19. public function __construct() { 
  20. $this->general_settings = get_option('wpo_wcpdf_general_settings'); 
  21. $this->template_settings = get_option('wpo_wcpdf_template_settings'); 
  22.  
  23. add_action( 'woocommerce_admin_order_actions_end', array( $this, 'add_listing_actions' ) ); 
  24. add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_invoice_number_column' ), 999 ); 
  25. add_action( 'manage_shop_order_posts_custom_column', array( $this, 'invoice_number_column_data' ), 2 ); 
  26. add_action( 'add_meta_boxes_shop_order', array( $this, 'add_meta_boxes' ) ); 
  27. add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'my_account_pdf_link' ), 10, 2 ); 
  28. add_action( 'admin_print_scripts', array( $this, 'add_scripts' ) ); 
  29. add_action( 'admin_print_styles', array( $this, 'add_styles' ) ); 
  30. add_action( 'admin_footer', array( $this, 'bulk_actions' ) ); 
  31.  
  32. add_action( 'save_post', array( $this, 'save_invoice_number_date' ) ); 
  33.  
  34. add_filter( 'woocommerce_shop_order_search_fields', array( $this, 'search_fields' ) ); 
  35.  
  36. $this->bulk_actions = array( 
  37. 'invoice' => __( 'PDF Invoices', 'wpo_wcpdf' ),  
  38. 'packing-slip' => __( 'PDF Packing Slips', 'wpo_wcpdf' ),  
  39. ); 
  40.  
  41. /** 
  42. * Add the styles 
  43. */ 
  44. public function add_styles() { 
  45. if( $this->is_order_edit_page() ) { 
  46. wp_enqueue_style( 'thickbox' ); 
  47.  
  48. wp_enqueue_style( 
  49. 'wpo-wcpdf',  
  50. WooCommerce_PDF_Invoices::$plugin_url . 'css/style.css',  
  51. array(),  
  52. WooCommerce_PDF_Invoices::$version 
  53. ); 
  54.  
  55. if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) { 
  56. // WC 2.1 or newer (MP6) is used: bigger buttons 
  57. wp_enqueue_style( 
  58. 'wpo-wcpdf-buttons',  
  59. WooCommerce_PDF_Invoices::$plugin_url . 'css/style-buttons.css',  
  60. array(),  
  61. WooCommerce_PDF_Invoices::$version 
  62. ); 
  63. } else { 
  64. // legacy WC 2.0 styles 
  65. wp_enqueue_style( 
  66. 'wpo-wcpdf-buttons',  
  67. WooCommerce_PDF_Invoices::$plugin_url . 'css/style-buttons-wc20.css',  
  68. array(),  
  69. WooCommerce_PDF_Invoices::$version 
  70. ); 
  71.  
  72. /** 
  73. * Add the scripts 
  74. */ 
  75. public function add_scripts() { 
  76. if( $this->is_order_edit_page() ) { 
  77. wp_enqueue_script( 
  78. 'wpo-wcpdf',  
  79. WooCommerce_PDF_Invoices::$plugin_url . 'js/script.js',  
  80. array( 'jquery' ),  
  81. WooCommerce_PDF_Invoices::$version 
  82. ); 
  83. wp_localize_script(  
  84. 'wpo-wcpdf',  
  85. 'wpo_wcpdf_ajax',  
  86. array( 
  87. // 'ajaxurl' => add_query_arg( 'action', 'generate_wpo_wcpdf', admin_url( 'admin-ajax.php' ) ), // URL to WordPress ajax handling page  
  88. 'ajaxurl' => admin_url( 'admin-ajax.php' ), // URL to WordPress ajax handling page  
  89. 'nonce' => wp_create_nonce('generate_wpo_wcpdf'),  
  90. 'bulk_actions' => array_keys( apply_filters( 'wpo_wcpdf_bulk_actions', $this->bulk_actions ) ),  
  91. )  
  92. );  
  93. }  
  94.  
  95. /** 
  96. * Is order page 
  97. */ 
  98. public function is_order_edit_page() { 
  99. global $post_type; 
  100. if( $post_type == 'shop_order' ) { 
  101. return true;  
  102. } else { 
  103. return false; 
  104. }  
  105.  
  106. /** 
  107. * Add PDF actions to the orders listing 
  108. */ 
  109. public function add_listing_actions( $order ) { 
  110. // do not show buttons for trashed orders 
  111. if ( WCX_Order::get_status( $order ) == 'trash' ) { 
  112. return; 
  113.  
  114. $listing_actions = array( 
  115. 'invoice' => array ( 
  116. 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . WCX_Order::get_id( $order ) ), 'generate_wpo_wcpdf' ),  
  117. 'img' => WooCommerce_PDF_Invoices::$plugin_url . 'images/invoice.png',  
  118. 'alt' => __( 'PDF Invoice', 'wpo_wcpdf' ),  
  119. ),  
  120. 'packing-slip' => array ( 
  121. 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=packing-slip&order_ids=' . WCX_Order::get_id( $order ) ), 'generate_wpo_wcpdf' ),  
  122. 'img' => WooCommerce_PDF_Invoices::$plugin_url . 'images/packing-slip.png',  
  123. 'alt' => __( 'PDF Packing Slip', 'wpo_wcpdf' ),  
  124. ),  
  125. ); 
  126.  
  127. $listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );  
  128.  
  129. foreach ($listing_actions as $action => $data) { 
  130. ?> 
  131. <a href="<?php echo $data['url']; ?>" class="button tips wpo_wcpdf <?php echo $action; ?>" target="_blank" alt="<?php echo $data['alt']; ?>" data-tip="<?php echo $data['alt']; ?>"> 
  132. <img src="<?php echo $data['img']; ?>" alt="<?php echo $data['alt']; ?>" width="16"> 
  133. </a> 
  134. <?php 
  135.  
  136. /** 
  137. * Create additional Shop Order column for Invoice Numbers 
  138. * @param array $columns shop order columns 
  139. */ 
  140. public function add_invoice_number_column( $columns ) { 
  141. // Check user setting 
  142. if ( !isset($this->general_settings['invoice_number_column'] ) ) { 
  143. return $columns; 
  144.  
  145. // put the column after the Status column 
  146. $new_columns = array_slice($columns, 0, 2, true) + 
  147. array( 'pdf_invoice_number' => __( 'Invoice Number', 'wpo_wcpdf' ) ) + 
  148. array_slice($columns, 2, count($columns) - 1, true) ; 
  149. return $new_columns; 
  150.  
  151. /** 
  152. * Display Invoice Number in Shop Order column (if available) 
  153. * @param string $column column slug 
  154. */ 
  155. public function invoice_number_column_data( $column ) { 
  156. global $post, $the_order, $wpo_wcpdf; 
  157.  
  158. if ( $column == 'pdf_invoice_number' ) { 
  159. if ( empty( $the_order ) || WCX_Order::get_id( $the_order ) != $post->ID ) { 
  160. $order = WCX::get_order( $post->ID ); 
  161. echo $wpo_wcpdf->export->get_invoice_number( WCX_Order::get_id( $order ) ); 
  162. do_action( 'wcpdf_invoice_number_column_end', $order ); 
  163. } else { 
  164. echo $wpo_wcpdf->export->get_invoice_number( WCX_Order::get_id( $the_order ) ); 
  165. do_action( 'wcpdf_invoice_number_column_end', $the_order ); 
  166.  
  167. /** 
  168. * Display download link on My Account page 
  169. */ 
  170. public function my_account_pdf_link( $actions, $order ) { 
  171. $pdf_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . WCX_Order::get_id( $order ) . '&my-account'), 'generate_wpo_wcpdf' ); 
  172.  
  173. // check my account button settings 
  174. if (isset($this->general_settings['my_account_buttons'])) { 
  175. switch ($this->general_settings['my_account_buttons']) { 
  176. case 'available': 
  177. $invoice_allowed = WCX_Order::get_meta( $order, '_wcpdf_invoice_exists', true ); 
  178. break; 
  179. case 'always': 
  180. $invoice_allowed = true; 
  181. break; 
  182. case 'never': 
  183. $invoice_allowed = false; 
  184. break; 
  185. case 'custom': 
  186. if ( isset( $this->general_settings['my_account_restrict'] ) && in_array( WCX_Order::get_status( $order ), array_keys( $this->general_settings['my_account_restrict'] ) ) ) { 
  187. $invoice_allowed = true; 
  188. } else { 
  189. $invoice_allowed = false;  
  190. break; 
  191. } else { 
  192. // backwards compatibility 
  193. $invoice_allowed = WCX_Order::get_meta( $order, '_wcpdf_invoice_exists', true ); 
  194.  
  195. // Check if invoice has been created already or if status allows download (filter your own array of allowed statuses) 
  196. if ( $invoice_allowed || in_array(WCX_Order::get_status( $order ), apply_filters( 'wpo_wcpdf_myaccount_allowed_order_statuses', array() ) ) ) { 
  197. $actions['invoice'] = array( 
  198. 'url' => $pdf_url,  
  199. 'name' => apply_filters( 'wpo_wcpdf_myaccount_button_text', __( 'Download invoice (PDF)', 'wpo_wcpdf' ) ) 
  200. );  
  201.  
  202. return apply_filters( 'wpo_wcpdf_myaccount_actions', $actions, $order ); 
  203.  
  204. /** 
  205. * Add the meta box on the single order page 
  206. */ 
  207. public function add_meta_boxes() { 
  208. // create PDF buttons 
  209. add_meta_box( 
  210. 'wpo_wcpdf-box',  
  211. __( 'Create PDF', 'wpo_wcpdf' ),  
  212. array( $this, 'sidebar_box_content' ),  
  213. 'shop_order',  
  214. 'side',  
  215. 'default' 
  216. ); 
  217.  
  218. // Invoice number & date 
  219. add_meta_box( 
  220. 'wpo_wcpdf-data-input-box',  
  221. __( 'PDF Invoice data', 'wpo_wcpdf' ),  
  222. array( $this, 'data_input_box_content' ),  
  223. 'shop_order',  
  224. 'normal',  
  225. 'default' 
  226. ); 
  227.  
  228. /** 
  229. * Create the meta box content on the single order page 
  230. */ 
  231. public function sidebar_box_content( $post ) { 
  232. global $post_id; 
  233.  
  234. $meta_actions = array( 
  235. 'invoice' => array ( 
  236. 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $post_id ), 'generate_wpo_wcpdf' ),  
  237. 'alt' => esc_attr__( 'PDF Invoice', 'wpo_wcpdf' ),  
  238. 'title' => __( 'PDF Invoice', 'wpo_wcpdf' ),  
  239. ),  
  240. 'packing-slip' => array ( 
  241. 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=packing-slip&order_ids=' . $post_id ), 'generate_wpo_wcpdf' ),  
  242. 'alt' => esc_attr__( 'PDF Packing Slip', 'wpo_wcpdf' ),  
  243. 'title' => __( 'PDF Packing Slip', 'wpo_wcpdf' ),  
  244. ),  
  245. ); 
  246.  
  247. $meta_actions = apply_filters( 'wpo_wcpdf_meta_box_actions', $meta_actions, $post_id ); 
  248.  
  249. ?> 
  250. <ul class="wpo_wcpdf-actions"> 
  251. <?php 
  252. foreach ($meta_actions as $action => $data) { 
  253. printf('<li><a href="%1$s" class="button" target="_blank" alt="%2$s">%3$s</a></li>', $data['url'], $data['alt'], $data['title']); 
  254. ?> 
  255. </ul> 
  256. <?php 
  257.  
  258. /** 
  259. * Add metabox for invoice number & date 
  260. */ 
  261. public function data_input_box_content ( $post ) { 
  262. $order = WCX::get_order( $post->ID ); 
  263. $invoice_exists = WCX_Order::get_meta( $order, '_wcpdf_invoice_exists', true ); 
  264. $invoice_number = WCX_Order::get_meta( $order, '_wcpdf_invoice_number', true ); 
  265. $invoice_date = WCX_Order::get_meta( $order, '_wcpdf_invoice_date', true ); 
  266.  
  267. do_action( 'wpo_wcpdf_meta_box_start', $post->ID ); 
  268.  
  269. ?> 
  270. <h4><?php _e( 'Invoice', 'wpo_wcpdf' ) ?></h4> 
  271. <p class="form-field _wcpdf_invoice_number_field "> 
  272. <label for="_wcpdf_invoice_number"><?php _e( 'Invoice Number (unformatted!)', 'wpo_wcpdf' ); ?>:</label> 
  273. <?php if (!empty($invoice_exists)) : ?> 
  274. <input type="text" class="short" style="" name="_wcpdf_invoice_number" id="_wcpdf_invoice_number" value="<?php echo $invoice_number ?>"> 
  275. <?php else : ?> 
  276. <input type="text" class="short" style="" name="_wcpdf_invoice_number" id="_wcpdf_invoice_number" value="<?php echo $invoice_number ?>" disabled="disabled" > 
  277. <?php endif; ?> 
  278. </p> 
  279. <p class="form-field form-field-wide"> 
  280. <label for="wcpdf_invoice_date"><?php _e( 'Invoice Date:', 'wpo_wcpdf' ); ?></label> 
  281. <?php if (!empty($invoice_exists)) : ?> 
  282. <input type="text" class="date-picker-field" name="wcpdf_invoice_date" id="wcpdf_invoice_date" maxlength="10" value="<?php echo date_i18n( 'Y-m-d', strtotime( $invoice_date ) ); ?>" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="number" class="hour" placeholder="<?php _e( 'h', 'woocommerce' ) ?>" name="wcpdf_invoice_date_hour" id="wcpdf_invoice_date_hour" min="0" max="23" size="2" value="<?php echo date_i18n( 'H', strtotime( $invoice_date ) ); ?>" pattern="([01]?[0-9]{1}|2[0-3]{1})" />:<input type="number" class="minute" placeholder="<?php _e( 'm', 'woocommerce' ) ?>" name="wcpdf_invoice_date_minute" id="wcpdf_invoice_date_minute" min="0" max="59" size="2" value="<?php echo date_i18n( 'i', strtotime( $invoice_date ) ); ?>" pattern="[0-5]{1}[0-9]{1}" /> 
  283. <?php else : ?> 
  284. <input type="text" class="date-picker-field" name="wcpdf_invoice_date" id="wcpdf_invoice_date" maxlength="10" disabled="disabled" value="" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="number" class="hour" disabled="disabled" placeholder="<?php _e( 'h', 'woocommerce' ) ?>" name="wcpdf_invoice_date_hour" id="wcpdf_invoice_date_hour" min="0" max="23" size="2" value="" pattern="([01]?[0-9]{1}|2[0-3]{1})" />:<input type="number" class="minute" placeholder="<?php _e( 'm', 'woocommerce' ) ?>" name="wcpdf_invoice_date_minute" id="wcpdf_invoice_date_minute" min="0" max="59" size="2" value="" pattern="[0-5]{1}[0-9]{1}" disabled="disabled" /> 
  285. <?php endif; ?> 
  286. </p> 
  287. <?php 
  288.  
  289. do_action( 'wpo_wcpdf_meta_box_end', $post->ID ); 
  290.  
  291. /** 
  292. * Add actions to menu 
  293. */ 
  294. public function bulk_actions() { 
  295. global $post_type; 
  296. $bulk_actions = apply_filters( 'wpo_wcpdf_bulk_actions', $this->bulk_actions ); 
  297.  
  298. if ( 'shop_order' == $post_type ) { 
  299. ?> 
  300. <script type="text/javascript"> 
  301. jQuery(document).ready(function() { 
  302. <?php foreach ($bulk_actions as $action => $title) { ?> 
  303. jQuery('<option>').val('<?php echo $action; ?>').html('<?php echo esc_attr( $title ); ?>').appendTo("select[name='action'], select[name='action2']"); 
  304. <?php } ?> 
  305. }); 
  306. </script> 
  307. <?php 
  308.  
  309. /** 
  310. * Save invoice number 
  311. */ 
  312. public function save_invoice_number_date($post_id) { 
  313. global $wpo_wcpdf; 
  314. $post_type = get_post_type( $post_id ); 
  315. if( $post_type == 'shop_order' ) { 
  316. // bail if this is not an actual 'Save order' action 
  317. if (!isset($_POST['action']) || $_POST['action'] != 'editpost') { 
  318. return; 
  319.  
  320. $order = WCX::get_order( $post_id ); 
  321. if ( isset($_POST['_wcpdf_invoice_number']) ) { 
  322. WCX_Order::update_meta_data( $order, '_wcpdf_invoice_number', stripslashes( $_POST['_wcpdf_invoice_number'] ) ); 
  323. WCX_Order::update_meta_data( $order, '_wcpdf_formatted_invoice_number', $wpo_wcpdf->export->get_invoice_number( $post_id ) ); 
  324. WCX_Order::update_meta_data( $order, '_wcpdf_invoice_exists', 1 ); 
  325.  
  326. if ( isset($_POST['wcpdf_invoice_date']) ) { 
  327. if ( empty($_POST['wcpdf_invoice_date']) ) { 
  328. WCX_Order::delete_meta_data( $order, '_wcpdf_invoice_date' ); 
  329. } else { 
  330. $invoice_date = strtotime( $_POST['wcpdf_invoice_date'] . ' ' . (int) $_POST['wcpdf_invoice_date_hour'] . ':' . (int) $_POST['wcpdf_invoice_date_minute'] . ':00' ); 
  331. $invoice_date = date_i18n( 'Y-m-d H:i:s', $invoice_date ); 
  332. WCX_Order::update_meta_data( $order, '_wcpdf_invoice_date', $invoice_date ); 
  333. WCX_Order::update_meta_data( $order, '_wcpdf_invoice_exists', 1 ); 
  334.  
  335. if (empty($_POST['wcpdf_invoice_date']) && isset($_POST['_wcpdf_invoice_number'])) { 
  336. $invoice_date = date_i18n( 'Y-m-d H:i:s', time() ); 
  337. WCX_Order::update_meta_data( $order, '_wcpdf_invoice_date', $invoice_date ); 
  338.  
  339. if ( empty($_POST['wcpdf_invoice_date']) && empty($_POST['_wcpdf_invoice_number'])) { 
  340. WCX_Order::delete_meta_data( $order, '_wcpdf_invoice_exists' ); 
  341.  
  342. /** 
  343. * Add invoice number to order search scope 
  344. */ 
  345. public function search_fields ( $custom_fields ) { 
  346. $custom_fields[] = '_wcpdf_invoice_number'; 
  347. $custom_fields[] = '_wcpdf_formatted_invoice_number'; 
  348. return $custom_fields; 
.