PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/woocommerce-api-manager/classes/class-wc-api-helpers.php

https://github.com/Acekid88/website
PHP | 1463 lines | 750 code | 333 blank | 380 comment | 179 complexity | f6b313ca12df34430fe2535b82e64cc4 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. // Exit if accessed directly
  3. if ( ! defined( 'ABSPATH' ) ) exit;
  4. /**
  5. * WooCommerce API Manager Helpers Class
  6. *
  7. * @package Update API Manager/Helpers
  8. * @author Todd Lahman LLC
  9. * @copyright Copyright (c) 2011-2013, Todd Lahman LLC
  10. * @since 1.0.0
  11. *
  12. */
  13. class WC_Api_Manager_Helpers {
  14. public static $user_meta_key_orders = 'wc_am_orders';
  15. public static $user_meta_key_activations = 'wc_am_activations_';
  16. // For troubleshooting
  17. //exit( var_dump( $wpdb->last_query ) );
  18. /**
  19. * order_complete function.
  20. *
  21. * Order is complete - update activation_limit if Software Add-on activated, and saves user_meta data
  22. *
  23. * Updates the number of activations per license key according to the API Manager settings
  24. * Saves array of data for each order generated for a customer
  25. *
  26. */
  27. public static function order_complete( $order_id ) {
  28. global $wpdb;
  29. $order = new WC_Order( $order_id );
  30. if ( count( $order->get_items() ) > 0 ) {
  31. foreach ( $order->get_items() as $item ) {
  32. $item_product_id = ( isset( $item['product_id'] ) ) ? $item['product_id'] : $item['id'];
  33. $item_variation_id = ( isset( $item['variation_id'] ) ) ? $item['variation_id'] : $item['id'];
  34. // verify this is a variable product
  35. if ( $item_variation_id > 0 ) {
  36. $meta = get_post_custom( $item_product_id );
  37. $meta_var = get_post_custom( $item_variation_id );
  38. if ( $meta['_downloadable'][0] == 'yes' || $meta_var['_downloadable'][0] == 'yes' ) {
  39. $quantity = isset( $item['item_meta']['_qty'][0] ) ? absint( $item['item_meta']['_qty'][0] ) : 1;
  40. /**
  41. * If the parent product has a tile else use the variable product title
  42. */
  43. if ( isset( $meta_var['_api_software_title_parent'][0] ) && $meta_var['_api_software_title_parent'][0] != '' && ! empty( $meta_var['_api_software_title_parent'][0] ) ) {
  44. $software_title_parent = $meta_var['_api_software_title_parent'][0];
  45. $software_title = $meta_var['_api_software_title_parent'][0];
  46. } else if ( isset( $meta_var['_api_software_title_var'][0] ) && $meta_var['_api_software_title_var'][0] != '' && ! empty( $meta_var['_api_software_title_var'][0] ) ) {
  47. $software_title_var = $meta_var['_api_software_title_var'][0];
  48. $software_title = $meta_var['_api_software_title_var'][0];
  49. } else {
  50. $software_title = '';
  51. }
  52. if ( get_option( 'wc_api_manager_software_add_on_license_key' ) == 'yes' && self::is_plugin_active( 'woocommerce-software-add-on/woocommerce-software.php' ) ) {
  53. // Get the order_id
  54. $lic_order_id = $wpdb->get_var( $wpdb->prepare( "
  55. SELECT order_id FROM {$wpdb->prefix}woocommerce_software_licences
  56. WHERE order_id = %d
  57. LIMIT 1
  58. ", $order_id ) );
  59. // verify the license has been created before continuing
  60. if ( $lic_order_id ) {
  61. for ( $i = 0; $i < $quantity; $i++ ) {
  62. $data = array(
  63. 'order_id' => $order_id,
  64. 'activations_limit' => empty( $meta_var['_api_activations'][0] ) ? '' : (int) $meta_var['_api_activations'][0],
  65. 'software_title' => empty( $software_title ) ? '' : (string) $software_title,
  66. 'current_version' => empty( $meta_var['_api_new_version'][0] ) ? '' : (string) $meta_var['_api_new_version'][0],
  67. );
  68. self::update_licence_key( $data );
  69. // Saves meta data for this order to be used by the API Manager if Software Add-on license is required
  70. $meta_data =
  71. array( $order->order_key =>
  72. array(
  73. 'user_id' => $order->user_id,
  74. 'order_id' => $order_id,
  75. 'order_key' => $order->order_key,
  76. 'license_email' => $order->billing_email,
  77. '_api_software_title_parent' => empty( $software_title_parent ) ? '' : (string) $software_title_parent,
  78. '_api_software_title_var' => empty( $software_title_var ) ? '' : (string) $software_title_var,
  79. 'software_title' => empty( $software_title ) ? '' : (string) $software_title,
  80. 'parent_product_id' => empty( $item_product_id ) ? '' : (int) $item_product_id,
  81. 'variable_product_id' => empty( $item_variation_id ) ? '' : (int) $item_variation_id,
  82. 'current_version' => empty( $meta_var['_api_new_version'][0] ) ? '' : (string) $meta_var['_api_new_version'][0],
  83. '_api_activations' => empty( $meta_var['_api_activations'][0] ) ? '' : (int) $meta_var['_api_activations'][0],
  84. '_api_activations_parent' => '',
  85. '_api_update_permission' => 'yes',
  86. 'is_variable_product' => 'yes',
  87. 'license_type' => '',
  88. 'expires' => '',
  89. )
  90. );
  91. self::save_order_complete_user_meta( $meta_data, $order->order_key );
  92. }
  93. }
  94. } else { // end if Software Add-on is activated
  95. for ( $i = 0; $i < $quantity; $i++ ) {
  96. // Saves meta data for this order to be used by the API Manager if order_key is required
  97. $meta_data =
  98. array( $order->order_key =>
  99. array(
  100. 'user_id' => $order->user_id,
  101. 'order_id' => $order_id,
  102. 'order_key' => $order->order_key,
  103. 'license_email' => $order->billing_email,
  104. '_api_software_title_parent' => empty( $software_title_parent ) ? '' : (string) $software_title_parent,
  105. '_api_software_title_var' => empty( $software_title_var ) ? '' : (string) $software_title_var,
  106. 'software_title' => empty( $software_title ) ? '' : (string) $software_title,
  107. 'parent_product_id' => empty( $item_product_id ) ? '' : (int) $item_product_id,
  108. 'variable_product_id' => empty( $item_variation_id ) ? '' : (int) $item_variation_id,
  109. 'current_version' => empty( $meta_var['_api_new_version'][0] ) ? '' : (string) $meta_var['_api_new_version'][0],
  110. '_api_activations' => empty( $meta_var['_api_activations'][0] ) ? '' : (int) $meta_var['_api_activations'][0],
  111. '_api_activations_parent' => '',
  112. '_api_update_permission' => 'yes',
  113. 'is_variable_product' => 'yes',
  114. 'license_type' => '',
  115. 'expires' => '',
  116. )
  117. );
  118. self::save_order_complete_user_meta( $meta_data, $order->order_key );
  119. }
  120. }
  121. } // end if is_software
  122. } else { // end if variable product
  123. // Start if simple product
  124. $meta = get_post_custom( $item_product_id );
  125. $meta_var = get_post_custom( $item_variation_id );
  126. if ( $meta['_downloadable'][0] == 'yes' || $meta_var['_downloadable'][0] == 'yes' ) {
  127. $quantity = isset( $item['item_meta']['_qty'][0] ) ? absint( $item['item_meta']['_qty'][0] ) : 1;
  128. /**
  129. * If the parent product has a tile else use the variable product title
  130. */
  131. if ( isset( $meta['_api_software_title_parent'][0] ) && $meta['_api_software_title_parent'][0] != '' && ! empty( $meta['_api_software_title_parent'][0] ) ) {
  132. $software_title_parent = $meta['_api_software_title_parent'][0];
  133. $software_title = $meta['_api_software_title_parent'][0];
  134. } else if ( isset( $meta_var['_api_software_title_var'][0] ) && $meta_var['_api_software_title_var'][0] != '' && ! empty( $meta_var['_api_software_title_var'][0] ) ) {
  135. $software_title_var = $meta_var['_api_software_title_var'][0];
  136. $software_title = $meta_var['_api_software_title_var'][0];
  137. } else {
  138. $software_title = '';
  139. }
  140. if ( get_option( 'wc_api_manager_software_add_on_license_key' ) == 'yes' && self::is_plugin_active( 'woocommerce-software-add-on/woocommerce-software.php' ) ) {
  141. // Get the order_id
  142. $lic_order_id = $wpdb->get_var( $wpdb->prepare( "
  143. SELECT order_id FROM {$wpdb->prefix}woocommerce_software_licences
  144. WHERE order_id = %d
  145. LIMIT 1
  146. ", $order_id ) );
  147. // verify the license has been created before continuing
  148. if ( $lic_order_id ) {
  149. for ( $i = 0; $i < $quantity; $i++ ) {
  150. $data = array(
  151. 'order_id' => $order_id,
  152. 'activations_limit' => empty( $meta['_api_activations_parent'][0] ) ? '' : (int) $meta['_api_activations_parent'][0],
  153. 'software_title' => empty( $software_title ) ? '' : (string) $software_title,
  154. 'current_version' => empty( $meta['_api_new_version'][0] ) ? '' : (string) $meta['_api_new_version'][0],
  155. );
  156. self::update_licence_key( $data );
  157. // Saves meta data for this order to be used by the API Manager if Software Add-on license is required
  158. $meta_data =
  159. array( $order->order_key =>
  160. array(
  161. 'user_id' => $order->user_id,
  162. 'order_id' => $order_id,
  163. 'order_key' => $order->order_key,
  164. 'license_email' => $order->billing_email,
  165. '_api_software_title_parent' => empty( $software_title_parent ) ? '' : (string) $software_title_parent,
  166. '_api_software_title_var' => empty( $software_title_var ) ? '' : (string) $software_title_var,
  167. 'software_title' => empty( $software_title ) ? '' : (string) $software_title,
  168. 'parent_product_id' => empty( $item_product_id ) ? '' : (int) $item_product_id,
  169. 'variable_product_id' => empty( $item_variation_id ) ? '' : (int) $item_variation_id,
  170. 'current_version' => empty( $meta['_api_new_version'][0] ) ? '' : (string) $meta['_api_new_version'][0],
  171. '_api_activations' => '',
  172. '_api_activations_parent' => empty( $meta['_api_activations_parent'][0] ) ? '' : (int) $meta['_api_activations_parent'][0],
  173. '_api_update_permission' => 'yes',
  174. 'is_variable_product' => 'no',
  175. 'license_type' => '',
  176. 'expires' => '',
  177. )
  178. );
  179. self::save_order_complete_user_meta( $meta_data, $order->order_key );
  180. }
  181. }
  182. } else { // end if Software Add-on is activated
  183. for ( $i = 0; $i < $quantity; $i++ ) {
  184. // Saves meta data for this order to be used by the API Manager if order_key is required
  185. $meta_data =
  186. array( $order->order_key =>
  187. array(
  188. 'user_id' => $order->user_id,
  189. 'order_id' => $order_id,
  190. 'order_key' => $order->order_key,
  191. 'license_email' => $order->billing_email,
  192. '_api_software_title_parent' => empty( $software_title_parent ) ? '' : (string) $software_title_parent,
  193. '_api_software_title_var' => empty( $software_title_var ) ? '' : (string) $software_title_var,
  194. 'software_title' => empty( $software_title ) ? '' : (string) $software_title,
  195. 'parent_product_id' => empty( $item_product_id ) ? '' : (int) $item_product_id,
  196. 'variable_product_id' => empty( $item_variation_id ) ? '' : (int) $item_variation_id,
  197. 'current_version' => empty( $meta['_api_new_version'][0] ) ? '' : (string) $meta['_api_new_version'][0],
  198. '_api_activations' => '',
  199. '_api_activations_parent' => empty( $meta['_api_activations_parent'][0] ) ? '' : (int) $meta['_api_activations_parent'][0],
  200. '_api_update_permission' => 'yes',
  201. 'is_variable_product' => 'no',
  202. 'license_type' => '',
  203. 'expires' => '',
  204. )
  205. );
  206. self::save_order_complete_user_meta( $meta_data, $order->order_key );
  207. }
  208. }
  209. } // end if is_software
  210. } // end if is not a variable product
  211. }
  212. }
  213. }
  214. /**
  215. * update_licence_key function.
  216. *
  217. * Updates the number of activations per license key according to the API Manager settings
  218. *
  219. * @access public
  220. * @return void
  221. */
  222. public static function update_licence_key( $data ) {
  223. global $wpdb;
  224. $order_id = $data['order_id'];
  225. $activations = $data['activations_limit'];
  226. $product_id = $data['software_title'];
  227. $software_version = $data['current_version'];
  228. $sql =
  229. "
  230. UPDATE {$wpdb->prefix}woocommerce_software_licences
  231. SET activations_limit = %d,
  232. software_product_id = %s,
  233. software_version = %s
  234. WHERE order_id = %d
  235. LIMIT 1
  236. ";
  237. $wpdb->query( $wpdb->prepare( $sql, $activations, $product_id, $software_version, $order_id ) );
  238. }
  239. /**
  240. * update_licence_key function.
  241. *
  242. * Adds user_meta info for download permissions query to the database
  243. *
  244. * @access public
  245. * @return void
  246. */
  247. public static function save_order_complete_user_meta( $data, $order_key ) {
  248. global $wpdb;
  249. $current_info = self::get_users_data( $data[$order_key]['user_id'] );
  250. $new_info = self::array_merge_recursive_associative( $data, $current_info );
  251. update_user_meta( $data[$order_key]['user_id'], $wpdb->get_blog_prefix() . self::$user_meta_key_orders, $new_info );
  252. }
  253. /**
  254. * Gets the user order info stored in an array for the $user_id, aka $object_id
  255. *
  256. * @since 1.1
  257. * @param $user_id int
  258. * @return array
  259. */
  260. public static function get_users_data( $user_id = 0 ) {
  261. global $wpdb;
  262. if ( $user_id === 0 ) {
  263. $data = array();
  264. return $data;
  265. }
  266. $data = get_metadata( 'user', $user_id, $wpdb->get_blog_prefix() . self::$user_meta_key_orders, true );
  267. if( empty( $data ) )
  268. $data = array();
  269. return $data;
  270. }
  271. /**
  272. * Gets the order info from the postmeta table with the $post_id, aka $object_id
  273. *
  274. * @since 1.1
  275. * @param $user_id int
  276. * @return array
  277. */
  278. public function get_postmeta_data( $post_id = 0 ) {
  279. global $wpdb;
  280. if ( $post_id === 0 ) {
  281. $data = array();
  282. return $data;
  283. }
  284. $data = get_metadata( 'post', $post_id, '', true );
  285. if( empty( $data ) )
  286. $data = array();
  287. return $data;
  288. }
  289. /**
  290. * Gets the user order info stored in an array for the $user_id, aka $object_id
  291. *
  292. * @since 1.1
  293. * @param $user_id int
  294. * @return array
  295. */
  296. public function get_users_activation_data( $user_id = 0, $order_key = 0 ) {
  297. global $wpdb;
  298. if ( $user_id === 0 ) {
  299. $data = array();
  300. return $data;
  301. }
  302. if ( $order_key === 0 ) {
  303. $data = array();
  304. return $data;
  305. }
  306. $data = get_metadata( 'user', $user_id, $wpdb->get_blog_prefix() . self::$user_meta_key_activations . $order_key, true );
  307. if( empty( $data ) )
  308. $data = array();
  309. return $data;
  310. }
  311. /**
  312. * renew_subscription_order_complete function.
  313. *
  314. * Creates license key for renewed subscription orders.
  315. *
  316. * @access public
  317. * @return void
  318. */
  319. public static function renew_subscription_order_complete( $order_id ) {
  320. global $wpdb;
  321. $order = new WC_Order( $order_id );
  322. if ( count( $order->get_items() ) > 0 ) {
  323. foreach ( $order->get_items() as $item ) {
  324. $item_product_id = ( isset( $item['product_id'] ) ) ? $item['product_id'] : $item['id'];
  325. if ( $item_product_id > 0 ) {
  326. $meta = get_post_custom( $item_product_id );
  327. $quantity = isset( $item['item_meta']['_qty'][0] ) ? absint( $item['item_meta']['_qty'][0] ) : 1;
  328. for ( $i = 0; $i < $quantity; $i++ ) {
  329. $data = array(
  330. 'order_id' => $order_id,
  331. 'activation_email' => $order->billing_email,
  332. 'prefix' => empty( $meta['_software_license_key_prefix'][0] ) ? '' : $meta['_software_license_key_prefix'][0],
  333. 'software_product_id' => empty( $meta['_software_product_id'][0] ) ? '' : $meta['_software_product_id'][0],
  334. 'software_version' => empty( $meta['_software_version'][0] ) ? '' : $meta['_software_version'][0],
  335. 'activations_limit' => empty( $meta['_software_activations'][0] ) ? '' : (int) $meta['_software_activations'][0],
  336. );
  337. $key_id = self::save_licence_key( $data );
  338. }
  339. }
  340. }
  341. }
  342. update_post_meta( $order_id, 'software_processed', 1);
  343. }
  344. /**
  345. * save_licence_key function.
  346. *
  347. * @access public
  348. * @return void
  349. */
  350. function save_licence_key( $data ) {
  351. global $wpdb;
  352. $defaults = array(
  353. 'order_id' => '',
  354. 'activation_email' => '',
  355. 'prefix' => '',
  356. 'licence_key' => self::generate_licence_key(),
  357. 'software_product_id' => '',
  358. 'software_version' => '',
  359. 'activations_limit' => '',
  360. 'created' => current_time( 'mysql' )
  361. );
  362. $data = wp_parse_args( $data, $defaults );
  363. $insert = array(
  364. 'order_id' => $data['order_id'],
  365. 'activation_email' => $data['activation_email'],
  366. 'licence_key' => $data['prefix'] . $data['licence_key'],
  367. 'software_product_id' => $data['software_product_id'],
  368. 'software_version' => $data['software_version'],
  369. 'activations_limit' => $data['activations_limit'],
  370. 'created' => $data['created']
  371. );
  372. $format = array(
  373. '%s',
  374. '%s',
  375. '%s',
  376. '%s',
  377. '%s',
  378. '%s',
  379. '%s',
  380. '%s'
  381. );
  382. $wpdb->insert( $wpdb->prefix . 'woocommerce_software_licences',
  383. $insert,
  384. $format
  385. );
  386. return $wpdb->insert_id;
  387. }
  388. /**
  389. * generates a unique id that is used as the license code
  390. *
  391. * @since 1.0
  392. * @return string the unique ID
  393. */
  394. function generate_licence_key() {
  395. return sprintf(
  396. '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
  397. mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
  398. mt_rand( 0, 0x0fff ) | 0x4000,
  399. mt_rand( 0, 0x3fff ) | 0x8000,
  400. mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  401. );
  402. }
  403. /**
  404. * Find post_id that matches api_key and activation_email
  405. *
  406. * @access public
  407. * @param mixed license_key
  408. * @param mixed activation_email
  409. * @return integer $post_id which is the same as the product_id
  410. */
  411. public function get_post_id( $api_key, $activation_email ) {
  412. global $wpdb;
  413. $order_id = $wpdb->get_var( $wpdb->prepare( "
  414. SELECT order_id FROM {$wpdb->prefix}woocommerce_software_licences
  415. WHERE licence_key = %s
  416. AND activation_email = %s LIMIT 1
  417. ", $api_key, $activation_email ) );
  418. $post_id = $wpdb->get_var( $wpdb->prepare( "
  419. SELECT product_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
  420. WHERE order_id = %s
  421. LIMIT 1
  422. ", $order_id ) );
  423. if ( ! $post_id ) return false;
  424. return $post_id;
  425. }
  426. /**
  427. * Find order_id that matches api_key and activation_email
  428. *
  429. * @access public
  430. * @param mixed license_key
  431. * @param mixed activation_email
  432. * @return integer $order_id
  433. */
  434. public function get_order_id( $api_key, $activation_email ) {
  435. global $wpdb;
  436. $order_id = $wpdb->get_var( $wpdb->prepare( "
  437. SELECT order_id FROM {$wpdb->prefix}woocommerce_software_licences
  438. WHERE licence_key = %s
  439. AND activation_email = %s LIMIT 1
  440. ", $api_key, $activation_email ) );
  441. if ( ! $order_id ) return false;
  442. return $order_id;
  443. }
  444. /**
  445. * Find post_id which can match a purchase ID or a product ID
  446. *
  447. * @access public
  448. * @param mixed meta_key
  449. * @param mixed meta_value
  450. * @return integer $post_id which is the same as the product_id
  451. */
  452. public function get_post_id_by( $meta_key, $meta_value ) {
  453. global $wpdb;
  454. $post_id = $wpdb->get_var( $wpdb->prepare( "
  455. SELECT post_id FROM {$wpdb->postmeta}
  456. WHERE meta_key = %s
  457. AND meta_value = %s LIMIT 1
  458. ", $meta_key, $meta_value ) );
  459. if ( ! $post_id ) return false;
  460. return $post_id;
  461. }
  462. /**
  463. * Find file download id (am_key)
  464. *
  465. * @access public
  466. * @param $post_id (integer)
  467. * @return array $download_id (limited to first value in array)
  468. */
  469. public function get_download_id( $post_id ) {
  470. $file_path = get_post_meta( $post_id, '_file_paths', true );
  471. if ( is_array( $file_path ) ) {
  472. foreach ( $file_path as $key => $value ) {
  473. $path[] = $key;
  474. }
  475. }
  476. if ( ! $path[0] ) return false;
  477. return $path[0];
  478. }
  479. /**
  480. * Find file download path, or download link, usually the same value
  481. *
  482. * @access public
  483. * @param mixed $software_product_id, i.e. Simple Comments, or $post->ID if Software add-on not installed
  484. * @return array $file_path (limited to first value in array)
  485. */
  486. public function get_file_path( $software_product_id, $software_add_on = true ) {
  487. if ( $software_add_on ) { // use the product id, i.e. Simple Comments
  488. $product_id = self::get_post_id( $software_product_id );
  489. if ( ! $product_id ) return false;
  490. $file_path = get_post_meta( $product_id, '_file_paths', true );
  491. } else { // use post->ID
  492. $file_path = get_post_meta( $software_product_id, '_file_paths', true );
  493. }
  494. if ( is_array( $file_path ) ) {
  495. foreach ( $file_path as $key => $value ) {
  496. $path[] = $value;
  497. }
  498. }
  499. if ( ! $path[0] ) return false;
  500. return $path[0];
  501. }
  502. /**
  503. * verify_licence_key function.
  504. *
  505. * @access public
  506. * @param mixed $api_key
  507. * @param mixed $activation_email
  508. * @return bool
  509. */
  510. public function verify_license_key( $api_key, $activation_email ) {
  511. global $wpdb;
  512. $sql =
  513. "
  514. SELECT licence_key FROM {$wpdb->prefix}woocommerce_software_licences
  515. WHERE licence_key = %s
  516. AND activation_email = %s
  517. LIMIT 1
  518. ";
  519. $key = $wpdb->get_var( $wpdb->prepare( $sql, $api_key, $activation_email ) );
  520. if ( $key == $api_key )
  521. return true;
  522. return false;
  523. }
  524. /**
  525. * get_order_number function.
  526. *
  527. * @access public
  528. * @param mixed $api_key
  529. * @param mixed $activation_email
  530. * @return string
  531. */
  532. public function get_order_number( $api_key, $activation_email ) {
  533. global $wpdb;
  534. $order_id = $wpdb->get_var( $wpdb->prepare( "
  535. SELECT order_id FROM {$wpdb->prefix}woocommerce_software_licences
  536. WHERE licence_key = %s
  537. AND activation_email = %s
  538. LIMIT 1
  539. ", $api_key, $activation_email ) );
  540. $order_number = $wpdb->get_var( $wpdb->prepare( "
  541. SELECT meta_value FROM {$wpdb->postmeta}
  542. WHERE post_id = %s
  543. AND meta_key = '_order_key'
  544. LIMIT 1
  545. ", $order_id ) );
  546. return $order_number;
  547. }
  548. /**
  549. * download_count function.
  550. *
  551. * @access public
  552. * @param mixed $order_id
  553. * @param mixed $order_key
  554. * @return integer or boolean
  555. */
  556. public function get_download_count( $order_id, $order_key ) {
  557. global $wpdb;
  558. $download_count = $wpdb->get_var( $wpdb->prepare( "
  559. SELECT download_count FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
  560. WHERE order_id = %s
  561. AND order_key = %s
  562. LIMIT 1
  563. ", $order_id, $order_key ) );
  564. if ( isset( $download_count ) )
  565. return $download_count;
  566. return false;
  567. }
  568. /**
  569. * create_url function to properly format download url
  570. *
  571. * @access public
  572. * @param mixed $api_key
  573. * @param mixed $activation_email
  574. * @param mixed $product_id
  575. * @return url + query string
  576. */
  577. public function create_url( $api_key, $activation_email, $product_id, $download_id = '' ) {
  578. global $wpdb;
  579. if ( stristr( $api_key, 'order_') ) {
  580. $order_key = $api_key;
  581. } else if ( self::is_plugin_active( 'woocommerce-software-add-on/woocommerce-software.php' ) ) {
  582. $order_key = self::get_order_number( $api_key, $activation_email );
  583. }
  584. $sql = "
  585. SELECT product_id,order_id,downloads_remaining,user_id,download_count,access_expires,download_id
  586. FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
  587. WHERE user_email = %s
  588. AND order_key = %s
  589. AND product_id = %s";
  590. $args = array(
  591. $activation_email,
  592. $order_key,
  593. $product_id
  594. );
  595. if ( $download_id ) {
  596. // backwards compatibility for existing download URLs
  597. $sql .= " AND download_id = %s";
  598. $args[] = $download_id;
  599. }
  600. //$result = $wpdb->get_row( $wpdb->prepare( $sql, $args ), ARRAY_A );
  601. $result = $wpdb->get_row( $wpdb->prepare( $sql, $args ) );
  602. //$result = get_object_vars( $download_result );
  603. /**
  604. * Since adding the ARRAY_A flag an associative array is returned rather than an object
  605. *
  606. * $download_result returns:
  607. * stdClass Object
  608. * (
  609. * [product_id] =>
  610. * [order_id] =>
  611. * [downloads_remaining] =>
  612. * [user_id] =>
  613. * [download_count] =>
  614. * [access_expires] =>
  615. * [download_id] =>
  616. * )
  617. * get_object_vars() puts oject into an array
  618. */
  619. $url_args = array(
  620. 'am_download_file' => $result->product_id,
  621. 'am_order' => $order_key,
  622. 'am_email' => $activation_email,
  623. );
  624. if ( $result->download_id != '' ) {
  625. $url_args['am_key'] = $result->download_id;
  626. }
  627. return site_url() . '/?' . http_build_query( $url_args, '', '&' );
  628. }
  629. /**
  630. * Checks if a plugin is activated
  631. *
  632. * @since 1.1
  633. */
  634. public static function is_plugin_active( $slug ) {
  635. $active_plugins = (array) get_option( 'active_plugins', array() );
  636. if ( is_multisite() )
  637. $active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', array() ) );
  638. return in_array( $slug, $active_plugins ) || array_key_exists( $slug, $active_plugins );
  639. }
  640. /**
  641. * Checks if page content exists
  642. *
  643. * @since 1.1
  644. */
  645. public function get_page_content( $page_obj ) {
  646. if ( isset( $page_obj ) && is_object( $page_obj ) ) {
  647. if ( ! empty( $page_obj->post_content ) ) {
  648. return $page_obj->post_content;
  649. } else {
  650. return '';
  651. }
  652. } else {
  653. return '';
  654. }
  655. }
  656. /**
  657. * Merges arrays recursively with an associative key
  658. * To merge arrays that are numerically indexed use the PHP array_merge_recursive() function
  659. *
  660. * @since 1.1
  661. * @param $array1 Array
  662. * @param $array2 Array
  663. * @return array
  664. */
  665. public static function array_merge_recursive_associative( $array1, $array2 ) {
  666. $merged_arrays = $array1;
  667. if ( is_array( $array2 ) ) {
  668. foreach ( $array2 as $key => $val ) {
  669. if ( is_array( $array2[$key] ) ) {
  670. $merged_arrays[$key] = ( isset( $merged_arrays[$key] ) && is_array( $merged_arrays[$key] ) ) ? self::array_merge_recursive_associative( $merged_arrays[$key], $array2[$key] ) : $array2[$key];
  671. } else {
  672. $merged_arrays[$key] = $val;
  673. }
  674. }
  675. }
  676. return $merged_arrays;
  677. }
  678. /**
  679. * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
  680. * keys to arrays rather than overwriting the value in the first array with the duplicate
  681. * value in the second array, as array_merge does. I.e., with array_merge_recursive,
  682. * this happens (documented behavior):
  683. *
  684. * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
  685. * => array('key' => array('org value', 'new value'));
  686. *
  687. * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
  688. * Matching keys' values in the second array overwrite those in the first array, as is the
  689. * case with array_merge, i.e.:
  690. *
  691. * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
  692. * => array('key' => array('new value'));
  693. *
  694. * Parameters are passed by reference, though only for performance reasons. They're not
  695. * altered by this function.
  696. *
  697. * @param array $array1
  698. * @param array $array2
  699. * @return array
  700. * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
  701. * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
  702. * @since 1.1.1
  703. */
  704. public function array_merge_recursive_distinct ( array &$array1, array &$array2 ) {
  705. $merged = $array1;
  706. foreach ( $array2 as $key => &$value ) {
  707. if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) ) {
  708. $merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
  709. } else {
  710. $merged [$key] = $value;
  711. }
  712. }
  713. return $merged;
  714. }
  715. /**
  716. * Experimental
  717. * @since 1.1.1
  718. * @param [type] $needle [description]
  719. * @param [type] $haystack [description]
  720. * @param boolean $strict [description]
  721. * @return [type] [description]
  722. */
  723. public function in_array_recursive( $needle, $haystack, $strict = false ) {
  724. foreach ( $haystack as $item ) {
  725. if ( ( $strict ? $item === $needle : $item == $needle ) || ( is_array( $item ) && self::in_array_recursive( $needle, $item, $strict ) ) ) {
  726. return true;
  727. }
  728. }
  729. return false;
  730. }
  731. /**
  732. * Removes element from array based on key
  733. * @since 1.1
  734. * @return array New array minus removed elements
  735. *
  736. * For example:
  737. *
  738. * $fruit_inventory = array(
  739. * 'apples' => 52,
  740. * 'bananas' => 78,
  741. * 'peaches' => 'out of season',
  742. * 'pears' => 'out of season',
  743. * 'oranges' => 'no longer sold',
  744. * 'carrots' => 15,
  745. * 'beets' => 15,
  746. * );
  747. *
  748. * $fruit_inventory = array_remove_by_key($fruit_inventory,
  749. * "beets",
  750. * "carrots");
  751. */
  752. public function array_remove_by_key() {
  753. $args = func_get_args();
  754. return array_diff_key( $args[0], array_flip( array_slice( $args, 1 ) ) );
  755. }
  756. /**
  757. * Removes element from array based on value
  758. * @since 1.1
  759. * @return array New array minus removed elements
  760. * For example:
  761. *
  762. * $fruit_inventory = array(
  763. * 'apples' => 52,
  764. * 'bananas' => 78,
  765. * 'peaches' => 'out of season',
  766. * 'pears' => 'out of season',
  767. * 'oranges' => 'no longer sold',
  768. * 'carrots' => 15,
  769. * 'beets' => 15,
  770. * );
  771. *
  772. * $fruit_inventory = array_remove_by_value($fruit_inventory,
  773. * "out of season",
  774. * "no longer sold");
  775. */
  776. public function array_remove_by_value() {
  777. $args = func_get_args();
  778. return array_diff( $args[0], array_slice( $args, 1 ) );
  779. }
  780. /**
  781. * array_search_multi Finds if a value matched with a needle exists in a multidimensional array
  782. * @param array $array multidimensional array (for simple array use array_search)
  783. * @param mixed $value value to search for
  784. * @param mixed $needle needle that needs to match value in array
  785. * @since 1.1.1
  786. * @return boolean
  787. */
  788. public function array_search_multi( $array, $value, $needle ) {
  789. foreach( $array as $index_key => $value_key ) {
  790. if ( $value_key[$value] === $needle ) return true;
  791. }
  792. return false;
  793. }
  794. /**
  795. * get_array_search_multi Finds a key for a value matched by a needle in a multidimensional array
  796. * @param array $array multidimensional array (for simple array use array_search)
  797. * @param mixed $value value to search for
  798. * @param mixed $needle needle that needs to match value in array
  799. * @since 1.1.1
  800. * @return mixed
  801. */
  802. public function get_key_array_search_multi( $array, $value, $needle ) {
  803. foreach( $array as $index_key => $value_key ) {
  804. if ( $value_key[$value] === $needle ) return $value_key;
  805. }
  806. return false;
  807. }
  808. /**
  809. * Gets the status of a checkbox
  810. *
  811. * @since 1.1
  812. * @param $product_id int
  813. * @param $meta_key string
  814. * @return boolean
  815. */
  816. public function get_product_checkbox_status( $post_id, $meta_key ) {
  817. $result = get_post_meta( $post_id, $meta_key, true );
  818. if ( $result == 'yes' )
  819. return true;
  820. else
  821. return false;
  822. }
  823. /**
  824. * get_order_info_by_email_with_order_key Gets the user order info
  825. * @param string $activation_email license email
  826. * @param string $order_key order key
  827. * @return array array populated with user purchase info
  828. */
  829. public function get_order_info_by_email_with_order_key( $activation_email, $order_key ) {
  830. if ( isset( $activation_email ) )
  831. $user = get_user_by( 'email', $activation_email ); // returns $user->ID
  832. else
  833. return false;
  834. if ( ! is_object( $user ) ) return false;
  835. // Check if this is an order_key
  836. if ( isset( $order_key ) && stristr( $order_key, 'order_') ) {
  837. $user_orders = self::get_users_data( $user->ID );
  838. if ( isset( $user_orders ) && ! empty( $user_orders ) )
  839. return $user_orders[$order_key]; // returns a single order info array identified by order_key
  840. else
  841. return false;
  842. }
  843. return false;
  844. }
  845. /**
  846. * Determine subscription status using order_id = post_id
  847. *
  848. * For Suscriptions > 1.4
  849. *
  850. * @access public
  851. * @param int order_id
  852. * @since 1.1.1
  853. * @return string subscription status
  854. */
  855. public function get_subscription_status( $order_id ) {
  856. global $wpdb;
  857. $order_item_id = $wpdb->get_var( $wpdb->prepare( "
  858. SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items
  859. WHERE order_id = %d
  860. LIMIT 1
  861. ", $order_id ) );
  862. $status = $wpdb->get_var( $wpdb->prepare( "
  863. SELECT meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta
  864. WHERE order_item_id = %d
  865. AND meta_key = %s LIMIT 1
  866. ", $order_item_id, '_subscription_status' ) );
  867. if ( isset( $status ) && ! empty( $status ) )
  868. return $status;
  869. else
  870. return false;
  871. }
  872. /**
  873. * Nonce URL
  874. * @param mixed $args string or array
  875. * @see http://codex.wordpress.org/Function_Reference/add_query_arg
  876. * @return string
  877. * @since 1.2.1
  878. */
  879. public function nonce_url( $args ) {
  880. $action_url = wp_nonce_url( add_query_arg( $args ) );
  881. return $action_url;
  882. }
  883. /**
  884. * Finds the default order_ prefix or a unique prefix that was created
  885. * by the woocommerce_generate_order_key filter
  886. *
  887. * example $uniqid = $this->get_uniqid_prefix( $product_post_meta['_order_key'][0], '_' );
  888. *
  889. * @access public
  890. * @param mixed $haystack
  891. * @param mixed $needle
  892. * @return mixed
  893. */
  894. public function get_uniqid_prefix( $haystack, $needle ) {
  895. $pos = stripos( $haystack, $needle ) + 1;
  896. return trim( substr( $haystack, 0, $pos ) );
  897. }
  898. /**
  899. * Allows the customer to delete a domain name activated for an order on their My Account dashbaord
  900. * @return void or error message
  901. * @since 1.2.1
  902. */
  903. public static function delete_my_account_url() {
  904. global $woocommerce, $wpdb, $wc_api_manager_helpers, $woocommerce_plugin_update_api_manager;
  905. if ( isset( $_GET['domain'] ) && isset( $_GET['instance'] ) && isset( $_GET['order_key'] ) && isset( $_GET['user_id'] ) && isset( $_GET['_wpnonce'] ) ) {
  906. if ( wp_verify_nonce( $_GET['_wpnonce'] ) === false )
  907. $woocommerce->add_error( __( 'The domain name could not be deleted.', $woocommerce_plugin_update_api_manager->text_domain ) );
  908. $domain = sanitize_text_field( $_GET['domain'] );
  909. $instance = sanitize_text_field( $_GET['instance'] );
  910. $order_key = sanitize_text_field( $_GET['order_key'] );
  911. $user_id = intval( $_GET['user_id'] );
  912. $current_info = self::get_users_activation_data( $user_id, $order_key );
  913. if ( ! empty( $current_info ) ) {
  914. $active_activations = 0;
  915. foreach ( $current_info as $key => $activations ) {
  916. if ( $activations['activation_active'] == 1 && $order_key == $activations['order_key'] ) {
  917. $active_activations++;
  918. }
  919. }
  920. foreach ( $current_info as $key => $activation_info ) {
  921. if ( $active_activations <= 1 && $activation_info['activation_active'] == 1 && $activation_info['instance'] == $instance && $activation_info['activation_domain'] == $domain ) {
  922. delete_user_meta( $user_id, $wpdb->get_blog_prefix() . self::$user_meta_key_activations . $order_key );
  923. wp_safe_redirect( get_permalink( woocommerce_get_page_id( 'myaccount' ) ) );
  924. break;
  925. exit();
  926. } else if ( $activation_info['activation_active'] == 1 && $activation_info['activation_active'] == 1 && $activation_info['instance'] == $instance && $activation_info['activation_domain'] == $domain ) {
  927. // Delete the activation data array
  928. unset( $current_info[$key] );
  929. // Re-index the numerical array keys:
  930. $new_info = array_values( $current_info );
  931. update_user_meta( $user_id, $wpdb->get_blog_prefix() . self::$user_meta_key_activations . $order_key, $new_info );
  932. wp_safe_redirect( get_permalink( woocommerce_get_page_id( 'myaccount' ) ) );
  933. break;
  934. exit();
  935. }
  936. } // end foreach
  937. }
  938. }
  939. }
  940. /**
  941. * Download a file - hook into init function.
  942. * variation of woocommerce_download_product() function
  943. *
  944. * No login required for Plugin Updates since authentication is handled by the APIs
  945. * Download restrictions controlled by WooCommerce order screen
  946. *
  947. * @access public
  948. * @return void
  949. */
  950. public static function download_product() {
  951. global $woocommerce_plugin_update_api_manager;
  952. if ( isset( $_GET['am_download_file'] ) && isset( $_GET['am_order'] ) && isset( $_GET['am_email'] ) ) {
  953. global $wpdb, $is_IE;
  954. $product_id = (int) urldecode($_GET['am_download_file']);
  955. $order_key = urldecode( $_GET['am_order'] );
  956. $email = sanitize_email( str_replace( ' ', '+', urldecode( $_GET['am_email'] ) ) );
  957. $download_id = isset( $_GET['am_key'] ) ? preg_replace( '/\s+/', ' ', urldecode( $_GET['am_key'] ) ) : '';
  958. $_product = get_product( $product_id );
  959. $file_download_method = apply_filters( 'woocommerce_file_download_method', get_option( 'woocommerce_file_download_method' ), $product_id );
  960. if ( ! is_email( $email) )
  961. wp_die( __( 'Invalid email address.', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  962. $query = "
  963. SELECT order_id,downloads_remaining,user_id,download_count,access_expires,download_id
  964. FROM " . $wpdb->prefix . "woocommerce_downloadable_product_permissions
  965. WHERE user_email = %s
  966. AND order_key = %s
  967. AND product_id = %s";
  968. $args = array(
  969. $email,
  970. $order_key,
  971. $product_id
  972. );
  973. if ( $download_id ) {
  974. // backwards compatibility for existing download URLs
  975. $query .= " AND download_id = %s";
  976. $args[] = $download_id;
  977. }
  978. $download_result = $wpdb->get_row( $wpdb->prepare( $query, $args ) );
  979. if ( ! $download_result )
  980. wp_die( __( 'Invalid download.', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="'.home_url().'">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  981. $download_id = $download_result->download_id;
  982. $order_id = $download_result->order_id;
  983. $downloads_remaining = $download_result->downloads_remaining;
  984. $download_count = $download_result->download_count;
  985. $user_id = $download_result->user_id;
  986. $access_expires = $download_result->access_expires;
  987. // if ( $user_id && get_option( 'woocommerce_downloads_require_login' ) == 'yes' ) {
  988. // if ( ! is_user_logged_in() )
  989. // wp_die( __( 'You must be logged in to download files.', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="' . wp_login_url( get_permalink( woocommerce_get_page_id( 'myaccount' ) ) ) . '">' . __( 'Login &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  990. // elseif ( $user_id != get_current_user_id() )
  991. // wp_die( __( 'This is not your download link.', $woocommerce_plugin_update_api_manager->text_domain ) );
  992. // }
  993. if ( ! get_post( $product_id ) )
  994. wp_die( __( 'Product no longer exists.', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  995. if ( $order_id ) {
  996. $order = new WC_Order( $order_id );
  997. if ( ! $order->is_download_permitted() || $order->post_status != 'publish' )
  998. wp_die( __( 'Invalid order.', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  999. }
  1000. if ( $downloads_remaining == '0' )
  1001. wp_die( __( 'Sorry, you have reached your download limit for this file', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="'.home_url().'">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  1002. if ( $access_expires > 0 && strtotime( $access_expires) < current_time( 'timestamp' ) )
  1003. wp_die( __( 'Sorry, this download has expired', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  1004. if ( $downloads_remaining > 0 ) {
  1005. $wpdb->update( $wpdb->prefix . "woocommerce_downloadable_product_permissions", array(
  1006. 'downloads_remaining' => $downloads_remaining - 1,
  1007. ), array(
  1008. 'user_email' => $email,
  1009. 'order_key' => $order_key,
  1010. 'product_id' => $product_id,
  1011. 'download_id' => $download_id
  1012. ), array( '%d' ), array( '%s', '%s', '%d', '%s' ) );
  1013. }
  1014. // Count the download
  1015. $wpdb->update( $wpdb->prefix . "woocommerce_downloadable_product_permissions", array(
  1016. 'download_count' => $download_count + 1,
  1017. ), array(
  1018. 'user_email' => $email,
  1019. 'order_key' => $order_key,
  1020. 'product_id' => $product_id,
  1021. 'download_id' => $download_id
  1022. ), array( '%d' ), array( '%s', '%s', '%d', '%s' ) );
  1023. // Trigger action
  1024. do_action( 'download_product', $email, $order_key, $product_id, $user_id, $download_id, $order_id );
  1025. // Get the download URL and try to replace the url with a path
  1026. $file_path = $_product->get_file_download_path( $download_id );
  1027. if ( ! $file_path )
  1028. wp_die( __( 'No file defined', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="'.home_url().'">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  1029. // Redirect to the file...
  1030. if ( $file_download_method == "redirect" ) {
  1031. header( 'Location: ' . $file_path );
  1032. exit;
  1033. }
  1034. // ...or serve it
  1035. if ( ! is_multisite() ) {
  1036. /*
  1037. * Download file may be either http or https.
  1038. * site_url() depends on whether the page containing the download (ie; My Account) is served via SSL because WC
  1039. * modifies site_url() via a filter to force_ssl.
  1040. * So blindly doing a str_replace is incorrect because it will fail when schemes are mismatched. This code
  1041. * handles the various permutations.
  1042. */
  1043. $scheme = parse_url( $file_path, PHP_URL_SCHEME );
  1044. if ( $scheme ) {
  1045. $site_url = set_url_scheme( site_url( '' ), $scheme );
  1046. } else {
  1047. $site_url = is_ssl() ? str_replace( 'https:', 'http:', site_url() ) : site_url();
  1048. }
  1049. $file_path = str_replace( trailingslashit( $site_url ), ABSPATH, $file_path );
  1050. } else {
  1051. $network_url = is_ssl() ? str_replace( 'https:', 'http:', network_admin_url() ) : network_admin_url();
  1052. $upload_dir = wp_upload_dir();
  1053. // Try to replace network url
  1054. $file_path = str_replace( trailingslashit( $network_url ), ABSPATH, $file_path );
  1055. // Now try to replace upload URL
  1056. $file_path = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $file_path );
  1057. }
  1058. // See if its local or remote
  1059. if ( strstr( $file_path, 'http:' ) || strstr( $file_path, 'https:' ) || strstr( $file_path, 'ftp:' ) ) {
  1060. $remote_file = true;
  1061. } else {
  1062. $remote_file = false;
  1063. // Remove Query String
  1064. if ( strstr( $file_path, '?' ) )
  1065. $file_path = current( explode( '?', $file_path ) );
  1066. $file_path = realpath( $file_path );
  1067. }
  1068. $file_extension = strtolower( substr( strrchr( $file_path, "." ), 1 ) );
  1069. $ctype = "application/force-download";
  1070. foreach ( get_allowed_mime_types() as $mime => $type ) {
  1071. $mimes = explode( '|', $mime );
  1072. if ( in_array( $file_extension, $mimes ) ) {
  1073. $ctype = $type;
  1074. break;
  1075. }
  1076. }
  1077. // Start setting headers
  1078. if ( ! ini_get('safe_mode') )
  1079. @set_time_limit(0);
  1080. if ( function_exists( 'get_magic_quotes_runtime' ) && get_magic_quotes_runtime() )
  1081. @set_magic_quotes_runtime(0);
  1082. if( function_exists( 'apache_setenv' ) )
  1083. @apache_setenv( 'no-gzip', 1 );
  1084. @session_write_close();
  1085. @ini_set( 'zlib.output_compression', 'Off' );
  1086. @ob_end_clean();
  1087. if ( ob_get_level() )
  1088. @ob_end_clean(); // Zip corruption fix
  1089. if ( $is_IE && is_ssl() ) {
  1090. // IE bug prevents download via SSL when Cache Control and Pragma no-cache headers set.
  1091. header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
  1092. header( 'Cache-Control: private' );
  1093. } else {
  1094. nocache_headers();
  1095. }
  1096. $file_name = basename( $file_path );
  1097. if ( strstr( $file_name, '?' ) )
  1098. $file_name = current( explode( '?', $file_name ) );
  1099. header( "Robots: none" );
  1100. header( "Content-Type: " . $ctype );
  1101. header( "Content-Description: File Transfer" );
  1102. header( "Content-Disposition: attachment; filename=\"" . $file_name . "\";" );
  1103. header( "Content-Transfer-Encoding: binary" );
  1104. if ( $size = @filesize( $file_path ) )
  1105. header( "Content-Length: " . $size );
  1106. if ( $file_download_method == 'xsendfile' ) {
  1107. // Path fix - kudos to Jason Judge
  1108. if ( getcwd() )
  1109. $file_path = trim( preg_replace( '`^' . getcwd() . '`' , '', $file_path ), '/' );
  1110. header( "Content-Disposition: attachment; filename=\"" . $file_name . "\";" );
  1111. if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules() ) ) {
  1112. header("X-Sendfile: $file_path");
  1113. exit;
  1114. } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) {
  1115. header( "X-Lighttpd-Sendfile: $file_path" );
  1116. exit;
  1117. } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'nginx' ) || stristr( getenv( 'SERVER_SOFTWARE' ), 'cherokee' ) ) {
  1118. header( "X-Accel-Redirect: /$file_path" );
  1119. exit;
  1120. }
  1121. }
  1122. if ( $remote_file )
  1123. @woocommerce_readfile_chunked( $file_path ) or header( 'Location: ' . $file_path );
  1124. else
  1125. @woocommerce_readfile_chunked( $file_path ) or wp_die( __( 'File not found', $woocommerce_plugin_update_api_manager->text_domain ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage &rarr;', $woocommerce_plugin_update_api_manager->text_domain ) . '</a>' );
  1126. exit;
  1127. }
  1128. }
  1129. }
  1130. $GLOBALS['wc_api_manager_helpers'] = new WC_Api_Manager_Helpers();