/** * Gets the number of purchases for a variably priced download * * @since 1.0.6 * @param int $download_id The ID for this download * @param int $price_id The price ID for this item * @param string $user_email The email for the purchaser * @return mixed $purchases */ function edd_pl_get_file_purchases($download_id = 0, $price_id = 0, $user_email = false) { global $post; $post_old = $post; $scope = edd_get_option('edd_purchase_limit_scope') ? edd_get_option('edd_purchase_limit_scope') : 'site-wide'; // Retrieve all sales of this download $query_args = array('download' => $download_id, 'number' => -1); // Override global search if site-wide isn't selected if ($scope != 'site-wide') { if (!$user_email) { get_currentuserinfo(); } $query_args['s'] = $user_email; } // Get all purchases for this download $query = new EDD_Payments_Query($query_args); $payments = $query->get_payments(); $purchased = 0; // Count purchases foreach ($payments as $payment_id => $payment_data) { foreach ($payment_data->cart_details as $cart_item) { if (isset($cart_item['item_number']['options']['price_id']) && (int) $cart_item['item_number']['options']['price_id'] == (int) $price_id) { $purchased++; } } } wp_reset_postdata(); $post = $post_old; return $purchased; }
/** * edd_rp_generate_stats * * Generates the full relational data array for all downloads * * * @since 1.0 */ function edd_rp_generate_stats() { $defaults = array('number' => 250); // Data is acquired from the most recent 250 purchase logs to protect performance. If you need to increase or decrease this, use the following filter $log_query = apply_filters('edd_rp_log_query_args', $defaults); $edd_payments_query = new EDD_Payments_Query($log_query); $edd_payments = $edd_payments_query->get_payments(); // Determine what users have purchased what products if (!empty($edd_payments)) { foreach ($edd_payments as $payment) { $user_email = strtolower($payment->user_info['email']); $cart_items = $payment->cart_details; if (is_array($cart_items)) { foreach ($cart_items as $item) { $logs_data[md5($user_email)][] = $item['id']; } } } foreach ($logs_data as &$log) { $log = array_unique($log); } // Itterate through each download and find users who have purchased it, then if they have purhcased any other downloads // add those to the count. $downloads = get_posts(array('post_type' => 'download', 'posts_per_page' => '-1', 'fields' => 'ids')); $relation_array = array(); $display_free = edd_get_option('edd_rp_show_free', 1); foreach ($downloads as $download) { $relation_array[$download] = array(); foreach ($logs_data as $log) { if (in_array($download, $log)) { foreach ($log as $item) { if ($display_free && !edd_has_variable_prices($item) && absint(edd_get_download_price($item)) === 0) { continue; } if (!isset($relation_array[$download][$item])) { $relation_array[$download][$item] = 0; } $relation_array[$download][$item]++; } } } // Since the data inherintly includes itself in it's own array, just unset it. unset($relation_array[$download][$download]); arsort($relation_array[$download]); } update_option('_edd_rp_master_array', $relation_array); } }
/** * Retrieve all the data for all the payments * * @access public * @since 1.4 * @return array $payment_data Array of all the data for the payments */ public function payments_data() { $per_page = $this->per_page; $orderby = isset($_GET['orderby']) ? urldecode($_GET['orderby']) : 'ID'; $order = isset($_GET['order']) ? $_GET['order'] : 'DESC'; $user = isset($_GET['user']) ? $_GET['user'] : null; $customer = isset($_GET['customer']) ? $_GET['customer'] : null; $status = isset($_GET['status']) ? $_GET['status'] : edd_get_payment_status_keys(); $meta_key = isset($_GET['meta_key']) ? $_GET['meta_key'] : null; $year = isset($_GET['year']) ? $_GET['year'] : null; $month = isset($_GET['m']) ? $_GET['m'] : null; $day = isset($_GET['day']) ? $_GET['day'] : null; $search = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : null; $start_date = isset($_GET['start-date']) ? sanitize_text_field($_GET['start-date']) : null; $end_date = isset($_GET['end-date']) ? sanitize_text_field($_GET['end-date']) : $start_date; if (!empty($search)) { $status = 'any'; // Force all payment statuses when searching } $args = array('output' => 'payments', 'number' => $per_page, 'page' => isset($_GET['paged']) ? $_GET['paged'] : null, 'orderby' => $orderby, 'order' => $order, 'user' => $user, 'customer' => $customer, 'status' => $status, 'meta_key' => $meta_key, 'year' => $year, 'month' => $month, 'day' => $day, 's' => $search, 'start_date' => $start_date, 'end_date' => $end_date); if (is_string($search) && false !== strpos($search, 'txn:')) { $args['search_in_notes'] = true; $args['s'] = trim(str_replace('txn:', '', $args['s'])); } $p_query = new EDD_Payments_Query($args); return $p_query->get_payments(); }
/** * Loads the dashboard sales widget via ajax * * @since 2.1 * @return void */ function edd_load_dashboard_sales_widget() { if (!current_user_can(apply_filters('edd_dashboard_stats_cap', 'view_shop_reports'))) { die; } $stats = new EDD_Payment_Stats(); ?> <div class="edd_dashboard_widget"> <div class="table table_left table_current_month"> <table> <thead> <tr> <td colspan="2"><?php _e('Current Month', 'edd'); ?> </td> </tr> </thead> <tbody> <tr> <td class="first t monthly_earnings"><?php _e('Earnings', 'edd'); ?> </td> <td class="b b-earnings"><?php echo edd_currency_filter(edd_format_amount($stats->get_earnings(0, 'this_month'))); ?> </td> </tr> <tr> <?php $monthly_sales = $stats->get_sales(0, 'this_month', false, array('publish', 'revoked')); ?> <td class="first t monthly_sales"><?php echo _n('Sale', 'Sales', $monthly_sales, 'edd'); ?> </td> <td class="b b-sales"><?php echo $monthly_sales; ?> </td> </tr> </tbody> </table> <table> <thead> <tr> <td colspan="2"><?php _e('Last Month', 'edd'); ?> </td> </tr> </thead> <tbody> <tr> <td class="first t earnings"><?php echo __('Earnings', 'edd'); ?> </td> <td class="b b-last-month-earnings"><?php echo edd_currency_filter(edd_format_amount($stats->get_earnings(0, 'last_month'))); ?> </td> </tr> <tr> <td class="first t sales"> <?php $last_month_sales = $stats->get_sales(0, 'last_month', false, array('publish', 'revoked')); ?> <?php echo _n('Sale', 'Sales', $last_month_sales, 'edd'); ?> </td> <td class="b b-last-month-sales"> <?php echo $last_month_sales; ?> </td> </tr> </tbody> </table> </div> <div class="table table_right table_today"> <table> <thead> <tr> <td colspan="2"> <?php _e('Today', 'edd'); ?> </td> </tr> </thead> <tbody> <tr> <td class="t sales"><?php _e('Earnings', 'edd'); ?> </td> <td class="last b b-earnings"> <?php $earnings_today = $stats->get_earnings(0, 'today', false); ?> <?php echo edd_currency_filter(edd_format_amount($earnings_today)); ?> </td> </tr> <tr> <td class="t sales"> <?php _e('Sales', 'edd'); ?> </td> <td class="last b b-sales"> <?php $sales_today = $stats->get_sales(0, 'today', false, array('publish', 'revoked')); ?> <?php echo edd_format_amount($sales_today, false); ?> </td> </tr> </tbody> </table> </div> <div class="table table_right table_totals"> <table> <thead> <tr> <td colspan="2"><?php _e('Totals', 'edd'); ?> </td> </tr> </thead> <tbody> <tr> <td class="t earnings"><?php _e('Total Earnings', 'edd'); ?> </td> <td class="last b b-earnings"><?php echo edd_currency_filter(edd_format_amount(edd_get_total_earnings())); ?> </td> </tr> <tr> <td class="t sales"><?php _e('Total Sales', 'edd'); ?> </td> <td class="last b b-sales"><?php echo edd_format_amount(edd_get_total_sales(), false); ?> </td> </tr> </tbody> </table> </div> <div style="clear: both"></div> <?php do_action('edd_sales_summary_widget_after_stats', $stats); ?> <?php $p_query = new EDD_Payments_Query(array('number' => 5, 'status' => 'publish')); $payments = $p_query->get_payments(); if ($payments) { ?> <div class="table recent_purchases"> <table> <thead> <tr> <td colspan="2"> <?php _e('Recent Purchases', 'edd'); ?> <a href="<?php echo admin_url('edit.php?post_type=download&page=edd-payment-history'); ?> "> – <?php _e('View All', 'edd'); ?> </a> </td> </tr> </thead> <tbody> <?php foreach ($payments as $payment) { ?> <tr> <td class="edd_order_label"> <a href="<?php echo add_query_arg('id', $payment->ID, admin_url('edit.php?post_type=download&page=edd-payment-history&view=view-order-details')); ?> " title="<?php printf(__('Purchase Details for Payment #%s', 'edd'), $payment->ID); ?> "> <?php echo get_the_title($payment->ID); ?> — <?php echo $payment->user_info['email']; ?> </a> <?php if ($payment->user_info['id'] > 0) { $user = get_user_by('id', $payment->user_info['id']); if ($user) { echo "(" . $user->data->user_login . ")"; } } ?> </td> <td class="edd_order_price"> <a href="<?php echo add_query_arg('id', $payment->ID, admin_url('edit.php?post_type=download&page=edd-payment-history&view=view-order-details')); ?> " title="<?php printf(__('Purchase Details for Payment #%s', 'edd'), $payment->ID); ?> "> <span class="edd_price_label"><?php echo edd_currency_filter(edd_format_amount($payment->total), edd_get_payment_currency_code($payment->ID)); ?> </span> </a> </td> </tr> <?php } // End foreach ?> </tbody> </table> </div> <?php } // End if ?> <?php do_action('edd_sales_summary_widget_after_purchases', $payments); ?> </div> <?php die; }
/** * Gets the next available order number * * This is used when inserting a new payment * * @since 2.0 * @return string $number The next available payment number */ function edd_get_next_payment_number() { if (!edd_get_option('enable_sequential')) { return false; } $number = get_option('edd_last_payment_number'); $start = edd_get_option('sequential_start', 1); $increment_number = true; if (false !== $number) { if (empty($number)) { $number = $start; $increment_number = false; } } else { // This case handles the first addition of the new option, as well as if it get's deleted for any reason $payments = new EDD_Payments_Query(array('number' => 1, 'order' => 'DESC', 'orderby' => 'ID', 'output' => 'posts', 'fields' => 'ids')); $last_payment = $payments->get_payments(); if ($last_payment) { $number = edd_get_payment_number($last_payment[0]); } if (!empty($number) && $number !== $last_payment[0]) { $number = edd_remove_payment_prefix_postfix($number); } else { $number = $start; $increment_number = false; } } $increment_number = apply_filters('edd_increment_payment_number', $increment_number, $number); if ($increment_number) { $number++; } return apply_filters('edd_get_next_payment_number', $number); }
/** * Gets the next available order number * * This is used when inserting a new payment * * @since 2.0 * @return string $number The next available payment number */ function edd_get_next_payment_number() { if (!edd_get_option('enable_sequential')) { return false; } $prefix = edd_get_option('sequential_prefix'); $postfix = edd_get_option('sequential_postfix'); $start = edd_get_option('sequential_start', 1); $payments = new EDD_Payments_Query(array('number' => 1, 'order' => 'DESC', 'orderby' => 'ID', 'output' => 'posts', 'fields' => 'ids')); $last_payment = $payments->get_payments(); if ($last_payment) { $number = edd_get_payment_number($last_payment[0]); if (empty($number)) { $number = $prefix . $start . $postfix; } else { // Remove prefix and postfix $number = str_replace($prefix, '', $number); $number = str_replace($postfix, '', $number); // Ensure it's a whole number $number = intval($number); // Increment the payment number $number++; // Re-add the prefix and postfix $number = $prefix . $number . $postfix; } } else { $number = $prefix . $start . $postfix; } return apply_filters('edd_get_next_payment_number', $number); }
function edd_drip_cron_half_hourly_func() { $now = time(); $thirty_mins_before = $now - 30 * 60; $args = array('status' => 'pending', 'start_date' => $thirty_mins_before, 'end_date' => $now); $p_query = new EDD_Payments_Query($args); $payments = $p_query->get_payments(); foreach ($payments as $payment) { // push subscribe infor to server $drip_api = EDDDripApi::getInstance(); $infor = $this->get_infor_by_payment_id($payment->ID); $email = $infor['email']; //get all item in the cart $cart_items = $infor['cart_items']; foreach ($cart_items as $item) { $drip_api->fire_event($email, 'Abandoned cart', array('value' => $item['price'], 'product_name' => $item['name'], 'price_name' => edd_get_cart_item_price_name($item))); } } }
/** * Handle the ajax call, no need for nopriv handling since this is admin only * * @access private * @since 2.6 * @return void */ function edd_sl_generate_download_keys_ajax_callback() { if (!current_user_can('edit_shop_payments')) { status_header(404); die; } // If there is no download ID posted, breakout immediately because we cannot find the download if (!isset($_POST['download'])) { status_header(404); die; } // Grab the download ID and make sure its an int $download = intval($_POST['download']); // Make sure the post we are looking at is a download, otherwise the post (media type) is unsupported! if (get_post_type($download) !== 'download') { status_header(415); die; } // Gather all the payments, and individual download IDs so we can verify licenses exist $args = array('download' => $download, 'number' => -1); $query = new EDD_Payments_Query($args); $payments = $query->get_payments(); $is_bundle = edd_is_bundled_product($download); $downloads = $is_bundle ? edd_get_bundled_products($download) : array($download); // Loop through the payments, and then the downloads, and maybe generate licenses $generated = 0; $updated = 0; foreach ($payments as $payment) { if ($is_bundle) { $parent_license = edd_software_licensing()->get_license_by_purchase($payment->ID, $download); } foreach ($downloads as $d) { // If download ID is empty, continue if (empty($d)) { continue; } // Maybe generate a key, and if we do increase the count $license = edd_software_licensing()->get_license_by_purchase($payment->ID, $d); // If no license exists... generate one! if (!$license) { add_action('edd_sl_store_license', 'edd_sl_log_generated_license', 10, 4); $key = edd_software_licensing()->generate_license($d, $payment->ID); $license = edd_software_licensing()->get_license_by_purchase($payment->ID, $d); if ($is_bundle && $key) { // Set the post parent to the Bundle Key $update_args = array('ID' => $license->ID, 'post_parent' => $parent_license->ID); wp_update_post($update_args); } remove_action('edd_sl_store_license', 'edd_sl_log_generated_license', 10); // Return true if a key was generated if ($key) { $generated++; } } elseif ($is_bundle && $license) { if (empty($license->post_parent)) { // Set the post parent to the Bundle Key $update_args = array('ID' => $license->ID, 'post_parent' => $parent_license->ID); wp_update_post($update_args); $updated++; } } } } // We must die, or we live too long... but we must speak our last workd. printf(_n('One key was generated', '%d keys were generated.', $generated), $generated); echo '<br />'; printf(_n('One key was updated', '%d keys were updated.', $updated), $updated); die; }
/** * Get all payments that are missing license keys * * @access public * @since 2.4 * @return array */ public static function get_unlicensed_payments() { global $wpdb; $products = self::get_licensed_products(); if (empty($products)) { return array(); } $products = array_keys($products); $products_csv = implode(',', $products); $license_query = <<<EOD \t\t\tSELECT pm.meta_value \t\t\tFROM {$wpdb->postmeta} pm \t\t\tWHERE 1 = 1 \t\t\t\tAND pm.meta_key = '_edd_sl_payment_id' \t\t\t\tAND pm.post_id NOT IN ( \t\t\t\t\tSELECT post_id \t\t\t\t\tFROM {$wpdb->postmeta} \t\t\t\t\tWHERE 1 = 1 \t\t\t\t\t\tAND meta_key = '_edd_sl_download_id' \t\t\t\t\t\tAND meta_value IN ( {$products_csv} ) \t\t\t\t) EOD; $post__not_in = $wpdb->get_col($license_query); $post__in = array(); foreach ($products as $product) { $args = array('download' => $product, 'number' => -1); $query = new EDD_Payments_Query($args); $payments = $query->get_payments(); foreach ($payments as $payment) { $post__in[] = $payment->ID; } } $query = array('post_status' => array('publish', 'edd_subscription'), 'post_type' => 'edd_payment', 'orderby' => 'post_modified', 'order' => 'DESC', 'posts_per_page' => 1); if (!empty($post__in) && !empty($post__not_in)) { $post__in = array_diff($post__in, $post__not_in); $post__in = array_unique($post__in); $query['post__in'] = $post__in; } elseif (!empty($post__in)) { $post__in = array_unique($post__in); $query['post__in'] = $post__in; } elseif (!empty($post__not_in)) { $post__not_in = array_unique($post__not_in); $query['post__not_in'] = $post__not_in; } $results = new WP_Query($query); $query_wp = $results->request; $query_wp = preg_replace('#\\bLIMIT 0,.*#', '', $query_wp); $payments = $wpdb->get_col($query_wp); return $payments; }
/** * Find old pending carts and consider them abandoned. * @return null */ public static function find_old_abandoned_carts() { $time = time(); $thirty_mins_ago = $time - apply_filters('find_old_abandoned_carts_mins_ago', 1800); // a half hour $args = array('status' => array('abandoned', 'pending'), 'start_date' => $thirty_mins_ago, 'end_date' => $time); $pending_payments = new EDD_Payments_Query($args); $payments = $pending_payments->get_payments(); if (empty($payments)) { return; } foreach ($payments as $payment) { $payment_id = $payment->ID; $user_id = edd_get_payment_user_id($payment_id); $uid = EDD_Segment_Identity::get_uid_from_user_id($user_id); $meta = edd_get_payment_meta($payment_id); // Adding an event for each item foreach ($meta['cart_details'] as $key => $item_details) { $item_details = array_merge($item_details, array('time' => time())); do_action('edd_segment_track', $uid, 'Abandoned Cart', $item_details); } } }