PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/www/wp-content/plugins/ithemes-exchange/api/shipping.php

https://github.com/ArzuA/gitwordpress
PHP | 493 lines | 213 code | 72 blank | 208 comment | 46 complexity | f7647299de9b0325a53171ce4abeb429 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * This file contains functions related to the shipping API
  4. * See also: api/shipping-features.php
  5. * @since 1.4.0
  6. * @package IT_Exchagne
  7. */
  8. /**
  9. * Register a shipping provider
  10. *
  11. * @since 1.4.0
  12. *
  13. * @param string $slug provider slug
  14. * @param array $options options for the provider
  15. * @return boolean
  16. */
  17. function it_exchange_register_shipping_provider( $slug, $options ) {
  18. // Lets just make sure the slug is in the options
  19. $options['slug'] = $slug;
  20. // Store the initiated class in our global
  21. $GLOBALS['it_exchange']['shipping']['providers'][$slug] = $options;
  22. // Return the object
  23. return true;
  24. }
  25. /**
  26. * Returns all registered shipping providers
  27. *
  28. * @since 1.4.0
  29. *
  30. * @param mixed $filtered a string or an array of strings to limit returned providers to specific providers
  31. * @return array
  32. */
  33. function it_exchange_get_registered_shipping_providers( $filtered=array() ) {
  34. $providers = empty( $GLOBALS['it_exchange']['shipping']['providers'] ) ? array() : $GLOBALS['it_exchange']['shipping']['providers'];
  35. if ( empty( $filtered ) )
  36. return $providers;
  37. foreach( (array) $filtered as $provider ) {
  38. if ( isset( $providers[$provider] ) )
  39. unset( $providers[$provider] );
  40. }
  41. return $providers;
  42. }
  43. /**
  44. * Returns a specific registered shipping provider object
  45. *
  46. * @since 1.4.0
  47. *
  48. * @param string $slug the registerd slug
  49. * @return mixed false or object
  50. */
  51. function it_exchange_get_registered_shipping_provider( $slug ) {
  52. // Return false if we don't have one registered
  53. if ( empty( $GLOBALS['it_exchange']['shipping']['providers'][$slug] ) )
  54. return false;
  55. // Retrieve the provider details
  56. $options = $GLOBALS['it_exchange']['shipping']['providers'][$slug];
  57. // Include the class
  58. include_once( dirname( dirname( __FILE__ ) ) . '/lib/shipping/class-provider.php' );
  59. // Init the class
  60. return new IT_Exchange_Shipping_Provider( $slug, $options );
  61. // Return false if no object was found
  62. return false;
  63. }
  64. /**
  65. * Is the requested shipping provider registered?
  66. *
  67. * @since 1.4.0
  68. *
  69. * @param string $slug the registerd slug
  70. * @return boolean
  71. */
  72. function it_exchange_is_shipping_provider_registered( $slug ) {
  73. return (boolean) it_exchange_get_registered_shipping_provider( $slug );
  74. }
  75. /**
  76. * Register a shipping method
  77. *
  78. * @since 1.4.0
  79. *
  80. * @param string $slug method slug
  81. * @param array $options options for the slug
  82. * @return boolean
  83. */
  84. function it_exchange_register_shipping_method( $slug, $class ) {
  85. // Validate opitons
  86. if ( ! class_exists( $class ) )
  87. return false;
  88. // Store the initiated class in our global
  89. $GLOBALS['it_exchange']['shipping']['methods'][$slug] = $class;
  90. // Return the object
  91. return true;
  92. }
  93. /**
  94. * Returns a specific registered shipping method object
  95. *
  96. * @since 1.4.0
  97. *
  98. * @param string $slug the registerd slug
  99. * @return mixed false or object
  100. */
  101. function it_exchange_get_registered_shipping_method( $slug, $product_id=false ) {
  102. // Return false if we don't have one registered
  103. if ( empty( $GLOBALS['it_exchange']['shipping']['methods'][$slug] ) )
  104. return false;
  105. // Retrieve the method class
  106. $class = $GLOBALS['it_exchange']['shipping']['methods'][$slug];
  107. // Make sure we have a class index and it corresponds to a defined class
  108. if ( empty( $class ) || ! class_exists( $class ) )
  109. return false;
  110. // Init the class
  111. return new $class( $product_id );
  112. // Return false if no object was found
  113. return false;
  114. }
  115. /**
  116. * Returns all registered shipping methods
  117. *
  118. * @since 1.4.0
  119. *
  120. * @param mixed $filtered a string or an array of strings to limit returned methods to specific methods
  121. * @return array
  122. */
  123. function it_exchange_get_registered_shipping_methods( $filtered=array() ) {
  124. $methods = empty( $GLOBALS['it_exchange']['shipping']['methods'] ) ? array() : $GLOBALS['it_exchange']['shipping']['methods'];
  125. if ( empty( $filtered ) )
  126. return $methods;
  127. foreach( (array) $filtered as $method ) {
  128. if ( isset( $methods[$method] ) )
  129. unset( $methods[$method] );
  130. }
  131. return $methods;
  132. }
  133. /**
  134. * Save the shipping address based on the User's ID
  135. *
  136. * @since 1.4.0
  137. *
  138. * @param array $address the shipping address as an array
  139. * @param int $customer_id optional. if empty, will attempt to get he current user's ID
  140. * @return boolean Will fail if no user ID was provided or found
  141. */
  142. function it_exchange_save_shipping_address( $address, $customer_id=false ) {
  143. $customer_id = empty( $customer_id ) ? it_exchange_get_current_customer_id() : $customer_id;
  144. if ( ! it_exchange_get_customer( $customer_id ) )
  145. return false;
  146. $address = apply_filters( 'it_exchange_save_customer_shipping_address', $address, $customer_id );
  147. // Add to usermeta
  148. if ( false !== $address ) {
  149. update_user_meta( $customer_id, 'it-exchange-shipping-address', $address );
  150. do_action( 'it_exchange_shipping_address_updated', $address, $customer_id );
  151. return true;
  152. }
  153. return false;
  154. }
  155. /**
  156. * Returns the value of an address field for the address form.
  157. *
  158. * @since 1.4.0
  159. *
  160. * @param string $field the form field we are looking for the value
  161. * @param int $customer_id the wp ID of the customer
  162. *
  163. * @return string
  164. */
  165. function it_exchange_print_shipping_address_value( $field, $customer_id=false ) {
  166. $customer_id = empty( $customer_id ) ? it_exchange_get_current_customer_id() : $customer_id;
  167. $saved_address = get_user_meta( $customer_id, 'it_exchange_shipping_address', true );
  168. $cart_address = it_exchange_get_cart_shipping_address();
  169. $value = empty( $saved_address[$field] ) ? '' : $saved_address[$field];
  170. $value = empty( $cart_address[$field] ) ? $value : $cart_address[$field];
  171. echo 'value="' . esc_attr( $value ) . '" ';
  172. }
  173. /**
  174. * Formats the Shipping Address for display
  175. *
  176. * @todo this function sucks. Lets make a function for formatting any address. ^gta
  177. * @since 1.4.0
  178. *
  179. * @return string HTML
  180. */
  181. function it_exchange_get_formatted_shipping_address( $shipping_address=false ) {
  182. $formatted = array();
  183. $shipping = empty( $shipping_address ) ? it_exchange_get_cart_shipping_address() : $shipping_address;
  184. $formatted[] = implode( ' ', array( $shipping['first-name'], $shipping['last-name'] ) );
  185. if ( ! empty( $shipping['company-name'] ) )
  186. $formatted[] = $shipping['company-name'];
  187. if ( ! empty( $shipping['address1'] ) )
  188. $formatted[] = $shipping['address1'];
  189. if ( ! empty( $shipping['address2'] ) )
  190. $formatted[] = $shipping['address2'];
  191. if ( ! empty( $shipping['city'] ) || ! empty( $shipping['state'] ) || ! empty( $shipping['zip'] ) ) {
  192. $formatted[] = implode( ' ', array( ( empty( $shipping['city'] ) ? '': $shipping['city'] .',' ),
  193. ( empty( $shipping['state'] ) ? '': $shipping['state'] ),
  194. ( empty( $shipping['zip'] ) ? '': $shipping['zip'] ),
  195. ) );
  196. }
  197. if ( ! empty( $shipping['country'] ) )
  198. $formatted[] = $shipping['country'];
  199. $formatted = implode( '<br />', $formatted );
  200. return apply_filters( 'it_exchange_get_formatted_shipping_address', $formatted );
  201. }
  202. /**
  203. * Grabs all the shipping methods available to the passed product
  204. *
  205. * 1) Grab all shipping methods
  206. * 2) Check to see if they're enabled
  207. * 3) Return an arry of ones that are enabled.
  208. *
  209. * @since 1.4.0
  210. *
  211. * @param object product an IT_Exchange_Product object
  212. * @return an array of shipping methods
  213. */
  214. function it_exchange_get_available_shipping_methods_for_product( $product ) {
  215. $providers = it_exchange_get_registered_shipping_providers();
  216. $provider_methods = array();
  217. $available_methods = array();
  218. // Grab all registerd shipping methods for all providers
  219. foreach( (array) $providers as $provider ) {
  220. $provider = it_exchange_get_registered_shipping_provider( $provider['slug'] );
  221. $provider_methods = array_merge( $provider_methods, $provider->shipping_methods );
  222. }
  223. // Loop through provider methods and only use the ones that are available for this product
  224. foreach( $provider_methods as $slug ) {
  225. if ( $method = it_exchange_get_registered_shipping_method( $slug, $product->ID ) ) {
  226. if ( $method->available )
  227. $available_methods[$slug] = $method;
  228. }
  229. }
  230. return apply_filters( 'it_exchange_get_available_shipping_methods_for_product', $available_methods, $product );
  231. }
  232. function it_exchange_get_enabled_shipping_methods_for_product( $product, $return='object' ) {
  233. // Are we viewing a new product?
  234. $screen = is_admin() ? get_current_screen() : false;
  235. $is_new_product = is_admin() && ! empty( $screen->action ) && 'add' == $screen->action;
  236. // Return false if shipping is turned off for this product
  237. if ( ! it_exchange_product_has_feature( $product->ID, 'shipping' ) && ! $is_new_product )
  238. return false;
  239. $enabled_methods = array();
  240. $product_overriding_default_methods = it_exchange_get_shipping_feature_for_product( 'core-available-shipping-methods', $product->ID );
  241. foreach( (array) it_exchange_get_available_shipping_methods_for_product( $product ) as $slug => $available_method ) {
  242. // If we made it here, the method is available. Check to see if it has been turned off for this specific product
  243. if ( false !== $product_overriding_default_methods ) {
  244. if ( ! empty( $product_overriding_default_methods->$slug ) )
  245. $enabled_methods[$slug] = ( 'slug' == $return ) ? $slug : $available_method;
  246. } else {
  247. $enabled_methods[$slug] = ( 'slug' == $return ) ? $slug : $available_method;
  248. }
  249. }
  250. return $enabled_methods;
  251. }
  252. /**
  253. * Is cart address valid?
  254. *
  255. * @since 1.4.0
  256. *
  257. * @return boolean
  258. */
  259. function it_exchange_is_shipping_address_valid() {
  260. $cart_address = it_exchange_get_cart_data( 'shipping-address' );
  261. $cart_customer = empty( $cart_address['customer'] ) ? 0 : $cart_address['customer'];
  262. $customer_id = it_exchange_get_current_customer_id();
  263. $customer_id = empty( $customer_id ) ? $cart_customer : $customer_id;
  264. return (boolean) get_user_meta( $customer_id, 'it_exchange_shipping_address', true );
  265. }
  266. /**
  267. * Returns the selected shipping method saved in the cart Session
  268. *
  269. * @since 1.4.0
  270. *
  271. * @return string method slug
  272. */
  273. function it_exchange_get_cart_shipping_method() {
  274. $method = it_exchange_get_cart_data( 'shipping-method' );
  275. $method = empty( $method[0] ) ? false : $method[0];
  276. // If there is only one possible shippign method for the cart, set it and return it.
  277. $cart_methods = it_exchange_get_available_shipping_methods_for_cart();
  278. $cart_product_methods = it_exchange_get_available_shipping_methods_for_cart_products();
  279. if ( ( count( $cart_methods ) === 1 && count( $cart_product_methods ) === 1 ) || count( $cart_product_methods ) === 1 ) {
  280. $single_method = reset($cart_methods);
  281. it_exchange_update_cart_data( 'shipping-method', $single_method->slug );
  282. return $single_method->slug;
  283. }
  284. return $method;
  285. }
  286. /**
  287. * This returns available shipping methods for the cart
  288. *
  289. * By default, it only returns the highest common denominator for all products.
  290. * ie: If product one supports methods A and B but product two only supports method A,
  291. * this function will only return method A.
  292. * Toggling the first paramater to false will return a composite of all available methods across products
  293. *
  294. * @since 1.4.0
  295. *
  296. * @parma boolean $only_return_methods_available_to_all_cart_products defaults to true.
  297. */
  298. function it_exchange_get_available_shipping_methods_for_cart( $only_return_methods_available_to_all_cart_products=true ) {
  299. $methods = array();
  300. $product_i = 0;
  301. // Grab all the products in the cart
  302. foreach( it_exchange_get_cart_products() as $product ) {
  303. // Skip foreach element if it isn't an exchange product - just to be safe
  304. if ( false === ( $product = it_exchange_get_product( $product['product_id'] ) ) )
  305. continue;
  306. // Skip product if it doesn't have shipping.
  307. if ( ! it_exchange_product_has_feature( $product->ID, 'shipping' ) )
  308. continue;
  309. // Bump product incrementer
  310. $product_i++;
  311. $product_methods = array();
  312. // Loop through shipping methods available for this product
  313. foreach( (array) it_exchange_get_enabled_shipping_methods_for_product( $product ) as $method ) {
  314. // Skip if method is false
  315. if ( empty( $method->slug ) )
  316. continue;
  317. // If this is the first product, put all available methods in methods array
  318. if ( ! empty( $method->slug ) && 1 === $product_i ) {
  319. $methods[$method->slug] = $method;
  320. }
  321. // If we're returning all methods, even when they aren't available to other products, tack them onto the array
  322. if ( ! $only_return_methods_available_to_all_cart_products )
  323. $methods[$method->slug] = $method;
  324. // Keep track of all this products methods
  325. $product_methods[] = $method->slug;
  326. }
  327. // Remove any methods previously added that aren't supported by this product
  328. if ( $only_return_methods_available_to_all_cart_products ) {
  329. foreach( $methods as $slug => $object ) {
  330. if ( ! in_array( $slug, $product_methods ) )
  331. unset( $methods[$slug] );
  332. }
  333. }
  334. }
  335. return $methods;
  336. }
  337. /**
  338. * Returns all available shipping methods for all cart products
  339. *
  340. * @since 1.4.0
  341. *
  342. * @return array an array of shipping methods
  343. */
  344. function it_exchange_get_available_shipping_methods_for_cart_products() {
  345. return it_exchange_get_available_shipping_methods_for_cart( false );
  346. }
  347. /**
  348. * Returns the cost of shipping for the cart based on selected shipping method(s)
  349. *
  350. * If called without the method param, it uses the selected cart method. Use with a param to get estimates for an unselected method
  351. *
  352. * @since 1.4.0
  353. *
  354. * @param string $shipping_method optional method.
  355. */
  356. function it_exchange_get_cart_shipping_cost( $shipping_method=false, $format_price=true ) {
  357. if ( ! $cart_products = it_exchange_get_cart_products() )
  358. return false;
  359. $cart_shipping_method = empty( $shipping_method ) ? it_exchange_get_cart_shipping_method() : $shipping_method;
  360. $cart_cost = 0;
  361. foreach( (array) $cart_products as $cart_product ) {
  362. if ( ! it_exchange_product_has_feature( $cart_product['product_id'], 'shipping' ) )
  363. continue;
  364. if ( 'multiple-methods' == $cart_shipping_method )
  365. $shipping_method = it_exchange_get_multiple_shipping_method_for_cart_product( $cart_product['product_cart_id'] );
  366. else
  367. $shipping_method = $cart_shipping_method;
  368. $cart_cost = $cart_cost + it_exchange_get_shipping_method_cost_for_cart_item( $shipping_method, $cart_product );
  369. }
  370. return empty( $format_price ) ? $cart_cost : it_exchange_format_price( $cart_cost );
  371. }
  372. /**
  373. * This will return the shipping cost for a specific method/product combination in the cart.
  374. *
  375. * @since unknown
  376. *
  377. * @param string $method_slug the shipping method slug
  378. * @param array $cart_product the cart product array
  379. * @param boolean $format_price format the price for a display
  380. */
  381. function it_exchange_get_shipping_method_cost_for_cart_item( $method_slug, $cart_product, $format_price=false ) {
  382. $method = it_exchange_get_registered_shipping_method( $method_slug, $cart_product['product_id'] );
  383. if ( empty( $method->slug ) )
  384. return 0;
  385. $cost = $method->get_shipping_cost_for_product( $cart_product );
  386. $cost = empty( $cost ) ? 0 : $cost;
  387. return empty( $format_price ) ? $cost : it_exchange_format_price( $cost );
  388. }
  389. /**
  390. * Returns the shipping method slug used by a specific cart product
  391. *
  392. * Only applicable when the cart is using multiple shipping methods for multiple products
  393. *
  394. * @since 1.4.0
  395. *
  396. * @param string $product_cart_id the product_cart_id in the cart session. NOT the database ID of the product
  397. * @return string
  398. */
  399. function it_exchange_get_multiple_shipping_method_for_cart_product( $product_cart_id ) {
  400. $selected_multiple_methods = it_exchange_get_cart_data( 'multiple-shipping-methods' );
  401. $selected_multiple_methods = empty( $selected_multiple_methods ) ? false : $selected_multiple_methods;
  402. $method = empty( $selected_multiple_methods[$product_cart_id] ) ? false : $selected_multiple_methods[$product_cart_id];
  403. return $method;
  404. }
  405. /**
  406. * This function updates the shipping method being used for a specific product in the cart
  407. *
  408. * Only applicable when the cart is using multiple shipping methods for multiple products
  409. *
  410. * @since 1.4.0
  411. *
  412. * @param string $product_cart_id the product_cart_id in the cart session. NOT the database ID of the product
  413. * @param string $method_slug the slug of the method this cart product will use
  414. * @return void
  415. */
  416. function it_exchange_update_multiple_shipping_method_for_cart_product( $product_cart_id, $method_slug ) {
  417. $selected_multiple_methods = it_exchange_get_cart_data( 'multiple-shipping-methods' );
  418. $selected_multiple_methods = empty( $selected_multiple_methods ) ? array() : $selected_multiple_methods;
  419. $selected_multiple_methods[$product_cart_id] = $method_slug;
  420. it_exchange_update_cart_data( 'multiple-shipping-methods', $selected_multiple_methods );
  421. }