diff --git a/.gitignore b/.gitignore
index 9f821f0f712..c2a5ad15911 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,7 @@ logs/
project.xml
project.properties
.DS_Store
-Thumbs.db
\ No newline at end of file
+Thumbs.db
+.buildpath
+.project
+.settings*
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 43d9f5f48fd..3edaccba971 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,7 +4,7 @@ Community made patches, localisations, bug reports and contributions are always
When contributing please ensure you follow the guidelines below so that we can keep on top of things.
-__note__ GitHub is for bug reports and contributions only - if you have a support question or a request for a customisation don't post here. Use [WooThemes Support](http://support.woothemes.com) and [WooJobs](http://jobs.woothemes.com) respectively.
+__note:__ GitHub is for bug reports and contributions only - if you have a support question or a request for a customization don't post here. Use [WooThemes Support](http://support.woothemes.com) and [WooJobs](http://jobs.woothemes.com) respectively.
## Getting Started
@@ -13,20 +13,20 @@ __note__ GitHub is for bug reports and contributions only - if you have a suppor
* Clearly describe the issue including steps to reproduce when it is a bug.
* Make sure you fill in the earliest version that you know has the issue.
-## Making Changes
+## Making Changes
-* Fork the repository on GitHub
-* Make the changes to your forked repository
- * Ensure you stick to the [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards)
- * Ensure you use LF line endings - no crazy windows line endings :)
-* When committing, reference your issue (#1234) and include a note about the fix
-* Push the changes to your fork and submit a pull request on the master WooCommerce repository
+* Fork the repository on GitHub.
+* Make the changes to your forked repository.
+ * **Ensure you stick to the [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards).**
+ * Ensure you use LF line endings - no crazy windows line endings. :)
+* When committing, reference your issue (#1234) and include a note about the fix.
+* Push the changes to your fork and submit a pull request on the master WooCommerce repository.
-At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
+At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
# Additional Resources
* [General GitHub documentation](http://help.github.com/)
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
-* [WooCommerce Docs](http://wcdocs.woothemes.com/)
-* [WooThemes Support](http://support.woothemes.com)
\ No newline at end of file
+* [WooCommerce Docs](http://docs.woothemes.com/)
+* [WooThemes Support](http://support.woothemes.com)
diff --git a/admin/importers/tax-rates-importer.php b/admin/importers/tax-rates-importer.php
index 97a229bfdff..e1fca0c7ed9 100644
--- a/admin/importers/tax-rates-importer.php
+++ b/admin/importers/tax-rates-importer.php
@@ -59,7 +59,7 @@ if ( class_exists( 'WP_Importer' ) ) {
else
$file = ABSPATH . $this->file_url;
- add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
+ add_filter( 'http_request_timeout', array( $this, 'bump_request_timeout' ) );
if ( function_exists( 'gc_enable' ) )
gc_enable();
@@ -149,28 +149,32 @@ if ( class_exists( 'WP_Importer' ) ) {
$postcodes = explode( ';', $postcode );
$postcodes = array_map( 'strtoupper', array_map( 'woocommerce_clean', $postcodes ) );
foreach( $postcodes as $postcode ) {
- $wpdb->insert(
- $wpdb->prefix . "woocommerce_tax_rate_locations",
- array(
- 'location_code' => $postcode,
- 'tax_rate_id' => $tax_rate_id,
- 'location_type' => 'postcode',
- )
- );
+ if ( ! empty( $postcode ) && $postcode != '*' ) {
+ $wpdb->insert(
+ $wpdb->prefix . "woocommerce_tax_rate_locations",
+ array(
+ 'location_code' => $postcode,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'postcode',
+ )
+ );
+ }
}
$city = woocommerce_clean( $city );
$cities = explode( ';', $city );
$cities = array_map( 'strtoupper', array_map( 'woocommerce_clean', $cities ) );
foreach( $cities as $city ) {
- $wpdb->insert(
- $wpdb->prefix . "woocommerce_tax_rate_locations",
- array(
- 'location_code' => $city,
- 'tax_rate_id' => $tax_rate_id,
- 'location_type' => 'city',
- )
- );
+ if ( ! empty( $city ) && $city != '*' ) {
+ $wpdb->insert(
+ $wpdb->prefix . "woocommerce_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
}
$loop ++;
diff --git a/admin/includes/notice-installed.php b/admin/includes/notice-installed.php
deleted file mode 100644
index c3d4117342b..00000000000
--- a/admin/includes/notice-installed.php
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
';
@@ -183,51 +188,51 @@ function woocommerce_custom_product_columns( $column ) {
echo '
-
' . $product->sku . '
-
' . $product->regular_price . '
-
' . $product->sale_price . '
-
' . $product->weight . '
-
' . $product->length . '
-
' . $product->width . '
-
' . $product->height . '
-
' . $product->visibility . '
-
' . $product->stock_status . '
-
' . $product->stock . '
-
' . $product->manage_stock . '
-
' . $product->featured . '
-
' . $product->product_type . '
-
' . $product->virtual . '
+
' . $the_product->sku . '
+
' . $the_product->regular_price . '
+
' . $the_product->sale_price . '
+
' . $the_product->weight . '
+
' . $the_product->length . '
+
' . $the_product->width . '
+
' . $the_product->height . '
+
' . $the_product->visibility . '
+
' . $the_product->stock_status . '
+
' . $the_product->stock . '
+
' . $the_product->manage_stock . '
+
' . $the_product->featured . '
+
' . $the_product->product_type . '
+
' . $the_product->virtual . '
';
break;
case "sku" :
- if ($product->get_sku()) echo $product->get_sku(); else echo '
– ';
+ if ($the_product->get_sku()) echo $the_product->get_sku(); else echo '
– ';
break;
case "product_type" :
- if( $product->product_type == 'grouped' ):
- echo '
';
- elseif ( $product->product_type == 'external' ):
- echo '
';
- elseif ( $product->product_type == 'simple' ):
+ if( $the_product->product_type == 'grouped' ):
+ echo '
';
+ elseif ( $the_product->product_type == 'external' ):
+ echo '
';
+ elseif ( $the_product->product_type == 'simple' ):
- if ($product->is_virtual()) {
+ if ($the_product->is_virtual()) {
echo '
';
- } elseif ($product->is_downloadable()) {
+ } elseif ($the_product->is_downloadable()) {
echo '
';
} else {
- echo '
';
+ echo '
';
}
- elseif ( $product->product_type == 'variable' ):
- echo '
';
+ elseif ( $the_product->product_type == 'variable' ):
+ echo '
';
else:
// Assuming that we have other types in future
- echo '
';
+ echo '
';
endif;
break;
case "price":
- if ($product->get_price_html()) echo $product->get_price_html(); else echo '
– ';
+ if ($the_product->get_price_html()) echo $the_product->get_price_html(); else echo '
– ';
break;
case "product_cat" :
case "product_tag" :
@@ -241,23 +246,26 @@ function woocommerce_custom_product_columns( $column ) {
echo implode( ', ', $termlist );
}
break;
- case "featured" :
- $url = wp_nonce_url( admin_url('admin-ajax.php?action=woocommerce-feature-product&product_id=' . $post->ID), 'woocommerce-feature-product' );
- echo '
';
- if ($product->is_featured()) echo ' ';
- else echo ' ';
+ case 'featured':
+ $url = wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-feature-product&product_id=' . $post->ID ), 'woocommerce-feature-product' );
+ echo '';
+ if ( $the_product->is_featured() ) {
+ echo ' ';
+ } else {
+ echo ' ';
+ }
echo ' ';
break;
case "is_in_stock" :
- if ($product->is_in_stock()) {
+ if ($the_product->is_in_stock()) {
echo '
' . __( 'In stock', 'woocommerce' ) . ' ';
} else {
echo '
' . __( 'Out of stock', 'woocommerce' ) . ' ';
}
- if ( $product->managing_stock() ) :
- echo ' × ' . $product->get_total_stock();
+ if ( $the_product->managing_stock() ) :
+ echo ' × ' . $the_product->get_total_stock();
endif;
break;
@@ -283,7 +291,6 @@ add_action('manage_product_posts_custom_column', 'woocommerce_custom_product_col
*/
function woocommerce_custom_product_sort($columns) {
$custom = array(
- 'is_in_stock' => 'inventory',
'price' => 'price',
'featured' => 'featured',
'sku' => 'sku',
@@ -306,12 +313,6 @@ add_filter( 'manage_edit-product_sortable_columns', 'woocommerce_custom_product_
*/
function woocommerce_custom_product_orderby( $vars ) {
if (isset( $vars['orderby'] )) :
- if ( 'inventory' == $vars['orderby'] ) :
- $vars = array_merge( $vars, array(
- 'meta_key' => '_stock',
- 'orderby' => 'meta_value_num'
- ) );
- endif;
if ( 'price' == $vars['orderby'] ) :
$vars = array_merge( $vars, array(
'meta_key' => '_price',
@@ -371,7 +372,7 @@ function woocommerce_products_by_type() {
$output = "
";
$output .= ''.__( 'Show all product types', 'woocommerce' ).' ';
foreach($terms as $term) :
- $output .="name ) . "' ";
if ( isset( $wp_query->query['product_type'] ) ) $output .=selected($term->slug, $wp_query->query['product_type'], false);
$output .=">";
@@ -702,54 +703,54 @@ add_action( 'admin_enqueue_scripts', 'woocommerce_admin_product_quick_edit_scrip
*/
function woocommerce_admin_product_quick_edit_save( $post_id, $post ) {
- if ( !$_POST ) return $post_id;
- if ( is_int( wp_is_post_revision( $post_id ) ) ) return;
- if( is_int( wp_is_post_autosave( $post_id ) ) ) return;
- if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
- if ( !isset($_POST['woocommerce_quick_edit_nonce']) || (isset($_POST['woocommerce_quick_edit_nonce']) && !wp_verify_nonce( $_POST['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ))) return $post_id;
- if ( !current_user_can( 'edit_post', $post_id )) return $post_id;
+ if ( ! $_POST || is_int( wp_is_post_revision( $post_id ) ) || is_int( wp_is_post_autosave( $post_id ) ) ) return $post_id;
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return $post_id;
+ if ( ! isset( $_POST['woocommerce_quick_edit_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ) ) return $post_id;
+ if ( ! current_user_can( 'edit_post', $post_id ) ) return $post_id;
if ( $post->post_type != 'product' ) return $post_id;
global $woocommerce, $wpdb;
- $product = get_product( $post );
+ $product = get_product( $post );
+ $old_regular_price = $product->regular_price;
+ $old_sale_price = $product->sale_price;
// Save fields
- if(isset($_POST['_sku'])) update_post_meta($post_id, '_sku', esc_html(stripslashes($_POST['_sku'])));
- if(isset($_POST['_weight'])) update_post_meta($post_id, '_weight', esc_html(stripslashes($_POST['_weight'])));
- if(isset($_POST['_length'])) update_post_meta($post_id, '_length', esc_html(stripslashes($_POST['_length'])));
- if(isset($_POST['_width'])) update_post_meta($post_id, '_width', esc_html(stripslashes($_POST['_width'])));
- if(isset($_POST['_height'])) update_post_meta($post_id, '_height', esc_html(stripslashes($_POST['_height'])));
- if(isset($_POST['_stock_status'])) update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
- if(isset($_POST['_visibility'])) update_post_meta( $post_id, '_visibility', stripslashes( $_POST['_visibility'] ) );
- if(isset($_POST['_featured'])) update_post_meta( $post_id, '_featured', 'yes' ); else update_post_meta( $post_id, '_featured', 'no' );
+ if ( isset( $_POST['_sku'] ) ) update_post_meta( $post_id, '_sku', woocommerce_clean( $_POST['_sku'] ) );
+ if ( isset( $_POST['_weight'] ) ) update_post_meta( $post_id, '_weight', woocommerce_clean( $_POST['_weight'] ) );
+ if ( isset( $_POST['_length'] ) ) update_post_meta( $post_id, '_length', woocommerce_clean( $_POST['_length'] ) );
+ if ( isset( $_POST['_width'] ) ) update_post_meta( $post_id, '_width', woocommerce_clean( $_POST['_width'] ) );
+ if ( isset( $_POST['_height'] ) ) update_post_meta( $post_id, '_height', woocommerce_clean( $_POST['_height'] ) );
+ if ( isset( $_POST['_stock_status'] ) ) update_post_meta( $post_id, '_stock_status', woocommerce_clean( $_POST['_stock_status'] ) );
+ if ( isset( $_POST['_visibility'] ) ) update_post_meta( $post_id, '_visibility', woocommerce_clean( $_POST['_visibility'] ) );
+ if ( isset( $_POST['_featured'] ) ) update_post_meta( $post_id, '_featured', 'yes' ); else update_post_meta( $post_id, '_featured', 'no' );
- if ($product->is_type('simple') || $product->is_type('external')) {
+ if ( $product->is_type('simple') || $product->is_type('external') ) {
- if(isset($_POST['_regular_price'])) update_post_meta( $post_id, '_regular_price', stripslashes( $_POST['_regular_price'] ) );
- if(isset($_POST['_sale_price'])) update_post_meta( $post_id, '_sale_price', stripslashes( $_POST['_sale_price'] ) );
+ if ( isset( $_POST['_regular_price'] ) ) update_post_meta( $post_id, '_regular_price', woocommerce_clean( $_POST['_regular_price'] ) );
+ if ( isset( $_POST['_sale_price'] ) ) update_post_meta( $post_id, '_sale_price', woocommerce_clean( $_POST['_sale_price'] ) );
// Handle price - remove dates and set to lowest
$price_changed = false;
- if(isset($_POST['_regular_price']) && stripslashes( $_POST['_regular_price'] )!=$product->regular_price) $price_changed = true;
- if(isset($_POST['_sale_price']) && stripslashes( $_POST['_sale_price'] )!=$product->sale_price) $price_changed = true;
+ if ( isset( $_POST['_regular_price'] ) && woocommerce_clean( $_POST['_regular_price'] ) != $old_regular_price ) $price_changed = true;
+ if ( isset( $_POST['_sale_price'] ) && woocommerce_clean( $_POST['_sale_price'] ) != $old_sale_price ) $price_changed = true;
- if ($price_changed) {
- update_post_meta( $post_id, '_sale_price_dates_from', '');
- update_post_meta( $post_id, '_sale_price_dates_to', '');
+ if ( $price_changed ) {
+ update_post_meta( $post_id, '_sale_price_dates_from', '' );
+ update_post_meta( $post_id, '_sale_price_dates_to', '' );
- if ($_POST['_sale_price'] != '') {
- update_post_meta( $post_id, '_price', stripslashes($_POST['_sale_price']) );
+ if ( isset( $_POST['_sale_price'] ) && $_POST['_sale_price'] != '' ) {
+ update_post_meta( $post_id, '_price', woocommerce_clean( $_POST['_sale_price'] ) );
} else {
- update_post_meta( $post_id, '_price', stripslashes($_POST['_regular_price']) );
+ update_post_meta( $post_id, '_price', woocommerce_clean( $_POST['_regular_price'] ) );
}
}
}
// Handle stock
- if (!$product->is_type('grouped')) {
- if (isset($_POST['_manage_stock'])) {
+ if ( ! $product->is_type('grouped') ) {
+ if ( isset( $_POST['_manage_stock'] ) ) {
update_post_meta( $post_id, '_manage_stock', 'yes' );
update_post_meta( $post_id, '_stock', (int) $_POST['_stock'] );
} else {
@@ -1003,7 +1004,9 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
global $woocommerce, $wpdb;
- $product = get_product( $post );
+ $product = get_product( $post );
+ $old_regular_price = $product->regular_price;
+ $old_sale_price = $product->sale_price;
// Save fields
if ( ! empty( $_REQUEST['change_weight'] ) && isset( $_REQUEST['_weight'] ) )
@@ -1034,7 +1037,6 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
if ( ! empty( $_REQUEST['change_regular_price'] ) ) {
- $old_price = $product->regular_price;
$change_regular_price = absint( $_REQUEST['change_regular_price'] );
$regular_price = esc_attr( stripslashes( $_REQUEST['_regular_price'] ) );
@@ -1045,22 +1047,22 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
case 2 :
if ( strstr( $regular_price, '%' ) ) {
$percent = str_replace( '%', '', $regular_price ) / 100;
- $new_price = $old_price + ( $old_price * $percent );
+ $new_price = $old_regular_price + ( $old_regular_price * $percent );
} else {
- $new_price = $old_price + $regular_price;
+ $new_price = $old_regular_price + $regular_price;
}
break;
case 3 :
if ( strstr( $regular_price, '%' ) ) {
$percent = str_replace( '%', '', $regular_price ) / 100;
- $new_price = $old_price - ( $old_price * $percent );
+ $new_price = $old_regular_price - ( $old_regular_price * $percent );
} else {
- $new_price = $old_price - $regular_price;
+ $new_price = $old_regular_price - $regular_price;
}
break;
}
- if ( isset( $new_price ) && $new_price != $product->regular_price ) {
+ if ( isset( $new_price ) && $new_price != $old_regular_price ) {
$price_changed = true;
update_post_meta( $post_id, '_regular_price', $new_price );
$product->regular_price = $new_price;
@@ -1069,7 +1071,6 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
if ( ! empty( $_REQUEST['change_sale_price'] ) ) {
- $old_price = $product->sale_price;
$change_sale_price = absint( $_REQUEST['change_sale_price'] );
$sale_price = esc_attr( stripslashes( $_REQUEST['_sale_price'] ) );
@@ -1080,17 +1081,17 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
case 2 :
if ( strstr( $sale_price, '%' ) ) {
$percent = str_replace( '%', '', $sale_price ) / 100;
- $new_price = $old_price + ( $old_price * $percent );
+ $new_price = $old_sale_price + ( $old_sale_price * $percent );
} else {
- $new_price = $old_price + $sale_price;
+ $new_price = $old_sale_price + $sale_price;
}
break;
case 3 :
if ( strstr( $sale_price, '%' ) ) {
$percent = str_replace( '%', '', $sale_price ) / 100;
- $new_price = $old_price - ( $old_price * $percent );
+ $new_price = $old_sale_price - ( $old_sale_price * $percent );
} else {
- $new_price = $old_price - $sale_price;
+ $new_price = $old_sale_price - $sale_price;
}
break;
case 4 :
@@ -1103,7 +1104,7 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
break;
}
- if ( isset( $new_price ) && $new_price != $product->sale_price ) {
+ if ( isset( $new_price ) && $new_price != $old_sale_price ) {
$price_changed = true;
update_post_meta( $post_id, '_sale_price', $new_price );
$product->sale_price = $new_price;
@@ -1197,3 +1198,24 @@ function woocommerce_disable_checked_ontop( $args ) {
}
add_filter( 'wp_terms_checklist_args', 'woocommerce_disable_checked_ontop' );
+
+/**
+ * Change label for insert buttons.
+ *
+ * @access public
+ * @param mixed $translation
+ * @param mixed $original
+ * @return void
+ */
+function woocommerce_change_insert_into_post( $strings ) {
+ global $post_type;
+
+ if ( $post_type == 'product' ) {
+ $strings['insertIntoPost'] = __( 'Insert into product', 'woocommerce' );
+ $strings['uploadedToThisPost'] = __( 'Uploaded to this product', 'woocommerce' );
+ }
+
+ return $strings;
+}
+
+add_filter( 'media_view_strings', 'woocommerce_change_insert_into_post' );
diff --git a/admin/post-types/shop_coupon.php b/admin/post-types/shop_coupon.php
index f1fb5b3e6ea..3441ad050c2 100644
--- a/admin/post-types/shop_coupon.php
+++ b/admin/post-types/shop_coupon.php
@@ -62,11 +62,11 @@ function woocommerce_custom_coupon_columns( $column ) {
if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
if ( 'trash' == $post->post_status )
- $actions['untrash'] = "ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID ) . "'>" . __( 'Restore', 'woocommerce' ) . " ";
+ $actions['untrash'] = "ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore' ) . " ";
elseif ( EMPTY_TRASH_DAYS )
- $actions['trash'] = "" . __( 'Trash', 'woocommerce' ) . " ";
+ $actions['trash'] = "" . __( 'Trash' ) . " ";
if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS )
- $actions['delete'] = "" . __( 'Delete Permanently', 'woocommerce' ) . " ";
+ $actions['delete'] = "" . __( 'Delete Permanently' ) . " ";
}
$actions = apply_filters( 'post_row_actions', $actions, $post );
diff --git a/admin/post-types/shop_order.php b/admin/post-types/shop_order.php
index 6b6f1cd5168..af7d0789d2a 100644
--- a/admin/post-types/shop_order.php
+++ b/admin/post-types/shop_order.php
@@ -64,20 +64,21 @@ add_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
* @return void
*/
function woocommerce_custom_order_columns( $column ) {
+ global $post, $woocommerce, $the_order;
- global $post, $woocommerce;
- $order = new WC_Order( $post->ID );
+ if ( empty( $the_order ) || $the_order->id != $post->ID )
+ $the_order = new WC_Order( $post->ID );
switch ( $column ) {
case "order_status" :
- printf( '%s ', sanitize_title( $order->status ), esc_html__( $order->status, 'woocommerce' ) );
+ printf( '%s ', sanitize_title( $the_order->status ), esc_html__( $the_order->status, 'woocommerce' ), esc_html__( $the_order->status, 'woocommerce' ) );
break;
case "order_title" :
- if ( $order->user_id )
- $user_info = get_userdata( $order->user_id );
+ if ( $the_order->user_id )
+ $user_info = get_userdata( $the_order->user_id );
if ( ! empty( $user_info ) ) {
@@ -94,35 +95,35 @@ function woocommerce_custom_order_columns( $column ) {
$user = __( 'Guest', 'woocommerce' );
}
- echo '' . sprintf( __( 'Order %s', 'woocommerce' ), esc_attr( $order->get_order_number() ) ) . ' ' . __( 'made by', 'woocommerce' ) . ' ' . $user;
+ echo '' . sprintf( __( 'Order %s', 'woocommerce' ), esc_attr( $the_order->get_order_number() ) ) . ' ' . __( 'made by', 'woocommerce' ) . ' ' . $user;
- if ( $order->billing_email )
- echo '' . __( 'Email:', 'woocommerce' ) . ' ' . '' . esc_html( $order->billing_email ) . ' ';
+ if ( $the_order->billing_email )
+ echo '' . __( 'Email:', 'woocommerce' ) . ' ' . '' . esc_html( $the_order->billing_email ) . ' ';
- if ( $order->billing_phone )
- echo '' . __( 'Tel:', 'woocommerce' ) . ' ' . esc_html( $order->billing_phone ) . ' ';
+ if ( $the_order->billing_phone )
+ echo '' . __( 'Tel:', 'woocommerce' ) . ' ' . esc_html( $the_order->billing_phone ) . ' ';
break;
case "billing_address" :
- if ( $order->get_formatted_billing_address() )
- echo '' . esc_html( preg_replace( '# #i', ', ', $order->get_formatted_billing_address() ) ) .' ';
+ if ( $the_order->get_formatted_billing_address() )
+ echo '' . esc_html( preg_replace( '# #i', ', ', $the_order->get_formatted_billing_address() ) ) .' ';
else
echo '–';
- if ( $order->payment_method_title )
- echo '' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $order->payment_method_title ) . ' ';
+ if ( $the_order->payment_method_title )
+ echo '' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $the_order->payment_method_title ) . ' ';
break;
case "shipping_address" :
- if ( $order->get_formatted_shipping_address() )
- echo ''. esc_html( preg_replace('# #i', ', ', $order->get_formatted_shipping_address() ) ) .' ';
+ if ( $the_order->get_formatted_shipping_address() )
+ echo ''. esc_html( preg_replace('# #i', ', ', $the_order->get_formatted_shipping_address() ) ) .' ';
else
echo '–';
- if ( $order->shipping_method_title )
- echo '' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $order->shipping_method_title ) . ' ';
+ if ( $the_order->shipping_method_title )
+ echo '' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $the_order->shipping_method_title ) . ' ';
break;
case "total_cost" :
- echo esc_html( strip_tags( $order->get_formatted_order_total() ) );
+ echo esc_html( strip_tags( $the_order->get_formatted_order_total() ) );
break;
case "order_date" :
@@ -147,45 +148,45 @@ function woocommerce_custom_order_columns( $column ) {
?>
status, array( 'pending', 'on-hold' ) ) )
- $actions[] = array(
+ if ( in_array( $the_order->status, array( 'pending', 'on-hold' ) ) )
+ $actions['processing'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-mark-order-processing&order_id=' . $post->ID ), 'woocommerce-mark-order-processing' ),
'name' => __( 'Processing', 'woocommerce' ),
'action' => "processing"
);
- if ( in_array( $order->status, array( 'pending', 'on-hold', 'processing' ) ) )
- $actions[] = array(
+ if ( in_array( $the_order->status, array( 'pending', 'on-hold', 'processing' ) ) )
+ $actions['complete'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-mark-order-complete&order_id=' . $post->ID ), 'woocommerce-mark-order-complete' ),
'name' => __( 'Complete', 'woocommerce' ),
'action' => "complete"
);
- $actions[] = array(
- 'url' => admin_url( 'post.php?post=' . $post->ID . '&action=edit' ),
- 'name' => __( 'View', 'woocommerce' ),
- 'action' => "view"
- );
+ $actions['view'] = array(
+ 'url' => admin_url( 'post.php?post=' . $post->ID . '&action=edit' ),
+ 'name' => __( 'View', 'woocommerce' ),
+ 'action' => "view"
+ );
- $actions = apply_filters( 'woocommerce_admin_order_actions', $actions, $order );
+ $actions = apply_filters( 'woocommerce_admin_order_actions', $actions, $the_order );
foreach ( $actions as $action ) {
$image = ( isset( $action['image_url'] ) ) ? $action['image_url'] : $woocommerce->plugin_url() . '/assets/images/icons/' . $action['action'] . '.png';
printf( ' ', esc_url( $action['url'] ), esc_attr( $action['name'] ), esc_attr( $image ), esc_attr( $action['name'] ) );
}
- do_action( 'woocommerce_admin_order_actions_end', $order );
+ do_action( 'woocommerce_admin_order_actions_end', $the_order );
?>
customer_note )
+ if ( $the_order->customer_note )
echo ' ';
else
echo ' ';
@@ -423,9 +424,8 @@ add_filter( 'request', 'woocommerce_custom_shop_order_orderby' );
function woocommerce_shop_order_search_custom_fields( $wp ) {
global $pagenow, $wpdb;
- if ( 'edit.php' != $pagenow ) return $wp;
- if ( ! isset( $wp->query_vars['s'] ) || ! $wp->query_vars['s'] ) return $wp;
- if ( $wp->query_vars['post_type'] != 'shop_order' ) return $wp;
+ if ( 'edit.php' != $pagenow || empty( $wp->query_vars['s'] ) || $wp->query_vars['post_type'] != 'shop_order' )
+ return $wp;
$search_fields = array_map( 'esc_attr', apply_filters( 'woocommerce_shop_order_search_fields', array(
'_order_key',
@@ -442,42 +442,54 @@ function woocommerce_shop_order_search_custom_fields( $wp ) {
'_billing_phone'
) ) );
- // Query matching custom fields - this seems faster than meta_query
- $post_ids = $wpdb->get_col(
- $wpdb->prepare(
- "SELECT post_id FROM " . $wpdb->postmeta . " WHERE meta_key IN ('" . implode( "','", $search_fields ) . "') AND meta_value LIKE '%%%s%%'", esc_attr( $_GET['s'] )
- )
- );
-
- // Query matching excerpts and titles
- $post_ids = array_merge( $post_ids, $wpdb->get_col( $wpdb->prepare('
- SELECT ' . $wpdb->posts . '.ID
- FROM ' . $wpdb->posts . '
- LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id
- LEFT JOIN ' . $wpdb->users . ' ON ' . $wpdb->postmeta . '.meta_value = ' . $wpdb->users . '.ID
- WHERE
- post_excerpt LIKE "%%%1$s%%" OR
- post_title LIKE "%%%1$s%%" OR
- (
- meta_key = "_customer_user" AND
- (
- user_login LIKE "%%%1$s%%" OR
- user_nicename LIKE "%%%1$s%%" OR
- user_email LIKE "%%%1$s%%" OR
- display_name LIKE "%%%1$s%%"
- )
- )
- ',
- esc_attr($_GET['s'])
- ) ) );
-
- // Add ID
$search_order_id = str_replace( 'Order #', '', $_GET['s'] );
- if ( is_numeric( $search_order_id ) )
- $post_ids[] = $search_order_id;
+ if ( ! is_numeric( $search_order_id ) )
+ $search_order_id = 0;
- // Add blank ID so not all results are returned if the search finds nothing
- $post_ids[] = 0;
+ // Search orders
+ $post_ids = array_merge(
+ $wpdb->get_col(
+ $wpdb->prepare( "
+ SELECT post_id
+ FROM {$wpdb->postmeta}
+ WHERE meta_key IN ('" . implode( "','", $search_fields ) . "')
+ AND meta_value LIKE '%%%s%%'",
+ esc_attr( $_GET['s'] )
+ )
+ ),
+ $wpdb->get_col(
+ $wpdb->prepare( "
+ SELECT order_id
+ FROM {$wpdb->prefix}woocommerce_order_items as order_items
+ WHERE order_item_name LIKE '%%%s%%'
+ ",
+ esc_attr( $_GET['s'] )
+ )
+ ),
+ $wpdb->get_col(
+ $wpdb->prepare( "
+ SELECT posts.ID
+ FROM {$wpdb->posts} as posts
+ LEFT JOIN {$wpdb->postmeta} as postmeta ON posts.ID = postmeta.post_id
+ LEFT JOIN {$wpdb->users} as users ON postmeta.meta_value = users.ID
+ WHERE
+ post_excerpt LIKE '%%%1\$s%%' OR
+ post_title LIKE '%%%1\$s%%' OR
+ (
+ meta_key = '_customer_user' AND
+ (
+ user_login LIKE '%%%1\$s%%' OR
+ user_nicename LIKE '%%%1\$s%%' OR
+ user_email LIKE '%%%1\$s%%' OR
+ display_name LIKE '%%%1\$s%%'
+ )
+ )
+ ",
+ esc_attr( $_GET['s'] )
+ )
+ ),
+ array( $search_order_id )
+ );
// Remove s - we don't want to search order name
unset( $wp->query_vars['s'] );
@@ -526,4 +538,27 @@ function woocommerce_add_custom_query_var($public_query_vars) {
return $public_query_vars;
}
-add_filter('query_vars', 'woocommerce_add_custom_query_var');
\ No newline at end of file
+add_filter('query_vars', 'woocommerce_add_custom_query_var');
+
+/**
+ * Remove item meta on permanent deletion
+ *
+ * @access public
+ * @return void
+ **/
+function woocommerce_delete_order_items( $postid )
+{
+ global $wpdb;
+
+ if ( get_post_type( $postid ) == 'shop_order' )
+ {
+ $wpdb->query( "
+ DELETE {$wpdb->prefix}woocommerce_order_items, {$wpdb->prefix}woocommerce_order_itemmeta
+ FROM {$wpdb->prefix}woocommerce_order_items
+ JOIN {$wpdb->prefix}woocommerce_order_itemmeta ON {$wpdb->prefix}woocommerce_order_items.order_item_id = {$wpdb->prefix}woocommerce_order_itemmeta.order_item_id
+ WHERE {$wpdb->prefix}woocommerce_order_items.order_id = '{$postid}';
+ " );
+ }
+}
+
+add_action( 'before_delete_post', 'woocommerce_delete_order_items' );
\ No newline at end of file
diff --git a/admin/post-types/writepanels/order-fee-html.php b/admin/post-types/writepanels/order-fee-html.php
index ab10170c13d..feb56fce461 100644
--- a/admin/post-types/writepanels/order-fee-html.php
+++ b/admin/post-types/writepanels/order-fee-html.php
@@ -11,6 +11,8 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
+
+
@@ -33,14 +35,20 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
+
+
1
:
+
+
+
+
\ No newline at end of file
diff --git a/admin/post-types/writepanels/order-item-html.php b/admin/post-types/writepanels/order-item-html.php
index 4fa5b9c7a90..a0ccb1fa1de 100644
--- a/admin/post-types/writepanels/order-item-html.php
+++ b/admin/post-types/writepanels/order-item-html.php
@@ -48,7 +48,6 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
'_line_subtotal_tax',
'_line_total',
'_line_tax',
- '_refunded'
) ) ) ) continue;
// Handle serialised fields
@@ -79,6 +78,8 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
+
+
+
+
@@ -109,10 +112,14 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
:
+
+
+
+
\ No newline at end of file
diff --git a/admin/post-types/writepanels/variation-admin-html.php b/admin/post-types/writepanels/variation-admin-html.php
index 790088b0fcd..09275816d65 100644
--- a/admin/post-types/writepanels/variation-admin-html.php
+++ b/admin/post-types/writepanels/variation-admin-html.php
@@ -21,15 +21,21 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
// Get terms for attribute taxonomy or value if its a custom attribute
if ( $attribute['is_taxonomy'] ) {
+
$post_terms = wp_get_post_terms( $parent_data['id'], $attribute['name'] );
+
foreach ( $post_terms as $term ) {
echo ' slug, false ) . ' value="' . esc_attr( $term->slug ) . '">' . apply_filters( 'woocommerce_variation_option_name', esc_html( $term->name ) ) . ' ';
}
+
} else {
- $options = explode( '|', $attribute['value'] );
+
+ $options = array_map( 'trim', explode( '|', $attribute['value'] ) );
+
foreach ( $options as $option ) {
- echo '' . ucfirst( apply_filters( 'woocommerce_variation_option_name', esc_html( $option ) ) ) . ' ';
+ echo '' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . ' ';
}
+
}
echo ' ';
@@ -50,11 +56,11 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
-
+
- [?]
+ [?]
@@ -63,11 +69,11 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
-
-
+
+
-
+
@@ -110,7 +116,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
$args = array(
'taxonomy' => 'product_shipping_class',
'hide_empty' => 0,
- 'show_option_all' => __( 'Same as parent', 'woocommerce' ),
+ 'show_option_none' => __( 'Same as parent', 'woocommerce' ),
'name' => 'variable_shipping_class[' . $loop . ']',
'id' => '',
'selected' => isset( $shipping_class ) ? esc_attr( $shipping_class ) : '',
@@ -120,11 +126,13 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
echo wp_dropdown_categories( $args );
?>
+
$value )
echo '' . esc_html( $value ) . ' ';
?>
+
@@ -132,7 +140,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
@@ -150,7 +158,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
-
+
@@ -165,7 +173,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/> [?]
-
+
diff --git a/admin/post-types/writepanels/writepanel-coupon_data.php b/admin/post-types/writepanels/writepanel-coupon_data.php
index f64d3817059..8a0ed594cf1 100644
--- a/admin/post-types/writepanels/writepanel-coupon_data.php
+++ b/admin/post-types/writepanels/writepanel-coupon_data.php
@@ -42,13 +42,13 @@ function woocommerce_coupon_data_meta_box( $post ) {
woocommerce_wp_select( array( 'id' => 'discount_type', 'label' => __( 'Discount type', 'woocommerce' ), 'options' => $woocommerce->get_coupon_discount_types() ) );
// Amount
- woocommerce_wp_text_input( array( 'id' => 'coupon_amount', 'label' => __( 'Coupon amount', 'woocommerce' ), 'placeholder' => '0.00', 'description' => __( 'Enter an amount e.g. 2.99', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array(
+ woocommerce_wp_text_input( array( 'id' => 'coupon_amount', 'label' => __( 'Coupon amount', 'woocommerce' ), 'placeholder' => '0.00', 'description' => __( 'Value of the coupon.', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array(
'step' => 'any',
'min' => '0'
) ) );
// Free Shipping
- woocommerce_wp_checkbox( array( 'id' => 'free_shipping', 'label' => __( 'Enable free shipping', 'woocommerce' ), 'description' => sprintf(__( 'Check this box if the coupon grants free shipping. The free shipping method must be enabled with the "must use coupon" setting checked.', 'woocommerce' ), admin_url('admin.php?page=woocommerce_settings&tab=shipping§ion=WC_Free_Shipping')) ) );
+ woocommerce_wp_checkbox( array( 'id' => 'free_shipping', 'label' => __( 'Enable free shipping', 'woocommerce' ), 'description' => sprintf(__( 'Check this box if the coupon grants free shipping. The free shipping method must be enabled with the "must use coupon" setting checked.', 'woocommerce' ), admin_url('admin.php?page=woocommerce_settings&tab=shipping§ion=WC_Shipping_Free_Shipping')) ) );
// Individual use
woocommerce_wp_checkbox( array( 'id' => 'individual_use', 'label' => __( 'Individual use', 'woocommerce' ), 'description' => __( 'Check this box if the coupon cannot be used in conjunction with other coupons.', 'woocommerce' ) ) );
@@ -56,6 +56,9 @@ function woocommerce_coupon_data_meta_box( $post ) {
// Apply before tax
woocommerce_wp_checkbox( array( 'id' => 'apply_before_tax', 'label' => __( 'Apply before tax', 'woocommerce' ), 'description' => __( 'Check this box if the coupon should be applied before calculating cart tax.', 'woocommerce' ) ) );
+ // Exclude Sale Products
+ woocommerce_wp_checkbox( array( 'id' => 'exclude_sale_items', 'label' => __( 'Exclude sale items', 'woocommerce' ), 'description' => __( 'Check this box if the coupon should not apply to items on sale. Per-item coupons will only work if the item is not on sale. Per-cart coupons will only work if there are no sale items in the cart.', 'woocommerce' ) ) );
+
echo '';
// minimum spend
@@ -75,16 +78,11 @@ function woocommerce_coupon_data_meta_box( $post ) {
if ( $product_ids ) {
$product_ids = array_map( 'absint', explode( ',', $product_ids ) );
foreach ( $product_ids as $product_id ) {
- $title = get_the_title( $product_id );
- $sku = get_post_meta( $product_id, '_sku', true );
- if ( ! $title )
- continue;
+ $product = get_product( $product_id );
+ $product_name = woocommerce_get_formatted_product_name( $product );
- if ( ! empty( $sku ) )
- $sku = ' (SKU: ' . $sku . ')';
-
- echo '
' . esc_html( $title . $sku ) . ' ';
+ echo '
' . wp_kses_post( $product_name ) . ' ';
}
}
?>
@@ -100,16 +98,11 @@ function woocommerce_coupon_data_meta_box( $post ) {
if ( $product_ids ) {
$product_ids = array_map( 'absint', explode( ',', $product_ids ) );
foreach ( $product_ids as $product_id ) {
- $title = get_the_title( $product_id );
- $sku = get_post_meta( $product_id, '_sku', true );
- if ( ! $title )
- continue;
+ $product = get_product( $product_id );
+ $product_name = woocommerce_get_formatted_product_name( $product );
- if ( ! empty( $sku ) )
- $sku = ' (SKU: ' . $sku . ')';
-
- echo '
' . esc_html( $title . $sku ) . ' ';
+ echo '
' . esc_html( $product_name ) . ' ';
}
}
?>
@@ -209,6 +202,7 @@ function woocommerce_process_shop_coupon_meta( $post_id, $post ) {
$expiry_date = woocommerce_clean( $_POST['expiry_date'] );
$apply_before_tax = isset( $_POST['apply_before_tax'] ) ? 'yes' : 'no';
$free_shipping = isset( $_POST['free_shipping'] ) ? 'yes' : 'no';
+ $exclude_sale_items = isset( $_POST['exclude_sale_items'] ) ? 'yes' : 'no';
$minimum_amount = woocommerce_clean( $_POST['minimum_amount'] );
$customer_email = array_filter( array_map( 'trim', explode( ',', woocommerce_clean( $_POST['customer_email'] ) ) ) );
@@ -237,6 +231,7 @@ function woocommerce_process_shop_coupon_meta( $post_id, $post ) {
update_post_meta( $post_id, 'expiry_date', $expiry_date );
update_post_meta( $post_id, 'apply_before_tax', $apply_before_tax );
update_post_meta( $post_id, 'free_shipping', $free_shipping );
+ update_post_meta( $post_id, 'exclude_sale_items', $exclude_sale_items );
update_post_meta( $post_id, 'product_categories', $product_categories );
update_post_meta( $post_id, 'exclude_product_categories', $exclude_product_categories );
update_post_meta( $post_id, 'minimum_amount', $minimum_amount );
diff --git a/admin/post-types/writepanels/writepanel-order_data.php b/admin/post-types/writepanels/writepanel-order_data.php
index 5e7fcebda54..3b78b03078c 100644
--- a/admin/post-types/writepanels/writepanel-order_data.php
+++ b/admin/post-types/writepanels/writepanel-order_data.php
@@ -49,82 +49,95 @@ function woocommerce_order_data_meta_box($post) {
$order_title = $post->post_title;
?>
-
+
+
— get_order_number() ); ?>
+ echo __( 'Order number', 'woocommerce' ) . ' ' . esc_html( $order->get_order_number() ) . '. ';
-
-
- 0, 'orderby' => 'id' ) );
- foreach ( $statuses as $status ) {
- echo 'slug, $order_status, false ) . '>' . esc_html__( $status->name, 'woocommerce' ) . ' ';
- }
- ?>
-
+ $ip_address = get_post_meta( $post->ID, '_customer_ip_address', true );
-
- @ :
-
+ if ( $ip_address )
+ echo __( 'Customer IP:', 'woocommerce' ) . ' ' . esc_html( $ip_address );
-
-
-
-
+ ?>
+
+
+
+
+
+
+
+
ID ) . '" ' . selected( 1, 1, false ) . '>' . esc_html( $user->display_name ) . ' (#' . absint( $user->ID ) . ' – ' . esc_html( $user->user_email ) . ')';
+ $statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
+ foreach ( $statuses as $status ) {
+ echo 'slug, $order_status, false ) . '>' . esc_html__( $status->name, 'woocommerce' ) . ' ';
}
?>
-
-
- // Ajax Chosen Customer Selectors JS
- $woocommerce->add_inline_js( "
- jQuery('select.ajax_chosen_select_customer').ajaxChosen({
- method: 'GET',
- url: '" . admin_url('admin-ajax.php') . "',
- dataType: 'json',
- afterTypeDelay: 100,
- minTermLength: 1,
- data: {
- action: 'woocommerce_json_search_customers',
- security: '" . wp_create_nonce("search-customers") . "'
- }
- }, function (data) {
+
+ @ :
+
- var terms = {};
+
+
+
+
+ ID ) . '" ' . selected( 1, 1, false ) . '>' . esc_html( $user->display_name ) . ' (#' . absint( $user->ID ) . ' – ' . esc_html( $user->user_email ) . ')';
+ }
+ ?>
+
+ add_inline_js( "
+ jQuery('select.ajax_chosen_select_customer').ajaxChosen({
+ method: 'GET',
+ url: '" . admin_url('admin-ajax.php') . "',
+ dataType: 'json',
+ afterTypeDelay: 100,
+ minTermLength: 1,
+ data: {
+ action: 'woocommerce_json_search_customers',
+ security: '" . wp_create_nonce("search-customers") . "'
+ }
+ }, function (data) {
- return terms;
- });
- " );
+ var terms = {};
- ?>
-
+ $.each(data, function (i, val) {
+ terms[i] = val;
+ });
-
-
-
-
+ return terms;
+ });
+ " );
+ ?>
+
-
+
-
-
-
+
+
array(
@@ -182,7 +195,7 @@ function woocommerce_order_data_meta_box($post) {
echo '
' . __( 'Address', 'woocommerce' ) . ': ' . __( 'No billing address set.', 'woocommerce' ) . '
';
foreach ( $billing_data as $key => $field ) {
- if ( empty( $field['show'] ) )
+ if ( isset( $field['show'] ) && $field['show'] === false )
continue;
$field_name = 'billing_' . $key;
if ( $order->$field_name )
@@ -212,9 +225,9 @@ function woocommerce_order_data_meta_box($post) {
do_action( 'woocommerce_admin_order_data_after_billing_address', $order );
?>
-
+
-
+
array(
@@ -266,7 +279,7 @@ function woocommerce_order_data_meta_box($post) {
echo '
' . __( 'Address', 'woocommerce' ) . ': ' . __( 'No shipping address set.', 'woocommerce' ) . '
';
if ( $shipping_data ) foreach ( $shipping_data as $key => $field ) {
- if ( empty( $field['show'] ) )
+ if ( isset( $field['show'] ) && $field['show'] === false )
continue;
$field_name = 'shipping_' . $key;
if ( $order->$field_name )
@@ -316,7 +329,7 @@ function woocommerce_order_items_meta_box( $post ) {
$order = $theorder;
- $data = get_post_custom( $post->ID );
+ $data = get_post_meta( $post->ID );
?>
@@ -327,13 +340,17 @@ function woocommerce_order_items_meta_box( $post ) {
- [?]
+
+ [?]
+
[?]
-
+
+
+
@@ -344,14 +361,13 @@ function woocommerce_order_items_meta_box( $post ) {
foreach ( $order_items as $item_id => $item ) {
- $class = ( isset( $item['refunded'] ) ) ? 'refunded' : '';
-
switch ( $item['type'] ) {
case 'line_item' :
$_product = $order->get_product_from_item( $item );
$item_meta = $order->get_item_meta( $item_id );
- include( 'order-item-html.php' );
+ if ( $_product )
+ include( 'order-item-html.php' );
break;
case 'fee' :
include( 'order-fee-html.php' );
@@ -371,23 +387,6 @@ function woocommerce_order_items_meta_box( $post ) {
-
- payment_gateways->payment_gateways();
-
- if ( isset( $gateways[ $order->payment_method ] ) ) {
- $gateway = $gateways[ $order->payment_method ];
-
- if ( ! in_array( 'refunds', $gateway->supports ) || ! method_exists( $gateway, 'refund' ) ) {
- $supports_refunds = false;
- } else {
- $supports_refunds = true;
- }
-
- echo '' . sprintf( __( 'Refund Lines via %s', 'woocommerce' ), $order->payment_method ) . ' ';
- }
- echo '' . __( 'Mark Lines Refunded', 'woocommerce' ) . ' ';
- ?>
@@ -395,7 +394,7 @@ function woocommerce_order_items_meta_box( $post ) {
-
+
@@ -450,27 +449,12 @@ function woocommerce_order_actions_meta_box( $post ) {
}
?>
-
- payment_gateways->payment_gateways();
-
- if ( isset( $gateways[ $order->payment_method ] ) ) {
- $gateway = $gateways[ $order->payment_method ];
-
- if ( ! in_array( 'refunds', $gateway->supports ) || ! method_exists( $gateway, 'refund' ) ) {
- $supports_refunds = false;
- } else {
- $supports_refunds = true;
- }
-
- echo '' . sprintf( __( 'Refund Order via %s', 'woocommerce' ), $order->payment_method ) . ' ';
- }
- echo '' . __( 'Mark Order Refunded', 'woocommerce' ) . ' ';
- ?>
-
+ $title ) { ?>
+
+
-
+
@@ -506,7 +490,7 @@ function woocommerce_order_totals_meta_box( $post ) {
$order = $theorder;
- $data = get_post_custom( $post->ID );
+ $data = get_post_meta( $post->ID );
?>
@@ -574,10 +558,10 @@ function woocommerce_order_totals_meta_box( $post ) {
shipping ) {
+ if ( $woocommerce->shipping() ) {
foreach ( $woocommerce->shipping->load_shipping_methods() as $method ) {
if ( strpos( $chosen_method, $method->id ) === 0 )
@@ -604,6 +588,9 @@ function woocommerce_order_totals_meta_box( $post ) {
ID ) ?>
+
+
+
@@ -656,6 +643,9 @@ function woocommerce_order_totals_meta_box( $post ) {
+
+
+
-
+
+
+
$value ) {
+ foreach ( $meta_keys as $id => $meta_key ) {
+ $meta_value = ( empty( $meta_values[ $id ] ) && ! is_numeric( $meta_values[ $id ] ) ) ? '' : $meta_values[ $id ];
$wpdb->update(
$wpdb->prefix . "woocommerce_order_itemmeta",
array(
- 'meta_key' => $value,
- 'meta_value' => empty( $meta_values[ $id ] ) ? '' : $meta_values[ $id ]
+ 'meta_key' => $meta_key,
+ 'meta_value' => $meta_value
),
array( 'meta_id' => $id ),
array( '%s', '%s' ),
@@ -944,15 +935,7 @@ function woocommerce_process_shop_order_meta( $post_id, $post ) {
}
}
- do_action( 'woocommerce_after_resend_order_emails', $order, $resend_emails );
-
- } elseif ( $action == 'refund_order' ) {
-
- $order->refund_order( true );
-
- } elseif ( $action == 'manual_refund_order' ) {
-
- $order->refund_order( false );
+ do_action( 'woocommerce_after_resend_order_email', $order, $email_to_send );
} else {
diff --git a/admin/post-types/writepanels/writepanel-order_downloads.php b/admin/post-types/writepanels/writepanel-order_downloads.php
index 6ea2cbe88c8..d79987712d4 100644
--- a/admin/post-types/writepanels/writepanel-order_downloads.php
+++ b/admin/post-types/writepanels/writepanel-order_downloads.php
@@ -75,12 +75,10 @@ function woocommerce_order_downloads_meta_box() {
if ( $products ) foreach ( $products as $product ) {
- $sku = get_post_meta( $product->ID, '_sku', true );
+ $product_object = get_product( $product->ID );
+ $product_name = woocommerce_get_formatted_product_name( $product_object );
- if ( $sku )
- $sku = ' SKU: ' . $sku;
-
- echo '
' . esc_html( $product->post_title . ' (#' . $product->ID . '' . $sku . ')' ) . ' ';
+ echo '
' . esc_html( $product_name ) . ' ';
}
?>
@@ -124,7 +122,7 @@ function woocommerce_order_downloads_meta_box() {
} else {
- alert('');
+ alert('');
}
diff --git a/admin/post-types/writepanels/writepanel-order_notes.php b/admin/post-types/writepanels/writepanel-order_notes.php
index f64e90c7bb1..0d8b31a0a01 100644
--- a/admin/post-types/writepanels/writepanel-order_notes.php
+++ b/admin/post-types/writepanels/writepanel-order_notes.php
@@ -67,7 +67,9 @@ function woocommerce_order_notes_meta_box() {
payment_gateways->process_admin_options();
+ break;
+ case "shipping" :
+ woocommerce_update_options( $woocommerce_settings[ $current_tab ] );
+ $woocommerce->shipping->process_admin_options();
+ break;
+ default :
+ if ( isset( $woocommerce_settings[ $current_tab ] ) )
+ woocommerce_update_options( $woocommerce_settings[ $current_tab ] );
+
+ // Trigger action for tab
+ do_action( 'woocommerce_update_options_' . $current_tab );
break;
}
do_action( 'woocommerce_update_options' );
- do_action( 'woocommerce_update_options_' . $current_tab );
// Handle Colour Settings
if ( $current_tab == 'general' && get_option('woocommerce_frontend_css') == 'yes' ) {
@@ -95,7 +99,7 @@ if ( ! function_exists( 'woocommerce_settings' ) ) {
} else {
// If saving a shipping methods options, load 'er up
- if ( $current_tab == 'shipping' && class_exists( $current_section ) ) {
+ if ( ( $current_tab == 'shipping' || $current_tab == 'payment_gateways' && class_exists( $current_section ) ) ) {
$current_section_class = new $current_section();
do_action( 'woocommerce_update_options_' . $current_tab . '_' . $current_section_class->id );
@@ -104,7 +108,7 @@ if ( ! function_exists( 'woocommerce_settings' ) ) {
} elseif ( $current_tab == 'email' ) {
// Load mailer
- $mailer = $woocommerce->mailer();
+ $mailer = $woocommerce->mailer();
if ( class_exists( $current_section ) ) {
$current_section_class = new $current_section();
@@ -165,45 +169,8 @@ if ( ! function_exists( 'woocommerce_settings' ) ) {
}
// Hide WC Link
- if (isset($_GET['hide-wc-extensions-message']))
- update_option('hide-wc-extensions-message', 1);
-
- // Install/page installer
- $install_complete = false;
-
- // Add pages button
- if (isset($_GET['install_woocommerce_pages']) && $_GET['install_woocommerce_pages']) {
-
- require_once( 'woocommerce-admin-install.php' );
- woocommerce_create_pages();
- update_option('skip_install_woocommerce_pages', 1);
- $install_complete = true;
-
- // Skip button
- } elseif (isset($_GET['skip_install_woocommerce_pages']) && $_GET['skip_install_woocommerce_pages']) {
-
- update_option('skip_install_woocommerce_pages', 1);
- $install_complete = true;
-
- }
-
- if ($install_complete) {
- ?>
-
-
-
Congratulations! – WooCommerce has been installed and setup. Enjoy :)', 'woocommerce' ); ?>
-
-
-
-
-
');
+ event.preventDefault();
- var img = jQuery('#temp_image').find('img');
+ // If the media frame already exists, reopen it.
+ if ( file_frame ) {
+ file_frame.open();
+ return;
+ }
- imgurl = img.attr('src');
- imgclass = img.attr('class');
- imgid = parseInt(imgclass.replace(/\D/g, ''), 10);
+ // Create the media frame.
+ file_frame = wp.media.frames.downloadable_file = wp.media({
+ title: '',
+ button: {
+ text: '',
+ },
+ multiple: false
+ });
- jQuery('#product_cat_thumbnail_id').val(imgid);
- jQuery('#product_cat_thumbnail img').attr('src', imgurl);
- jQuery('.remove_image_button').show();
- jQuery('#temp_image').remove();
+ // When an image is selected, run a callback.
+ file_frame.on( 'select', function() {
+ attachment = file_frame.state().get('selection').first().toJSON();
- tb_remove();
+ jQuery('#product_cat_thumbnail_id').val( attachment.id );
+ jQuery('#product_cat_thumbnail img').attr('src', attachment.url );
+ jQuery('.remove_image_button').show();
+ });
- window.send_to_editor = window.send_to_editor_default;
- }
-
- jQuery('.upload_image_button').live('click', function(){
- var post_id = 0;
-
- window.send_to_editor = window.send_to_termmeta;
-
- tb_show('', 'media-upload.php?post_id=' + post_id + '&type=image&TB_iframe=true');
- return false;
+ // Finally, open the modal.
+ file_frame.open();
});
- jQuery('.remove_image_button').live('click', function(){
+ jQuery(document).on( 'click', '.remove_image_button', function( event ){
jQuery('#product_cat_thumbnail img').attr('src', '');
jQuery('#product_cat_thumbnail_id').val('');
jQuery('.remove_image_button').hide();
@@ -132,35 +136,45 @@ function woocommerce_edit_category_fields( $term, $taxonomy ) {
' /* html or false to disable */
+ }, pp_settings);
+
+ // Global variables accessible only by prettyPhoto
+ var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
+
+ // prettyPhoto container specific
+ pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
+
+ // Window size
+ windowHeight = $(window).height(), windowWidth = $(window).width(),
+
+ // Global elements
+ pp_slideshow;
+
+ doresize = true, scroll_pos = _get_scroll();
+
+ // Window/Keyboard events
+ $(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
+
+ if(pp_settings.keyboard_shortcuts) {
+ $(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
+ if(typeof $pp_pic_holder != 'undefined'){
+ if($pp_pic_holder.is(':visible')){
+ switch(e.keyCode){
+ case 37:
+ $.prettyPhoto.changePage('previous');
+ e.preventDefault();
+ break;
+ case 39:
+ $.prettyPhoto.changePage('next');
+ e.preventDefault();
+ break;
+ case 27:
+ if(!settings.modal)
+ $.prettyPhoto.close();
+ e.preventDefault();
+ break;
+ };
+ // return false;
+ };
+ };
+ });
+ };
+
+ /**
+ * Initialize prettyPhoto.
+ */
+ $.prettyPhoto.initialize = function() {
+
+ settings = pp_settings;
+
+ if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
+
+ // Find out if the picture is part of a set
+ theRel = $(this).attr(settings.hook);
+ galleryRegExp = /\[(?:.*)\]/;
+ isSet = (galleryRegExp.exec(theRel)) ? true : false;
+
+ // Put the SRCs, TITLEs, ALTs into an array.
+ pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
+ pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
+ pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
+
+ if(pp_images.length > settings.overlay_gallery_max) settings.overlay_gallery = false;
+
+ set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
+ rel_index = (isSet) ? set_position : $("a["+settings.hook+"^='"+theRel+"']").index($(this));
+
+ _build_overlay(this); // Build the overlay {this} being the caller
+
+ if(settings.allow_resize)
+ $(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
+
+
+ $.prettyPhoto.open();
+
+ return false;
+ }
+
+
+ /**
+ * Opens the prettyPhoto modal box.
+ * @param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
+ * @param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
+ * @param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
+ */
+ $.prettyPhoto.open = function(event) {
+ if(typeof settings == "undefined"){ // Means it's an API call, need to manually get the settings and set the variables
+ settings = pp_settings;
+ pp_images = $.makeArray(arguments[0]);
+ pp_titles = (arguments[1]) ? $.makeArray(arguments[1]) : $.makeArray("");
+ pp_descriptions = (arguments[2]) ? $.makeArray(arguments[2]) : $.makeArray("");
+ isSet = (pp_images.length > 1) ? true : false;
+ set_position = (arguments[3])? arguments[3]: 0;
+ _build_overlay(event.target); // Build the overlay {this} being the caller
+ }
+
+ if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
+
+ _checkPosition($(pp_images).size()); // Hide the next/previous links if on first or last images.
+
+ $('.pp_loaderIcon').show();
+
+ if(settings.deeplinking)
+ setHashtag();
+
+ // Rebuild Facebook Like Button with updated href
+ if(settings.social_tools){
+ facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
+ $pp_pic_holder.find('.pp_social').html(facebook_like_link);
+ }
+
+ // Fade the content in
+ if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
+ $pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
+
+ // Display the current position
+ $pp_pic_holder.find('.currentTextHolder').text((set_position+1) + settings.counter_separator_label + $(pp_images).size());
+
+ // Set the description
+ if(typeof pp_descriptions[set_position] != 'undefined' && pp_descriptions[set_position] != ""){
+ $pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));
+ }else{
+ $pp_pic_holder.find('.pp_description').hide();
+ }
+
+ // Get the dimensions
+ movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
+ movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
+
+ // If the size is % based, calculate according to window dimensions
+ percentBased=false;
+ if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
+ if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
+
+ // Fade the holder
+ $pp_pic_holder.fadeIn(function(){
+ // Set the title
+ (settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html(' ');
+
+ imgPreloader = "";
+ skipInjection = false;
+
+ // Inject the proper content
+ switch(_getFileType(pp_images[set_position])){
+ case 'image':
+ imgPreloader = new Image();
+
+ // Preload the neighbour images
+ nextImage = new Image();
+ if(isSet && set_position < $(pp_images).size() -1) nextImage.src = pp_images[set_position + 1];
+ prevImage = new Image();
+ if(isSet && pp_images[set_position - 1]) prevImage.src = pp_images[set_position - 1];
+
+ $pp_pic_holder.find('#pp_full_res')[0].innerHTML = settings.image_markup.replace(/{path}/g,pp_images[set_position]);
+
+ imgPreloader.onload = function(){
+ // Fit item to viewport
+ pp_dimensions = _fitToViewport(imgPreloader.width,imgPreloader.height);
+
+ _showContent();
+ };
+
+ imgPreloader.onerror = function(){
+ alert('Image cannot be loaded. Make sure the path is correct and image exist.');
+ $.prettyPhoto.close();
+ };
+
+ imgPreloader.src = pp_images[set_position];
+ break;
+
+ case 'youtube':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ // Regular youtube link
+ movie_id = getParam('v',pp_images[set_position]);
+
+ // youtu.be link
+ if(movie_id == ""){
+ movie_id = pp_images[set_position].split('youtu.be/');
+ movie_id = movie_id[1];
+ if(movie_id.indexOf('?') > 0)
+ movie_id = movie_id.substr(0,movie_id.indexOf('?')); // Strip anything after the ?
+
+ if(movie_id.indexOf('&') > 0)
+ movie_id = movie_id.substr(0,movie_id.indexOf('&')); // Strip anything after the &
+ }
+
+ movie = 'http://www.youtube.com/embed/'+movie_id;
+ (getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
+
+ if(settings.autoplay) movie += "&autoplay=1";
+
+ toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
+ break;
+
+ case 'vimeo':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ movie_id = pp_images[set_position];
+ var regExp = /http(s?):\/\/(www\.)?vimeo.com\/(\d+)/;
+ var match = movie_id.match(regExp);
+
+ movie = 'http://player.vimeo.com/video/'+ match[3] +'?title=0&byline=0&portrait=0';
+ if(settings.autoplay) movie += "&autoplay=1;";
+
+ vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
+
+ toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
+ break;
+
+ case 'quicktime':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+ pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
+
+ toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
+ break;
+
+ case 'flash':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ flash_vars = pp_images[set_position];
+ flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
+
+ filename = pp_images[set_position];
+ filename = filename.substring(0,filename.indexOf('?'));
+
+ toInject = settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
+ break;
+
+ case 'iframe':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ frame_url = pp_images[set_position];
+ frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
+
+ toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
+ break;
+
+ case 'ajax':
+ doresize = false; // Make sure the dimensions are not resized.
+ pp_dimensions = _fitToViewport(movie_width,movie_height);
+ doresize = true; // Reset the dimensions
+
+ skipInjection = true;
+ $.get(pp_images[set_position],function(responseHTML){
+ toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
+ $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
+ _showContent();
+ });
+
+ break;
+
+ case 'custom':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ toInject = settings.custom_markup;
+ break;
+
+ case 'inline':
+ // to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
+ myClone = $(pp_images[set_position]).clone().append(' ').css({'width':settings.default_width}).wrapInner('').appendTo($('body')).show();
+ doresize = false; // Make sure the dimensions are not resized.
+ pp_dimensions = _fitToViewport($(myClone).width(),$(myClone).height());
+ doresize = true; // Reset the dimensions
+ $(myClone).remove();
+ toInject = settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());
+ break;
+ };
+
+ if(!imgPreloader && !skipInjection){
+ $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
+
+ // Show content
+ _showContent();
+ };
+ });
+
+ return false;
+ };
+
+
+ /**
+ * Change page in the prettyPhoto modal box
+ * @param direction {String} Direction of the paging, previous or next.
+ */
+ $.prettyPhoto.changePage = function(direction){
+ currentGalleryPage = 0;
+
+ if(direction == 'previous') {
+ set_position--;
+ if (set_position < 0) set_position = $(pp_images).size()-1;
+ }else if(direction == 'next'){
+ set_position++;
+ if(set_position > $(pp_images).size()-1) set_position = 0;
+ }else{
+ set_position=direction;
+ };
+
+ rel_index = set_position;
+
+ if(!doresize) doresize = true; // Allow the resizing of the images
+ if(settings.allow_expand) {
+ $('.pp_contract').removeClass('pp_contract').addClass('pp_expand');
+ }
+
+ _hideContent(function(){ $.prettyPhoto.open(); });
+ };
+
+
+ /**
+ * Change gallery page in the prettyPhoto modal box
+ * @param direction {String} Direction of the paging, previous or next.
+ */
+ $.prettyPhoto.changeGalleryPage = function(direction){
+ if(direction=='next'){
+ currentGalleryPage ++;
+
+ if(currentGalleryPage > totalPage) currentGalleryPage = 0;
+ }else if(direction=='previous'){
+ currentGalleryPage --;
+
+ if(currentGalleryPage < 0) currentGalleryPage = totalPage;
+ }else{
+ currentGalleryPage = direction;
+ };
+
+ slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
+
+ slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
+
+ $pp_gallery.find('ul').animate({left:-slide_to},slide_speed);
+ };
+
+
+ /**
+ * Start the slideshow...
+ */
+ $.prettyPhoto.startSlideshow = function(){
+ if(typeof pp_slideshow == 'undefined'){
+ $pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+ pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
+ }else{
+ $.prettyPhoto.changePage('next');
+ };
+ }
+
+
+ /**
+ * Stop the slideshow...
+ */
+ $.prettyPhoto.stopSlideshow = function(){
+ $pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){
+ $.prettyPhoto.startSlideshow();
+ return false;
+ });
+ clearInterval(pp_slideshow);
+ pp_slideshow=undefined;
+ }
+
+
+ /**
+ * Closes prettyPhoto.
+ */
+ $.prettyPhoto.close = function(){
+ if($pp_overlay.is(":animated")) return;
+
+ $.prettyPhoto.stopSlideshow();
+
+ $pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
+
+ $('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
+
+ $pp_overlay.fadeOut(settings.animation_speed, function(){
+
+ if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
+
+ $(this).remove(); // No more need for the prettyPhoto markup
+
+ $(window).unbind('scroll.prettyphoto');
+
+ clearHashtag();
+
+ settings.callback();
+
+ doresize = true;
+
+ pp_open = false;
+
+ delete settings;
+ });
+ };
+
+ /**
+ * Set the proper sizes on the containers and animate the content in.
+ */
+ function _showContent(){
+ $('.pp_loaderIcon').hide();
+
+ // Calculate the opened top position of the pic holder
+ projectedTop = scroll_pos['scrollTop'] + ((windowHeight/2) - (pp_dimensions['containerHeight']/2));
+ if(projectedTop < 0) projectedTop = 0;
+
+ $ppt.fadeTo(settings.animation_speed,1);
+
+ // Resize the content holder
+ $pp_pic_holder.find('.pp_content')
+ .animate({
+ height:pp_dimensions['contentHeight'],
+ width:pp_dimensions['contentWidth']
+ },settings.animation_speed);
+
+ // Resize picture the holder
+ $pp_pic_holder.animate({
+ 'top': projectedTop,
+ 'left': ((windowWidth/2) - (pp_dimensions['containerWidth']/2) < 0) ? 0 : (windowWidth/2) - (pp_dimensions['containerWidth']/2),
+ width:pp_dimensions['containerWidth']
+ },settings.animation_speed,function(){
+ $pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);
+
+ $pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed); // Fade the new content
+
+ // Show the nav
+ if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
+
+ if(settings.allow_expand) {
+ if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
+ $('a.pp_expand,a.pp_contract').show();
+ }else{
+ $('a.pp_expand').hide();
+ }
+ }
+
+ if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
+
+ settings.changepicturecallback(); // Callback!
+
+ pp_open = true;
+ });
+
+ _insert_gallery();
+ pp_settings.ajaxcallback();
+ };
+
+ /**
+ * Hide the content...DUH!
+ */
+ function _hideContent(callback){
+ // Fade out the current picture
+ $pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
+ $pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
+ $('.pp_loaderIcon').show();
+
+ callback();
+ });
+ };
+
+ /**
+ * Check the item position in the gallery array, hide or show the navigation links
+ * @param setCount {integer} The total number of items in the set
+ */
+ function _checkPosition(setCount){
+ (setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
+ };
+
+ /**
+ * Resize the item dimensions if it's bigger than the viewport
+ * @param width {integer} Width of the item to be opened
+ * @param height {integer} Height of the item to be opened
+ * @return An array containin the "fitted" dimensions
+ */
+ function _fitToViewport(width,height){
+ resized = false;
+
+ _getDimensions(width,height);
+
+ // Define them in case there's no resize needed
+ imageWidth = width, imageHeight = height;
+
+ if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
+ resized = true, fitting = false;
+
+ while (!fitting){
+ if((pp_containerWidth > windowWidth)){
+ imageWidth = (windowWidth - 200);
+ imageHeight = (height/width) * imageWidth;
+ }else if((pp_containerHeight > windowHeight)){
+ imageHeight = (windowHeight - 200);
+ imageWidth = (width/height) * imageHeight;
+ }else{
+ fitting = true;
+ };
+
+ pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
+ };
+
+
+
+ if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
+ _fitToViewport(pp_containerWidth,pp_containerHeight)
+ };
+
+ _getDimensions(imageWidth,imageHeight);
+ };
+
+ return {
+ width:Math.floor(imageWidth),
+ height:Math.floor(imageHeight),
+ containerHeight:Math.floor(pp_containerHeight),
+ containerWidth:Math.floor(pp_containerWidth) + (settings.horizontal_padding * 2),
+ contentHeight:Math.floor(pp_contentHeight),
+ contentWidth:Math.floor(pp_contentWidth),
+ resized:resized
+ };
+ };
+
+ /**
+ * Get the containers dimensions according to the item size
+ * @param width {integer} Width of the item to be opened
+ * @param height {integer} Height of the item to be opened
+ */
+ function _getDimensions(width,height){
+ width = parseFloat(width);
+ height = parseFloat(height);
+
+ // Get the details height, to do so, I need to clone it since it's invisible
+ $pp_details = $pp_pic_holder.find('.pp_details');
+ $pp_details.width(width);
+ detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
+
+ $pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
+ 'position':'absolute',
+ 'top':-10000
+ });
+ detailsHeight += $pp_details.height();
+ detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
+ $pp_details.remove();
+
+ // Get the titles height, to do so, I need to clone it since it's invisible
+ $pp_title = $pp_pic_holder.find('.ppt');
+ $pp_title.width(width);
+ titleHeight = parseFloat($pp_title.css('marginTop')) + parseFloat($pp_title.css('marginBottom'));
+ $pp_title = $pp_title.clone().appendTo($('body')).css({
+ 'position':'absolute',
+ 'top':-10000
+ });
+ titleHeight += $pp_title.height();
+ $pp_title.remove();
+
+ // Get the container size, to resize the holder to the right dimensions
+ pp_contentHeight = height + detailsHeight;
+ pp_contentWidth = width;
+ pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
+ pp_containerWidth = width;
+ }
+
+ function _getFileType(itemSrc){
+ if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
+ return 'youtube';
+ }else if (itemSrc.match(/vimeo\.com/i)) {
+ return 'vimeo';
+ }else if(itemSrc.match(/\b.mov\b/i)){
+ return 'quicktime';
+ }else if(itemSrc.match(/\b.swf\b/i)){
+ return 'flash';
+ }else if(itemSrc.match(/\biframe=true\b/i)){
+ return 'iframe';
+ }else if(itemSrc.match(/\bajax=true\b/i)){
+ return 'ajax';
+ }else if(itemSrc.match(/\bcustom=true\b/i)){
+ return 'custom';
+ }else if(itemSrc.substr(0,1) == '#'){
+ return 'inline';
+ }else{
+ return 'image';
+ };
+ };
+
+ function _center_overlay(){
+ if(doresize && typeof $pp_pic_holder != 'undefined') {
+ scroll_pos = _get_scroll();
+ contentHeight = $pp_pic_holder.height(), contentwidth = $pp_pic_holder.width();
+
+ projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
+ if(projectedTop < 0) projectedTop = 0;
+
+ if(contentHeight > windowHeight)
+ return;
+
+ $pp_pic_holder.css({
+ 'top': projectedTop,
+ 'left': (windowWidth/2) + scroll_pos['scrollLeft'] - (contentwidth/2)
+ });
+ };
+ };
+
+ function _get_scroll(){
+ if (self.pageYOffset) {
+ return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
+ } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
+ return {scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};
+ } else if (document.body) {// all other Explorers
+ return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
+ };
+ };
+
+ function _resize_overlay() {
+ windowHeight = $(window).height(), windowWidth = $(window).width();
+
+ if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
+ };
+
+ function _insert_gallery(){
+ if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image") {
+ itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
+ navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
+
+ itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
+ itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
+ totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
+
+ // Hide the nav in the case there's no need for links
+ if(totalPage == 0){
+ navWidth = 0; // No nav means no width!
+ $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').hide();
+ }else{
+ $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').show();
+ };
+
+ galleryWidth = itemsPerPage * itemWidth;
+ fullGalleryWidth = pp_images.length * itemWidth;
+
+ // Set the proper width to the gallery items
+ $pp_gallery
+ .css('margin-left',-((galleryWidth/2) + (navWidth/2)))
+ .find('div:first').width(galleryWidth+5)
+ .find('ul').width(fullGalleryWidth)
+ .find('li.selected').removeClass('selected');
+
+ goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
+
+ $.prettyPhoto.changeGalleryPage(goToPage);
+
+ $pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
+ }else{
+ $pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
+ // $pp_gallery.hide();
+ }
+ }
+
+ function _build_overlay(caller){
+ // Inject Social Tool markup into General markup
+ if(settings.social_tools)
+ facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
+
+ settings.markup = settings.markup.replace('{pp_social}','');
+
+ $('body').append(settings.markup); // Inject the markup
+
+ $pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
+
+ // Inject the inline gallery!
+ if(isSet && settings.overlay_gallery) {
+ currentGalleryPage = 0;
+ toInject = "";
+ for (var i=0; i < pp_images.length; i++) {
+ if(!pp_images[i].match(/\b(jpg|jpeg|png|gif)\b/gi)){
+ classname = 'default';
+ img_src = '';
+ }else{
+ classname = '';
+ img_src = pp_images[i];
+ }
+ toInject += " ";
+ };
+
+ toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
+
+ $pp_pic_holder.find('#pp_full_res').after(toInject);
+
+ $pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
+
+ $pp_gallery.find('.pp_arrow_next').click(function(){
+ $.prettyPhoto.changeGalleryPage('next');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ $pp_gallery.find('.pp_arrow_previous').click(function(){
+ $.prettyPhoto.changeGalleryPage('previous');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ $pp_pic_holder.find('.pp_content').hover(
+ function(){
+ $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
+ },
+ function(){
+ $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
+ });
+
+ itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
+ $pp_gallery_li.each(function(i){
+ $(this)
+ .find('a')
+ .click(function(){
+ $.prettyPhoto.changePage(i);
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+ });
+ };
+
+
+ // Inject the play/pause if it's a slideshow
+ if(settings.slideshow){
+ $pp_pic_holder.find('.pp_nav').prepend('Play ')
+ $pp_pic_holder.find('.pp_nav .pp_play').click(function(){
+ $.prettyPhoto.startSlideshow();
+ return false;
+ });
+ }
+
+ $pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
+
+ $pp_overlay
+ .css({
+ 'opacity':0,
+ 'height':$(document).height(),
+ 'width':$(window).width()
+ })
+ .bind('click',function(){
+ if(!settings.modal) $.prettyPhoto.close();
+ });
+
+ $('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
+
+
+ if(settings.allow_expand) {
+ $('a.pp_expand').bind('click',function(e){
+ // Expand the image
+ if($(this).hasClass('pp_expand')){
+ $(this).removeClass('pp_expand').addClass('pp_contract');
+ doresize = false;
+ }else{
+ $(this).removeClass('pp_contract').addClass('pp_expand');
+ doresize = true;
+ };
+
+ _hideContent(function(){ $.prettyPhoto.open(); });
+
+ return false;
+ });
+ }
+
+ $pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
+ $.prettyPhoto.changePage('previous');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ $pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
+ $.prettyPhoto.changePage('next');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ _center_overlay(); // Center it
+ };
+
+ if(!pp_alreadyInitialized && getHashtag()){
+ pp_alreadyInitialized = true;
+
+ // Grab the rel index to trigger the click on the correct element
+ hashIndex = getHashtag();
+ hashRel = hashIndex;
+ hashIndex = hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);
+ hashRel = hashRel.substring(0,hashRel.indexOf('/'));
+
+ // Little timeout to make sure all the prettyPhoto initialize scripts has been run.
+ // Useful in the event the page contain several init scripts.
+ setTimeout(function(){ $("a["+pp_settings.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
+ }
+
+ return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
+ };
+
+ function getHashtag(){
+ var url = location.href;
+ hashtag = (url.indexOf('#prettyPhoto') !== -1) ? decodeURI(url.substring(url.indexOf('#prettyPhoto')+1,url.length)) : false;
+
+ return hashtag;
+ };
+
+ function setHashtag(){
+ if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
+ location.hash = theRel + '/'+rel_index+'/';
+ };
+
+ function clearHashtag(){
+ if ( location.href.indexOf('#prettyPhoto') !== -1 ) location.hash = "prettyPhoto";
+ }
+
+ function getParam(name,url){
+ name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
+ var regexS = "[\\?&]"+name+"=([^]*)";
+ var regex = new RegExp( regexS );
+ var results = regex.exec( url );
+ return ( results == null ) ? "" : results[1];
+ }
+
+})(jQuery);
+
+var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.
diff --git a/assets/js/prettyPhoto/jquery.prettyPhoto.min.js b/assets/js/prettyPhoto/jquery.prettyPhoto.min.js
new file mode 100644
index 00000000000..3f13c3090f4
--- /dev/null
+++ b/assets/js/prettyPhoto/jquery.prettyPhoto.min.js
@@ -0,0 +1,6 @@
+/* ------------------------------------------------------------------------
+ Class: prettyPhoto
+ Use: Lightbox clone for jQuery
+ Author: Stephane Caron (http://www.no-margin-for-errors.com)
+ Version: 3.1.5
+------------------------------------------------------------------------- */(function(e){function t(){var e=location.href;hashtag=e.indexOf("#prettyPhoto")!==-1?decodeURI(e.substring(e.indexOf("#prettyPhoto")+1,e.length)):!1;return hashtag}function n(){if(typeof theRel=="undefined")return;location.hash=theRel+"/"+rel_index+"/"}function r(){location.href.indexOf("#prettyPhoto")!==-1&&(location.hash="prettyPhoto")}function i(e,t){e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var n="[\\?&]"+e+"=([^]*)",r=new RegExp(n),i=r.exec(t);return i==null?"":i[1]}e.prettyPhoto={version:"3.1.5"};e.fn.prettyPhoto=function(s){function g(){e(".pp_loaderIcon").hide();projectedTop=scroll_pos.scrollTop+(d/2-a.containerHeight/2);projectedTop<0&&(projectedTop=0);$ppt.fadeTo(settings.animation_speed,1);$pp_pic_holder.find(".pp_content").animate({height:a.contentHeight,width:a.contentWidth},settings.animation_speed);$pp_pic_holder.animate({top:projectedTop,left:v/2-a.containerWidth/2<0?0:v/2-a.containerWidth/2,width:a.containerWidth},settings.animation_speed,function(){$pp_pic_holder.find(".pp_hoverContainer,#fullResImage").height(a.height).width(a.width);$pp_pic_holder.find(".pp_fade").fadeIn(settings.animation_speed);isSet&&S(pp_images[set_position])=="image"?$pp_pic_holder.find(".pp_hoverContainer").show():$pp_pic_holder.find(".pp_hoverContainer").hide();settings.allow_expand&&(a.resized?e("a.pp_expand,a.pp_contract").show():e("a.pp_expand").hide());settings.autoplay_slideshow&&!m&&!f&&e.prettyPhoto.startSlideshow();settings.changepicturecallback();f=!0});C();s.ajaxcallback()}function y(t){$pp_pic_holder.find("#pp_full_res object,#pp_full_res embed").css("visibility","hidden");$pp_pic_holder.find(".pp_fade").fadeOut(settings.animation_speed,function(){e(".pp_loaderIcon").show();t()})}function b(t){t>1?e(".pp_nav").show():e(".pp_nav").hide()}function w(e,t){resized=!1;E(e,t);imageWidth=e,imageHeight=t;if((p>v||h>d)&&doresize&&settings.allow_resize&&!u){resized=!0,fitting=!1;while(!fitting){if(p>v){imageWidth=v-200;imageHeight=t/e*imageWidth}else if(h>d){imageHeight=d-200;imageWidth=e/t*imageHeight}else fitting=!0;h=imageHeight,p=imageWidth}(p>v||h>d)&&w(p,h);E(imageWidth,imageHeight)}return{width:Math.floor(imageWidth),height:Math.floor(imageHeight),containerHeight:Math.floor(h),containerWidth:Math.floor(p)+settings.horizontal_padding*2,contentHeight:Math.floor(l),contentWidth:Math.floor(c),resized:resized}}function E(t,n){t=parseFloat(t);n=parseFloat(n);$pp_details=$pp_pic_holder.find(".pp_details");$pp_details.width(t);detailsHeight=parseFloat($pp_details.css("marginTop"))+parseFloat($pp_details.css("marginBottom"));$pp_details=$pp_details.clone().addClass(settings.theme).width(t).appendTo(e("body")).css({position:"absolute",top:-1e4});detailsHeight+=$pp_details.height();detailsHeight=detailsHeight<=34?36:detailsHeight;$pp_details.remove();$pp_title=$pp_pic_holder.find(".ppt");$pp_title.width(t);titleHeight=parseFloat($pp_title.css("marginTop"))+parseFloat($pp_title.css("marginBottom"));$pp_title=$pp_title.clone().appendTo(e("body")).css({position:"absolute",top:-1e4});titleHeight+=$pp_title.height();$pp_title.remove();l=n+detailsHeight;c=t;h=l+titleHeight+$pp_pic_holder.find(".pp_top").height()+$pp_pic_holder.find(".pp_bottom").height();p=t}function S(e){return e.match(/youtube\.com\/watch/i)||e.match(/youtu\.be/i)?"youtube":e.match(/vimeo\.com/i)?"vimeo":e.match(/\b.mov\b/i)?"quicktime":e.match(/\b.swf\b/i)?"flash":e.match(/\biframe=true\b/i)?"iframe":e.match(/\bajax=true\b/i)?"ajax":e.match(/\bcustom=true\b/i)?"custom":e.substr(0,1)=="#"?"inline":"image"}function x(){if(doresize&&typeof $pp_pic_holder!="undefined"){scroll_pos=T();contentHeight=$pp_pic_holder.height(),contentwidth=$pp_pic_holder.width();projectedTop=d/2+scroll_pos.scrollTop-contentHeight/2;projectedTop<0&&(projectedTop=0);if(contentHeight>d)return;$pp_pic_holder.css({top:projectedTop,left:v/2+scroll_pos.scrollLeft-contentwidth/2})}}function T(){if(self.pageYOffset)return{scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};if(document.documentElement&&document.documentElement.scrollTop)return{scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};if(document.body)return{scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft}}function N(){d=e(window).height(),v=e(window).width();typeof $pp_overlay!="undefined"&&$pp_overlay.height(e(document).height()).width(v)}function C(){if(isSet&&settings.overlay_gallery&&S(pp_images[set_position])=="image"){itemWidth=57;navWidth=settings.theme=="facebook"||settings.theme=="pp_default"?50:30;itemsPerPage=Math.floor((a.containerWidth-100-navWidth)/itemWidth);itemsPerPage=itemsPerPage "}toInject=settings.gallery_markup.replace(/{gallery}/g,toInject);$pp_pic_holder.find("#pp_full_res").after(toInject);$pp_gallery=e(".pp_pic_holder .pp_gallery"),$pp_gallery_li=$pp_gallery.find("li");$pp_gallery.find(".pp_arrow_next").click(function(){e.prettyPhoto.changeGalleryPage("next");e.prettyPhoto.stopSlideshow();return!1});$pp_gallery.find(".pp_arrow_previous").click(function(){e.prettyPhoto.changeGalleryPage("previous");e.prettyPhoto.stopSlideshow();return!1});$pp_pic_holder.find(".pp_content").hover(function(){$pp_pic_holder.find(".pp_gallery:not(.disabled)").fadeIn()},function(){$pp_pic_holder.find(".pp_gallery:not(.disabled)").fadeOut()});itemWidth=57;$pp_gallery_li.each(function(t){e(this).find("a").click(function(){e.prettyPhoto.changePage(t);e.prettyPhoto.stopSlideshow();return!1})})}if(settings.slideshow){$pp_pic_holder.find(".pp_nav").prepend('Play ');$pp_pic_holder.find(".pp_nav .pp_play").click(function(){e.prettyPhoto.startSlideshow();return!1})}$pp_pic_holder.attr("class","pp_pic_holder "+settings.theme);$pp_overlay.css({opacity:0,height:e(document).height(),width:e(window).width()}).bind("click",function(){settings.modal||e.prettyPhoto.close()});e("a.pp_close").bind("click",function(){e.prettyPhoto.close();return!1});settings.allow_expand&&e("a.pp_expand").bind("click",function(t){if(e(this).hasClass("pp_expand")){e(this).removeClass("pp_expand").addClass("pp_contract");doresize=!1}else{e(this).removeClass("pp_contract").addClass("pp_expand");doresize=!0}y(function(){e.prettyPhoto.open()});return!1});$pp_pic_holder.find(".pp_previous, .pp_nav .pp_arrow_previous").bind("click",function(){e.prettyPhoto.changePage("previous");e.prettyPhoto.stopSlideshow();return!1});$pp_pic_holder.find(".pp_next, .pp_nav .pp_arrow_next").bind("click",function(){e.prettyPhoto.changePage("next");e.prettyPhoto.stopSlideshow();return!1});x()}s=jQuery.extend({hook:"rel",animation_speed:"fast",ajaxcallback:function(){},slideshow:5e3,autoplay_slideshow:!1,opacity:.8,show_title:!0,allow_resize:!0,allow_expand:!0,default_width:500,default_height:344,counter_separator_label:"/",theme:"pp_default",horizontal_padding:20,hideflash:!1,wmode:"opaque",autoplay:!0,modal:!1,deeplinking:!0,overlay_gallery:!0,overlay_gallery_max:30,keyboard_shortcuts:!0,changepicturecallback:function(){},callback:function(){},ie6_fallback:!0,markup:'
',gallery_markup:'',image_markup:' ',flash_markup:' ',quicktime_markup:' ',iframe_markup:'',inline_markup:'{content}
',custom_markup:"",social_tools:'
'},s);var o=this,u=!1,a,f,l,c,h,p,d=e(window).height(),v=e(window).width(),m;doresize=!0,scroll_pos=T();e(window).unbind("resize.prettyphoto").bind("resize.prettyphoto",function(){x();N()});s.keyboard_shortcuts&&e(document).unbind("keydown.prettyphoto").bind("keydown.prettyphoto",function(t){if(typeof $pp_pic_holder!="undefined"&&$pp_pic_holder.is(":visible"))switch(t.keyCode){case 37:e.prettyPhoto.changePage("previous");t.preventDefault();break;case 39:e.prettyPhoto.changePage("next");t.preventDefault();break;case 27:settings.modal||e.prettyPhoto.close();t.preventDefault()}});e.prettyPhoto.initialize=function(){settings=s;settings.theme=="pp_default"&&(settings.horizontal_padding=16);theRel=e(this).attr(settings.hook);galleryRegExp=/\[(?:.*)\]/;isSet=galleryRegExp.exec(theRel)?!0:!1;pp_images=isSet?jQuery.map(o,function(t,n){if(e(t).attr(settings.hook).indexOf(theRel)!=-1)return e(t).attr("href")}):e.makeArray(e(this).attr("href"));pp_titles=isSet?jQuery.map(o,function(t,n){if(e(t).attr(settings.hook).indexOf(theRel)!=-1)return e(t).find("img").attr("alt")?e(t).find("img").attr("alt"):""}):e.makeArray(e(this).find("img").attr("alt"));pp_descriptions=isSet?jQuery.map(o,function(t,n){if(e(t).attr(settings.hook).indexOf(theRel)!=-1)return e(t).attr("title")?e(t).attr("title"):""}):e.makeArray(e(this).attr("title"));pp_images.length>settings.overlay_gallery_max&&(settings.overlay_gallery=!1);set_position=jQuery.inArray(e(this).attr("href"),pp_images);rel_index=isSet?set_position:e("a["+settings.hook+"^='"+theRel+"']").index(e(this));k(this);settings.allow_resize&&e(window).bind("scroll.prettyphoto",function(){x()});e.prettyPhoto.open();return!1};e.prettyPhoto.open=function(t){if(typeof settings=="undefined"){settings=s;pp_images=e.makeArray(arguments[0]);pp_titles=arguments[1]?e.makeArray(arguments[1]):e.makeArray("");pp_descriptions=arguments[2]?e.makeArray(arguments[2]):e.makeArray("");isSet=pp_images.length>1?!0:!1;set_position=arguments[3]?arguments[3]:0;k(t.target)}settings.hideflash&&e("object,embed,iframe[src*=youtube],iframe[src*=vimeo]").css("visibility","hidden");b(e(pp_images).size());e(".pp_loaderIcon").show();settings.deeplinking&&n();if(settings.social_tools){facebook_like_link=settings.social_tools.replace("{location_href}",encodeURIComponent(location.href));$pp_pic_holder.find(".pp_social").html(facebook_like_link)}$ppt.is(":hidden")&&$ppt.css("opacity",0).show();$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);$pp_pic_holder.find(".currentTextHolder").text(set_position+1+settings.counter_separator_label+e(pp_images).size());typeof pp_descriptions[set_position]!="undefined"&&pp_descriptions[set_position]!=""?$pp_pic_holder.find(".pp_description").show().html(unescape(pp_descriptions[set_position])):$pp_pic_holder.find(".pp_description").hide();movie_width=parseFloat(i("width",pp_images[set_position]))?i("width",pp_images[set_position]):settings.default_width.toString();movie_height=parseFloat(i("height",pp_images[set_position]))?i("height",pp_images[set_position]):settings.default_height.toString();u=!1;if(movie_height.indexOf("%")!=-1){movie_height=parseFloat(e(window).height()*parseFloat(movie_height)/100-150);u=!0}if(movie_width.indexOf("%")!=-1){movie_width=parseFloat(e(window).width()*parseFloat(movie_width)/100-150);u=!0}$pp_pic_holder.fadeIn(function(){settings.show_title&&pp_titles[set_position]!=""&&typeof pp_titles[set_position]!="undefined"?$ppt.html(unescape(pp_titles[set_position])):$ppt.html(" ");imgPreloader="";skipInjection=!1;switch(S(pp_images[set_position])){case"image":imgPreloader=new Image;nextImage=new Image;isSet&&set_position0&&(movie_id=movie_id.substr(0,movie_id.indexOf("?")));movie_id.indexOf("&")>0&&(movie_id=movie_id.substr(0,movie_id.indexOf("&")))}movie="http://www.youtube.com/embed/"+movie_id;i("rel",pp_images[set_position])?movie+="?rel="+i("rel",pp_images[set_position]):movie+="?rel=1";settings.autoplay&&(movie+="&autoplay=1");toInject=settings.iframe_markup.replace(/{width}/g,a.width).replace(/{height}/g,a.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);break;case"vimeo":a=w(movie_width,movie_height);movie_id=pp_images[set_position];var t=/http(s?):\/\/(www\.)?vimeo.com\/(\d+)/,n=movie_id.match(t);movie="http://player.vimeo.com/video/"+n[3]+"?title=0&byline=0&portrait=0";settings.autoplay&&(movie+="&autoplay=1;");vimeo_width=a.width+"/embed/?moog_width="+a.width;toInject=settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,a.height).replace(/{path}/g,movie);break;case"quicktime":a=w(movie_width,movie_height);a.height+=15;a.contentHeight+=15;a.containerHeight+=15;toInject=settings.quicktime_markup.replace(/{width}/g,a.width).replace(/{height}/g,a.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);break;case"flash":a=w(movie_width,movie_height);flash_vars=pp_images[set_position];flash_vars=flash_vars.substring(pp_images[set_position].indexOf("flashvars")+10,pp_images[set_position].length);filename=pp_images[set_position];filename=filename.substring(0,filename.indexOf("?"));toInject=settings.flash_markup.replace(/{width}/g,a.width).replace(/{height}/g,a.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+"?"+flash_vars);break;case"iframe":a=w(movie_width,movie_height);frame_url=pp_images[set_position];frame_url=frame_url.substr(0,frame_url.indexOf("iframe")-1);toInject=settings.iframe_markup.replace(/{width}/g,a.width).replace(/{height}/g,a.height).replace(/{path}/g,frame_url);break;case"ajax":doresize=!1;a=w(movie_width,movie_height);doresize=!0;skipInjection=!0;e.get(pp_images[set_position],function(e){toInject=settings.inline_markup.replace(/{content}/g,e);$pp_pic_holder.find("#pp_full_res")[0].innerHTML=toInject;g()});break;case"custom":a=w(movie_width,movie_height);toInject=settings.custom_markup;break;case"inline":myClone=e(pp_images[set_position]).clone().append(' ').css({width:settings.default_width}).wrapInner('').appendTo(e("body")).show();doresize=!1;a=w(e(myClone).width(),e(myClone).height());doresize=!0;e(myClone).remove();toInject=settings.inline_markup.replace(/{content}/g,e(pp_images[set_position]).html())}if(!imgPreloader&&!skipInjection){$pp_pic_holder.find("#pp_full_res")[0].innerHTML=toInject;g()}});return!1};e.prettyPhoto.changePage=function(t){currentGalleryPage=0;if(t=="previous"){set_position--;set_position<0&&(set_position=e(pp_images).size()-1)}else if(t=="next"){set_position++;set_position>e(pp_images).size()-1&&(set_position=0)}else set_position=t;rel_index=set_position;doresize||(doresize=!0);settings.allow_expand&&e(".pp_contract").removeClass("pp_contract").addClass("pp_expand");y(function(){e.prettyPhoto.open()})};e.prettyPhoto.changeGalleryPage=function(e){if(e=="next"){currentGalleryPage++;currentGalleryPage>totalPage&&(currentGalleryPage=0)}else if(e=="previous"){currentGalleryPage--;currentGalleryPage<0&&(currentGalleryPage=totalPage)}else currentGalleryPage=e;slide_speed=e=="next"||e=="previous"?settings.animation_speed:0;slide_to=currentGalleryPage*itemsPerPage*itemWidth;$pp_gallery.find("ul").animate({left:-slide_to},slide_speed)};e.prettyPhoto.startSlideshow=function(){if(typeof m=="undefined"){$pp_pic_holder.find(".pp_play").unbind("click").removeClass("pp_play").addClass("pp_pause").click(function(){e.prettyPhoto.stopSlideshow();return!1});m=setInterval(e.prettyPhoto.startSlideshow,settings.slideshow)}else e.prettyPhoto.changePage("next")};e.prettyPhoto.stopSlideshow=function(){$pp_pic_holder.find(".pp_pause").unbind("click").removeClass("pp_pause").addClass("pp_play").click(function(){e.prettyPhoto.startSlideshow();return!1});clearInterval(m);m=undefined};e.prettyPhoto.close=function(){if($pp_overlay.is(":animated"))return;e.prettyPhoto.stopSlideshow();$pp_pic_holder.stop().find("object,embed").css("visibility","hidden");e("div.pp_pic_holder,div.ppt,.pp_fade").fadeOut(settings.animation_speed,function(){e(this).remove()});$pp_overlay.fadeOut(settings.animation_speed,function(){settings.hideflash&&e("object,embed,iframe[src*=youtube],iframe[src*=vimeo]").css("visibility","visible");e(this).remove();e(window).unbind("scroll.prettyphoto");r();settings.callback();doresize=!0;f=!1;delete settings})};if(!pp_alreadyInitialized&&t()){pp_alreadyInitialized=!0;hashIndex=t();hashRel=hashIndex;hashIndex=hashIndex.substring(hashIndex.indexOf("/")+1,hashIndex.length-1);hashRel=hashRel.substring(0,hashRel.indexOf("/"));setTimeout(function(){e("a["+s.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger("click")},50)}return this.unbind("click.prettyphoto").bind("click.prettyphoto",e.prettyPhoto.initialize)}})(jQuery);var pp_alreadyInitialized=!1;
\ No newline at end of file
diff --git a/classes/emails/class-wc-email.php b/classes/abstracts/abstract-wc-email.php
similarity index 79%
rename from classes/emails/class-wc-email.php
rename to classes/abstracts/abstract-wc-email.php
index eff8f9f1390..6a40ab143ad 100644
--- a/classes/emails/class-wc-email.php
+++ b/classes/abstracts/abstract-wc-email.php
@@ -1,19 +1,20 @@
',
+ '<',
+ '&',
+ '(c)',
+ '(tm)',
+ '(R)',
+ '--',
+ '-',
+ '*',
+ '£',
+ 'EUR', // Euro sign. € ?
+ '', // Unknown/unhandled entities
+ ' ' // Runs of spaces, post-handling
+ );
+
/**
* Constructor
*
@@ -77,21 +135,24 @@ class WC_Email extends WC_Settings_API {
$this->init_settings();
// Save settings hook
- add_action( 'woocommerce_update_options_email_' . $this->id, array( &$this, 'process_admin_options' ) );
+ add_action( 'woocommerce_update_options_email_' . $this->id, array( $this, 'process_admin_options' ) );
+
+ // Default template base if not declared in child constructor
+ if ( is_null( $this->template_base ) )
+ $this->template_base = $woocommerce->plugin_path() . '/templates/';
// Settings
- $this->template_base = $woocommerce->plugin_path() . '/templates/';
- $this->heading = empty( $this->settings['heading'] ) ? $this->heading : $this->settings['heading'];
- $this->subject = empty( $this->settings['subject'] ) ? $this->subject : $this->settings['subject'];
- $this->email_type = $this->settings['email_type'];
- $this->enabled = $this->settings['enabled'];
+ $this->heading = $this->get_option( 'heading', $this->heading );
+ $this->subject = $this->get_option( 'subject', $this->subject );
+ $this->email_type = $this->get_option( 'email_type' );
+ $this->enabled = $this->get_option( 'enabled' );
// Find/replace
$this->find = array( '{blogname}' );
$this->replace = array( $this->get_blogname() );
// For multipart messages
- add_filter( 'phpmailer_init', array( &$this, 'handle_multipart' ) );
+ add_filter( 'phpmailer_init', array( $this, 'handle_multipart' ) );
}
/**
@@ -104,7 +165,9 @@ class WC_Email extends WC_Settings_API {
function handle_multipart( $mailer ) {
if ( $this->sending && $this->get_email_type() == 'multipart' ) {
- $mailer->AltBody = wordwrap( html_entity_decode( strip_tags( $this->get_content_plain() ) ), 70 );
+
+ $mailer->AltBody = wordwrap( preg_replace( $this->plain_search, $this->plain_replace, strip_tags( $this->get_content_plain() ) ) );
+ //$mailer->AltBody = wordwrap( html_entity_decode( strip_tags( $this->get_content_plain() ) ), 70 );
$this->sending = false;
}
@@ -205,8 +268,9 @@ class WC_Email extends WC_Settings_API {
* @return bool
*/
function is_enabled() {
- if ( $this->enabled == "yes" )
- return true;
+ $enabled = $this->enabled == "yes" ? true : false;
+
+ return apply_filters( 'woocommerce_email_enabled_' . $this->id, $enabled, $this->object );
}
/**
@@ -230,7 +294,7 @@ class WC_Email extends WC_Settings_API {
$this->sending = true;
if ( $this->get_email_type() == 'plain' ) {
- $email_content = html_entity_decode( strip_tags( $this->get_content_plain() ) );
+ $email_content = preg_replace( $this->plain_search, $this->plain_replace, strip_tags( $this->get_content_plain() ) );
} else {
$email_content = $this->style_inline( $this->get_content_html() );
}
@@ -309,7 +373,7 @@ class WC_Email extends WC_Settings_API {
* @return string
*/
function get_from_name() {
- return esc_html( get_option( 'woocommerce_email_from_name' ) );
+ return wp_specialchars_decode( esc_html( get_option( 'woocommerce_email_from_name' ) ) );
}
/**
@@ -334,15 +398,15 @@ class WC_Email extends WC_Settings_API {
* @return void
*/
function send( $to, $subject, $message, $headers, $attachments ) {
- add_filter( 'wp_mail_from', array( &$this, 'get_from_address' ) );
- add_filter( 'wp_mail_from_name', array( &$this, 'get_from_name' ) );
- add_filter( 'wp_mail_content_type', array( &$this, 'get_content_type' ) );
+ add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
+ add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
+ add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
wp_mail( $to, $subject, $message, $headers, $attachments );
- remove_filter( 'wp_mail_from', array( &$this, 'get_from_address' ) );
- remove_filter( 'wp_mail_from_name', array( &$this, 'get_from_name' ) );
- remove_filter( 'wp_mail_content_type', array( &$this, 'get_content_type' ) );
+ remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
+ remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
+ remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
}
/**
@@ -536,7 +600,7 @@ class WC_Email extends WC_Settings_API {
- %s to your theme folder: %s
.', 'woocommerce' ), 'woocommerce/templates/' . $this->$template, 'yourtheme/woocommerce/' . $this->$template ); ?>
+ %s to your theme folder: %s
.', 'woocommerce' ), plugin_basename( $core_file ) , 'yourtheme/woocommerce/' . $this->$template ); ?>
@@ -601,4 +665,4 @@ class WC_Email extends WC_Settings_API {
");
}
}
-}
\ No newline at end of file
+}
diff --git a/classes/integrations/class-wc-integration.php b/classes/abstracts/abstract-wc-integration.php
similarity index 86%
rename from classes/integrations/class-wc-integration.php
rename to classes/abstracts/abstract-wc-integration.php
index a92ef729bbc..0ddead33747 100644
--- a/classes/integrations/class-wc-integration.php
+++ b/classes/abstracts/abstract-wc-integration.php
@@ -1,4 +1,7 @@
id = absint( $product->ID );
- $this->post = $product;
- } else {
- $this->id = absint( $product );
- $this->post = get_post( $this->id );
+ if ( ( function_exists( 'get_called_class' ) && get_called_class() == 'WC_Product' ) || ( ! function_exists( 'get_called_class' ) && is_null( $this->product_type ) ) ) {
+ _doing_it_wrong( 'WC_Product', __( 'The
WC_Product
class is now abstract. Use
get_product()
to instantiate an instance of a product instead of calling this class directly.', 'woocommerce' ), '2.0 of WooCommerce' );
+
+ $product = get_product( $product );
}
- $this->product_custom_fields = get_post_custom( $this->id );
+ if ( is_object( $product ) ) {
+ $this->id = absint( $product->ID );
+ $this->post = $product;
+ } else {
+ $this->id = absint( $product );
+ $this->post = get_post( $this->id );
+ }
}
-
/**
- * Load the data from the custom fields
+ * __isset function.
*
* @access public
- * @param mixed $fields
- * @param string $data (default: '')
- * @return void
+ * @param mixed $key
+ * @return bool
*/
- function load_product_data( $fields, $data = '' ) {
-
- if ( ! $data )
- $data = $this->product_custom_fields;
-
- if ( $fields )
- foreach ( $fields as $key => $default )
- $this->$key = isset( $data[ '_' . $key ][0] ) && $data[ '_' . $key ][0] !== '' ? $data[ '_' . $key ][0] : $default;
+ public function __isset( $key ) {
+ return metadata_exists( 'post', $this->id, '_' . $key );
}
+ /**
+ * __get function.
+ *
+ * @access public
+ * @param mixed $key
+ * @return mixed
+ */
+ public function __get( $key ) {
+
+ // Get values or default if not set
+ if ( in_array( $key, array( 'downloadable', 'virtual', 'backorders', 'manage_stock', 'featured', 'sold_individually' ) ) )
+ $value = ( $value = get_post_meta( $this->id, '_' . $key, true ) ) ? $value : 'no';
+
+ elseif( in_array( $key, array( 'product_attributes', 'crosssell_ids', 'upsell_ids' ) ) )
+ $value = ( $value = get_post_meta( $this->id, '_' . $key, true ) ) ? $value : array();
+
+ elseif ( 'visibility' == $key )
+ $value = ( $value = get_post_meta( $this->id, '_visibility', true ) ) ? $value : 'hidden';
+
+ elseif ( 'stock' == $key )
+ $value = ( $value = get_post_meta( $this->id, '_stock', true ) ) ? $value : 0;
+
+ elseif ( 'stock_status' == $key )
+ $value = ( $value = get_post_meta( $this->id, '_stock_status', true ) ) ? $value : 'instock';
+
+ elseif ( 'tax_status' == $key )
+ $value = ( $value = get_post_meta( $this->id, '_tax_status', true ) ) ? $value : 'taxable';
+
+ else
+ $value = get_post_meta( $this->id, '_' . $key, true );
+
+ return $value;
+ }
+
+ /**
+ * Get the product's post data.
+ *
+ * @access public
+ * @return object
+ */
+ public function get_post_data() {
+ return $this->post;
+ }
+
+ /**
+ * get_gallery_attachment_ids function.
+ *
+ * @access public
+ * @return array
+ */
+ function get_gallery_attachment_ids() {
+ if ( ! isset( $this->product_image_gallery ) ) {
+ // Backwards compat
+ $attachment_ids = array_diff( get_posts( 'post_parent=' . $this->id . '&numberposts=-1&post_type=attachment&orderby=menu_order&order=ASC&post_mime_type=image&fields=ids' ), array( get_post_thumbnail_id() ) );
+ $this->product_image_gallery = implode( ',', $attachment_ids );
+ }
+
+ return array_filter( (array) explode( ',', $this->product_image_gallery ) );
+ }
/**
* Get SKU (Stock-keeping unit) - product unique ID.
@@ -177,6 +147,33 @@ abstract class WC_Product {
}
+ /**
+ * Set stock level of the product.
+ *
+ * @access public
+ * @param mixed $amount (default: null)
+ * @return int Stock
+ */
+ function set_stock( $amount = null ) {
+ global $woocommerce;
+
+ if ( $this->managing_stock() && ! is_null( $amount ) ) {
+ $this->stock = intval( $amount );
+ update_post_meta( $this->id, '_stock', $this->stock );
+
+ // Out of stock attribute
+ if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
+ $this->set_stock_status( 'outofstock' );
+ elseif ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
+ $this->set_stock_status( 'instock' );
+
+ $woocommerce->clear_product_transients( $this->id ); // Clear transient
+
+ return $this->get_stock_quantity();
+ }
+ }
+
+
/**
* Reduce stock level of the product.
*
@@ -192,7 +189,7 @@ abstract class WC_Product {
update_post_meta( $this->id, '_stock', $this->stock );
// Out of stock attribute
- if ( $this->managing_stock() && ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
+ if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
$woocommerce->clear_product_transients( $this->id ); // Clear transient
@@ -217,7 +214,7 @@ abstract class WC_Product {
update_post_meta( $this->id, '_stock', $this->stock );
// Out of stock attribute
- if ( $this->managing_stock() && ( $this->backorders_allowed() || $this->get_total_stock() > 0 ) )
+ if ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
$this->set_stock_status( 'instock' );
$woocommerce->clear_product_transients( $this->id ); // Clear transient
@@ -292,7 +289,7 @@ abstract class WC_Product {
*/
function get_file_download_path( $download_id ) {
- $file_paths = isset( $this->product_custom_fields['_file_paths'][0] ) ? $this->product_custom_fields['_file_paths'][0] : '';
+ $file_paths = isset( $this->file_paths ) ? $this->file_paths : '';
$file_paths = maybe_unserialize( $file_paths );
$file_paths = apply_filters( 'woocommerce_file_download_paths', $file_paths, $this->id, null, null );
@@ -341,8 +338,7 @@ abstract class WC_Product {
function is_sold_individually() {
$return = false;
- // Sold individually if downloadable, virtual, and the option is enabled OR if intentionally a singular item
- if ( 'yes' == $this->sold_individually || ( $this->is_downloadable() && $this->is_virtual() && get_option('woocommerce_limit_downloadable_product_qty') == 'yes' ) || ( ! $this->backorders_allowed() && $this->get_stock_quantity() == 1 ) ) {
+ if ( 'yes' == $this->sold_individually || ( ! $this->backorders_allowed() && $this->get_stock_quantity() == 1 ) ) {
$return = true;
}
@@ -675,10 +671,7 @@ abstract class WC_Product {
* @return void
*/
function adjust_price( $price ) {
- if ( $price > 0 )
- $this->price += $price;
- else
- $this->price = $this->price - $price;
+ $this->price = $this->price + $price;
}
@@ -888,25 +881,52 @@ abstract class WC_Product {
return '
' . ( ( is_numeric( $from ) ) ? woocommerce_price( $from ) : $from ) . ' ' . ( ( is_numeric( $to ) ) ? woocommerce_price( $to ) : $to ) . ' ';
}
-
/**
- * Returns the product rating in html format - ratings are stored in transient cache.
+ * get_average_rating function.
*
* @access public
- * @param string $location (default: '')
* @return void
*/
- function get_rating_html( $location = '' ) {
-
- if ( $location )
- $location = '_' . $location;
-
- $star_size = apply_filters( 'woocommerce_star_rating_size' . $location, 16 );
-
+ function get_average_rating() {
if ( false === ( $average_rating = get_transient( 'wc_average_rating_' . $this->id ) ) ) {
global $wpdb;
+ $average_rating = '';
+ $count = $this->get_rating_count();
+
+ if ( $count > 0 ) {
+
+ $ratings = $wpdb->get_var( $wpdb->prepare("
+ SELECT SUM(meta_value) FROM $wpdb->commentmeta
+ LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
+ WHERE meta_key = 'rating'
+ AND comment_post_ID = %d
+ AND comment_approved = '1'
+ AND meta_value > 0
+ ", $this->id ) );
+
+ $average_rating = number_format( $ratings / $count, 2 );
+
+ }
+
+ set_transient( 'wc_average_rating_' . $this->id, $average_rating );
+ }
+
+ return $average_rating;
+ }
+
+ /**
+ * get_rating_count function.
+ *
+ * @access public
+ * @return void
+ */
+ function get_rating_count() {
+ if ( false === ( $count = get_transient( 'wc_rating_count_' . $this->id ) ) ) {
+
+ global $wpdb;
+
$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(meta_value) FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
@@ -916,26 +936,36 @@ abstract class WC_Product {
AND meta_value > 0
", $this->id ) );
- $ratings = $wpdb->get_var( $wpdb->prepare("
- SELECT SUM(meta_value) FROM $wpdb->commentmeta
- LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
- WHERE meta_key = 'rating'
- AND comment_post_ID = %d
- AND comment_approved = '1'
- ", $this->id ) );
-
- if ( $count > 0 )
- $average_rating = number_format($ratings / $count, 2);
- else
- $average_rating = '';
-
- set_transient( 'wc_average_rating_' . $this->id, $average_rating );
+ set_transient( 'wc_rating_count_' . $this->id, $count );
}
- if ( $average_rating > 0 )
- return '
' . $average_rating . ' ' . __( 'out of 5', 'woocommerce' ) . '
';
- else
- return '';
+ return $count;
+ }
+
+ /**
+ * Returns the product rating in html format - ratings are stored in transient cache.
+ *
+ * @access public
+ * @param string $location (default: '')
+ * @return void
+ */
+ function get_rating_html( $location = '' ) {
+
+ $average_rating = $this->get_average_rating();
+
+ if ( $average_rating > 0 ) {
+
+ if ( $location )
+ $location = '_' . $location;
+
+ $rating_html = '
';
+
+ $rating_html .= '' . $average_rating . ' ' . __( 'out of 5', 'woocommerce' ) . ' ';
+
+ $rating_html .= '
';
+
+ return $rating_html;
+ }
}
@@ -951,7 +981,7 @@ abstract class WC_Product {
/**
- * Returns the crosssell product ids.
+ * Returns the cross sell product ids.
*
* @access public
* @return array
@@ -980,8 +1010,7 @@ abstract class WC_Product {
* Returns the product tags.
*
* @access public
- * @param string $sep (default: ')
- * @param mixed '
+ * @param string $sep (default: ', ')
* @param string $before (default: '')
* @param string $after (default: '')
* @return array
@@ -1090,7 +1119,7 @@ abstract class WC_Product {
*
* @access public
* @param mixed $attr
- * @return mixed
+ * @return string
*/
function get_attribute( $attr ) {
$attributes = $this->get_attributes();
@@ -1112,7 +1141,8 @@ abstract class WC_Product {
}
}
- return false;
+
+ return '';
}
@@ -1123,16 +1153,7 @@ abstract class WC_Product {
* @return array
*/
function get_attributes() {
-
- if ( ! is_array( $this->attributes ) ) {
-
- if ( isset( $this->product_custom_fields['_product_attributes'][0] ) )
- $this->attributes = maybe_unserialize( maybe_unserialize( $this->product_custom_fields['_product_attributes'][0] ));
- else
- $this->attributes = array();
- }
-
- return (array) $this->attributes;
+ return (array) maybe_unserialize( $this->product_attributes );
}
diff --git a/classes/abstracts/abstract-wc-session.php b/classes/abstracts/abstract-wc-session.php
index 63c607e5667..c621045461f 100644
--- a/classes/abstracts/abstract-wc-session.php
+++ b/classes/abstracts/abstract-wc-session.php
@@ -4,31 +4,20 @@
*
* @class WC_Session
* @version 2.0.0
- * @package WooCommerce/Classes/Abstracts
+ * @package WooCommerce/Abstracts
+ * @category Abstract Class
* @author WooThemes
*/
abstract class WC_Session {
+
+ /** customer_id */
+ protected $_customer_id;
+
/** _data */
- protected $_data;
+ protected $_data = array();
- /**
- * save_data function to be implemented
- *
- * @access public
- * @return void
- */
- abstract public function save_data();
-
- /**
- * Constructor for the session classes. Hooks in methods.
- *
- * @access public
- * @return void
- */
- public function __construct() {
- // When leaving or ending page load, store data
- add_action( 'shutdown', array( &$this, 'save_data' ), 20 );
- }
+ /** When something changes */
+ protected $_dirty = false;
/**
* __get function.
@@ -51,6 +40,7 @@ abstract class WC_Session {
*/
public function __set( $property, $value ) {
$this->_data[ $property ] = $value;
+ $this->_dirty = true;
}
/**
@@ -72,6 +62,19 @@ abstract class WC_Session {
* @return void
*/
public function __unset( $property ) {
- unset( $this->_data[ $property ] );
+ if ( isset( $this->_data[ $property ] ) ) {
+ unset( $this->_data[ $property ] );
+ $this->_dirty = true;
+ }
}
+
+ /**
+ * get_customer_id function.
+ *
+ * @access public
+ * @return void
+ */
+ public function get_customer_id() {
+ return $this->_customer_id;
+ }
}
\ No newline at end of file
diff --git a/classes/class-wc-settings-api.php b/classes/abstracts/abstract-wc-settings-api.php
similarity index 62%
rename from classes/class-wc-settings-api.php
rename to classes/abstracts/abstract-wc-settings-api.php
index 8b9331c15a3..d76a2e74665 100644
--- a/classes/class-wc-settings-api.php
+++ b/classes/abstracts/abstract-wc-settings-api.php
@@ -3,27 +3,27 @@
* Admin Settings API used by Shipping Methods and Payment Gateways
*
* @class WC_Settings_API
- * @version 1.6.4
- * @package WooCommerce/Classes
+ * @version 2.0.0
+ * @package WooCommerce/Abstracts
+ * @category Abstract Class
* @author WooThemes
*/
-class WC_Settings_API {
+abstract class WC_Settings_API {
/** @var string The plugin ID. Used for option names. */
- var $plugin_id = 'woocommerce_';
+ public $plugin_id = 'woocommerce_';
/** @var array Array of setting values. */
- var $settings = array();
+ public $settings = array();
/** @var array Array of form option fields. */
- var $form_fields = array();
+ public $form_fields = array();
/** @var array Array of validation errors. */
- var $errors = array();
+ public $errors = array();
/** @var array Sanitized fields after validation. */
- var $sanitized_fields = array();
-
+ public $sanitized_fields = array();
/**
* Admin Options
@@ -35,8 +35,8 @@ class WC_Settings_API {
* @access public
* @return void
*/
- function admin_options() { ?>
-
method_title ) ) ? $this->method_title : __( 'Settings','woocommerce' ) ; ?>
+ public function admin_options() { ?>
+
method_title ) ) ? $this->method_title : __( 'Settings', 'woocommerce' ) ; ?>
method_description ) ) ? wpautop( $this->method_description ) : ''; ?>
@@ -45,6 +45,7 @@ class WC_Settings_API {
display_errors();
return false;
} else {
- update_option( $this->plugin_id . $this->id . '_settings', $this->sanitized_fields );
+ update_option( $this->plugin_id . $this->id . '_settings', apply_filters( 'woocommerce_settings_api_sanitized_fields_' . $this->id, $this->sanitized_fields ) );
return true;
}
}
+
/**
* Display admin error messages.
*
@@ -86,7 +87,8 @@ class WC_Settings_API {
* @access public
* @return void
*/
- function display_errors() {}
+ public function display_errors() {}
+
/**
* Initialise Gateway Settings
@@ -100,34 +102,55 @@ class WC_Settings_API {
* @access public
* @return void
*/
- function init_settings() {
+ public function init_settings() {
+
+ if ( ! empty( $this->settings ) )
+ return;
// Load form_field settings
- if ( $this->form_fields ) {
+ $this->settings = get_option( $this->plugin_id . $this->id . '_settings', null );
- $form_field_settings = ( array ) get_option( $this->plugin_id . $this->id . '_settings' );
+ if ( ! $this->settings || ! is_array( $this->settings ) ) {
- if ( ! $form_field_settings ) {
+ $this->settings = array();
- // If there are no settings defined, load defaults
+ // If there are no settings defined, load defaults
+ if ( $this->form_fields )
foreach ( $this->form_fields as $k => $v )
- $form_field_settings[ $k ] = isset( $v['default'] ) ? $v['default'] : '';
-
- } else {
-
- // Prevent "undefined index" errors.
- foreach ( $this->form_fields as $k => $v )
- $form_field_settings[ $k ] = isset( $form_field_settings[ $k ] ) ? $form_field_settings[ $k ] : ( isset( $v['default'] ) ? $v['default'] : '' );
-
- }
-
- // Set and decode escaped values
- $this->settings = array_map( array( &$this, 'format_settings' ), $form_field_settings );
+ $this->settings[ $k ] = isset( $v['default'] ) ? $v['default'] : '';
}
- if ( isset( $this->settings['enabled'] ) && ( $this->settings['enabled'] == 'yes' ) )
- $this->enabled = 'yes';
+ if ( $this->settings && is_array( $this->settings ) ) {
+ $this->settings = array_map( array( $this, 'format_settings' ), $this->settings );
+ $this->enabled = isset( $this->settings['enabled'] ) && $this->settings['enabled'] == 'yes' ? 'yes' : 'no';
+ }
+ }
+
+ /**
+ * get_option function.
+ *
+ * Gets and option from the settings API, using defaults if necessary to prevent undefined notices.
+ *
+ * @access public
+ * @param mixed $key
+ * @param mixed $empty_value
+ * @return void
+ */
+ public function get_option( $key, $empty_value = '' ) {
+
+ if ( empty( $this->settings ) )
+ $this->init_settings();
+
+ // Get option default if unset
+ if ( ! isset( $this->settings[ $key ] ) ) {
+ $this->settings[ $key ] = isset( $this->form_fields[ $key ]['default'] ) ? $this->form_fields[ $key ]['default'] : '';
+ }
+
+ if ( empty( $this->settings[ $key ] ) )
+ $this->settings[ $key ] = $empty_value;
+
+ return $this->settings[ $key ];
}
@@ -138,7 +161,7 @@ class WC_Settings_API {
* @param mixed $value
* @return array
*/
- function format_settings( $value ) {
+ public function format_settings( $value ) {
return ( is_array( $value ) ) ? $value : html_entity_decode( $value );
}
@@ -155,10 +178,11 @@ class WC_Settings_API {
* @access public
* @return string the html for the settings
*/
- function generate_settings_html ( $form_fields = false ) {
+ public function generate_settings_html ( $form_fields = false ) {
- if ( ! $form_fields )
+ if ( ! $form_fields ) {
$form_fields = $this->form_fields;
+ }
$html = '';
foreach ( $form_fields as $k => $v ) {
@@ -184,7 +208,9 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function generate_text_html( $key, $data ) {
+ public function generate_text_html( $key, $data ) {
+ global $woocommerce;
+
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
@@ -193,6 +219,22 @@ class WC_Settings_API {
$data['css'] = isset( $data['css'] ) ? $data['css'] : '';
$data['placeholder'] = isset( $data['placeholder'] ) ? $data['placeholder'] : '';
$data['type'] = isset( $data['type'] ) ? $data['type'] : 'text';
+ $data['desc_tip'] = isset( $data['desc_tip'] ) ? $data['desc_tip'] : false;
+ $data['description'] = isset( $data['description'] ) ? $data['description'] : '';
+
+ // Description handling
+ if ( $data['desc_tip'] === true ) {
+ $description = '';
+ $tip = $data['description'];
+ } elseif ( ! empty( $data['desc_tip'] ) ) {
+ $description = $data['description'];
+ $tip = $data['desc_tip'];
+ } elseif ( ! empty( $data['description'] ) ) {
+ $description = $data['description'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
// Custom attribute handling
$custom_attributes = array();
@@ -204,12 +246,18 @@ class WC_Settings_API {
$html .= '
' . "\n";
$html .= '';
$html .= '' . wp_kses_post( $data['title'] ) . ' ';
+
+ if ( $tip )
+ $html .= ' ';
+
$html .= ' ' . "\n";
$html .= '' . "\n";
$html .= '' . wp_kses_post( $data['title'] ) . ' ' . "\n";
- $value = ( isset( $this->settings[ $key ] ) ) ? esc_attr( $this->settings[ $key ] ) : '';
- $html .= ' ';
- if ( isset( $data['description'] ) && $data['description'] != '' ) { $html .= ' ' . wp_kses_post( $data['description'] ) . '
' . "\n"; }
+ $html .= ' ';
+
+ if ( $description )
+ $html .= ' ' . wp_kses_post( $description ) . '
' . "\n";
+
$html .= ' ';
$html .= ' ' . "\n";
$html .= ' ' . "\n";
@@ -226,13 +274,31 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function generate_password_html( $key, $data ) {
+ public function generate_password_html( $key, $data ) {
+ global $woocommerce;
+
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
$data['disabled'] = empty( $data['disabled'] ) ? false : true;
$data['class'] = isset( $data['class'] ) ? $data['class'] : '';
$data['css'] = isset( $data['css'] ) ? $data['css'] : '';
+ $data['desc_tip'] = isset( $data['desc_tip'] ) ? $data['desc_tip'] : false;
+ $data['description'] = isset( $data['description'] ) ? $data['description'] : '';
+
+ // Description handling
+ if ( $data['desc_tip'] === true ) {
+ $description = '';
+ $tip = $data['description'];
+ } elseif ( ! empty( $data['desc_tip'] ) ) {
+ $description = $data['description'];
+ $tip = $data['desc_tip'];
+ } elseif ( ! empty( $data['description'] ) ) {
+ $description = $data['description'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
// Custom attribute handling
$custom_attributes = array();
@@ -244,12 +310,18 @@ class WC_Settings_API {
$html .= '
' . "\n";
$html .= '';
$html .= '' . wp_kses_post( $data['title'] ) . ' ';
+
+ if ( $tip )
+ $html .= ' ';
+
$html .= ' ' . "\n";
$html .= '' . "\n";
$html .= '' . wp_kses_post( $data['title'] ) . ' ' . "\n";
- $value = ( isset( $this->settings[ $key ] ) ) ? esc_attr( $this->settings[ $key ] ) : '';
- $html .= ' ';
- if ( isset( $data['description'] ) && $data['description'] != '' ) { $html .= ' ' . esc_attr( $data['description'] ) . '
' . "\n"; }
+ $html .= ' ';
+
+ if ( $description )
+ $html .= ' ' . wp_kses_post( $description ) . '
' . "\n";
+
$html .= ' ';
$html .= ' ' . "\n";
$html .= ' ' . "\n";
@@ -266,14 +338,32 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function generate_textarea_html( $key, $data ) {
+ public function generate_textarea_html( $key, $data ) {
+ global $woocommerce;
+
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
$data['disabled'] = empty( $data['disabled'] ) ? false : true;
- if ( ! isset( $this->settings[$key] ) ) $this->settings[$key] = '';
$data['class'] = isset( $data['class'] ) ? $data['class'] : '';
$data['css'] = isset( $data['css'] ) ? $data['css'] : '';
+ $data['desc_tip'] = isset( $data['desc_tip'] ) ? $data['desc_tip'] : false;
+ $data['description'] = isset( $data['description'] ) ? $data['description'] : '';
+ $data['placeholder'] = isset( $data['placeholder'] ) ? $data['placeholder'] : '';
+
+ // Description handling
+ if ( $data['desc_tip'] === true ) {
+ $description = '';
+ $tip = $data['description'];
+ } elseif ( ! empty( $data['desc_tip'] ) ) {
+ $description = $data['description'];
+ $tip = $data['desc_tip'];
+ } elseif ( ! empty( $data['description'] ) ) {
+ $description = $data['description'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
// Custom attribute handling
$custom_attributes = array();
@@ -285,12 +375,18 @@ class WC_Settings_API {
$html .= '
' . "\n";
$html .= '';
$html .= '' . wp_kses_post( $data['title'] ) . ' ';
+
+ if ( $tip )
+ $html .= ' ';
+
$html .= ' ' . "\n";
$html .= '' . "\n";
$html .= '' . wp_kses_post( $data['title'] ) . ' ' . "\n";
- $value = ( isset( $this->settings[ $key ] ) ) ? esc_textarea( $this->settings[ $key ] ) : '';
- $html .= '';
- if ( isset( $data['description'] ) && $data['description'] != '' ) { $html .= ' ' . wp_kses_post( $data['description'] ) . '
' . "\n"; }
+ $html .= '';
+
+ if ( $description )
+ $html .= ' ' . wp_kses_post( $description ) . '
' . "\n";
+
$html .= ' ';
$html .= ' ' . "\n";
$html .= ' ' . "\n";
@@ -307,14 +403,32 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function generate_checkbox_html( $key, $data ) {
+ public function generate_checkbox_html( $key, $data ) {
+ global $woocommerce;
+
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
$data['label'] = isset( $data['label'] ) ? $data['label'] : $data['title'];
$data['disabled'] = empty( $data['disabled'] ) ? false : true;
- $data['class'] = isset( $data['class'] ) ? $data['class'] : '';
- $data['css'] = isset( $data['css'] ) ? $data['css'] : '';
+ $data['class'] = isset( $data['class'] ) ? $data['class'] : '';
+ $data['css'] = isset( $data['css'] ) ? $data['css'] : '';
+ $data['desc_tip'] = isset( $data['desc_tip'] ) ? $data['desc_tip'] : false;
+ $data['description'] = isset( $data['description'] ) ? $data['description'] : '';
+
+ // Description handling
+ if ( $data['desc_tip'] === true ) {
+ $description = '';
+ $tip = $data['description'];
+ } elseif ( ! empty( $data['desc_tip'] ) ) {
+ $description = $data['description'];
+ $tip = $data['desc_tip'];
+ } elseif ( ! empty( $data['description'] ) ) {
+ $description = $data['description'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
// Custom attribute handling
$custom_attributes = array();
@@ -324,12 +438,20 @@ class WC_Settings_API {
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
$html .= '
' . "\n";
- $html .= '' . $data['title'] . ' ' . "\n";
+ $html .= '' . $data['title'];
+
+ if ( $tip )
+ $html .= ' ';
+
+ $html .= ' ' . "\n";
$html .= '' . "\n";
$html .= '' . wp_kses_post( $data['title'] ) . ' ' . "\n";
$html .= '';
- $html .= ' settings[$key], 'yes', false ) . ' class="' . esc_attr( $data['class'] ).'" ' . disabled( $data['disabled'], true, false ) . ' ' . implode( ' ', $custom_attributes ) . ' /> ' . wp_kses_post( $data['label'] ) . ' ' . "\n";
- if ( isset( $data['description'] ) && $data['description'] != '' ) { $html .= ' ' . wp_kses_post( $data['description'] ) . '
' . "\n"; }
+ $html .= ' get_option( $key ), 'yes', false ) . ' class="' . esc_attr( $data['class'] ).'" ' . disabled( $data['disabled'], true, false ) . ' ' . implode( ' ', $custom_attributes ) . ' /> ' . wp_kses_post( $data['label'] ) . ' ' . "\n";
+
+ if ( $description )
+ $html .= ' ' . wp_kses_post( $description ) . '
' . "\n";
+
$html .= ' ';
$html .= ' ' . "\n";
$html .= ' ' . "\n";
@@ -346,7 +468,9 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function generate_select_html( $key, $data ) {
+ public function generate_select_html( $key, $data ) {
+ global $woocommerce;
+
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
@@ -354,6 +478,22 @@ class WC_Settings_API {
$data['options'] = isset( $data['options'] ) ? (array) $data['options'] : array();
$data['class'] = isset( $data['class'] ) ? $data['class'] : '';
$data['css'] = isset( $data['css'] ) ? $data['css'] : '';
+ $data['desc_tip'] = isset( $data['desc_tip'] ) ? $data['desc_tip'] : false;
+ $data['description'] = isset( $data['description'] ) ? $data['description'] : '';
+
+ // Description handling
+ if ( $data['desc_tip'] === true ) {
+ $description = '';
+ $tip = $data['description'];
+ } elseif ( ! empty( $data['desc_tip'] ) ) {
+ $description = $data['description'];
+ $tip = $data['desc_tip'];
+ } elseif ( ! empty( $data['description'] ) ) {
+ $description = $data['description'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
// Custom attribute handling
$custom_attributes = array();
@@ -365,17 +505,24 @@ class WC_Settings_API {
$html .= '
' . "\n";
$html .= '';
$html .= '' . wp_kses_post( $data['title'] ) . ' ';
+
+ if ( $tip )
+ $html .= ' ';
+
$html .= ' ' . "\n";
$html .= '' . "\n";
$html .= '' . wp_kses_post( $data['title'] ) . ' ' . "\n";
$html .= '';
foreach ($data['options'] as $option_key => $option_value) :
- $html .= 'settings[$key]), false).'>' . esc_attr( $option_value ) . ' ';
+ $html .= 'get_option( $key ) ), false ).'>' . esc_attr( $option_value ) . ' ';
endforeach;
$html .= ' ';
- if ( isset( $data['description'] ) && $data['description'] != '' ) { $html .= ' ' . wp_kses_post( $data['description'] ) . '
' . "\n"; }
+
+ if ( $description )
+ $html .= ' ' . wp_kses_post( $description ) . '
' . "\n";
+
$html .= ' ';
$html .= ' ' . "\n";
$html .= ' ' . "\n";
@@ -392,7 +539,9 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function generate_multiselect_html( $key, $data ) {
+ public function generate_multiselect_html( $key, $data ) {
+ global $woocommerce;
+
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
@@ -400,6 +549,22 @@ class WC_Settings_API {
$data['options'] = isset( $data['options'] ) ? (array) $data['options'] : array();
$data['class'] = isset( $data['class'] ) ? $data['class'] : '';
$data['css'] = isset( $data['css'] ) ? $data['css'] : '';
+ $data['desc_tip'] = isset( $data['desc_tip'] ) ? $data['desc_tip'] : false;
+ $data['description'] = isset( $data['description'] ) ? $data['description'] : '';
+
+ // Description handling
+ if ( $data['desc_tip'] === true ) {
+ $description = '';
+ $tip = $data['description'];
+ } elseif ( ! empty( $data['desc_tip'] ) ) {
+ $description = $data['description'];
+ $tip = $data['desc_tip'];
+ } elseif ( ! empty( $data['description'] ) ) {
+ $description = $data['description'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
// Custom attribute handling
$custom_attributes = array();
@@ -411,19 +576,24 @@ class WC_Settings_API {
$html .= '
' . "\n";
$html .= '';
$html .= '' . wp_kses_post( $data['title'] ) . ' ';
+
+ if ( $tip )
+ $html .= ' ';
+
$html .= ' ' . "\n";
$html .= '' . "\n";
$html .= '' . wp_kses_post( $data['title'] ) . ' ' . "\n";
$html .= '';
foreach ( $data['options'] as $option_key => $option_value) {
- $html .= 'settings[ $key ] ) && in_array( $option_key, (array) $this->settings[ $key ] ) ) $html .= 'selected="selected"';
- $html .= '>' . esc_attr( $option_value ) . ' ';
+ $html .= 'get_option( $key, array() ) ), true, false ) . '>' . esc_attr( $option_value ) . ' ';
}
$html .= ' ';
- if ( isset( $data['description'] ) && $data['description'] != '' ) { $html .= '' . wp_kses_post( $data['description'] ) . '
' . "\n"; }
+
+ if ( $description )
+ $html .= ' ' . wp_kses_post( $description ) . '
' . "\n";
+
$html .= ' ';
$html .= ' ' . "\n";
$html .= ' ' . "\n";
@@ -440,7 +610,7 @@ class WC_Settings_API {
* @since 1.6.2
* @return string
*/
- function generate_title_html( $key, $data ) {
+ public function generate_title_html( $key, $data ) {
$html = '';
$data['title'] = isset( $data['title'] ) ? $data['title'] : '';
@@ -466,7 +636,7 @@ class WC_Settings_API {
* @param bool $form_fields (default: false)
* @return void
*/
- function validate_settings_fields( $form_fields = false ) {
+ public function validate_settings_fields( $form_fields = false ) {
if ( ! $form_fields )
$form_fields = $this->form_fields;
@@ -498,7 +668,7 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function validate_checkbox_field( $key ) {
+ public function validate_checkbox_field( $key ) {
$status = 'no';
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) && ( 1 == $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$status = 'yes';
@@ -517,8 +687,8 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function validate_text_field( $key ) {
- $text = ( isset( $this->settings[ $key ] ) ) ? $this->settings[ $key ] : '';
+ public function validate_text_field( $key ) {
+ $text = $this->get_option( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$text = esc_attr( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
@@ -538,8 +708,8 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function validate_password_field( $key ) {
- $text = (isset($this->settings[$key])) ? $this->settings[$key] : '';
+ public function validate_password_field( $key ) {
+ $text = $this->get_option( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$text = esc_attr( woocommerce_clean( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
@@ -559,8 +729,8 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function validate_textarea_field( $key ) {
- $text = ( isset( $this->settings[ $key ] ) ) ? $this->settings[ $key ] : '';
+ public function validate_textarea_field( $key ) {
+ $text = $this->get_option( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$text = esc_attr( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
@@ -580,8 +750,8 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function validate_select_field( $key ) {
- $value = ( isset( $this->settings[ $key ] ) ) ? $this->settings[ $key ] : '';
+ public function validate_select_field( $key ) {
+ $value = $this->get_option( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$value = esc_attr( woocommerce_clean( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
@@ -600,8 +770,8 @@ class WC_Settings_API {
* @since 1.0.0
* @return string
*/
- function validate_multiselect_field( $key ) {
- $value = ( isset( $this->settings[ $key ] ) ) ? $this->settings[ $key ] : '';
+ public function validate_multiselect_field( $key ) {
+ $value = $this->get_option( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$value = array_map('esc_attr', array_map('woocommerce_clean', (array) $_POST[ $this->plugin_id . $this->id . '_' . $key ] ));
diff --git a/classes/shipping/class-wc-shipping-method.php b/classes/abstracts/abstract-wc-shipping-method.php
similarity index 84%
rename from classes/shipping/class-wc-shipping-method.php
rename to classes/abstracts/abstract-wc-shipping-method.php
index 790c129c65b..21840b2e335 100644
--- a/classes/shipping/class-wc-shipping-method.php
+++ b/classes/abstracts/abstract-wc-shipping-method.php
@@ -1,4 +1,7 @@
0 && get_option( 'woocommerce_calc_taxes' ) == 'yes' && $this->tax_status == 'taxable' ) {
$_tax = new WC_Tax();
@@ -208,7 +209,7 @@ class WC_Shipping_Method extends WC_Settings_API {
* @access public
* @param mixed $fee
* @param mixed $total
- * @return void
+ * @return float
*/
function get_fee( $fee, $total ) {
if ( strstr( $fee, '%' ) ) :
@@ -230,54 +231,4 @@ class WC_Shipping_Method extends WC_Settings_API {
function supports( $feature ) {
return apply_filters( 'woocommerce_shipping_method_supports', in_array( $feature, $this->supports ) ? true : false, $feature, $this );
}
-}
-
-/**
- * WooCommerce Shipping Rate Class
- *
- * Simple Class for storing rates.
- *
- * @class WC_Shipping_Rate
- * @version 1.6.4
- * @package WooCommerce/Classes/Shipping
- * @author WooThemes
- */
-class WC_Shipping_Rate {
-
- var $id = '';
- var $label = '';
- var $cost = 0;
- var $taxes = array();
- var $method_id = '';
-
- /**
- * __construct function.
- *
- * @access public
- * @param mixed $id
- * @param mixed $label
- * @param mixed $cost
- * @param mixed $taxes
- * @return void
- */
- public function __construct( $id, $label, $cost, $taxes, $method_id ) {
- $this->id = $id;
- $this->label = $label;
- $this->cost = $cost;
- $this->taxes = $taxes ? $taxes : array();
- $this->method_id = $method_id;
- }
-
- /**
- * get_shipping_tax function.
- *
- * @access public
- * @return array
- */
- function get_shipping_tax() {
- $taxes = 0;
- if ( $this->taxes && sizeof( $this->taxes ) > 0 )
- $taxes = array_sum( $this->taxes );
- return $taxes;
- }
}
\ No newline at end of file
diff --git a/classes/class-wc-api.php b/classes/class-wc-api.php
new file mode 100644
index 00000000000..ab69ece5a40
--- /dev/null
+++ b/classes/class-wc-api.php
@@ -0,0 +1,79 @@
+query_vars['wc-api'] = $_GET['wc-api'];
+
+ if ( ! empty( $wp->query_vars['wc-api'] ) ) {
+ // Buffer, we won't want any output here
+ ob_start();
+
+ // Get API trigger
+ $api = strtolower( esc_attr( $wp->query_vars['wc-api'] ) );
+
+ // Load class if exists
+ if ( class_exists( $api ) )
+ $api_class = new $api();
+
+ // Trigger actions
+ do_action( 'woocommerce_api_' . $api );
+
+ // Done, clear buffer and exit
+ ob_end_clean();
+ die('1');
+ }
+ }
+}
\ No newline at end of file
diff --git a/classes/class-wc-cart.php b/classes/class-wc-cart.php
index 8580ca06a50..b41c6c8e937 100644
--- a/classes/class-wc-cart.php
+++ b/classes/class-wc-cart.php
@@ -8,72 +8,73 @@
* @class WC_Cart
* @version 2.0.0
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Cart {
/** @var array Contains an array of cart items. */
- var $cart_contents;
+ public $cart_contents;
/** @var array Contains an array of coupon codes applied to the cart. */
- var $applied_coupons;
+ public $applied_coupons;
/** @var array Contains an array of coupon code discounts after they have been applied. */
- var $coupon_discount_amounts;
+ public $coupon_discount_amounts;
/** @var float The total cost of the cart items. */
- var $cart_contents_total;
+ public $cart_contents_total;
/** @var float The total weight of the cart items. */
- var $cart_contents_weight;
+ public $cart_contents_weight;
/** @var float The total count of the cart items. */
- var $cart_contents_count;
+ public $cart_contents_count;
/** @var float The total tax for the cart items. */
- var $cart_contents_tax;
+ public $cart_contents_tax;
/** @var float Cart grand total. */
- var $total;
+ public $total;
/** @var float Cart subtotal. */
- var $subtotal;
+ public $subtotal;
/** @var float Cart subtotal without tax. */
- var $subtotal_ex_tax;
+ public $subtotal_ex_tax;
/** @var float Total cart tax. */
- var $tax_total;
+ public $tax_total;
/** @var array An array of taxes/tax rates for the cart. */
- var $taxes;
+ public $taxes;
/** @var array An array of taxes/tax rates for the shipping. */
- var $shipping_taxes;
+ public $shipping_taxes;
/** @var float Discounts before tax. */
- var $discount_cart;
+ public $discount_cart;
/** @var float Discounts after tax. */
- var $discount_total;
+ public $discount_total;
- /** @var float Total for additonal fees. */
- var $fee_total;
+ /** @var float Total for additional fees. */
+ public $fee_total;
/** @var float Shipping cost. */
- var $shipping_total;
+ public $shipping_total;
/** @var float Shipping tax. */
- var $shipping_tax_total;
+ public $shipping_tax_total;
/** @var float Shipping title/label. */
- var $shipping_label;
+ public $shipping_label;
/** @var WC_Tax */
- var $tax;
+ public $tax;
/** @var array An array of fees. */
- var $fees;
+ public $fees;
/**
* Constructor for the cart class. Loads options and hooks in the init method.
@@ -81,7 +82,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function __construct() {
+ public function __construct() {
$this->tax = new WC_Tax();
$this->prices_include_tax = ( get_option( 'woocommerce_prices_include_tax' ) == 'yes' ) ? true : false;
$this->tax_display_cart = get_option( 'woocommerce_tax_display_cart' );
@@ -90,7 +91,7 @@ class WC_Cart {
$this->display_totals_ex_tax = $this->tax_display_cart == 'excl' ? true : false;
$this->display_cart_ex_tax = $this->tax_display_cart == 'excl' ? true : false;
- add_action( 'init', array( &$this, 'init' ), 5 ); // Get cart on init
+ add_action( 'init', array( $this, 'init' ), 5 ); // Get cart on init
}
@@ -100,12 +101,12 @@ class WC_Cart {
* @access public
* @return void
*/
- function init() {
+ public function init() {
$this->get_cart_from_session();
- add_action('woocommerce_check_cart_items', array( &$this, 'check_cart_items' ), 1 );
- add_action('woocommerce_check_cart_items', array( &$this, 'check_cart_coupons' ), 1 );
- add_action('woocommerce_after_checkout_validation', array( &$this, 'check_customer_coupons' ), 1 );
+ add_action('woocommerce_check_cart_items', array( $this, 'check_cart_items' ), 1 );
+ add_action('woocommerce_check_cart_items', array( $this, 'check_cart_coupons' ), 1 );
+ add_action('woocommerce_after_checkout_validation', array( $this, 'check_customer_coupons' ), 1 );
}
/*-----------------------------------------------------------------------------------*/
@@ -118,14 +119,12 @@ class WC_Cart {
* @access public
* @return void
*/
- function get_cart_from_session() {
+ public function get_cart_from_session() {
global $woocommerce;
// Load the coupons
- if ( get_option( 'woocommerce_enable_coupons' ) == 'yes' ) {
- $this->applied_coupons = ( empty( $woocommerce->session->coupon_codes ) ) ? array() : array_filter( (array) $woocommerce->session->coupon_codes );
- $this->coupon_discount_amounts = ( empty( $woocommerce->session->coupon_amounts ) ) ? array() : array_filter( (array) $woocommerce->session->coupon_amounts );
- }
+ $this->applied_coupons = ( empty( $woocommerce->session->coupon_codes ) ) ? array() : array_filter( (array) $woocommerce->session->coupon_codes );
+ $this->coupon_discount_amounts = ( empty( $woocommerce->session->coupon_amounts ) ) ? array() : array_filter( (array) $woocommerce->session->coupon_amounts );
// Load the cart
if ( isset( $woocommerce->session->cart ) && is_array( $woocommerce->session->cart ) ) {
@@ -135,7 +134,7 @@ class WC_Cart {
$_product = get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
- if ( $_product->exists() && $values['quantity'] > 0 ) {
+ if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
// Put session data into array. Run through filter so other plugins can load their own session data
$this->cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', array(
@@ -149,6 +148,8 @@ class WC_Cart {
}
}
+ do_action( 'woocommerce_cart_loaded_from_session', $this );
+
if ( ! is_array( $this->cart_contents ) )
$this->cart_contents = array();
@@ -181,22 +182,19 @@ class WC_Cart {
// Queue re-calc if subtotal is not set
if ( ! $this->subtotal && sizeof( $this->cart_contents ) > 0 )
- $this->set_session();
+ $this->calculate_totals();
}
/**
- * Sets the php session data for the cart and coupons and re-calculates totals.
+ * Sets the php session data for the cart and coupons.
*
* @access public
* @return void
*/
- function set_session() {
+ public function set_session() {
global $woocommerce;
- // Re-calc totals
- $this->calculate_totals();
-
// Set cart and coupon session data
$cart_session = array();
@@ -244,7 +242,7 @@ class WC_Cart {
* @param bool $clear_persistent_cart (default: true)
* @return void
*/
- function empty_cart( $clear_persistent_cart = true ) {
+ public function empty_cart( $clear_persistent_cart = true ) {
global $woocommerce;
$this->cart_contents = array();
@@ -268,7 +266,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function persistent_cart_update() {
+ public function persistent_cart_update() {
global $woocommerce;
update_user_meta( get_current_user_id(), '_woocommerce_persistent_cart', array(
@@ -283,7 +281,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function persistent_cart_destroy() {
+ public function persistent_cart_destroy() {
delete_user_meta( get_current_user_id(), '_woocommerce_persistent_cart' );
}
@@ -291,13 +289,25 @@ class WC_Cart {
/* Cart Data Functions */
/*-----------------------------------------------------------------------------------*/
+ /**
+ * Coupons enabled function. Filterable.
+ *
+ * @access public
+ * @return void
+ */
+ public function coupons_enabled() {
+ $coupons_enabled = get_option( 'woocommerce_enable_coupons' ) == 'no' ? false : true;
+
+ return apply_filters( 'woocommerce_coupons_enabled', $coupons_enabled );
+ }
+
/**
* Get number of items in the cart.
*
* @access public
* @return int
*/
- function get_cart_contents_count() {
+ public function get_cart_contents_count() {
return apply_filters( 'woocommerce_cart_contents_count', $this->cart_contents_count );
}
@@ -308,7 +318,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function check_cart_items() {
+ public function check_cart_items() {
global $woocommerce;
// Check item stock
@@ -325,7 +335,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function check_cart_coupons() {
+ public function check_cart_coupons() {
global $woocommerce;
if ( ! empty( $this->applied_coupons ) ) {
@@ -334,7 +344,7 @@ class WC_Cart {
if ( is_wp_error( $coupon->is_valid() ) ) {
- $woocommerce->add_error( sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), $code ) );
+ $coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_INVALID_REMOVED );
// Remove the coupon
unset( $this->applied_coupons[ $key ] );
@@ -352,7 +362,7 @@ class WC_Cart {
* @access public
* @return array
*/
- function get_cart_item_quantities() {
+ public function get_cart_item_quantities() {
$quantities = array();
foreach ( $this->get_cart() as $cart_item_key => $values ) {
@@ -391,14 +401,14 @@ class WC_Cart {
* @access public
* @param array $posted
*/
- function check_customer_coupons( $posted ) {
+ public function check_customer_coupons( $posted ) {
global $woocommerce;
if ( ! empty( $this->applied_coupons ) ) {
foreach ( $this->applied_coupons as $key => $code ) {
$coupon = new WC_Coupon( $code );
- if ( is_array( $coupon->customer_email ) && sizeof( $coupon->customer_email ) > 0 ) {
+ if ( ! is_wp_error( $coupon->is_valid() ) && is_array( $coupon->customer_email ) && sizeof( $coupon->customer_email ) > 0 ) {
$coupon->customer_email = array_map( 'sanitize_email', $coupon->customer_email );
@@ -411,7 +421,8 @@ class WC_Cart {
$check_emails = array_map( 'sanitize_email', array_map( 'strtolower', $check_emails ) );
if ( 0 == sizeof( array_intersect( $check_emails, $coupon->customer_email ) ) ) {
- $woocommerce->add_error( sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), $code ) );
+ $coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED );
+
// Remove the coupon
unset( $this->applied_coupons[ $key ] );
@@ -429,7 +440,9 @@ class WC_Cart {
* @access public
* @return bool
*/
- function check_cart_item_stock() {
+ public function check_cart_item_stock() {
+ global $woocommerce, $wpdb;
+
$error = new WP_Error();
$product_qty_in_cart = $this->get_cart_item_quantities();
@@ -452,31 +465,76 @@ class WC_Cart {
return $error;
}
+ // For later on...
+ $key = '_product_id';
+ $value = $values['product_id'];
+ $in_cart = $values['quantity'];
+
/**
* Next check entire cart quantities
*/
- if ( $values['variation_id'] && $_product->variation_has_stock && isset( $product_qty_in_cart[$values['variation_id']] ) ) {
+ if ( $values['variation_id'] && $_product->variation_has_stock && isset( $product_qty_in_cart[ $values['variation_id'] ] ) ) {
- if ( ! $_product->has_enough_stock( $product_qty_in_cart[$values['variation_id']] ) ) {
- $error->add( 'out-of-stock', sprintf(__( 'Sorry, we do not have enough "%s" in stock to fulfill your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title(), $_product->stock ) );
+ $key = '_variation_id';
+ $value = $values['variation_id'];
+ $in_cart = $product_qty_in_cart[ $values['variation_id'] ];
+
+ if ( ! $_product->has_enough_stock( $product_qty_in_cart[ $values['variation_id'] ] ) ) {
+ $error->add( 'out-of-stock', sprintf(__( 'Sorry, we do not have enough "%s" in stock to fulfil your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title(), $_product->stock ) );
return $error;
}
- } elseif ( isset( $product_qty_in_cart[$values['product_id']] ) ) {
+ } elseif ( isset( $product_qty_in_cart[ $values['product_id'] ] ) ) {
- if ( ! $_product->has_enough_stock( $product_qty_in_cart[$values['product_id']] ) ) {
- $error->add( 'out-of-stock', sprintf(__( 'Sorry, we do not have enough "%s" in stock to fulfill your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title(), $_product->stock ) );
+ $in_cart = $product_qty_in_cart[ $values['product_id'] ];
+
+ if ( ! $_product->has_enough_stock( $product_qty_in_cart[ $values['product_id'] ] ) ) {
+ $error->add( 'out-of-stock', sprintf(__( 'Sorry, we do not have enough "%s" in stock to fulfil your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title(), $_product->stock ) );
return $error;
}
}
+ /**
+ * Finally consider any held stock, from pending orders
+ */
+ if ( get_option( 'woocommerce_hold_stock_minutes' ) > 0 && ! $_product->backorders_allowed() ) {
+
+ $order_id = isset( $woocommerce->session->order_awaiting_payment ) ? absint( $woocommerce->session->order_awaiting_payment ) : 0;
+
+ $held_stock = $wpdb->get_var( $wpdb->prepare( "
+ SELECT SUM( order_item_meta.meta_value ) AS held_qty
+
+ FROM {$wpdb->posts} AS posts
+
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_items as order_items ON posts.ID = order_items.order_id
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as order_item_meta2 ON order_items.order_item_id = order_item_meta2.order_item_id
+ LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
+ LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
+ LEFT JOIN {$wpdb->terms} AS term USING( term_id )
+
+ WHERE order_item_meta.meta_key = '_qty'
+ AND order_item_meta2.meta_key = %s AND order_item_meta2.meta_value = %d
+ AND posts.post_type = 'shop_order'
+ AND posts.post_status = 'publish'
+ AND tax.taxonomy = 'shop_order_status'
+ AND term.slug IN ('pending')
+ AND posts.ID != %d
+ ", $key, $value, $order_id ) );
+
+ if ( $_product->stock < ( $held_stock + $in_cart ) ) {
+ $error->add( 'out-of-stock', sprintf(__( 'Sorry, we do not have enough "%s" in stock to fulfil your order right now. Please try again in %d minutes or edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title(), get_option( 'woocommerce_hold_stock_minutes' ) ) );
+ return $error;
+ }
+ }
+
/**
* Check stock based on stock-status
*/
} else {
if ( ! $_product->is_in_stock() ) {
- $error->add( 'out-of-stock', sprintf(__( 'Sorry, we do not have enough "%s" in stock to fulfill your order. Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title() ) );
+ $error->add( 'out-of-stock', sprintf(__( 'Sorry, "%s" is not in stock. Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce' ), $_product->get_title() ) );
return $error;
}
}
@@ -493,7 +551,7 @@ class WC_Cart {
* @param bool $flat (default: false)
* @return string
*/
- function get_item_data( $cart_item, $flat = false ) {
+ public function get_item_data( $cart_item, $flat = false ) {
global $woocommerce;
$return = '';
@@ -515,8 +573,10 @@ class WC_Cart {
$term = get_term_by( 'slug', $value, esc_attr( str_replace( 'attribute_', '', $name ) ) );
if ( ! is_wp_error( $term ) && $term->name )
$value = $term->name;
+
+ // If this is a custom option slug, get the options name
} else {
- $value = ucfirst( $value );
+ $value = apply_filters( 'woocommerce_variation_option_name', $value );
}
if ( $flat )
@@ -575,7 +635,7 @@ class WC_Cart {
*
* @return array cross_sells (item ids)
*/
- function get_cross_sells() {
+ public function get_cross_sells() {
$cross_sells = array();
$in_cart = array();
if ( sizeof( $this->cart_contents) > 0 ) {
@@ -595,7 +655,7 @@ class WC_Cart {
*
* @return string url to page
*/
- function get_cart_url() {
+ public function get_cart_url() {
$cart_page_id = woocommerce_get_page_id('cart');
if ( $cart_page_id ) return apply_filters( 'woocommerce_get_cart_url', get_permalink( $cart_page_id ) );
}
@@ -605,7 +665,7 @@ class WC_Cart {
*
* @return string url to page
*/
- function get_checkout_url() {
+ public function get_checkout_url() {
$checkout_page_id = woocommerce_get_page_id('checkout');
if ( $checkout_page_id ) {
if ( is_ssl() )
@@ -620,7 +680,7 @@ class WC_Cart {
*
* @return string url to page
*/
- function get_remove_url( $cart_item_key ) {
+ public function get_remove_url( $cart_item_key ) {
global $woocommerce;
$cart_page_id = woocommerce_get_page_id('cart');
if ($cart_page_id)
@@ -632,7 +692,7 @@ class WC_Cart {
*
* @return array contents of the cart
*/
- function get_cart() {
+ public function get_cart() {
return array_filter( (array) $this->cart_contents );
}
@@ -641,7 +701,7 @@ class WC_Cart {
*
* @return array merged taxes
*/
- function get_taxes() {
+ public function get_taxes() {
$merged_taxes = array();
// Merge
@@ -657,7 +717,7 @@ class WC_Cart {
*
* @return array merged taxes
*/
- function get_formatted_taxes() {
+ public function get_formatted_taxes() {
$taxes = $this->get_taxes();
@@ -680,7 +740,7 @@ class WC_Cart {
* @param mixed id of product to find in the cart
* @return string cart item key
*/
- function find_product_in_cart( $cart_id = false ) {
+ public function find_product_in_cart( $cart_id = false ) {
if ( $cart_id !== false )
foreach ( $this->cart_contents as $cart_item_key => $cart_item )
if ( $cart_item_key == $cart_id )
@@ -696,7 +756,7 @@ class WC_Cart {
* @param array $cart_item_data other cart item data passed which affects this items uniqueness in the cart
* @return string cart item key
*/
- function generate_cart_id( $product_id, $variation_id = '', $variation = '', $cart_item_data = array() ) {
+ public function generate_cart_id( $product_id, $variation_id = '', $variation = '', $cart_item_data = array() ) {
$id_parts = array( $product_id );
@@ -732,7 +792,7 @@ class WC_Cart {
* @param array $cart_item_data extra cart item data we want to pass into the item
* @return bool
*/
- function add_to_cart( $product_id, $quantity = 1, $variation_id = '', $variation = '', $cart_item_data = array() ) {
+ public function add_to_cart( $product_id, $quantity = 1, $variation_id = '', $variation = '', $cart_item_data = array() ) {
global $woocommerce;
if ( $quantity <= 0 ) return false;
@@ -748,6 +808,9 @@ class WC_Cart {
$product_data = get_product( $variation_id ? $variation_id : $product_id );
+ if ( ! $product_data )
+ return false;
+
// Force quantity to 1 if sold individually
if ( $product_data->is_sold_individually() )
$quantity = 1;
@@ -834,7 +897,7 @@ class WC_Cart {
$woocommerce->cart_has_contents_cookie( true );
- $this->set_session();
+ $this->calculate_totals();
return true;
}
@@ -845,7 +908,7 @@ class WC_Cart {
* @param string cart_item_key contains the id of the cart item
* @param string quantity contains the quantity of the item
*/
- function set_quantity( $cart_item_key, $quantity = 1 ) {
+ public function set_quantity( $cart_item_key, $quantity = 1 ) {
if ( $quantity == 0 || $quantity < 0 ) {
do_action( 'woocommerce_before_cart_item_quantity_zero', $cart_item_key );
@@ -855,7 +918,7 @@ class WC_Cart {
do_action( 'woocommerce_after_cart_item_quantity_update', $cart_item_key, $quantity );
}
- $this->set_session();
+ $this->calculate_totals();
}
/*-----------------------------------------------------------------------------------*/
@@ -872,7 +935,7 @@ class WC_Cart {
global $woocommerce;
$this->total = $this->cart_contents_total = $this->cart_contents_weight = $this->cart_contents_count = $this->cart_contents_tax = $this->tax_total = $this->shipping_tax_total = $this->subtotal = $this->subtotal_ex_tax = $this->discount_total = $this->discount_cart = $this->shipping_total = $this->fee_total = 0;
- $this->shipping_taxes = $this->taxes = array();
+ $this->shipping_taxes = $this->taxes = $this->coupon_discount_amounts = array();
unset( $woocommerce->session->cart_contents_total, $woocommerce->session->cart_contents_weight, $woocommerce->session->cart_contents_count, $woocommerce->session->cart_contents_tax, $woocommerce->session->total, $woocommerce->session->subtotal, $woocommerce->session->subtotal_ex_tax, $woocommerce->session->tax_total, $woocommerce->session->taxes, $woocommerce->session->shipping_taxes, $woocommerce->session->discount_cart, $woocommerce->session->discount_total, $woocommerce->session->shipping_total, $woocommerce->session->shipping_tax_total, $woocommerce->session->shipping_label );
}
@@ -886,7 +949,7 @@ class WC_Cart {
* @param bool $add_totals (default: false)
* @return float price
*/
- function get_discounted_price( $values, $price, $add_totals = false ) {
+ public function get_discounted_price( $values, $price, $add_totals = false ) {
if ( ! $price ) return $price;
@@ -904,6 +967,7 @@ class WC_Cart {
$this_item_is_discounted = false;
$product_cats = wp_get_post_terms( $values['product_id'], 'product_cat', array("fields" => "ids") );
+ $product_ids_on_sale = woocommerce_get_product_ids_on_sale();
// Specific products get the discount
if ( sizeof( $coupon->product_ids ) > 0 ) {
@@ -934,8 +998,13 @@ class WC_Cart {
if ( sizeof( array_intersect( $product_cats, $coupon->exclude_product_categories ) ) > 0 )
$this_item_is_discounted = false;
+ // Sale Items excluded from discount
+ if ( $coupon->exclude_sale_items == 'yes' )
+ if ( in_array( $values['product_id'], $product_ids_on_sale, true ) || in_array( $values['variation_id'], $product_ids_on_sale, true ) || in_array( $values['data']->get_parent(), $product_ids_on_sale, true ) )
+ $this_item_is_discounted = false;
+
// Apply filter
- $this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = true );
+ $this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = true, $coupon );
// Apply the discount
if ( $this_item_is_discounted ) {
@@ -953,16 +1022,16 @@ class WC_Cart {
if ( $add_totals ) {
$this->discount_cart = $this->discount_cart + ( $discount_amount * $values['quantity'] );
- $this->coupon_discount_amounts[ $code ] = ( $discount_amount * $values['quantity'] );
+ $this->increase_coupon_discount_amount( $code, $discount_amount * $values['quantity'] );
}
} elseif ( $coupon->type == 'percent_product' ) {
- $percent_discount = ( $values['data']->get_price_excluding_tax() / 100 ) * $coupon->amount;
+ $percent_discount = ( $values['data']->get_price() / 100 ) * $coupon->amount;
if ( $add_totals ) {
$this->discount_cart = $this->discount_cart + ( $percent_discount * $values['quantity'] );
- $this->coupon_discount_amounts[ $code ] = ( $percent_discount * $values['quantity'] );
+ $this->increase_coupon_discount_amount( $code, $percent_discount * $values['quantity'] );
}
$price = $price - $percent_discount;
@@ -982,7 +1051,7 @@ class WC_Cart {
// Get item discount by dividing item cost by subtotal to get a %
if ( $this->subtotal_ex_tax )
- $discount_percent = ( $values['data']->get_price_excluding_tax()*$values['quantity'] ) / $this->subtotal_ex_tax;
+ $discount_percent = ( $values['data']->get_price_excluding_tax() * $values['quantity'] ) / $this->subtotal_ex_tax;
else
$discount_percent = 0;
@@ -996,7 +1065,7 @@ class WC_Cart {
$item_discount = $item_discount / $values['quantity'];
// Pence
- $price = ( $price * 100 );
+ $price = $price * 100;
// Check if discount is more than price
if ( $price < $item_discount )
@@ -1011,12 +1080,13 @@ class WC_Cart {
$price = $price / 100;
// Cannot be below 0
- if ( $price < 0 ) $price = 0;
+ if ( $price < 0 )
+ $price = 0;
// Add coupon to discount total (once, since this is a fixed cart discount and we don't want rounding issues)
if ( $add_totals ) {
$this->discount_cart = $this->discount_cart + ( ( $discount_amount * $values['quantity'] ) / 100 );
- $this->coupon_discount_amounts[ $code ] = ( ( $discount_amount * $values['quantity'] ) / 100 );
+ $this->increase_coupon_discount_amount( $code, ( $discount_amount * $values['quantity'] ) / 100 );
}
break;
@@ -1027,7 +1097,7 @@ class WC_Cart {
if ( $add_totals ) {
$this->discount_cart = $this->discount_cart + ( $percent_discount * $values['quantity'] );
- $this->coupon_discount_amounts[ $code ] = ( $percent_discount * $values['quantity'] );
+ $this->increase_coupon_discount_amount( $code, $percent_discount * $values['quantity'] );
}
$price = $price - $percent_discount;
@@ -1049,7 +1119,7 @@ class WC_Cart {
* @param mixed $values
* @param mixed $price
*/
- function apply_product_discounts_after_tax( $values, $price ) {
+ public function apply_product_discounts_after_tax( $values, $price ) {
if ( ! empty( $this->applied_coupons) ) {
foreach ( $this->applied_coupons as $code ) {
@@ -1057,11 +1127,14 @@ class WC_Cart {
do_action( 'woocommerce_product_discount_after_tax_' . $coupon->type, $coupon, $values, $price );
+ if ( ! $coupon->is_valid() ) continue;
+
if ( $coupon->type != 'fixed_product' && $coupon->type != 'percent_product' ) continue;
- if ( !$coupon->apply_before_tax() && $coupon->is_valid() ) {
+ if ( ! $coupon->apply_before_tax() ) {
$product_cats = wp_get_post_terms( $values['product_id'], 'product_cat', array("fields" => "ids") );
+ $product_ids_on_sale = woocommerce_get_product_ids_on_sale();
$this_item_is_discounted = false;
@@ -1094,8 +1167,13 @@ class WC_Cart {
if ( sizeof( array_intersect( $product_cats, $coupon->exclude_product_categories ) ) > 0 )
$this_item_is_discounted = false;
+ // Sale Items excluded from discount
+ if ( $coupon->exclude_sale_items == 'yes' )
+ if ( in_array( $values['product_id'], $product_ids_on_sale, true ) || in_array( $values['variation_id'], $product_ids_on_sale, true ) || in_array( $values['data']->get_parent(), $product_ids_on_sale, true ) )
+ $this_item_is_discounted = false;
+
// Apply filter
- $this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = false );
+ $this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = false, $coupon );
// Apply the discount
if ( $this_item_is_discounted ) {
@@ -1107,12 +1185,11 @@ class WC_Cart {
$discount_amount = $coupon->amount;
$this->discount_total = $this->discount_total + ( $discount_amount * $values['quantity'] );
-
- $this->coupon_discount_amounts[ $code ] = ( $discount_amount * $values['quantity'] );
+ $this->increase_coupon_discount_amount( $code, $discount_amount * $values['quantity'] );
} elseif ( $coupon->type == 'percent_product' ) {
$this->discount_total = $this->discount_total + round( ( $price / 100 ) * $coupon->amount, $this->dp );
- $this->coupon_discount_amounts[ $code ] = round( ( $price / 100 ) * $coupon->amount, $this->dp );
+ $this->increase_coupon_discount_amount( $code, round( ( $price / 100 ) * $coupon->amount, $this->dp ) );
}
}
}
@@ -1126,7 +1203,9 @@ class WC_Cart {
*
* @access public
*/
- function apply_cart_discounts_after_tax() {
+ public function apply_cart_discounts_after_tax() {
+
+ $pre_discount_total = number_format( $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total + $this->fee_total, $this->dp, '.', '' );
if ( $this->applied_coupons ) {
foreach ( $this->applied_coupons as $code ) {
@@ -1134,25 +1213,35 @@ class WC_Cart {
do_action( 'woocommerce_cart_discount_after_tax_' . $coupon->type, $coupon );
- if ( !$coupon->apply_before_tax() && $coupon->is_valid() ) {
+ if ( ! $coupon->apply_before_tax() && $coupon->is_valid() ) {
switch ( $coupon->type ) {
case "fixed_cart" :
+ if ( $coupon->amount > $pre_discount_total )
+ $coupon->amount = $pre_discount_total;
+
+ $pre_discount_total = $pre_discount_total - $coupon->amount;
+
$this->discount_total = $this->discount_total + $coupon->amount;
- $this->coupon_discount_amounts[ $code ] = $coupon->amount;
+ $this->increase_coupon_discount_amount( $code, $coupon->amount );
break;
case "percent" :
- $percent_discount = ( round( $this->cart_contents_total + $this->tax_total, $this->dp ) / 100 ) * $coupon->amount;
+ $percent_discount = round( ( round( $this->cart_contents_total + $this->tax_total, $this->dp ) / 100 ) * $coupon->amount, $this->dp );
- $this->discount_total = $this->discount_total + round( $percent_discount, $this->dp );
+ if ( $coupon->amount > $percent_discount )
+ $coupon->amount = $percent_discount;
- $this->coupon_discount_amounts[ $code ] = round( $percent_discount, $this->dp );
+ $pre_discount_total = $pre_discount_total - $percent_discount;
+
+ $this->discount_total = $this->discount_total + $percent_discount;
+
+ $this->increase_coupon_discount_amount( $code, $percent_discount );
break;
@@ -1163,12 +1252,27 @@ class WC_Cart {
}
}
+ /**
+ * Store how much discount each coupon grants.
+ *
+ * @access private
+ * @param mixed $code
+ * @param mixed $amount
+ * @return void
+ */
+ private function increase_coupon_discount_amount( $code, $amount ) {
+ if ( empty( $this->coupon_discount_amounts[ $code ] ) )
+ $this->coupon_discount_amounts[ $code ] = 0;
+
+ $this->coupon_discount_amounts[ $code ] += $amount;
+ }
+
/**
* Calculate totals for the items in the cart.
*
* @access public
*/
- function calculate_totals() {
+ public function calculate_totals() {
global $woocommerce;
$this->reset();
@@ -1197,30 +1301,31 @@ class WC_Cart {
// ADJUST BASE if tax rate is different (different region or modified tax class)
if ( $tax_rates !== $base_tax_rates ) {
- $base_taxes = $this->tax->calc_tax( $row_base_price, $base_tax_rates, true, true );
- $modded_taxes = $this->tax->calc_tax( $row_base_price - array_sum( $base_taxes ), $tax_rates, false );
- $row_base_price = ( $row_base_price - array_sum( $base_taxes ) ) + array_sum( $modded_taxes );
+ $base_taxes = $this->tax->calc_tax( $row_base_price, $base_tax_rates, true, true );
+ $modded_taxes = $this->tax->calc_tax( $row_base_price - array_sum( $base_taxes ), $tax_rates, false );
+ $row_base_price = ( $row_base_price - array_sum( $base_taxes ) ) + array_sum( $modded_taxes );
}
- $taxes = $this->tax->calc_tax( $row_base_price, $tax_rates, true );
- $tax_amount = $this->tax->get_tax_total( $taxes );
+ $taxes = $this->tax->calc_tax( $row_base_price, $tax_rates, true );
+ $tax_amount = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->get_tax_total( $taxes ) : array_sum( $taxes );
+
}
// Sub total is based on base prices (without discounts)
- $this->subtotal = $this->subtotal + $row_base_price;
- $this->subtotal_ex_tax = $this->subtotal_ex_tax + ( $row_base_price - $tax_amount);
+ $this->subtotal = $this->subtotal + $row_base_price;
+ $this->subtotal_ex_tax = $this->subtotal_ex_tax + ( $row_base_price - $tax_amount);
} else {
if ( $_product->is_taxable() ) {
- $tax_rates = $this->tax->get_rates( $_product->get_tax_class() );
- $taxes = $this->tax->calc_tax( $row_base_price, $tax_rates, false );
- $tax_amount = $this->tax->get_tax_total( $taxes );
+ $tax_rates = $this->tax->get_rates( $_product->get_tax_class() );
+ $taxes = $this->tax->calc_tax( $row_base_price, $tax_rates, false );
+ $tax_amount = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->get_tax_total( $taxes ) : array_sum( $taxes );
}
// Sub total is based on base prices (without discounts)
- $this->subtotal = $this->subtotal + $row_base_price + $tax_amount;
- $this->subtotal_ex_tax = $this->subtotal_ex_tax + $row_base_price;
+ $this->subtotal = $this->subtotal + $row_base_price + $tax_amount;
+ $this->subtotal_ex_tax = $this->subtotal_ex_tax + $row_base_price;
}
}
@@ -1252,7 +1357,7 @@ class WC_Cart {
*/
$_product = $values['data'];
- // Base Price (inlusive of tax for now)
+ // Base Price (inclusive of tax for now)
$base_price = $_product->get_price();
// Base Price Adjustment
@@ -1280,7 +1385,7 @@ class WC_Cart {
$tax_amount = array_sum( $taxes );
// Line subtotal + tax
- $line_subtotal_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? round( $tax_amount, $this->dp ) : $tax_amount;
+ $line_subtotal_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->round( $tax_amount ) : $tax_amount;
$line_subtotal = $row_base_price - $this->tax->get_tax_total( $base_taxes );
// Adjusted price
@@ -1301,8 +1406,8 @@ class WC_Cart {
$tax_amount = array_sum( $this->tax->calc_tax( $base_price * $values['quantity'], $tax_rates, true ) );
// Line subtotal + tax
- $line_subtotal_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? round( $tax_amount, $this->dp ) : $tax_amount;
- $line_subtotal = ( $base_price * $values['quantity'] ) - round( $line_subtotal_tax, $this->dp );
+ $line_subtotal_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->round( $tax_amount ) : $tax_amount;
+ $line_subtotal = ( $base_price * $values['quantity'] ) - $this->tax->round( $line_subtotal_tax );
// Calc prices and tax (discounted)
$discounted_price = $this->get_discounted_price( $values, $base_price, true );
@@ -1328,8 +1433,8 @@ class WC_Cart {
}
// Line prices
- $line_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? round( $discounted_tax_amount, $this->dp ) : $discounted_tax_amount;
- $line_total = round( ( $discounted_price * $values['quantity'] ) - round( $line_tax, $this->dp ), $this->dp );
+ $line_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->round( $discounted_tax_amount ) : $discounted_tax_amount;
+ $line_total = ( $discounted_price * $values['quantity'] ) - $this->tax->round( $line_tax );
// Add any product discounts (after tax)
$this->apply_product_discounts_after_tax( $values, $line_total + $discounted_tax_amount );
@@ -1414,7 +1519,7 @@ class WC_Cart {
if ( $fee->taxable ) {
// Get tax rates
- $tax_rates = $this->tax->get_rates();
+ $tax_rates = $this->tax->get_rates( $fee->tax_class );
$fee_taxes = $this->tax->calc_tax( $fee->amount, $tax_rates, false );
// Store
@@ -1442,34 +1547,38 @@ class WC_Cart {
// Cart Discounts (after tax)
$this->apply_cart_discounts_after_tax();
- // Only go beyond this point if on the cart/checkout
- if ( ! is_checkout() && ! is_cart() && ! defined('WOOCOMMERCE_CHECKOUT') && ! defined('WOOCOMMERCE_CART') ) return;
+ // Only calculate the grand total + shipping if on the cart/checkout
+ if ( is_checkout() || is_cart() || defined('WOOCOMMERCE_CHECKOUT') || defined('WOOCOMMERCE_CART') ) {
- // Cart Shipping
- $this->calculate_shipping();
+ // Cart Shipping
+ $this->calculate_shipping();
+
+ // VAT exemption for shipping
+ if ( $woocommerce->customer->is_vat_exempt() ) {
+ $this->shipping_tax_total = 0;
+ $this->shipping_taxes = array();
+ }
+
+ // Round cart/shipping tax rows
+ $this->taxes = array_map( array( $this->tax, 'round' ), $this->taxes );
+ $this->shipping_taxes = array_map( array( $this->tax, 'round' ), $this->shipping_taxes );
+
+ // Allow plugins to hook and alter totals before final total is calculated
+ do_action( 'woocommerce_calculate_totals', $this );
+
+ /**
+ * Grand Total
+ *
+ * Based on discounted product prices, discounted tax, shipping cost + tax, and any discounts to be added after tax (e.g. store credit)
+ */
+ $this->total = apply_filters( 'woocommerce_calculated_total', number_format( $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total - $this->discount_total + $this->fee_total, $this->dp, '.', '' ), $this );
+
+ if ( $this->total < 0 )
+ $this->total = 0;
- // VAT exemption for shipping
- if ( $woocommerce->customer->is_vat_exempt() ) {
- $this->shipping_tax_total = 0;
- $this->shipping_taxes = array();
}
- // Round cart/shipping tax rows
- $this->taxes = array_map( array( &$this->tax, 'round' ), $this->taxes );
- $this->shipping_taxes = array_map( array( &$this->tax, 'round' ), $this->shipping_taxes );
-
- // Allow plugins to hook and alter totals before final total is calculated
- do_action( 'woocommerce_calculate_totals', $this );
-
- /**
- * Grand Total
- *
- * Based on discounted product prices, discounted tax, shipping cost + tax, and any discounts to be added after tax (e.g. store credit)
- */
- $this->total = apply_filters( 'woocommerce_calculated_total', number_format( $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total - $this->discount_total + $this->fee_total, $this->dp, '.', '' ), $this );
-
- if ( $this->total < 0 )
- $this->total = 0;
+ $this->set_session();
}
/**
@@ -1477,7 +1586,7 @@ class WC_Cart {
*
* @return bool
*/
- function needs_payment() {
+ public function needs_payment() {
$needs_payment = ( $this->total > 0 ) ? true : false;
return apply_filters( 'woocommerce_cart_needs_payment', $needs_payment, $this );
}
@@ -1492,7 +1601,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function calculate_shipping() {
+ public function calculate_shipping() {
global $woocommerce;
if ( $this->needs_shipping() && $this->show_shipping() ) {
@@ -1513,7 +1622,7 @@ class WC_Cart {
*
* This lets us calculate costs for carts that are shipped to multiple locations.
*
- * Shipping methods are responsble for looping through these packages.
+ * Shipping methods are responsible for looping through these packages.
*
* By default we pass the cart itself as a package - plugins can change this
* through the filter and break it up.
@@ -1522,19 +1631,21 @@ class WC_Cart {
* @access public
* @return array of cart items
*/
- function get_shipping_packages() {
+ public function get_shipping_packages() {
global $woocommerce;
// Packages array for storing 'carts'
$packages = array();
- $packages[0]['contents'] = $this->get_cart(); // Items in the package
- $packages[0]['contents_cost'] = 0; // Cost of items in the package, set below
- $packages[0]['applied_coupons'] = $this->applied_coupons; // Applied coupons - some, like free shipping, affect costs
- $packages[0]['destination']['country'] = $woocommerce->customer->get_shipping_country();
- $packages[0]['destination']['state'] = $woocommerce->customer->get_shipping_state();
- $packages[0]['destination']['postcode'] = $woocommerce->customer->get_shipping_postcode();
- $packages[0]['destination']['city'] = $woocommerce->customer->get_shipping_city();
+ $packages[0]['contents'] = $this->get_cart(); // Items in the package
+ $packages[0]['contents_cost'] = 0; // Cost of items in the package, set below
+ $packages[0]['applied_coupons'] = $this->applied_coupons; // Applied coupons - some, like free shipping, affect costs
+ $packages[0]['destination']['country'] = $woocommerce->customer->get_shipping_country();
+ $packages[0]['destination']['state'] = $woocommerce->customer->get_shipping_state();
+ $packages[0]['destination']['postcode'] = $woocommerce->customer->get_shipping_postcode();
+ $packages[0]['destination']['city'] = $woocommerce->customer->get_shipping_city();
+ $packages[0]['destination']['address'] = $woocommerce->customer->get_shipping_address();
+ $packages[0]['destination']['address_2'] = $woocommerce->customer->get_shipping_address_2();
foreach ( $this->get_cart() as $item )
if ( $item['data']->needs_shipping() )
@@ -1548,7 +1659,7 @@ class WC_Cart {
*
* @return bool whether or not the cart needs shipping
*/
- function needs_shipping() {
+ public function needs_shipping() {
if ( get_option('woocommerce_calc_shipping')=='no' ) return false;
if ( ! is_array( $this->cart_contents ) ) return false;
@@ -1561,7 +1672,7 @@ class WC_Cart {
}
}
- return apply_filters( 'woocomerce_cart_needs_shipping', $needs_shipping );
+ return apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping );
}
/**
@@ -1569,7 +1680,7 @@ class WC_Cart {
*
* @return bool
*/
- function show_shipping() {
+ public function show_shipping() {
global $woocommerce;
if ( get_option('woocommerce_calc_shipping')=='no' ) return false;
@@ -1583,7 +1694,7 @@ class WC_Cart {
$show_shipping = true;
- return apply_filters( 'woocomerce_cart_ready_to_calc_shipping', $show_shipping );
+ return apply_filters( 'woocommerce_cart_ready_to_calc_shipping', $show_shipping );
}
@@ -1592,7 +1703,7 @@ class WC_Cart {
*
* @return bool
*/
- function ship_to_billing_address_only() {
+ public function ship_to_billing_address_only() {
if ( get_option('woocommerce_ship_to_billing_address_only') == 'yes' ) return true; else return false;
}
@@ -1601,7 +1712,7 @@ class WC_Cart {
*
* @return mixed price or string for the shipping total
*/
- function get_cart_shipping_total() {
+ public function get_cart_shipping_total() {
global $woocommerce;
if ( isset( $this->shipping_label ) ) {
@@ -1641,7 +1752,7 @@ class WC_Cart {
*
* @return string shipping method title
*/
- function get_cart_shipping_title() {
+ public function get_cart_shipping_title() {
if ( isset( $this->shipping_label ) ) {
return __( 'via', 'woocommerce' ) . ' ' . $this->shipping_label;
}
@@ -1657,7 +1768,7 @@ class WC_Cart {
*
* @return bool
*/
- function has_discount( $code ) {
+ public function has_discount( $code ) {
if ( in_array( $code, $this->applied_coupons ) ) return true;
return false;
}
@@ -1668,38 +1779,46 @@ class WC_Cart {
* @param string $coupon_code - The code to apply
* @return bool True if the coupon is applied, false if it does not exist or cannot be applied
*/
- function add_discount( $coupon_code ) {
+ public function add_discount( $coupon_code ) {
global $woocommerce;
// Coupons are globally disabled
- if ( get_option('woocommerce_enable_coupons') == 'no' ) return false;
+ if ( ! $woocommerce->cart->coupons_enabled() )
+ return false;
$the_coupon = new WC_Coupon( $coupon_code );
if ( $the_coupon->id ) {
// Check it can be used with cart
- $return = $the_coupon->is_valid();
- if ( ! $return || is_wp_error( $return ) ) {
- $woocommerce->add_error( is_wp_error( $return ) ? $return->get_error_message() : __( 'Invalid coupon.', 'woocommerce' ) );
+ if ( ! $the_coupon->is_valid() ) {
+ $woocommerce->add_error( $the_coupon->get_error_message() );
return false;
}
// Check if applied
if ( $woocommerce->cart->has_discount( $coupon_code ) ) {
- $woocommerce->add_error( __( 'Discount code already applied!', 'woocommerce' ) );
+ $the_coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_ALREADY_APPLIED );
return false;
}
// If its individual use then remove other coupons
if ( $the_coupon->individual_use == 'yes' ) {
- $this->applied_coupons = array();
+ $this->applied_coupons = apply_filters( 'woocommerce_apply_individual_use_coupon', array(), $the_coupon, $this->applied_coupons );
}
- foreach ( $this->applied_coupons as $code ) {
- $coupon = new WC_Coupon($code);
- if ( $coupon->individual_use == 'yes' ) {
- $this->applied_coupons = array();
+ if ( $this->applied_coupons ) {
+ foreach ( $this->applied_coupons as $code ) {
+
+ $existing_coupon = new WC_Coupon( $code );
+
+ if ( $existing_coupon->individual_use == 'yes' && false === apply_filters( 'woocommerce_apply_with_individual_use_coupon', false, $the_coupon, $existing_coupon, $this->applied_coupons ) ) {
+
+ // Reject new coupon
+ $existing_coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY );
+
+ return false;
+ }
}
}
@@ -1710,16 +1829,16 @@ class WC_Cart {
$woocommerce->session->chosen_shipping_method = 'free_shipping';
}
- $this->set_session();
+ $this->calculate_totals();
- $woocommerce->add_message( __( 'Discount code applied successfully.', 'woocommerce' ) );
+ $the_coupon->add_coupon_message( WC_Coupon::WC_COUPON_SUCCESS );
do_action( 'woocommerce_applied_coupon', $coupon_code );
return true;
} else {
- $woocommerce->add_error( __( 'Coupon does not exist!', 'woocommerce' ) );
+ $the_coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_EXIST );
return false;
}
return false;
@@ -1730,7 +1849,7 @@ class WC_Cart {
*
* @return array of applied coupons
*/
- function get_applied_coupons() {
+ public function get_applied_coupons() {
return (array) $this->applied_coupons;
}
@@ -1739,14 +1858,14 @@ class WC_Cart {
*
* @params int type - 0 for all, 1 for before tax, 2 for after tax
*/
- function remove_coupons( $type = 0 ) {
+ public function remove_coupons( $type = 0 ) {
global $woocommerce;
if ( 1 == $type ) {
if ( $this->applied_coupons ) {
foreach ( $this->applied_coupons as $index => $code ) {
$coupon = new WC_Coupon( $code );
- if ( $coupon->apply_before_tax() ) unset( $this->applied_coupons[ $index ] );
+ if ( $coupon->is_valid() && $coupon->apply_before_tax() ) unset( $this->applied_coupons[ $index ] );
}
}
@@ -1755,7 +1874,7 @@ class WC_Cart {
if ( $this->applied_coupons ) {
foreach ( $this->applied_coupons as $index => $code ) {
$coupon = new WC_Coupon( $code );
- if ( ! $coupon->apply_before_tax() ) unset( $this->applied_coupons[ $index ] );
+ if ( $coupon->is_valid() && ! $coupon->apply_before_tax() ) unset( $this->applied_coupons[ $index ] );
}
}
@@ -1780,7 +1899,7 @@ class WC_Cart {
* @param string $tax_class (default: '')
* @return void
*/
- function add_fee( $name, $amount, $taxable = false, $tax_class = '' ) {
+ public function add_fee( $name, $amount, $taxable = false, $tax_class = '' ) {
if ( empty( $this->fees ) )
$this->fees = array();
@@ -1802,7 +1921,7 @@ class WC_Cart {
* @access public
* @return void
*/
- function get_fees() {
+ public function get_fees() {
return (array) $this->fees;
}
@@ -1815,7 +1934,7 @@ class WC_Cart {
*
* @return float
*/
- function get_order_discount_total() {
+ public function get_order_discount_total() {
return $this->discount_total;
}
@@ -1824,7 +1943,7 @@ class WC_Cart {
*
* @return float
*/
- function get_cart_discount_total() {
+ public function get_cart_discount_total() {
return $this->discount_cart;
}
@@ -1833,7 +1952,7 @@ class WC_Cart {
*
* @return string formatted price
*/
- function get_total() {
+ public function get_total() {
return apply_filters( 'woocommerce_cart_total', woocommerce_price( $this->total ) );
}
@@ -1842,7 +1961,7 @@ class WC_Cart {
*
* @return string formatted price
*/
- function get_total_ex_tax() {
+ public function get_total_ex_tax() {
$total = $this->total - $this->tax_total - $this->shipping_tax_total;
if ( $total < 0 ) $total = 0;
return apply_filters( 'woocommerce_cart_total_ex_tax', woocommerce_price( $total ) );
@@ -1853,7 +1972,7 @@ class WC_Cart {
*
* @return string formatted price
*/
- function get_cart_total() {
+ public function get_cart_total() {
if ( ! $this->prices_include_tax ) {
$cart_contents_total = woocommerce_price( $this->cart_contents_total );
} else {
@@ -1869,7 +1988,7 @@ class WC_Cart {
* @params bool whether to include compound taxes
* @return string formatted price
*/
- function get_cart_subtotal( $compound = false ) {
+ public function get_cart_subtotal( $compound = false ) {
global $woocommerce;
// If the cart has compound tax, we want to show the subtotal as
@@ -1915,7 +2034,7 @@ class WC_Cart {
* @params int quantity
* @return string formatted price
*/
- function get_product_subtotal( $_product, $quantity ) {
+ public function get_product_subtotal( $_product, $quantity ) {
global $woocommerce;
$price = $_product->get_price();
@@ -1931,7 +2050,7 @@ class WC_Cart {
$row_price = $_product->get_price_excluding_tax( $quantity );
$product_subtotal = woocommerce_price( $row_price );
- if ( $this->prices_include_tax )
+ if ( $this->prices_include_tax && $this->tax_total > 0 )
$product_subtotal .= '
' . $woocommerce->countries->ex_tax_or_vat() . ' ';
} else {
@@ -1939,7 +2058,7 @@ class WC_Cart {
$row_price = $_product->get_price_including_tax( $quantity );
$product_subtotal = woocommerce_price( $row_price );
- if ( ! $this->prices_include_tax )
+ if ( ! $this->prices_include_tax && $this->tax_total > 0 )
$product_subtotal .= '
' . $woocommerce->countries->inc_tax_or_vat() . ' ';
}
@@ -1960,7 +2079,7 @@ class WC_Cart {
*
* @return string formatted price
*/
- function get_cart_tax() {
+ public function get_cart_tax() {
$return = false;
$cart_total_tax = $this->tax_total + $this->shipping_tax_total;
if ( $cart_total_tax > 0 ) $return = woocommerce_price( $cart_total_tax );
@@ -1972,7 +2091,7 @@ class WC_Cart {
*
* @return float price
*/
- function get_taxes_total( $compound = true ) {
+ public function get_taxes_total( $compound = true ) {
$total = 0;
foreach ( $this->taxes as $key => $tax ) {
if ( ! $compound && $this->tax->is_compound( $key ) ) continue;
@@ -1990,7 +2109,7 @@ class WC_Cart {
*
* @return mixed formatted price or false if there are none
*/
- function get_discounts_before_tax() {
+ public function get_discounts_before_tax() {
if ( $this->discount_cart ) {
$discounts_before_tax = woocommerce_price( $this->discount_cart );
} else {
@@ -2004,7 +2123,7 @@ class WC_Cart {
*
* @return mixed formatted price or false if there are none
*/
- function get_discounts_after_tax() {
+ public function get_discounts_after_tax() {
if ( $this->discount_total ) {
$discounts_after_tax = woocommerce_price( $this->discount_total );
} else {
@@ -2018,7 +2137,7 @@ class WC_Cart {
*
* @return mixed formatted price or false if there are none
*/
- function get_total_discount() {
+ public function get_total_discount() {
if ( $this->discount_total || $this->discount_cart ) {
$total_discount = woocommerce_price( $this->discount_total + $this->discount_cart );
} else {
diff --git a/classes/class-wc-checkout.php b/classes/class-wc-checkout.php
index 5b09946c574..6898a1f4ceb 100644
--- a/classes/class-wc-checkout.php
+++ b/classes/class-wc-checkout.php
@@ -7,37 +7,47 @@
* @class WC_Cart
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Checkout {
/** @var array Array of posted form data. */
- var $posted;
+ public $posted;
/** @var array Array of fields to display on the checkout. */
- var $checkout_fields;
+ public $checkout_fields;
/** @var bool Whether or not the user must create an account to checkout. */
- var $must_create_account;
+ public $must_create_account;
/** @var bool Whether or not signups are allowed. */
- var $enable_signup;
+ public $enable_signup;
/** @var bool True when the user is creating an account. */
- var $creating_account;
+ public $creating_account;
+
+ /** @var object The shipping method being used. */
+ private $shipping_method;
+
+ /** @var array The payment gateway being used. */
+ private $payment_method;
+
+ /** @var int ID of customer. */
+ private $customer_id;
/**
- * Constructor for the checkout class. Hooks in methods and defines eheckout fields.
+ * Constructor for the checkout class. Hooks in methods and defines checkout fields.
*
* @access public
* @return void
*/
- function __construct () {
+ public function __construct () {
global $woocommerce;
- add_action( 'woocommerce_checkout_process', array( &$this,'checkout_process' ) );
- add_action( 'woocommerce_checkout_billing', array( &$this,'checkout_form_billing' ) );
- add_action( 'woocommerce_checkout_shipping', array( &$this,'checkout_form_shipping' ) );
+ add_action( 'woocommerce_checkout_process', array( $this,'checkout_process' ) );
+ add_action( 'woocommerce_checkout_billing', array( $this,'checkout_form_billing' ) );
+ add_action( 'woocommerce_checkout_shipping', array( $this,'checkout_form_shipping' ) );
$this->enable_signup = get_option( 'woocommerce_enable_signup_and_login_from_checkout' ) == 'yes' ? true : false;
$this->enable_guest_checkout = get_option( 'woocommerce_enable_guest_checkout' ) == 'yes' ? true : false;
@@ -93,7 +103,7 @@ class WC_Checkout {
* @access public
* @return void
*/
- function checkout_process() {
+ public function checkout_process() {
// When we process the checkout, lets ensure cart items are rechecked to prevent checkout
do_action('woocommerce_check_cart_items');
}
@@ -105,7 +115,7 @@ class WC_Checkout {
* @access public
* @return void
*/
- function checkout_form_billing() {
+ public function checkout_form_billing() {
woocommerce_get_template( 'checkout/form-billing.php', array( 'checkout' => $this ) );
}
@@ -116,24 +126,261 @@ class WC_Checkout {
* @access public
* @return void
*/
- function checkout_form_shipping() {
+ public function checkout_form_shipping() {
woocommerce_get_template( 'checkout/form-shipping.php', array( 'checkout' => $this ) );
}
+ /**
+ * create_order function.
+ *
+ * @access public
+ * @return void
+ */
+ public function create_order() {
+ global $woocommerce, $wpdb;
+
+ // Give plugins the opportunity to create an order themselves
+ $order_id = apply_filters( 'woocommerce_create_order', null, $this );
+
+ if ( is_numeric( $order_id ) )
+ return $order_id;
+
+ // Create Order (send cart variable so we can record items and reduce inventory). Only create if this is a new order, not if the payment was rejected.
+ $order_data = apply_filters( 'woocommerce_new_order_data', array(
+ 'post_type' => 'shop_order',
+ 'post_title' => sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ),
+ 'post_status' => 'publish',
+ 'ping_status' => 'closed',
+ 'post_excerpt' => isset( $this->posted['order_comments'] ) ? $this->posted['order_comments'] : '',
+ 'post_author' => 1,
+ 'post_password' => uniqid( 'order_' ) // Protects the post just in case
+ ) );
+
+ // Insert or update the post data
+ $create_new_order = true;
+
+ if ( $woocommerce->session->order_awaiting_payment > 0 ) {
+
+ $order_id = absint( $woocommerce->session->order_awaiting_payment );
+
+ /* Check order is unpaid by getting its status */
+ $terms = wp_get_object_terms( $order_id, 'shop_order_status', array( 'fields' => 'slugs' ) );
+ $order_status = isset( $terms[0] ) ? $terms[0] : 'pending';
+
+ // Resume the unpaid order if its pending
+ if ( $order_status == 'pending' || $order_status == 'failed' ) {
+
+ // Update the existing order as we are resuming it
+ $create_new_order = false;
+ $order_data['ID'] = $order_id;
+ wp_update_post( $order_data );
+
+ // Clear the old line items - we'll add these again in case they changed
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d )", $order_id ) );
+
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $order_id ) );
+
+ // Trigger an action for the resumed order
+ do_action( 'woocommerce_resume_order', $order_id );
+ }
+ }
+
+ if ( $create_new_order ) {
+ $order_id = wp_insert_post( $order_data );
+
+ if ( is_wp_error( $order_id ) )
+ throw new MyException( 'Error: Unable to create order. Please try again.' );
+ else
+ do_action( 'woocommerce_new_order', $order_id );
+ }
+
+ // Store user data
+ if ( $this->checkout_fields['billing'] ) {
+ foreach ( $this->checkout_fields['billing'] as $key => $field ) {
+
+ update_post_meta( $order_id, '_' . $key, $this->posted[ $key ] );
+
+ // User
+ if ( $this->customer_id && ! empty( $this->posted[ $key ] ) ) {
+ update_user_meta( $this->customer_id, $key, $this->posted[ $key ] );
+
+ // Special fields
+ switch ( $key ) {
+ case "billing_email" :
+ if ( ! email_exists( $this->posted[ $key ] ) )
+ wp_update_user( array ( 'ID' => $this->customer_id, 'user_email' => $this->posted[ $key ] ) ) ;
+ break;
+ case "billing_first_name" :
+ wp_update_user( array ( 'ID' => $this->customer_id, 'first_name' => $this->posted[ $key ] ) ) ;
+ break;
+ case "billing_last_name" :
+ wp_update_user( array ( 'ID' => $this->customer_id, 'last_name' => $this->posted[ $key ] ) ) ;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( $this->checkout_fields['shipping'] && ( $woocommerce->cart->needs_shipping() || get_option('woocommerce_require_shipping_address') == 'yes' ) ) {
+ foreach ( $this->checkout_fields['shipping'] as $key => $field ) {
+ $postvalue = false;
+
+ if ( $this->posted['shiptobilling'] ) {
+ if ( isset( $this->posted[ str_replace( 'shipping_', 'billing_', $key ) ] ) ) {
+ $postvalue = $this->posted[ str_replace( 'shipping_', 'billing_', $key ) ];
+ update_post_meta( $order_id, '_' . $key, $postvalue );
+ }
+ } else {
+ $postvalue = $this->posted[ $key ];
+ update_post_meta( $order_id, '_' . $key, $postvalue );
+ }
+
+ // User
+ if ( $postvalue && $this->customer_id )
+ update_user_meta( $this->customer_id, $key, $postvalue );
+ }
+ }
+
+ // Save any other user meta
+ if ( $this->customer_id )
+ do_action( 'woocommerce_checkout_update_user_meta', $this->customer_id, $this->posted );
+
+ // Store the line items to the new/resumed order
+ foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
+
+ $_product = $values['data'];
+
+ // Add line item
+ $item_id = woocommerce_add_order_item( $order_id, array(
+ 'order_item_name' => $_product->get_title(),
+ 'order_item_type' => 'line_item'
+ ) );
+
+ // Add line item meta
+ if ( $item_id ) {
+ woocommerce_add_order_item_meta( $item_id, '_qty', apply_filters( 'woocommerce_stock_amount', $values['quantity'] ) );
+ woocommerce_add_order_item_meta( $item_id, '_tax_class', $_product->get_tax_class() );
+ woocommerce_add_order_item_meta( $item_id, '_product_id', $values['product_id'] );
+ woocommerce_add_order_item_meta( $item_id, '_variation_id', $values['variation_id'] );
+ woocommerce_add_order_item_meta( $item_id, '_line_subtotal', woocommerce_format_decimal( $values['line_subtotal'], 4 ) );
+ woocommerce_add_order_item_meta( $item_id, '_line_total', woocommerce_format_decimal( $values['line_total'], 4 ) );
+ woocommerce_add_order_item_meta( $item_id, '_line_tax', woocommerce_format_decimal( $values['line_tax'], 4 ) );
+ woocommerce_add_order_item_meta( $item_id, '_line_subtotal_tax', woocommerce_format_decimal( $values['line_subtotal_tax'], 4 ) );
+
+ // Store variation data in meta so admin can view it
+ if ( $values['variation'] && is_array( $values['variation'] ) )
+ foreach ( $values['variation'] as $key => $value )
+ woocommerce_add_order_item_meta( $item_id, esc_attr( str_replace( 'attribute_', '', $key ) ), $value );
+
+ // Add line item meta for backorder status
+ if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $values['quantity'] ) )
+ woocommerce_add_order_item_meta( $item_id, apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ), $cart_item_key, $order_id ), $values['quantity'] - max( 0, $_product->get_total_stock() ) );
+
+ //allow plugins to add order item meta
+ do_action( 'woocommerce_add_order_item_meta', $item_id, $values );
+ }
+ }
+
+ // Store fees
+ foreach ( $woocommerce->cart->get_fees() as $fee ) {
+ $item_id = woocommerce_add_order_item( $order_id, array(
+ 'order_item_name' => $fee->name,
+ 'order_item_type' => 'fee'
+ ) );
+
+ if ( $fee->taxable )
+ woocommerce_add_order_item_meta( $item_id, '_tax_class', $fee->tax_class );
+ else
+ woocommerce_add_order_item_meta( $item_id, '_tax_class', '0' );
+
+ woocommerce_add_order_item_meta( $item_id, '_line_total', woocommerce_format_decimal( $fee->amount ) );
+ woocommerce_add_order_item_meta( $item_id, '_line_tax', woocommerce_format_decimal( $fee->tax ) );
+ }
+
+ // Store tax rows
+ foreach ( array_keys( $woocommerce->cart->taxes + $woocommerce->cart->shipping_taxes ) as $key ) {
+
+ $item_id = woocommerce_add_order_item( $order_id, array(
+ 'order_item_name' => $woocommerce->cart->tax->get_rate_code( $key ),
+ 'order_item_type' => 'tax'
+ ) );
+
+ // Add line item meta
+ if ( $item_id ) {
+ woocommerce_add_order_item_meta( $item_id, 'rate_id', $key );
+ woocommerce_add_order_item_meta( $item_id, 'label', $woocommerce->cart->tax->get_rate_label( $key ) );
+ woocommerce_add_order_item_meta( $item_id, 'compound', absint( $woocommerce->cart->tax->is_compound( $key ) ? 1 : 0 ) );
+ woocommerce_add_order_item_meta( $item_id, 'tax_amount', woocommerce_clean( isset( $woocommerce->cart->taxes[ $key ] ) ? $woocommerce->cart->taxes[ $key ] : 0 ) );
+ woocommerce_add_order_item_meta( $item_id, 'shipping_tax_amount', woocommerce_clean( isset( $woocommerce->cart->shipping_taxes[ $key ] ) ? $woocommerce->cart->shipping_taxes[ $key ] : 0 ) );
+ }
+ }
+
+ // Store coupons
+ if ( $applied_coupons = $woocommerce->cart->get_applied_coupons() ) {
+ foreach ( $applied_coupons as $code ) {
+
+ $item_id = woocommerce_add_order_item( $order_id, array(
+ 'order_item_name' => $code,
+ 'order_item_type' => 'coupon'
+ ) );
+
+ // Add line item meta
+ if ( $item_id ) {
+ woocommerce_add_order_item_meta( $item_id, 'discount_amount', isset( $woocommerce->cart->coupon_discount_amounts[ $code ] ) ? $woocommerce->cart->coupon_discount_amounts[ $code ] : 0 );
+ }
+ }
+ }
+
+ // Store meta
+ if ( $this->shipping_method ) {
+ update_post_meta( $order_id, '_shipping_method', $this->shipping_method->id );
+ update_post_meta( $order_id, '_shipping_method_title', $this->shipping_method->label );
+ }
+
+ if ( $this->payment_method ) {
+ update_post_meta( $order_id, '_payment_method', $this->payment_method->id );
+ update_post_meta( $order_id, '_payment_method_title', $this->payment_method->get_title() );
+ }
+
+ update_post_meta( $order_id, '_order_shipping', woocommerce_format_total( $woocommerce->cart->shipping_total ) );
+ update_post_meta( $order_id, '_order_discount', woocommerce_format_total( $woocommerce->cart->get_order_discount_total() ) );
+ update_post_meta( $order_id, '_cart_discount', woocommerce_format_total( $woocommerce->cart->get_cart_discount_total() ) );
+ update_post_meta( $order_id, '_order_tax', woocommerce_format_total( $woocommerce->cart->tax_total ) );
+ update_post_meta( $order_id, '_order_shipping_tax', woocommerce_format_total( $woocommerce->cart->shipping_tax_total ) );
+ update_post_meta( $order_id, '_order_total', woocommerce_format_total( $woocommerce->cart->total ) );
+ update_post_meta( $order_id, '_order_key', apply_filters('woocommerce_generate_order_key', uniqid('order_') ) );
+ update_post_meta( $order_id, '_customer_user', absint( $this->customer_id ) );
+ update_post_meta( $order_id, '_order_currency', get_woocommerce_currency() );
+ update_post_meta( $order_id, '_prices_include_tax', get_option( 'woocommerce_prices_include_tax' ) );
+ update_post_meta( $order_id, '_customer_ip_address', isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'] );
+ update_post_meta( $order_id, '_customer_user_agent', isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '' );
+
+ // Let plugins add meta
+ do_action( 'woocommerce_checkout_update_order_meta', $order_id, $this->posted );
+
+ // Order status
+ wp_set_object_terms( $order_id, 'pending', 'shop_order_status' );
+
+ return $order_id;
+ }
+
/**
* Process the checkout after the confirm order button is pressed
*
* @access public
* @return void
*/
- function process_checkout() {
- global $wpdb, $woocommerce;
+ public function process_checkout() {
+ global $wpdb, $woocommerce, $current_user;
+
+ $woocommerce->verify_nonce( 'process_checkout' );
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) )
define( 'WOOCOMMERCE_CHECKOUT', true );
- $woocommerce->verify_nonce( 'process_checkout' );
+ // Prevent timeout
+ @set_time_limit(0);
do_action( 'woocommerce_before_checkout_process' );
@@ -332,9 +579,12 @@ class WC_Checkout {
// Shipping Method
$available_methods = $woocommerce->shipping->get_available_shipping_methods();
- if ( ! isset( $available_methods[ $this->posted['shipping_method'] ] ) )
+ if ( ! isset( $available_methods[ $this->posted['shipping_method'] ] ) ) {
+ $this->shipping_method = '';
$woocommerce->add_error( __( 'Invalid shipping method.', 'woocommerce' ) );
-
+ } else {
+ $this->shipping_method = $available_methods[ $this->posted['shipping_method'] ];
+ }
}
if ( $woocommerce->cart->needs_payment() ) {
@@ -342,10 +592,13 @@ class WC_Checkout {
// Payment Method
$available_gateways = $woocommerce->payment_gateways->get_available_payment_gateways();
- if ( ! isset( $available_gateways[ $this->posted['payment_method'] ] ) )
+ if ( ! isset( $available_gateways[ $this->posted['payment_method'] ] ) ) {
+ $this->payment_method = '';
$woocommerce->add_error( __( 'Invalid payment method.', 'woocommerce' ) );
- else
- $available_gateways[ $this->posted['payment_method'] ]->validate_fields(); // Payment Method Field Validation
+ } else {
+ $this->payment_method = $available_gateways[ $this->posted['payment_method'] ];
+ $this->payment_method->validate_fields();
+ }
}
// Action after validation
@@ -353,41 +606,50 @@ class WC_Checkout {
if ( ! isset( $_POST['woocommerce_checkout_update_totals'] ) && $woocommerce->error_count() == 0 ) {
- $user_id = get_current_user_id();
+ $this->customer_id = get_current_user_id();
try {
// Create customer account and log them in
- if ( $this->creating_account && ! $user_id ) {
+ if ( $this->creating_account && ! $this->customer_id ) {
$reg_errors = new WP_Error();
- do_action('woocommerce_register_post', $this->posted['account_username'], $this->posted['billing_email'], $reg_errors);
+ do_action( 'woocommerce_register_post', $this->posted['account_username'], $this->posted['billing_email'], $reg_errors );
$errors = apply_filters( 'woocommerce_registration_errors', $reg_errors, $this->posted['account_username'], $this->posted['billing_email'] );
// if there are no errors, let's create the user account
if ( ! $reg_errors->get_error_code() ) {
- $user_pass = esc_attr( $this->posted['account_password'] );
- $user_id = wp_create_user( $this->posted['account_username'], $user_pass, $this->posted['billing_email'] );
+ $user_pass = esc_attr( $this->posted['account_password'] );
- if ( ! $user_id )
+ $new_customer_data = array(
+ 'user_login' => $this->posted['account_username'],
+ 'user_pass' => $user_pass,
+ 'user_email' => $this->posted['billing_email'],
+ 'role' => 'customer'
+ );
+
+ $this->customer_id = wp_insert_user( apply_filters( 'woocommerce_new_customer_data', $new_customer_data ) );
+
+ if ( is_wp_error( $this->customer_id ) ) {
throw new MyException( '
' . __( 'ERROR', 'woocommerce' ) . ' : ' . __( 'Couldn’t register you… please contact us if you continue to have problems.', 'woocommerce' ) );
+ }
- // Change role
- wp_update_user( array('ID' => $user_id, 'role' => 'customer') ) ;
+ // Set the global user object
+ $current_user = get_user_by ( 'id', $this->customer_id );
// Action
- do_action( 'woocommerce_created_customer', $user_id );
+ do_action( 'woocommerce_created_customer', $this->customer_id );
// send the user a confirmation and their login details
$mailer = $woocommerce->mailer();
- $mailer->customer_new_account( $user_id, $user_pass );
+ $mailer->customer_new_account( $this->customer_id, $user_pass );
// set the WP login cookie
$secure_cookie = is_ssl() ? true : false;
- wp_set_auth_cookie($user_id, true, $secure_cookie);
+ wp_set_auth_cookie( $this->customer_id, true, $secure_cookie );
} else {
throw new MyException( $reg_errors->get_error_message() );
@@ -395,244 +657,16 @@ class WC_Checkout {
}
- // Create Order (send cart variable so we can record items and reduce inventory). Only create if this is a new order, not if the payment was rejected last time.
- $order_data = apply_filters( 'woocommerce_new_order_data', array(
- 'post_type' => 'shop_order',
- 'post_title' => sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ),
- 'post_status' => 'publish',
- 'ping_status' => 'closed',
- 'post_excerpt' => isset( $this->posted['order_comments'] ) ? $this->posted['order_comments'] : '',
- 'post_author' => 1,
- 'post_password' => uniqid( 'order_' ) // Protects the post just in case
- ) );
-
+ // Abort if errors are present
if ( $woocommerce->error_count() > 0 )
throw new MyException();
- // Insert or update the post data
- $create_new_order = true;
-
- if ( $woocommerce->session->order_awaiting_payment > 0 ) {
-
- $order_id = (int) $woocommerce->session->order_awaiting_payment;
-
- /* Check order is unpaid by getting its status */
- $terms = wp_get_object_terms( $order_id, 'shop_order_status', array( 'fields' => 'slugs' ) );
- $order_status = isset( $terms[0] ) ? $terms[0] : 'pending';
-
- if ( $order_status == 'pending' ) {
-
- // Resume the unpaid order
- $order_data['ID'] = $order_id;
- wp_update_post( $order_data );
- do_action( 'woocommerce_resume_order', $order_id );
-
- $create_new_order = false;
- }
- }
-
- if ( $create_new_order ) {
- $order_id = wp_insert_post( $order_data );
-
- if ( is_wp_error( $order_id ) )
- throw new MyException( 'Error: Unable to create order. Please try again.' );
- else
- do_action( 'woocommerce_new_order', $order_id ); // Inserted successfully
- }
-
- // DELETE ANY ITEMS IN CURRENT ORDER
-
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d )", $order_id ) );
-
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $order_id ) );
-
- // SAVE LINE ITEMS
-
- foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
-
- $_product = $values['data'];
-
- // Add line item
- $item_id = woocommerce_add_order_item( $order_id, array(
- 'order_item_name' => $_product->get_title(),
- 'order_item_type' => 'line_item'
- ) );
-
- // Add line item meta
- if ( $item_id ) {
- woocommerce_add_order_item_meta( $item_id, '_qty', apply_filters( 'woocommerce_stock_amount', $values['quantity'] ) );
- woocommerce_add_order_item_meta( $item_id, '_tax_class', $_product->get_tax_class() );
- woocommerce_add_order_item_meta( $item_id, '_product_id', $values['product_id'] );
- woocommerce_add_order_item_meta( $item_id, '_variation_id', $values['variation_id'] );
- woocommerce_add_order_item_meta( $item_id, '_line_subtotal', woocommerce_format_decimal( $values['line_subtotal'] ) );
- woocommerce_add_order_item_meta( $item_id, '_line_subtotal_tax', woocommerce_format_decimal( $values['line_subtotal_tax'] ) );
- woocommerce_add_order_item_meta( $item_id, '_line_total', woocommerce_format_decimal( $values['line_total'] ) );
- woocommerce_add_order_item_meta( $item_id, '_line_tax', woocommerce_format_decimal( $values['line_tax'] ) );
-
- // Store variation data in meta so admin can view it
- if ( $values['variation'] && is_array( $values['variation'] ) )
- foreach ( $values['variation'] as $key => $value )
- woocommerce_add_order_item_meta( $item_id, esc_attr( str_replace( 'attribute_', '', $key ) ), $value );
-
- // Add line item meta for backorder status
- if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $values['quantity'] ) )
- woocommerce_add_order_item_meta( $item_id, __( 'Backordered', 'woocommerce' ), $values['quantity'] - max( 0, $_product->get_total_stock() ) );
-
- //allow plugins to add order item meta
- do_action( 'woocommerce_add_order_item_meta', $item_id, $values );
- }
- }
-
- // Store fees
- foreach ( $woocommerce->cart->get_fees() as $fee ) {
- $item_id = woocommerce_add_order_item( $order_id, array(
- 'order_item_name' => $fee->name,
- 'order_item_type' => 'fee'
- ) );
-
- if ( $fee->taxable )
- woocommerce_add_order_item_meta( $item_id, '_tax_class', $fee->tax_class );
- else
- woocommerce_add_order_item_meta( $item_id, '_tax_class', '0' );
-
- woocommerce_add_order_item_meta( $item_id, '_line_total', woocommerce_format_decimal( $fee->amount ) );
- woocommerce_add_order_item_meta( $item_id, '_line_tax', woocommerce_format_decimal( $fee->tax ) );
- }
-
- // UPDATE USER META
-
- // Save billing and shipping first, also save to user meta if logged in
- if ( $this->checkout_fields['billing'] ) {
- foreach ( $this->checkout_fields['billing'] as $key => $field ) {
-
- // Post
- update_post_meta( $order_id, '_' . $key, $this->posted[ $key ] );
-
- // User
- if ( $user_id > 0 && ! empty( $this->posted[ $key ] ) ) {
- update_user_meta( $user_id, $key, $this->posted[ $key ] );
-
- // Special fields
- switch ( $key ) {
- case "billing_email" :
- if ( ! email_exists( $this->posted[ $key ] ) )
- wp_update_user( array ( 'ID' => $user_id, 'user_email' => $this->posted[ $key ] ) ) ;
- break;
- case "billing_first_name" :
- wp_update_user( array ( 'ID' => $user_id, 'first_name' => $this->posted[ $key ] ) ) ;
- break;
- case "billing_last_name" :
- wp_update_user( array ( 'ID' => $user_id, 'last_name' => $this->posted[ $key ] ) ) ;
- break;
- }
- }
- }
- }
-
- if ( $this->checkout_fields['shipping'] && ( $woocommerce->cart->needs_shipping() || get_option('woocommerce_require_shipping_address') == 'yes' ) ) {
- foreach ( $this->checkout_fields['shipping'] as $key => $field ) {
- if ( $this->posted['shiptobilling'] ) {
-
- $field_key = str_replace('shipping_', 'billing_', $key);
-
- // Post
- update_post_meta( $order_id, '_' . $key, $this->posted[ $field_key ] );
- } else {
- // Post
- update_post_meta( $order_id, '_' . $key, $this->posted[ $key ] );
-
- // User
- if ( $user_id > 0 )
- update_user_meta( $user_id, $key, $this->posted[ $key ] );
- }
- }
- }
-
- // Save any other user meta
- if ( $user_id )
- do_action( 'woocommerce_checkout_update_user_meta', $user_id, $this->posted );
-
- // UPDATE ORDER META
-
- // Get better formatted shipping method (title)
- $shipping_method = $this->posted['shipping_method'];
- if ( isset( $available_methods[ $this->posted['shipping_method'] ] ) )
- $shipping_method = $available_methods[ $this->posted['shipping_method'] ]->label;
-
- // Get better formatted payment method (title/label)
- $payment_method = $this->posted['payment_method'];
- if ( isset( $available_gateways[ $this->posted['payment_method'] ] ) )
- $payment_method = $available_gateways[ $this->posted['payment_method'] ]->get_title();
-
- // Store tax rows
- foreach ( array_keys( $woocommerce->cart->taxes + $woocommerce->cart->shipping_taxes ) as $key ) {
-
- $item_id = woocommerce_add_order_item( $order_id, array(
- 'order_item_name' => $woocommerce->cart->tax->get_rate_code( $key ),
- 'order_item_type' => 'tax'
- ) );
-
- // Add line item meta
- if ( $item_id ) {
- woocommerce_add_order_item_meta( $item_id, 'rate_id', $key );
- woocommerce_add_order_item_meta( $item_id, 'label', $woocommerce->cart->tax->get_rate_label( $key ) );
- woocommerce_add_order_item_meta( $item_id, 'compound', absint( $woocommerce->cart->tax->is_compound( $key ) ? 1 : 0 ) );
- woocommerce_add_order_item_meta( $item_id, 'tax_amount', woocommerce_clean( isset( $woocommerce->cart->taxes[ $key ] ) ? $woocommerce->cart->taxes[ $key ] : 0 ) );
- woocommerce_add_order_item_meta( $item_id, 'shipping_tax_amount', woocommerce_clean( isset( $woocommerce->cart->shipping_taxes[ $key ] ) ? $woocommerce->cart->shipping_taxes[ $key ] : 0 ) );
- }
- }
-
- // Store coupons
- if ( $applied_coupons = $woocommerce->cart->get_applied_coupons() ) {
- foreach ( $applied_coupons as $code ) {
-
- $item_id = woocommerce_add_order_item( $order_id, array(
- 'order_item_name' => $code,
- 'order_item_type' => 'coupon'
- ) );
-
- // Add line item meta
- if ( $item_id ) {
- woocommerce_add_order_item_meta( $item_id, 'discount_amount', isset( $woocommerce->cart->coupon_discount_amounts[ $code ] ) ? $woocommerce->cart->coupon_discount_amounts[ $code ] : 0 );
- }
- }
- }
-
- // Save other order meta fields
- update_post_meta( $order_id, '_shipping_method', $this->posted['shipping_method'] );
- update_post_meta( $order_id, '_payment_method', $this->posted['payment_method'] );
- update_post_meta( $order_id, '_shipping_method_title', $shipping_method );
- update_post_meta( $order_id, '_payment_method_title', $payment_method );
- update_post_meta( $order_id, '_order_shipping', woocommerce_format_total( $woocommerce->cart->shipping_total ) );
- update_post_meta( $order_id, '_order_discount', woocommerce_format_total( $woocommerce->cart->get_order_discount_total() ) );
- update_post_meta( $order_id, '_cart_discount', woocommerce_format_total( $woocommerce->cart->get_cart_discount_total() ) );
- update_post_meta( $order_id, '_order_tax', woocommerce_format_total( $woocommerce->cart->tax_total ) );
- update_post_meta( $order_id, '_order_shipping_tax', woocommerce_format_total( $woocommerce->cart->shipping_tax_total ) );
- update_post_meta( $order_id, '_order_total', woocommerce_format_total( $woocommerce->cart->total ) );
- update_post_meta( $order_id, '_order_key', apply_filters('woocommerce_generate_order_key', uniqid('order_') ) );
- update_post_meta( $order_id, '_customer_user', (int) $user_id );
- update_post_meta( $order_id, '_order_currency', get_woocommerce_currency() );
- update_post_meta( $order_id, '_prices_include_tax', get_option( 'woocommerce_prices_include_tax' ) );
-
- // Store technical customer details in meta
- $customer_ip = isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
- $customer_user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
-
- update_post_meta( $order_id, __( 'Customer IP Address', 'woocommerce' ), $customer_ip );
- update_post_meta( $order_id, __( 'Customer UA', 'woocommerce' ), $customer_user_agent );
-
- // Let plugins add meta
- do_action( 'woocommerce_checkout_update_order_meta', $order_id, $this->posted );
-
- // Order status
- wp_set_object_terms( $order_id, 'pending', 'shop_order_status' );
+ // Create the order
+ $order_id = $this->create_order();
// Order is saved
do_action( 'woocommerce_checkout_order_processed', $order_id, $this->posted );
- // Prevent timeout
- @set_time_limit(0);
-
// Process payment
if ( $woocommerce->cart->needs_payment() ) {
@@ -648,7 +682,7 @@ class WC_Checkout {
$result = apply_filters('woocommerce_payment_successful_result', $result );
if ( is_ajax() ) {
- echo json_encode( $result );
+ echo '' . json_encode( $result ) . '';
exit;
} else {
wp_redirect( $result['redirect'] );
@@ -674,12 +708,12 @@ class WC_Checkout {
// Redirect to success/confirmation/payment page
if ( is_ajax() ) {
- echo json_encode(
+ echo '' . json_encode(
array(
'result' => 'success',
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $return_url, $order)
)
- );
+ ) . '';
exit;
} else {
wp_safe_redirect(
@@ -706,13 +740,13 @@ class WC_Checkout {
$woocommerce->show_messages();
$messages = ob_get_clean();
- echo json_encode(
+ echo '' . json_encode(
array(
'result' => 'failure',
'messages' => $messages,
'refresh' => isset( $woocommerce->session->refresh_totals ) ? 'true' : 'false'
)
- );
+ ) . '';
unset( $woocommerce->session->refresh_totals );
exit;
@@ -727,48 +761,55 @@ class WC_Checkout {
* @param string $input
* @return string
*/
- function get_value( $input ) {
+ public function get_value( $input ) {
global $woocommerce;
if ( ! empty( $_POST[ $input ] ) ) {
return esc_attr( $_POST[ $input ] );
- } elseif ( is_user_logged_in() ) {
-
- if ( $meta = get_user_meta( get_current_user_id(), $input, true ) )
- return $meta;
-
- $current_user = wp_get_current_user();
- if ( $input == "billing_email" )
- return $current_user->user_email;
-
} else {
- $default_billing_country = apply_filters('default_checkout_country', ($woocommerce->customer->get_country()) ? $woocommerce->customer->get_country() : $woocommerce->countries->get_base_country());
+ if ( is_user_logged_in() ) {
- $default_shipping_country = apply_filters('default_checkout_country', ($woocommerce->customer->get_shipping_country()) ? $woocommerce->customer->get_shipping_country() : $woocommerce->countries->get_base_country());
+ $current_user = wp_get_current_user();
- if ( $woocommerce->customer->has_calculated_shipping() ) {
- $default_billing_state = apply_filters('default_checkout_state', $woocommerce->customer->get_state());
- $default_shipping_state = apply_filters('default_checkout_state', $woocommerce->customer->get_shipping_state());
- } else {
- $default_billing_state = apply_filters('default_checkout_state', '');
- $default_shipping_state = apply_filters('default_checkout_state', '');
+ if ( $meta = get_user_meta( $current_user->ID, $input, true ) )
+ return $meta;
+
+ if ( $input == "billing_email" )
+ return $current_user->user_email;
}
- if ( $input == "billing_country" ) return $default_billing_country;
+ $default_billing_country = apply_filters('default_checkout_country', ($woocommerce->customer->get_country()) ? $woocommerce->customer->get_country() : $woocommerce->countries->get_base_country());
- if ( $input == "billing_state" ) return $default_billing_state;
+ $default_shipping_country = apply_filters('default_checkout_country', ($woocommerce->customer->get_shipping_country()) ? $woocommerce->customer->get_shipping_country() : $woocommerce->countries->get_base_country());
- if ( $input == "billing_postcode" ) return ($woocommerce->customer->get_postcode()) ? $woocommerce->customer->get_postcode() : '';
+ if ( $woocommerce->customer->has_calculated_shipping() ) {
+ $default_billing_state = apply_filters('default_checkout_state', $woocommerce->customer->get_state());
+ $default_shipping_state = apply_filters('default_checkout_state', $woocommerce->customer->get_shipping_state());
+ } else {
+ $default_billing_state = apply_filters('default_checkout_state', '');
+ $default_shipping_state = apply_filters('default_checkout_state', '');
+ }
- if ( $input == "shipping_country" ) return $default_shipping_country;
+ if ( $input == "billing_country" )
+ return $default_billing_country;
- if ( $input == "shipping_state" ) return $default_shipping_state;
+ if ( $input == "billing_state" )
+ return $default_billing_state;
- if ( $input == "shipping_postcode" ) return ($woocommerce->customer->get_shipping_postcode()) ? $woocommerce->customer->get_shipping_postcode() : '';
+ if ( $input == "billing_postcode" )
+ return $woocommerce->customer->get_postcode() ? $woocommerce->customer->get_postcode() : '';
+ if ( $input == "shipping_country" )
+ return $default_shipping_country;
+
+ if ( $input == "shipping_state" )
+ return $default_shipping_state;
+
+ if ( $input == "shipping_postcode" )
+ return $woocommerce->customer->get_shipping_postcode() ? $woocommerce->customer->get_shipping_postcode() : '';
}
}
-}
\ No newline at end of file
+}
diff --git a/classes/class-wc-countries.php b/classes/class-wc-countries.php
index de13bc61ddb..7763f60f3bb 100644
--- a/classes/class-wc-countries.php
+++ b/classes/class-wc-countries.php
@@ -7,21 +7,22 @@
* @class WC_Countries
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Countries {
/** @var array Array of countries */
- var $countries;
+ public $countries;
/** @var array Array of states */
- var $states;
+ public $states;
/** @var array Array of locales */
- var $locale;
+ public $locale;
/** @var array Array of address formats for locales */
- var $address_formats;
+ public $address_formats;
/**
* Constructor for the counties class - defines all countries and states.
@@ -29,14 +30,14 @@ class WC_Countries {
* @access public
* @return void
*/
- function __construct() {
+ public function __construct() {
+ global $woocommerce, $states;
$this->countries = apply_filters('woocommerce_countries', array(
'AF' => __( 'Afghanistan', 'woocommerce' ),
'AX' => __( 'Åland Islands', 'woocommerce' ),
'AL' => __( 'Albania', 'woocommerce' ),
'DZ' => __( 'Algeria', 'woocommerce' ),
- 'AS' => __( 'American Samoa', 'woocommerce' ),
'AD' => __( 'Andorra', 'woocommerce' ),
'AO' => __( 'Angola', 'woocommerce' ),
'AI' => __( 'Anguilla', 'woocommerce' ),
@@ -54,6 +55,7 @@ class WC_Countries {
'BB' => __( 'Barbados', 'woocommerce' ),
'BY' => __( 'Belarus', 'woocommerce' ),
'BE' => __( 'Belgium', 'woocommerce' ),
+ 'PW' => __( 'Belau', 'woocommerce' ),
'BZ' => __( 'Belize', 'woocommerce' ),
'BJ' => __( 'Benin', 'woocommerce' ),
'BM' => __( 'Bermuda', 'woocommerce' ),
@@ -121,7 +123,6 @@ class WC_Countries {
'GL' => __( 'Greenland', 'woocommerce' ),
'GD' => __( 'Grenada', 'woocommerce' ),
'GP' => __( 'Guadeloupe', 'woocommerce' ),
- 'GU' => __( 'Guam', 'woocommerce' ),
'GT' => __( 'Guatemala', 'woocommerce' ),
'GG' => __( 'Guernsey', 'woocommerce' ),
'GN' => __( 'Guinea', 'woocommerce' ),
@@ -196,11 +197,9 @@ class WC_Countries {
'NU' => __( 'Niue', 'woocommerce' ),
'NF' => __( 'Norfolk Island', 'woocommerce' ),
'KP' => __( 'North Korea', 'woocommerce' ),
- 'MP' => __( 'Northern Mariana Islands', 'woocommerce' ),
'NO' => __( 'Norway', 'woocommerce' ),
'OM' => __( 'Oman', 'woocommerce' ),
'PK' => __( 'Pakistan', 'woocommerce' ),
- 'PW' => __( 'Palau', 'woocommerce' ),
'PS' => __( 'Palestinian Territory', 'woocommerce' ),
'PA' => __( 'Panama', 'woocommerce' ),
'PG' => __( 'Papua New Guinea', 'woocommerce' ),
@@ -210,7 +209,6 @@ class WC_Countries {
'PN' => __( 'Pitcairn', 'woocommerce' ),
'PL' => __( 'Poland', 'woocommerce' ),
'PT' => __( 'Portugal', 'woocommerce' ),
- 'PR' => __( 'Puerto Rico', 'woocommerce' ),
'QA' => __( 'Qatar', 'woocommerce' ),
'RE' => __( 'Reunion', 'woocommerce' ),
'RO' => __( 'Romania', 'woocommerce' ),
@@ -224,7 +222,6 @@ class WC_Countries {
'SX' => __( 'Saint Martin (Dutch part)', 'woocommerce' ),
'PM' => __( 'Saint Pierre and Miquelon', 'woocommerce' ),
'VC' => __( 'Saint Vincent and the Grenadines', 'woocommerce' ),
- 'WS' => __( 'Samoa', 'woocommerce' ),
'SM' => __( 'San Marino', 'woocommerce' ),
'ST' => __( 'São Tomé and Príncipe', 'woocommerce' ),
'SA' => __( 'Saudi Arabia', 'woocommerce' ),
@@ -264,8 +261,6 @@ class WC_Countries {
'TM' => __( 'Turkmenistan', 'woocommerce' ),
'TC' => __( 'Turks and Caicos Islands', 'woocommerce' ),
'TV' => __( 'Tuvalu', 'woocommerce' ),
- 'VI' => __( 'U.S. Virgin Islands', 'woocommerce' ),
- 'UM' => __( 'US Minor Outlying Islands', 'woocommerce' ),
'UG' => __( 'Uganda', 'woocommerce' ),
'UA' => __( 'Ukraine', 'woocommerce' ),
'AE' => __( 'United Arab Emirates', 'woocommerce' ),
@@ -279,166 +274,48 @@ class WC_Countries {
'VN' => __( 'Vietnam', 'woocommerce' ),
'WF' => __( 'Wallis and Futuna', 'woocommerce' ),
'EH' => __( 'Western Sahara', 'woocommerce' ),
+ 'WS' => __( 'Western Samoa', 'woocommerce' ),
'YE' => __( 'Yemen', 'woocommerce' ),
'ZM' => __( 'Zambia', 'woocommerce' ),
'ZW' => __( 'Zimbabwe', 'woocommerce' )
));
- $this->states = apply_filters('woocommerce_states', array(
- 'AU' => array(
- 'ACT' => __( 'Australian Capital Territory', 'woocommerce' ) ,
- 'NSW' => __( 'New South Wales', 'woocommerce' ) ,
- 'NT' => __( 'Northern Territory', 'woocommerce' ) ,
- 'QLD' => __( 'Queensland', 'woocommerce' ) ,
- 'SA' => __( 'South Australia', 'woocommerce' ) ,
- 'TAS' => __( 'Tasmania', 'woocommerce' ) ,
- 'VIC' => __( 'Victoria', 'woocommerce' ) ,
- 'WA' => __( 'Western Australia', 'woocommerce' )
- ),
+ // States set to array() are blank i.e. the country has no use for the state field.
+ $states = array(
'AF' => array(),
'AT' => array(),
'BE' => array(),
'BI' => array(),
- 'BR' => array(
- 'AC' => __( 'Acre', 'woocommerce' ),
- 'AL' => __( 'Alagoas', 'woocommerce' ),
- 'AP' => __( 'Amapá', 'woocommerce' ),
- 'AM' => __( 'Amazonas', 'woocommerce' ),
- 'BH' => __( 'Bahia', 'woocommerce' ),
- 'CE' => __( 'Ceará', 'woocommerce' ),
- 'DF' => __( 'Distrito Federal', 'woocommerce' ),
- 'ES' => __( 'Espírito Santo', 'woocommerce' ),
- 'GO' => __( 'Goiás', 'woocommerce' ),
- 'MA' => __( 'Maranhão', 'woocommerce' ),
- 'MT' => __( 'Mato Grosso', 'woocommerce' ),
- 'MS' => __( 'Mato Grosso do Sul', 'woocommerce' ),
- 'MG' => __( 'Minas Gerais', 'woocommerce' ),
- 'PA' => __( 'Pará', 'woocommerce' ),
- 'PB' => __( 'Paraíba', 'woocommerce' ),
- 'PR' => __( 'Paraná', 'woocommerce' ),
- 'PE' => __( 'Pernambuco', 'woocommerce' ),
- 'PI' => __( 'Piauí', 'woocommerce' ),
- 'RJ' => __( 'Rio de Janeiro', 'woocommerce' ),
- 'RN' => __( 'Rio Grande do Norte', 'woocommerce' ),
- 'RS' => __( 'Rio Grande do Sul', 'woocommerce' ),
- 'RO' => __( 'Rondônia', 'woocommerce' ),
- 'RR' => __( 'Roraima', 'woocommerce' ),
- 'SC' => __( 'Santa Catarina', 'woocommerce' ),
- 'SP' => __( 'São Paulo', 'woocommerce' ),
- 'SE' => __( 'Sergipe', 'woocommerce' ),
- 'TO' => __( 'Tocantins', 'woocommerce' )
- ),
- 'CA' => array(
- 'AB' => __( 'Alberta', 'woocommerce' ) ,
- 'BC' => __( 'British Columbia', 'woocommerce' ) ,
- 'MB' => __( 'Manitoba', 'woocommerce' ) ,
- 'NB' => __( 'New Brunswick', 'woocommerce' ) ,
- 'NF' => __( 'Newfoundland', 'woocommerce' ) ,
- 'NT' => __( 'Northwest Territories', 'woocommerce' ) ,
- 'NS' => __( 'Nova Scotia', 'woocommerce' ) ,
- 'NU' => __( 'Nunavut', 'woocommerce' ) ,
- 'ON' => __( 'Ontario', 'woocommerce' ) ,
- 'PE' => __( 'Prince Edward Island', 'woocommerce' ) ,
- 'QC' => __( 'Quebec', 'woocommerce' ) ,
- 'SK' => __( 'Saskatchewan', 'woocommerce' ) ,
- 'YT' => __( 'Yukon Territory', 'woocommerce' )
- ),
'CZ' => array(),
'DE' => array(),
'DK' => array(),
'FI' => array(),
'FR' => array(),
- 'HK' => array(
- 'HONG KONG' => __( 'Hong Kong Island', 'woocommerce' ),
- 'KOWLOON' => __( 'Kowloon', 'woocommerce' ),
- 'NEW TERRITORIES' => __( 'New Territories', 'woocommerce' )
- ),
'HU' => array(),
'IS' => array(),
'IL' => array(),
+ 'KR' => array(),
'NL' => array(),
- 'NZ' => array(
- 'AK' => __( 'Auckland', 'woocommerce' ),
- 'BP' => __( 'Bay of Plenty', 'woocommerce' ),
- 'CT' => __( 'Canterbury', 'woocommerce' ),
- 'HB' => __( 'Hawke’s Bay', 'woocommerce' ),
- 'MW' => __( 'Manawatu-Wanganui', 'woocommerce' ),
- 'MB' => __( 'Marlborough', 'woocommerce' ),
- 'NS' => __( 'Nelson', 'woocommerce' ),
- 'NL' => __( 'Northland', 'woocommerce' ),
- 'OT' => __( 'Otago', 'woocommerce' ),
- 'SL' => __( 'Southland', 'woocommerce' ),
- 'TK' => __( 'Taranaki', 'woocommerce' ),
- 'TM' => __( 'Tasman', 'woocommerce' ),
- 'WA' => __( 'Waikato', 'woocommerce' ),
- 'WE' => __( 'Wellington', 'woocommerce' ),
- 'WC' => __( 'West Coast', 'woocommerce' )
- ),
'NO' => array(),
'PL' => array(),
+ 'PT' => array(),
'SG' => array(),
'SK' => array(),
'SI' => array(),
'LK' => array(),
'SE' => array(),
- 'US' => array(
- 'AL' => __( 'Alabama', 'woocommerce' ) ,
- 'AK' => __( 'Alaska', 'woocommerce' ) ,
- 'AZ' => __( 'Arizona', 'woocommerce' ) ,
- 'AR' => __( 'Arkansas', 'woocommerce' ) ,
- 'CA' => __( 'California', 'woocommerce' ) ,
- 'CO' => __( 'Colorado', 'woocommerce' ) ,
- 'CT' => __( 'Connecticut', 'woocommerce' ) ,
- 'DE' => __( 'Delaware', 'woocommerce' ) ,
- 'DC' => __( 'District Of Columbia', 'woocommerce' ) ,
- 'FL' => __( 'Florida', 'woocommerce' ) ,
- 'GA' => __( 'Georgia', 'woocommerce' ) ,
- 'HI' => __( 'Hawaii', 'woocommerce' ) ,
- 'ID' => __( 'Idaho', 'woocommerce' ) ,
- 'IL' => __( 'Illinois', 'woocommerce' ) ,
- 'IN' => __( 'Indiana', 'woocommerce' ) ,
- 'IA' => __( 'Iowa', 'woocommerce' ) ,
- 'KS' => __( 'Kansas', 'woocommerce' ) ,
- 'KY' => __( 'Kentucky', 'woocommerce' ) ,
- 'LA' => __( 'Louisiana', 'woocommerce' ) ,
- 'ME' => __( 'Maine', 'woocommerce' ) ,
- 'MD' => __( 'Maryland', 'woocommerce' ) ,
- 'MA' => __( 'Massachusetts', 'woocommerce' ) ,
- 'MI' => __( 'Michigan', 'woocommerce' ) ,
- 'MN' => __( 'Minnesota', 'woocommerce' ) ,
- 'MS' => __( 'Mississippi', 'woocommerce' ) ,
- 'MO' => __( 'Missouri', 'woocommerce' ) ,
- 'MT' => __( 'Montana', 'woocommerce' ) ,
- 'NE' => __( 'Nebraska', 'woocommerce' ) ,
- 'NV' => __( 'Nevada', 'woocommerce' ) ,
- 'NH' => __( 'New Hampshire', 'woocommerce' ) ,
- 'NJ' => __( 'New Jersey', 'woocommerce' ) ,
- 'NM' => __( 'New Mexico', 'woocommerce' ) ,
- 'NY' => __( 'New York', 'woocommerce' ) ,
- 'NC' => __( 'North Carolina', 'woocommerce' ) ,
- 'ND' => __( 'North Dakota', 'woocommerce' ) ,
- 'OH' => __( 'Ohio', 'woocommerce' ) ,
- 'OK' => __( 'Oklahoma', 'woocommerce' ) ,
- 'OR' => __( 'Oregon', 'woocommerce' ) ,
- 'PA' => __( 'Pennsylvania', 'woocommerce' ) ,
- 'RI' => __( 'Rhode Island', 'woocommerce' ) ,
- 'SC' => __( 'South Carolina', 'woocommerce' ) ,
- 'SD' => __( 'South Dakota', 'woocommerce' ) ,
- 'TN' => __( 'Tennessee', 'woocommerce' ) ,
- 'TX' => __( 'Texas', 'woocommerce' ) ,
- 'UT' => __( 'Utah', 'woocommerce' ) ,
- 'VT' => __( 'Vermont', 'woocommerce' ) ,
- 'VA' => __( 'Virginia', 'woocommerce' ) ,
- 'WA' => __( 'Washington', 'woocommerce' ) ,
- 'WV' => __( 'West Virginia', 'woocommerce' ) ,
- 'WI' => __( 'Wisconsin', 'woocommerce' ) ,
- 'WY' => __( 'Wyoming', 'woocommerce' ) ,
- 'AA' => __( 'Armed Forces (AA)', 'woocommerce' ) ,
- 'AE' => __( 'Armed Forces (AE)', 'woocommerce' ) ,
- 'AP' => __( 'Armed Forces (AP)', 'woocommerce' )
- ),
- 'VN' => array()
- ));
+ 'VN' => array(),
+ );
+
+ // Load only the state files the shop owner wants/needs
+ $allowed = $this->get_allowed_countries();
+
+ if ( $allowed )
+ foreach ( $allowed as $CC => $country )
+ if ( ! isset( $states[ $CC ] ) && file_exists( $woocommerce->plugin_path() . '/i18n/states/' . $CC . '.php' ) )
+ include( $woocommerce->plugin_path() . '/i18n/states/' . $CC . '.php' );
+
+ $this->states = apply_filters('woocommerce_states', $states );
}
@@ -448,7 +325,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function get_base_country() {
+ public function get_base_country() {
$default = esc_attr( get_option('woocommerce_default_country') );
if ( ( $pos = strpos( $default, ':' ) ) === false )
return $default;
@@ -462,7 +339,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function get_base_state() {
+ public function get_base_state() {
$default = esc_attr( get_option( 'woocommerce_default_country' ) );
if ( ( $pos = strrpos( $default, ':' ) ) === false )
return '';
@@ -476,9 +353,10 @@ class WC_Countries {
* @access public
* @return array
*/
- function get_allowed_countries() {
+ public function get_allowed_countries() {
- asort( $this->countries );
+ if ( apply_filters('woocommerce_sort_countries', true ) )
+ asort( $this->countries );
if ( get_option('woocommerce_allowed_countries') !== 'specific' )
return $this->countries;
@@ -487,8 +365,8 @@ class WC_Countries {
$allowed_countries_raw = get_option( 'woocommerce_specific_allowed_countries' );
- foreach ($allowed_countries_raw as $country)
- $allowed_countries[$country] = $this->countries[$country];
+ foreach ( $allowed_countries_raw as $country )
+ $allowed_countries[ $country ] = $this->countries[ $country ];
return $allowed_countries;
}
@@ -500,7 +378,7 @@ class WC_Countries {
* @access public
* @return array
*/
- function get_allowed_country_states() {
+ public function get_allowed_country_states() {
if ( get_option('woocommerce_allowed_countries') !== 'specific' )
return $this->states;
@@ -523,8 +401,8 @@ class WC_Countries {
* @access public
* @return array
*/
- function get_european_union_countries() {
- return array('AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK');
+ public function get_european_union_countries() {
+ return array( 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK' );
}
@@ -534,7 +412,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function shipping_to_prefix() {
+ public function shipping_to_prefix() {
global $woocommerce;
$return = '';
if (in_array($woocommerce->customer->get_shipping_country(), array( 'GB', 'US', 'AE', 'CZ', 'DO', 'NL', 'PH', 'USAF' ))) $return = __( 'to the', 'woocommerce' );
@@ -549,7 +427,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function estimated_for_prefix() {
+ public function estimated_for_prefix() {
$return = '';
if (in_array($this->get_base_country(), array( 'GB', 'US', 'AE', 'CZ', 'DO', 'NL', 'PH', 'USAF' ))) $return = __( 'the', 'woocommerce' ) . ' ';
return apply_filters('woocommerce_countries_estimated_for_prefix', $return, $this->get_base_country());
@@ -562,7 +440,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function tax_or_vat() {
+ public function tax_or_vat() {
$return = ( in_array($this->get_base_country(), $this->get_european_union_countries()) ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
return apply_filters( 'woocommerce_countries_tax_or_vat', $return );
@@ -575,7 +453,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function inc_tax_or_vat() {
+ public function inc_tax_or_vat() {
$return = ( in_array($this->get_base_country(), $this->get_european_union_countries()) ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
return apply_filters( 'woocommerce_countries_inc_tax_or_vat', $return );
@@ -588,7 +466,7 @@ class WC_Countries {
* @access public
* @return string
*/
- function ex_tax_or_vat() {
+ public function ex_tax_or_vat() {
$return = ( in_array($this->get_base_country(), $this->get_european_union_countries()) ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
return apply_filters( 'woocommerce_countries_ex_tax_or_vat', $return );
@@ -602,7 +480,7 @@ class WC_Countries {
* @param mixed $cc country code
* @return array of states
*/
- function get_states( $cc ) {
+ public function get_states( $cc ) {
if (isset( $this->states[$cc] )) return $this->states[$cc];
}
@@ -616,9 +494,10 @@ class WC_Countries {
* @param bool $escape (default: false)
* @return void
*/
- function country_dropdown_options( $selected_country = '', $selected_state = '', $escape = false ) {
+ public function country_dropdown_options( $selected_country = '', $selected_state = '', $escape = false ) {
- asort($this->countries);
+ if ( apply_filters('woocommerce_sort_countries', true ) )
+ asort( $this->countries );
if ( $this->countries ) foreach ( $this->countries as $key=>$value) :
if ( $states = $this->get_states($key) ) :
@@ -648,7 +527,7 @@ class WC_Countries {
* @param bool $escape (default: false)
* @return void
*/
- function country_multiselect_options( $selected_countries = '', $escape = false ) {
+ public function country_multiselect_options( $selected_countries = '', $escape = false ) {
$countries = $this->get_allowed_countries();
@@ -674,7 +553,7 @@ class WC_Countries {
* @access public
* @return array
*/
- function get_address_formats() {
+ public function get_address_formats() {
if (!$this->address_formats) :
@@ -724,7 +603,7 @@ class WC_Countries {
* @param array $args (default: array())
* @return string address
*/
- function get_formatted_address( $args = array() ) {
+ public function get_formatted_address( $args = array() ) {
$args = array_map( 'trim', $args );
@@ -786,13 +665,78 @@ class WC_Countries {
}
+ /**
+ * Returns the fields we show by default. This can be filtered later on.
+ *
+ * @access public
+ * @return void
+ */
+ public function get_default_address_fields() {
+ $fields = array(
+ 'country' => array(
+ 'type' => 'country',
+ 'label' => __( 'Country', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ),
+ ),
+ 'first_name' => array(
+ 'label' => __( 'First Name', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-first' ),
+ ),
+ 'last_name' => array(
+ 'label' => __( 'Last Name', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-last' ),
+ 'clear' => true
+ ),
+ 'company' => array(
+ 'label' => __( 'Company Name', 'woocommerce' ),
+ 'class' => array( 'form-row-wide' ),
+ ),
+ 'address_1' => array(
+ 'label' => __( 'Address', 'woocommerce' ),
+ 'placeholder' => _x( 'Street address', 'placeholder', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-wide', 'address-field' ),
+ ),
+ 'address_2' => array(
+ 'placeholder' => _x( 'Apartment, suite, unit etc. (optional)', 'placeholder', 'woocommerce' ),
+ 'class' => array( 'form-row-wide', 'address-field' ),
+ 'required' => false
+ ),
+ 'city' => array(
+ 'label' => __( 'Town / City', 'woocommerce' ),
+ 'placeholder' => __( 'Town / City', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-wide', 'address-field' ),
+ ),
+ 'state' => array(
+ 'type' => 'state',
+ 'label' => __( 'State / County', 'woocommerce' ),
+ 'placeholder' => __( 'State / County', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-first', 'address-field' )
+ ),
+ 'postcode' => array(
+ 'label' => __( 'Postcode / Zip', 'woocommerce' ),
+ 'placeholder' => __( 'Postcode / Zip', 'woocommerce' ),
+ 'required' => true,
+ 'class' => array( 'form-row-last', 'address-field' ),
+ 'clear' => true
+ ),
+ );
+
+ return apply_filters( 'woocommerce_default_address_fields', $fields );
+ }
+
/**
* Get country locale settings
*
* @access public
* @return array
*/
- function get_country_locale() {
+ public function get_country_locale() {
if ( ! $this->locale ) {
// Locale information used by the checkout
@@ -812,6 +756,7 @@ class WC_Countries {
'postcode_before_city' => true,
'state' => array(
'required' => false,
+ 'label' => __( 'Province', 'woocommerce' ),
),
),
'BI' => array(
@@ -822,14 +767,12 @@ class WC_Countries {
'CA' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
- 'placeholder' => __( 'Province', 'woocommerce' )
)
),
'CH' => array(
'postcode_before_city' => true,
'state' => array(
'label' => __( 'Canton', 'woocommerce' ),
- 'placeholder' => __( 'Canton', 'woocommerce' ),
'required' => false
)
),
@@ -839,13 +782,11 @@ class WC_Countries {
),
'state' => array(
'label' => __( 'Municipality', 'woocommerce' ),
- 'placeholder' => __( 'Municipality', 'woocommerce' )
)
),
'CN' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
- 'placeholder' => __( 'Province', 'woocommerce' )
)
),
'CO' => array(
@@ -887,12 +828,10 @@ class WC_Countries {
'required' => false
),
'city' => array(
- 'label' => __( 'Town/District', 'woocommerce' ),
- 'placeholder' => __( 'Town/District', 'woocommerce' )
+ 'label' => __( 'Town / District', 'woocommerce' ),
),
'state' => array(
'label' => __( 'Region', 'woocommerce' ),
- 'placeholder' => __( 'Region', 'woocommerce' )
)
),
'HU' => array(
@@ -900,6 +839,11 @@ class WC_Countries {
'required' => false
)
),
+ 'ID' => array(
+ 'state' => array(
+ 'label' => __( 'Province', 'woocommerce' ),
+ )
+ ),
'IS' => array(
'postcode_before_city' => true,
'state' => array(
@@ -912,10 +856,16 @@ class WC_Countries {
'required' => false
)
),
+ 'KR' => array(
+ 'state' => array(
+ 'required' => false
+ )
+ ),
'NL' => array(
'postcode_before_city' => true,
'state' => array(
- 'required' => false
+ 'required' => false,
+ 'label' => __( 'Province', 'woocommerce' ),
)
),
'NZ' => array(
@@ -935,6 +885,11 @@ class WC_Countries {
'required' => false
)
),
+ 'PT' => array(
+ 'state' => array(
+ 'required' => false
+ )
+ ),
'RO' => array(
'state' => array(
'required' => false
@@ -961,14 +916,12 @@ class WC_Countries {
'postcode_before_city' => true,
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
- 'placeholder' => __( 'Province', 'woocommerce' )
)
),
'LI' => array(
'postcode_before_city' => true,
'state' => array(
'label' => __( 'Municipality', 'woocommerce' ),
- 'placeholder' => __( 'Municipality', 'woocommerce' ),
'required' => false
)
),
@@ -987,27 +940,22 @@ class WC_Countries {
'postcode_before_city' => true,
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
- 'placeholder' => __( 'Province', 'woocommerce' )
)
),
'US' => array(
'postcode' => array(
'label' => __( 'Zip', 'woocommerce' ),
- 'placeholder' => __( 'Zip', 'woocommerce' )
),
'state' => array(
'label' => __( 'State', 'woocommerce' ),
- 'placeholder' => __( 'State', 'woocommerce' )
)
),
'GB' => array(
'postcode' => array(
'label' => __( 'Postcode', 'woocommerce' ),
- 'placeholder' => __( 'Postcode', 'woocommerce' )
),
'state' => array(
'label' => __( 'County', 'woocommerce' ),
- 'placeholder' => __( 'County', 'woocommerce' ),
'required' => false
)
),
@@ -1024,133 +972,77 @@ class WC_Countries {
'hidden' => true
)
),
+ 'WS' => array(
+ 'postcode' => array(
+ 'required' => false,
+ 'hidden' => true
+ ),
+ ),
+ 'ZA' => array(
+ 'state' => array(
+ 'label' => __( 'Province', 'woocommerce' ),
+ )
+ ),
+ 'ZW' => array(
+ 'postcode' => array(
+ 'required' => false,
+ 'hidden' => true
+ ),
+ ),
));
$this->locale = array_intersect_key( $this->locale, $this->get_allowed_countries() );
- $this->locale['default'] = apply_filters('woocommerce_get_country_locale_default', array(
- 'address_2' => array(
- 'required' => false
- ),
- 'postcode' => array(
- 'label' => __( 'Postcode/Zip', 'woocommerce' ),
- 'placeholder' => __( 'Postcode/Zip', 'woocommerce' ),
- 'required' => true
- ),
- 'city' => array(
- 'label' => __( 'Town/City', 'woocommerce' ),
- 'placeholder' => __( 'Town/City', 'woocommerce' ),
- 'required' => true
- ),
- 'state' => array(
- 'label' => __( 'State/County', 'woocommerce' ),
- 'placeholder' => __( 'State/County', 'woocommerce' ),
- 'required' => true
- )
- ));
+ // Default Locale Can be filters to override fields in get_address_fields().
+ // Countries with no specific locale will use default.
+ $this->locale['default'] = apply_filters('woocommerce_get_country_locale_default', $this->get_default_address_fields() );
// Filter default AND shop base locales to allow overides via a single function. These will be used when changing countries on the checkout
- if ( ! isset( $this->locale[ $this->get_base_country() ] ) ) $this->locale[ $this->get_base_country() ] = $this->locale['default'];
+ if ( ! isset( $this->locale[ $this->get_base_country() ] ) )
+ $this->locale[ $this->get_base_country() ] = $this->locale['default'];
$this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale['default'] );
$this->locale[ $this->get_base_country() ] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale[ $this->get_base_country() ] );
-
}
return $this->locale;
-
}
- /** Apply locale and get address fields */
- function get_address_fields( $country, $type = 'billing_' ) {
+ /**
+ * Apply locale and get address fields
+ *
+ * @access public
+ * @param mixed $country
+ * @param string $type (default: 'billing_')
+ * @return void
+ */
+ public function get_address_fields( $country, $type = 'billing_' ) {
+ $fields = $this->get_default_address_fields();
$locale = $this->get_country_locale();
- $fields = array(
- 'first_name' => array(
- 'label' => __( 'First Name', 'woocommerce' ),
- 'placeholder' => _x('First Name', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-first'),
- ),
- 'last_name' => array(
- 'label' => __( 'Last Name', 'woocommerce' ),
- 'placeholder' => _x('Last Name', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-last'),
- 'clear' => true
- ),
- 'company' => array(
- 'label' => __( 'Company Name', 'woocommerce' ),
- 'placeholder' => _x('Company (optional)', 'placeholder', 'woocommerce'),
- 'clear' => true
- ),
- 'address_1' => array(
- 'label' => __( 'Address', 'woocommerce' ),
- 'placeholder' => _x('Address', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-first'),
- ),
- 'address_2' => array(
- 'label' => __( 'Address 2', 'woocommerce' ),
- 'placeholder' => _x('Address 2 (optional)', 'placeholder', 'woocommerce'),
- 'class' => array('form-row-last'),
- 'label_class' => array('hidden'),
- 'clear' => true
- ),
- 'city' => array(
- 'label' => __( 'Town/City', 'woocommerce' ),
- 'placeholder' => _x('Town/City', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-first', 'update_totals_on_change'),
- ),
- 'postcode' => array(
- 'label' => __( 'Postcode/Zip', 'woocommerce' ),
- 'placeholder' => _x('Postcode/Zip', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-last', 'update_totals_on_change'),
- 'clear' => true
- ),
- 'country' => array(
- 'type' => 'country',
- 'label' => __( 'Country', 'woocommerce' ),
- 'placeholder' => _x('Country', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-first', 'update_totals_on_change'),
- ),
- 'state' => array(
- 'type' => 'state',
- 'label' => __( 'State/County', 'woocommerce' ),
- 'placeholder' => _x('State/County', 'placeholder', 'woocommerce'),
- 'required' => true,
- 'class' => array('form-row-last', 'update_totals_on_change'),
- 'clear' => true
- )
- );
+ if ( isset( $locale[ $country ] ) ) {
- if ( isset( $locale[$country] ) ) {
+ $fields = woocommerce_array_overlay( $fields, $locale[ $country ] );
- $fields = woocommerce_array_overlay( $fields, $locale[$country] );
+ // If default country has postcode_before_city switch the fields round.
+ // This is only done at this point, not if country changes on checkout.
+ if ( isset( $locale[ $country ]['postcode_before_city'] ) ) {
+ if ( isset( $fields['postcode'] ) ) {
+ $fields['postcode']['class'] = array( 'form-row-wide', 'address-field' );
- // If default country has postcode_before_city switch the fields round
- if ( isset( $locale[$country]['postcode_before_city'] ) ) {
- $fields['city']['class'] = array('form-row-last');
- $fields['city']['clear'] = true;
- $fields['postcode']['class'] = array('form-row-first', 'update_totals_on_change');
- $fields['postcode']['clear'] = false;
+ $switch_fields = array();
- $switch_fields = array();
-
- foreach ( $fields as $key => $value ) {
- if ( $key == 'city' ) {
- // Place postcode before city
- $switch_fields['postcode'] = '';
+ foreach ( $fields as $key => $value ) {
+ if ( $key == 'city' ) {
+ // Place postcode before city
+ $switch_fields['postcode'] = '';
+ }
+ $switch_fields[$key] = $value;
}
- $switch_fields[$key] = $value;
+
+ $fields = $switch_fields;
}
-
- $fields = $switch_fields;
}
-
}
// Prepend field keys
@@ -1165,22 +1057,20 @@ class WC_Countries {
$address_fields['billing_email'] = array(
'label' => __( 'Email Address', 'woocommerce' ),
- 'placeholder' => _x('Email Address', 'placeholder', 'woocommerce'),
'required' => true,
- 'class' => array('form-row-first'),
- 'validate' => array('email'),
+ 'class' => array( 'form-row-first' ),
+ 'validate' => array( 'email' ),
);
$address_fields['billing_phone'] = array(
'label' => __( 'Phone', 'woocommerce' ),
- 'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => true,
- 'class' => array('form-row-last'),
+ 'class' => array( 'form-row-last' ),
'clear' => true
);
- $address_fields = apply_filters('woocommerce_billing_fields', $address_fields);
+ $address_fields = apply_filters( 'woocommerce_billing_fields', $address_fields, $country );
} else {
- $address_fields = apply_filters('woocommerce_shipping_fields', $address_fields);
+ $address_fields = apply_filters( 'woocommerce_shipping_fields', $address_fields, $country );
}
// Return
diff --git a/classes/class-wc-coupon.php b/classes/class-wc-coupon.php
index 845d100bdca..5ada0260864 100644
--- a/classes/class-wc-coupon.php
+++ b/classes/class-wc-coupon.php
@@ -5,154 +5,172 @@
* The WooCommerce coupons class gets coupon data from storage and checks coupon validity
*
* @class WC_Coupon
- * @package WooCommerce
+ * @package WooCommerce/Classes
* @category Class
* @author WooThemes
*/
class WC_Coupon {
- /** @var string Coupon code. */
- var $code;
+ // Coupon message codes
+ const E_WC_COUPON_INVALID_FILTERED = 100;
+ const E_WC_COUPON_INVALID_REMOVED = 101;
+ const E_WC_COUPON_NOT_YOURS_REMOVED = 102;
+ const E_WC_COUPON_ALREADY_APPLIED = 103;
+ const E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY = 104;
+ const E_WC_COUPON_NOT_EXIST = 105;
+ const E_WC_COUPON_USAGE_LIMIT_REACHED = 106;
+ const E_WC_COUPON_EXPIRED = 107;
+ const E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET = 108;
+ const E_WC_COUPON_NOT_APPLICABLE = 109;
+ const E_WC_COUPON_NOT_VALID_SALE_ITEMS = 110;
+ const E_WC_COUPON_PLEASE_ENTER = 111;
+ const WC_COUPON_SUCCESS = 200;
- /** @var int Coupon ID. */
- var $id;
+ /** @public string Coupon code. */
+ public $code;
- /** @var string Type of discount. */
- var $type;
+ /** @public int Coupon ID. */
+ public $id;
- /** @var string Type of discount (alias). */
- var $discount_type;
+ /** @public string Type of discount. */
+ public $type;
- /** @var string Coupon amount. */
- var $amount;
+ /** @public string Type of discount (alias). */
+ public $discount_type;
- /** @var string "Yes" if for individual use. */
- var $individual_use;
+ /** @public string Coupon amount. */
+ public $amount;
- /** @var array Array of product IDs. */
- var $product_ids;
+ /** @public string "Yes" if for individual use. */
+ public $individual_use;
- /** @var int Coupon usage limit. */
- var $usage_limit;
+ /** @public array Array of product IDs. */
+ public $product_ids;
- /** @var int Coupon usage count. */
- var $usage_count;
+ /** @public int Coupon usage limit. */
+ public $usage_limit;
- /** @var string Expirey date. */
- var $expiry_date;
+ /** @public int Coupon usage count. */
+ public $usage_count;
- /** @var string "yes" if applied before tax. */
- var $apply_before_tax;
+ /** @public string Expiry date. */
+ public $expiry_date;
- /** @var string "yes" if coupon grants free shipping. */
- var $free_shipping;
+ /** @public string "yes" if applied before tax. */
+ public $apply_before_tax;
- /** @var array Array of category ids. */
- var $product_categories;
+ /** @public string "yes" if coupon grants free shipping. */
+ public $free_shipping;
- /** @var array Array of category ids. */
- var $exclude_product_categories;
+ /** @public array Array of category ids. */
+ public $product_categories;
- /** @var string Minimum cart amount. */
- var $minimum_amount;
+ /** @public array Array of category ids. */
+ public $exclude_product_categories;
- /** @var string Coupon owner's email. */
- var $customer_email;
+ /** @public string "yes" if coupon does NOT apply to items on sale. */
+ public $exclude_sale_items;
- /** @var array Post meta. */
- var $coupon_custom_fields;
+ /** @public string Minimum cart amount. */
+ public $minimum_amount;
- /** @var string How much the coupon is worth. */
- var $coupon_amount;
+ /** @public string Coupon owner's email. */
+ public $customer_email;
+
+ /** @public array Post meta. */
+ public $coupon_custom_fields;
+
+ /** @public string How much the coupon is worth. */
+ public $coupon_amount;
+
+ /** @public string Error message. */
+ public $error_message;
/**
* Coupon constructor. Loads coupon data.
*
* @access public
* @param mixed $code code of the coupon to load
- * @return bool whether or not the coupon was found
+ * @return void
*/
- function __construct( $code ) {
+ public function __construct( $code ) {
global $wpdb;
- $this->code = apply_filters( 'woocommerce_coupon_code', $code );
+ $this->code = apply_filters( 'woocommerce_coupon_code', $code );
// Coupon data lets developers create coupons through code
- $coupon_data = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code );
+ $coupon_data = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code );
if ( $coupon_data ) {
- $this->id = absint( $coupon_data['id'] );
- $this->type = esc_html( $coupon_data['type'] );
- $this->amount = esc_html( $coupon_data['amount'] );
- $this->individual_use = esc_html( $coupon_data['individual_use'] );
- $this->product_ids = is_array( $coupon_data['product_ids'] ) ? $coupon_data['product_ids'] : array();
- $this->exclude_product_ids = is_array( $coupon_data['exclude_product_ids'] ) ? $coupon_data['exclude_product_ids'] : array();
- $this->usage_limit = absint( $coupon_data['usage_limit'] );
- $this->usage_count = absint( $coupon_data['usage_count'] );
- $this->expiry_date = esc_html( $coupon_data['expiry_date'] );
- $this->apply_before_tax = esc_html( $coupon_data['apply_before_tax'] );
- $this->free_shipping = esc_html( $coupon_data['free_shipping'] );
- $this->product_categories = is_array( $coupon_data['product_categories'] ) ? $coupon_data['product_categories'] : array();
- $this->exclude_product_categories = is_array( $coupon_data['exclude_product_categories'] ) ? $coupon_data['exclude_product_categories'] : array();
- $this->minimum_amount = esc_html( $coupon_data['minimum_amount'] );
- $this->customer_email = esc_html( $coupon_data['customer_email'] );
-
- return true;
+ $this->id = absint( $coupon_data['id'] );
+ $this->type = esc_html( $coupon_data['type'] );
+ $this->amount = esc_html( $coupon_data['amount'] );
+ $this->individual_use = esc_html( $coupon_data['individual_use'] );
+ $this->product_ids = is_array( $coupon_data['product_ids'] ) ? $coupon_data['product_ids'] : array();
+ $this->exclude_product_ids = is_array( $coupon_data['exclude_product_ids'] ) ? $coupon_data['exclude_product_ids'] : array();
+ $this->usage_limit = absint( $coupon_data['usage_limit'] );
+ $this->usage_count = absint( $coupon_data['usage_count'] );
+ $this->expiry_date = esc_html( $coupon_data['expiry_date'] );
+ $this->apply_before_tax = esc_html( $coupon_data['apply_before_tax'] );
+ $this->free_shipping = esc_html( $coupon_data['free_shipping'] );
+ $this->product_categories = is_array( $coupon_data['product_categories'] ) ? $coupon_data['product_categories'] : array();
+ $this->exclude_product_categories = is_array( $coupon_data['exclude_product_categories'] ) ? $coupon_data['exclude_product_categories'] : array();
+ $this->exclude_sale_items = esc_html( $coupon_data['exclude_sale_items'] );
+ $this->minimum_amount = esc_html( $coupon_data['minimum_amount'] );
+ $this->customer_email = esc_html( $coupon_data['customer_email'] );
} else {
- $coupon_id = $wpdb->get_var( $wpdb->prepare( apply_filters( 'woocommerce_coupon_code_query', "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon'" ), $this->code ) );
+ $coupon_id = $wpdb->get_var( $wpdb->prepare( apply_filters( 'woocommerce_coupon_code_query', "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'" ), $this->code ) );
- if ( $coupon_id )
- $coupon = get_post( $coupon_id );
- else
- return false;
+ if ( ! $coupon_id )
+ return;
+ $coupon = get_post( $coupon_id );
$coupon->post_title = apply_filters( 'woocommerce_coupon_code', $coupon->post_title );
- if ( empty( $coupon ) || $coupon->post_status !== 'publish' || $this->code !== $coupon->post_title )
- return false;
+ if ( empty( $coupon ) || $this->code !== $coupon->post_title )
+ return;
- $this->id = $coupon->ID;
- $this->coupon_custom_fields = get_post_custom( $this->id );
+ $this->id = $coupon->ID;
+ $this->coupon_custom_fields = get_post_meta( $this->id );
$load_data = array(
- 'discount_type' => 'fixed_cart',
- 'coupon_amount' => 0,
- 'individual_use' => 'no',
- 'product_ids' => '',
- 'exclude_product_ids' => '',
- 'usage_limit' => '',
- 'usage_count' => '',
- 'expiry_date' => '',
- 'apply_before_tax' => 'yes',
- 'free_shipping' => 'no',
- 'product_categories' => array(),
- 'exclude_product_categories' => array(),
- 'minimum_amount' => '',
- 'customer_email' => array()
+ 'discount_type' => 'fixed_cart',
+ 'coupon_amount' => 0,
+ 'individual_use' => 'no',
+ 'product_ids' => '',
+ 'exclude_product_ids' => '',
+ 'usage_limit' => '',
+ 'usage_count' => '',
+ 'expiry_date' => '',
+ 'apply_before_tax' => 'yes',
+ 'free_shipping' => 'no',
+ 'product_categories' => array(),
+ 'exclude_product_categories' => array(),
+ 'exclude_sale_items' => 'no',
+ 'minimum_amount' => '',
+ 'customer_email' => array()
);
foreach ( $load_data as $key => $default )
$this->$key = isset( $this->coupon_custom_fields[ $key ][0] ) && $this->coupon_custom_fields[ $key ][0] !== '' ? $this->coupon_custom_fields[ $key ][0] : $default;
// Alias
- $this->type = $this->discount_type;
- $this->amount = $this->coupon_amount;
+ $this->type = $this->discount_type;
+ $this->amount = $this->coupon_amount;
// Formatting
- $this->product_ids = array_filter( array_map( 'trim', explode( ',', $this->product_ids ) ) );
- $this->exclude_product_ids = array_filter( array_map( 'trim', explode( ',', $this->exclude_product_ids ) ) );
- $this->expiry_date = $this->expiry_date ? strtotime( $this->expiry_date ) : '';
- $this->product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->product_categories ) ) );
- $this->exclude_product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->exclude_product_categories ) ) );
- $this->customer_email = array_filter( array_map( 'trim', array_map( 'strtolower', (array) maybe_unserialize( $this->customer_email ) ) ) );
-
- return true;
+ $this->product_ids = array_filter( array_map( 'trim', explode( ',', $this->product_ids ) ) );
+ $this->exclude_product_ids = array_filter( array_map( 'trim', explode( ',', $this->exclude_product_ids ) ) );
+ $this->expiry_date = $this->expiry_date ? strtotime( $this->expiry_date ) : '';
+ $this->product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->product_categories ) ) );
+ $this->exclude_product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->exclude_product_categories ) ) );
+ $this->customer_email = array_filter( array_map( 'trim', array_map( 'strtolower', (array) maybe_unserialize( $this->customer_email ) ) ) );
}
- return false;
+ do_action( 'woocommerce_coupon_loaded', $this );
}
@@ -162,7 +180,7 @@ class WC_Coupon {
* @access public
* @return bool
*/
- function apply_before_tax() {
+ public function apply_before_tax() {
return $this->apply_before_tax == 'yes' ? true : false;
}
@@ -173,18 +191,30 @@ class WC_Coupon {
* @access public
* @return void
*/
- function enable_free_shipping() {
+ public function enable_free_shipping() {
return $this->free_shipping == 'yes' ? true : false;
}
+ /**
+ * Check if a coupon excludes sale items.
+ *
+ * @access public
+ * @return void
+ */
+ public function exclude_sale_items() {
+ return $this->exclude_sale_items == 'yes' ? true : false;
+ }
+
+
+
/**
* Increase usage count fo current coupon.
*
* @access public
* @return void
*/
- function inc_usage_count() {
+ public function inc_usage_count() {
$this->usage_count++;
update_post_meta( $this->id, 'usage_count', $this->usage_count );
}
@@ -196,32 +226,43 @@ class WC_Coupon {
* @access public
* @return void
*/
- function dcr_usage_count() {
+ public function dcr_usage_count() {
$this->usage_count--;
update_post_meta( $this->id, 'usage_count', $this->usage_count );
}
+ /**
+ * Returns the error_message string
+ *
+ * @access public
+ * @return string
+ */
+ public function get_error_message() {
+ return $this->error_message;
+ }
+
/**
* is_valid function.
*
- * Check if a coupon is valid. Return a reason code if invaid. Reason codes:
+ * Check if a coupon is valid. Return a reason code if invalid. Reason codes:
*
* @access public
* @return bool|WP_Error validity or a WP_Error if not valid
*/
- function is_valid() {
+ public function is_valid() {
global $woocommerce;
- if ( $this->id ) {
+ $error_code = null;
+ $valid = true;
+ $error = false;
- $valid = true;
- $error = false;
+ if ( $this->id ) {
// Usage Limit
if ( $this->usage_limit > 0 ) {
if ( $this->usage_count >= $this->usage_limit ) {
$valid = false;
- $error = __( 'Coupon usage limit has been reached.', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_USAGE_LIMIT_REACHED;
}
}
@@ -229,7 +270,7 @@ class WC_Coupon {
if ( $this->expiry_date ) {
if ( current_time( 'timestamp' ) > $this->expiry_date ) {
$valid = false;
- $error = __( 'This coupon has expired.', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_EXPIRED;
}
}
@@ -237,7 +278,7 @@ class WC_Coupon {
if ( $this->minimum_amount > 0 ) {
if ( $this->minimum_amount > $woocommerce->cart->subtotal ) {
$valid = false;
- $error = sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), woocommerce_price( $this->minimum_amount ) );
+ $error_code = self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET;
}
}
@@ -253,7 +294,7 @@ class WC_Coupon {
}
if ( ! $valid_for_cart ) {
$valid = false;
- $error = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
}
}
@@ -271,7 +312,7 @@ class WC_Coupon {
}
if ( ! $valid_for_cart ) {
$valid = false;
- $error = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
}
}
@@ -290,7 +331,24 @@ class WC_Coupon {
}
if ( ! $valid_for_cart ) {
$valid = false;
- $error = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
+ }
+ }
+
+ // Exclude Sale Items
+ if ( $this->exclude_sale_items == 'yes' ) {
+ $valid_for_cart = true;
+ $product_ids_on_sale = woocommerce_get_product_ids_on_sale();
+ if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
+ foreach( $woocommerce->cart->get_cart() as $cart_item_key => $cart_item ) {
+ if ( in_array( $cart_item['product_id'], $product_ids_on_sale, true ) || in_array( $cart_item['variation_id'], $product_ids_on_sale, true ) || in_array( $cart_item['data']->get_parent(), $product_ids_on_sale, true ) ) {
+ $valid_for_cart = false;
+ }
+ }
+ }
+ if ( ! $valid_for_cart ) {
+ $valid = false;
+ $error_code = self::E_WC_COUPON_NOT_VALID_SALE_ITEMS;
}
}
@@ -308,20 +366,143 @@ class WC_Coupon {
}
if ( ! $valid_for_cart ) {
$valid = false;
- $error = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
}
}
}
$valid = apply_filters( 'woocommerce_coupon_is_valid', $valid, $this );
- if ( $valid )
+ if ( $valid ) {
return true;
+ } else {
+ $error_code = self::E_WC_COUPON_INVALID_FILTERED;
+ }
} else {
- $error = __( 'Invalid coupon', 'woocommerce' );
+ $error_code = self::E_WC_COUPON_NOT_EXIST;
}
- return new WP_Error( 'coupon_error', apply_filters( 'woocommerce_coupon_error', $error, $this ) );
+ if ( $error_code )
+ $this->error_message = $this->get_coupon_error( $error_code );
+
+ return false;
}
-}
\ No newline at end of file
+
+ /**
+ * Converts one of the WC_Coupon message/error codes to a message string and
+ * displays the message/error.
+ *
+ * @access public
+ * @param int $msg_code Message/error code.
+ * @return void
+ */
+ public function add_coupon_message( $msg_code ) {
+ global $woocommerce;
+
+ if ( $msg_code < 200 )
+ $woocommerce->add_error( $this->get_coupon_error( $msg_code ) );
+ else
+ $woocommerce->add_message( $this->get_coupon_message( $msg_code ) );
+ }
+
+ /**
+ * Map one of the WC_Coupon message codes to a message string
+ *
+ * @access public
+ * @param mixed $msg_code
+ * @return string| Message/error string
+ */
+ public function get_coupon_message( $msg_code ) {
+
+ switch ( $msg_code ) {
+ case self::WC_COUPON_SUCCESS:
+ $msg = __( 'Coupon code applied successfully.', 'woocommerce' );
+ break;
+ default:
+ $msg = '';
+ break;
+ }
+
+ return apply_filters( 'woocommerce_coupon_message', $msg, $msg_code, $this );
+ }
+
+ /**
+ * Map one of the WC_Coupon error codes to a message string
+ *
+ * @access public
+ * @param int $err_code Message/error code.
+ * @return string| Message/error string
+ */
+ public function get_coupon_error( $err_code ) {
+
+ switch ( $err_code ) {
+ case self::E_WC_COUPON_INVALID_FILTERED:
+ $err = __( 'Coupon is not valid.', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_NOT_EXIST:
+ $err = __( 'Coupon does not exist!', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_INVALID_REMOVED:
+ $err = sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), $this->code );
+ break;
+ case self::E_WC_COUPON_NOT_YOURS_REMOVED:
+ $err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), $this->code );
+ break;
+ case self::E_WC_COUPON_ALREADY_APPLIED:
+ $err = __( 'Coupon code already applied!', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY:
+ $err = sprintf( __( 'Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), $this->code );
+ break;
+ case self::E_WC_COUPON_USAGE_LIMIT_REACHED:
+ $err = __( 'Coupon usage limit has been reached.', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_EXPIRED:
+ $err = __( 'This coupon has expired.', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET:
+ $err = sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), woocommerce_price( $this->minimum_amount ) );
+ break;
+ case self::E_WC_COUPON_NOT_APPLICABLE:
+ $err = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_NOT_VALID_SALE_ITEMS:
+ $err = __( 'Sorry, this coupon is not valid for sale items.', 'woocommerce' );
+ break;
+ default:
+ $err = '';
+ break;
+ }
+
+ return apply_filters( 'woocommerce_coupon_error', $err, $err_code, $this );
+ }
+
+ /**
+ * Map one of the WC_Coupon error codes to an error string
+ * No coupon instance will be available where a coupon does not exist,
+ * so this static method exists.
+ *
+ * @access public
+ * @param int $err_code Error code
+ * @return string| Error string
+ */
+ public static function get_generic_coupon_error( $err_code ) {
+
+ switch ( $err_code ) {
+ case self::E_WC_COUPON_NOT_EXIST:
+ $err = __( 'Coupon does not exist!', 'woocommerce' );
+ break;
+ case self::E_WC_COUPON_PLEASE_ENTER:
+ $err = __( 'Please enter a coupon code.', 'woocommerce' );
+ break;
+ default:
+ $err = '';
+ break;
+ }
+
+ // When using this static method, there is no $this to pass to filter
+ return apply_filters( 'woocommerce_coupon_error', $err, $err_code, null );
+ }
+
+}
diff --git a/classes/class-wc-customer.php b/classes/class-wc-customer.php
index a42fea3d880..cc067dc7b72 100644
--- a/classes/class-wc-customer.php
+++ b/classes/class-wc-customer.php
@@ -7,6 +7,7 @@
* @class WC_Customer
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Customer {
@@ -14,13 +15,16 @@ class WC_Customer {
/** Stores customer data as an array */
protected $_data;
+ /** Stores bool when data is changed */
+ private $_changed = false;
+
/**
* Constructor for the customer class loads the customer data.
*
* @access public
* @return void
*/
- function __construct() {
+ public function __construct() {
global $woocommerce;
if ( empty( $woocommerce->session->customer ) ) {
@@ -31,7 +35,7 @@ class WC_Customer {
list( $country, $state ) = explode( ':', $default );
} else {
$country = $default;
- $state = '';
+ $state = '';
}
$this->_data = array(
@@ -52,13 +56,38 @@ class WC_Customer {
);
} else {
+
$this->_data = $woocommerce->session->customer;
+
}
// When leaving or ending page load, store data
- add_action( 'shutdown', array( &$this, 'save_data' ), 10 );
+ add_action( 'shutdown', array( $this, 'save_data' ), 10 );
}
+ /**
+ * save_data function.
+ *
+ * @access public
+ * @return void
+ */
+ public function save_data() {
+ if ( $this->_changed )
+ $GLOBALS['woocommerce']->session->customer = $this->_data;
+ }
+
+ /**
+ * __set function.
+ *
+ * @access public
+ * @param mixed $property
+ * @param mixed $value
+ * @return void
+ */
+ public function __isset( $property ) {
+ return isset( $this->_data[ $property ] );
+ }
+
/**
* __get function.
*
@@ -80,27 +109,17 @@ class WC_Customer {
*/
public function __set( $property, $value ) {
$this->_data[ $property ] = $value;
+ $this->_changed = true;
}
- /**
- * save_data function.
- *
- * @access public
- * @return void
- */
- function save_data() {
- global $woocommerce;
- $woocommerce->session->customer = $this->_data;
- }
-
/**
* has_calculated_shipping function.
*
* @access public
* @return bool
*/
- function has_calculated_shipping() {
- return ( ! empty( $this->_data['calculated_shipping'] ) && $this->_data['calculated_shipping'] ) ? true : false;
+ public function has_calculated_shipping() {
+ return ( ! empty( $this->calculated_shipping ) ) ? true : false;
}
@@ -110,7 +129,7 @@ class WC_Customer {
* @access public
* @return void
*/
- function set_to_base() {
+ public function set_to_base() {
global $woocommerce;
$default = apply_filters( 'woocommerce_customer_default_location', get_option('woocommerce_default_country') );
if ( strstr( $default, ':' ) ) {
@@ -119,10 +138,10 @@ class WC_Customer {
$country = $default;
$state = '';
}
- $this->_data['country'] = $country;
- $this->_data['state'] = $state;
- $this->_data['postcode'] = '';
- $this->_data['city'] = '';
+ $this->country = $country;
+ $this->state = $state;
+ $this->postcode = '';
+ $this->city = '';
}
@@ -132,7 +151,7 @@ class WC_Customer {
* @access public
* @return void
*/
- function set_shipping_to_base() {
+ public function set_shipping_to_base() {
global $woocommerce;
$default = get_option('woocommerce_default_country');
if ( strstr( $default, ':' ) ) {
@@ -141,10 +160,10 @@ class WC_Customer {
$country = $default;
$state = '';
}
- $this->_data['shipping_country'] = $country;
- $this->_data['shipping_state'] = $state;
- $this->_data['shipping_postcode'] = '';
- $this->_data['shipping_city'] = '';
+ $this->shipping_country = $country;
+ $this->shipping_state = $state;
+ $this->shipping_postcode = '';
+ $this->shipping_city = '';
}
@@ -154,7 +173,7 @@ class WC_Customer {
* @access public
* @return bool
*/
- function is_customer_outside_base() {
+ public function is_customer_outside_base() {
list( $country, $state, $postcode, $city ) = $this->get_taxable_address();
if ( $country ) {
@@ -182,8 +201,8 @@ class WC_Customer {
* @access public
* @return bool
*/
- function is_vat_exempt() {
- return ( isset( $this->_data['is_vat_exempt'] ) && $this->_data['is_vat_exempt'] ) ? true : false;
+ public function is_vat_exempt() {
+ return ( ! empty( $this->is_vat_exempt ) ) ? true : false;
}
@@ -193,8 +212,8 @@ class WC_Customer {
* @access public
* @return string
*/
- function get_state() {
- if ( isset( $this->_data['state'] ) ) return $this->_data['state'];
+ public function get_state() {
+ if ( isset( $this->state ) ) return $this->state;
}
@@ -204,8 +223,8 @@ class WC_Customer {
* @access public
* @return string
*/
- function get_country() {
- if ( isset( $this->_data['country'] ) ) return $this->_data['country'];
+ public function get_country() {
+ if ( isset( $this->country ) ) return $this->country;
}
@@ -215,10 +234,11 @@ class WC_Customer {
* @access public
* @return string
*/
- function get_postcode() {
+ public function get_postcode() {
global $woocommerce;
$validation = $woocommerce->validation();
- if (isset($this->_data['postcode']) && $this->_data['postcode'] !== false) return $validation->format_postcode( $this->_data['postcode'], $this->get_country());
+ if ( isset( $this->postcode ) && $this->postcode !== false )
+ return $validation->format_postcode( $this->postcode, $this->get_country() );
}
@@ -228,8 +248,8 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_city() {
- if ( isset( $this->_data['city'] ) ) return $this->_data['city'];
+ public function get_city() {
+ if ( isset( $this->city ) ) return $this->city;
}
/**
@@ -238,8 +258,8 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_address() {
- if ( isset( $this->_data['address'] ) ) return $this->_data['address'];
+ public function get_address() {
+ if ( isset( $this->address ) ) return $this->address;
}
/**
@@ -248,8 +268,8 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_address_2() {
- if ( isset( $this->_data['address_2'] ) ) return $this->_data['address_2'];
+ public function get_address_2() {
+ if ( isset( $this->address_2 ) ) return $this->address_2;
}
/**
@@ -258,8 +278,8 @@ class WC_Customer {
* @access public
* @return string
*/
- function get_shipping_state() {
- if ( isset( $this->_data['shipping_state'] ) ) return $this->_data['shipping_state'];
+ public function get_shipping_state() {
+ if ( isset( $this->shipping_state ) ) return $this->shipping_state;
}
@@ -269,8 +289,8 @@ class WC_Customer {
* @access public
* @return string
*/
- function get_shipping_country() {
- if ( isset( $this->_data['shipping_country'] ) ) return $this->_data['shipping_country'];
+ public function get_shipping_country() {
+ if ( isset( $this->shipping_country ) ) return $this->shipping_country;
}
@@ -280,10 +300,11 @@ class WC_Customer {
* @access public
* @return string
*/
- function get_shipping_postcode() {
+ public function get_shipping_postcode() {
global $woocommerce;
$validation = $woocommerce->validation();
- if (isset($this->_data['shipping_postcode'])) return $validation->format_postcode( $this->_data['shipping_postcode'], $this->get_shipping_country());
+ if ( isset( $this->shipping_postcode ) )
+ return $validation->format_postcode( $this->shipping_postcode, $this->get_shipping_country() );
}
@@ -293,8 +314,8 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_shipping_city() {
- if ( isset( $this->_data['shipping_city'] ) ) return $this->_data['shipping_city'];
+ public function get_shipping_city() {
+ if ( isset( $this->shipping_city ) ) return $this->shipping_city;
}
/**
@@ -303,8 +324,8 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_shipping_address() {
- if ( isset( $this->_data['shipping_address'] ) ) return $this->_data['shipping_address'];
+ public function get_shipping_address() {
+ if ( isset( $this->shipping_address ) ) return $this->shipping_address;
}
/**
@@ -313,8 +334,8 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_shipping_address_2() {
- if ( isset( $this->_data['shipping_address_2'] ) ) return $this->_data['shipping_address_2'];
+ public function get_shipping_address_2() {
+ if ( isset( $this->shipping_address_2 ) ) return $this->shipping_address_2;
}
/**
@@ -323,7 +344,7 @@ class WC_Customer {
* @access public
* @return void
*/
- function get_taxable_address() {
+ public function get_taxable_address() {
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
if ( $tax_based_on == 'base' ) {
@@ -369,11 +390,11 @@ class WC_Customer {
* @param string $city (default: '')
* @return void
*/
- function set_location( $country, $state, $postcode = '', $city = '' ) {
- $this->_data['country'] = $country;
- $this->_data['state'] = $state;
- $this->_data['postcode'] = $postcode;
- $this->_data['city'] = $city;
+ public function set_location( $country, $state, $postcode = '', $city = '' ) {
+ $this->country = $country;
+ $this->state = $state;
+ $this->postcode = $postcode;
+ $this->city = $city;
}
@@ -384,8 +405,8 @@ class WC_Customer {
* @param mixed $country
* @return void
*/
- function set_country( $country ) {
- $this->_data['country'] = $country;
+ public function set_country( $country ) {
+ $this->country = $country;
}
@@ -396,8 +417,8 @@ class WC_Customer {
* @param mixed $state
* @return void
*/
- function set_state( $state ) {
- $this->_data['state'] = $state;
+ public function set_state( $state ) {
+ $this->state = $state;
}
@@ -408,8 +429,8 @@ class WC_Customer {
* @param mixed $postcode
* @return void
*/
- function set_postcode( $postcode ) {
- $this->_data['postcode'] = $postcode;
+ public function set_postcode( $postcode ) {
+ $this->postcode = $postcode;
}
@@ -420,8 +441,8 @@ class WC_Customer {
* @param mixed $postcode
* @return void
*/
- function set_city( $city ) {
- $this->_data['city'] = $city;
+ public function set_city( $city ) {
+ $this->city = $city;
}
/**
@@ -431,8 +452,8 @@ class WC_Customer {
* @param mixed $address
* @return void
*/
- function set_address( $address ) {
- $this->_data['address'] = $address;
+ public function set_address( $address ) {
+ $this->address = $address;
}
/**
@@ -442,8 +463,8 @@ class WC_Customer {
* @param mixed $address_2
* @return void
*/
- function set_address_2( $address_2 ) {
- $this->_data['address_2'] = $address_2;
+ public function set_address_2( $address_2 ) {
+ $this->address_2 = $address_2;
}
/**
@@ -456,11 +477,11 @@ class WC_Customer {
* @param string $city (default: '')
* @return void
*/
- function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) {
- $this->_data['shipping_country'] = $country;
- $this->_data['shipping_state'] = $state;
- $this->_data['shipping_postcode'] = $postcode;
- $this->_data['shipping_city'] = $city;
+ public function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) {
+ $this->shipping_country = $country;
+ $this->shipping_state = $state;
+ $this->shipping_postcode = $postcode;
+ $this->shipping_city = $city;
}
@@ -471,8 +492,8 @@ class WC_Customer {
* @param mixed $country
* @return void
*/
- function set_shipping_country( $country ) {
- $this->_data['shipping_country'] = $country;
+ public function set_shipping_country( $country ) {
+ $this->shipping_country = $country;
}
@@ -483,8 +504,8 @@ class WC_Customer {
* @param mixed $state
* @return void
*/
- function set_shipping_state( $state ) {
- $this->_data['shipping_state'] = $state;
+ public function set_shipping_state( $state ) {
+ $this->shipping_state = $state;
}
@@ -495,8 +516,8 @@ class WC_Customer {
* @param mixed $postcode
* @return void
*/
- function set_shipping_postcode( $postcode ) {
- $this->_data['shipping_postcode'] = $postcode;
+ public function set_shipping_postcode( $postcode ) {
+ $this->shipping_postcode = $postcode;
}
@@ -507,8 +528,8 @@ class WC_Customer {
* @param mixed $postcode
* @return void
*/
- function set_shipping_city( $city ) {
- $this->_data['shipping_city'] = $city;
+ public function set_shipping_city( $city ) {
+ $this->shipping_city = $city;
}
/**
@@ -518,8 +539,8 @@ class WC_Customer {
* @param mixed $address
* @return void
*/
- function set_shipping_address( $address ) {
- $this->_data['shipping_address'] = $address;
+ public function set_shipping_address( $address ) {
+ $this->shipping_address = $address;
}
/**
@@ -529,8 +550,8 @@ class WC_Customer {
* @param mixed $address_2
* @return void
*/
- function set_shipping_address_2( $address_2 ) {
- $this->_data['shipping_address_2'] = $address_2;
+ public function set_shipping_address_2( $address_2 ) {
+ $this->shipping_address_2 = $address_2;
}
@@ -541,8 +562,8 @@ class WC_Customer {
* @param mixed $is_vat_exempt
* @return void
*/
- function set_is_vat_exempt( $is_vat_exempt ) {
- $this->_data['is_vat_exempt'] = $is_vat_exempt;
+ public function set_is_vat_exempt( $is_vat_exempt ) {
+ $this->is_vat_exempt = $is_vat_exempt;
}
@@ -553,8 +574,8 @@ class WC_Customer {
* @param mixed $calculated
* @return void
*/
- function calculated_shipping( $calculated = true ) {
- $this->_data['calculated_shipping'] = $calculated;
+ public function calculated_shipping( $calculated = true ) {
+ $this->calculated_shipping = $calculated;
}
@@ -564,7 +585,7 @@ class WC_Customer {
* @access public
* @return array Array of downloadable products
*/
- function get_downloadable_products() {
+ public function get_downloadable_products() {
global $wpdb, $woocommerce;
$downloads = array();
diff --git a/classes/emails/class-wc-emails.php b/classes/class-wc-emails.php
similarity index 86%
rename from classes/emails/class-wc-emails.php
rename to classes/class-wc-emails.php
index 6631f3f9331..a8d767be8fc 100644
--- a/classes/emails/class-wc-emails.php
+++ b/classes/class-wc-emails.php
@@ -7,6 +7,7 @@
* @class WC_Emails
* @version 2.0.0
* @package WooCommerce/Classes/Emails
+ * @category Class
* @author WooThemes
*/
class WC_Emails {
@@ -44,14 +45,14 @@ class WC_Emails {
function __construct() {
// Include email classes
- include_once( 'class-wc-email.php' );
- include_once( 'class-wc-email-customer-completed-order.php' );
- include_once( 'class-wc-email-customer-invoice.php' );
- include_once( 'class-wc-email-customer-new-account.php' );
- include_once( 'class-wc-email-customer-note.php' );
- include_once( 'class-wc-email-customer-reset-password.php' );
- include_once( 'class-wc-email-customer-processing-order.php' );
- include_once( 'class-wc-email-new-order.php' );
+ include_once( 'abstracts/abstract-wc-email.php' );
+ include_once( 'emails/class-wc-email-customer-completed-order.php' );
+ include_once( 'emails/class-wc-email-customer-invoice.php' );
+ include_once( 'emails/class-wc-email-customer-new-account.php' );
+ include_once( 'emails/class-wc-email-customer-note.php' );
+ include_once( 'emails/class-wc-email-customer-reset-password.php' );
+ include_once( 'emails/class-wc-email-customer-processing-order.php' );
+ include_once( 'emails/class-wc-email-new-order.php' );
$this->emails['WC_Email_New_Order'] = new WC_Email_New_Order();
$this->emails['WC_Email_Customer_Processing_Order'] = new WC_Email_Customer_Processing_Order();
@@ -64,14 +65,14 @@ class WC_Emails {
$this->emails = apply_filters( 'woocommerce_email_classes', $this->emails );
// Email Header, Footer and content hooks
- add_action( 'woocommerce_email_header', array( &$this, 'email_header' ) );
- add_action( 'woocommerce_email_footer', array( &$this, 'email_footer' ) );
- add_action( 'woocommerce_email_order_meta', array( &$this, 'order_meta' ), 10, 3 );
+ add_action( 'woocommerce_email_header', array( $this, 'email_header' ) );
+ add_action( 'woocommerce_email_footer', array( $this, 'email_footer' ) );
+ add_action( 'woocommerce_email_order_meta', array( $this, 'order_meta' ), 10, 3 );
// Hooks for sending emails during store events
- add_action( 'woocommerce_low_stock_notification', array( &$this, 'low_stock' ) );
- add_action( 'woocommerce_no_stock_notification', array( &$this, 'no_stock' ) );
- add_action( 'woocommerce_product_on_backorder_notification', array( &$this, 'backorder' ));
+ add_action( 'woocommerce_low_stock_notification', array( $this, 'low_stock' ) );
+ add_action( 'woocommerce_no_stock_notification', array( $this, 'no_stock' ) );
+ add_action( 'woocommerce_product_on_backorder_notification', array( $this, 'backorder' ));
// Let 3rd parties unhook the above via this hook
do_action( 'woocommerce_email', $this );
@@ -97,7 +98,7 @@ class WC_Emails {
if ( ! $this->_from_name )
$this->_from_name = get_option( 'woocommerce_email_from_name' );
- return $this->_from_name;
+ return wp_specialchars_decode( $this->_from_name );
}
/**
@@ -186,17 +187,17 @@ class WC_Emails {
$this->_content_type = $content_type;
// Filters for the email
- add_filter( 'wp_mail_from', array( &$this, 'get_from_address' ) );
- add_filter( 'wp_mail_from_name', array( &$this, 'get_from_name' ) );
- add_filter( 'wp_mail_content_type', array( &$this, 'get_content_type' ) );
+ add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
+ add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
+ add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
// Send
wp_mail( $to, $subject, $message, $headers, $attachments );
// Unhook filters
- remove_filter( 'wp_mail_from', array( &$this, 'get_from_address' ) );
- remove_filter( 'wp_mail_from_name', array( &$this, 'get_from_name' ) );
- remove_filter( 'wp_mail_content_type', array( &$this, 'get_content_type' ) );
+ remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
+ remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
+ remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
}
/**
diff --git a/classes/integrations/class-wc-integrations.php b/classes/class-wc-integrations.php
similarity index 71%
rename from classes/integrations/class-wc-integrations.php
rename to classes/class-wc-integrations.php
index 0969b3d8471..89a0ad02448 100644
--- a/classes/integrations/class-wc-integrations.php
+++ b/classes/class-wc-integrations.php
@@ -5,8 +5,9 @@
* Loads Integrations into WooCommerce.
*
* @class WC_Integrations
- * @version 1.6.4
+ * @version 2.0.0
* @package WooCommerce/Classes/Integrations
+ * @category Class
* @author WooThemes
*/
class WC_Integrations {
@@ -15,16 +16,16 @@ class WC_Integrations {
var $integrations = array();
/**
- * Load integration classes.
+ * __construct function.
*
* @access public
* @return void
*/
- function init() {
+ public function __construct() {
- do_action('woocommerce_integrations_init');
+ do_action( 'woocommerce_integrations_init' );
- $load_integrations = apply_filters('woocommerce_integrations', array() );
+ $load_integrations = apply_filters( 'woocommerce_integrations', array() );
// Load integration classes
foreach ( $load_integrations as $integration ) {
@@ -43,8 +44,7 @@ class WC_Integrations {
* @access public
* @return array
*/
- function get_integrations() {
+ public function get_integrations() {
return $this->integrations;
}
-
}
\ No newline at end of file
diff --git a/classes/class-wc-logger.php b/classes/class-wc-logger.php
index 7895ea267ab..9cc9d18e327 100644
--- a/classes/class-wc-logger.php
+++ b/classes/class-wc-logger.php
@@ -5,15 +5,16 @@
* @class WC_Logger
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Logger {
/**
- * @var array Stores open file handles.
+ * @var array Stores open file _handles.
* @access private
*/
- private $handles;
+ private $_handles;
/**
* Constructor for the logger.
@@ -21,8 +22,8 @@ class WC_Logger {
* @access public
* @return void
*/
- function __construct() {
- $this->handles = array();
+ public function __construct() {
+ $this->_handles = array();
}
@@ -32,8 +33,8 @@ class WC_Logger {
* @access public
* @return void
*/
- function __destruct() {
- foreach ( $this->handles as $handle )
+ public function __destruct() {
+ foreach ( $this->_handles as $handle )
@fclose( escapeshellarg( $handle ) );
}
@@ -48,10 +49,10 @@ class WC_Logger {
private function open( $handle ) {
global $woocommerce;
- if ( isset( $this->handles[ $handle ] ) )
+ if ( isset( $this->_handles[ $handle ] ) )
return true;
- if ( $this->handles[ $handle ] = @fopen( $woocommerce->plugin_path() . '/logs/' . $this->file_name( $handle ) . '.txt', 'a' ) )
+ if ( $this->_handles[ $handle ] = @fopen( $woocommerce->plugin_path() . '/logs/' . $this->file_name( $handle ) . '.txt', 'a' ) )
return true;
return false;
@@ -67,15 +68,15 @@ class WC_Logger {
* @return void
*/
public function add( $handle, $message ) {
- if ( $this->open( $handle ) ) {
+ if ( $this->open( $handle ) && is_resource( $this->_handles[ $handle ] ) ) {
$time = date_i18n( 'm-d-Y @ H:i:s -' ); //Grab Time
- fwrite( $this->handles[ $handle ], $time . " " . $message . "\n" );
+ @fwrite( $this->_handles[ $handle ], $time . " " . $message . "\n" );
}
}
/**
- * Clear entrys from chosen file.
+ * Clear entries from chosen file.
*
* @access public
* @param mixed $handle
@@ -83,8 +84,8 @@ class WC_Logger {
*/
public function clear( $handle ) {
- if ( $this->open( $handle ) )
- ftruncate( $this->handles[ $handle ], 0 );
+ if ( $this->open( $handle ) && is_resource( $this->_handles[ $handle ] ) )
+ @ftruncate( $this->_handles[ $handle ], 0 );
}
diff --git a/classes/class-wc-order-item-meta.php b/classes/class-wc-order-item-meta.php
new file mode 100644
index 00000000000..d6a1bfa4432
--- /dev/null
+++ b/classes/class-wc-order-item-meta.php
@@ -0,0 +1,81 @@
+meta = $item_meta;
+ }
+
+ /**
+ * Display meta in a formatted list
+ *
+ * @access public
+ * @param bool $flat (default: false)
+ * @param bool $return (default: false)
+ * @param string $hideprefix (default: _)
+ * @return void
+ */
+ public function display( $flat = false, $return = false, $hideprefix = '_' ) {
+ global $woocommerce;
+
+ if ( ! empty( $this->meta ) ) {
+
+ $output = $flat ? '' : '
';
+
+ $meta_list = array();
+
+ foreach ( $this->meta as $meta_key => $meta_values ) {
+
+ if ( empty( $meta_values ) || ( ! empty( $hideprefix ) && substr( $meta_key, 0, 1 ) == $hideprefix ) )
+ continue;
+
+ foreach( $meta_values as $meta_value ) {
+
+ // If this is a term slug, get the term's nice name
+ if ( taxonomy_exists( esc_attr( str_replace( 'attribute_', '', $meta_key ) ) ) ) {
+ $term = get_term_by('slug', $meta_value, esc_attr( str_replace( 'attribute_', '', $meta_key ) ) );
+ if ( ! is_wp_error( $term ) && $term->name )
+ $meta_value = $term->name;
+ }
+
+ if ( $flat )
+ $meta_list[] = esc_attr( $woocommerce->attribute_label( str_replace( 'attribute_', '', $meta_key ) ) . ': ' . $meta_value );
+ else
+ $meta_list[] = '' . wp_kses_post( $woocommerce->attribute_label( str_replace( 'attribute_', '', $meta_key ) ) ) . ': ' . wp_kses_post( $meta_value ) . ' ';
+
+ }
+ }
+
+ if ( $flat )
+ $output .= implode( ", \n", $meta_list );
+ else
+ $output .= implode( '', $meta_list );
+
+ if ( ! $flat )
+ $output .= ' ';
+
+ if ( $return )
+ return $output;
+ else
+ echo $output;
+ }
+ }
+}
\ No newline at end of file
diff --git a/classes/class-wc-order.php b/classes/class-wc-order.php
index 4df558d8370..e7efbfb482b 100644
--- a/classes/class-wc-order.php
+++ b/classes/class-wc-order.php
@@ -7,150 +7,148 @@
* @class WC_Order
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Order {
- /** @var int Order (post) ID */
- var $id;
+ /** @public int Order (post) ID */
+ public $id;
- /** @var string Order status. */
- var $status;
+ /** @public string Order status. */
+ public $status;
- /** @var string Order date (placed). */
- var $order_date;
+ /** @public string Order date (placed). */
+ public $order_date;
- /** @var string Order date (paid). */
- var $modified_date;
+ /** @public string Order date (paid). */
+ public $modified_date;
- /** @var string Note added by the customer. */
- var $customer_note;
+ /** @public string Note added by the customer. */
+ public $customer_note;
- /** @var array Order (post) meta/custom fields. */
- var $order_custom_fields;
+ /** @public array Order (post) meta/custom fields. */
+ public $order_custom_fields;
- /** @var string Order unique key. */
- var $order_key;
+ /** @public string Order unique key. */
+ public $order_key;
- /** @var string */
- var $billing_first_name;
+ /** @public string */
+ public $billing_first_name;
- /** @var string */
- var $billing_last_name;
+ /** @public string */
+ public $billing_last_name;
- /** @var string */
- var $billing_company;
+ /** @public string */
+ public $billing_company;
- /** @var string */
- var $billing_address_1;
+ /** @public string */
+ public $billing_address_1;
- /** @var string */
- var $billing_address_2;
+ /** @public string */
+ public $billing_address_2;
- /** @var string */
- var $billing_city;
+ /** @public string */
+ public $billing_city;
- /** @var string */
- var $billing_postcode;
+ /** @public string */
+ public $billing_postcode;
- /** @var string */
- var $billing_country;
+ /** @public string */
+ public $billing_country;
- /** @var string */
- var $billing_state;
+ /** @public string */
+ public $billing_state;
- /** @var string */
- var $billing_email;
+ /** @public string */
+ public $billing_email;
- /** @var string */
- var $billing_phone;
+ /** @public string */
+ public $billing_phone;
- /** @var string */
- var $shipping_first_name;
+ /** @public string */
+ public $shipping_first_name;
- /** @var string */
- var $shipping_last_name;
+ /** @public string */
+ public $shipping_last_name;
- /** @var string */
- var $shipping_company;
+ /** @public string */
+ public $shipping_company;
- /** @var string */
- var $shipping_address_1;
+ /** @public string */
+ public $shipping_address_1;
- /** @var string */
- var $shipping_address_2;
+ /** @public string */
+ public $shipping_address_2;
- /** @var string */
- var $shipping_city;
+ /** @public string */
+ public $shipping_city;
- /** @var string */
- var $shipping_postcode;
+ /** @public string */
+ public $shipping_postcode;
- /** @var string */
- var $shipping_country;
+ /** @public string */
+ public $shipping_country;
- /** @var string */
- var $shipping_state;
+ /** @public string */
+ public $shipping_state;
- /** @var string Method id of the shipping used */
- var $shipping_method;
+ /** @public string Method id of the shipping used */
+ public $shipping_method;
- /** @var string Shipping method title */
- var $shipping_method_title;
+ /** @public string Shipping method title */
+ public $shipping_method_title;
- /** @var string Method id of the payment used */
- var $payment_method;
+ /** @public string Method id of the payment used */
+ public $payment_method;
- /** @var string Payment method title */
- var $payment_method_title;
+ /** @public string Payment method title */
+ public $payment_method_title;
- /** @var string After tax discount total */
- var $order_discount;
+ /** @public string After tax discount total */
+ public $order_discount;
- /** @var string Refund total */
- var $refund_total;
+ /** @public string Before tax discount total */
+ public $cart_discount;
- /** @var string Before tax discount total */
- var $cart_discount;
+ /** @public string Tax for the items total */
+ public $order_tax;
- /** @var string Tax for the items total */
- var $order_tax;
+ /** @public string Shipping cost */
+ public $order_shipping;
- /** @var string Shipping cost */
- var $order_shipping;
+ /** @public string Shipping tax */
+ public $order_shipping_tax;
- /** @var string Shipping tax */
- var $order_shipping_tax;
+ /** @public string Grand total */
+ public $order_total;
- /** @var string Grand total */
- var $order_total;
+ /** @public array Taxes array (tax rows) */
+ public $taxes;
- /** @var array Taxes array (tax rows) */
- var $taxes;
+ /** @public int User ID */
+ public $customer_user;
- /** @var int User ID */
- var $customer_user;
+ /** @public int User ID */
+ public $user_id;
- /** @var int User ID */
- var $user_id;
+ /** @public string */
+ public $completed_date;
- /** @var string */
- var $completed_date;
+ /** @public string */
+ public $billing_address;
- /** @var string */
- var $billing_address;
+ /** @public string */
+ public $formatted_billing_address;
- /** @var string */
- var $formatted_billing_address;
+ /** @public string */
+ public $shipping_address;
- /** @var string */
- var $shipping_address;
+ /** @public string */
+ public $formatted_shipping_address;
- /** @var string */
- var $formatted_shipping_address;
-
- /** @var string */
- var $post_status;
+ /** @public string */
+ public $post_status;
/**
* Get the order if ID is passed, otherwise the order is new and empty.
@@ -159,7 +157,7 @@ class WC_Order {
* @param string $id (default: '')
* @return void
*/
- function __construct( $id = '' ) {
+ public function __construct( $id = '' ) {
$this->prices_include_tax = get_option('woocommerce_prices_include_tax') == 'yes' ? true : false;
$this->tax_display_cart = get_option( 'woocommerce_tax_display_cart' );
@@ -178,7 +176,7 @@ class WC_Order {
* @param int $id (default: 0)
* @return bool
*/
- function get_order( $id = 0 ) {
+ public function get_order( $id = 0 ) {
if ( ! $id )
return false;
if ( $result = get_post( $id ) ) {
@@ -196,14 +194,14 @@ class WC_Order {
* @param mixed $result
* @return void
*/
- function populate( $result ) {
+ public function populate( $result ) {
// Standard post data
$this->id = $result->ID;
$this->order_date = $result->post_date;
$this->modified_date = $result->post_modified;
$this->customer_note = $result->post_excerpt;
$this->post_status = $result->post_status;
- $this->order_custom_fields = get_post_custom( $this->id );
+ $this->order_custom_fields = get_post_meta( $this->id );
// Define the data we're going to load: Key => Default value
$load_data = apply_filters( 'woocommerce_load_order_data', array(
@@ -233,7 +231,6 @@ class WC_Order {
'payment_method' => '',
'payment_method_title' => '',
'order_discount' => '',
- 'refund_total' => '',
'cart_discount' => '',
'order_tax' => '',
'order_shipping' => '',
@@ -268,7 +265,7 @@ class WC_Order {
* @param mixed $key
* @return bool
*/
- function key_is_valid( $key ) {
+ public function key_is_valid( $key ) {
if ( $key == $this->order_key ) return true;
return false;
}
@@ -282,7 +279,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_order_number() {
+ public function get_order_number() {
return apply_filters( 'woocommerce_order_number', _x( '#', 'hash before order number', 'woocommerce' ) . $this->id, $this );
}
@@ -292,7 +289,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_formatted_billing_address() {
+ public function get_formatted_billing_address() {
if ( ! $this->formatted_billing_address ) {
global $woocommerce;
@@ -320,7 +317,7 @@ class WC_Order {
* @access public
* @return array
*/
- function get_billing_address() {
+ public function get_billing_address() {
if ( ! $this->billing_address ) {
// Formatted Addresses
$address = array(
@@ -344,7 +341,7 @@ class WC_Order {
* @access public
* @return void
*/
- function get_formatted_shipping_address() {
+ public function get_formatted_shipping_address() {
if ( ! $this->formatted_shipping_address ) {
if ( $this->shipping_address_1 ) {
global $woocommerce;
@@ -375,7 +372,7 @@ class WC_Order {
* @access public
* @return array
*/
- function get_shipping_address() {
+ public function get_shipping_address() {
if ( ! $this->shipping_address ) {
if ( $this->shipping_address_1 ) {
// Formatted Addresses
@@ -402,15 +399,14 @@ class WC_Order {
* @param string $type Types of line items to get (array or string)
* @return void
*/
- function get_items( $type = '' ) {
+ public function get_items( $type = '' ) {
global $wpdb, $woocommerce;
if ( empty( $type ) )
$type = array( 'line_item' );
- if ( ! is_array( $type ) ) {
+ if ( ! is_array( $type ) )
$type = array( $type );
- }
$type = array_map( 'esc_attr', $type );
@@ -437,7 +433,37 @@ class WC_Order {
$items[ $item->order_item_id ][ $key ] = $value[0];
}
}
- return $items;
+
+ return apply_filters( 'woocommerce_order_get_items', $items, $this );
+ }
+
+ /**
+ * Gets order total - formatted for display.
+ *
+ * @access public
+ * @return string
+ */
+ public function get_item_count( $type = '' ) {
+ global $wpdb, $woocommerce;
+
+ if ( empty( $type ) )
+ $type = array( 'line_item' );
+
+ if ( ! is_array( $type ) )
+ $type = array( $type );
+
+ $items = $this->get_items( $type );
+
+ $count = 0;
+
+ foreach ( $items as $item ) {
+ if ( ! empty( $item['qty'] ) )
+ $count += $item['qty'];
+ else
+ $count ++;
+ }
+
+ return apply_filters( 'woocommerce_get_item_count', $count, $type, $this );
}
/**
@@ -446,7 +472,7 @@ class WC_Order {
* @access public
* @return array
*/
- function get_fees() {
+ public function get_fees() {
return $this->get_items( 'fee' );
}
@@ -456,7 +482,7 @@ class WC_Order {
* @access public
* @return void
*/
- function get_taxes() {
+ public function get_taxes() {
return $this->get_items( 'tax' );
}
@@ -466,7 +492,7 @@ class WC_Order {
* @access public
* @return array of meta data
*/
- function has_meta( $order_item_id ) {
+ public function has_meta( $order_item_id ) {
global $wpdb;
return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, order_item_id
@@ -483,7 +509,7 @@ class WC_Order {
* @param bool $single (default: false)
* @return void
*/
- function get_item_meta( $order_item_id, $key = '', $single = false ) {
+ public function get_item_meta( $order_item_id, $key = '', $single = false ) {
return get_metadata( 'order_item', $order_item_id, $key, $single );
}
@@ -496,7 +522,7 @@ class WC_Order {
* @access public
* @return float
*/
- function get_total_tax() {
+ public function get_total_tax() {
return apply_filters( 'woocommerce_order_amount_total_tax', number_format( (double) $this->order_tax + (double) $this->order_shipping_tax, 2, '.', '' ) );
}
@@ -507,7 +533,7 @@ class WC_Order {
* @access public
* @return float
*/
- function get_cart_discount() {
+ public function get_cart_discount() {
return apply_filters( 'woocommerce_order_amount_cart_discount', number_format( (double) $this->cart_discount, 2, '.', '' ) );
}
@@ -518,29 +544,18 @@ class WC_Order {
* @access public
* @return float
*/
- function get_order_discount() {
+ public function get_order_discount() {
return apply_filters( 'woocommerce_order_amount_order_discount', number_format( (double) $this->order_discount, 2, '.', '' ) );
}
- /**
- * Gets the total refund amount
- *
- * @access public
- * @return float
- */
- function get_refund_total() {
- return apply_filters( 'woocommerce_order_refund_total', number_format( (double) $this->refund_total, 2, '.', '' ) );
- }
-
-
/**
* Gets the total discount amount - both kinds
*
* @access public
* @return float
*/
- function get_total_discount() {
+ public function get_total_discount() {
if ( $this->order_discount || $this->cart_discount )
return apply_filters( 'woocommerce_order_amount_total_discount', number_format( (double) $this->order_discount + (double) $this->cart_discount, 2, '.', '' ) );
}
@@ -552,7 +567,7 @@ class WC_Order {
* @access public
* @return float
*/
- function get_shipping() {
+ public function get_shipping() {
return apply_filters( 'woocommerce_order_amount_shipping', number_format( (double) $this->order_shipping, 2, '.', '' ) );
}
@@ -563,7 +578,7 @@ class WC_Order {
* @access public
* @return float
*/
- function get_shipping_tax() {
+ public function get_shipping_tax() {
return apply_filters( 'woocommerce_order_amount_shipping_tax', number_format( (double) $this->order_shipping_tax, 2, '.', '' ) );
}
@@ -574,7 +589,7 @@ class WC_Order {
* @access public
* @return float
*/
- function get_total() {
+ public function get_total() {
return apply_filters( 'woocommerce_order_amount_total', number_format( (double) $this->order_total, 2, '.', '' ) );
}
@@ -585,7 +600,7 @@ class WC_Order {
* @access public
* @return void
*/
- function get_order_total() {
+ public function get_order_total() {
return $this->get_total();
}
@@ -595,7 +610,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_shipping_method() {
+ public function get_shipping_method() {
return apply_filters( 'woocommerce_order_shipping_method', ucwords( $this->shipping_method_title ) );
}
@@ -609,7 +624,7 @@ class WC_Order {
* @param bool $round (default: true)
* @return float
*/
- function get_item_subtotal( $item, $inc_tax = false, $round = true ) {
+ public function get_item_subtotal( $item, $inc_tax = false, $round = true ) {
if ( $inc_tax )
$price = ( $item['line_subtotal'] + $item['line_subtotal_tax'] / $item['qty'] );
else
@@ -627,7 +642,7 @@ class WC_Order {
* @param bool $round (default: true)
* @return float
*/
- function get_line_subtotal( $item, $inc_tax = false, $round = true ) {
+ public function get_line_subtotal( $item, $inc_tax = false, $round = true ) {
if ( $inc_tax )
$price = $item['line_subtotal'] + $item['line_subtotal_tax'];
else
@@ -645,7 +660,7 @@ class WC_Order {
* @param bool $round (default: true)
* @return float
*/
- function get_item_total( $item, $inc_tax = false, $round = true ) {
+ public function get_item_total( $item, $inc_tax = false, $round = true ) {
if ( $inc_tax )
$price = ( ( $item['line_total'] + $item['line_tax'] ) / $item['qty'] );
else
@@ -662,7 +677,7 @@ class WC_Order {
* @param bool $round (default: true)
* @return float
*/
- function get_item_tax( $item, $round = true ) {
+ public function get_item_tax( $item, $round = true ) {
$price = $item['line_tax'] / $item['qty'];
return apply_filters( 'woocommerce_order_amount_item_tax', ($round) ? number_format( $price, 2, '.', '') : $price );
}
@@ -676,7 +691,7 @@ class WC_Order {
* @param bool $inc_tax (default: false)
* @return float
*/
- function get_line_total( $item, $inc_tax = false ) {
+ public function get_line_total( $item, $inc_tax = false ) {
if ( $inc_tax )
return apply_filters( 'woocommerce_order_amount_line_total', number_format( $item['line_total'] + $item['line_tax'] , 2, '.', '') );
else
@@ -691,7 +706,7 @@ class WC_Order {
* @param mixed $item
* @return float
*/
- function get_line_tax( $item ) {
+ public function get_line_tax( $item ) {
return apply_filters( 'woocommerce_order_amount_line_tax', number_format( $item['line_tax'], 2, '.', '') );
}
@@ -704,12 +719,16 @@ class WC_Order {
* @param mixed $item
* @return string
*/
- function get_formatted_line_subtotal( $item ) {
+ public function get_formatted_line_subtotal( $item, $tax_display = '' ) {
+
+ if ( ! $tax_display )
+ $tax_display = $this->tax_display_cart;
+
$subtotal = 0;
if (!isset($item['line_subtotal']) || !isset($item['line_subtotal_tax'])) return;
- if ( $this->tax_display_cart == 'excl' ) {
+ if ( $tax_display == 'excl' ) {
if ( $this->prices_include_tax ) $ex_tax_label = 1; else $ex_tax_label = 0;
$subtotal = woocommerce_price( $this->get_line_subtotal( $item ), array( 'ex_tax_label' => $ex_tax_label ) );
} else {
@@ -726,7 +745,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_formatted_order_total() {
+ public function get_formatted_order_total() {
$formatted_total = woocommerce_price( $this->order_total );
@@ -741,9 +760,12 @@ class WC_Order {
* @param bool $compound (default: false)
* @return string
*/
- function get_subtotal_to_display( $compound = false ) {
+ public function get_subtotal_to_display( $compound = false, $tax_display = '' ) {
global $woocommerce;
+ if ( ! $tax_display )
+ $tax_display = $this->tax_display_cart;
+
$subtotal = 0;
if ( ! $compound ) {
@@ -754,7 +776,7 @@ class WC_Order {
$subtotal += $this->get_line_subtotal( $item );
- if ( $this->tax_display_cart == 'incl' ) {
+ if ( $tax_display == 'incl' ) {
$subtotal += $item['line_subtotal_tax'];
}
@@ -762,12 +784,12 @@ class WC_Order {
$subtotal = woocommerce_price( $subtotal );
- if ( $this->tax_display_cart == 'excl' && $this->prices_include_tax )
- $subtotal .= '
'.$woocommerce->countries->ex_tax_or_vat().' ';
+ if ( $tax_display == 'excl' && $this->prices_include_tax )
+ $subtotal .= '
' . $woocommerce->countries->ex_tax_or_vat() . ' ';
} else {
- if ( $this->tax_display_cart == 'incl' )
+ if ( $tax_display == 'incl' )
return;
foreach ( $this->get_items() as $item ) {
@@ -805,14 +827,17 @@ class WC_Order {
* @access public
* @return string
*/
- function get_shipping_to_display() {
+ public function get_shipping_to_display( $tax_display = '' ) {
global $woocommerce;
+ if ( ! $tax_display )
+ $tax_display = $this->tax_display_cart;
+
if ( $this->order_shipping > 0 ) {
$tax_text = '';
- if ( $this->tax_display_cart == 'excl' ) {
+ if ( $tax_display == 'excl' ) {
// Show shipping excluding tax
$shipping = woocommerce_price( $this->order_shipping );
@@ -848,7 +873,7 @@ class WC_Order {
* @access public
* @return string.
*/
- function get_cart_discount_to_display() {
+ public function get_cart_discount_to_display() {
return apply_filters( 'woocommerce_order_cart_discount_to_display', woocommerce_price( $this->get_cart_discount() ), $this );
}
@@ -859,7 +884,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_order_discount_to_display() {
+ public function get_order_discount_to_display() {
return apply_filters( 'woocommerce_order_discount_to_display', woocommerce_price( $this->get_order_discount() ), $this );
}
@@ -871,11 +896,10 @@ class WC_Order {
* @param mixed $item
* @return WC_Product
*/
- function get_product_from_item( $item ) {
+ public function get_product_from_item( $item ) {
$_product = get_product( $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );
return $_product;
-
}
@@ -885,9 +909,12 @@ class WC_Order {
* @access public
* @return array
*/
- function get_order_item_totals() {
+ public function get_order_item_totals( $tax_display = '' ) {
global $woocommerce;
+ if ( ! $tax_display )
+ $tax_display = $this->tax_display_cart;
+
$total_rows = array();
if ( $subtotal = $this->get_subtotal_to_display() )
@@ -911,7 +938,7 @@ class WC_Order {
if ( $fees = $this->get_fees() )
foreach( $fees as $id => $fee ) {
- if ( $this->tax_display_cart == 'excl' ) {
+ if ( $tax_display == 'excl' ) {
$total_rows[ 'fee_' . $id ] = array(
'label' => $fee['name'],
@@ -929,7 +956,7 @@ class WC_Order {
}
// Tax for tax exclusive prices
- if ( $this->tax_display_cart == 'excl' ) {
+ if ( $tax_display == 'excl' ) {
if ( sizeof( $this->get_taxes() ) > 0 ) {
$has_compound_tax = false;
@@ -984,15 +1011,8 @@ class WC_Order {
'value' => $this->get_formatted_order_total()
);
- if ( $refund_total = $this->get_refund_total() ) {
- $total_rows['order_refund_total'] = array(
- 'label' => __( 'Refund total:', 'woocommerce' ),
- 'value' => '-' . $refund_total,
- );
- }
-
// Tax for inclusive prices
- if ( $this->tax_display_cart == 'incl' ) {
+ if ( $tax_display == 'incl' ) {
$tax_string_array = array();
@@ -1000,7 +1020,7 @@ class WC_Order {
foreach ( $this->get_taxes() as $tax ) {
- $tax_string_array[] = sprintf( '%s %s', woocommerce_price( ( $tax[ 'tax_amount' ] + $tax[ 'shipping_tax_amount' ] ) ), $tax[ 'name' ] );
+ $tax_string_array[] = sprintf( '%s %s', woocommerce_price( ( $tax[ 'tax_amount' ] + $tax[ 'shipping_tax_amount' ] ) ), isset( $tax[ 'label' ] ) ? $tax[ 'label' ] : $tax[ 'name' ] );
}
} elseif ( $this->get_total_tax() > 0 ) {
@@ -1009,7 +1029,8 @@ class WC_Order {
}
- $total_rows['order_total']['value'] .= ' ' . sprintf( __( '(Includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) );
+ if ( ! empty( $tax_string_array ) )
+ $total_rows['order_total']['value'] .= ' ' . sprintf( __( '(Includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) );
}
return apply_filters( 'woocommerce_get_order_item_totals', $total_rows, $this );
@@ -1028,7 +1049,7 @@ class WC_Order {
* @param bool plain text
* @return string
*/
- function email_order_items_table( $show_download_links = false, $show_sku = false, $show_purchase_note = false, $show_image = false, $image_size = array( 32, 32 ), $plain_text = false ) {
+ public function email_order_items_table( $show_download_links = false, $show_sku = false, $show_purchase_note = false, $show_image = false, $image_size = array( 32, 32 ), $plain_text = false ) {
ob_start();
@@ -1055,7 +1076,7 @@ class WC_Order {
* @access public
* @return bool
*/
- function is_download_permitted() {
+ public function is_download_permitted() {
return apply_filters( 'woocommerce_order_is_download_permitted', $this->status == 'completed' || ( get_option( 'woocommerce_downloads_grant_access_after_payment' ) == 'yes' && $this->status == 'processing' ), $this );
}
@@ -1065,7 +1086,7 @@ class WC_Order {
* @access public
* @return bool
*/
- function has_downloadable_item() {
+ public function has_downloadable_item() {
$has_downloadable_item = false;
foreach($this->get_items() as $item) :
@@ -1088,7 +1109,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_checkout_payment_url() {
+ public function get_checkout_payment_url() {
$payment_page = get_permalink(woocommerce_get_page_id('pay'));
@@ -1104,7 +1125,7 @@ class WC_Order {
* @access public
* @return string
*/
- function get_cancel_order_url() {
+ public function get_cancel_order_url() {
global $woocommerce;
return apply_filters('woocommerce_get_cancel_order_url', $woocommerce->nonce_url( 'cancel_order', add_query_arg('cancel_order', 'true', add_query_arg('order', $this->order_key, add_query_arg('order_id', $this->id, trailingslashit( home_url() ))))));
}
@@ -1119,7 +1140,7 @@ class WC_Order {
* @param array $item the item
* @return array available downloadable file urls
*/
- function get_downloadable_file_urls( $product_id, $variation_id, $item ) {
+ public function get_downloadable_file_urls( $product_id, $variation_id, $item ) {
global $wpdb;
$download_file = $variation_id > 0 ? $variation_id : $product_id;
@@ -1138,7 +1159,9 @@ class WC_Order {
$file_urls = array();
foreach ( $results as $result ) {
if ( $_product->has_file( $result->download_id ) ) {
- $file_urls[] = 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 ) ] = add_query_arg( array( 'download_file' => $download_file, 'order' => $this->order_key, 'email' => $user_email, 'key' => $result->download_id ), trailingslashit( home_url() ) );
+
}
}
@@ -1153,7 +1176,7 @@ class WC_Order {
* @param int $is_customer_note (default: 0) Is this a note for the customer?
* @return id Comment ID
*/
- function add_order_note( $note, $is_customer_note = 0 ) {
+ public function add_order_note( $note, $is_customer_note = 0 ) {
$is_customer_note = intval( $is_customer_note );
@@ -1190,7 +1213,7 @@ class WC_Order {
* @param string $note (default: '') Optional note to add
* @return void
*/
- function update_status( $new_status_slug, $note = '' ) {
+ public function update_status( $new_status_slug, $note = '' ) {
if ( $note )
$note .= ' ';
@@ -1209,7 +1232,8 @@ class WC_Order {
do_action( 'woocommerce_order_status_' . $this->status . '_to_' . $new_status->slug, $this->id );
do_action( 'woocommerce_order_status_changed', $this->id, $this->status, $new_status->slug );
- $this->add_order_note( $note . sprintf( __( 'Order status changed from %s to %s.', 'woocommerce' ), __( $old_status->name, 'woocommerce' ), __( $new_status->name, 'woocommerce' ) ) );
+ if ( $old_status )
+ $this->add_order_note( $note . sprintf( __( 'Order status changed from %s to %s.', 'woocommerce' ), __( $old_status->name, 'woocommerce' ), __( $new_status->name, 'woocommerce' ) ) );
// Record the completed date of the order
if ( $new_status->slug == 'completed' )
@@ -1244,7 +1268,7 @@ class WC_Order {
* @param string $note (default: '') Optional note to add
* @return void
*/
- function cancel_order( $note = '' ) {
+ public function cancel_order( $note = '' ) {
global $woocommerce;
unset( $woocommerce->session->order_awaiting_payment );
@@ -1253,29 +1277,6 @@ class WC_Order {
}
- /**
- * refund_order function.
- *
- * @access public
- * @param bool $use_gateway (default: false)
- * @return void
- */
- function refund_order( $use_gateway = false ) {
-
- }
-
- /**
- * refund_line_item function.
- *
- * @access public
- * @param mixed $item_id
- * @param bool $use_gateway (default: false)
- * @return void
- */
- function refund_line_item( $item_id, $use_gateway = false ) {
-
- }
-
/**
* When a payment is complete this function is called
*
@@ -1288,12 +1289,13 @@ class WC_Order {
* @access public
* @return void
*/
- function payment_complete() {
+ public function payment_complete() {
global $woocommerce;
- unset( $woocommerce->session->order_awaiting_payment );
+ if ( ! empty( $woocommerce->session->order_awaiting_payment ) )
+ unset( $woocommerce->session->order_awaiting_payment );
- if ( $this->status == 'on-hold' || $this->status == 'pending' || $this->status == 'failed' ) {
+ if ( $this->id && ( $this->status == 'on-hold' || $this->status == 'pending' || $this->status == 'failed' ) ) {
$order_needs_processing = true;
@@ -1331,7 +1333,8 @@ class WC_Order {
);
wp_update_post( $this_order );
- $this->reduce_order_stock(); // Payment is complete so reduce stock levels
+ if ( apply_filters( 'woocommerce_payment_complete_reduce_order_stock', true, $this->id ) )
+ $this->reduce_order_stock(); // Payment is complete so reduce stock levels
do_action( 'woocommerce_payment_complete', $this->id );
}
@@ -1344,7 +1347,7 @@ class WC_Order {
* @access public
* @return void
*/
- function record_product_sales() {
+ public function record_product_sales() {
if ( get_post_meta( $this->id, '_recorded_sales', true ) == 'yes' )
return;
@@ -1370,7 +1373,7 @@ class WC_Order {
* @access public
* @return array
*/
- function get_used_coupons() {
+ public function get_used_coupons() {
$codes = array();
$coupons = $this->get_items( 'coupon' );
@@ -1389,7 +1392,7 @@ class WC_Order {
* @access public
* @return void
*/
- function increase_coupon_usage_counts() {
+ public function increase_coupon_usage_counts() {
global $woocommerce;
if ( get_post_meta( $this->id, '_recorded_coupon_usage_counts', true ) == 'yes' )
@@ -1400,7 +1403,7 @@ class WC_Order {
if ( ! $code )
continue;
- $coupon = $woocommerce->coupon( $code );
+ $coupon = new WC_Coupon( $code );
$coupon->inc_usage_count();
}
}
@@ -1415,7 +1418,7 @@ class WC_Order {
* @access public
* @return void
*/
- function decrease_coupon_usage_counts() {
+ public function decrease_coupon_usage_counts() {
global $woocommerce;
if ( get_post_meta( $this->id, '_recorded_coupon_usage_counts', true ) != 'yes' )
@@ -1426,7 +1429,7 @@ class WC_Order {
if ( ! $code )
continue;
- $coupon = $woocommerce->coupon( $code );
+ $coupon = new WC_Coupon( $code );
$coupon->dcr_usage_count();
}
}
@@ -1441,7 +1444,7 @@ class WC_Order {
* @access public
* @return void
*/
- function reduce_order_stock() {
+ public function reduce_order_stock() {
if ( get_option('woocommerce_manage_stock') == 'yes' && sizeof( $this->get_items() ) > 0 ) {
@@ -1455,7 +1458,9 @@ class WC_Order {
$old_stock = $_product->stock;
- $new_quantity = $_product->reduce_stock( $item['qty'] );
+ $qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $this, $item );
+
+ $new_quantity = $_product->reduce_stock( $qty );
$this->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $item['product_id'], $old_stock, $new_quantity) );
@@ -1484,7 +1489,7 @@ class WC_Order {
* @param int $qty_ordered
* @return void
*/
- function send_stock_notifications( $product, $new_stock, $qty_ordered ) {
+ public function send_stock_notifications( $product, $new_stock, $qty_ordered ) {
// Backorders
if ( $new_stock < 0 )
@@ -1511,7 +1516,7 @@ class WC_Order {
* @access public
* @return array
*/
- function get_customer_order_notes() {
+ public function get_customer_order_notes() {
$notes = array();
@@ -1539,87 +1544,3 @@ class WC_Order {
}
}
-
-
-/**
- * Order Item Meta
- *
- * A Simple class for managing order item meta so plugins add it in the correct format
- *
- * @class order_item_meta
- * @version 1.6.4
- * @package WooCommerce/Classes
- * @author WooThemes
- */
-class WC_Order_Item_Meta {
-
- var $meta;
-
- /**
- * Constructor
- *
- * @access public
- * @param string $item_meta (default: '')
- * @return void
- */
- function __construct( $item_meta = array() ) {
- $this->meta = $item_meta;
- }
-
- /**
- * Display meta in a formatted list
- *
- * @access public
- * @param bool $flat (default: false)
- * @param bool $return (default: false)
- * @param string $hideprefix (default: _)
- * @return void
- */
- function display( $flat = false, $return = false, $hideprefix = '_' ) {
- global $woocommerce;
-
- if ( ! empty( $this->meta ) ) {
-
- $output = $flat ? '' : '
';
-
- $meta_list = array();
-
- foreach ( $this->meta as $meta_key => $meta_value ) {
-
- if ( ! $meta_value || ( ! empty( $hideprefix ) && substr( $meta_key, 0, 1 ) == $hideprefix ) )
- continue;
-
- // Get first value
- $meta_value = $meta_value[0];
-
- // If this is a term slug, get the term's nice name
- if ( taxonomy_exists( esc_attr( str_replace( 'attribute_', '', $meta_key ) ) ) ) {
- $term = get_term_by('slug', $meta_value, esc_attr( str_replace( 'attribute_', '', $meta_key ) ) );
- if ( ! is_wp_error( $term ) && $term->name )
- $meta_value = $term->name;
- } else {
- $meta_value = ucfirst( $meta_value );
- }
-
- if ( $flat )
- $meta_list[] = esc_attr( $woocommerce->attribute_label( str_replace( 'attribute_', '', $meta_key ) ) . ': ' . $meta_value );
- else
- $meta_list[] = '' . wp_kses_post( $woocommerce->attribute_label( str_replace( 'attribute_', '', $meta_key ) ) ) . ': ' . wp_kses_post( $meta_value ) . ' ';
-
- }
-
- if ( $flat )
- $output .= implode( ", \n", $meta_list );
- else
- $output .= implode( '', $meta_list );
-
- if ( ! $flat )
- $output .= ' ';
-
- if ( $return )
- return $output;
- else
- echo $output;
- }
- }
-}
\ No newline at end of file
diff --git a/classes/gateways/class-wc-payment-gateways.php b/classes/class-wc-payment-gateways.php
similarity index 84%
rename from classes/gateways/class-wc-payment-gateways.php
rename to classes/class-wc-payment-gateways.php
index 50c58c8fb37..dd8cbc212f7 100644
--- a/classes/gateways/class-wc-payment-gateways.php
+++ b/classes/class-wc-payment-gateways.php
@@ -7,6 +7,7 @@
* @class WC_Payment_Gateways
* @version 1.6.4
* @package WooCommerce/Classes/Payment
+ * @category Class
* @author WooThemes
*/
class WC_Payment_Gateways {
@@ -14,6 +15,16 @@ class WC_Payment_Gateways {
/** @var array Array of payment gateway classes. */
var $payment_gateways;
+ /**
+ * __construct function.
+ *
+ * @access public
+ * @return void
+ */
+ public function __construct() {
+ $this->init();
+ }
+
/**
* Load gateways and hook in functions.
*
@@ -22,7 +33,7 @@ class WC_Payment_Gateways {
*/
function init() {
- $load_gateways = apply_filters('woocommerce_payment_gateways', array());
+ $load_gateways = apply_filters( 'woocommerce_payment_gateways', array() );
// Get order option
$ordering = (array) get_option('woocommerce_gateway_order');
@@ -44,9 +55,7 @@ class WC_Payment_Gateways {
endforeach;
- ksort($this->payment_gateways);
-
- add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
+ ksort( $this->payment_gateways );
}
@@ -60,13 +69,9 @@ class WC_Payment_Gateways {
$_available_gateways = array();
- if (sizeof($this->payment_gateways) > 0) :
- foreach ( $this->payment_gateways as $gateway ) :
-
- $_available_gateways[$gateway->id] = $gateway;
-
- endforeach;
- endif;
+ if ( sizeof( $this->payment_gateways ) > 0 )
+ foreach ( $this->payment_gateways as $gateway )
+ $_available_gateways[ $gateway->id ] = $gateway;
return $_available_gateways;
}
diff --git a/classes/class-wc-product-external.php b/classes/class-wc-product-external.php
index 8d614eba4de..e51d3b6694d 100644
--- a/classes/class-wc-product-external.php
+++ b/classes/class-wc-product-external.php
@@ -1,4 +1,7 @@
product_type = 'external';
- $this->downloadable = 'no';
- $this->virtual = 'no';
- $this->stock = '';
- $this->stock_status = 'instock';
- $this->manage_stock = 'no';
- $this->weight = '';
- $this->length = '';
- $this->width = '';
- $this->height = '';
-
- $this->load_product_data( array(
- 'product_url' => '',
- 'button_text' => 'no'
- ) );
+ parent::__construct( $product );
}
/**
@@ -53,7 +32,7 @@ class WC_Product_External extends WC_Product_Simple {
* @access public
* @return cool
*/
- function is_purchasable() {
+ public function is_purchasable() {
return apply_filters( 'woocommerce_is_purchasable', false, $this );
}
@@ -63,7 +42,7 @@ class WC_Product_External extends WC_Product_Simple {
* @access public
* @return void
*/
- function get_product_url() {
+ public function get_product_url() {
return $this->product_url;
}
@@ -73,7 +52,7 @@ class WC_Product_External extends WC_Product_Simple {
* @access public
* @return void
*/
- function get_button_text() {
+ public function get_button_text() {
return $this->button_text ? $this->button_text : __( 'Buy product', 'woocommerce' );
}
}
\ No newline at end of file
diff --git a/classes/class-wc-product-factory.php b/classes/class-wc-product-factory.php
index 9f977f7cab7..195c7b4602a 100644
--- a/classes/class-wc-product-factory.php
+++ b/classes/class-wc-product-factory.php
@@ -8,6 +8,7 @@
* @class WC_Product_Factory
* @version 2.0.0
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Product_Factory {
@@ -35,23 +36,29 @@ class WC_Product_Factory {
$product_id = absint( $the_product->ID );
$post_type = $the_product->post_type;
- if ( isset( $args['product_type'] ) ) {
- $product_type = $args['product_type'];
- } elseif ( 'product_variation' == $post_type ) {
- $product_type = 'variation';
+ if ( in_array( $post_type, array( 'product', 'product_variation' ) ) ) {
+ if ( isset( $args['product_type'] ) ) {
+ $product_type = $args['product_type'];
+ } elseif ( 'product_variation' == $post_type ) {
+ $product_type = 'variation';
+ } else {
+ $terms = get_the_terms( $product_id, 'product_type' );
+ $product_type = ! empty( $terms ) && isset( current( $terms )->name ) ? sanitize_title( current( $terms )->name ) : 'simple';
+ }
+
+ // Create a WC coding standards compliant class name e.g. WC_Product_Type_Class instead of WC_Product_type-class
+ $classname = 'WC_Product_' . preg_replace( '/-(.)/e', "'_' . strtoupper( '$1' )", ucfirst( $product_type ) );
} else {
- $terms = get_the_terms( $product_id, 'product_type' );
- $product_type = ! empty( $terms ) && isset( current( $terms )->name ) ? sanitize_title( current( $terms )->name ) : 'simple';
+ $classname = false;
+ $product_type = false;
}
// Filter classname so that the class can be overridden if extended.
- $classname = apply_filters( 'woocommerce_product_class', 'WC_Product_' . ucfirst( $product_type ), $product_type, $post_type, $product_id );
+ $classname = apply_filters( 'woocommerce_product_class', $classname, $product_type, $post_type, $product_id );
- if ( class_exists( $classname ) ) {
- return new $classname( $the_product, $args );
- } else {
- // Use simple
- return new WC_Product_Simple( $the_product, $args );
- }
+ if ( ! class_exists( $classname ) )
+ $classname = 'WC_Product_Simple';
+
+ return new $classname( $the_product, $args );
}
}
\ No newline at end of file
diff --git a/classes/class-wc-product-grouped.php b/classes/class-wc-product-grouped.php
index f2a288addd5..e58b70ea5c0 100644
--- a/classes/class-wc-product-grouped.php
+++ b/classes/class-wc-product-grouped.php
@@ -1,4 +1,7 @@
product_type = 'grouped';
- $this->product_custom_fields = get_post_custom( $this->id );
- $this->downloadable = 'no';
- $this->virtual = 'no';
- $this->stock = '';
- $this->stock_status = 'instock';
- $this->manage_stock = 'no';
- $this->weight = '';
- $this->length = '';
- $this->width = '';
- $this->height = '';
-
- // Load data from custom fields
- $this->load_product_data( array(
- 'sku' => '',
- 'price' => '',
- 'visibility' => 'hidden',
- 'sale_price' => '',
- 'regular_price' => '',
- 'upsell_ids' => array(),
- 'crosssell_ids' => array(),
- 'featured' => 'no'
- ) );
+ parent::__construct( $product );
}
/**
@@ -63,9 +40,9 @@ class WC_Product_Grouped extends WC_Product {
* @access public
* @return int
*/
- function get_total_stock() {
+ public function get_total_stock() {
- if ( is_null( $this->total_stock ) ) {
+ if ( empty( $this->total_stock ) ) {
$transient_name = 'wc_product_total_stock_' . $this->id;
@@ -95,7 +72,7 @@ class WC_Product_Grouped extends WC_Product {
* @access public
* @return array
*/
- function get_children() {
+ public function get_children() {
if ( ! is_array( $this->children ) ) {
@@ -123,7 +100,7 @@ class WC_Product_Grouped extends WC_Product {
* @param mixed $child_id
* @return object WC_Product or WC_Product_variation
*/
- function get_child( $child_id ) {
+ public function get_child( $child_id ) {
return get_product( $child_id );
}
@@ -134,7 +111,7 @@ class WC_Product_Grouped extends WC_Product {
* @access public
* @return bool
*/
- function has_child() {
+ public function has_child() {
return sizeof( $this->get_children() ) ? true : false;
}
@@ -145,7 +122,7 @@ class WC_Product_Grouped extends WC_Product {
* @access public
* @return bool
*/
- function is_on_sale() {
+ public function is_on_sale() {
if ( $this->has_child() ) {
foreach ( $this->get_children() as $child_id ) {
@@ -170,7 +147,7 @@ class WC_Product_Grouped extends WC_Product {
* @access public
* @return cool
*/
- function is_purchasable() {
+ public function is_purchasable() {
return apply_filters( 'woocommerce_is_purchasable', false, $this );
}
@@ -182,7 +159,7 @@ class WC_Product_Grouped extends WC_Product {
* @param string $price (default: '')
* @return string
*/
- function get_price_html( $price = '' ) {
+ public function get_price_html( $price = '' ) {
$child_prices = array();
diff --git a/classes/class-wc-product-simple.php b/classes/class-wc-product-simple.php
index c693dad80e0..2190846b6a0 100644
--- a/classes/class-wc-product-simple.php
+++ b/classes/class-wc-product-simple.php
@@ -1,4 +1,7 @@
product_type = 'simple';
-
- // Load data from custom fields
- $this->load_product_data( array(
- 'sku' => '',
- 'downloadable' => 'no',
- 'virtual' => 'no',
- 'price' => '',
- 'visibility' => 'hidden',
- 'stock' => 0,
- 'stock_status' => 'instock',
- 'backorders' => 'no',
- 'manage_stock' => 'no',
- 'sale_price' => '',
- 'regular_price' => '',
- 'weight' => '',
- 'length' => '',
- 'width' => '',
- 'height' => '',
- 'tax_status' => 'taxable',
- 'tax_class' => '',
- 'upsell_ids' => array(),
- 'crosssell_ids' => array(),
- 'sale_price_dates_from' => '',
- 'sale_price_dates_to' => '',
- 'featured' => 'no',
- 'sold_individually' => 'no'
- ) );
+ parent::__construct( $product );
}
/**
@@ -60,7 +32,7 @@ class WC_Product_Simple extends WC_Product {
* @access public
* @return string
*/
- function get_title() {
+ public function get_title() {
$title = $this->post->post_title;
@@ -71,14 +43,13 @@ class WC_Product_Simple extends WC_Product {
return apply_filters( 'woocommerce_product_title', apply_filters( 'the_title', $title, $this->id ), $this );
}
-
/**
- * Sync grouped products with the childs lowest price (so they can be sorted by price accurately).
+ * Sync grouped products with the children lowest price (so they can be sorted by price accurately).
*
* @access public
* @return void
*/
- function grouped_product_sync() {
+ public function grouped_product_sync() {
global $wpdb, $woocommerce;
if ( ! $this->get_parent() ) return;
diff --git a/classes/class-wc-product-variable.php b/classes/class-wc-product-variable.php
index 034608d37d4..eca60599463 100644
--- a/classes/class-wc-product-variable.php
+++ b/classes/class-wc-product-variable.php
@@ -1,4 +1,7 @@
product_type = 'variable';
- $this->product_custom_fields = get_post_custom( $this->id );
-
- // Load data from custom fields
- $this->load_product_data( array(
- 'sku' => '',
- 'price' => '',
- 'sale_price' => '',
- 'regular_price' => '',
- 'visibility' => 'hidden',
- 'stock' => 0,
- 'stock_status' => 'instock',
- 'backorders' => 'no',
- 'manage_stock' => 'no',
- 'weight' => '',
- 'length' => '',
- 'width' => '',
- 'height' => '',
- 'tax_status' => 'taxable',
- 'tax_class' => '',
- 'upsell_ids' => array(),
- 'crosssell_ids' => array(),
- 'featured' => 'no',
- 'min_variation_price' => '',
- 'max_variation_price' => '',
- 'min_variation_regular_price' => '',
- 'max_variation_regular_price' => '',
- 'min_variation_sale_price' => '',
- 'max_variation_sale_price' => '',
- 'sold_individually' => 'no'
- ) );
+ parent::__construct( $product );
}
/**
@@ -89,9 +40,9 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return int
*/
- function get_total_stock() {
+ public function get_total_stock() {
- if ( is_null( $this->total_stock ) ) {
+ if ( empty( $this->total_stock ) ) {
$transient_name = 'wc_product_total_stock_' . $this->id;
@@ -114,6 +65,34 @@ class WC_Product_Variable extends WC_Product {
return apply_filters( 'woocommerce_stock_amount', $this->total_stock );
}
+ /**
+ * Set stock level of the product.
+ *
+ * @access public
+ * @param mixed $amount (default: null)
+ * @return int Stock
+ */
+ function set_stock( $amount = null ) {
+ global $woocommerce;
+
+ if ( $this->managing_stock() && ! is_null( $amount ) ) {
+
+ $this->stock = intval( $amount );
+ $this->total_stock = intval( $amount );
+ update_post_meta( $this->id, '_stock', $this->stock );
+
+ // Check parents out of stock attribute
+ if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
+ $this->set_stock_status( 'outofstock' );
+ elseif ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
+ $this->set_stock_status( 'instock' );
+
+ $woocommerce->clear_product_transients( $this->id ); // Clear transient
+
+ return apply_filters( 'woocommerce_stock_amount', $this->stock );
+ }
+ }
+
/**
* Reduce stock level of the product.
*
@@ -121,7 +100,7 @@ class WC_Product_Variable extends WC_Product {
* @param int $by (default: 1) Amount to reduce by.
* @return int Stock
*/
- function reduce_stock( $by = 1 ) {
+ public function reduce_stock( $by = 1 ) {
global $woocommerce;
if ( $this->managing_stock() ) {
@@ -130,7 +109,7 @@ class WC_Product_Variable extends WC_Product {
update_post_meta($this->id, '_stock', $this->stock);
// Out of stock attribute
- if ($this->managing_stock() && !$this->backorders_allowed() && $this->get_total_stock()<=0)
+ if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
$woocommerce->clear_product_transients( $this->id ); // Clear transient
@@ -147,7 +126,7 @@ class WC_Product_Variable extends WC_Product {
* @param int $by (default: 1) Amount to increase by
* @return int Stock
*/
- function increase_stock( $by = 1 ) {
+ public function increase_stock( $by = 1 ) {
global $woocommerce;
if ($this->managing_stock()) :
@@ -156,7 +135,7 @@ class WC_Product_Variable extends WC_Product {
update_post_meta($this->id, '_stock', $this->stock);
// Out of stock attribute
- if ($this->managing_stock() && ($this->backorders_allowed() || $this->get_total_stock()>0))
+ if ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
$this->set_stock_status( 'instock' );
$woocommerce->clear_product_transients( $this->id ); // Clear transient
@@ -172,7 +151,7 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return array
*/
- function get_children() {
+ public function get_children() {
if ( ! is_array( $this->children ) ) {
@@ -201,11 +180,10 @@ class WC_Product_Variable extends WC_Product {
* @param mixed $child_id
* @return object WC_Product or WC_Product_variation
*/
- function get_child( $child_id ) {
+ public function get_child( $child_id ) {
return get_product( $child_id, array(
'parent_id' => $this->id,
- 'parent' => $this,
- 'meta' => $this->product_custom_fields
+ 'parent' => $this
) );
}
@@ -216,7 +194,7 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return bool
*/
- function has_child() {
+ public function has_child() {
return sizeof( $this->get_children() ) ? true : false;
}
@@ -227,7 +205,8 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return bool
*/
- function is_on_sale() {
+ public function is_on_sale() {
+
if ( $this->has_child() ) {
foreach ( $this->get_children() as $child_id ) {
@@ -252,16 +231,16 @@ class WC_Product_Variable extends WC_Product {
* @param string $price (default: '')
* @return string
*/
- function get_price_html( $price = '' ) {
+ public function get_price_html( $price = '' ) {
// Ensure variation prices are synced with variations
- if ( $this->min_variation_price === '' || $this->min_variation_regular_price === '' ) {
+ if ( $this->min_variation_price === '' || $this->min_variation_regular_price === '' || $this->price === '' ) {
$this->variable_product_sync();
$this->price = $this->min_variation_price;
}
// Get the price
- if ($this->price > 0) {
+ if ( $this->price > 0 ) {
if ( $this->is_on_sale() && isset( $this->min_variation_price ) && $this->min_variation_regular_price !== $this->get_price() ) {
if ( ! $this->min_variation_price || $this->min_variation_price !== $this->max_variation_price )
@@ -273,7 +252,7 @@ class WC_Product_Variable extends WC_Product {
} else {
- if ( ! $this->min_variation_price || $this->min_variation_price !== $this->max_variation_price )
+ if ( $this->min_variation_price !== $this->max_variation_price )
$price .= $this->get_price_html_from_text();
$price .= woocommerce_price( $this->get_price() );
@@ -281,15 +260,15 @@ class WC_Product_Variable extends WC_Product {
$price = apply_filters('woocommerce_variable_price_html', $price, $this);
}
- } elseif ($this->price === '' ) {
+ } elseif ( $this->price === '' ) {
$price = apply_filters('woocommerce_variable_empty_price_html', '', $this);
- } elseif ($this->price == 0 ) {
+ } elseif ( $this->price == 0 ) {
if ( $this->is_on_sale() && isset( $this->min_variation_regular_price ) && $this->min_variation_regular_price !== $this->get_price() ) {
- if ( ! $this->min_variation_price || $this->min_variation_price !== $this->max_variation_price )
+ if ( $this->min_variation_price !== $this->max_variation_price )
$price .= $this->get_price_html_from_text();
$price .= $this->get_price_html_from_to( $this->min_variation_regular_price, __( 'Free!', 'woocommerce' ) );
@@ -298,7 +277,7 @@ class WC_Product_Variable extends WC_Product {
} else {
- if ( ! $this->min_variation_price || $this->min_variation_price !== $this->max_variation_price )
+ if ( $this->min_variation_price !== $this->max_variation_price )
$price .= $this->get_price_html_from_text();
$price .= __( 'Free!', 'woocommerce' );
@@ -319,7 +298,7 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return array of attributes and their available values
*/
- function get_variation_attributes() {
+ public function get_variation_attributes() {
$variation_attributes = array();
@@ -346,7 +325,7 @@ class WC_Product_Variable extends WC_Product {
foreach ( $child_variation_attributes as $name => $value )
if ( $name == $attribute_field_name )
- $values[] = $value;
+ $values[] = sanitize_title( $value );
}
// empty value indicates that all options for given attribute are available
@@ -360,19 +339,22 @@ class WC_Product_Variable extends WC_Product {
foreach ( $post_terms as $term )
$values[] = $term->slug;
} else {
- $values = explode( '|', $attribute['value'] );
+ $values = array_map( 'trim', explode( '|', $attribute['value'] ) );
}
- $values = array_unique( array_map( 'trim', $values ) );
+ $values = array_unique( $values );
// Order custom attributes (non taxonomy) as defined
- } else {
+ } elseif ( ! $attribute['is_taxonomy'] ) {
- if ( ! $attribute['is_taxonomy'] ) {
- $options = array_map( 'trim', explode( '|', $attribute['value'] ) );
- $values = array_intersect( $options, $values );
- }
+ $option_names = array_map( 'trim', explode( '|', $attribute['value'] ) );
+ $option_slugs = $values;
+ $values = array();
+ foreach ( $option_names as $option_name ) {
+ if ( in_array( sanitize_title( $option_name ), $option_slugs ) )
+ $values[] = $option_name;
+ }
}
$variation_attributes[ $attribute['name'] ] = array_unique( $values );
@@ -387,9 +369,9 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return array
*/
- function get_variation_default_attributes() {
+ public function get_variation_default_attributes() {
- $default = isset( $this->product_custom_fields['_default_attributes'][0] ) ? $this->product_custom_fields['_default_attributes'][0] : '';
+ $default = isset( $this->default_attributes ) ? $this->default_attributes : '';
return apply_filters( 'woocommerce_product_default_attributes', (array) maybe_unserialize( $default ), $this );
}
@@ -400,7 +382,7 @@ class WC_Product_Variable extends WC_Product {
* @access public
* @return array
*/
- function get_available_variations() {
+ public function get_available_variations() {
$available_variations = array();
@@ -458,12 +440,12 @@ class WC_Product_Variable extends WC_Product {
/**
- * Sync variable product prices with the childs lowest/highest prices.
+ * Sync variable product prices with the children lowest/highest prices.
*
* @access public
* @return void
*/
- function variable_product_sync() {
+ public function variable_product_sync() {
global $woocommerce;
$children = get_posts( array(
@@ -476,7 +458,7 @@ class WC_Product_Variable extends WC_Product {
$this->min_variation_price = $this->min_variation_regular_price = $this->min_variation_sale_price = $this->max_variation_price = $this->max_variation_regular_price = $this->max_variation_sale_price = '';
- if ($children) {
+ if ( $children ) {
foreach ( $children as $child ) {
$child_price = get_post_meta( $child, '_price', true );
@@ -484,35 +466,44 @@ class WC_Product_Variable extends WC_Product {
$child_sale_price = get_post_meta( $child, '_sale_price', true );
// Regular prices
- if ( ! is_numeric( $this->min_variation_regular_price ) || $child_regular_price < $this->min_variation_regular_price )
- $this->min_variation_regular_price = $child_regular_price;
+ if ( $child_regular_price !== '' ) {
+ if ( ! is_numeric( $this->min_variation_regular_price ) || $child_regular_price < $this->min_variation_regular_price )
+ $this->min_variation_regular_price = $child_regular_price;
- if ( ! is_numeric( $this->max_variation_regular_price ) || $child_regular_price > $this->max_variation_regular_price )
- $this->max_variation_regular_price = $child_regular_price;
+ if ( ! is_numeric( $this->max_variation_regular_price ) || $child_regular_price > $this->max_variation_regular_price )
+ $this->max_variation_regular_price = $child_regular_price;
+ }
// Sale prices
- if ( $child_price == $child_sale_price ) {
- if ( $child_sale_price !== '' && ( ! is_numeric( $this->min_variation_sale_price ) || $child_sale_price < $this->min_variation_sale_price ) )
- $this->min_variation_sale_price = $child_sale_price;
+ if ( $child_sale_price !== '' ) {
+ if ( $child_price == $child_sale_price ) {
+ if ( ! is_numeric( $this->min_variation_sale_price ) || $child_sale_price < $this->min_variation_sale_price )
+ $this->min_variation_sale_price = $child_sale_price;
- if ( $child_sale_price !== '' && ( ! is_numeric( $this->max_variation_sale_price ) || $child_sale_price > $this->max_variation_sale_price ) )
- $this->max_variation_sale_price = $child_sale_price;
+ if ( ! is_numeric( $this->max_variation_sale_price ) || $child_sale_price > $this->max_variation_sale_price )
+ $this->max_variation_sale_price = $child_sale_price;
+ }
+ }
+
+ // Actual prices
+ if ( $child_price !== '' ) {
+ if ( $child_price > $this->max_variation_price )
+ $this->max_variation_price = $child_price;
+
+ if ( $this->min_variation_price === '' || $child_price < $this->min_variation_price )
+ $this->min_variation_price = $child_price;
}
}
- $this->min_variation_price = $this->min_variation_sale_price === '' || $this->min_variation_regular_price < $this->min_variation_sale_price ? $this->min_variation_regular_price : $this->min_variation_sale_price;
+ update_post_meta( $this->id, '_price', $this->min_variation_price );
+ update_post_meta( $this->id, '_min_variation_price', $this->min_variation_price );
+ update_post_meta( $this->id, '_max_variation_price', $this->max_variation_price );
+ update_post_meta( $this->id, '_min_variation_regular_price', $this->min_variation_regular_price );
+ update_post_meta( $this->id, '_max_variation_regular_price', $this->max_variation_regular_price );
+ update_post_meta( $this->id, '_min_variation_sale_price', $this->min_variation_sale_price );
+ update_post_meta( $this->id, '_max_variation_sale_price', $this->max_variation_sale_price );
- $this->max_variation_price = $this->max_variation_sale_price === '' || $this->max_variation_regular_price > $this->max_variation_sale_price ? $this->max_variation_regular_price : $this->max_variation_sale_price;
+ $woocommerce->clear_product_transients( $this->id );
}
-
- update_post_meta( $this->id, '_price', $this->min_variation_price );
- update_post_meta( $this->id, '_min_variation_price', $this->min_variation_price );
- update_post_meta( $this->id, '_max_variation_price', $this->max_variation_price );
- update_post_meta( $this->id, '_min_variation_regular_price', $this->min_variation_regular_price );
- update_post_meta( $this->id, '_max_variation_regular_price', $this->max_variation_regular_price );
- update_post_meta( $this->id, '_min_variation_sale_price', $this->min_variation_sale_price );
- update_post_meta( $this->id, '_max_variation_sale_price', $this->max_variation_sale_price );
-
- $woocommerce->clear_product_transients( $this->id );
}
}
\ No newline at end of file
diff --git a/classes/class-wc-product-variation.php b/classes/class-wc-product-variation.php
index 4ce7a346d9c..c1e5378044a 100644
--- a/classes/class-wc-product-variation.php
+++ b/classes/class-wc-product-variation.php
@@ -1,4 +1,7 @@
product_type = 'variable';
+ $this->product_type = 'variation';
if ( is_object( $variation ) ) {
$this->variation_id = absint( $variation->ID );
@@ -84,50 +73,23 @@ class WC_Product_Variation extends WC_Product {
$this->id = ! empty( $args['parent_id'] ) ? intval( $args['parent_id'] ) : wp_get_post_parent_id( $this->variation_id );
// The post doesn't have a parent id, therefore its invalid.
- if ( empty( $this->id ) ) return false;
+ if ( empty( $this->id ) )
+ return false;
// Get post data
$this->parent = ! empty( $args['parent'] ) ? $args['parent'] : get_product( $this->id );
- $this->post = $this->parent->post;
-
- // Get custom fields
- $this->product_custom_fields = get_post_custom( $this->variation_id );
- $this->parent_custom_fields = ! empty( $args['meta'] ) ? $args['meta'] : get_post_custom( $this->id );
-
- $this->load_product_data( array(
- 'sku' => '',
- 'price' => 0,
- 'visibility' => 'hidden',
- 'stock' => 0,
- 'stock_status' => 'instock',
- 'backorders' => 'no',
- 'manage_stock' => 'no',
- 'sale_price' => '',
- 'regular_price' => '',
- 'weight' => '',
- 'length' => '',
- 'width' => '',
- 'height' => '',
- 'tax_status' => 'taxable',
- 'tax_class' => '',
- 'upsell_ids' => array(),
- 'crosssell_ids' => array()
- ), $this->parent_custom_fields );
+ $this->post = ! empty( $this->parent->post ) ? $this->parent->post : array();
+ $this->product_custom_fields = get_post_meta( $this->variation_id );
// Get the variation attributes from meta
- $this->variation_data = array();
-
foreach ( $this->product_custom_fields as $name => $value ) {
+ if ( ! strstr( $name, 'attribute_' ) )
+ continue;
- if ( ! strstr( $name, 'attribute_' ) ) continue;
-
- $this->variation_data[ $name ] = $value[0];
+ $this->variation_data[ $name ] = sanitize_title( $value[0] );
}
- // Now get variation meta and override the parent variable product
- $this->variation_has_sku = $this->variation_has_stock = $this->variation_has_weight = $this->variation_has_length = $this->variation_has_width = $this->variation_has_height = $this->variation_has_price = $this->variation_has_regular_price = $this->variation_has_sale_price = false;
-
- /* Override parent data with variation */
+ // Now get variation meta to override the parent variable product
if ( ! empty( $this->product_custom_fields['_sku'][0] ) ) {
$this->variation_has_sku = true;
$this->sku = $this->product_custom_fields['_sku'][0];
@@ -176,42 +138,40 @@ class WC_Product_Variation extends WC_Product {
$this->tax_class = $this->product_custom_fields['_tax_class'][0];
}
- if ( isset( $this->product_custom_fields['_price'][0] ) && $this->product_custom_fields['_price'][0] !== '' ) {
- $this->variation_has_price = true;
- $this->price = $this->product_custom_fields['_price'][0];
- }
-
- if ( isset( $this->product_custom_fields['_regular_price'][0] ) && $this->product_custom_fields['_regular_price'][0] !== '' ) {
- $this->variation_has_regular_price = true;
- $this->regular_price = $this->product_custom_fields['_regular_price'][0];
- }
-
- if ( isset( $this->product_custom_fields['_sale_price'][0] ) && $this->product_custom_fields['_sale_price'][0] !== '' ) {
- $this->variation_has_sale_price = true;
- $this->sale_price = $this->product_custom_fields['_sale_price'][0];
- }
-
- // Backwards compat for prices
- if ( $this->variation_has_price && ! $this->variation_has_regular_price ) {
- update_post_meta( $this->variation_id, '_regular_price', $this->price );
- $this->variation_has_regular_price = true;
- $this->regular_price = $this->price;
-
- if ( $this->variation_has_sale_price && $this->sale_price < $this->regular_price ) {
- update_post_meta( $this->variation_id, '_price', $this->sale_price );
- $this->price = $this->sale_price;
- }
- }
-
if ( isset( $this->product_custom_fields['_sale_price_dates_from'][0] ) )
$this->sale_price_dates_from = $this->product_custom_fields['_sale_price_dates_from'][0];
if ( isset( $this->product_custom_fields['_sale_price_dates_to'][0] ) )
$this->sale_price_dates_from = $this->product_custom_fields['_sale_price_dates_to'][0];
+ // Prices
+ $this->price = isset( $this->product_custom_fields['_price'][0] ) ? $this->product_custom_fields['_price'][0] : '';
+ $this->regular_price = isset( $this->product_custom_fields['_regular_price'][0] ) ? $this->product_custom_fields['_regular_price'][0] : '';
+ $this->sale_price = isset( $this->product_custom_fields['_sale_price'][0] ) ? $this->product_custom_fields['_sale_price'][0] : '';
+
+ // Backwards compat for prices
+ if ( $this->price !== '' && $this->regular_price == '' ) {
+ update_post_meta( $this->variation_id, '_regular_price', $this->price );
+ $this->regular_price = $this->price;
+
+ if ( $this->sale_price !== '' && $this->sale_price < $this->regular_price ) {
+ update_post_meta( $this->variation_id, '_price', $this->sale_price );
+ $this->price = $this->sale_price;
+ }
+ }
+
$this->total_stock = $this->stock;
}
+ /**
+ * Returns whether or not the product post exists.
+ *
+ * @access public
+ * @return bool
+ */
+ function exists() {
+ return empty( $this->id ) ? false : true;
+ }
/**
* Returns whether or not the variation is visible.
@@ -219,7 +179,7 @@ class WC_Product_Variation extends WC_Product {
* @access public
* @return bool
*/
- function is_visible() {
+ public function is_visible() {
$visible = true;
@@ -227,6 +187,10 @@ class WC_Product_Variation extends WC_Product {
if ( get_option('woocommerce_hide_out_of_stock_items') == 'yes' && ! $this->is_in_stock() )
$visible = false;
+ // Price not set
+ elseif ( $this->price == "" )
+ $visible = false;
+
return apply_filters( 'woocommerce_product_is_visible', $visible, $this->id );
}
@@ -237,7 +201,7 @@ class WC_Product_Variation extends WC_Product {
* @access public
* @return bool
*/
- function parent_is_visible() {
+ public function parent_is_visible() {
return parent::is_visible();
}
@@ -246,7 +210,7 @@ class WC_Product_Variation extends WC_Product {
*
* @return int
*/
- function get_variation_id() {
+ public function get_variation_id() {
return absint( $this->variation_id );
}
@@ -255,33 +219,39 @@ class WC_Product_Variation extends WC_Product {
*
* @return array of attributes and their values for this variation
*/
- function get_variation_attributes() {
+ public function get_variation_attributes() {
return $this->variation_data;
}
/**
- * Get variation attribute values
+ * Get variation price HTML. Prices are not inherited from parents.
*
* @return string containing the formatted price
*/
- function get_price_html() {
- if ( $this->variation_has_price ) {
- $price = '';
+ public function get_price_html() {
+
+ if ( $this->price !== '' ) {
+ if ( $this->price == $this->sale_price && $this->sale_price < $this->regular_price ) {
+
+ $price = '
' . woocommerce_price( $this->regular_price ) . ' ' . woocommerce_price( $this->sale_price ) . ' ';
+ $price = apply_filters( 'woocommerce_variation_sale_price_html', $price, $this );
+
+ } elseif ( $this->price > 0 ) {
+
+ $price = woocommerce_price( $this->price );
+ $price = apply_filters( 'woocommerce_variation_price_html', $price, $this );
+
+ } else {
+
+ $price = __( 'Free!', 'woocommerce' );
+ $price = apply_filters( 'woocommerce_variation_free_price_html', $price, $this );
- if ( $this->price !== '' ) {
- if ( $this->price == $this->sale_price && $this->sale_price < $this->regular_price ) {
- $price .= '
' . woocommerce_price( $this->regular_price ) . ' ' . woocommerce_price( $this->sale_price ) . ' ';
- $price = apply_filters( 'woocommerce_variation_sale_price_html', $price, $this );
- } else {
- $price .= woocommerce_price( $this->price );
- $price = apply_filters( 'woocommerce_variation_price_html', $price, $this );
- }
}
-
- return $price;
} else {
- return woocommerce_price( parent::get_price() );
+ $price = apply_filters( 'woocommerce_variation_empty_price_html', '', $this );
}
+
+ return $price;
}
@@ -292,7 +262,7 @@ class WC_Product_Variation extends WC_Product {
* @param string $size (default: 'shop_thumbnail')
* @return string
*/
- function get_image( $size = 'shop_thumbnail', $attr = array() ) {
+ public function get_image( $size = 'shop_thumbnail', $attr = array() ) {
global $woocommerce;
$image = '';
@@ -311,6 +281,46 @@ class WC_Product_Variation extends WC_Product {
}
+ /**
+ * Set stock level of the product.
+ *
+ * @access public
+ * @param mixed $amount (default: null)
+ * @return int Stock
+ */
+ function set_stock( $amount = null ) {
+ global $woocommerce;
+
+ if ( $this->variation_has_stock ) {
+ if ( $this->managing_stock() && ! is_null( $amount ) ) {
+
+ $this->stock = intval( $amount );
+ $this->total_stock = intval( $amount );
+ update_post_meta( $this->variation_id, '_stock', $this->stock );
+ $woocommerce->clear_product_transients( $this->id ); // Clear transient
+
+ // Check parents out of stock attribute
+ if ( ! $this->is_in_stock() ) {
+
+ // Check parent
+ $parent_product = get_product( $this->id );
+
+ // Only continue if the parent has backorders off
+ if ( ! $parent_product->backorders_allowed() && $parent_product->get_total_stock() <= 0 )
+ $this->set_stock_status( 'outofstock' );
+
+ } elseif ( $this->is_in_stock() ) {
+ $this->set_stock_status( 'instock' );
+ }
+
+ return apply_filters( 'woocommerce_stock_amount', $this->stock );
+ }
+ } else {
+ return parent::set_stock( $amount );
+ }
+ }
+
+
/**
* Reduce stock level of the product.
*
@@ -318,7 +328,7 @@ class WC_Product_Variation extends WC_Product {
* @param int $by (default: 1) Amount to reduce by
* @return int stock level
*/
- function reduce_stock( $by = 1 ) {
+ public function reduce_stock( $by = 1 ) {
global $woocommerce;
if ( $this->variation_has_stock ) {
@@ -356,7 +366,7 @@ class WC_Product_Variation extends WC_Product {
* @param int $by (default: 1) Amount to increase by
* @return int stock level
*/
- function increase_stock( $by = 1 ) {
+ public function increase_stock( $by = 1 ) {
global $woocommerce;
if ($this->variation_has_stock) :
@@ -385,7 +395,7 @@ class WC_Product_Variation extends WC_Product {
* @access public
* @return string
*/
- function get_shipping_class() {
+ public function get_shipping_class() {
if ( ! $this->variation_shipping_class ) {
$classes = get_the_terms( $this->variation_id, 'product_shipping_class' );
@@ -406,7 +416,7 @@ class WC_Product_Variation extends WC_Product {
* @access public
* @return int
*/
- function get_shipping_class_id() {
+ public function get_shipping_class_id() {
if ( ! $this->variation_shipping_class_id ) {
$classes = get_the_terms( $this->variation_id, 'product_shipping_class' );
@@ -427,7 +437,7 @@ class WC_Product_Variation extends WC_Product {
* @param string $download_id file identifier
* @return array
*/
- function get_file_download_path( $download_id ) {
+ public function get_file_download_path( $download_id ) {
$file_path = '';
$file_paths = apply_filters( 'woocommerce_file_download_paths', get_post_meta( $this->variation_id, '_file_paths', true ), $this->variation_id, null, null );
diff --git a/classes/class-wc-query.php b/classes/class-wc-query.php
index 98797dbab43..a71ee9b931f 100644
--- a/classes/class-wc-query.php
+++ b/classes/class-wc-query.php
@@ -5,27 +5,28 @@
* @class WC_Query
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Query {
- /** @var array Unfiltered product ids (before layered nav etc) */
- var $unfiltered_product_ids = array();
+ /** @public array Unfiltered product ids (before layered nav etc) */
+ public $unfiltered_product_ids = array();
- /** @var array Filtered product ids (after layered nav) */
- var $filtered_product_ids = array();
+ /** @public array Filtered product ids (after layered nav) */
+ public $filtered_product_ids = array();
- /** @var array Product IDs that match the layered nav + price filter */
- var $post__in = array();
+ /** @public array Product IDs that match the layered nav + price filter */
+ public $post__in = array();
- /** @var array The meta query for the page */
- var $meta_query = '';
+ /** @public array The meta query for the page */
+ public $meta_query = '';
- /** @var array Post IDs matching layered nav only */
- var $layered_nav_post__in = array();
+ /** @public array Post IDs matching layered nav only */
+ public $layered_nav_post__in = array();
- /** @var array Stores post IDs matching layered nav, so price filter can find max price in view */
- var $layered_nav_product_ids = array();
+ /** @public array Stores post IDs matching layered nav, so price filter can find max price in view */
+ public $layered_nav_product_ids = array();
/**
* Constructor for the query class. Hooks in methods.
@@ -33,13 +34,12 @@ class WC_Query {
* @access public
* @return void
*/
- function __construct() {
- add_filter( 'pre_get_posts', array( &$this, 'pre_get_posts') );
- add_filter( 'the_posts', array( &$this, 'the_posts'), 11, 2 );
- add_filter( 'wp', array( &$this, 'remove_product_query') );
+ public function __construct() {
+ add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
+ add_filter( 'the_posts', array( $this, 'the_posts' ), 11, 2 );
+ add_filter( 'wp', array( $this, 'remove_product_query' ) );
}
-
/**
* Hook into pre_get_posts to do the main product query
*
@@ -47,13 +47,24 @@ class WC_Query {
* @param mixed $q query object
* @return void
*/
- function pre_get_posts( $q ) {
+ public function pre_get_posts( $q ) {
global $woocommerce;
// We only want to affect the main query
if ( ! $q->is_main_query() )
return;
+ // When orderby is set, WordPress shows posts. Get around that here.
+ if ( $q->is_home() && 'page' == get_option('show_on_front') && get_option('page_on_front') == woocommerce_get_page_id('shop') ) {
+ $_query = wp_parse_args( $q->query );
+ if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) {
+ $q->is_page = true;
+ $q->is_home = false;
+ $q->set( 'page_id', get_option('page_on_front') );
+ $q->set( 'post_type', 'product' );
+ }
+ }
+
// Special check for shops with the product archive on front
if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $q->get('page_id') == woocommerce_get_page_id('shop') ) {
@@ -78,33 +89,58 @@ class WC_Query {
$wp_post_types['product']->post_name = $shop_page->post_name;
// Fix conditional Functions like is_front_page
- $q->is_singular = false;
- $q->is_post_type_archive = true;
- $q->is_archive = true;
+ $q->is_singular = false;
+ $q->is_post_type_archive = true;
+ $q->is_archive = true;
- // Fix WP SEO
- if ( function_exists( 'wpseo_get_value' ) ) {
- add_filter( 'wpseo_metadesc', array( &$this, 'wpseo_metadesc' ) );
- add_filter( 'wpseo_metakey', array( &$this, 'wpseo_metakey' ) );
- }
+ // Fix WP SEO
+ if ( function_exists( 'wpseo_get_value' ) ) {
+ add_filter( 'wpseo_metadesc', array( $this, 'wpseo_metadesc' ) );
+ add_filter( 'wpseo_metakey', array( $this, 'wpseo_metakey' ) );
+ }
} else {
// Only apply to product categories, the product post archive, the shop page, product tags, and product attribute taxonomies
- if ( ! $q->is_post_type_archive( 'product' ) && ! $q->is_tax( array_merge( array('product_cat', 'product_tag'), $woocommerce->get_attribute_taxonomy_names() ) ) )
+ if ( ! $q->is_post_type_archive( 'product' ) && ! $q->is_tax( get_object_taxonomies( 'product' ) ) )
return;
}
- $this->product_query( $q );
+ $this->product_query( $q );
- // We're on a shop page so queue the woocommerce_get_products_in_view function
- add_action( 'wp', array( &$this, 'get_products_in_view' ), 2);
+ if ( is_search() ) {
+ add_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
+ add_filter( 'wp', array( $this, 'remove_posts_where' ) );
+ }
- // And remove the pre_get_posts hook
- $this->remove_product_query();
+ // We're on a shop page so queue the woocommerce_get_products_in_view function
+ add_action( 'wp', array( $this, 'get_products_in_view' ), 2);
+
+ // And remove the pre_get_posts hook
+ $this->remove_product_query();
}
+ /**
+ * search_post_excerpt function.
+ *
+ * @access public
+ * @param string $where (default: '')
+ * @return string (modified where clause)
+ */
+ public function search_post_excerpt( $where = '' ) {
+ global $wp_the_query;
+
+ // If this is not a WC Query, do not modify the query
+ if ( empty( $wp_the_query->query_vars['wc_query'] ) )
+ return $where;
+
+ $where = preg_replace(
+ "/post_title\s+LIKE\s*(\'[^\']+\')/",
+ "post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
+
+ return $where;
+ }
/**
* wpseo_metadesc function.
@@ -113,7 +149,7 @@ class WC_Query {
* @param mixed $meta
* @return void
*/
- function wpseo_metadesc() {
+ public function wpseo_metadesc() {
return wpseo_get_value( 'metadesc', woocommerce_get_page_id('shop') );
}
@@ -124,7 +160,7 @@ class WC_Query {
* @access public
* @return void
*/
- function wpseo_metakey() {
+ public function wpseo_metakey() {
return wpseo_get_value( 'metakey', woocommerce_get_page_id('shop') );
}
@@ -137,10 +173,10 @@ class WC_Query {
* @param bool $query (default: false)
* @return void
*/
- function the_posts( $posts, $query = false ) {
+ public function the_posts( $posts, $query = false ) {
global $woocommerce;
- // Abort if theres no query
+ // Abort if there's no query
if ( ! $query )
return $posts;
@@ -157,33 +193,33 @@ class WC_Query {
return $posts;
// Abort if we're not on a post type archive/product taxonomy
- if ( ! $query->is_post_type_archive( 'product' ) && ! $query->is_tax( array_merge( array('product_cat', 'product_tag'), $woocommerce->get_attribute_taxonomy_names() ) ) )
+ if ( ! $query->is_post_type_archive( 'product' ) && ! $query->is_tax( get_object_taxonomies( 'product' ) ) )
return $posts;
- $filtered_posts = array();
- $queried_post_ids = array();
+ $filtered_posts = array();
+ $queried_post_ids = array();
- foreach ( $posts as $post ) {
- if ( in_array( $post->ID, $this->post__in ) ) {
- $filtered_posts[] = $post;
- $queried_post_ids[] = $post->ID;
- }
- }
-
- $query->posts = $filtered_posts;
- $query->post_count = count( $filtered_posts );
-
- // Ensure filters are set
- $this->unfiltered_product_ids = $queried_post_ids;
- $this->filtered_product_ids = $queried_post_ids;
-
- if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
- $this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
- } else {
- $this->layered_nav_product_ids = $this->unfiltered_product_ids;
+ foreach ( $posts as $post ) {
+ if ( in_array( $post->ID, $this->post__in ) ) {
+ $filtered_posts[] = $post;
+ $queried_post_ids[] = $post->ID;
+ }
}
- return $filtered_posts;
+ $query->posts = $filtered_posts;
+ $query->post_count = count( $filtered_posts );
+
+ // Ensure filters are set
+ $this->unfiltered_product_ids = $queried_post_ids;
+ $this->filtered_product_ids = $queried_post_ids;
+
+ if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
+ $this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
+ } else {
+ $this->layered_nav_product_ids = $this->unfiltered_product_ids;
+ }
+
+ return $filtered_posts;
}
@@ -194,12 +230,12 @@ class WC_Query {
* @param mixed $q
* @return void
*/
- function product_query( $q ) {
+ public function product_query( $q ) {
// Meta query
$meta_query = (array) $q->get( 'meta_query' );
- $meta_query[] = $this->visibility_meta_query();
- $meta_query[] = $this->stock_status_meta_query();
+ $meta_query[] = $this->visibility_meta_query();
+ $meta_query[] = $this->stock_status_meta_query();
// Ordering
$ordering = $this->get_catalog_ordering_args();
@@ -217,17 +253,17 @@ class WC_Query {
if ( ! $q->is_tax( 'product_cat' ) && ! $q->is_tax( 'product_tag' ) )
$q->set( 'post_type', 'product' );
$q->set( 'meta_query', $meta_query );
- $q->set( 'post__in', $post__in );
- $q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', get_option( 'posts_per_page' ) ) );
+ $q->set( 'post__in', $post__in );
+ $q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', get_option( 'posts_per_page' ) ) );
- // Set a special variable
- $q->set( 'wc_query', true );
+ // Set a special variable
+ $q->set( 'wc_query', true );
- // Store variables
- $this->post__in = $post__in;
- $this->meta_query = $meta_query;
+ // Store variables
+ $this->post__in = $post__in;
+ $this->meta_query = $meta_query;
- do_action( 'woocommerce_product_query', $q, $this );
+ do_action( 'woocommerce_product_query', $q, $this );
}
@@ -237,8 +273,18 @@ class WC_Query {
* @access public
* @return void
*/
- function remove_product_query() {
- remove_filter( 'pre_get_posts', array( &$this, 'pre_get_posts') );
+ public function remove_product_query() {
+ remove_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
+ }
+
+ /**
+ * Remove the posts_where filter
+ *
+ * @access public
+ * @return void
+ */
+ public function remove_posts_where() {
+ remove_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
}
@@ -248,7 +294,7 @@ class WC_Query {
* @access public
* @return void
*/
- function get_products_in_view() {
+ public function get_products_in_view() {
global $wp_the_query;
$unfiltered_product_ids = array();
@@ -265,7 +311,7 @@ class WC_Query {
if ( false === ( $unfiltered_product_ids = get_transient( $transient_name ) ) ) {
- // Get all visible posts, regardless of filters
+ // Get all visible posts, regardless of filters
$unfiltered_product_ids = get_posts(
array_merge(
$current_wp_query,
@@ -308,49 +354,80 @@ class WC_Query {
* @access public
* @return array
*/
- function get_catalog_ordering_args() {
+ public function get_catalog_ordering_args( $orderby = '', $order = '' ) {
global $woocommerce;
- $current_order = ( isset( $woocommerce->session->orderby ) ) ? $woocommerce->session->orderby : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
+ // Get ordering from query string unless defined
+ if ( ! $orderby ) {
+ $orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
- switch ( $current_order ) {
- case 'date' :
- $orderby = 'date';
- $order = 'desc';
- $meta_key = '';
- break;
- case 'price' :
- $orderby = 'meta_value_num';
- $order = 'asc';
- $meta_key = '_price';
- break;
- case 'high_price' :
- $orderby = 'meta_value_num';
- $order = 'desc';
- $meta_key = '_price';
- break;
- case 'title' :
- $orderby = 'title';
- $order = 'asc';
- $meta_key = '';
- break;
- default :
- $orderby = 'menu_order title';
- $order = 'asc';
- $meta_key = '';
- break;
+ // Get order + orderby args from string
+ $orderby_value = explode( '-', $orderby_value );
+ $orderby = esc_attr( $orderby_value[0] );
+ $order = ! empty( $orderby_value[1] ) ? $orderby_value[1] : $order;
}
$args = array();
- $args['orderby'] = $orderby;
- $args['order'] = $order;
- if ($meta_key)
- $args['meta_key'] = $meta_key;
+ switch ( $orderby ) {
+ case 'date' :
+ $args['orderby'] = 'date';
+ $args['order'] = $order == 'asc' ? 'asc' : 'desc';
+ $args['meta_key'] = '';
+ break;
+ case 'price' :
+ $args['orderby'] = 'meta_value_num';
+ $args['order'] = $order == 'desc' ? 'desc' : 'asc';
+ $args['meta_key'] = '_price';
+ break;
+ case 'popularity' :
+ $args['orderby'] = 'meta_value_num';
+ $args['order'] = $order == 'asc' ? 'asc' : 'desc';
+ $args['meta_key'] = 'total_sales';
+ break;
+ case 'rating' :
+ $args['orderby'] = 'menu_order title';
+ $args['order'] = $order == 'desc' ? 'desc' : 'asc';
+ $args['meta_key'] = '';
- return apply_filters('woocommerce_get_catalog_ordering_args', $args );
+ add_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) );
+ break;
+ default :
+ $args['orderby'] = 'menu_order title';
+ $args['order'] = $order == 'desc' ? 'desc' : 'asc';
+ $args['meta_key'] = '';
+ break;
+ }
+
+ return apply_filters( 'woocommerce_get_catalog_ordering_args', $args );
}
+ /**
+ * order_by_rating_post_clauses function.
+ *
+ * @access public
+ * @param array $args
+ * @return array
+ */
+ public function order_by_rating_post_clauses( $args ) {
+
+ global $wpdb;
+
+ $args['fields'] .= ", AVG( $wpdb->commentmeta.meta_value ) as average_rating ";
+
+ $args['where'] .= " AND ( $wpdb->commentmeta.meta_key = 'rating' OR $wpdb->commentmeta.meta_key IS null ) ";
+
+ $args['join'] .= "
+ LEFT OUTER JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
+ LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
+ ";
+
+ $args['orderby'] = "average_rating DESC";
+
+ $args['groupby'] = "$wpdb->posts.ID";
+
+ return $args;
+ }
/**
* Returns a meta query to handle product visibility
@@ -359,16 +436,16 @@ class WC_Query {
* @param string $compare (default: 'IN')
* @return array
*/
- function visibility_meta_query( $compare = 'IN' ) {
+ public function visibility_meta_query( $compare = 'IN' ) {
if ( is_search() ) $in = array( 'visible', 'search' ); else $in = array( 'visible', 'catalog' );
- $meta_query = array(
- 'key' => '_visibility',
- 'value' => $in,
- 'compare' => $compare
- );
+ $meta_query = array(
+ 'key' => '_visibility',
+ 'value' => $in,
+ 'compare' => $compare
+ );
- return $meta_query;
+ return $meta_query;
}
@@ -379,7 +456,7 @@ class WC_Query {
* @param string $status (default: 'instock')
* @return array
*/
- function stock_status_meta_query( $status = 'instock' ) {
+ public function stock_status_meta_query( $status = 'instock' ) {
$meta_query = array();
if ( get_option( 'woocommerce_hide_out_of_stock_items' ) == 'yes' ) {
$meta_query = array(
diff --git a/classes/class-wc-session-handler.php b/classes/class-wc-session-handler.php
new file mode 100644
index 00000000000..303acde310a
--- /dev/null
+++ b/classes/class-wc-session-handler.php
@@ -0,0 +1,191 @@
+_cookie = 'wc_session_cookie_' . COOKIEHASH;
+
+ if ( $cookie = $this->get_session_cookie() ) {
+ $this->_customer_id = $cookie[0];
+ $this->_session_expiration = $cookie[1];
+ $this->_session_expiring = $cookie[2];
+
+ // Update session if its close to expiring
+ if ( time() > $this->_session_expiring ) {
+ $this->set_session_expiration();
+ update_option( '_wc_session_expires_' . $this->_customer_id, $this->_session_expiration );
+ }
+
+ } else {
+ $this->set_session_expiration();
+ $this->_customer_id = $this->generate_customer_id();
+ }
+
+ $this->_data = $this->get_session_data();
+
+ // Set/renew our cookie
+ $to_hash = $this->_customer_id . $this->_session_expiration;
+ $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
+ $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $this->_session_expiring . '||' . $cookie_hash;
+
+ setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, COOKIEPATH, COOKIE_DOMAIN, false, true );
+
+ // Actions
+ add_action( 'woocommerce_cleanup_sessions', array( $this, 'cleanup_sessions' ), 10 );
+ add_action( 'shutdown', array( $this, 'save_data' ), 20 );
+ }
+
+ /**
+ * set_session_expiration function.
+ *
+ * @access private
+ * @return void
+ */
+ private function set_session_expiration() {
+ $this->_session_expiring = time() + intval( apply_filters( 'wc_session_expiring', 60 * 60 * 47 ) ); // 47 Hours
+ $this->_session_expiration = time() + intval( apply_filters( 'wc_session_expiration', 60 * 60 * 48 ) ); // 48 Hours
+ }
+
+ /**
+ * generate_customer_id function.
+ *
+ * @access private
+ * @return mixed
+ */
+ private function generate_customer_id() {
+ if ( is_user_logged_in() )
+ return get_current_user_id();
+ else
+ return wp_generate_password( 32 );
+ }
+
+ /**
+ * get_session_cookie function.
+ *
+ * @access private
+ * @return mixed
+ */
+ private function get_session_cookie() {
+ if ( empty( $_COOKIE[ $this->_cookie ] ) )
+ return false;
+
+ list( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $_COOKIE[ $this->_cookie ] );
+
+ // Validate hash
+ $to_hash = $customer_id . $session_expiration;
+ $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
+
+ if ( $hash != $cookie_hash )
+ return false;
+
+ return array( $customer_id, $session_expiration, $session_expiring, $cookie_hash );
+ }
+
+ /**
+ * get_session_data function.
+ *
+ * @access private
+ * @return array
+ */
+ private function get_session_data() {
+ return get_option( '_wc_session_' . $this->_customer_id, array() );
+ }
+
+ /**
+ * save_data function.
+ *
+ * @access public
+ * @return void
+ */
+ public function save_data() {
+ // Dirty if something changed - prevents saving nothing new
+ if ( $this->_dirty ) {
+
+ $session_option = '_wc_session_' . $this->_customer_id;
+ $session_expiry_option = '_wc_session_expires_' . $this->_customer_id;
+
+ if ( false === get_option( $session_option ) ) {
+ add_option( $session_option, $this->_data, '', 'no' );
+ add_option( $session_expiry_option, $this->_session_expiration, '', 'no' );
+ } else {
+ update_option( $session_option, $this->_data );
+ }
+ }
+ }
+
+ /**
+ * cleanup_sessions function.
+ *
+ * @access public
+ * @return void
+ */
+ public function cleanup_sessions() {
+ global $wpdb;
+
+ $now = time();
+
+ $session_names = $wpdb->get_col( $wpdb->prepare( "
+ SELECT
+ a.option_name
+ FROM
+ {$wpdb->options} a
+ WHERE
+ a.option_name LIKE '_wc_session_expires_%%'
+ AND a.option_value < %s
+ ", $now ) );
+
+ // Clear cache
+ foreach ( $session_names as $session_name )
+ wp_cache_delete( substr( $session_name, 10 ), 'options' );
+
+ // Delete rows
+ $wpdb->query( $wpdb->prepare( "
+ DELETE
+ a, b
+ FROM
+ {$wpdb->options} a, {$wpdb->options} b
+ WHERE
+ a.option_name LIKE '_wc_session_%%' AND
+ b.option_name = CONCAT(
+ '_wc_session_expires_',
+ SUBSTRING(
+ a.option_name,
+ CHAR_LENGTH('_wc_session_') + 1
+ )
+ )
+ AND b.option_value < %s
+ ", $now ) );
+ }
+}
\ No newline at end of file
diff --git a/classes/class-wc-session-transients.php b/classes/class-wc-session-transients.php
deleted file mode 100644
index 574fce55df7..00000000000
--- a/classes/class-wc-session-transients.php
+++ /dev/null
@@ -1,109 +0,0 @@
-_cookie = 'wc_session_cookie_' . COOKIEHASH;
- $this->_cookie_expiration = apply_filters( 'wc_session_transients_expiration', 172800 ); // 48 hours default
- $this->_customer_id = $this->get_customer_id();
- $this->_data = maybe_unserialize( get_transient( 'wc_session_' . $this->_customer_id ) );
-
- if ( false === $this->_data )
- $this->_data = array();
- }
-
- /**
- * get_customer_id function.
- *
- * @access private
- * @return mixed
- */
- private function get_customer_id() {
- if ( $customer_id = $this->get_session_cookie() ) {
- return $customer_id;
- } elseif ( is_user_logged_in() ) {
- return get_current_user_id();
- } else {
- return $this->create_customer_id();
- }
- }
-
- /**
- * get_session_cookie function.
- *
- * @access private
- * @return mixed
- */
- private function get_session_cookie() {
- if ( ! isset( $_COOKIE[ $this->_cookie ] ) )
- return false;
-
- list( $customer_id, $expires, $hash ) = explode( '|', $_COOKIE[ $this->_cookie ] );
-
- // Validate hash
- $data = $customer_id . $expires;
- $rehash = hash_hmac( 'md5', $data, wp_hash( $data ) );
-
- if ( $hash != $rehash )
- return false;
-
- return $customer_id;
- }
-
- /**
- * Create a unqiue customer ID and store it in a cookie, along with its hashed value and expirey date. Stored for 48hours.
- *
- * @access private
- * @return void
- */
- private function create_customer_id() {
- $customer_id = wp_generate_password( 32 ); // Ensure this and the transient is < 45 chars. wc_session_ leaves 34.
- $expires = time() + $this->_cookie_expiration;
- $data = $customer_id . $expires;
- $hash = hash_hmac( 'md5', $data, wp_hash( $data ) );
- $value = $customer_id . '|' . $expires . '|' . $hash;
-
- setcookie( $this->_cookie, $value, $expires, COOKIEPATH, COOKIE_DOMAIN, false, true );
-
- return $customer_id;
- }
-
- /**
- * save_data function.
- *
- * @access public
- * @return void
- */
- public function save_data() {
- // Set cart data
- set_transient( 'wc_session_' . $this->_customer_id, $this->_data, $this->_cookie_expiration );
- }
-}
\ No newline at end of file
diff --git a/classes/class-wc-shipping-rate.php b/classes/class-wc-shipping-rate.php
new file mode 100644
index 00000000000..6ee2e0132e4
--- /dev/null
+++ b/classes/class-wc-shipping-rate.php
@@ -0,0 +1,54 @@
+id = $id;
+ $this->label = $label;
+ $this->cost = $cost;
+ $this->taxes = $taxes ? $taxes : array();
+ $this->method_id = $method_id;
+ }
+
+ /**
+ * get_shipping_tax function.
+ *
+ * @access public
+ * @return array
+ */
+ function get_shipping_tax() {
+ $taxes = 0;
+ if ( $this->taxes && sizeof( $this->taxes ) > 0 )
+ $taxes = array_sum( $this->taxes );
+ return $taxes;
+ }
+}
\ No newline at end of file
diff --git a/classes/shipping/class-wc-shipping.php b/classes/class-wc-shipping.php
similarity index 97%
rename from classes/shipping/class-wc-shipping.php
rename to classes/class-wc-shipping.php
index 459b0c026ad..7a7d7d419b2 100644
--- a/classes/shipping/class-wc-shipping.php
+++ b/classes/class-wc-shipping.php
@@ -7,6 +7,7 @@
* @class WC_Shipping
* @version 1.6.4
* @package WooCommerce/Classes/Shipping
+ * @category Class
* @author WooThemes
*/
@@ -35,6 +36,16 @@ class WC_Shipping {
/** @var array Stores packages to ship and to get quotes for. */
var $packages = array();
+ /**
+ * __construct function.
+ *
+ * @access public
+ * @return void
+ */
+ public function __construct() {
+ $this->init();
+ }
+
/**
* init function.
*
@@ -44,8 +55,6 @@ class WC_Shipping {
do_action( 'woocommerce_shipping_init' );
$this->enabled = ( get_option('woocommerce_calc_shipping') == 'no' ) ? false : true;
-
- add_action( 'woocommerce_update_options_shipping', array( &$this, 'process_admin_options' ) );
}
/**
@@ -177,7 +186,7 @@ class WC_Shipping {
* Calculate shipping for (multiple) packages of cart items.
*
* @access public
- * @param array $packages multi-dimentional array of cart items to calc shipping for
+ * @param array $packages multi-dimensional array of cart items to calc shipping for
*/
function calculate_shipping( $packages = array() ) {
global $woocommerce;
@@ -310,7 +319,7 @@ class WC_Shipping {
* Gets all available shipping methods which have rates.
*
* @todo Currently we support 1 shipping method per order so this function merges rates - in the future we should offer
- * 1 rate per package and list them accordinly for user selection
+ * 1 rate per package and list them accordingly for user selection
*
* @access public
* @return array
diff --git a/classes/class-wc-shortcodes.php b/classes/class-wc-shortcodes.php
new file mode 100644
index 00000000000..4b3e2c6c82b
--- /dev/null
+++ b/classes/class-wc-shortcodes.php
@@ -0,0 +1,1029 @@
+shortcode_wrapper( array( 'WC_Shortcode_Cart', 'output' ), $atts );
+ }
+
+ /**
+ * Checkout page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function checkout( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Checkout', 'output' ), $atts );
+ }
+
+ /**
+ * Order tracking page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function order_tracking( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Order_Tracking', 'output' ), $atts );
+ }
+
+ /**
+ * Cart shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function my_account( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_My_Account', 'output' ), $atts );
+ }
+
+ /**
+ * Edit address page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function edit_address( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Edit_Address', 'output' ), $atts );
+ }
+
+
+ /**
+ * Change password page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function change_password( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Change_Password', 'output' ), $atts );
+ }
+
+ /**
+ * Lost password page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function lost_password( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Lost_Password', 'output' ), $atts );
+ }
+
+ /**
+ * View order page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function view_order( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_View_Order', 'output' ), $atts );
+ }
+
+ /**
+ * Pay page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function pay( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Pay', 'output' ), $atts );
+ }
+
+ /**
+ * Thankyou page shortcode.
+ *
+ * @access public
+ * @param mixed $atts
+ * @return string
+ */
+ public function thankyou( $atts ) {
+ global $woocommerce;
+ return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Thankyou', 'output' ), $atts );
+ }
+
+ /**
+ * List products in a category shortcode
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function product_category( $atts ){
+ global $woocommerce, $woocommerce_loop;
+
+ if ( empty( $atts ) ) return;
+
+ extract( shortcode_atts( array(
+ 'per_page' => '12',
+ 'columns' => '4',
+ 'orderby' => 'title',
+ 'order' => 'desc',
+ 'category' => ''
+ ), $atts ) );
+
+ if ( ! $category ) return;
+
+ // Default ordering args
+ $ordering_args = $woocommerce->query->get_catalog_ordering_args( $orderby, $order );
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'orderby' => $ordering_args['orderby'],
+ 'order' => $ordering_args['order'],
+ 'posts_per_page' => $per_page,
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array('catalog', 'visible'),
+ 'compare' => 'IN'
+ )
+ ),
+ 'tax_query' => array(
+ array(
+ 'taxonomy' => 'product_cat',
+ 'terms' => array( esc_attr($category) ),
+ 'field' => 'slug',
+ 'operator' => 'IN'
+ )
+ )
+ );
+
+ if ( isset( $ordering_args['meta_key'] ) ) {
+ $args['meta_key'] = $ordering_args['meta_key'];
+ }
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * List all (or limited) product categories
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function product_categories( $atts ) {
+ global $woocommerce_loop;
+
+ extract( shortcode_atts( array (
+ 'number' => null,
+ 'orderby' => 'name',
+ 'order' => 'ASC',
+ 'columns' => '4',
+ 'hide_empty' => 1,
+ 'parent' => ''
+ ), $atts ) );
+
+ if ( isset( $atts[ 'ids' ] ) ) {
+ $ids = explode( ',', $atts[ 'ids' ] );
+ $ids = array_map( 'trim', $ids );
+ } else {
+ $ids = array();
+ }
+
+ $hide_empty = ( $hide_empty == true || $hide_empty == 1 ) ? 1 : 0;
+
+ // get terms and workaround WP bug with parents/pad counts
+ $args = array(
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'hide_empty' => $hide_empty,
+ 'include' => $ids,
+ 'pad_counts' => true,
+ 'child_of' => $parent
+ );
+
+ $product_categories = get_terms( 'product_cat', $args );
+
+ if ( $parent !== "" )
+ $product_categories = wp_list_filter( $product_categories, array( 'parent' => $parent ) );
+
+ if ( $number )
+ $product_categories = array_slice( $product_categories, 0, $number );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ ob_start();
+
+ // Reset loop/columns globals when starting a new loop
+ $woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
+
+ if ( $product_categories ) {
+
+ woocommerce_product_loop_start();
+
+ foreach ( $product_categories as $category ) {
+
+ woocommerce_get_template( 'content-product_cat.php', array(
+ 'category' => $category
+ ) );
+
+ }
+
+ woocommerce_product_loop_end();
+
+ }
+
+ woocommerce_reset_loop();
+
+ return '
' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * Recent Products shortcode
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function recent_products( $atts ) {
+
+ global $woocommerce_loop, $woocommerce;
+
+ extract(shortcode_atts(array(
+ 'per_page' => '12',
+ 'columns' => '4',
+ 'orderby' => 'date',
+ 'order' => 'desc'
+ ), $atts));
+
+ $meta_query = array();
+ $meta_query[] = $woocommerce->query->visibility_meta_query();
+ $meta_query[] = $woocommerce->query->stock_status_meta_query();
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'posts_per_page' => $per_page,
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'meta_query' => $meta_query
+ );
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * List multiple products shortcode
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function products( $atts ) {
+ global $woocommerce_loop;
+
+ if (empty($atts)) return;
+
+ extract(shortcode_atts(array(
+ 'columns' => '4',
+ 'orderby' => 'title',
+ 'order' => 'asc'
+ ), $atts));
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'posts_per_page' => -1,
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array('catalog', 'visible'),
+ 'compare' => 'IN'
+ )
+ )
+ );
+
+ if(isset($atts['skus'])){
+ $skus = explode(',', $atts['skus']);
+ $skus = array_map('trim', $skus);
+ $args['meta_query'][] = array(
+ 'key' => '_sku',
+ 'value' => $skus,
+ 'compare' => 'IN'
+ );
+ }
+
+ if(isset($atts['ids'])){
+ $ids = explode(',', $atts['ids']);
+ $ids = array_map('trim', $ids);
+ $args['post__in'] = $ids;
+ }
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * Display a single product
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function product( $atts ) {
+ if (empty($atts)) return;
+
+ $args = array(
+ 'post_type' => 'product',
+ 'posts_per_page' => 1,
+ 'no_found_rows' => 1,
+ 'post_status' => 'publish',
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array('catalog', 'visible'),
+ 'compare' => 'IN'
+ )
+ )
+ );
+
+ if(isset($atts['sku'])){
+ $args['meta_query'][] = array(
+ 'key' => '_sku',
+ 'value' => $atts['sku'],
+ 'compare' => '='
+ );
+ }
+
+ if(isset($atts['id'])){
+ $args['p'] = $atts['id'];
+ }
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * Display a single product price + cart button
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function product_add_to_cart( $atts ) {
+ global $wpdb, $woocommerce;
+
+ if ( empty( $atts ) ) return;
+
+ if ( ! isset( $atts['style'] ) ) $atts['style'] = 'border:4px solid #ccc; padding: 12px;';
+
+ if ( isset( $atts['id'] ) ) {
+ $product_data = get_post( $atts['id'] );
+ } elseif ( isset( $atts['sku'] ) ) {
+ $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $atts['sku'] ) );
+ $product_data = get_post( $product_id );
+ } else {
+ return;
+ }
+
+ if ( 'product' == $product_data->post_type ) {
+
+ $product = $woocommerce->setup_product_data( $product_data );
+
+ ob_start();
+ ?>
+
+
+ get_price_html(); ?>
+
+
+
+
post_type ) {
+
+ $product = get_product( $product_data->post_parent );
+
+ $GLOBALS['product'] = $product;
+
+ $variation = get_product( $product_data );
+
+ ob_start();
+ ?>
+
+
+ get_price_html(); ?>
+
+ add_to_cart_url();
+
+ $label = apply_filters('add_to_cart_text', __( 'Add to cart', 'woocommerce' ));
+
+ $link = add_query_arg( 'variation_id', $variation->variation_id, $link );
+
+ foreach ($variation->variation_data as $key => $data) {
+ if ($data) $link = add_query_arg( $key, $data, $link );
+ }
+
+ printf('%s ', esc_url( $link ), $product->id, $product->product_type, $label);
+
+ ?>
+
+
get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $atts['sku'] ) );
+ $product_data = get_post( $product_id );
+ } else {
+ return;
+ }
+
+ if ( 'product' !== $product_data->post_type ) return;
+
+ $_product = get_product( $product_data );
+
+ return esc_url( $_product->add_to_cart_url() );
+ }
+
+ /**
+ * List all products on sale
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function sale_products( $atts ){
+ global $woocommerce_loop, $woocommerce;
+
+ extract( shortcode_atts( array(
+ 'per_page' => '12',
+ 'columns' => '4',
+ 'orderby' => 'title',
+ 'order' => 'asc'
+ ), $atts ) );
+
+ // Get products on sale
+ $product_ids_on_sale = woocommerce_get_product_ids_on_sale();
+
+ $meta_query = array();
+ $meta_query[] = $woocommerce->query->visibility_meta_query();
+ $meta_query[] = $woocommerce->query->stock_status_meta_query();
+
+ $args = array(
+ 'posts_per_page'=> $per_page,
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'no_found_rows' => 1,
+ 'post_status' => 'publish',
+ 'post_type' => 'product',
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ 'meta_query' => $meta_query,
+ 'post__in' => $product_ids_on_sale
+ );
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+ /**
+ * List best selling products on sale
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function best_selling_products( $atts ){
+ global $woocommerce_loop;
+
+ extract( shortcode_atts( array(
+ 'per_page' => '12',
+ 'columns' => '4'
+ ), $atts ) );
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'posts_per_page' => $per_page,
+ 'meta_key' => 'total_sales',
+ 'orderby' => 'meta_value',
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array( 'catalog', 'visible' ),
+ 'compare' => 'IN'
+ )
+ )
+ );
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+ /**
+ * List top rated products on sale
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function top_rated_products( $atts ){
+ global $woocommerce_loop;
+
+ extract( shortcode_atts( array(
+ 'per_page' => '12',
+ 'columns' => '4',
+ 'orderby' => 'title',
+ 'order' => 'asc'
+ ), $atts ) );
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'posts_per_page' => $per_page,
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array('catalog', 'visible'),
+ 'compare' => 'IN'
+ )
+ )
+ );
+
+ ob_start();
+
+ add_filter( 'posts_clauses', array( &$this, 'order_by_rating_post_clauses' ) );
+
+ $products = new WP_Query( $args );
+
+ remove_filter( 'posts_clauses', array( &$this, 'order_by_rating_post_clauses' ) );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+ /**
+ * Output featured products
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function featured_products( $atts ) {
+
+ global $woocommerce_loop;
+
+ extract(shortcode_atts(array(
+ 'per_page' => '12',
+ 'columns' => '4',
+ 'orderby' => 'date',
+ 'order' => 'desc'
+ ), $atts));
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'posts_per_page' => $per_page,
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array('catalog', 'visible'),
+ 'compare' => 'IN'
+ ),
+ array(
+ 'key' => '_featured',
+ 'value' => 'yes'
+ )
+ )
+ );
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * Show a single product page
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function product_page_shortcode( $atts ) {
+ if ( empty( $atts ) ) return;
+
+ if ( ! isset( $atts['id'] ) && ! isset( $atts['sku'] ) ) return;
+
+ $args = array(
+ 'posts_per_page' => 1,
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'no_found_rows' => 1
+ );
+
+ if ( isset( $atts['sku'] ) ) {
+ $args['meta_query'][] = array(
+ 'key' => '_sku',
+ 'value' => $atts['sku'],
+ 'compare' => '='
+ );
+ }
+
+ if ( isset( $atts['id'] ) ) {
+ $args['p'] = $atts['id'];
+ }
+
+ $single_product = new WP_Query( $args );
+
+ ob_start();
+
+ while ( $single_product->have_posts() ) : $single_product->the_post(); wp_enqueue_script( 'wc-single-product' ); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '
';
+ }
+
+
+ /**
+ * Show messages
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ public function messages_shortcode() {
+ ob_start();
+
+ woocommerce_show_messages();
+
+ return ob_get_clean();
+ }
+
+ /**
+ * woocommerce_order_by_rating_post_clauses function.
+ *
+ * @access public
+ * @param mixed $args
+ * @return void
+ */
+ public function order_by_rating_post_clauses( $args ) {
+
+ global $wpdb;
+
+ $args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' ";
+
+ $args['join'] .= "
+ LEFT JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
+ LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
+ ";
+
+ $args['orderby'] = "$wpdb->commentmeta.meta_value DESC";
+
+ $args['groupby'] = "$wpdb->posts.ID";
+
+ return $args;
+ }
+
+
+ /**
+ * List products with an attribute shortcode
+ * Example [product_attribute attribute='color' filter='black']
+ *
+ * @access public
+ * @param array $atts
+ * @return string
+ */
+ function product_attribute( $atts ) {
+ global $woocommerce_loop;
+
+ extract( shortcode_atts( array(
+ 'per_page' => '12',
+ 'columns' => '4',
+ 'orderby' => 'title',
+ 'order' => 'asc',
+ 'attribute' => '',
+ 'filter' => ''
+ ), $atts ) );
+
+ $attribute = strstr( $attribute, 'pa_' ) ? sanitize_title( $attribute ) : 'pa_' . sanitize_title( $attribute );
+ $filter = sanitize_title( $filter );
+
+ $args = array(
+ 'post_type' => 'product',
+ 'post_status' => 'publish',
+ 'ignore_sticky_posts' => 1,
+ 'posts_per_page' => $per_page,
+ 'orderby' => $orderby,
+ 'order' => $order,
+ 'meta_query' => array(
+ array(
+ 'key' => '_visibility',
+ 'value' => array('catalog', 'visible'),
+ 'compare' => 'IN'
+ )
+ ),
+ 'tax_query' => array(
+ array(
+ 'taxonomy' => $attribute,
+ 'terms' => $filter,
+ 'field' => 'slug'
+ )
+ )
+ );
+
+ ob_start();
+
+ $products = new WP_Query( $args );
+
+ $woocommerce_loop['columns'] = $columns;
+
+ if ( $products->have_posts() ) : ?>
+
+
+
+ have_posts() ) : $products->the_post(); ?>
+
+
+
+
+
+
+
+ ' . ob_get_clean() . '';
+ }
+}
\ No newline at end of file
diff --git a/classes/class-wc-tax.php b/classes/class-wc-tax.php
index aaa3d7a41cf..08b100f8dd6 100644
--- a/classes/class-wc-tax.php
+++ b/classes/class-wc-tax.php
@@ -5,12 +5,23 @@
* @class WC_Tax
* @version 2.0.0
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Tax {
/** @var array */
- var $matched_rates;
+ public $matched_rates;
+
+ /**
+ * __construct function.
+ *
+ * @access public
+ * @return void
+ */
+ public function __construct() {
+ $this->dp = (int) get_option( 'woocommerce_price_num_decimals' );
+ }
/**
* Searches for all matching country/state/postcode tax rates.
@@ -19,9 +30,34 @@ class WC_Tax {
* @param string $args (default: '')
* @return array
*/
- function find_rates( $args = '' ) {
+ public function find_rates( $args = array(), $deprecated_state = null, $deprecated_postcode = null, $deprecated_class = null ) {
global $wpdb;
+ // Make sure the arguments match the WC 2.0 structure
+ if ( is_string( $args ) ) {
+ _deprecated_argument( __CLASS__ . '->' . __FUNCTION__, '2.0', 'Use $args["country"] instead. Deprecated argument will be removed in WC 2.1.' );
+ $args = array(
+ 'country' => $args
+ );
+ }
+
+ if ( func_num_args() > 1 ) {
+ if ( null !== $deprecated_state ) {
+ _deprecated_argument( __CLASS__ . '->' . __FUNCTION__, '2.0', 'Use $args["state"] instead. Deprecated argument will be removed in WC 2.1.' );
+ $args['state'] = $deprecated_state;
+ }
+
+ if ( null !== $deprecated_postcode ) {
+ _deprecated_argument( __CLASS__ . '->' . __FUNCTION__, '2.0', 'Use $args["postcode"] instead. Deprecated argument will be removed in WC 2.1.' );
+ $args['postcode'] = $deprecated_postcode;
+ }
+
+ if ( null !== $deprecated_class ) {
+ _deprecated_argument( __CLASS__ . '->' . __FUNCTION__, '2.0', 'Use $args["tax_class"] instead. Deprecated argument will be removed in WC 2.1.' );
+ $args['tax_class'] = $deprecated_class;
+ }
+ }
+
$defaults = array(
'country' => '',
'state' => '',
@@ -107,7 +143,7 @@ class WC_Tax {
* @param object Tax Class
* @return array
*/
- function get_rates( $tax_class = '' ) {
+ public function get_rates( $tax_class = '' ) {
global $woocommerce;
$tax_class = sanitize_title( $tax_class );
@@ -128,8 +164,9 @@ class WC_Tax {
} else {
// Prices which include tax should always use the base rate if we don't know where the user is located
- // Prices exlcuding tax however should just not add any taxes, as they will be added during checkout
- $matched_tax_rates = $woocommerce->cart->prices_include_tax
+ // Prices excluding tax however should just not add any taxes, as they will be added during checkout.
+ // The woocommerce_default_customer_address option (when set to base) is also used here.
+ $matched_tax_rates = $woocommerce->cart->prices_include_tax || get_option( 'woocommerce_default_customer_address' ) == 'base'
? $this->get_shop_base_rate( $tax_class )
: array();
@@ -145,7 +182,7 @@ class WC_Tax {
* @param string Tax Class
* @return array
*/
- function get_shop_base_rate( $tax_class = '' ) {
+ public function get_shop_base_rate( $tax_class = '' ) {
global $woocommerce;
$country = $woocommerce->countries->get_base_country();
@@ -164,7 +201,7 @@ class WC_Tax {
* @param string Tax Class
* @return mixed
*/
- function get_shipping_tax_rates( $tax_class = null ) {
+ public function get_shipping_tax_rates( $tax_class = null ) {
global $woocommerce;
// See if we have an explicitly set shipping tax class
@@ -179,8 +216,8 @@ class WC_Tax {
} else {
// Prices which include tax should always use the base rate if we don't know where the user is located
- // Prices exlcuding tax however should just not add any taxes, as they will be added during checkout
- if ( $woocommerce->cart->prices_include_tax ) {
+ // Prices excluding tax however should just not add any taxes, as they will be added during checkout
+ if ( $woocommerce->cart->prices_include_tax || get_option( 'woocommerce_default_customer_address' ) == 'base' ) {
$country = $woocommerce->countries->get_base_country();
$state = $woocommerce->countries->get_base_state();
$postcode = '';
@@ -309,7 +346,7 @@ class WC_Tax {
* @param bool passed price includes tax
* @return array array of rates/amounts
*/
- function calc_tax( $price, $rates, $price_includes_tax = true, $supress_rounding = false ) {
+ public function calc_tax( $price, $rates, $price_includes_tax = true, $suppress_rounding = false ) {
$price = $price * 100; // To avoid float rounding errors, work with integers (pence)
@@ -341,16 +378,15 @@ class WC_Tax {
else
$tax_amount = ( $the_rate / $regular_tax_rate ) * $non_compound_price;
- // ADVANCED: Allow third parties to modifiy this rate
+ // ADVANCED: Allow third parties to modify this rate
$tax_amount = apply_filters( 'woocommerce_price_inc_tax_amount', $tax_amount, $key, $rate, $price, $non_compound_price );
// Back to pounds
$tax_amount = ( $tax_amount / 100 );
// Rounding
- if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' && ! $supress_rounding ) {
- $decimals = (int) get_option( 'woocommerce_price_num_decimals' );
- $tax_amount = round( $tax_amount, $decimals );
+ if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' && ! $suppress_rounding ) {
+ $tax_amount = $this->round( $tax_amount );
}
// Add rate
@@ -372,16 +408,15 @@ class WC_Tax {
$tax_amount = $price * ( $rate['rate'] / 100 );
- // ADVANCED: Allow third parties to modifiy this rate
+ // ADVANCED: Allow third parties to modify this rate
$tax_amount = apply_filters( 'woocommerce_price_ex_tax_amount', $tax_amount, $key, $rate, $price );
// Back to pounds
$tax_amount = ( $tax_amount / 100 );
// Rounding
- if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' && ! $supress_rounding ) {
- $decimals = (int) get_option( 'woocommerce_price_num_decimals' );
- $tax_amount = round( $tax_amount, $decimals );
+ if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' && ! $suppress_rounding ) {
+ $tax_amount = $this->round( $tax_amount );
}
// Add rate
@@ -412,9 +447,8 @@ class WC_Tax {
$tax_amount = ( $tax_amount / 100 );
// Rounding
- if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' && ! $supress_rounding ) {
- $decimals = (int) get_option( 'woocommerce_price_num_decimals' );
- $tax_amount = round( $tax_amount, $decimals );
+ if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' && ! $suppress_rounding ) {
+ $tax_amount = $this->round( $tax_amount );
}
// Add rate
@@ -427,7 +461,7 @@ class WC_Tax {
}
}
- return apply_filters( 'woocommerce_calc_tax', $taxes, $price, $rates, $price_includes_tax, $supress_rounding );
+ return apply_filters( 'woocommerce_calc_tax', $taxes, $price, $rates, $price_includes_tax, $suppress_rounding );
}
/**
@@ -437,7 +471,7 @@ class WC_Tax {
* @param int Taxation Rate
* @return int
*/
- function calc_shipping_tax( $price, $rates ) {
+ public function calc_shipping_tax( $price, $rates ) {
// Taxes array
$taxes = array();
@@ -477,7 +511,7 @@ class WC_Tax {
* @param int key
* @return bool
*/
- function is_compound( $key ) {
+ public function is_compound( $key ) {
global $wpdb;
return $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_compound FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ) ? true : false;
}
@@ -488,7 +522,7 @@ class WC_Tax {
* @param int key
* @return string
*/
- function get_rate_label( $key ) {
+ public function get_rate_label( $key ) {
global $wpdb;
return apply_filters( 'woocommerce_rate_label', $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_name FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ), $key, $this );
}
@@ -500,7 +534,7 @@ class WC_Tax {
* @param mixed $key
* @return void
*/
- function get_rate_code( $key ) {
+ public function get_rate_code( $key ) {
global $wpdb;
$rate = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) );
@@ -521,16 +555,23 @@ class WC_Tax {
* @param array
* @return float
*/
- function get_tax_total( $taxes ) {
- return array_sum( array_map( array(&$this, 'round'), $taxes ) );
+ public function get_tax_total( $taxes ) {
+ return array_sum( array_map( array( $this, 'round' ), $taxes ) );
}
/**
- * Round to currency DP.
+ * Round to currency DP. Wrapper for PHP round.
+ *
+ * Filter example: to return rounding to .5 cents you'd use:
+ *
+ * public function euro_5cent_rounding( $in ) {
+ * return round( $in / 5, 2 ) * 5;
+ * }
+ * add_filter( 'woocommerce_tax_round', 'euro_5cent_rounding' );
+ *
*/
- function round( $in ) {
- $decimals = (int) get_option( 'woocommerce_price_num_decimals' );
- return round( $in, $decimals );
+ public function round( $in ) {
+ return apply_filters( 'woocommerce_tax_round', round( $in, $this->dp ), $in );
}
}
\ No newline at end of file
diff --git a/classes/class-wc-validation.php b/classes/class-wc-validation.php
index 8e54f2cf652..4d4a30684bf 100644
--- a/classes/class-wc-validation.php
+++ b/classes/class-wc-validation.php
@@ -5,6 +5,7 @@
* @class WC_Validation
* @version 1.6.4
* @package WooCommerce/Classes
+ * @category Class
* @author WooThemes
*/
class WC_Validation {
@@ -15,7 +16,7 @@ class WC_Validation {
* @param string email address
* @return bool
*/
- function is_email( $email ) {
+ public function is_email( $email ) {
return is_email( $email );
}
@@ -26,7 +27,7 @@ class WC_Validation {
* @param string phone number
* @return bool
*/
- function is_phone( $phone ) {
+ public function is_phone( $phone ) {
if ( strlen( trim( preg_replace( '/[\s\#0-9_\-\+\(\)]/', '', $phone ) ) ) > 0 )
return false;
@@ -41,7 +42,7 @@ class WC_Validation {
* @param string country
* @return bool
*/
- function is_postcode( $postcode, $country ) {
+ public function is_postcode( $postcode, $country ) {
if ( strlen( trim( preg_replace( '/[\s\-A-Za-z0-9]/', '', $postcode ) ) ) > 0 )
return false;
@@ -67,7 +68,7 @@ class WC_Validation {
* @param mixed $toCheck A postcode
* @return bool
*/
- function is_GB_postcode( $toCheck ) {
+ public function is_GB_postcode( $toCheck ) {
// Permitted letters depend upon their position in the postcode.
$alpha1 = "[abcdefghijklmnoprstuwyz]"; // Character 1
@@ -128,7 +129,7 @@ class WC_Validation {
* @param string country
* @return string formatted postcode
*/
- function format_postcode( $postcode, $country ) {
+ public function format_postcode( $postcode, $country ) {
$postcode = strtoupper(trim($postcode));
$postcode = trim(preg_replace('/[\s]/', '', $postcode));
@@ -146,7 +147,7 @@ class WC_Validation {
* @param mixed $tel
* @return string
*/
- function format_phone( $tel ) {
+ public function format_phone( $tel ) {
$tel = str_replace( '.', '-', $tel );
return $tel;
}
diff --git a/classes/emails/class-wc-email-customer-completed-order.php b/classes/emails/class-wc-email-customer-completed-order.php
index 85175cfb8d7..7f459b8b6b3 100644
--- a/classes/emails/class-wc-email-customer-completed-order.php
+++ b/classes/emails/class-wc-email-customer-completed-order.php
@@ -1,4 +1,7 @@
heading = __( 'Your order is complete', 'woocommerce' );
$this->subject = __( 'Your {blogname} order from {order_date} is complete', 'woocommerce' );
- $this->heading_downloadable = __( 'Your order is complete - download your files', 'woocommerce' );
- $this->subject_downloadable = __( 'Your {blogname} order from {order_date} is complete - download your files', 'woocommerce' );
-
$this->template_html = 'emails/customer-completed-order.php';
$this->template_plain = 'emails/plain/customer-completed-order.php';
// Triggers for this email
- add_action( 'woocommerce_order_status_completed_notification', array( &$this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_completed_notification', array( $this, 'trigger' ) );
+
+ // Other settings
+ $this->heading_downloadable = $this->get_option( 'heading_downloadable', __( 'Your order is complete - download your files', 'woocommerce' ) );
+ $this->subject_downloadable = $this->get_option( 'subject_downloadable', __( 'Your {blogname} order from {order_date} is complete - download your files', 'woocommerce' ) );
// Call parent constuctor
parent::__construct();
-
- // Get other settings
- $this->heading_downloadable = empty( $this->settings['heading_downloadable'] ) ? $this->heading_downloadable : $this->settings['heading_downloadable'];
- $this->subject_downloadable = empty( $this->settings['subject_downloadable'] ) ? $this->subject_downloadable : $this->settings['subject_downloadable'];
}
/**
diff --git a/classes/emails/class-wc-email-customer-invoice.php b/classes/emails/class-wc-email-customer-invoice.php
index 2bc88d8e056..ccc24e8b98b 100644
--- a/classes/emails/class-wc-email-customer-invoice.php
+++ b/classes/emails/class-wc-email-customer-invoice.php
@@ -1,4 +1,7 @@
subject_paid = __( 'Your {blogname} order from {order_date}', 'woocommerce');
$this->heading_paid = __( 'Order {order_number} details', 'woocommerce');
- // Call parent constuctor
+ // Call parent constructor
parent::__construct();
}
diff --git a/classes/emails/class-wc-email-customer-new-account.php b/classes/emails/class-wc-email-customer-new-account.php
index c71a9f531b0..0bbad86886f 100644
--- a/classes/emails/class-wc-email-customer-new-account.php
+++ b/classes/emails/class-wc-email-customer-new-account.php
@@ -1,4 +1,7 @@
heading = __( 'A note has been added to your order', 'woocommerce');
// Triggers
- add_action( 'woocommerce_new_customer_note_notification', array( &$this, 'trigger' ) );
+ add_action( 'woocommerce_new_customer_note_notification', array( $this, 'trigger' ) );
- // Call parent constuctor
+ // Call parent constructor
parent::__construct();
}
diff --git a/classes/emails/class-wc-email-customer-processing-order.php b/classes/emails/class-wc-email-customer-processing-order.php
index faaf3dda42e..e8ad8369afd 100644
--- a/classes/emails/class-wc-email-customer-processing-order.php
+++ b/classes/emails/class-wc-email-customer-processing-order.php
@@ -1,4 +1,7 @@
template_plain = 'emails/plain/customer-processing-order.php';
// Triggers for this email
- add_action( 'woocommerce_order_status_pending_to_processing_notification', array( &$this, 'trigger' ) );
- add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( &$this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
- // Call parent constuctor
+ // Call parent constructor
parent::__construct();
}
diff --git a/classes/emails/class-wc-email-customer-reset-password.php b/classes/emails/class-wc-email-customer-reset-password.php
index 362888b2a13..87fb9deb405 100644
--- a/classes/emails/class-wc-email-customer-reset-password.php
+++ b/classes/emails/class-wc-email-customer-reset-password.php
@@ -1,4 +1,7 @@
template_plain = 'emails/plain/admin-new-order.php';
// Triggers for this email
- add_action( 'woocommerce_order_status_pending_to_processing_notification', array( &$this, 'trigger' ) );
- add_action( 'woocommerce_order_status_pending_to_completed_notification', array( &$this, 'trigger' ) );
- add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( &$this, 'trigger' ) );
- add_action( 'woocommerce_order_status_failed_to_processing_notification', array( &$this, 'trigger' ) );
- add_action( 'woocommerce_order_status_failed_to_completed_notification', array( &$this, 'trigger' ) );
- add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( &$this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'trigger' ) );
+ add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'trigger' ) );
- // Call parent constuctor
+ // Call parent constructor
parent::__construct();
// Other settings
- $this->recipient = $this->settings['recipient'];
+ $this->recipient = $this->get_option( 'recipient' );
if ( ! $this->recipient )
$this->recipient = get_option( 'admin_email' );
diff --git a/classes/gateways/bacs/class-wc-bacs.php b/classes/gateways/bacs/class-wc-gateway-bacs.php
similarity index 82%
rename from classes/gateways/bacs/class-wc-bacs.php
rename to classes/gateways/bacs/class-wc-gateway-bacs.php
index 6395911e4b8..32f583ffa9e 100644
--- a/classes/gateways/bacs/class-wc-bacs.php
+++ b/classes/gateways/bacs/class-wc-gateway-bacs.php
@@ -1,19 +1,19 @@
icon = apply_filters('woocommerce_bacs_icon', '');
$this->has_fields = false;
$this->method_title = __( 'Bacs', 'woocommerce' );
- // Load the form fields.
- $this->init_form_fields();
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
// Define user set variables
- $this->title = $this->settings['title'];
- $this->description = $this->settings['description'];
- $this->account_name = $this->settings['account_name'];
- $this->account_number = $this->settings['account_number'];
- $this->sort_code = $this->settings['sort_code'];
- $this->bank_name = $this->settings['bank_name'];
- $this->iban = $this->settings['iban'];
- $this->bic = $this->settings['bic'];
+ $this->title = $this->get_option( 'title' );
+ $this->description = $this->get_option( 'description' );
+ $this->account_name = $this->get_option( 'account_name' );
+ $this->account_number = $this->get_option( 'account_number' );
+ $this->sort_code = $this->get_option( 'sort_code' );
+ $this->bank_name = $this->get_option( 'bank_name' );
+ $this->iban = $this->get_option( 'iban' );
+ $this->bic = $this->get_option( 'bic' );
// Actions
- add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
- add_action('woocommerce_thankyou_bacs', array(&$this, 'thankyou_page'));
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
+ add_action( 'woocommerce_thankyou_bacs', array( $this, 'thankyou_page' ) );
// Customer Emails
- add_action('woocommerce_email_before_order_table', array(&$this, 'email_instructions'), 10, 2);
+ add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 2 );
}
@@ -70,7 +69,8 @@ class WC_BACS extends WC_Payment_Gateway {
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
- 'default' => __( 'Direct Bank Transfer', 'woocommerce' )
+ 'default' => __( 'Direct Bank Transfer', 'woocommerce' ),
+ 'desc_tip' => true,
),
'description' => array(
'title' => __( 'Customer Message', 'woocommerce' ),
@@ -111,13 +111,11 @@ class WC_BACS extends WC_Payment_Gateway {
'iban' => array(
'title' => __( 'IBAN', 'woocommerce' ),
'type' => 'text',
- 'description' => __( 'Your bank may require this for international payments','woocommerce'),
'default' => ''
),
'bic' => array(
'title' => __( 'BIC (formerly Swift)', 'woocommerce' ),
'type' => 'text',
- 'description' => __('Your bank may require this for international payments','woocommerce'),
'default' => ''
),
@@ -248,20 +246,4 @@ class WC_BACS extends WC_Payment_Gateway {
);
}
-}
-
-
-/**
- * Add the gateway to WooCommerce
- *
- * @access public
- * @param array $methods
- * @package WooCommerce/Classes/Payment
- * @return array
- */
-function add_bacs_gateway( $methods ) {
- $methods[] = 'WC_BACS';
- return $methods;
-}
-
-add_filter('woocommerce_payment_gateways', 'add_bacs_gateway' );
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/classes/gateways/cheque/class-wc-cheque.php b/classes/gateways/cheque/class-wc-gateway-cheque.php
similarity index 82%
rename from classes/gateways/cheque/class-wc-cheque.php
rename to classes/gateways/cheque/class-wc-gateway-cheque.php
index 520a0e29520..252fc74f0ce 100755
--- a/classes/gateways/cheque/class-wc-cheque.php
+++ b/classes/gateways/cheque/class-wc-gateway-cheque.php
@@ -1,19 +1,19 @@
has_fields = false;
$this->method_title = __( 'Cheque', 'woocommerce' );
- // Load the form fields.
- $this->init_form_fields();
-
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
// Define user set variables
- $this->title = $this->settings['title'];
- $this->description = $this->settings['description'];
+ $this->title = $this->get_option( 'title' );
+ $this->description = $this->get_option( 'description' );
// Actions
- add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
- add_action('woocommerce_thankyou_cheque', array(&$this, 'thankyou_page'));
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
+ add_action( 'woocommerce_thankyou_cheque', array( $this, 'thankyou_page' ) );
// Customer Emails
- add_action('woocommerce_email_before_order_table', array(&$this, 'email_instructions'), 10, 2);
+ add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 2 );
}
@@ -65,7 +63,8 @@ class WC_Cheque extends WC_Payment_Gateway {
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
- 'default' => __( 'Cheque Payment', 'woocommerce' )
+ 'default' => __( 'Cheque Payment', 'woocommerce' ),
+ 'desc_tip' => true,
),
'description' => array(
'title' => __( 'Customer Message', 'woocommerce' ),
@@ -161,20 +160,4 @@ class WC_Cheque extends WC_Payment_Gateway {
}
-}
-
-
-/**
- * Add the gateway to WooCommerce
- *
- * @access public
- * @param array $methods
- * @package WooCommerce/Classes/Payment
- * @return array
- */
-function add_cheque_gateway( $methods ) {
- $methods[] = 'WC_Cheque';
- return $methods;
-}
-
-add_filter('woocommerce_payment_gateways', 'add_cheque_gateway' );
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/classes/gateways/cod/class-wc-cod.php b/classes/gateways/cod/class-wc-gateway-cod.php
similarity index 74%
rename from classes/gateways/cod/class-wc-cod.php
rename to classes/gateways/cod/class-wc-gateway-cod.php
index 75d7229bcad..e6ac740d527 100644
--- a/classes/gateways/cod/class-wc-cod.php
+++ b/classes/gateways/cod/class-wc-gateway-cod.php
@@ -1,19 +1,19 @@
id = 'cod';
- $this->icon = apply_filters('woocommerce_cod_icon', '');
+ $this->id = 'cod';
+ $this->icon = apply_filters( 'woocommerce_cod_icon', '' );
$this->method_title = __( 'Cash on Delivery', 'woocommerce' );
- $this->has_fields = false;
+ $this->has_fields = false;
- // Load the form fields.
+ // Load the settings
$this->init_form_fields();
-
- // Load the settings.
$this->init_settings();
- // Define user set variables
- $this->title = $this->settings['title'];
- $this->description = $this->settings['description'];
- $this->instructions = $this->settings['instructions'];
- $this->enable_for_methods = empty( $this->settings['enable_for_methods'] ) ? array() : $this->settings['enable_for_methods'];
+ // Get settings
+ $this->title = $this->get_option( 'title' );
+ $this->description = $this->get_option( 'description' );
+ $this->instructions = $this->get_option( 'instructions' );
+ $this->enable_for_methods = $this->get_option( 'enable_for_methods', array() );
- add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
- add_action('woocommerce_thankyou_cod', array(&$this, 'thankyou'));
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
+ add_action( 'woocommerce_thankyou_cod', array( $this, 'thankyou' ) );
}
@@ -72,9 +70,10 @@ class WC_COD extends WC_Payment_Gateway {
$shipping_methods = array();
- foreach ( $woocommerce->shipping->load_shipping_methods() as $method ) {
- $shipping_methods[ $method->id ] = $method->get_title();
- }
+ if ( is_admin() )
+ foreach ( $woocommerce->shipping->load_shipping_methods() as $method ) {
+ $shipping_methods[ $method->id ] = $method->get_title();
+ }
$this->form_fields = array(
'enabled' => array(
@@ -88,19 +87,20 @@ class WC_COD extends WC_Payment_Gateway {
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Payment method title that the customer will see on your website.', 'woocommerce' ),
- 'default' => __( 'Cash on Delivery', 'woocommerce' )
+ 'default' => __( 'Cash on Delivery', 'woocommerce' ),
+ 'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your website.', 'woocommerce' ),
- 'default' => 'Pay with cash upon delivery.'
+ 'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ),
),
'instructions' => array(
'title' => __( 'Instructions', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Instructions that will be added to the thank you page.', 'woocommerce' ),
- 'default' => 'Pay with cash upon delivery.'
+ 'default' => __( 'Pay with cash upon delivery.', 'woocommerce' )
),
'enable_for_methods' => array(
'title' => __( 'Enable for shipping methods', 'woocommerce' ),
@@ -109,7 +109,8 @@ class WC_COD extends WC_Payment_Gateway {
'css' => 'width: 450px;',
'default' => '',
'description' => __( 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woocommerce' ),
- 'options' => $shipping_methods
+ 'options' => $shipping_methods,
+ 'desc_tip' => true,
)
);
}
@@ -195,23 +196,7 @@ class WC_COD extends WC_Payment_Gateway {
* @return void
*/
function thankyou() {
- if ($this->instructions!='') { echo wpautop($this->instructions); }
+ echo $this->instructions != '' ? wpautop( $this->instructions ) : '';
}
-}
-
-
-/**
- * Add the gateway to WooCommerce
- *
- * @access public
- * @param array $methods
- * @package WooCommerce/Classes/Payment
- * @return array
- */
-function woocommerce_cod_add_gateway( $methods ) {
- $methods[] = 'WC_COD';
- return $methods;
-}
-
-add_filter( 'woocommerce_payment_gateways', 'woocommerce_cod_add_gateway' );
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/classes/gateways/mijireh/assets/images/mijireh-logo.png b/classes/gateways/mijireh/assets/images/mijireh-logo.png
new file mode 100644
index 00000000000..5a2cb8f06f7
Binary files /dev/null and b/classes/gateways/mijireh/assets/images/mijireh-logo.png differ
diff --git a/classes/gateways/mijireh/assets/js/page_slurp.js b/classes/gateways/mijireh/assets/js/page_slurp.js
index 4af157365d5..959b4bb868c 100644
--- a/classes/gateways/mijireh/assets/js/page_slurp.js
+++ b/classes/gateways/mijireh/assets/js/page_slurp.js
@@ -6,11 +6,11 @@
action: 'page_slurp',
page_id: page_id
};
-
+
$('#page_slurp').attr('disabled', 'disabled');
$('#slurp_progress').show();
$('#slurp_progress_bar').html('Starting up');
-
+
$.post(ajaxurl, data, function(job_id) {
// The job id is the id for the page slurp job or 0 if the slurp failed
if(job_id.substring(0, 4) === 'http') {
@@ -22,7 +22,7 @@
pusher = new Pusher('7dcd33b15307eb9be5fb');
channel_name = 'slurp-' + job_id;
channel = pusher.subscribe(channel_name);
-
+
channel.bind('status_changed', function (data) {
// console.log(data);
if(data.level == 'info') {
@@ -37,14 +37,14 @@
}
});
}
-
+
})
.error(function(response) {
$('#slurp_progress').hide();
$('#page_slurp').removeAttr('disabled');
alert('Please make sure your Mijireh access key is correct');
});
-
+
return false;
});
diff --git a/classes/gateways/mijireh/class-wc-mijireh-checkout.php b/classes/gateways/mijireh/class-wc-gateway-mijireh.php
similarity index 88%
rename from classes/gateways/mijireh/class-wc-mijireh-checkout.php
rename to classes/gateways/mijireh/class-wc-gateway-mijireh.php
index 01c30bba012..1a220db3b43 100644
--- a/classes/gateways/mijireh/class-wc-mijireh-checkout.php
+++ b/classes/gateways/mijireh/class-wc-gateway-mijireh.php
@@ -1,19 +1,19 @@
icon = apply_filters( 'woocommerce_mijireh_checkout_icon', $woocommerce->plugin_url() . '/classes/gateways/mijireh/assets/images/credit_cards.png' );
$this->has_fields = false;
- // Load the form fields.
- $this->init_form_fields();
-
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
// Define user set variables
- $this->access_key = $this->settings['access_key'];
- $this->title = $this->settings['title'];
- $this->description = $this->settings['description'];
+ $this->access_key = $this->get_option( 'access_key' );
+ $this->title = $this->get_option( 'title' );
+ $this->description = $this->get_option( 'description' );
if ( $this->enabled && is_admin() ) {
$this->install_slurp_page();
-
- // Hooks
- add_action( 'add_meta_boxes', array( &$this, 'add_page_slurp_meta' ) );
- add_action( 'wp_ajax_page_slurp', array( &$this, 'page_slurp' ) );
}
// Save options
- add_action( 'woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ) );
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
// Payment listener/API hook
- add_action( 'woocommerce_api_wc_mijireh_checkout', array( &$this, 'mijireh_notification' ) );
- }
-
- /**
- * init_mijireh function.
- *
- * @access public
- */
- public function init_mijireh() {
- if ( ! class_exists( 'Mijireh' ) ) {
- require_once 'includes/Mijireh.php';
-
- Mijireh::$access_key = $this->access_key;
- }
+ add_action( 'woocommerce_api_wc_gateway_mijireh', array( $this, 'mijireh_notification' ) );
}
/**
@@ -96,25 +77,6 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
}
}
- /**
- * page_slurp function.
- *
- * @access public
- * @return void
- */
- public function page_slurp() {
-
- $this->init_mijireh();
-
- $page = get_page( absint( $_POST['page_id'] ) );
- $url = get_permalink( $page->ID );
- wp_update_post( array( 'ID' => $page->ID, 'post_status' => 'publish' ) );
- $job_id = Mijireh::slurp( $url );
- wp_update_post( array( 'ID' => $page->ID, 'post_status' => 'private' ) );
- echo $job_id;
- die;
- }
-
/**
* mijireh_notification function.
*
@@ -166,13 +128,15 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
'title' => __( 'Access Key', 'woocommerce' ),
'type' => 'text',
'description' => __( 'The Mijireh access key for your store.', 'woocommerce' ),
- 'default' => ''
+ 'default' => '',
+ 'desc_tip' => true,
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
- 'default' => __( 'Credit Card', 'woocommerce' )
+ 'default' => __( 'Credit Card', 'woocommerce' ),
+ 'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
@@ -305,7 +269,7 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
$mj_order->add_meta_data( 'wc_order_id', $order_id );
// Set URL for mijireh payment notificatoin - use WC API
- $mj_order->return_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'WC_Mijireh_Checkout', home_url( '/' ) ) );
+ $mj_order->return_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'WC_Gateway_Mijireh', home_url( '/' ) ) );
// Identify woocommerce
$mj_order->partner_id = 'woo';
@@ -323,16 +287,57 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
}
+ /**
+ * init_mijireh function.
+ *
+ * @access public
+ */
+ public function init_mijireh() {
+ if ( ! class_exists( 'Mijireh' ) ) {
+ require_once 'includes/Mijireh.php';
+
+ if ( ! isset( $this ) ) {
+ $settings = get_option( 'woocommerce_' . 'mijireh_checkout' . '_settings', null );
+ $key = ! empty( $settings['access_key'] ) ? $settings['access_key'] : '';
+ } else {
+ $key = $this->access_key;
+ }
+
+ Mijireh::$access_key = $key;
+ }
+ }
+
+
+ /**
+ * page_slurp function.
+ *
+ * @access public
+ * @return void
+ */
+ public static function page_slurp() {
+
+ self::init_mijireh();
+
+ $page = get_page( absint( $_POST['page_id'] ) );
+ $url = get_permalink( $page->ID );
+ wp_update_post( array( 'ID' => $page->ID, 'post_status' => 'publish' ) );
+ $job_id = Mijireh::slurp( $url );
+ wp_update_post( array( 'ID' => $page->ID, 'post_status' => 'private' ) );
+ echo $job_id;
+ die;
+ }
+
+
/**
* add_page_slurp_meta function.
*
* @access public
* @return void
*/
- public function add_page_slurp_meta() {
+ public static function add_page_slurp_meta() {
global $woocommerce;
- if ( $this->is_slurp_page() ) {
+ if ( self::is_slurp_page() ) {
wp_enqueue_style( 'mijireh_css', $woocommerce->plugin_url() . '/classes/gateways/mijireh/assets/css/mijireh.css' );
wp_enqueue_script( 'pusher', 'https://d3dy5gmtp8yhk7.cloudfront.net/1.11/pusher.min.js', null, false, true );
wp_enqueue_script( 'page_slurp', $woocommerce->plugin_url() . '/classes/gateways/mijireh/assets/js/page_slurp.js', array('jquery'), false, true );
@@ -340,7 +345,7 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
add_meta_box(
'slurp_meta_box', // $id
'Mijireh Page Slurp', // $title
- array( &$this, 'draw_page_slurp_meta_box' ), // $callback
+ array( 'WC_Gateway_Mijireh', 'draw_page_slurp_meta_box' ), // $callback
'page', // $page
'normal', // $context
'high' // $priority
@@ -355,7 +360,7 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
* @access public
* @return void
*/
- public function is_slurp_page() {
+ public static function is_slurp_page() {
global $post;
$is_slurp = false;
if ( isset( $post ) && is_object( $post ) ) {
@@ -375,10 +380,10 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
* @param mixed $post
* @return void
*/
- public function draw_page_slurp_meta_box( $post ) {
+ public static function draw_page_slurp_meta_box( $post ) {
global $woocommerce;
- $this->init_mijireh();
+ self::init_mijireh();
echo "";
echo "
Slurp your custom checkout page! ";
@@ -388,20 +393,4 @@ class WC_Mijireh_Checkout extends WC_Payment_Gateway {
echo '
Preview Checkout Page ';
echo "
";
}
-}
-
-
-/**
- * Add the gateway to WooCommerce
- *
- * @access public
- * @package WooCommerce/Classes/Payment
- * @param array $methods
- * @return array
- */
-function add_mijireh_gateway( $methods ) {
- $methods[] = 'WC_Mijireh_Checkout';
- return $methods;
-}
-
-add_filter( 'woocommerce_payment_gateways', 'add_mijireh_gateway' );
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/classes/gateways/mijireh/includes/Rest.php b/classes/gateways/mijireh/includes/Rest.php
index 9fbbb91b7eb..aef02d575ca 100755
--- a/classes/gateways/mijireh/includes/Rest.php
+++ b/classes/gateways/mijireh/includes/Rest.php
@@ -14,7 +14,7 @@ class Mijireh_Rest {
public $curl_opts = array(
CURLOPT_RETURNTRANSFER => true, // return result instead of echoing
CURLOPT_SSL_VERIFYPEER => false, // stop cURL from verifying the peer's certificate
- CURLOPT_MAXREDIRS => 10 // but dont redirect more than 10 times
+ CURLOPT_MAXREDIRS => 10 // but don't redirect more than 10 times
);
public $base_url;
diff --git a/classes/gateways/paypal/class-wc-paypal.php b/classes/gateways/paypal/class-wc-gateway-paypal.php
similarity index 79%
rename from classes/gateways/paypal/class-wc-paypal.php
rename to classes/gateways/paypal/class-wc-gateway-paypal.php
index 25b63555413..eb3719a720c 100644
--- a/classes/gateways/paypal/class-wc-paypal.php
+++ b/classes/gateways/paypal/class-wc-gateway-paypal.php
@@ -1,19 +1,19 @@
id = 'paypal';
- $this->icon = apply_filters( 'woocommerce_paypal_icon', $woocommerce->plugin_url() . '/assets/images/icons/paypal.png' );
- $this->has_fields = false;
- $this->liveurl = 'https://www.paypal.com/webscr';
- $this->testurl = 'https://www.sandbox.paypal.com/webscr';
- $this->method_title = __( 'PayPal', 'woocommerce' );
- $this->notify_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'WC_Paypal', home_url( '/' ) ) );
-
- // Load the form fields.
- $this->init_form_fields();
+ $this->id = 'paypal';
+ $this->icon = apply_filters( 'woocommerce_paypal_icon', $woocommerce->plugin_url() . '/assets/images/icons/paypal.png' );
+ $this->has_fields = false;
+ $this->liveurl = 'https://www.paypal.com/cgi-bin/webscr';
+ $this->testurl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
+ $this->method_title = __( 'PayPal', 'woocommerce' );
+ $this->notify_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'WC_Gateway_Paypal', home_url( '/' ) ) );
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
// Define user set variables
- $this->title = $this->settings['title'];
- $this->description = $this->settings['description'];
- $this->email = $this->settings['email'];
- $this->testmode = $this->settings['testmode'];
- $this->send_shipping = $this->settings['send_shipping'];
- $this->address_override = isset( $this->settings['address_override'] ) ? $this->settings['address_override'] : 'no';
- $this->debug = $this->settings['debug'];
- $this->form_submission_method = ( isset( $this->settings['form_submission_method'] ) && $this->settings['form_submission_method'] == 'yes' ) ? true : false;
- $this->page_style = ( isset( $this->settings['page_style'] ) ) ? $this->settings['page_style'] : '';
- $this->invoice_prefix = ! empty( $this->settings['invoice_prefix'] ) ? $this->settings['invoice_prefix'] : 'WC-';
+ $this->title = $this->get_option( 'title' );
+ $this->description = $this->get_option( 'description' );
+ $this->email = $this->get_option( 'email' );
+ $this->receiver_email = $this->get_option( 'receiver_email', $this->email );
+ $this->testmode = $this->get_option( 'testmode' );
+ $this->send_shipping = $this->get_option( 'send_shipping' );
+ $this->address_override = $this->get_option( 'address_override' );
+ $this->debug = $this->get_option( 'debug' );
+ $this->form_submission_method = $this->get_option( 'form_submission_method' ) == 'yes' ? true : false;
+ $this->page_style = $this->get_option( 'page_style' );
+ $this->invoice_prefix = $this->get_option( 'invoice_prefix', 'WC-' );
// Logs
- if ($this->debug=='yes') $this->log = $woocommerce->logger();
+ if ( 'yes' == $this->debug )
+ $this->log = $woocommerce->logger();
// Actions
- add_action( 'valid-paypal-standard-ipn-request', array( &$this, 'successful_request' ) );
- add_action( 'woocommerce_receipt_paypal', array( &$this, 'receipt_page' ) );
- add_action( 'woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ) );
+ add_action( 'valid-paypal-standard-ipn-request', array( $this, 'successful_request' ) );
+ add_action( 'woocommerce_receipt_paypal', array( $this, 'receipt_page' ) );
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
// Payment listener/API hook
- add_action( 'woocommerce_api_wc_paypal', array( &$this, 'check_ipn_response' ) );
+ add_action( 'woocommerce_api_wc_gateway_paypal', array( $this, 'check_ipn_response' ) );
if ( !$this->is_valid_for_use() ) $this->enabled = false;
}
@@ -74,7 +74,7 @@ class WC_Paypal extends WC_Payment_Gateway {
* @return bool
*/
function is_valid_for_use() {
- if (!in_array(get_woocommerce_currency(), array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB' ))) return false;
+ if ( ! in_array( get_woocommerce_currency(), apply_filters( 'woocommerce_paypal_supported_currencies', array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB' ) ) ) ) return false;
return true;
}
@@ -87,27 +87,24 @@ class WC_Paypal extends WC_Payment_Gateway {
*/
public function admin_options() {
- ?>
-
-
-
-
+
+ __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
- 'default' => __( 'PayPal', 'woocommerce' )
+ 'default' => __( 'PayPal', 'woocommerce' ),
+ 'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
@@ -141,13 +139,24 @@ class WC_Paypal extends WC_Payment_Gateway {
'title' => __( 'PayPal Email', 'woocommerce' ),
'type' => 'email',
'description' => __( 'Please enter your PayPal email address; this is needed in order to take payment.', 'woocommerce' ),
- 'default' => ''
+ 'default' => '',
+ 'desc_tip' => true,
+ 'placeholder' => 'you@youremail.com'
+ ),
+ 'receiver_email' => array(
+ 'title' => __( 'Receiver Email', 'woocommerce' ),
+ 'type' => 'email',
+ 'description' => __( 'If this differs from the email entered above, input your main receiver email for your PayPal account. This is used to validate IPN requests.', 'woocommerce' ),
+ 'default' => '',
+ 'desc_tip' => true,
+ 'placeholder' => 'you@youremail.com'
),
'invoice_prefix' => array(
'title' => __( 'Invoice Prefix', 'woocommerce' ),
'type' => 'text',
- 'description' => __( 'Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unqiue as PayPal will not allow orders with the same invoice number.', 'woocommerce' ),
- 'default' => 'WC-'
+ 'description' => __( 'Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number.', 'woocommerce' ),
+ 'default' => 'WC-',
+ 'desc_tip' => true,
),
'form_submission_method' => array(
'title' => __( 'Submission method', 'woocommerce' ),
@@ -160,7 +169,9 @@ class WC_Paypal extends WC_Payment_Gateway {
'title' => __( 'Page Style', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Optionally enter the name of the page style you wish to use. These are defined within your PayPal account.', 'woocommerce' ),
- 'default' => ''
+ 'default' => '',
+ 'desc_tip' => true,
+ 'placeholder' => __( 'Optional', 'woocommerce' )
),
'shipping' => array(
'title' => __( 'Shipping options', 'woocommerce' ),
@@ -218,7 +229,7 @@ class WC_Paypal extends WC_Payment_Gateway {
$order_id = $order->id;
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Generating payment form for order ' . $order->get_order_number() . '. Notify URL: ' . $this->notify_url );
if ( in_array( $order->billing_country, array( 'US','CA' ) ) ) {
@@ -315,7 +326,7 @@ class WC_Paypal extends WC_Payment_Gateway {
// Shipping Cost
// No longer using shipping_1 because
// a) paypal ignore it if *any* shipping rules are within paypal
- // b) paypal ignore anyhing over 5 digits, so 999.99 is the max
+ // b) paypal ignore anything over 5 digits, so 999.99 is the max
// $paypal_args['shipping_1'] = number_format( $order->get_shipping() + $order->get_shipping_tax() , 2, '.', '' );
if ( ( $order->get_shipping() + $order->get_shipping_tax() ) > 0 ) {
$paypal_args['item_name_2'] = __( 'Shipping via', 'woocommerce' ) . ' ' . ucwords( $order->shipping_method_title );
@@ -496,23 +507,24 @@ class WC_Paypal extends WC_Payment_Gateway {
function check_ipn_request_is_valid() {
global $woocommerce;
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Checking IPN response is valid...' );
// Get recieved values from post data
- $received_values = (array) stripslashes_deep( $_POST );
-
- // Add cmd to the post array
- $received_values['cmd'] = '_notify-validate';
+ $received_values = array( 'cmd' => '_notify-validate' );
+ $received_values += stripslashes_deep( $_POST );
// Send back post vars to paypal
$params = array(
'body' => $received_values,
'sslverify' => false,
- 'timeout' => 30,
+ 'timeout' => 60,
'user-agent' => 'WooCommerce/' . $woocommerce->version
);
+ if ( 'yes' == $this->debug )
+ $this->log->add( 'paypal', 'IPN Request: ' . print_r( $params, true ) );
+
// Get url
if ( $this->testmode == 'yes' )
$paypal_adr = $this->testurl;
@@ -522,21 +534,21 @@ class WC_Paypal extends WC_Payment_Gateway {
// Post back to get a response
$response = wp_remote_post( $paypal_adr, $params );
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'IPN Response: ' . print_r( $response, true ) );
// check to see if the request was valid
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && ( strcmp( $response['body'], "VERIFIED" ) == 0 ) ) {
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Received valid response from PayPal' );
return true;
}
- if ( $this->debug == 'yes' ) {
+ if ( 'yes' == $this->debug ) {
$this->log->add( 'paypal', 'Received invalid response from PayPal' );
if ( is_wp_error( $response ) )
- $this->log->add( 'paypal', 'Error response: ' . $result->get_error_message() );
+ $this->log->add( 'paypal', 'Error response: ' . $response->get_error_message() );
}
return false;
@@ -553,9 +565,7 @@ class WC_Paypal extends WC_Payment_Gateway {
@ob_clean();
- $_POST = stripslashes_deep( $_POST );
-
- if ( $this->check_ipn_request_is_valid() ) {
+ if ( ! empty( $_POST ) && $this->check_ipn_request_is_valid() ) {
header( 'HTTP/1.1 200 OK' );
@@ -580,20 +590,21 @@ class WC_Paypal extends WC_Payment_Gateway {
function successful_request( $posted ) {
global $woocommerce;
+ $posted = stripslashes_deep( $posted );
+
// Custom holds post ID
if ( ! empty( $posted['invoice'] ) && ! empty( $posted['custom'] ) ) {
$order = $this->get_paypal_order( $posted );
+ if ( 'yes' == $this->debug )
+ $this->log->add( 'paypal', 'Found order #' . $order->id );
+
// Lowercase returned variables
$posted['payment_status'] = strtolower( $posted['payment_status'] );
$posted['txn_type'] = strtolower( $posted['txn_type'] );
- // Sandbox fix
- if ( $posted['test_ipn'] == 1 && $posted['payment_status'] == 'pending' )
- $posted['payment_status'] = 'completed';
-
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Payment status: ' . $posted['payment_status'] );
// We are here so lets check status and do actions
@@ -602,15 +613,15 @@ class WC_Paypal extends WC_Payment_Gateway {
// Check order not already completed
if ( $order->status == 'completed' ) {
- if ( $this->debug == 'yes' )
- $this->log->add( 'paypal', 'Aborting, Order #' . $order_id . ' is already complete.' );
+ if ( 'yes' == $this->debug )
+ $this->log->add( 'paypal', 'Aborting, Order #' . $order->id . ' is already complete.' );
exit;
}
// Check valid txn_type
$accepted_types = array( 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money' );
if ( ! in_array( $posted['txn_type'], $accepted_types ) ) {
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Aborting, Invalid type:' . $posted['txn_type'] );
exit;
}
@@ -618,7 +629,7 @@ class WC_Paypal extends WC_Payment_Gateway {
// Validate Amount
if ( $order->get_total() != $posted['mc_gross'] ) {
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Payment error: Amounts do not match (gross ' . $posted['mc_gross'] . ')' );
// Put this order on-hold for manual checking
@@ -627,6 +638,17 @@ class WC_Paypal extends WC_Payment_Gateway {
exit;
}
+ // Validate Email Address
+ if ( strcasecmp( trim( $posted['receiver_email'] ), trim( $this->receiver_email ) ) != 0 ) {
+ if ( 'yes' == $this->debug )
+ $this->log->add( 'paypal', "IPN Response is for another one: {$posted['receiver_email']} our email is {$this->receiver_email}" );
+
+ // Put this order on-hold for manual checking
+ $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s).', 'woocommerce' ), $posted['receiver_email'] ) );
+
+ exit;
+ }
+
// Store PP Details
if ( ! empty( $posted['payer_email'] ) )
update_post_meta( $order_id, 'Payer PayPal address', $posted['payer_email'] );
@@ -643,7 +665,7 @@ class WC_Paypal extends WC_Payment_Gateway {
$order->add_order_note( __( 'IPN payment completed', 'woocommerce' ) );
$order->payment_complete();
- if ( $this->debug == 'yes' )
+ if ( 'yes' == $this->debug )
$this->log->add( 'paypal', 'Payment complete.' );
break;
@@ -669,7 +691,7 @@ class WC_Paypal extends WC_Payment_Gateway {
sprintf( __( 'Order %s has been marked as refunded - PayPal reason code: %s', 'woocommerce' ), $order->get_order_number(), $posted['reason_code'] )
);
- $mailer->send( get_option( 'woocommerce_new_order_email_recipient' ), sprintf( __( 'Payment for order %s refunded/reversed', 'woocommerce' ), $order->get_order_number() ), $message );
+ $mailer->send( get_option( 'admin_email' ), sprintf( __( 'Payment for order %s refunded/reversed', 'woocommerce' ), $order->get_order_number() ), $message );
}
@@ -687,7 +709,7 @@ class WC_Paypal extends WC_Payment_Gateway {
sprintf(__( 'Order %s has been marked as refunded - PayPal reason code: %s', 'woocommerce' ), $order->get_order_number(), $posted['reason_code'] )
);
- $mailer->send( get_option( 'woocommerce_new_order_email_recipient' ), sprintf( __( 'Payment for order %s refunded/reversed', 'woocommerce' ), $order->get_order_number() ), $message );
+ $mailer->send( get_option( 'admin_email' ), sprintf( __( 'Payment for order %s refunded/reversed', 'woocommerce' ), $order->get_order_number() ), $message );
break;
default :
@@ -742,18 +764,9 @@ class WC_Paypal extends WC_Payment_Gateway {
}
-
-/**
- * Add the gateway to WooCommerce
- *
- * @access public
- * @param array $methods
- * @package WooCommerce/Classes/Payment
- * @return array
- */
-function add_paypal_gateway( $methods ) {
- $methods[] = 'WC_Paypal';
- return $methods;
-}
-
-add_filter('woocommerce_payment_gateways', 'add_paypal_gateway' );
\ No newline at end of file
+class WC_Paypal extends WC_Gateway_Paypal {
+ public function __construct() {
+ _deprecated_function( 'WC_Paypal', '1.4', 'WC_Gateway_Paypal' );
+ parent::__construct();
+ }
+}
\ No newline at end of file
diff --git a/classes/integrations/google-analytics/class-wc-google-analytics.php b/classes/integrations/google-analytics/class-wc-google-analytics.php
index f490f8f5926..421c69a5479 100644
--- a/classes/integrations/google-analytics/class-wc-google-analytics.php
+++ b/classes/integrations/google-analytics/class-wc-google-analytics.php
@@ -1,4 +1,7 @@
method_title = __( 'Google Analytics', 'woocommerce' );
$this->method_description = __( 'Google Analytics is a free service offered by Google that generates detailed statistics about the visitors to a website.', 'woocommerce' );
- // Load the form fields.
- $this->init_form_fields();
-
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
// Define user set variables
- $this->ga_id = $this->settings['ga_id'];
- $this->ga_standard_tracking_enabled = $this->settings['ga_standard_tracking_enabled'];
- $this->ga_ecommerce_tracking_enabled = $this->settings['ga_ecommerce_tracking_enabled'];
- $this->ga_event_tracking_enabled = $this->settings['ga_event_tracking_enabled'];
+ $this->ga_id = $this->get_option( 'ga_id' );
+ $this->ga_standard_tracking_enabled = $this->get_option( 'ga_standard_tracking_enabled' );
+ $this->ga_ecommerce_tracking_enabled = $this->get_option( 'ga_ecommerce_tracking_enabled' );
+ $this->ga_event_tracking_enabled = $this->get_option( 'ga_event_tracking_enabled' );
// Actions
- add_action( 'woocommerce_update_options_integration_google_analytics', array( &$this, 'process_admin_options') );
+ add_action( 'woocommerce_update_options_integration_google_analytics', array( $this, 'process_admin_options') );
// Tracking code
- add_action( 'wp_footer', array( &$this, 'google_tracking_code' ) );
- add_action( 'woocommerce_thankyou', array( &$this, 'ecommerce_tracking_code' ) );
+ add_action( 'wp_footer', array( $this, 'google_tracking_code' ) );
+ add_action( 'woocommerce_thankyou', array( $this, 'ecommerce_tracking_code' ) );
// Event tracking code
- add_action( 'woocommerce_after_add_to_cart_button', array( &$this, 'add_to_cart' ) );
- add_action( 'woocommerce_after_shop_loop', array( &$this, 'loop_add_to_cart' ) );
+ add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart' ) );
+ add_action( 'woocommerce_after_shop_loop', array( $this, 'loop_add_to_cart' ) );
}
@@ -146,7 +144,7 @@ class WC_Google_Analytics extends WC_Integration {
function ecommerce_tracking_code( $order_id ) {
global $woocommerce;
- if ( $this->ga_ecommerce_tracking_enabled == "no" || current_user_can('manage_options') )
+ if ( $this->ga_ecommerce_tracking_enabled == "no" || current_user_can('manage_options') || get_post_meta( $order_id, '_ga_tracked', true ) == 1 )
return;
$tracking_id = $this->ga_id;
@@ -154,7 +152,7 @@ class WC_Google_Analytics extends WC_Integration {
if ( ! $tracking_id ) return;
// Doing eCommerce tracking so unhook standard tracking from the footer
- remove_action( 'wp_footer', array( &$this, 'google_tracking_code' ) );
+ remove_action( 'wp_footer', array( $this, 'google_tracking_code' ) );
// Get the order and output tracking code
$order = new WC_Order( $order_id );
@@ -235,6 +233,8 @@ class WC_Google_Analytics extends WC_Integration {
";
echo '';
+
+ update_post_meta( $order_id, '_ga_tracked', 1 );
}
@@ -254,8 +254,8 @@ class WC_Google_Analytics extends WC_Integration {
$parameters = array();
// Add single quotes to allow jQuery to be substituted into _trackEvent parameters
$parameters['category'] = "'" . __( 'Products', 'woocommerce' ) . "'";
- $parameters['action'] = "'" . __( 'Add to Cart', 'woocommerce' ) . "'";
- $parameters['label'] = "'#" . esc_js( $product->id ) . "'";
+ $parameters['action'] = "'" . __( 'Add to cart', 'woocommerce' ) . "'";
+ $parameters['label'] = "'" . esc_js( $product->get_sku() ? __('SKU:', 'woocommerce') . ' ' . $product->get_sku() : "#" . $product->id ) . "'";
$this->event_tracking_code( $parameters, '.single_add_to_cart_button' );
}
@@ -275,7 +275,7 @@ class WC_Google_Analytics extends WC_Integration {
// Add single quotes to allow jQuery to be substituted into _trackEvent parameters
$parameters['category'] = "'" . __( 'Products', 'woocommerce' ) . "'";
$parameters['action'] = "'" . __( 'Add to Cart', 'woocommerce' ) . "'";
- $parameters['label'] = "'#' + $(this).attr('data-product_id')"; // Product ID
+ $parameters['label'] = "($(this).data('product_sku')) ? ('SKU: ' + $(this).data('product_sku')) : ('#' + $(this).data('product_id'))"; // Product SKU or ID
$this->event_tracking_code( $parameters, '.add_to_cart_button:not(.product_type_variable, .product_type_grouped)' );
}
@@ -331,4 +331,4 @@ function add_google_analytics_integration( $integrations ) {
return $integrations;
}
-add_filter('woocommerce_integrations', 'add_google_analytics_integration' );
\ No newline at end of file
+add_filter('woocommerce_integrations', 'add_google_analytics_integration' );
diff --git a/classes/integrations/sharedaddy/class-wc-sharedaddy.php b/classes/integrations/sharedaddy/class-wc-sharedaddy.php
index 05e2cb2bd20..53e6f943856 100644
--- a/classes/integrations/sharedaddy/class-wc-sharedaddy.php
+++ b/classes/integrations/sharedaddy/class-wc-sharedaddy.php
@@ -1,4 +1,7 @@
method_title = __( 'ShareDaddy', 'woocommerce' );
$this->method_description = __( 'ShareDaddy is a sharing plugin bundled with JetPack.', 'woocommerce' );
- // Load the form fields.
- $this->init_form_fields();
-
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
- // Define user set variables
- $this->enabled = $this->settings['enabled'];
-
// Actions
- add_action( 'woocommerce_update_options_integration_sharedaddy', array( &$this, 'process_admin_options') );
+ add_action( 'woocommerce_update_options_integration_sharedaddy', array( $this, 'process_admin_options' ) );
// Share widget
- add_action( 'woocommerce_share', array( &$this, 'sharedaddy_code') );
+ add_action( 'woocommerce_share', array( $this, 'sharedaddy_code' ) );
}
diff --git a/classes/integrations/sharethis/class-wc-sharethis.php b/classes/integrations/sharethis/class-wc-sharethis.php
index e7d1c9d7afe..c16be656af8 100644
--- a/classes/integrations/sharethis/class-wc-sharethis.php
+++ b/classes/integrations/sharethis/class-wc-sharethis.php
@@ -1,4 +1,7 @@
';
- // Load the form fields.
- $this->init_form_fields();
-
// Load the settings.
+ $this->init_form_fields();
$this->init_settings();
// Define user set variables
- $this->publisher_id = $this->settings['publisher_id'];
- $this->sharethis_code = $this->settings['sharethis_code'];
-
- if ( ! $this->sharethis_code ) $this->settings['sharethis_code'] = $this->sharethis_code = $this->default_code;
+ $this->publisher_id = $this->get_option( 'publisher_id' );
+ $this->sharethis_code = $this->get_option( 'sharethis_code', $this->default_code );
// Actions
- add_action( 'woocommerce_update_options_integration_sharethis', array( &$this, 'process_admin_options') );
+ add_action( 'woocommerce_update_options_integration_sharethis', array( $this, 'process_admin_options' ) );
// Share widget
- add_action( 'woocommerce_share', array( &$this, 'sharethis_code') );
+ add_action( 'woocommerce_share', array( $this, 'sharethis_code' ) );
}
diff --git a/classes/integrations/shareyourcart/class-shareyourcart-woocommerce-extended.php b/classes/integrations/shareyourcart/class-shareyourcart-woocommerce-extended.php
index c165c32d2d3..a38713c5832 100644
--- a/classes/integrations/shareyourcart/class-shareyourcart-woocommerce-extended.php
+++ b/classes/integrations/shareyourcart/class-shareyourcart-woocommerce-extended.php
@@ -27,7 +27,7 @@ class ShareYourCartWooCommerceEx extends ShareYourCartWooCommerce {
}
public function showAdminMenu() {
- //since we have allready integrated this in our own settings page,
+ //since we have already integrated this in our own settings page,
//leave this function empty
}
@@ -46,8 +46,8 @@ class ShareYourCartWooCommerceEx extends ShareYourCartWooCommerce {
$this->settings['enabled'] = ( $value == 'active' ? 'yes' : 'no' );
break;
case "plugin_current_version":
- //this setting needs to be set globaly as well, in order to be recognized by other ShareYourCart integrations,
- //and to not interfear with one-another
+ //this setting needs to be set globally as well, in order to be recognized by other ShareYourCart integrations,
+ //and to not interfere with one-another
parent::setConfigValue($field, $value);
break;
}
diff --git a/classes/integrations/shareyourcart/class-wc-shareyourcart.php b/classes/integrations/shareyourcart/class-wc-shareyourcart.php
index c40c1179512..6e05304a70a 100644
--- a/classes/integrations/shareyourcart/class-wc-shareyourcart.php
+++ b/classes/integrations/shareyourcart/class-wc-shareyourcart.php
@@ -1,4 +1,7 @@
id = 'shareyourcart';
$this->method_title = __( 'ShareYourCart', 'woocommerce' );
- $this->method_description = __( 'Increase your social media exposure by 10 percent! ShareYourCart helps you get more customers by motivating satisfied customers to talk with their friends about your products. For help with ShareYourCart view the documentation .', 'woocommerce' );
+ $this->method_description = __( 'Increase your social media exposure by 10 percent! ShareYourCart helps you get more customers by motivating satisfied customers to talk with their friends about your products. For help with ShareYourCart view the documentation .', 'woocommerce' );
// Load the settings.
- $this->settings = ( array ) get_option( $this->plugin_id . $this->id . '_settings' ); //do not rely on the base implementation of init_settings
+ $this->init_form_fields();
+ $this->init_settings();
- if ( isset( $this->settings['enabled'] ) && $this->settings['enabled'] == 'yes' ) {
+ if ( $this->enabled == 'yes' ) {
//the classes need to be initialized
$this->init_share_your_cart();
diff --git a/classes/integrations/shareyourcart/class.shareyourcart-wp-woocommerce.php b/classes/integrations/shareyourcart/class.shareyourcart-wp-woocommerce.php
index 291bafaed4a..d062c61650e 100644
--- a/classes/integrations/shareyourcart/class.shareyourcart-wp-woocommerce.php
+++ b/classes/integrations/shareyourcart/class.shareyourcart-wp-woocommerce.php
@@ -202,7 +202,7 @@ class ShareYourCartWooCommerce extends ShareYourCartWordpressPlugin{
//WooCommerce actually echoes the image
ob_start();
- echo $product->get_image(); //older WooCommerce versions might allready echo, but newer versions don't, so force it anyway
+ echo $product->get_image(); //older WooCommerce versions might already echo, but newer versions don't, so force it anyway
$image = ob_get_clean();
//check is image actually a HTML img entity
diff --git a/classes/integrations/shareyourcart/sdk/class.shareyourcart-api.php b/classes/integrations/shareyourcart/sdk/class.shareyourcart-api.php
index 1ac7b9f735e..523dde495f6 100755
--- a/classes/integrations/shareyourcart/sdk/class.shareyourcart-api.php
+++ b/classes/integrations/shareyourcart/sdk/class.shareyourcart-api.php
@@ -90,7 +90,7 @@ class ShareYourCartAPI {
$httpCode = curl_getinfo($session, CURLINFO_HTTP_CODE);
curl_close($session);
- // If the operation was not succesfull, print the error
+ // If the operation was not successful, print the error
if($httpCode != 200)
throw new Exception($response);
@@ -151,7 +151,7 @@ class ShareYourCartAPI {
$httpCode = curl_getinfo($session, CURLINFO_HTTP_CODE);
curl_close($session);
- //if the operation was not succesfull, print the error
+ //if the operation was not successful, print the error
if($httpCode != 200)
throw new Exception(SyC::t('sdk',"Coupon Invalid: {coupon}", array('{coupon}' => $response)));
@@ -194,7 +194,7 @@ class ShareYourCartAPI {
$httpCode = curl_getinfo($session, CURLINFO_HTTP_CODE);
curl_close($session);
- // If the operation was not succesfull, return FALSE
+ // If the operation was not successful, return FALSE
if($httpCode != 200) {
if(isset($message)) $message = $response;
diff --git a/classes/integrations/shareyourcart/sdk/class.shareyourcart-base.php b/classes/integrations/shareyourcart/sdk/class.shareyourcart-base.php
index f11e53e0e14..d7cf3aba061 100755
--- a/classes/integrations/shareyourcart/sdk/class.shareyourcart-base.php
+++ b/classes/integrations/shareyourcart/sdk/class.shareyourcart-base.php
@@ -29,7 +29,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
//set exception handler
if(set_exception_handler(array(&$this,'UncaughtExceptionHandler')) !== null)
- restore_exception_handler(); //if there allready was an exception handler, revert back to it
+ restore_exception_handler(); //if there already was an exception handler, revert back to it
parent::__construct();
@@ -109,7 +109,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
/**
*
- * Return FALSE if the curent single product is out of stock, or not
+ * Return FALSE if the current single product is out of stock, or not
*
*/
public function isOutOfStock(){
@@ -225,7 +225,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
/**
*
* Check if this instance can load, or not!
- * This is ment so that at ALL times, only the latest plugin version will work
+ * This is meant so that at ALL times, only the latest plugin version will work
*
*/
protected function canLoad()
@@ -698,7 +698,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
//since we might have changed the status, REFRESH
$refresh = true;
}
- //check if the user want's to recover his account
+ //check if the user wants to recover his account
else if (@$_REQUEST['syc-account'] === 'recover'){
//by default, show the form if we are here
@@ -1071,7 +1071,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
$this->executeNonQuery($sql);
- //we can't relly on the fact that the table has been properly created, so check it!
+ //we can't rely on the fact that the table has been properly created, so check it!
if(!$this->existsTable($tableName))
throw new Exception(SyC::t('sdk','Cannot create table "{table_name}". Check your database permissions or manually run the following SQL command and try again:{sql} ', array('{table_name}' => $tableName,'{sql}' => nl2br($sql))));
}
@@ -1099,7 +1099,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
$sql = "DROP TABLE $tableName";
$this->executeNonQuery($sql);
- //we can't relly on the fact that the table has been properly droped, so check it!
+ //we can't rely on the fact that the table has been properly dropped, so check it!
if($this->existsTable($tableName))
throw new Exception(SyC::t('sdk','Cannot drop table "{table_name}". Check your database permissions or manually run the following SQL command and try again:{sql} ', array('{table_name}' => $tableName, '{sql}' => nl2br($sql))));
}
@@ -1118,7 +1118,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
//check if there is a file in the specified location
if(!file_exists($_viewFile_)){
- //the view has not been overrided, so use the SDK one
+ //the view has not been overridden, so use the SDK one
$_viewFile_ = dirname(__FILE__) . "/views/$_viewName_.php";
}
@@ -1266,7 +1266,7 @@ abstract class ShareYourCartBase extends ShareYourCartAPI {
/**
*
- * User to catch any unhandled exceptions and print them nicelly
+ * User to catch any unhandled exceptions and print them nicely
*
*/
public function UncaughtExceptionHandler(Exception $e) {
diff --git a/classes/integrations/shareyourcart/sdk/messages/cs/sdk.php b/classes/integrations/shareyourcart/sdk/messages/cs/sdk.php
index e1e9fb31db5..28052e882f3 100755
--- a/classes/integrations/shareyourcart/sdk/messages/cs/sdk.php
+++ b/classes/integrations/shareyourcart/sdk/messages/cs/sdk.php
@@ -71,7 +71,7 @@ return array (
'Save' => '',
'Show button by default on: ' => '',
'Standard Button' => '',
- 'This plugin allows you to easilly set the above meta properties directly in the post or page edit form' => '',
+ 'This plugin allows you to easily set the above meta properties directly in the post or page edit form' => '',
'To position the {brand} button, you need to override the following CSS classes' => '',
'Use Image Button' => '',
'Use Standard Button' => '',
diff --git a/classes/integrations/shareyourcart/sdk/messages/fr/sdk.php b/classes/integrations/shareyourcart/sdk/messages/fr/sdk.php
index e1e9fb31db5..802384494ad 100755
--- a/classes/integrations/shareyourcart/sdk/messages/fr/sdk.php
+++ b/classes/integrations/shareyourcart/sdk/messages/fr/sdk.php
@@ -71,7 +71,7 @@ return array (
'Save' => '',
'Show button by default on: ' => '',
'Standard Button' => '',
- 'This plugin allows you to easilly set the above meta properties directly in the post or page edit form' => '',
+ 'This plugin allows you to easily set the above meta properties directly in the post or page edit form' => '',
'To position the {brand} button, you need to override the following CSS classes' => '',
'Use Image Button' => '',
'Use Standard Button' => '',
@@ -79,6 +79,6 @@ return array (
'You can choose how much of a discount to give (in fixed amount, percentage, or free shipping) and to which social media channels it should it be applied. You can also define what the advertisement should say, so that it fully benefits your sales.' => '',
'or' => '',
'{brand} helps you get more customers by motivating satisfied customers to talk with their friends about your products. Each customer that promotes your products, via social media, will receive a coupon that they can apply to their shopping cart in order to get a small discount.' => '',
- '{css_class} for the horrizontal button' => '',
+ '{css_class} for the horizontal button' => '',
'{css_class} for the vertical button' => '',
);
diff --git a/classes/integrations/shareyourcart/sdk/messages/ro/sdk.php b/classes/integrations/shareyourcart/sdk/messages/ro/sdk.php
index e1e9fb31db5..28052e882f3 100755
--- a/classes/integrations/shareyourcart/sdk/messages/ro/sdk.php
+++ b/classes/integrations/shareyourcart/sdk/messages/ro/sdk.php
@@ -71,7 +71,7 @@ return array (
'Save' => '',
'Show button by default on: ' => '',
'Standard Button' => '',
- 'This plugin allows you to easilly set the above meta properties directly in the post or page edit form' => '',
+ 'This plugin allows you to easily set the above meta properties directly in the post or page edit form' => '',
'To position the {brand} button, you need to override the following CSS classes' => '',
'Use Image Button' => '',
'Use Standard Button' => '',
diff --git a/classes/integrations/shareyourcart/sdk/views/documentation.php b/classes/integrations/shareyourcart/sdk/views/documentation.php
index 9d350289ad2..9e8995d5814 100755
--- a/classes/integrations/shareyourcart/sdk/views/documentation.php
+++ b/classes/integrations/shareyourcart/sdk/views/documentation.php
@@ -45,12 +45,12 @@
...