WC_Flespakket_Export

The WooCommerce Flespakket WC Flespakket Export class.

Defined (1)

The class is defined in the following location(s).

/includes/wcflespakket-export.php  
  1. class WC_Flespakket_Export { 
  2. public $order_id; 
  3.  
  4. /** 
  5. * Construct. 
  6. */ 
  7.  
  8. public function __construct() { 
  9. add_action( 'load-edit.php', array( &$this, 'wcflespakket_action' ) ); // Export actions (popup & file export) 
  10. $this->settings = get_option( 'wcflespakket_settings' ); 
  11. $this->log_file = dirname(dirname(__FILE__)).'/flespakket_log.txt'; 
  12.  
  13. /** 
  14. * Export selected orders 
  15. * @access public 
  16. * @return void 
  17. */ 
  18. public function wcflespakket_action() { 
  19. if ( isset($_REQUEST['action']) ) { 
  20. $action = $_REQUEST['action']; 
  21.  
  22. switch($action) { 
  23. case 'wcflespakket': 
  24. if ( empty($_GET['order_ids']) ) 
  25. die('U heeft geen orders geselecteerd!'); 
  26.  
  27. $order_ids = explode('x', $_GET['order_ids']); 
  28.  
  29. foreach($order_ids as $order_id) { 
  30. $order_meta = get_post_meta( $order_id ); 
  31. $order = new WC_Order( $order_id ); 
  32. $order_number = $order->get_order_number(); 
  33. $formatted_address = $order->get_formatted_shipping_address(); 
  34. $full_country = new WC_Countries; 
  35. $data[] = array( 
  36. 'naam' => $order_meta['_shipping_first_name'][0].' '.$order_meta['_shipping_last_name'][0],  
  37. 'bedrijfsnaam' => $order_meta['_shipping_company'][0],  
  38. 'postcode' => $order_meta['_shipping_postcode'][0],  
  39. 'adres1' => isset($order_meta['_shipping_address_1'][0])?$order_meta['_shipping_address_1'][0]:'',  
  40. 'adres2' => isset($order_meta['_shipping_address_2'][0])?$order_meta['_shipping_address_2'][0]:'',  
  41. 'huisnummer' => isset($order_meta['_shipping_house_number'][0])?$order_meta['_shipping_house_number'][0]:'',  
  42. 'huisnummertoevoeging' => isset($order_meta['_shipping_house_number_suffix'][0])?$order_meta['_shipping_house_number_suffix'][0]:'',  
  43. 'straat' => isset($order_meta['_shipping_street_name'][0])?$order_meta['_shipping_street_name'][0]:'',  
  44. 'woonplaats' => $order_meta['_shipping_city'][0],  
  45. 'landcode' => $order_meta['_shipping_country'][0],  
  46. 'land' => $full_country->countries[$order_meta['_shipping_country'][0]],  
  47. 'email' => $order_meta['_billing_email'][0],  
  48. 'telefoon' => $order_meta['_billing_phone'][0],  
  49. 'orderid' => $order_id,  
  50. 'ordernr' => $order_number,  
  51. 'bestelling' => $this->get_order_items( $order_id ),  
  52. 'formatted_address' => $formatted_address,  
  53. ); 
  54.  
  55. // Include HTML for export page/iframe 
  56. ?><?php include('wcflespakket-export-html.php'); ?><?php 
  57.  
  58. die(); 
  59. break; 
  60. case 'wcflespakket-export': 
  61. // die(print_r($_POST['data'])); // for debugging 
  62. // ERROR LOGGING 
  63. if (isset($this->settings['error_logging'])) 
  64. file_put_contents($this->log_file, date("Y-m-d H:i:s")." Export started\n", FILE_APPEND); 
  65.  
  66. // Get the data 
  67. if (!isset($_POST['data']))  
  68. die('Er zijn geen orders om te exporteren!'); 
  69.  
  70. // stripslashes! Wordpress always slashes POST data, regardless of magic quotes settings... http://stackoverflow.com/q/8949768/1446634 
  71. $post_data = stripslashes_deep($_POST['data']); 
  72.  
  73. $array = array( 
  74. 'process' => isset($this->settings['process'])?1:0, // NOTE: process parameter is active, put on 0 to create a consignment without processing it 
  75. 'consignments' => array() 
  76. ); 
  77.  
  78. foreach ($post_data as $order_id => $consignment) { 
  79. $array['consignments'][$order_id] = array( 
  80. 'colli_amount' => (isset($consignment['colli_amount'])) ? $consignment['colli_amount'] : '1',  
  81. 'package' => (isset($consignment['package'])) ? $consignment['package'] : 'bottle_1', // default to bottle_1... 
  82. 'ToAddress' => array(),  
  83. 'ProductCode' => array( 
  84. 'signature_on_receipt' => (isset($consignment['handtekening'])) ? '1' : '0',  
  85. 'return_if_no_answer' => (isset($consignment['retourbgg'])) ? '1' : '0',  
  86. 'home_address_only' => (isset($consignment['huisadres'])) ? '1' : '0',  
  87. 'home_address_signature'=> (isset($consignment['huishand'])) ? '1' : '0',  
  88. 'insured' => (isset($consignment['verzekerd'])) ? '1' : '0',  
  89.  
  90. ),  
  91. 'insured_amount' => $consignment['verzekerdbedrag'],  
  92. 'custom_id' => (isset($consignment['kenmerk'])) ? $consignment['kenmerk'] : '',  
  93. 'comments' => (isset($consignment['bericht'])) ? $consignment['bericht'] : '',  
  94. 'weight' => $consignment['gewicht'],  
  95. ); 
  96.  
  97. if( $consignment['landcode'] == 'NL' ) { 
  98. $array['consignments'][$order_id]['ToAddress'] = array( 
  99. 'name' => $consignment['naam'],  
  100. 'business' => $consignment['bedrijfsnaam'],  
  101. 'town' => $consignment['woonplaats'],  
  102. 'email' => (isset($consignment['email'])) ? $consignment['email'] : '',  
  103. 'phone_number' => (isset($consignment['telefoon'])) ? $consignment['telefoon'] : '',  
  104. // Country specific from here // 
  105. 'postcode' => $consignment['postcode'],  
  106. 'house_number' => $consignment['huisnummer'],  
  107. 'number_addition' => $consignment['huisnummertoevoeging'],  
  108. 'street' => $consignment['straat'],  
  109. ); 
  110.  
  111. if ($consignment['colli_amount'] > 1) { 
  112. $array['consignments'][$order_id]['MultiColli'] = array(); 
  113. for ($x=2; $x<=$consignment['colli_amount']; $x++) { 
  114. $array['consignments'][$order_id]['MultiColli']['package_'.$x] = $consignment['package_'.$x]; 
  115.  
  116. } else { 
  117. $array['consignments'][$order_id]['ToAddress'] = array( 
  118. 'name' => $consignment['naam'],  
  119. 'business' => $consignment['bedrijfsnaam'],  
  120. 'town' => $consignment['woonplaats'],  
  121. 'email' => (isset($consignment['email'])) ? $consignment['email'] : '',  
  122. 'phone_number' => (isset($consignment['telefoon'])) ? $consignment['telefoon'] : '',  
  123. // Country specific from here // 
  124. 'country_code' => $consignment['landcode'],  
  125. 'eps_postcode' => $consignment['postcode'],  
  126. 'street' => $consignment['adres1'].' '.$consignment['adres2'],  
  127. ); 
  128.  
  129. // ERROR LOGGING 
  130. if (isset($this->settings['error_logging'])) 
  131. file_put_contents($this->log_file, date("Y-m-d H:i:s")." consignment data:\n".var_export($array['consignments'], true)."\n", FILE_APPEND); 
  132. // die( print_r( $array ) ); 
  133.  
  134. // Send consignments to Flespakket API 
  135. $decode = $this->api_request( 'create-consignments', $array); 
  136.  
  137. // ERROR LOGGING 
  138. if (isset($this->settings['error_logging'])) 
  139. file_put_contents($this->log_file, date("Y-m-d H:i:s")." API response:\n".print_r($decode, true)."\n", FILE_APPEND); 
  140.  
  141. if (isset($decode['error'])) { 
  142. echo $this->translate_error($decode['error']); 
  143. exit; 
  144.  
  145. // put order_id in key! 
  146. $decode = array_combine( array_keys($array['consignments']), array_values($decode) ); 
  147.  
  148. //die( print_r( $decode, true ) ); //for debugging 
  149.  
  150. $consignment_list = array(); 
  151. $order_ids = array(); 
  152. $error = array(); 
  153. foreach ($decode as $order_id => $order_decode ) { 
  154. if ( !isset($order_decode['error']) ) { 
  155. $consignment_id = $order_decode['consignment_id']; 
  156. $order_ids[] = $order_id; 
  157. $consignment_list[] = $consignment_id; //collect consigment_ids in an array for pdf retreival 
  158. $tracktrace = $order_decode['tracktrace']; 
  159.  
  160. update_post_meta ( $order_id, '_flespakket_consignment_id', $consignment_id ); 
  161. update_post_meta ( $order_id, '_flespakket_tracktrace', $tracktrace ); 
  162.  
  163. // set status to complete 
  164. if ( isset($this->settings['auto_complete']) ) { 
  165. $order = new WC_Order( $order_id ); 
  166. $order->update_status( 'completed', 'Order voltooid na Flespakket export' ); 
  167.  
  168. } else { 
  169. //$error[$order_id] = $order_decode['error']; 
  170. $error[$order_id] = implode( ', ', $this->array_flatten($order_decode) ); 
  171.  
  172.  
  173. $consignment_list_flat = implode('x', $consignment_list); 
  174. $order_ids_flat = implode('x', $order_ids); 
  175. $pdf_url = wp_nonce_url( admin_url( 'edit.php?&action=wcflespakket-label&consignment=' . $consignment_list_flat . '&order_ids=' . $order_ids_flat ), 'wcflespakket-label' ); 
  176.  
  177. $this->export_done($pdf_url, $consignment_list, $error); 
  178.  
  179. exit; 
  180. case 'wcflespakket-label': 
  181. if ( empty($_GET['consignment']) && empty($_GET['order_ids']) ) 
  182. die('U heeft geen orders geselecteerd!'); 
  183.  
  184. // ERROR LOGGING 
  185. if (isset($this->settings['error_logging'])) 
  186. file_put_contents($this->log_file, date("Y-m-d H:i:s")." Label request\n", FILE_APPEND); 
  187.  
  188. $order_ids = explode('x', $_GET['order_ids']); 
  189.  
  190. $consignment_list = array(); 
  191.  
  192. if ( !isset($_GET['consignment']) ) { 
  193. // Bulk export label 
  194. foreach ($order_ids as $order_id) { 
  195. if (get_post_meta($order_id, '_flespakket_consignment_id', true)) { 
  196. $order_consignment_id = get_post_meta($order_id, '_flespakket_consignment_id', true); 
  197. $consignment_list[$order_id] = $order_consignment_id; 
  198. $consignment_id_encoded = implode('x', $consignment_list);  
  199. } else { 
  200. // Label request from modal (directly after export) 
  201. // consignments already given! 
  202. $consignments = explode('x', $_GET['consignment']); 
  203. $consignment_list = array_combine($order_ids, $consignments); 
  204. $consignment_id_encoded = implode('x', $consignment_list);  
  205.  
  206. $consignment_id = str_replace('x', ', ', $consignment_id_encoded); 
  207.  
  208. // retrieve pdf for the consignment (this is another api call to retrieve-pdf) 
  209. $array = array( 
  210. 'consignment_id' => $consignment_id,  
  211. 'format' => 'json',  
  212. ); 
  213.  
  214. // ERROR LOGGING 
  215. if (isset($this->settings['error_logging'])) 
  216. file_put_contents($this->log_file, date("Y-m-d H:i:s")." consignment(s) requested: ".$consignment_id."\n", FILE_APPEND); 
  217.  
  218. // Request labels from Flespakket API 
  219. $decode = $this->api_request( 'retrieve-pdf', $array); 
  220.  
  221. if (isset($decode['consignment_pdf'])) { 
  222. $pdf_data = $decode['consignment_pdf']; 
  223. $consigments_tracktrace = array_combine( explode(', ', $decode['consignment_id']), explode(', ', $decode['tracktrace']) ); 
  224.  
  225. // track & trace fallback 
  226. foreach ( $consignment_list as $order_id => $consignment_id ) { 
  227. if ( isset($consigments_tracktrace[$consignment_id]) ) { 
  228. // create array with $order_id => $tracktrace 
  229. $orders_tracktrace[$order_id] = $consigments_tracktrace[$consignment_id]; 
  230.  
  231. // put track&trace code in order meta 
  232. update_post_meta ( $order_id, '_flespakket_tracktrace', $consigments_tracktrace[$consignment_id] ); 
  233.  
  234. unset($decode['consignment_pdf']); 
  235.  
  236. // ERROR LOGGING 
  237. if (isset($this->settings['error_logging'])) { 
  238. file_put_contents($this->log_file, date("Y-m-d H:i:s")." PDF data received\n", FILE_APPEND); 
  239. file_put_contents($this->log_file, print_r($orders_tracktrace, true)."\n", FILE_APPEND); 
  240.  
  241. do_action( 'wcflespakket_before_label_print', $consignment_list ); 
  242.  
  243. $filename = 'Flespakket'; 
  244. $filename .= '-' . date('Y-m-d') . '.pdf'; 
  245.  
  246. // Get output setting 
  247. $output_mode = isset($this->settings['download_display'])?$this->settings['download_display']:''; 
  248.  
  249. // Switch headers according to output setting 
  250. if ( $output_mode == 'display' ) { 
  251. header('Content-type: application/pdf'); 
  252. header('Content-Disposition: inline; filename="'.$filename.'"'); 
  253. } else { 
  254. header('Content-Description: File Transfer'); 
  255. header('Content-Type: application/octet-stream'); 
  256. header('Content-Disposition: attachment; filename="'.$filename.'"');  
  257. header('Content-Transfer-Encoding: binary'); 
  258. header('Connection: Keep-Alive'); 
  259. header('Expires: 0'); 
  260. header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
  261. header('Pragma: public'); 
  262.  
  263. // stream data 
  264. echo urldecode($pdf_data); 
  265. } elseif (isset($decode['error'])) { 
  266. echo 'Error: ' . $decode['error']; 
  267.  
  268. if (isset($this->settings['error_logging'])) 
  269. file_put_contents($this->log_file, date("Y-m-d H:i:s")." server response:\n".print_r($decode, true)."\n", FILE_APPEND); 
  270. } else { 
  271. echo 'An unknown error occured<br/>'; 
  272. echo 'Server response: ' . print_r($decode); 
  273.  
  274. if (isset($this->settings['error_logging'])) 
  275. file_put_contents($this->log_file, date("Y-m-d H:i:s")." server response:\n".print_r($decode, true)."\n", FILE_APPEND); 
  276. exit; 
  277. default: return; 
  278.  
  279.  
  280. public function api_request( $request_type, $data, $method = 'POST' ) { 
  281. // collect API credentials/settings 
  282. $target_site_api = 'http://www.flespakket.nl/api/'; 
  283. $username = $this->settings['api_username']; 
  284. $api_key = $this->settings['api_key']; 
  285. $timestamp = time(); 
  286. $nonce = rand(0, 255); // note: this should be incremented in case 2 requests occur within the same timestamp (second) 
  287.  
  288. // JSON encode data 
  289. $json = urlencode(json_encode($data)); 
  290.  
  291. // create GET/POST string (keys in alphabetical order) 
  292. $string = implode('&', array( 
  293. 'json=' . $json,  
  294. 'nonce=' . $nonce,  
  295. 'test=' . (isset( $this->settings['testmode'] ) ? '1' : '0'),  
  296. 'timestamp=' . $timestamp,  
  297. 'username=' . $username,  
  298. ));  
  299.  
  300. // ERROR LOGGING 
  301. if (isset($this->settings['error_logging'])) 
  302. file_put_contents($this->log_file, date("Y-m-d H:i:s")." Post content:\n".$string."\n", FILE_APPEND); 
  303.  
  304. // create hash 
  305. $signature = hash_hmac('sha1', $method . '&' . urlencode($string), $api_key); 
  306.  
  307. if($method == 'POST') 
  308. $ch = curl_init(); 
  309. curl_setopt($ch, CURLOPT_URL, $target_site_api . $request_type . '/'); 
  310. curl_setopt($ch, CURLOPT_POST, true); 
  311. curl_setopt($ch, CURLOPT_POSTFIELDS, $string . '&signature=' . $signature); 
  312. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
  313. curl_setopt($ch, CURLOPT_TIMEOUT, 60); 
  314. $result = curl_exec($ch); 
  315. curl_close ($ch); 
  316. else // GET 
  317. // depricated, long urls for batch processing gives issues 
  318. $request = $target_site_api . $request_type . '/?' . $string . '&signature=' . $signature; 
  319. $result = file_get_contents($request); 
  320.  
  321. // decode result 
  322. $decode = json_decode($result, true); 
  323.  
  324. // ERROR LOGGING 
  325. if (isset($this->settings['error_logging'])) 
  326. file_put_contents($this->log_file, date("Y-m-d H:i:s")." API response:\n".print_r($decode, true)."\n", FILE_APPEND); 
  327.  
  328. return $decode; 
  329.  
  330. /** 
  331. * Get the current order items 
  332. */ 
  333. public function get_order_items( $order_id ) { 
  334. global $woocommerce; 
  335. $order = new WC_Order( $order_id ); 
  336. //global $_product; 
  337. $items = $order->get_items(); 
  338. $data_list = array(); 
  339.  
  340. if( sizeof( $items ) > 0 ) { 
  341. foreach ( $items as $item ) { 
  342. // Array with data for the printing template 
  343. $data = array(); 
  344.  
  345. // Create the product 
  346. $product = $order->get_product_from_item( $item ); 
  347.  
  348. // Set the variation 
  349. if( isset( $item['variation_id'] ) && $item['variation_id'] > 0 ) { 
  350. $data['variation'] = woocommerce_get_formatted_variation( $product->get_variation_attributes() ); 
  351. } else { 
  352. $data['variation'] = null; 
  353.  
  354. // Set item name 
  355. $data['name'] = $item['name']; 
  356.  
  357. // Set item quantity 
  358. $data['quantity'] = $item['qty']; 
  359.  
  360. // Set item SKU 
  361. $data['sku'] = $product->get_sku(); 
  362.  
  363. // Set item weight 
  364. $weight = $product->get_weight(); 
  365. $weight_unit = get_option( 'woocommerce_weight_unit' ); 
  366. switch ($weight_unit) { 
  367. case 'kg': 
  368. $data['weight'] = $weight; 
  369. break; 
  370. case 'g': 
  371. $data['weight'] = $weight / 1000; 
  372. break; 
  373. case 'lbs': 
  374. $data['weight'] = $weight * 0.45359237; 
  375. break; 
  376. case 'oz': 
  377. $data['weight'] = $weight * 0.0283495231; 
  378. break; 
  379. default: 
  380. $data['weight'] = $weight; 
  381. break; 
  382.  
  383. $data['total_weight'] = $data['quantity']*$data['weight']; 
  384.  
  385. // Set item dimensions 
  386. $data['dimensions'] = $product->get_dimensions(); 
  387.  
  388. $data_list[] = $data; 
  389.  
  390. return $data_list; 
  391.  
  392.  
  393. /** 
  394. * Get shipping data for current order 
  395. */ 
  396. public function name_length_check($names) { 
  397. $voornaam = $names['voornaam']; 
  398. $achternaam = $names['achternaam']; 
  399. $bedrijfsnaam = $names['bedrijfsnaam']; 
  400.  
  401. if (strlen($voornaam) + strlen($achternaam) + 1 > 30 ) { $voornaam = preg_replace('/(\w)(\w+) *-*/', '\1.', $voornaam); }  
  402. $naam = $voornaam . ' ' . $achternaam; 
  403.  
  404. if (!$bedrijfsnaam=="") { 
  405. if (strlen($bedrijfsnaam) > 35 ) { $bedrijfsnaam = substr($bedrijfsnaam, 0, 35); } 
  406.  
  407. if (strlen($bedrijfsnaam) + strlen($naam) > 30) { 
  408. if (strlen($bedrijfsnaam) + strlen($achternaam) <= 30) {$naam = $achternaam;} 
  409. else {$bedrijfsnaam = "";} 
  410. $checked_names['naam'] = $naam; 
  411. $checked_names['bedrijfsnaam'] = $bedrijfsnaam;  
  412. return $checked_names;  
  413.  
  414. /** 
  415. * Multi-dimensional array flatten 
  416. */ 
  417. public function array_flatten($a, $f=array()) { 
  418. if(!$a||!is_array($a))return ''; 
  419. foreach($a as $k=>$v) { 
  420. if(is_array($v))$f=$this->array_flatten($v, $f); 
  421. else $f[$k]=$v; 
  422. return $f; 
  423.  
  424. /** 
  425. * Vertaal engelse Flespakket foutmeldingen 
  426. */ 
  427. public function translate_error($error) { 
  428. switch ($error) { 
  429. case 'access denied - Signature does not match request - parameters need to be hashed in alphabetical order': 
  430. $error = 'Toegang geweigerd - De API key komt niet overeen met de gebruikersnaam.'; 
  431. break; 
  432. case 'access denied - Username \''.$this->settings['api_username'].'\' does not exist': 
  433. $error = 'Toegang geweigerd - De gebruikersnaam <strong>'.$this->settings['api_username'].'</strong> bestaat niet.'; 
  434. break; 
  435.  
  436. return $error; 
  437.  
  438. /** 
  439. * Export result page 
  440. */ 
  441. public function export_done ($pdf_url, $consignment_list, $error) { 
  442. ?> 
  443. <!DOCTYPE html> 
  444. <html xmlns="http://www.w3.org/1999/xhtml"> 
  445. <head> 
  446. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
  447. <?php 
  448. require_once(ABSPATH . 'wp-admin/admin.php'); 
  449. wp_register_style( 'wcflespakket-admin-styles', dirname(plugin_dir_url(__FILE__)) . '/css/wcflespakket-admin-styles.css', array(), '', 'all' ); 
  450. wp_enqueue_style( 'wcflespakket-admin-styles' );  
  451. wp_enqueue_style( 'colors' ); 
  452. wp_enqueue_style( 'media' ); 
  453. do_action('admin_print_styles'); 
  454. ?> 
  455. </head> 
  456. <body style="padding:10px 20px;"> 
  457. <h1>Export voltooid</h1> 
  458. <?php 
  459. if (!empty($error)) { 
  460. echo '<p>Er hebben zich fouten voorgedaan bij de volgende orders, deze zijn niet verwerkt:<ul style="margin-left:20px;">'; 
  461. foreach($error as $order_id => $error_message) { 
  462. $order = new WC_Order($order_id); 
  463. $order_number = $order->get_order_number(); 
  464. echo '<li><strong>'.$order_number.'</strong> <i>'.$error_message.'</i></li>'; 
  465. echo '</ul></p>'; 
  466. if (!empty($consignment_list)) { 
  467. if (!empty($error)) { 
  468. echo '<p>De overige orders zijn succesvol verwerkt bij Flespakket.<br />'; 
  469. } else { 
  470. echo '<p>De geselecteerde orders zijn succesvol verwerkt bij Flespakket.<br />';  
  471. $target = ( isset($this->settings['download_display']) && $this->settings['download_display'] == 'display') ? 'target="_blank"' : ''; 
  472.  
  473. ?> 
  474. Hieronder kunt u de labels in PDF formaat downloaden.</p> 
  475. <?php printf('<a href="%1$s" %2$s><img src="%3$s"></a>', $pdf_url, $target, dirname(plugin_dir_url(__FILE__)) . '/img/download-pdf.png'); ?> 
  476. <p><strong>Let op!</strong><br /> 
  477. Uw pakket met daarop het verzendetiket dient binnen 9 werkdagen na het aanmaken bij PostNL binnen te zijn. Daarna verliest het zijn geldigheid. 
  478. </body></html> 
  479. <?php 
  480.