Merge branch 'downloadable-files-2.1'

Conflicts:
	assets/css/admin.css
This commit is contained in:
Mike Jolley 2013-09-23 12:44:35 +01:00
commit 97b1e176d2
22 changed files with 411 additions and 200 deletions

File diff suppressed because one or more lines are too long

View File

@ -2235,7 +2235,61 @@ img.help_tip {
margin: 7px 0;
width: auto;
}
.woocommerce_variations, .woocommerce_options_panel {
.downloadable_files {
table {
width: 100%;
padding:0 !important;
th {
padding: 7px 0 7px 7px;
}
td {
vertical-align: middle !important;
padding: 4px 0 4px 7px;
position: relative;
&:last-child {
padding-right: 7px;
}
input.input_text {
width: 100%;
float: none;
margin: 1px 0;
}
.upload_file_button {
float: right;
width: auto;
cursor: pointer;
}
.delete {
.ir;
&:before {
.icon;
content: "\e013";
color: #999;
}
&:hover {
&:before {
color: red;
}
}
}
}
}
}
}
.woocommerce_options_panel {
.downloadable_files {
padding: 0 9px 0 162px;
position: relative;
margin: 9px 0 9px;
label {
position: absolute;
left: 0;
margin: 0 0 0 12px;
line-height: 24px;
}
}
p {
margin: 9px 0 9px;
}
@ -2330,13 +2384,6 @@ img.help_tip {
}
}
}
.upload_file_button {
padding-left: 20px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAQ0lEQVQYV3WPUQoAMAhC1+E6tYdrFBgiW185X7biSAGolpkZfN6GJg1CA7ip0CYo+FzxBTqeE/7J1qGAXsTEAdxQfQHJTymZe4oqiAAAAABJRU5ErkJggg==) !important;
background-color: #FEFEFE !important;
background-repeat: no-repeat !important;
background-position: 8px 7px !important;
}
}
#woocommerce-product-data input.dp-applied {
float: left;
@ -2451,11 +2498,6 @@ img.help_tip {
padding: 4px;
color: #555;
}
.upload_file_button {
font-size: 12px;
padding: 3px 8px 3px 20px;
line-height: 1;
}
select, .chosen-container {
width: 100% !important;
}
@ -2609,18 +2651,6 @@ img.help_tip {
background: #eee url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAWElEQVQYGY2OUQ6AMAxCZdm9jSev65K3YKNm+6EFBlVEHDxJJ3Pi0C72xlBNyTs3jU7wEUTTIB51GCp2CL8HLpHEdaOLb/N2dfuq9NT0zOo/M9q6EaImsd/uViMLVuD4KAAAAABJRU5ErkJggg==) no-repeat center center;
}
}
.file_path_field {
.upload_file_button {
text-align: center;
width: auto;
margin: 5px 0 0 0;
padding: 3px 8px 3px 20px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAQ0lEQVQYV3WPUQoAMAhC1+E6tYdrFBgiW185X7biSAGolpkZfN6GJg1CA7ip0CYo+FzxBTqeE/7J1qGAXsTEAdxQfQHJTymZe4oqiAAAAABJRU5ErkJggg==) !important;
background-color: #FEFEFE !important;
background-repeat: no-repeat !important;
background-position: 8px 7px !important;
}
}
}
.cancel_sale_schedule, .sale_schedule {
float: right;

View File

@ -219,7 +219,6 @@ jQuery( function($){
case 'variable_length' :
case 'variable_width' :
case 'variable_height' :
case 'variable_file_paths' :
case 'variable_download_limit' :
case 'variable_download_expiry' :
var value = prompt( woocommerce_admin_meta_boxes_variations.i18n_enter_a_value );

File diff suppressed because one or more lines are too long

View File

@ -946,6 +946,16 @@ jQuery( function($){
return false;
});
// File inputs
$('.downloadable_files').on('click','a.insert',function(){
$(this).closest('.downloadable_files').find('tbody').append( $(this).data( 'row' ) );
return false;
});
$('.downloadable_files').on('click','a.delete',function(){
$(this).closest('tr').remove();
return false;
});
// STOCK OPTIONS
$('input#_manage_stock').change(function(){
@ -1222,14 +1232,12 @@ jQuery( function($){
// Uploading files
var downloadable_file_frame;
var file_path_field;
var file_paths;
jQuery(document).on( 'click', '.upload_file_button', function( event ){
var $el = $(this);
file_path_field = $el.parent().find('.file_paths');
file_paths = file_path_field.val();
file_path_field = $el.closest('tr').find('td.file_url input');
event.preventDefault();
@ -1267,6 +1275,7 @@ jQuery( function($){
// When an image is selected, run a callback.
downloadable_file_frame.on( 'select', function() {
var file_path = '';
var selection = downloadable_file_frame.state().get('selection');
selection.map( function( attachment ) {
@ -1274,11 +1283,11 @@ jQuery( function($){
attachment = attachment.toJSON();
if ( attachment.url )
file_paths = file_paths ? file_paths + "\n" + attachment.url : attachment.url
file_path = attachment.url
} );
file_path_field.val( file_paths );
file_path_field.val( file_path );
});
// Set post to 0 and set our custom type

File diff suppressed because one or more lines are too long

View File

@ -252,33 +252,74 @@ class WC_Product {
* @return bool Whether downloadable product has a file attached.
*/
public function has_file( $download_id = '' ) {
return ( $this->is_downloadable() && $this->get_file_download_path( $download_id ) ) ? true : false;
return ( $this->is_downloadable() && $this->get_file( $download_id ) ) ? true : false;
}
/**
* Gets an array of downloadable files for this product.
*
* @since 2.1.0
*
* @return array
*/
public function get_files() {
$downloadable_files = array_filter( isset( $this->downloadable_files ) ? (array) maybe_unserialize( $this->downloadable_files ) : array() );
if ( $downloadable_files ) {
foreach ( $downloadable_files as $key => $file ) {
if ( ! is_array( $file ) ) {
$downloadable_files[ $key ] = array(
'file' => $file,
'name' => ''
);
}
// Set default name
if ( empty( $file['name'] ) )
$downloadable_files[ $key ]['name'] = woocommerce_get_filename_from_url( $file );
// Filter URL
$downloadable_files[ $key ]['file'] = apply_filters( 'woocommerce_file_download_path', $downloadable_files[ $key ]['file'], $this->id, $key );
}
}
return apply_filters( 'woocommerce_product_files', $downloadable_files, $this->id );
}
/**
* Get a file by $download_id
*
* @param string $download_id file identifier
* @return array|false if not found
*/
public function get_file( $download_id ) {
$files = $this->get_files();
if ( isset( $files[ $download_id ] ) )
$file = $files[ $download_id ];
else
$file = false;
// allow overriding based on the particular file being requested
return apply_filters( 'woocommerce_product_file', $file, $this->id, $download_id );
}
/**
* Get file download path identified by $download_id
*
* @access public
* @param string $download_id file identifier
* @return array
* @return string
*/
public function get_file_download_path( $download_id ) {
$files = $this->get_files();
$file_paths = isset( $this->file_paths ) ? $this->file_paths : '';
$file_paths = maybe_unserialize( $file_paths );
$file_paths = (array) apply_filters( 'woocommerce_file_download_paths', $file_paths, $this->id, null, null );
if ( ! $download_id && count( $file_paths ) == 1 ) {
// backwards compatibility for old-style download URLs and template files
$file_path = array_shift( $file_paths );
} elseif ( isset( $file_paths[ $download_id ] ) ) {
$file_path = $file_paths[ $download_id ];
} else {
if ( isset( $files[ $download_id ] ) )
$file_path = $files[ $download_id ]['file'];
else
$file_path = '';
}
// allow overriding based on the particular file being requested
return apply_filters( 'woocommerce_file_download_path', $file_path, $this->id, $download_id );
return apply_filters( 'woocommerce_product_file_download_path', $file_path, $this->id, $download_id );
}
/**
@ -715,9 +756,9 @@ class WC_Product {
} elseif ( $tax_rates !== $base_tax_rates ) {
$base_taxes = $_tax->calc_tax( $price * $qty, $base_tax_rates, true, true );
$modded_taxes = $_tax->calc_tax( $price * $qty - array_sum( $base_taxes ), $tax_rates, false );
$price = round( $price * $qty - array_sum( $base_taxes ) + array_sum( $modded_taxes ), 2 );
$base_taxes = $_tax->calc_tax( $price * $qty, $base_tax_rates, true );
$modded_taxes = $_tax->calc_tax( ( $price * $qty ) - array_sum( $base_taxes ), $tax_rates, false );
$price = round( ( $price * $qty ) - array_sum( $base_taxes ) + array_sum( $modded_taxes ), 2 );
} else {

View File

@ -956,34 +956,44 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
* Grant downloadable file access to any newly added files on any existing
* orders for this product that have previously been granted downloadable file access
*
* @access public
* @param int $product_id product identifier
* @param int $variation_id optional product variation identifier
* @param array $file_paths newly set file paths
* @param array $downloadable_files newly set files
*/
public function process_product_file_download_paths( $product_id, $variation_id, $file_paths ) {
public function process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ) {
global $wpdb;
if ( $variation_id )
$product_id = $variation_id;
// determine whether any new files have been added
$existing_file_paths = apply_filters( 'woocommerce_file_download_paths', get_post_meta( $product_id, '_file_paths', true ), $product_id, null, null );
if ( ! $existing_file_paths ) $existing_file_paths = array();
$product = get_product( $product_id );
$existing_download_ids = array_keys( (array) $product->get_files() );
$updated_download_ids = array_keys( (array) $downloadable_files );
$new_download_ids = array_diff( array_keys( (array) $file_paths ), array_keys( (array) $existing_file_paths ) );
$new_download_ids = array_filter( array_diff( $updated_download_ids, $existing_download_ids ) );
$removed_download_ids = array_filter( array_diff( $existing_download_ids, $updated_download_ids ) );
if ( $new_download_ids ) {
// determine whether downloadable file access has been granted (either via the typical order completion, or via the admin ajax method)
if ( $new_download_ids || $removed_download_ids ) {
// determine whether downloadable file access has been granted via the typical order completion, or via the admin ajax method
$existing_permissions = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = %d GROUP BY order_id", $product_id ) );
foreach ( $existing_permissions as $existing_permission ) {
$order = new WC_Order( $existing_permission->order_id );
if ( $order->id ) {
foreach ( $new_download_ids as $new_download_id ) {
// grant permission if it doesn't already exist
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT true FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->id, $product_id, $new_download_id ) ) ) {
woocommerce_downloadable_file_permission( $new_download_id, $product_id, $order );
// Remove permissions
if ( $removed_download_ids ) {
foreach ( $removed_download_ids as $download_id ) {
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->id, $product_id, $download_id ) );
}
}
// Add permissions
if ( $new_download_ids ) {
foreach ( $new_download_ids as $download_id ) {
// grant permission if it doesn't already exist
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT 1 FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->id, $product_id, $download_id ) ) ) {
woocommerce_downloadable_file_permission( $download_id, $product_id, $order );
}
}
}
}

View File

@ -49,6 +49,7 @@ class WC_Meta_Box_Order_Actions {
}
?>
</optgroup>
<option value="regenerate_download_permissions"><?php _e( 'Generate Download Permissions', 'woocommerce' ); ?></option>
<?php foreach( apply_filters( 'woocommerce_order_actions', array() ) as $action => $title ) { ?>
<option value="<?php echo $action; ?>"><?php echo $title; ?></option>
<?php } ?>
@ -109,6 +110,11 @@ class WC_Meta_Box_Order_Actions {
do_action( 'woocommerce_after_resend_order_email', $order, $email_to_send );
} elseif ( $action == 'regenerate_download_permissions' ) {
delete_post_meta( $post_id, '_download_permissions_granted' );
woocommerce_downloadable_product_permissions( $post_id );
} else {
do_action( 'woocommerce_order_action_' . sanitize_title( $action ), $order );

View File

@ -181,15 +181,46 @@ class WC_Meta_Box_Product_Data {
echo '<div class="options_group show_if_downloadable">';
// File URL
$file_paths = get_post_meta( $post->ID, '_file_paths', true );
if ( is_array( $file_paths ) )
$file_paths = implode( "\n", $file_paths );
?>
<div class="form-field downloadable_files">
<label><?php _e( 'Downloadable Files', 'woocommerce' ); ?>:</label>
<table class="widefat">
<thead>
<tr>
<th><?php _e( 'Name', 'woocommerce' ); ?> <span class="tips" data-tip="<?php _e( 'This is the name of the download shown to the customer.', 'woocommerce' ); ?>">[?]</span></th>
<th colspan="2"><?php _e( 'File URL', 'woocommerce' ); ?> <span class="tips" data-tip="<?php _e( 'This is the URL or absolute path to the file which customers will get access to.', 'woocommerce' ); ?>">[?]</span></th>
<th>&nbsp;</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="4">
<a href="#" class="button insert" data-row="<?php
$file = array(
'file' => '',
'name' => ''
);
ob_start();
include( 'views/html-product-download.php' );
echo esc_attr( ob_get_clean() );
?>"><?php _e( 'Add File', 'woocommerce' ); ?></a>
</th>
</tr>
</tfoot>
<tbody>
<?php
$downloadable_files = get_post_meta( $post->ID, '_downloadable_files', true );
echo '<p class="form-field"><label for="_file_paths">' . __( 'File paths (one per line)', 'woocommerce' ) . ':</label>
<textarea style="float:left;height:5em;" id="_file_paths" class="short file_paths" cols="20" rows="3" placeholder="' . __( 'File paths/URLs, one per line', 'woocommerce' ) . '" name="_file_paths" wrap="off">' . esc_textarea( $file_paths ) . '</textarea>
<input type="button" class="upload_file_button button" data-choose="' . __( 'Choose a file', 'woocommerce' ) . '" data-update="' . __( 'Insert file URL', 'woocommerce' ) . '" value="' . __( 'Choose a file', 'woocommerce' ) . '" />
</p>';
if ( $downloadable_files ) {
foreach ( $downloadable_files as $key => $file ) {
include( 'views/html-product-download.php' );
}
}
?>
</tbody>
</table>
</div>
<?php
// Download Limit
woocommerce_wp_text_input( array( 'id' => '_download_limit', 'label' => __( 'Download Limit', 'woocommerce' ), 'placeholder' => __( 'Unlimited', 'woocommerce' ), 'description' => __( 'Leave blank for unlimited re-downloads.', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array(
@ -204,7 +235,7 @@ class WC_Meta_Box_Product_Data {
) ) );
// Download Type
woocommerce_wp_select( array( 'id' => '_download_type', 'label' => __( 'Download Type', 'woocommerce' ), 'options' => array(
woocommerce_wp_select( array( 'id' => '_download_type', 'label' => __( 'Download Type', 'woocommerce' ), 'description' => sprintf( __( 'Choose a download type - this controls the <a href="%s">schema</a>.', 'woocommerce' ), 'http://schema.org/' ), 'options' => array(
'' => __( 'Standard Product', 'woocommerce' ),
'application' => __( 'Application/Software', 'woocommerce' ),
'music' => __( 'Music', 'woocommerce' ),
@ -746,7 +777,6 @@ class WC_Meta_Box_Product_Data {
<option value="variable_length"><?php _e( 'Length', 'woocommerce' ); ?></option>
<option value="variable_width"><?php _e( 'Width', 'woocommerce' ); ?></option>
<option value="variable_height"><?php _e( 'Height', 'woocommerce' ); ?></option>
<option value="variable_file_paths"><?php _e( 'File Path', 'woocommerce' ); ?></option>
<option value="variable_download_limit"><?php _e( 'Download limit', 'woocommerce' ); ?></option>
<option value="variable_download_expiry"><?php _e( 'Download Expiry', 'woocommerce' ); ?></option>
<?php do_action( 'woocommerce_variable_product_bulk_edit_actions' ); ?>
@ -815,7 +845,7 @@ class WC_Meta_Box_Product_Data {
'_height',
'_download_limit',
'_download_expiry',
'_file_paths',
'_downloadable_files',
'_downloadable',
'_virtual',
'_thumbnail_id',
@ -824,7 +854,7 @@ class WC_Meta_Box_Product_Data {
);
foreach ( $variation_fields as $field )
$$field = isset( $variation_data[ $field ][0] ) ? $variation_data[ $field ][0] : '';
$$field = isset( $variation_data[ $field ][0] ) ? maybe_unserialize( $variation_data[ $field ][0] ) : '';
// Tax class handling
$_tax_class = isset( $variation_data['_tax_class'][0] ) ? $variation_data['_tax_class'][0] : null;
@ -839,11 +869,6 @@ class WC_Meta_Box_Product_Data {
if ( $image_id )
$image = wp_get_attachment_thumb_url( $image_id );
// Format file paths
$_file_paths = maybe_unserialize( $_file_paths );
if ( is_array( $_file_paths ) )
$_file_paths = implode( "\n", $_file_paths );
include( 'views/html-variation-admin.php' );
$loop++;
@ -1235,23 +1260,25 @@ class WC_Meta_Box_Product_Data {
$_download_expiry = ''; // 0 or blank = unlimited
// file paths will be stored in an array keyed off md5(file path)
if ( isset( $_POST['_file_paths'] ) ) {
$_file_paths = array();
$file_paths = str_replace( "\r\n", "\n", esc_attr( $_POST['_file_paths'] ) );
$file_paths = trim( preg_replace( "/\n+/", "\n", $file_paths ) );
if ( $file_paths ) {
$file_paths = explode( "\n", $file_paths );
if ( isset( $_POST['_wc_file_urls'] ) ) {
$files = array();
foreach ( $file_paths as $file_path ) {
$file_path = trim( $file_path );
$_file_paths[ md5( $file_path ) ] = $file_path;
}
$file_names = isset( $_POST['_wc_file_names'] ) ? array_map( 'woocommerce_clean', $_POST['_wc_file_names'] ) : array();
$file_urls = isset( $_POST['_wc_file_urls'] ) ? array_map( 'esc_url_raw', array_map( 'trim', $_POST['_wc_file_urls'] ) ) : array();
$file_url_size = sizeof( $file_urls );
for ( $i = 0; $i < $file_url_size; $i ++ ) {
if ( ! empty( $file_urls[ $i ] ) )
$files[ md5( $file_urls[ $i ] ) ] = array(
'name' => $file_names[ $i ],
'file' => $file_urls[ $i ]
);
}
// grant permission to any newly added files on any existing orders for this product
do_action( 'woocommerce_process_product_file_download_paths', $post_id, 0, $_file_paths );
// grant permission to any newly added files on any existing orders for this product prior to saving
do_action( 'woocommerce_process_product_file_download_paths', $post_id, 0, $files );
update_post_meta( $post_id, '_file_paths', $_file_paths );
update_post_meta( $post_id, '_downloadable_files', $files );
}
update_post_meta( $post_id, '_download_limit', $_download_limit );
@ -1294,7 +1321,6 @@ class WC_Meta_Box_Product_Data {
$variable_regular_price = $_POST['variable_regular_price'];
$variable_sale_price = $_POST['variable_sale_price'];
$upload_image_id = $_POST['upload_image_id'];
$variable_file_paths = $_POST['variable_file_paths'];
$variable_download_limit = $_POST['variable_download_limit'];
$variable_download_expiry = $_POST['variable_download_expiry'];
$variable_shipping_class = $_POST['variable_shipping_class'];
@ -1416,26 +1442,27 @@ class WC_Meta_Box_Product_Data {
update_post_meta( $variation_id, '_download_limit', woocommerce_clean( $variable_download_limit[ $i ] ) );
update_post_meta( $variation_id, '_download_expiry', woocommerce_clean( $variable_download_expiry[ $i ] ) );
$_file_paths = array();
$file_paths = str_replace( "\r\n", "\n", $variable_file_paths[ $i ] );
$file_paths = trim( preg_replace( "/\n+/", "\n", $file_paths ) );
if ( $file_paths ) {
$file_paths = explode( "\n", $file_paths );
$files = array();
$file_names = isset( $_POST['_wc_variation_file_names'][ $variation_id ] ) ? array_map( 'woocommerce_clean', $_POST['_wc_variation_file_names'][ $variation_id ] ) : array();
$file_urls = isset( $_POST['_wc_variation_file_urls'][ $variation_id ] ) ? array_map( 'esc_url_raw', array_map( 'trim', $_POST['_wc_variation_file_urls'][ $variation_id ] ) ) : array();
$file_url_size = sizeof( $file_urls );
foreach ( $file_paths as $file_path ) {
$file_path = trim( $file_path );
$_file_paths[ md5( $file_path ) ] = $file_path;
}
for ( $i = 0; $i < $file_url_size; $i ++ ) {
if ( ! empty( $file_urls[ $i ] ) )
$files[ md5( $file_urls[ $i ] ) ] = array(
'name' => $file_names[ $i ],
'file' => $file_urls[ $i ]
);
}
// grant permission to any newly added files on any existing orders for this product
do_action( 'woocommerce_process_product_file_download_paths', $post_id, $variation_id, $_file_paths );
// grant permission to any newly added files on any existing orders for this product prior to saving
do_action( 'woocommerce_process_product_file_download_paths', $post_id, $variation_id, $files );
update_post_meta( $variation_id, '_file_paths', $_file_paths );
update_post_meta( $variation_id, '_downloadable_files', $files );
} else {
update_post_meta( $variation_id, '_download_limit', '' );
update_post_meta( $variation_id, '_download_expiry', '' );
update_post_meta( $variation_id, '_file_paths', '' );
update_post_meta( $variation_id, '_downloadable_files', '' );
}
// Save shipping class

View File

@ -0,0 +1,6 @@
<tr>
<td class="file_name"><input type="text" class="input_text" placeholder="<?php _e( 'File Name', 'woocommerce' ); ?>" name="_wc_file_names[]" value="<?php echo esc_attr( $file['name'] ); ?>" /></td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php _e( "http://", 'woocommerce' ); ?>" name="_wc_file_urls[]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php _e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php _e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo str_replace( ' ', '&nbsp;', __( 'Choose file', 'woocommerce' ) ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
</tr>

View File

@ -0,0 +1,6 @@
<tr>
<td class="file_name"><input type="text" class="input_text" placeholder="<?php _e( 'File Name', 'woocommerce' ); ?>" name="_wc_variation_file_names[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $file['name'] ); ?>" /></td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php _e( "http://", 'woocommerce' ); ?>" name="_wc_variation_file_urls[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php _e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php _e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo str_replace( ' ', '&nbsp;', __( 'Choose file', 'woocommerce' ) ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
</tr>

View File

@ -138,21 +138,58 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
</td>
</tr>
<tr class="show_if_variation_downloadable">
<td rowspan="2">
<div class="file_path_field">
<label><?php _e( 'File paths:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enter one or more File Paths, one per line, to make this variation a downloadable product, or leave blank.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<textarea style="float:left;" class="short file_paths" cols="20" rows="2" placeholder="<?php _e( 'File paths/URLs, one per line', 'woocommerce' ); ?>" name="variable_file_paths[<?php echo $loop; ?>]" wrap="off"><?php if ( isset( $_file_paths ) ) echo esc_textarea( $_file_paths ); ?></textarea>
<input type="button" class="upload_file_button button" value="<?php _e( 'Choose a file', 'woocommerce' ); ?>" title="<?php _e( 'Upload', 'woocommerce' ); ?>" data-choose="<?php _e( 'Choose a file', 'woocommerce' ); ?>" data-update="<?php _e( 'Insert file URL', 'woocommerce' ); ?>" value="<?php _e( 'Choose a file', 'woocommerce' ); ?>" />
<td colspan="2">
<div class="form-field downloadable_files">
<label><?php _e( 'Downloadable Files', 'woocommerce' ); ?>:</label>
<table class="widefat">
<thead>
<tr>
<th><?php _e( 'Name', 'woocommerce' ); ?> <span class="tips" data-tip="<?php _e( 'This is the name of the download shown to the customer.', 'woocommerce' ); ?>">[?]</span></th>
<th colspan="2"><?php _e( 'File URL', 'woocommerce' ); ?> <span class="tips" data-tip="<?php _e( 'This is the URL or absolute path to the file which customers will get access to.', 'woocommerce' ); ?>">[?]</span></th>
<th>&nbsp;</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="4">
<a href="#" class="button insert" data-row="<?php
$file = array(
'file' => '',
'name' => ''
);
ob_start();
include( 'html-product-variation-download.php' );
echo esc_attr( ob_get_clean() );
?>"><?php _e( 'Add File', 'woocommerce' ); ?></a>
</th>
</tr>
</tfoot>
<tbody>
<?php
if ( $_downloadable_files ) {
foreach ( $_downloadable_files as $key => $file ) {
if ( ! is_array( $file ) ) {
$file = array(
'file' => $file,
'name' => ''
);
}
include( 'html-product-variation-download.php' );
}
}
?>
</tbody>
</table>
</div>
</td>
</tr>
<tr class="show_if_variation_downloadable">
<td>
<div>
<label><?php _e( 'Download Limit:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Leave blank for unlimited re-downloads.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<input type="number" size="5" name="variable_download_limit[<?php echo $loop; ?>]" value="<?php if ( isset( $_download_limit ) ) echo esc_attr( $_download_limit ); ?>" placeholder="<?php _e( 'Unlimited', 'woocommerce' ); ?>" step="1" min="0" />
</div>
</td>
</tr>
<tr class="show_if_variation_downloadable">
<td>
<div>
<label><?php _e( 'Download Expiry:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enter the number of days before a download link expires, or leave blank.', 'woocommerce' ); ?>" href="#">[?]</a></label>

View File

@ -1463,11 +1463,9 @@ class WC_Cart {
$item_tax_rates = $tax_rates[ $_product->get_tax_class() ];
/**
* ADJUST TAX - Calculations when customer is OUTSIDE the shop base country/state and prices INCLUDE tax
* OR
* ADJUST TAX - Calculations when a tax class is modified
* ADJUST TAX - Calculations when base tax is not equal to the item tax
*/
if ( $_product->get_tax_class() !== $_product->tax_class || ( $woocommerce->customer->is_customer_outside_base() && ( defined('WOOCOMMERCE_CHECKOUT') || $woocommerce->customer->has_calculated_shipping() ) ) ) {
if ( $item_tax_rates !== $base_tax_rates ) {
// Work out a new base price without the shop's base tax
$line_tax = array_sum( $this->tax->calc_tax( $line_price, $base_tax_rates, true ) );

View File

@ -164,7 +164,7 @@ class WC_Install {
update_option( 'woocommerce_db_version', '2.0.14' );
}
if ( version_compare( $current_db_version, '2.1.0', '<' ) ) {
if ( version_compare( $current_db_version, '2.1.0', '<' ) || WOOCOMMERCE_VERSION == '2.1-bleeding' ) {
include( 'updates/woocommerce-update-2.1.php' );
update_option( 'woocommerce_db_version', '2.1.0' );
}

View File

@ -1022,7 +1022,7 @@ class WC_Order {
/**
* Gets any downloadable product file urls.
*
* @access public
* @deprecated as of 2.1 get_item_downloads is prefered as downloads are more than just file urls
* @param int $product_id product identifier
* @param int $variation_id variation identifier, or null
* @param array $item the item
@ -1031,6 +1031,8 @@ class WC_Order {
public function get_downloadable_file_urls( $product_id, $variation_id, $item ) {
global $wpdb;
_deprecated_function( 'get_downloadable_file_urls', '2.1', 'get_item_downloads' );
$download_file = $variation_id > 0 ? $variation_id : $product_id;
$_product = get_product( $download_file );
@ -1038,7 +1040,7 @@ class WC_Order {
$results = $wpdb->get_results( $wpdb->prepare("
SELECT download_id
FROM " . $wpdb->prefix . "woocommerce_downloadable_product_permissions
FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE user_email = %s
AND order_key = %s
AND product_id = %s
@ -1047,15 +1049,58 @@ class WC_Order {
$file_urls = array();
foreach ( $results as $result ) {
if ( $_product->has_file( $result->download_id ) ) {
$file_urls[ $_product->get_file_download_path( $result->download_id ) ] = add_query_arg( array( 'download_file' => $download_file, 'order' => $this->order_key, 'email' => $user_email, 'key' => $result->download_id ), trailingslashit( home_url() ) );
$file_urls[ $_product->get_file_download_path( $result->download_id ) ] = $this->get_download_url( $download_file, $result->download_id );
}
}
return apply_filters( 'woocommerce_get_downloadable_file_urls', $file_urls, $product_id, $variation_id, $item );
}
/**
* Get the downloadable files for an item in this order
* @param array $item
* @return array
*/
public function get_item_downloads( $item ) {
global $wpdb;
$product_id = $item['variation_id'] > 0 ? $item['variation_id'] : $item['product_id'];
$product = get_product( $product_id );
$download_ids = $wpdb->get_col( $wpdb->prepare("
SELECT download_id
FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE user_email = %s
AND order_key = %s
AND product_id = %s
", $this->billing_email, $this->order_key, $product_id ) );
$files = array();
foreach ( $download_ids as $download_id ) {
if ( $product->has_file( $download_id ) ) {
$files[ $download_id ] = $product->get_file( $download_id );
$files[ $download_id ]['download_url'] = $this->get_download_url( $product_id, $download_id );
}
}
return apply_filters( 'woocommerce_get_item_downloads', $files, $item, $this );
}
/**
* Get the Download URL
* @param int $product_id
* @param int $download_id
* @return string
*/
public function get_download_url( $product_id, $download_id ) {
return add_query_arg( array(
'download_file' => $product_id,
'order' => $this->order_key,
'email' => $this->billing_email,
'key' => $download_id
), trailingslashit( home_url() ) );
}
/**
* Adds a note (comment) to the order
*

View File

@ -51,6 +51,9 @@ class WC_Product_Variation extends WC_Product {
/** @public bool True if the variation has a tax class. */
public $variation_has_tax_class = false;
/** @public bool True if the variation has file paths. */
public $variation_has_downloadable_files = false;
/**
* Loads all product data from custom fields
*
@ -95,6 +98,11 @@ class WC_Product_Variation extends WC_Product {
$this->sku = $this->product_custom_fields['_sku'][0];
}
if ( ! empty( $this->product_custom_fields['_downloadable_files'][0] ) ) {
$this->variation_has_downloadable_files = true;
$this->downloadable_files = $this->product_custom_fields['_downloadable_files'][0];
}
if ( isset( $this->product_custom_fields['_stock'][0] ) && $this->product_custom_fields['_stock'][0] !== '' ) {
$this->variation_has_stock = true;
$this->manage_stock = 'yes';
@ -413,29 +421,6 @@ class WC_Product_Variation extends WC_Product {
return absint( $this->variation_shipping_class_id );
}
/**
* Get file download path identified by $download_id
*
* @access public
* @param string $download_id file identifier
* @return array
*/
public function get_file_download_path( $download_id ) {
$file_path = '';
$file_paths = (array) apply_filters( 'woocommerce_file_download_paths', get_post_meta( $this->variation_id, '_file_paths', true ), $this->variation_id, null, null );
if ( ! $download_id && count( $file_paths ) == 1 ) {
// backwards compatibility for old-style download URLs and template files
$file_path = array_shift( $file_paths );
} elseif ( isset( $file_paths[ $download_id ] ) ) {
$file_path = $file_paths[ $download_id ];
}
// allow overriding based on the particular file being requested
return apply_filters( 'woocommerce_file_download_path', $file_path, $this->variation_id, $download_id );
}
/**
* Get product name with extra details such as SKU, price and attributes. Used within admin.
*

View File

@ -23,4 +23,36 @@ wp_delete_post( get_option('woocommerce_lost_password_page_id'), true );
// Update table primary keys - remove old key and then add new 'permission_id' row.
$wpdb->hide_errors();
$wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions DROP PRIMARY KEY" );
$wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD `permission_id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT" );
$wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD `permission_id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT" );
// Upgrade file paths to support multiple file paths + names etc
$existing_file_paths = $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_file_paths' AND meta_value != '';" );
if ( $existing_file_paths ) {
foreach( $existing_file_paths as $existing_file_path ) {
$needs_update = false;
$new_value = array();
$value = maybe_unserialize( trim( $existing_file_path->meta_value ) );
if ( $value ) {
foreach ( $value as $key => $file ) {
if ( ! is_array( $file ) ) {
$needs_update = true;
$new_value[ $key ] = array(
'file' => $file,
'name' => woocommerce_get_filename_from_url( $file )
);
} else {
$new_value[ $key ] = $file;
}
}
if ( $needs_update ) {
$new_value = serialize( $new_value );
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = %s, meta_value = %s WHERE meta_id = %d", '_downloadable_files', $new_value, $existing_file_path->meta_id ) );
}
}
}
}

View File

@ -106,35 +106,25 @@ add_action('woocommerce_order_status_processing', 'woocommerce_downloadable_prod
* @return void
*/
function woocommerce_downloadable_product_permissions( $order_id ) {
if ( get_post_meta( $order_id, __( 'Download Permissions Granted', 'woocommerce' ), true ) == 1 )
if ( get_post_meta( $order_id, '_download_permissions_granted', true ) == 1 )
return; // Only do this once
$order = new WC_Order( $order_id );
if (sizeof($order->get_items())>0) foreach ($order->get_items() as $item) :
if ($item['product_id']>0) :
if ( sizeof( $order->get_items() ) > 0 ) {
foreach ( $order->get_items() as $item ) {
$_product = $order->get_product_from_item( $item );
if ( $_product && $_product->exists() && $_product->is_downloadable() ) :
if ( $_product && $_product->exists() && $_product->is_downloadable() ) {
$downloads = $order->get_item_downloads( $item );
$product_id = ($item['variation_id']>0) ? $item['variation_id'] : $item['product_id'];
foreach ( $downloads as $download_id => $download )
woocommerce_downloadable_file_permission( $download_id, $item['variation_id'] > 0 ? $item['variation_id'] : $item['product_id'], $order );
}
}
}
$file_download_paths = apply_filters( 'woocommerce_file_download_paths', get_post_meta( $product_id, '_file_paths', true ), $product_id, $order_id, $item );
if ( ! empty( $file_download_paths ) ) {
foreach ( $file_download_paths as $download_id => $file_path ) {
woocommerce_downloadable_file_permission( $download_id, $product_id, $order );
}
}
endif;
endif;
endforeach;
update_post_meta( $order_id, __( 'Download Permissions Granted', 'woocommerce' ), 1);
update_post_meta( $order_id, '_download_permissions_granted', 1 );
do_action( 'woocommerce_grant_product_download_permissions', $order_id );

View File

@ -32,23 +32,18 @@ foreach ( $items as $item ) :
// File URLs
if ( $show_download_links && $_product->exists() && $_product->is_downloadable() ) {
$download_file_urls = $order->get_downloadable_file_urls( $item['product_id'], $item['variation_id'], $item );
$i = 0;
foreach ( $download_file_urls as $file_url => $download_file_url ) {
echo '<br/><small>';
$filename = woocommerce_get_filename_from_url( $file_url );
if ( count( $download_file_urls ) > 1 ) {
echo sprintf( __( 'Download %d:', 'woocommerce' ), $i + 1 );
} elseif ( $i == 0 )
echo __( 'Download:', 'woocommerce' );
echo ' <a href="' . $download_file_url . '" target="_blank">' . $filename . '</a></small>';
$download_files = $order->get_item_downloads( $item );
$i = 0;
foreach ( $download_files as $download_id => $file ) {
$i++;
if ( count( $download_files ) > 1 ) {
$prefix = sprintf( __( 'Download %d:', 'woocommerce' ), $i );
} elseif ( $i == 1 )
$prefix = __( 'Download:', 'woocommerce' );
echo '<br/><small>' . $prefix . ' <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a></small>';
}
}

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.0.3
* @version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
@ -56,18 +56,14 @@ $order = new WC_Order( $order_id );
if ( $_product && $_product->exists() && $_product->is_downloadable() && $order->is_download_permitted() ) {
$download_file_urls = $order->get_downloadable_file_urls( $item['product_id'], $item['variation_id'], $item );
$i = 0;
$links = array();
foreach ( $download_file_urls as $file_url => $download_file_url ) {
$filename = woocommerce_get_filename_from_url( $file_url );
$links[] = '<small><a href="' . $download_file_url . '">' . sprintf( __( 'Download file%s', 'woocommerce' ), ( count( $download_file_urls ) > 1 ? ' ' . ( $i + 1 ) . ': ' : ': ' ) ) . $filename . '</a></small>';
$download_files = $order->get_item_downloads( $item );
$i = 0;
$links = array();
foreach ( $download_files as $download_id => $file ) {
$i++;
$links[] = '<small><a href="' . esc_url( $file['download_url'] ) . '">' . sprintf( __( 'Download file%s', 'woocommerce' ), ( count( $download_file_urls ) > 1 ? ' ' . $i . ': ' : ': ' ) ) . esc_html( $file['name'] ) . '</a></small>';
}
echo implode( '<br/>', $links );

View File

@ -806,14 +806,13 @@ function woocommerce_grant_access_to_download() {
$file_count = 0;
$order = new WC_Order( $order_id );
$product = get_product( $product_id );
$files = $product->get_files();
if ( ! $order->billing_email )
die();
$file_paths = apply_filters( 'woocommerce_file_download_paths', get_post_meta( $product_id, '_file_paths', true ), $product_id, $order_id, null );
if ( $file_paths ) {
foreach ( $file_paths as $download_id => $file_path ) {
if ( $files ) {
foreach ( $files as $download_id => $file ) {
if ( $inserted_id = woocommerce_downloadable_file_permission( $download_id, $product_id, $order ) ) {
// insert complete - get inserted data