/classes/class-order-export-process.php

  1. <?php 
  2.  
  3. if( !defined('ABSPATH') ) { 
  4. exit; 
  5.  
  6. if( !class_exists('order_export_process') ) { 
  7.  
  8. class order_export_process { 
  9.  
  10. /** 
  11. * Delimiter for CSV file 
  12. */ 
  13. static $delimiter; 
  14.  
  15. /** 
  16. * Tells which fields to export. 
  17. *  
  18. * Also reset orders of fields according to which they were added 
  19. * in plugin. 
  20. *  
  21. * Refer this support link: https://wordpress.org/support/topic/change-order-5?replies=7#post-6818741 
  22. */ 
  23. static function export_options() { 
  24.  
  25. global $wpg_order_columns; 
  26.  
  27. $settings = wpg_order_export::get_settings_fields(); 
  28. $settings = apply_filters( 'wpg_export_options_settings', $settings ); 
  29.  
  30. $fields = array(); 
  31.  
  32. $setting_order = array(); 
  33.  
  34. if( is_array( $settings ) ) { 
  35.  
  36. foreach( $settings as $setting ) { 
  37.  
  38. if( !is_array( $setting ) || empty($setting['id']) ) { 
  39. continue; 
  40.  
  41. array_push( $setting_order, $setting['id'] ); 
  42.  
  43. $new_order = array(); 
  44.  
  45. foreach( $setting_order as $_setting ) { 
  46.  
  47. if( empty( $wpg_order_columns[$_setting] ) ) { 
  48. continue; 
  49.  
  50. $new_order[$_setting] = $wpg_order_columns[$_setting]; 
  51.  
  52. $wpg_order_columns = $new_order; 
  53.  
  54. foreach( $wpg_order_columns as $key=>$val ) { 
  55.  
  56. $retireve = get_option( $key, 'no' ); 
  57. $fields[$key] = ( strtolower($retireve) === 'yes' ) ? true : false; 
  58.  
  59. return $fields; 
  60.  
  61. /** 
  62. * Returns order details 
  63. */ 
  64. static function get_orders() { 
  65.  
  66. $fields = self::export_options(); 
  67. $fields = array_filter( $fields, 'wsoe_array_filter' ); 
  68. $headings = self::csv_heading($fields); 
  69.  
  70. $delimiter = ( empty( $_POST['wpg_delimiter'] ) || ( gettype( $_POST['wpg_delimiter'] ) !== 'string' ) ) ? ', ' : $_POST['wpg_delimiter'][0]; 
  71.  
  72. /** 
  73. * Filter : wpg_delimiter 
  74. * Filters the delimiter for exported csv file. Override user defined 
  75. * delimiter by using this filter. 
  76. */ 
  77. self::$delimiter = apply_filters( 'wpg_delimiter', $delimiter ); 
  78.  
  79. $iterator = 0; 
  80. $chunk_size = apply_filters( 'wsoe_chunk_size', 20 ); 
  81.  
  82. @set_time_limit(0); 
  83. do{ 
  84.  
  85. /** Check which order statuses to export. */ 
  86. $order_statuses = ( !empty( $_POST['order_status'] ) && is_array( $_POST['order_status'] ) ) ? $_POST['order_status'] : array_keys( wc_get_order_statuses() ); 
  87.  
  88. $args = array( 
  89. 'post_type'=>'shop_order',  
  90. 'posts_per_page'=> $chunk_size,  
  91. 'post_status'=> apply_filters( 'wpg_order_statuses', $order_statuses ),  
  92. 'offset' => ($chunk_size*$iterator) 
  93. ); 
  94.  
  95. $args['date_query'] = array( 
  96. array( 
  97. 'after'=> $_POST['start_date'],  
  98. 'before'=> $_POST['end_date'],  
  99. 'inclusive' => true ) 
  100. ); 
  101.  
  102. $args = apply_filters( 'wsoe_query_args', $args ); 
  103.  
  104. $orders = new WP_Query( $args ); 
  105.  
  106. if( $orders->have_posts() ) { 
  107.  
  108. /** 
  109. * Do these operations for only first iteration. 
  110. */ 
  111. if( !$iterator ) { 
  112.  
  113. /** 
  114. * This will be file pointer 
  115. */ 
  116. $csv_file = self::create_csv_file(); 
  117.  
  118. if( empty($csv_file) ) { 
  119. return new WP_Error( 'not_writable', __( 'Unable to create csv file, upload folder not writable', 'woocommerce-simply-order-export' ) ); 
  120.  
  121. fputcsv( $csv_file, $headings, self::$delimiter ); 
  122.  
  123.  
  124. /** 
  125. * Loop over each order 
  126. */ 
  127. while( $orders->have_posts() ) { 
  128.  
  129. $csv_values = array(); 
  130.  
  131. $orders->the_post(); 
  132.  
  133. $order_details = new WC_Order( get_the_ID() ); 
  134.  
  135. $items = $order_details->get_items(); 
  136.  
  137. foreach( $items as $item_id=>$item ) { 
  138.  
  139. $csv_values = array(); 
  140. self::add_fields_diff_row( $fields, $csv_values, $order_details, $item_id, $item ); 
  141. fputcsv( $csv_file, $csv_values, self::$delimiter ); 
  142.  
  143. wp_reset_postdata(); 
  144.  
  145. }elseif( empty($iterator) ) { // If there are no orders at first place, send error. 
  146.  
  147. return new WP_Error( 'no_orders', __( 'No orders for specified duration.', 'woocommerce-simply-order-export' ) ); 
  148.  
  149. ++$iterator; 
  150.  
  151. }while( ( $iterator < $orders->max_num_pages ) ); 
  152.  
  153. /** 
  154. *  
  155. */ 
  156. static function add_fields_diff_row( $fields, &$csv_values, $order_details, $item_id = null, $current_item = null ) { 
  157.  
  158. /** 
  159. * Loop over fields and add value for corresponding field. 
  160. */ 
  161. foreach( $fields as $key =>$field ) { 
  162.  
  163. switch ( $key ) { 
  164.  
  165. /** 
  166. * Check if we need order ID. 
  167. */ 
  168. case 'wc_settings_tab_order_id': 
  169. array_push( $csv_values, $order_details->get_order_number() ); 
  170. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  171. break; 
  172.  
  173. /** 
  174. * Check if we need customer name. 
  175. */ 
  176. case 'wc_settings_tab_customer_name': 
  177. array_push( $csv_values, self::customer_name( get_the_ID() ) ); 
  178. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  179. break; 
  180.  
  181. /** 
  182. * Check if we need product name. 
  183. */ 
  184. case 'wc_settings_tab_product_name': 
  185. array_push( $csv_values, $current_item['name'] ); 
  186. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  187. break; 
  188.  
  189. /** 
  190. * Check if we need product quantity. 
  191. * Product quantity will only be exported if user has selected product name to be exported. 
  192. *  
  193. * If product name is not selected, this column will be filled with just dashes. ;) 
  194. */ 
  195. case 'wc_settings_tab_product_quantity': 
  196. array_push( $csv_values, $current_item['qty'] ); 
  197. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  198. break; 
  199.  
  200. /** 
  201. * Check if we need product variations 
  202. */ 
  203. case 'wc_settings_tab_product_variation': 
  204. array_push( $csv_values, self::get_product_variation( $item_id, $order_details ) ); 
  205. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  206. break; 
  207.  
  208. /** 
  209. * Check if we need order amount. 
  210. */ 
  211. case 'wc_settings_tab_amount': 
  212. array_push( $csv_values, wsoe_formatted_price( $order_details->get_total(), $order_details ) ); 
  213. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  214. break; 
  215.  
  216. /** 
  217. * Check if we need customer email. 
  218. */ 
  219. case 'wc_settings_tab_customer_email': 
  220. array_push( $csv_values, self::customer_meta( get_the_ID(), '_billing_email' ) ); 
  221. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  222. break; 
  223.  
  224. /** 
  225. * Check if we need customer phone. 
  226. */ 
  227. case 'wc_settings_tab_customer_phone': 
  228. array_push( $csv_values, self::customer_meta( get_the_ID(), '_billing_phone' ) ); 
  229. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  230. break; 
  231.  
  232. /** 
  233. * Check if we need order status. 
  234. */ 
  235. case 'wc_settings_tab_order_status': 
  236. array_push( $csv_values, ucwords($order_details->get_status()) ); 
  237. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  238. break; 
  239.  
  240. default : 
  241. /** 
  242. * Add values to CSV. 
  243. *  
  244. * @param array $csv_values Array of csv values, callback function should accept this argument by reference. 
  245. *  
  246. * @param Object $order_details WC_Order object 
  247. *  
  248. * @param String $key Current key in loop. 
  249. *  
  250. */ 
  251. do_action_ref_array( 'wpg_add_values_to_csv', array( &$csv_values, $order_details, $key, $fields, $item_id, $current_item ) ); 
  252. do_action_ref_array( 'wsoe_after_value_'.$key, array( &$csv_values, $order_details, $item_id, $current_item ) ); 
  253. break; 
  254.  
  255.  
  256. /** 
  257. * Returns customer related meta. 
  258. * Basically it is just get_post_meta() function wrapper. 
  259. */ 
  260. static function customer_meta( $order_id , $meta = '' ) { 
  261.  
  262. if( empty( $order_id ) || empty( $meta ) ) 
  263. return ''; 
  264.  
  265. return get_post_meta( $order_id, $meta, true ); 
  266.  
  267. static function get_product_variation ( $product_id, $order_details ) { 
  268.  
  269. $metadata = $order_details->has_meta( $product_id ); 
  270. $_product = new WC_Product( $product_id ); 
  271.  
  272. $exclude_meta = apply_filters( 'woocommerce_hidden_order_itemmeta', array( 
  273. '_qty',  
  274. '_tax_class',  
  275. '_product_id',  
  276. '_variation_id',  
  277. '_line_subtotal',  
  278. '_line_subtotal_tax',  
  279. '_line_total',  
  280. '_line_tax',  
  281. ) ); 
  282.  
  283. $variation_details = array(); 
  284.  
  285. foreach( $metadata as $k => $meta ) { 
  286.  
  287. if( in_array( $meta['meta_key'], $exclude_meta ) ) { 
  288. continue; 
  289.  
  290. // Skip serialised meta 
  291. if ( is_serialized( $meta['meta_value'] ) ) { 
  292. continue; 
  293.  
  294. // Get attribute data 
  295. if ( taxonomy_exists( wc_sanitize_taxonomy_name( $meta['meta_key'] ) ) ) { 
  296.  
  297. $term = get_term_by( 'slug', $meta['meta_value'], wc_sanitize_taxonomy_name( $meta['meta_key'] ) ); 
  298. $meta['meta_key'] = wc_attribute_label( wc_sanitize_taxonomy_name( $meta['meta_key'] ) ); 
  299. $meta['meta_value'] = isset( $term->name ) ? $term->name : $meta['meta_value']; 
  300.  
  301. }else { 
  302. $meta['meta_key'] = apply_filters( 'woocommerce_attribute_label', wc_attribute_label( $meta['meta_key'], $_product ), $meta['meta_key'] ); 
  303.  
  304. array_push( $variation_details, wp_kses_post( urldecode( $meta['meta_key'] ) ) .': '.wp_kses_post( urldecode( $meta['meta_value'] ) ) ); 
  305.  
  306. return $variation_details = implode( ' | ', $variation_details ); 
  307.  
  308. /** 
  309. * Returns customer name for particular order 
  310. * @param type $order_id 
  311. * @return string 
  312. */ 
  313. static function customer_name( $order_id ) { 
  314.  
  315. if( empty( $order_id ) ) { 
  316. return ''; 
  317.  
  318. $firstname = get_post_meta( $order_id, '_billing_first_name', true ); 
  319. $lastname = get_post_meta( $order_id, '_billing_last_name', true ); 
  320.  
  321. return trim( $firstname.' '. $lastname );  
  322.  
  323. /** 
  324. * Makes first row for csv 
  325. */ 
  326. static function csv_heading( $fields ) { 
  327.  
  328. if( !is_array( $fields ) ) { 
  329. return false; 
  330.  
  331. global $wpg_order_columns; 
  332. $headings = array(); 
  333.  
  334. foreach( $fields as $key=>$val ) { 
  335.  
  336. if( $val === true && array_key_exists( $key, $wpg_order_columns ) ) { 
  337. array_push( $headings, $wpg_order_columns[$key] ); 
  338. // By using this we can add heading for keys which are not sanitized. 
  339. do_action_ref_array( 'wsoe_after_heading_'.$key, array( &$headings ) ); 
  340.  
  341. return $headings; 
  342.  
  343.  
  344. /** 
  345. * Creates csv file in upload directory. 
  346. */ 
  347. static function create_csv_file() { 
  348.  
  349. $csv_filename = empty($_POST['woo_soe_csv_name']) ? 'order_export.csv' : sanitize_file_name($_POST['woo_soe_csv_name']) .'.csv'; 
  350. $new_filename = wp_unique_filename( trailingslashit( wsoe_upload_dir() ), $csv_filename ); 
  351.  
  352. $csv_file = fopen( trailingslashit( wsoe_upload_dir() ) . $new_filename, 'w+' ); 
  353.  
  354. do_action( 'wsoe_file_created', $_POST['start_date'], $_POST['end_date'], $new_filename, $csv_file ); 
  355.  
  356. /** 
  357. * Save file name in global for later use. 
  358. */ 
  359. $GLOBALS['wsoe_filename'] = str_replace( '.csv', '', $new_filename ); 
  360. return $csv_file; 
.