2013-08-09 16:11:15 +00:00
< ? php
/**
* WooCommerce Order Functions
*
* Functions for order specific things .
*
* @ author WooThemes
* @ category Core
* @ package WooCommerce / Functions
* @ version 2.1 . 0
*/
if ( ! defined ( 'ABSPATH' ) ) exit ; // Exit if accessed directly
/**
* Finds an Order ID based on an order key .
*
* @ access public
* @ param string $order_key An order key has generated by
* @ return int The ID of an order , or 0 if the order could not be found
*/
2013-11-25 13:54:52 +00:00
function wc_get_order_id_by_order_key ( $order_key ) {
2013-08-09 16:11:15 +00:00
global $wpdb ;
// Faster than get_posts()
$order_id = $wpdb -> get_var ( " SELECT post_id FROM { $wpdb -> prefix } postmeta WHERE meta_key = '_order_key' AND meta_value = ' { $order_key } ' " );
return $order_id ;
}
/**
* Grant downloadable product access to the file identified by $download_id
*
* @ access public
* @ param string $download_id file identifier
* @ param int $product_id product identifier
* @ param WC_Order $order the order
2013-11-29 18:50:31 +00:00
* @ return int | bool insert id or false on failure
2013-08-09 16:11:15 +00:00
*/
2013-11-25 13:54:52 +00:00
function wc_downloadable_file_permission ( $download_id , $product_id , $order ) {
2013-08-09 16:11:15 +00:00
global $wpdb ;
$user_email = sanitize_email ( $order -> billing_email );
$limit = trim ( get_post_meta ( $product_id , '_download_limit' , true ) );
$expiry = trim ( get_post_meta ( $product_id , '_download_expiry' , true ) );
$limit = empty ( $limit ) ? '' : absint ( $limit );
// Default value is NULL in the table schema
$expiry = empty ( $expiry ) ? null : absint ( $expiry );
2013-12-17 05:07:19 +00:00
if ( $expiry ) {
$order_completed_date = date_i18n ( " Y-m-d " , strtotime ( $order -> completed_date ) );
$expiry = date_i18n ( " Y-m-d " , strtotime ( $order_completed_date . ' + ' . $expiry . ' DAY' ) );
}
2013-08-09 16:11:15 +00:00
2013-09-10 11:26:31 +00:00
$data = apply_filters ( 'woocommerce_downloadable_file_permission_data' , array (
'download_id' => $download_id ,
2013-08-09 16:11:15 +00:00
'product_id' => $product_id ,
'user_id' => absint ( $order -> user_id ),
'user_email' => $user_email ,
'order_id' => $order -> id ,
'order_key' => $order -> order_key ,
'downloads_remaining' => $limit ,
'access_granted' => current_time ( 'mysql' ),
'download_count' => 0
2013-09-10 11:26:31 +00:00
));
2013-08-09 16:11:15 +00:00
2013-09-10 11:26:31 +00:00
$format = apply_filters ( 'woocommerce_downloadable_file_permission_format' , array (
'%s' ,
2013-08-09 16:11:15 +00:00
'%s' ,
'%s' ,
'%s' ,
'%s' ,
'%s' ,
'%s' ,
'%s' ,
'%d'
2013-09-24 08:10:46 +00:00
), $data );
2013-08-09 16:11:15 +00:00
2013-09-10 11:26:31 +00:00
if ( ! is_null ( $expiry ) ) {
$data [ 'access_expires' ] = $expiry ;
$format [] = '%s' ;
}
2013-08-09 16:11:15 +00:00
// Downloadable product - give access to the customer
$result = $wpdb -> insert ( $wpdb -> prefix . 'woocommerce_downloadable_product_permissions' ,
2013-09-10 11:26:31 +00:00
$data ,
2013-09-10 14:08:20 +00:00
$format
2013-09-10 11:26:31 +00:00
);
do_action ( 'woocommerce_grant_product_download_access' , $data );
2013-08-09 16:11:15 +00:00
2013-09-10 11:26:31 +00:00
return $result ? $wpdb -> insert_id : false ;
2013-08-09 16:11:15 +00:00
}
2013-12-16 23:27:57 +00:00
2013-08-09 16:11:15 +00:00
/**
* Order Status completed - GIVE DOWNLOADABLE PRODUCT ACCESS TO CUSTOMER
*
* @ access public
* @ param int $order_id
* @ return void
*/
2013-11-25 13:54:52 +00:00
function wc_downloadable_product_permissions ( $order_id ) {
2014-02-17 10:50:36 +00:00
if ( get_post_meta ( $order_id , '_download_permissions_granted' , true ) == 1 ) {
2013-08-09 16:11:15 +00:00
return ; // Only do this once
2014-02-17 10:50:36 +00:00
}
2013-08-09 16:11:15 +00:00
$order = new WC_Order ( $order_id );
2014-02-17 10:50:36 +00:00
if ( $order -> status == 'processing' && get_option ( 'woocommerce_downloads_grant_access_after_payment' ) == 'no' ) {
2014-02-17 10:49:55 +00:00
return ;
2014-02-17 10:50:36 +00:00
}
2014-02-17 10:49:55 +00:00
2013-09-20 16:01:09 +00:00
if ( sizeof ( $order -> get_items () ) > 0 ) {
foreach ( $order -> get_items () as $item ) {
2013-08-09 16:11:15 +00:00
$_product = $order -> get_product_from_item ( $item );
2013-09-20 16:01:09 +00:00
if ( $_product && $_product -> exists () && $_product -> is_downloadable () ) {
2013-12-16 23:27:57 +00:00
$downloads = $_product -> get_files ();
2013-08-09 16:11:15 +00:00
2013-12-16 23:27:57 +00:00
foreach ( array_keys ( $downloads ) as $download_id ) {
2013-11-25 13:54:52 +00:00
wc_downloadable_file_permission ( $download_id , $item [ 'variation_id' ] > 0 ? $item [ 'variation_id' ] : $item [ 'product_id' ], $order );
2013-12-16 23:27:57 +00:00
}
2013-09-20 16:01:09 +00:00
}
}
}
2013-08-09 16:11:15 +00:00
2013-09-20 16:01:09 +00:00
update_post_meta ( $order_id , '_download_permissions_granted' , 1 );
2013-09-10 11:26:31 +00:00
do_action ( 'woocommerce_grant_product_download_permissions' , $order_id );
2013-08-09 16:11:15 +00:00
}
2014-02-17 10:50:36 +00:00
2014-02-17 10:49:55 +00:00
add_action ( 'woocommerce_order_status_completed' , 'wc_downloadable_product_permissions' );
add_action ( 'woocommerce_order_status_processing' , 'wc_downloadable_product_permissions' );
2013-08-09 16:11:15 +00:00
/**
* Add a item to an order ( for example a line item ) .
*
* @ access public
* @ param int $order_id
* @ param array $data
* @ return mixed
*/
2013-11-25 13:54:52 +00:00
function wc_add_order_item ( $order_id , $item ) {
2013-08-09 16:11:15 +00:00
global $wpdb ;
$order_id = absint ( $order_id );
if ( ! $order_id )
return false ;
$defaults = array (
'order_item_name' => '' ,
'order_item_type' => 'line_item' ,
);
$item = wp_parse_args ( $item , $defaults );
$wpdb -> insert (
$wpdb -> prefix . " woocommerce_order_items " ,
array (
'order_item_name' => $item [ 'order_item_name' ],
'order_item_type' => $item [ 'order_item_type' ],
'order_id' => $order_id
),
array (
'%s' , '%s' , '%d'
)
);
$item_id = absint ( $wpdb -> insert_id );
do_action ( 'woocommerce_new_order_item' , $item_id , $item , $order_id );
return $item_id ;
}
/**
2013-11-25 13:54:52 +00:00
* Delete an item from the order it belongs to based on item id
2013-08-09 16:11:15 +00:00
*
* @ access public
* @ param int $item_id
* @ return bool
*/
2013-11-25 13:54:52 +00:00
function wc_delete_order_item ( $item_id ) {
2013-08-09 16:11:15 +00:00
global $wpdb ;
$item_id = absint ( $item_id );
if ( ! $item_id )
return false ;
do_action ( 'woocommerce_before_delete_order_item' , $item_id );
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_order_items WHERE order_item_id = %d " , $item_id ) );
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_order_itemmeta WHERE order_item_id = %d " , $item_id ) );
do_action ( 'woocommerce_delete_order_item' , $item_id );
return true ;
}
/**
* WooCommerce Order Item Meta API - Update term meta
*
* @ access public
* @ param mixed $item_id
* @ param mixed $meta_key
* @ param mixed $meta_value
* @ param string $prev_value ( default : '' )
* @ return bool
*/
2013-11-25 13:54:52 +00:00
function wc_update_order_item_meta ( $item_id , $meta_key , $meta_value , $prev_value = '' ) {
2013-08-09 16:11:15 +00:00
return update_metadata ( 'order_item' , $item_id , $meta_key , $meta_value , $prev_value );
}
/**
* WooCommerce Order Item Meta API - Add term meta
*
* @ access public
* @ param mixed $item_id
* @ param mixed $meta_key
* @ param mixed $meta_value
* @ param bool $unique ( default : false )
* @ return bool
*/
2013-11-25 13:54:52 +00:00
function wc_add_order_item_meta ( $item_id , $meta_key , $meta_value , $unique = false ) {
2013-08-09 16:11:15 +00:00
return add_metadata ( 'order_item' , $item_id , $meta_key , $meta_value , $unique );
}
/**
* WooCommerce Order Item Meta API - Delete term meta
*
* @ access public
* @ param mixed $item_id
* @ param mixed $meta_key
* @ param string $meta_value ( default : '' )
* @ param bool $delete_all ( default : false )
* @ return bool
*/
2013-11-25 13:54:52 +00:00
function wc_delete_order_item_meta ( $item_id , $meta_key , $meta_value = '' , $delete_all = false ) {
2013-08-09 16:11:15 +00:00
return delete_metadata ( 'order_item' , $item_id , $meta_key , $meta_value , $delete_all );
}
/**
* WooCommerce Order Item Meta API - Get term meta
*
* @ access public
* @ param mixed $item_id
* @ param mixed $key
* @ param bool $single ( default : true )
* @ return mixed
*/
2013-11-25 13:54:52 +00:00
function wc_get_order_item_meta ( $item_id , $key , $single = true ) {
2013-08-09 16:11:15 +00:00
return get_metadata ( 'order_item' , $item_id , $key , $single );
}
/**
2013-11-25 13:54:52 +00:00
* Cancel all unpaid orders after held duration to prevent stock lock for those products
2013-08-09 16:11:15 +00:00
*
* @ access public
* @ return void
*/
2013-11-25 13:54:52 +00:00
function wc_cancel_unpaid_orders () {
2013-08-09 16:11:15 +00:00
global $wpdb ;
$held_duration = get_option ( 'woocommerce_hold_stock_minutes' );
if ( $held_duration < 1 || get_option ( 'woocommerce_manage_stock' ) != 'yes' )
return ;
$date = date ( " Y-m-d H:i:s " , strtotime ( '-' . absint ( $held_duration ) . ' MINUTES' , current_time ( 'timestamp' ) ) );
$unpaid_orders = $wpdb -> get_col ( $wpdb -> prepare ( "
SELECT posts . ID
FROM { $wpdb -> posts } AS posts
LEFT JOIN { $wpdb -> term_relationships } AS rel ON posts . ID = rel . object_ID
LEFT JOIN { $wpdb -> term_taxonomy } AS tax USING ( term_taxonomy_id )
LEFT JOIN { $wpdb -> terms } AS term USING ( term_id )
WHERE posts . post_type = 'shop_order'
AND posts . post_status = 'publish'
AND tax . taxonomy = 'shop_order_status'
AND term . slug = 'pending'
AND posts . post_modified < % s
" , $date ) );
if ( $unpaid_orders ) {
foreach ( $unpaid_orders as $unpaid_order ) {
$order = new WC_Order ( $unpaid_order );
if ( apply_filters ( 'woocommerce_cancel_unpaid_order' , true , $order ) )
$order -> update_status ( 'cancelled' , __ ( 'Unpaid order cancelled - time limit reached.' , 'woocommerce' ) );
}
}
wp_clear_scheduled_hook ( 'woocommerce_cancel_unpaid_orders' );
2014-03-07 19:17:11 +00:00
wp_schedule_single_event ( time () + ( absint ( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
2013-08-09 16:11:15 +00:00
}
2013-11-25 13:54:52 +00:00
add_action ( 'woocommerce_cancel_unpaid_orders' , 'wc_cancel_unpaid_orders' );
2013-08-09 16:11:15 +00:00
/**
* Return the count of processing orders .
*
* @ access public
* @ return int
*/
2013-11-25 13:54:52 +00:00
function wc_processing_order_count () {
2013-08-09 16:11:15 +00:00
if ( false === ( $order_count = get_transient ( 'woocommerce_processing_order_count' ) ) ) {
$order_statuses = get_terms ( 'shop_order_status' );
2013-09-10 11:26:31 +00:00
$order_count = false ;
foreach ( $order_statuses as $status ) {
if ( $status -> slug === 'processing' ) {
$order_count += $status -> count ;
break ;
}
}
$order_count = apply_filters ( 'woocommerce_admin_menu_count' , intval ( $order_count ) );
2014-03-12 11:58:41 +00:00
set_transient ( 'woocommerce_processing_order_count' , $order_count , YEAR_IN_SECONDS );
2013-08-09 16:11:15 +00:00
}
return $order_count ;
}
2014-02-26 15:43:19 +00:00
/**
* Clear all transients cache for order data .
*
* @ param int $post_id ( default : 0 )
*/
function wc_delete_shop_order_transients ( $post_id = 0 ) {
global $wpdb ;
$post_id = absint ( $post_id );
// Clear core transients
$transients_to_clear = array (
'woocommerce_processing_order_count'
);
2014-03-18 10:48:18 +00:00
// Clear transients for which we don't have the name
if ( wp_using_ext_object_cache () ) {
global $wp_object_cache ;
2014-03-18 11:18:35 +00:00
if ( isset ( $wp_object_cache -> cache [ 'transient' ] ) ) {
$keys = array_keys ( $wp_object_cache -> cache [ 'transient' ] );
2014-03-18 10:48:18 +00:00
foreach ( $keys as $key ) {
if ( 'wc_report_' === substr ( $key , 0 , 10 ) ) {
$transients_to_clear [] = $key ;
}
}
}
} else {
$wpdb -> query ( " DELETE FROM ` $wpdb->options ` WHERE `option_name` LIKE ('_transient_wc_report_%') OR `option_name` LIKE ('_transient_timeout_wc_report_%') " );
}
// Clear transients where we have names
2014-02-26 15:43:19 +00:00
foreach ( $transients_to_clear as $transient ) {
delete_transient ( $transient );
}
do_action ( 'woocommerce_delete_shop_order_transients' , $post_id );
}