installed plugin Easy Digital Downloads version 3.1.0.3

This commit is contained in:
2022-11-27 15:03:07 +00:00
committed by Gitium
parent 555673545b
commit c5dce2cec6
1200 changed files with 238970 additions and 0 deletions

View File

@ -0,0 +1,566 @@
<?php
/**
* Download import class
*
* This class handles importing downloads with the batch processing API
*
* @package EDD
* @subpackage Admin/Import
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.6
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* EDD_Batch_Downloads_Import Class
*
* @since 2.6
*/
class EDD_Batch_Downloads_Import extends EDD_Batch_Import {
/**
* Set up our import config.
*
* @since 2.6
* @return void
*/
public function init() {
// Set up default field map values
$this->field_mapping = array(
'post_title' => '',
'post_name' => '',
'post_status' => 'draft',
'post_author' => '',
'post_date' => '',
'post_content' => '',
'post_excerpt' => '',
'price' => '',
'files' => '',
'categories' => '',
'tags' => '',
'sku' => '',
'earnings' => '',
'sales' => '',
'featured_image' => '',
'download_limit' => '',
'notes' => ''
);
}
/**
* Process a step
*
* @since 2.6
* @return bool
*/
public function process_step() {
$more = false;
if ( ! $this->can_import() ) {
wp_die( __( 'You do not have permission to import data.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
$i = 1;
$offset = $this->step > 1 ? ( $this->per_step * ( $this->step - 1 ) ) : 0;
if( $offset > $this->total ) {
$this->done = true;
// Delete the uploaded CSV file.
unlink( $this->file );
}
if( ! $this->done && $this->csv ) {
$more = true;
foreach( $this->csv as $key => $row ) {
// Skip all rows until we pass our offset
if( $key + 1 <= $offset ) {
continue;
}
// Done with this batch
if( $i > $this->per_step ) {
break;
}
// Import Download
$args = array(
'post_type' => 'download',
'post_title' => '',
'post_name' => '',
'post_status' => '',
'post_author' => '',
'post_date' => '',
'post_content' => '',
'post_excerpt' => ''
);
foreach ( $args as $key => $field ) {
if ( ! empty( $this->field_mapping[ $key ] ) && ! empty( $row[ $this->field_mapping[ $key ] ] ) ) {
$args[ $key ] = $row[ $this->field_mapping[ $key ] ];
}
}
if ( empty( $args['post_author'] ) ) {
$user = wp_get_current_user();
$args['post_author'] = $user->ID;
} else {
// Check all forms of possible user inputs, email, ID, login.
if ( is_email( $args['post_author'] ) ) {
$user = get_user_by( 'email', $args['post_author'] );
} elseif ( is_numeric( $args['post_author'] ) ) {
$user = get_user_by( 'ID', $args['post_author'] );
} else {
$user = get_user_by( 'login', $args['post_author'] );
}
// If we don't find one, resort to the logged in user.
if ( false === $user ) {
$user = wp_get_current_user();
}
$args['post_author'] = $user->ID;
}
// Format the date properly
if ( ! empty( $args['post_date'] ) ) {
$timestamp = strtotime( $args['post_date'], current_time( 'timestamp' ) );
$date = date( 'Y-m-d H:i:s', $timestamp );
// If the date provided results in a date string, use it, or just default to today so it imports
if ( ! empty( $date ) ) {
$args['post_date'] = $date;
} else {
$date = '';
}
}
// Detect any status that could map to `publish`
if ( ! empty( $args['post_status'] ) ) {
$published_statuses = array(
'live',
'published',
);
$current_status = strtolower( $args['post_status'] );
if ( in_array( $current_status, $published_statuses ) ) {
$args['post_status'] = 'publish';
}
}
$download_id = wp_insert_post( $args );
// setup categories
if( ! empty( $this->field_mapping['categories'] ) && ! empty( $row[ $this->field_mapping['categories'] ] ) ) {
$categories = $this->str_to_array( $row[ $this->field_mapping['categories'] ] );
$this->set_taxonomy_terms( $download_id, $categories, 'download_category' );
}
// setup tags
if( ! empty( $this->field_mapping['tags'] ) && ! empty( $row[ $this->field_mapping['tags'] ] ) ) {
$tags = $this->str_to_array( $row[ $this->field_mapping['tags'] ] );
$this->set_taxonomy_terms( $download_id, $tags, 'download_tag' );
}
// setup price(s)
if( ! empty( $this->field_mapping['price'] ) && ! empty( $row[ $this->field_mapping['price'] ] ) ) {
$price = $row[ $this->field_mapping['price'] ];
$this->set_price( $download_id, $price );
}
// setup files
if( ! empty( $this->field_mapping['files'] ) && ! empty( $row[ $this->field_mapping['files'] ] ) ) {
$files = $this->convert_file_string_to_array( $row[ $this->field_mapping['files'] ] );
$this->set_files( $download_id, $files );
}
// Product Image
if( ! empty( $this->field_mapping['featured_image'] ) && ! empty( $row[ $this->field_mapping['featured_image'] ] ) ) {
$image = sanitize_text_field( $row[ $this->field_mapping['featured_image'] ] );
$this->set_image( $download_id, $image, $args['post_author'] );
}
// File download limit
if( ! empty( $this->field_mapping['download_limit'] ) && ! empty( $row[ $this->field_mapping['download_limit'] ] ) ) {
update_post_meta( $download_id, '_edd_download_limit', absint( $row[ $this->field_mapping['download_limit'] ] ) );
}
// Sale count
if( ! empty( $this->field_mapping['sales'] ) && ! empty( $row[ $this->field_mapping['sales'] ] ) ) {
update_post_meta( $download_id, '_edd_download_sales', absint( $row[ $this->field_mapping['sales'] ] ) );
}
// Earnings
if( ! empty( $this->field_mapping['earnings'] ) && ! empty( $row[ $this->field_mapping['earnings'] ] ) ) {
update_post_meta( $download_id, '_edd_download_earnings', edd_sanitize_amount( $row[ $this->field_mapping['earnings'] ] ) );
}
// Notes
if( ! empty( $this->field_mapping['notes'] ) && ! empty( $row[ $this->field_mapping['notes'] ] ) ) {
update_post_meta( $download_id, 'edd_product_notes', sanitize_text_field( $row[ $this->field_mapping['notes'] ] ) );
}
// SKU
if( ! empty( $this->field_mapping[ 'sku' ] ) && ! empty( $row[ $this->field_mapping[ 'sku' ] ] ) ) {
update_post_meta( $download_id, 'edd_sku', sanitize_text_field( $row[ $this->field_mapping['sku'] ] ) );
}
// Custom fields
$i++;
}
}
return $more;
}
/**
* Return the calculated completion percentage
*
* @since 2.6
* @return int
*/
public function get_percentage_complete() {
if( $this->total > 0 ) {
$percentage = ( $this->step * $this->per_step / $this->total ) * 100;
}
if( $percentage > 100 ) {
$percentage = 100;
}
return $percentage;
}
/**
* Set up and store the price for the download
*
* @since 2.6
* @return void
*/
private function set_price( $download_id = 0, $price = '' ) {
if( is_numeric( $price ) ) {
update_post_meta( $download_id, 'edd_price', edd_sanitize_amount( $price ) );
} else {
$prices = $this->str_to_array( $price );
if( ! empty( $prices ) ) {
$variable_prices = array();
$price_id = 1;
foreach( $prices as $price ) {
// See if this matches the EDD Download export for variable prices
if( false !== strpos( $price, ':' ) ) {
$price = array_map( 'trim', explode( ':', $price ) );
$variable_prices[ $price_id ] = array( 'name' => $price[ 0 ], 'amount' => $price[ 1 ] );
$price_id++;
}
}
update_post_meta( $download_id, '_variable_pricing', 1 );
update_post_meta( $download_id, 'edd_variable_prices', $variable_prices );
}
}
}
/**
* Set up and store the file downloads
*
* @since 2.6
* @return void
*/
private function set_files( $download_id = 0, $files = array() ) {
if( ! empty( $files ) ) {
$download_files = array();
$file_id = 1;
foreach( $files as $file ) {
$condition = '';
if ( false !== strpos( $file, ';' ) ) {
$split_on = strpos( $file, ';' );
$file_url = substr( $file, 0, $split_on );
$condition = substr( $file, $split_on + 1 );
} else {
$file_url = $file;
}
$download_file_args = array(
'index' => $file_id,
'file' => $file_url,
'name' => basename( $file_url ),
'condition' => empty( $condition ) ? 'all' : $condition
);
$download_files[ $file_id ] = $download_file_args;
$file_id++;
}
update_post_meta( $download_id, 'edd_download_files', $download_files );
}
}
/**
* Set up and store the Featured Image
*
* @since 2.6
* @return void
*/
private function set_image( $download_id = 0, $image = '', $post_author = 0 ) {
$is_url = false !== filter_var( $image, FILTER_VALIDATE_URL );
$is_local = $is_url && false !== strpos( site_url(), $image );
$ext = edd_get_file_extension( $image );
if( $is_url && $is_local ) {
// Image given by URL, see if we have an attachment already
$attachment_id = attachment_url_to_postid( $image );
} elseif( $is_url ) {
if( ! function_exists( 'media_sideload_image' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
// Image given by external URL
$url = media_sideload_image( $image, $download_id, '', 'src' );
if( ! is_wp_error( $url ) ) {
$attachment_id = attachment_url_to_postid( $url );
}
} elseif( false === strpos( $image, '/' ) && edd_get_file_extension( $image ) ) {
// Image given by name only
$upload_dir = wp_upload_dir();
if( file_exists( trailingslashit( $upload_dir['path'] ) . $image ) ) {
// Look in current upload directory first
$file = trailingslashit( $upload_dir['path'] ) . $image;
} else {
// Now look through year/month sub folders of upload directory for files with our image's same extension
$files = glob( $upload_dir['basedir'] . '/*/*/*' . $ext );
foreach( $files as $file ) {
if( basename( $file ) == $image ) {
// Found our file
break;
}
// Make sure $file is unset so our empty check below does not return a false positive
unset( $file );
}
}
if( ! empty( $file ) ) {
// We found the file, let's see if it already exists in the media library
$guid = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $file );
$attachment_id = attachment_url_to_postid( $guid );
if( empty( $attachment_id ) ) {
// Doesn't exist in the media library, let's add it
$filetype = wp_check_filetype( basename( $file ), null );
// Prepare an array of post data for the attachment.
$attachment = array(
'guid' => $guid,
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', $image ),
'post_content' => '',
'post_status' => 'inherit',
'post_author' => $post_author
);
// Insert the attachment.
$attachment_id = wp_insert_attachment( $attachment, $file, $download_id );
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata( $attachment_id, $file );
wp_update_attachment_metadata( $attachment_id, $attach_data );
}
}
}
if( ! empty( $attachment_id ) ) {
return set_post_thumbnail( $download_id, $attachment_id );
}
return false;
}
/**
* Set up and taxonomy terms
*
* @since 2.6
* @return void
*/
private function set_taxonomy_terms( $download_id = 0, $terms = array(), $taxonomy = 'download_category' ) {
$terms = $this->maybe_create_terms( $terms, $taxonomy );
if( ! empty( $terms ) ) {
wp_set_object_terms( $download_id, $terms, $taxonomy );
}
}
/**
* Locate term IDs or create terms if none are found
*
* @since 2.6
* @return array
*/
private function maybe_create_terms( $terms = array(), $taxonomy = 'download_category' ) {
// Return of term IDs
$term_ids = array();
foreach( $terms as $term ) {
if( is_numeric( $term ) && 0 === (int) $term ) {
$t = get_term( $term, $taxonomy );
} else {
$t = get_term_by( 'name', $term, $taxonomy );
if( ! $t ) {
$t = get_term_by( 'slug', $term, $taxonomy );
}
}
if( ! empty( $t ) ) {
$term_ids[] = $t->term_id;
} else {
$term_data = wp_insert_term( $term, $taxonomy, array( 'slug' => sanitize_title( $term ) ) );
if( ! is_wp_error( $term_data ) ) {
$term_ids[] = $term_data['term_id'];
}
}
}
return array_map( 'absint', $term_ids );
}
/**
* Retrieve URL to Downloads list table
*
* @since 2.6
* @return string
*/
public function get_list_table_url() {
return edd_get_admin_base_url();
}
/**
* Retrieve Download label
*
* @since 2.6
* @return void
*/
public function get_import_type_label() {
return edd_get_label_plural( true );
}
}

View File

@ -0,0 +1,636 @@
<?php
/**
* Payment Import Class
*
* This class handles importing payments with the batch processing API
*
* @package EDD
* @subpackage Admin/Import
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.6
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* EDD_Batch_Import Class
*
* @since 2.6
*/
class EDD_Batch_Payments_Import extends EDD_Batch_Import {
/**
* Set up our import config.
*
* @since 2.6
* @return void
*/
public function init() {
$this->per_step = 5;
// Set up default field map values
$this->field_mapping = array(
'total' => '',
'subtotal' => '',
'tax' => 'draft',
'number' => '',
'mode' => '',
'gateway' => '',
'date' => '',
'status' => '',
'email' => '',
'name' => '',
'first_name' => '',
'last_name' => '',
'edd_customer_id' => '',
'user_id' => '',
'discounts' => '',
'key' => '',
'transaction_id' => '',
'ip' => '',
'currency' => '',
'parent_payment_id' => '',
'downloads' => '',
'line1' => '',
'line2' => '',
'city' => '',
'state' => '',
'zip' => '',
'country' => '',
);
}
/**
* Process a step
*
* @since 2.6
* @return bool
*/
public function process_step() {
$more = false;
if ( ! $this->can_import() ) {
wp_die( __( 'You do not have permission to import data.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
// Remove certain actions to ensure they don't fire when creating the payments
remove_action( 'edd_complete_purchase', 'edd_trigger_purchase_receipt', 999 );
remove_action( 'edd_admin_sale_notice', 'edd_admin_email_notice', 10 );
$i = 1;
$offset = $this->step > 1 ? ( $this->per_step * ( $this->step - 1 ) ) : 0;
if( $offset > $this->total ) {
$this->done = true;
// Clean up the temporary records in the payment import process
global $wpdb;
$sql = "DELETE FROM {$wpdb->prefix}edd_customermeta WHERE meta_key = '_canonical_import_id'";
$wpdb->query( $sql );
// Delete the uploaded CSV file.
unlink( $this->file );
}
if( ! $this->done && $this->csv ) {
$more = true;
foreach( $this->csv as $key => $row ) {
// Skip all rows until we pass our offset
if( $key + 1 <= $offset ) {
continue;
}
// Done with this batch
if( $i > $this->per_step ) {
break;
}
// Import payment
$this->create_payment( $row );
$i++;
}
}
return $more;
}
/**
* Set up and store a payment record from a CSV row
*
* @since 2.6
* @return void
*/
public function create_payment( $row = array() ) {
$payment = new EDD_Payment;
$payment->status = 'pending';
if( ! empty( $this->field_mapping['number'] ) && ! empty( $row[ $this->field_mapping['number'] ] ) ) {
$payment->number = sanitize_text_field( $row[ $this->field_mapping['number'] ] );
}
if( ! empty( $this->field_mapping['mode'] ) && ! empty( $row[ $this->field_mapping['mode'] ] ) ) {
$mode = strtolower( sanitize_text_field( $row[ $this->field_mapping['mode'] ] ) );
$mode = 'test' != $mode && 'live' != $mode ? false : $mode;
if( ! $mode ) {
$mode = edd_is_test_mode() ? 'test' : 'live';
}
$payment->mode = $mode;
}
if( ! empty( $this->field_mapping['date'] ) && ! empty( $row[ $this->field_mapping['date'] ] ) ) {
$date = sanitize_text_field( $row[ $this->field_mapping['date'] ] );
if( ! strtotime( $date ) ) {
$date = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
} else {
$date = date( 'Y-m-d H:i:s', strtotime( $date ) );
}
$payment->date = $date;
}
$payment->customer_id = $this->set_customer( $row );
if( ! empty( $this->field_mapping['email'] ) && ! empty( $row[ $this->field_mapping['email'] ] ) ) {
$payment->email = sanitize_text_field( $row[ $this->field_mapping['email'] ] );
}
if ( ! empty( $this->field_mapping['name'] ) && ! empty( $row[ $this->field_mapping['name'] ] ) ) {
$payment->name = sanitize_text_field( $row[ $this->field_mapping['name'] ] );
} else {
if ( ! empty( $this->field_mapping['first_name'] ) && ! empty( $row[ $this->field_mapping['first_name'] ] ) ) {
$payment->first_name = sanitize_text_field( $row[ $this->field_mapping['first_name'] ] );
}
if ( ! empty( $this->field_mapping['last_name'] ) && ! empty( $row[ $this->field_mapping['last_name'] ] ) ) {
$payment->last_name = sanitize_text_field( $row[ $this->field_mapping['last_name'] ] );
}
}
if( ! empty( $this->field_mapping['user_id'] ) && ! empty( $row[ $this->field_mapping['user_id'] ] ) ) {
$user_id = sanitize_text_field( $row[ $this->field_mapping['user_id'] ] );
if( is_numeric( $user_id ) ) {
$user_id = absint( $row[ $this->field_mapping['user_id'] ] );
$user = get_userdata( $user_id );
} elseif( is_email( $user_id ) ) {
$user = get_user_by( 'email', $user_id );
} else {
$user = get_user_by( 'login', $user_id );
}
if( $user ) {
$payment->user_id = $user->ID;
$customer = new EDD_Customer( $payment->customer_id );
if( empty( $customer->user_id ) ) {
$customer->update( array( 'user_id' => $user->ID ) );
}
}
}
if( ! empty( $this->field_mapping['discounts'] ) && ! empty( $row[ $this->field_mapping['discounts'] ] ) ) {
$payment->discounts = sanitize_text_field( $row[ $this->field_mapping['discounts'] ] );
}
if( ! empty( $this->field_mapping['transaction_id'] ) && ! empty( $row[ $this->field_mapping['transaction_id'] ] ) ) {
$payment->transaction_id = sanitize_text_field( $row[ $this->field_mapping['transaction_id'] ] );
}
if( ! empty( $this->field_mapping['ip'] ) && ! empty( $row[ $this->field_mapping['ip'] ] ) ) {
$payment->ip = sanitize_text_field( $row[ $this->field_mapping['ip'] ] );
}
if( ! empty( $this->field_mapping['gateway'] ) && ! empty( $row[ $this->field_mapping['gateway'] ] ) ) {
$gateways = edd_get_payment_gateways();
$gateway = strtolower( sanitize_text_field( $row[ $this->field_mapping['gateway'] ] ) );
if( ! array_key_exists( $gateway, $gateways ) ) {
foreach( $gateways as $key => $enabled_gateway ) {
if( $enabled_gateway['checkout_label'] == $gateway ) {
$gateway = $key;
break;
}
}
}
$payment->gateway = $gateway;
}
if( ! empty( $this->field_mapping['currency'] ) && ! empty( $row[ $this->field_mapping['currency'] ] ) ) {
$payment->currency = strtoupper( sanitize_text_field( $row[ $this->field_mapping['currency'] ] ) );
}
if( ! empty( $this->field_mapping['key'] ) && ! empty( $row[ $this->field_mapping['key'] ] ) ) {
$payment->key = sanitize_text_field( $row[ $this->field_mapping['key'] ] );
}
if( ! empty( $this->field_mapping['parent_payment_id'] ) && ! empty( $row[ $this->field_mapping['parent_payment_id'] ] ) ) {
$payment->parent_payment_id = absint( $row[ $this->field_mapping['parent_payment_id'] ] );
}
if( ! empty( $this->field_mapping['downloads'] ) && ! empty( $row[ $this->field_mapping['downloads'] ] ) ) {
if( __( 'Products (Raw)', 'easy-digital-downloads' ) == $this->field_mapping['downloads'] ) {
// This is an EDD export so we can extract prices
$downloads = $this->get_downloads_from_edd( $row[ $this->field_mapping['downloads'] ] );
} else {
$downloads = $this->str_to_array( $row[ $this->field_mapping['downloads'] ] );
}
if( is_array( $downloads ) ) {
$download_count = count( $downloads );
foreach( $downloads as $download ) {
if( is_array( $download ) ) {
$download_name = $download['download'];
$price = $download['price'];
$tax = $download['tax'];
$price_id = $download['price_id'];
} else {
$download_name = $download;
}
$download_id = $this->maybe_create_download( $download_name );
if( ! $download_id ) {
continue;
}
$item_price = ! isset( $price ) ? edd_get_download_price( $download_id ) : $price;
$item_tax = ! isset( $tax ) ? ( $download_count > 1 ? 0.00 : $payment->tax ) : $tax;
$price_id = ! isset( $price_id ) ? false : $price_id;
$args = array(
'item_price' => $item_price,
'tax' => $item_tax,
'price_id' => $price_id,
);
$payment->add_download( $download_id, $args );
}
}
}
if( ! empty( $this->field_mapping['total'] ) && ! empty( $row[ $this->field_mapping['total'] ] ) ) {
$payment->total = edd_sanitize_amount( $row[ $this->field_mapping['total'] ] );
}
if( ! empty( $this->field_mapping['tax'] ) && ! empty( $row[ $this->field_mapping['tax'] ] ) ) {
$payment->tax = edd_sanitize_amount( $row[ $this->field_mapping['tax'] ] );
}
if( ! empty( $this->field_mapping['subtotal'] ) && ! empty( $row[ $this->field_mapping['subtotal'] ] ) ) {
$payment->subtotal = edd_sanitize_amount( $row[ $this->field_mapping['subtotal'] ] );
} else {
$payment->subtotal = $payment->total - $payment->tax;
}
$address = array( 'line1' => '', 'line2' => '', 'city' => '', 'state' => '', 'zip' => '', 'country' => '' );
foreach( $address as $key => $address_field ) {
if( ! empty( $this->field_mapping[ $key ] ) && ! empty( $row[ $this->field_mapping[ $key ] ] ) ) {
$address[ $key ] = sanitize_text_field( $row[ $this->field_mapping[ $key ] ] );
}
}
$payment->address = $address;
$payment->save();
// The status has to be set after payment is created to ensure status update properly
if( ! empty( $this->field_mapping['status'] ) && ! empty( $row[ $this->field_mapping['status'] ] ) ) {
$payment->status = strtolower( sanitize_text_field( $row[ $this->field_mapping['status'] ] ) );
} else {
$payment->status = 'complete';
}
// Save a second time to update stats
$payment->save();
}
private function set_customer( $row ) {
global $wpdb;
$customer = false;
$customer = false;
$email = '';
if( ! empty( $this->field_mapping['email'] ) && ! empty( $row[ $this->field_mapping['email'] ] ) ) {
$email = sanitize_text_field( $row[ $this->field_mapping['email'] ] );
}
// Look for a customer from the canonical source, if any
if( ! empty( $this->field_mapping['edd_customer_id'] ) && ! empty( $row[ $this->field_mapping['edd_customer_id'] ] ) ) {
$canonical_id = absint( $row[ $this->field_mapping['edd_customer_id'] ] );
$mapped_id = $wpdb->get_var( $wpdb->prepare( "SELECT edd_customer_id FROM $wpdb->edd_customermeta WHERE meta_key = '_canonical_import_id' AND meta_value = %d LIMIT 1", $canonical_id ) );
}
if( ! empty( $mapped_id ) ) {
$customer = new EDD_Customer( $mapped_id );
}
if( empty( $mapped_id ) || ! $customer->id > 0 ) {
// Look for a customer based on provided ID, if any
if ( ! empty( $this->field_mapping['edd_customer_id'] ) && ! empty( $row[ $this->field_mapping['edd_customer_id'] ] ) ) {
$customer_id = absint( $row[ $this->field_mapping['edd_customer_id'] ] );
$customer_by_id = new EDD_Customer( $customer_id );
}
// Now look for a customer based on provided email
if( ! empty( $email ) ) {
$customer_by_email = new EDD_Customer( $email );
}
// Now compare customer records. If they don't match, customer_id will be stored in meta and we will use the customer that matches the email
if ( ! empty( $customer_by_email ) && ( empty( $customer_by_id ) || $customer_by_id->id !== $customer_by_email->id ) ) {
$customer = $customer_by_email;
} elseif ( ! empty( $customer_by_id ) ) {
$customer = $customer_by_id;
if( ! empty( $email ) ) {
$customer->add_email( $email );
}
}
// Make sure we found a customer. Create one if not.
if ( empty( $customer->id ) ) {
if ( ! $customer instanceof EDD_Customer ) {
$customer = new EDD_Customer();
}
}
if ( ! empty( $this->field_mapping['name'] ) && ! empty( $row[ $this->field_mapping['name'] ] ) ) {
$name = $row[ $this->field_mapping['name'] ];
} else {
$first_name = '';
$last_name = '';
if ( ! empty( $this->field_mapping['first_name'] ) && ! empty( $row[ $this->field_mapping['first_name'] ] ) ) {
$first_name = $row[ $this->field_mapping['first_name'] ];
}
if ( ! empty( $this->field_mapping['last_name'] ) && ! empty( $row[ $this->field_mapping['last_name'] ] ) ) {
$last_name = $row[ $this->field_mapping['last_name'] ];
}
$name = $first_name . ' ' . $last_name;
}
$customer->create(
array(
'name' => sanitize_text_field( $name ),
'email' => empty( $email ) ? '' : $email,
)
);
if( ! empty( $canonical_id ) && (int) $canonical_id !== (int) $customer->id ) {
$customer->update_meta( '_canonical_import_id', $canonical_id );
}
}
if ( ! empty( $email ) && $email !== $customer->email ) {
$customer->add_email( $email );
}
return $customer->id;
}
/**
* Look up Download by title and create one if none is found
*
* @since 2.6
* @return int Download ID
*/
private function maybe_create_download( $title = '' ) {
if( ! is_string( $title ) ) {
return false;
}
$download = get_page_by_title( $title, OBJECT, 'download' );
if( $download ) {
$download_id = $download->ID;
} else {
$args = array(
'post_type' => 'download',
'post_title' => $title,
'post_author' => get_current_user_id()
);
$download_id = wp_insert_post( $args );
}
return $download_id;
}
/**
* Return the calculated completion percentage
*
* @since 2.6
* @return int
*/
public function get_downloads_from_edd( $data_str ) {
// Break string into separate products
$d_array = array();
$downloads = (array) explode( '/', $data_str );
if( $downloads ) {
foreach( $downloads as $key => $download ) {
$d = (array) explode( '|', $download );
if ( ! array_key_exists( 1, $d ) ) {
continue;
}
preg_match_all( '/\{(\d|(\d+(\.\d+|\d+)))\}/', $d[1], $matches );
if( false !== strpos( $d[1], '{' ) ) {
$price = trim( substr( $d[1], 0, strpos( $d[1], '{' ) ) );
} else {
$price = trim( $d[1] );
}
$price = floatval( $price );
$tax = isset( $matches[1][0] ) ? floatval( trim( $matches[1][0] ) ) : 0;
$price_id = isset( $matches[1][1] ) ? trim( $matches[1][1] ) : false;
$d_array[] = array(
'download' => trim( $d[0] ),
'price' => $price - $tax,
'tax' => $tax,
'price_id' => $price_id,
);
}
}
return $d_array;
}
/**
* Return the calculated completion percentage
*
* @since 2.6
* @return int
*/
public function get_percentage_complete() {
$total = count( $this->csv );
if( $total > 0 ) {
$percentage = ( $this->step * $this->per_step / $total ) * 100;
}
if( $percentage > 100 ) {
$percentage = 100;
}
return $percentage;
}
/**
* Retrieve the URL to the payments list table
*
* @since 2.6
* @return string
*/
public function get_list_table_url() {
return admin_url( 'edit.php?post_type=download&page=edd-payment-history' );
}
/**
* Retrieve the payments labels
*
* @since 2.6
* @return string
*/
public function get_import_type_label() {
return __( 'payments', 'easy-digital-downloads' );
}
}

View File

@ -0,0 +1,344 @@
<?php
/**
* Batch Import Class
*
* This is the base class for all batch import methods. Each data import type (customers, payments, etc) extend this class
*
* @package EDD
* @subpackage Admin/Import
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.6
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* EDD_Batch_Import Class
*
* @since 2.6
*/
class EDD_Batch_Import {
/**
* The file being imported
*
* @since 2.6
*/
public $file;
/**
* The parsed CSV file being imported
*
* @since 2.6
*/
public $csv;
/**
* Total rows in the CSV file
*
* @since 2.6
*/
public $total;
/**
* The current step being processed
*
* @since 2.6
*/
public $step;
/**
* The number of items to process per step
*
* @since 2.6
*/
public $per_step = 20;
/**
* The capability required to import data
*
* @since 2.6
*/
public $capability_type = 'manage_shop_settings';
/**
* Is the import file empty
*
* @since 2.6
*/
public $is_empty = false;
/**
* Map of CSV columns > database fields
*
* @since 2.6
*/
public $field_mapping = array();
/**
* Get things started
*
* @param $_step int The step to process
* @since 2.6
*/
public function __construct( $_file = '', $_step = 1 ) {
$this->step = $_step;
$this->file = $_file;
$this->done = false;
$this->csv = $this->get_csv_file( $this->file );
$this->total = count( $this->csv );
$this->init();
}
/**
* Initialize the updater. Runs after import file is loaded but before any processing is done.
*
* @since 2.6
* @return void
*/
public function init() {}
/**
* Can we import?
*
* @since 2.6
* @return bool Whether we can iport or not
*/
public function can_import() {
return (bool) apply_filters( 'edd_import_capability', current_user_can( $this->capability_type ) );
}
/**
* Parses the CSV from the file and returns the data as an array.
*
* @since 2.11.5
* @param string $file
*
* @return array
*/
public function get_csv_file( $file ) {
$csv = array_map( 'str_getcsv', file( $this->file ) );
array_walk(
$csv,
function ( &$a ) use ( $csv ) {
/*
* Make sure the two arrays have the same lengths.
* If not, we trim the larger array to match the smaller one.
*/
$min = min( count( $csv[0] ), count( $a ) );
$headers = array_slice( $csv[0], 0, $min );
$values = array_slice( $a, 0, $min );
$a = array_combine( $headers, $values );
}
);
array_shift( $csv );
return $csv;
}
/**
* Get the CSV columns
*
* @since 2.6
* @return array The columns in the CSV
*/
public function get_columns() {
$columns = array();
if ( isset( $this->csv[0] ) && is_array( $this->csv[0] ) ) {
$columns = array_keys( $this->csv[0] );
}
return $columns;
}
/**
* Get the first row of the CSV
*
* This is used for showing an example of what the import will look like
*
* @since 2.6
* @return array The first row after the header of the CSV
*/
public function get_first_row() {
if ( ! is_array( $this->csv ) ) {
return array();
}
return array_map( array( $this, 'trim_preview' ), current( $this->csv ) );
}
/**
* Process a step
*
* @since 2.6
* @return bool
*/
public function process_step() {
$more = false;
if ( ! $this->can_import() ) {
wp_die( __( 'You do not have permission to import data.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
return $more;
}
/**
* Return the calculated completion percentage
*
* @since 2.6
* @return int
*/
public function get_percentage_complete() {
return 100;
}
/**
* Map CSV columns to import fields
*
* @since 2.6
* @return void
*/
public function map_fields( $import_fields = array() ) {
$this->field_mapping = array_map( 'sanitize_text_field', $import_fields );
}
/**
* Retrieve the URL to the list table for the import data type
*
* @since 2.6
* @return string
*/
public function get_list_table_url() {}
/**
* Retrieve the label for the import type. Example: Payments
*
* @since 2.6
* @return string
*/
public function get_import_type_label() {}
/**
* Convert a string containing delimiters to an array
*
* @since 2.6
* @param $str Input string to convert to an array
* @return array
*/
public function str_to_array( $str = '' ) {
$array = array();
if( is_array( $str ) ) {
return array_map( 'trim', $str );
}
// Look for standard delimiters
if( false !== strpos( $str, '|' ) ) {
$delimiter = '|';
} elseif( false !== strpos( $str, ',' ) ) {
$delimiter = ',';
} elseif( false !== strpos( $str, ';' ) ) {
$delimiter = ';';
} elseif( false !== strpos( $str, '/' ) && ! filter_var( str_replace( ' ', '%20', $str ), FILTER_VALIDATE_URL ) && '/' !== substr( $str, 0, 1 ) ) {
$delimiter = '/';
}
if( ! empty( $delimiter ) ) {
$array = (array) explode( $delimiter, $str );
} else {
$array[] = $str;
}
return array_map( 'trim', $array );
}
/**
* Convert a files string containing delimiters to an array.
*
* This is identical to str_to_array() except it ignores all / characters.
*
* @since 2.9.20
* @param $str Input string to convert to an array
* @return array
*/
public function convert_file_string_to_array( $str = '' ) {
$array = array();
if( is_array( $str ) ) {
return array_map( 'trim', $str );
}
// Look for standard delimiters
if( false !== strpos( $str, '|' ) ) {
$delimiter = '|';
} elseif( false !== strpos( $str, ',' ) ) {
$delimiter = ',';
} elseif( false !== strpos( $str, ';' ) ) {
$delimiter = ';';
}
if( ! empty( $delimiter ) ) {
$array = (array) explode( $delimiter, $str );
} else {
$array[] = $str;
}
return array_map( 'trim', $array );
}
/**
* Trims a column value for preview
*
* @since 2.6
* @param $str Input string to trim down
* @return string
*/
public function trim_preview( $str = '' ) {
if( ! is_numeric( $str ) ) {
$long = strlen( $str ) >= 30;
$str = substr( $str, 0, 30 );
$str = $long ? $str . '...' : $str;
}
return $str;
}
}

View File

@ -0,0 +1,75 @@
<?php
/**
* Import Actions
*
* These are actions related to import data from Easy Digital Downloads.
*
* @package EDD
* @subpackage Admin/Import
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Add a hook allowing extensions to register a hook on the batch export process
*
* @since 2.6
* @return void
*/
function edd_register_batch_importers() {
if ( is_admin() ) {
do_action( 'edd_register_batch_importer' );
}
}
add_action( 'plugins_loaded', 'edd_register_batch_importers' );
/**
* Register the payments batch importer
*
* @since 2.6
*/
function edd_register_payments_batch_import() {
add_action( 'edd_batch_import_class_include', 'edd_include_payments_batch_import_processer', 10 );
}
add_action( 'edd_register_batch_importer', 'edd_register_payments_batch_import', 10 );
/**
* Loads the payments batch process if needed
*
* @since 2.6
* @param string $class The class being requested to run for the batch import
* @return void
*/
function edd_include_payments_batch_import_processer( $class ) {
if ( 'EDD_Batch_Payments_Import' === $class ) {
require_once EDD_PLUGIN_DIR . 'includes/admin/import/class-batch-import-payments.php';
}
}
/**
* Register the downloads batch importer
*
* @since 2.6
*/
function edd_register_downloads_batch_import() {
add_action( 'edd_batch_import_class_include', 'edd_include_downloads_batch_import_processer', 10 );
}
add_action( 'edd_register_batch_importer', 'edd_register_downloads_batch_import', 10 );
/**
* Loads the downloads batch process if needed
*
* @since 2.6
* @param string $class The class being requested to run for the batch import
* @return void
*/
function edd_include_downloads_batch_import_processer( $class ) {
if ( 'EDD_Batch_Downloads_Import' === $class ) {
require_once EDD_PLUGIN_DIR . 'includes/admin/import/class-batch-import-downloads.php';
}
}

View File

@ -0,0 +1,243 @@
<?php
/**
* Import Functions
*
* These are functions are used for import data into Easy Digital Downloads.
*
* @package EDD
* @subpackage Admin/Import
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Upload an import file with ajax
*
* @since 2.6
* @return void
*/
function edd_do_ajax_import_file_upload() {
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
require_once EDD_PLUGIN_DIR . 'includes/admin/import/class-batch-import.php';
if( ! wp_verify_nonce( $_REQUEST['edd_ajax_import'], 'edd_ajax_import' ) ) {
wp_send_json_error( array( 'error' => __( 'Nonce verification failed', 'easy-digital-downloads' ) ) );
}
if( empty( $_POST['edd-import-class'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import parameters. Import class must be specified.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( empty( $_FILES['edd-import-file'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import file. Please provide an import file.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if ( empty( $_FILES['edd-import-file']['type'] ) || ! in_array( strtolower( $_FILES['edd-import-file']['type'] ), edd_importer_accepted_mime_types(), true ) ) {
wp_send_json_error( array( 'error' => __( 'The file you uploaded does not appear to be a CSV file.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( ! file_exists( $_FILES['edd-import-file']['tmp_name'] ) ) {
wp_send_json_error( array( 'error' => __( 'Something went wrong during the upload process, please try again.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
// Let WordPress import the file. We will remove it after import is complete
$import_file = wp_handle_upload( $_FILES['edd-import-file'], array( 'test_form' => false ) );
if ( $import_file && empty( $import_file['error'] ) ) {
$importer_class = sanitize_text_field( $_POST['edd-import-class'] );
$is_class_allowed = edd_importer_is_class_allowed( $importer_class );
if ( false === $is_class_allowed ) {
wp_send_json_error( array( 'error' => __( 'Invalid importer class supplied', 'easy-digital-downloads' ) ) );
}
do_action( 'edd_batch_import_class_include', $importer_class );
$import = new $importer_class( $import_file['file'] );
if( ! $import->can_import() ) {
wp_send_json_error( array( 'error' => __( 'You do not have permission to import data', 'easy-digital-downloads' ) ) );
}
wp_send_json_success( array(
'form' => $_POST,
'class' => $importer_class,
'upload' => $import_file,
'first_row' => $import->get_first_row(),
'columns' => $import->get_columns(),
'nonce' => wp_create_nonce( 'edd_ajax_import', 'edd_ajax_import' )
) );
} else {
/**
* Error generated by _wp_handle_upload()
* @see _wp_handle_upload() in wp-admin/includes/file.php
*/
wp_send_json_error( array( 'error' => $import_file['error'] ) );
}
exit;
}
add_action( 'edd_upload_import_file', 'edd_do_ajax_import_file_upload' );
/**
* Process batch imports via ajax
*
* @since 2.6
* @return void
*/
function edd_do_ajax_import() {
require_once EDD_PLUGIN_DIR . 'includes/admin/import/class-batch-import.php';
if( ! wp_verify_nonce( $_REQUEST['nonce'], 'edd_ajax_import' ) ) {
wp_send_json_error( array( 'error' => __( 'Nonce verification failed', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( empty( $_REQUEST['class'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import parameters. Import class must be specified.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( ! file_exists( $_REQUEST['upload']['file'] ) ) {
wp_send_json_error( array( 'error' => __( 'Something went wrong during the upload process, please try again.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
$file = sanitize_text_field( $_REQUEST['upload']['file'] );
$mime_type_allowed = false;
if ( is_callable( 'mime_content_type' ) ) {
if ( in_array( mime_content_type( $file ), edd_importer_accepted_mime_types(), true ) ) {
$mime_type_allowed = true;
}
} else {
if ( wp_check_filetype( $file, edd_importer_accepted_mime_types() ) ) {
$mime_type_allowed = true;
}
}
if ( false === $mime_type_allowed ) {
wp_send_json_error( array( 'error' => __( 'The file you uploaded does not appear to be a CSV file.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
$importer_class = sanitize_text_field( $_REQUEST['class'] );
$is_class_allowed = edd_importer_is_class_allowed( $importer_class );
if ( ! $is_class_allowed ) {
wp_send_json_error( array( 'error' => __( 'Invalid importer class supplied', 'easy-digital-downloads' ) ) );
}
do_action( 'edd_batch_import_class_include', $importer_class );
$step = absint( $_REQUEST['step'] );
$class = $importer_class;
$import = new $class( $file, $step );
if( ! $import->can_import() ) {
wp_send_json_error( array( 'error' => __( 'You do not have permission to import data', 'easy-digital-downloads' ) ) );
}
parse_str( $_REQUEST['mapping'], $map );
$import->map_fields( $map['edd-import-field'] );
$ret = $import->process_step( $step );
$percentage = $import->get_percentage_complete();
if( $ret ) {
$step += 1;
wp_send_json_success( array(
'step' => $step,
'percentage' => $percentage,
'columns' => $import->get_columns(),
'mapping' => $import->field_mapping,
'total' => $import->total
) );
} elseif ( true === $import->is_empty ) {
wp_send_json_error( array(
'error' => __( 'No data found for import parameters', 'easy-digital-downloads' )
) );
} else {
wp_send_json_success( array(
'step' => 'done',
'message' => sprintf(
__( 'Import complete! <a href="%s">View imported %s</a>.', 'easy-digital-downloads' ),
esc_url( $import->get_list_table_url() ),
esc_html( $import->get_import_type_label() )
)
) );
}
}
add_action( 'wp_ajax_edd_do_ajax_import', 'edd_do_ajax_import' );
/**
* Returns the array of accepted mime types for the importer.
*
* @since 3.0
* @return array
*/
function edd_importer_accepted_mime_types() {
return array(
'text/csv',
'text/comma-separated-values',
'text/plain',
'text/anytext',
'text/*',
'text/plain',
'text/anytext',
'text/*',
'application/csv',
'application/excel',
'application/vnd.ms-excel',
'application/vnd.msexcel',
);
}
/**
* Given an importer class name, is it allowed to process as an importer.
*
* @since 3.0.2
*
* @param string $class The class name to check.
*
* @return bool If the class is allowed to be used as an importer.
*/
function edd_importer_is_class_allowed( $class = '' ) {
$allowed_importer_classes = edd_get_importer_accepted_classes();
return in_array( $class, $allowed_importer_classes, true );
}
/**
* Returns a list of allowed importer classes.
*
* @since 3.0.2
*
* @return array An array of class names to allow during imports.
*/
function edd_get_importer_accepted_classes() {
return apply_filters(
'edd_accepted_importer_classes',
array(
'EDD_Batch_Downloads_Import',
'EDD_Batch_Payments_Import',
)
);
}