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 @@ - -
-
-

WooCommerce has been installed – You\'re ready to start selling :)', 'woocommerce' ); ?>

- -

- -

-

-
-
\ No newline at end of file diff --git a/admin/includes/notice-theme-support.php b/admin/includes/notice-theme-support.php new file mode 100644 index 00000000000..b45bbb1c4bd --- /dev/null +++ b/admin/includes/notice-theme-support.php @@ -0,0 +1,9 @@ + +
+
+

Your theme does not declare WooCommerce support – if you encounter layout issues please read our integration guide or choose a WooCommerce theme :)', 'woocommerce' ); ?>

+

+
+
\ No newline at end of file diff --git a/admin/includes/notice-updated.php b/admin/includes/notice-updated.php deleted file mode 100644 index 00ce0ed5fb7..00000000000 --- a/admin/includes/notice-updated.php +++ /dev/null @@ -1,13 +0,0 @@ - -
-
-

WooCommerce has been updated – You\'re ready to continue selling :)', 'woocommerce' ); ?>

- -

- -

-

-
-
\ No newline at end of file diff --git a/admin/includes/updates/woocommerce-update-2.0.php b/admin/includes/updates/woocommerce-update-2.0.php index 7511c8efd4a..301d258a550 100644 --- a/admin/includes/updates/woocommerce-update-2.0.php +++ b/admin/includes/updates/woocommerce-update-2.0.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly global $wpdb, $woocommerce; // Upgrade old style files paths to support multiple file paths -$existing_file_paths = $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_file_path'" ); +$existing_file_paths = $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_file_path' AND meta_value != '';" ); if ( $existing_file_paths ) { @@ -22,8 +22,7 @@ if ( $existing_file_paths ) { $old_file_path = trim( $existing_file_path->meta_value ); if ( ! empty( $old_file_path ) ) { - $file_paths = maybe_serialize( array( md5( $old_file_path ) => $old_file_path ) ); - + $file_paths = serialize( array( md5( $old_file_path ) => $old_file_path ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = '_file_paths', meta_value = %s WHERE meta_id = %d", $file_paths, $existing_file_path->meta_id ) ); @@ -176,6 +175,9 @@ update_option( 'woocommerce_local_tax_rates_backup', $local_tax_rates ); delete_option( 'woocommerce_tax_rates' ); delete_option( 'woocommerce_local_tax_rates' ); +// Create lost password page +woocommerce_create_page( esc_sql( _x( 'lost-password', 'page_slug', 'woocommerce' ) ), 'woocommerce_lost_password_page_id', __( 'Lost Password', 'woocommerce' ), '[woocommerce_lost_password]', woocommerce_get_page_id( 'myaccount' ) ); + // Now its time for the massive update to line items - move them to the new DB tables // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_items' WHERE meta_key = '_order_items_old' @@ -293,4 +295,24 @@ foreach ( $order_tax_rows as $order_tax_row ) { unset( $tax_amount ); } } -} \ No newline at end of file +} + +// Grab the pre 2.0 Image options and use to populate the new image options settings, +// cleaning up afterwards like nice people do + +foreach ( array( 'catalog', 'single', 'thumbnail' ) as $value ) { + + $old_settings = array_filter( array( + 'width' => get_option( 'woocommerce_' . $value . '_image_width' ), + 'height' => get_option( 'woocommerce_' . $value . '_image_height' ), + 'crop' => get_option( 'woocommerce_' . $value . '_image_crop' ) + ) ); + + if ( ! empty( $old_settings ) && update_option( 'shop_' . $value . '_image_size', $old_settings ) ){ + + delete_option( 'woocommerce_' . $value . '_image_width' ); + delete_option( 'woocommerce_' . $value . '_image_height' ); + delete_option( 'woocommerce_' . $value . '_image_crop' ); + + } +} diff --git a/admin/includes/welcome.php b/admin/includes/welcome.php new file mode 100644 index 00000000000..4cf7db7b176 --- /dev/null +++ b/admin/includes/welcome.php @@ -0,0 +1,432 @@ +plugin = 'woocommerce/woocommerce.php'; + + add_action( 'admin_menu', array( $this, 'admin_menus') ); + add_action( 'admin_head', array( $this, 'admin_head' ) ); + add_action( 'admin_init', array( $this, 'welcome' ) ); + } + + /** + * Add admin menus/screens + * + * @access public + * @return void + */ + public function admin_menus() { + + $welcome_page_title = __( 'Welcome to WooCommerce', 'woocommerce' ); + + // About + $about = add_dashboard_page( $welcome_page_title, $welcome_page_title, 'manage_options', 'wc-about', array( $this, 'about_screen' ) ); + + // Credits + $credits = add_dashboard_page( $welcome_page_title, $welcome_page_title, 'manage_options', 'wc-credits', array( $this, 'credits_screen' ) ); + + add_action( 'admin_print_styles-'. $about, array( $this, 'admin_css' ) ); + add_action( 'admin_print_styles-'. $credits, array( $this, 'admin_css' ) ); + } + + /** + * admin_css function. + * + * @access public + * @return void + */ + public function admin_css() { + wp_enqueue_style( 'woocommerce-activation', plugins_url( '/assets/css/activation.css', dirname( dirname( __FILE__ ) ) ) ); + } + + /** + * Add styles just for this page, and remove dashboard page links. + * + * @access public + * @return void + */ + public function admin_head() { + global $woocommerce; + + remove_submenu_page( 'index.php', 'wc-about' ); + remove_submenu_page( 'index.php', 'wc-credits' ); + + // Badge for welcome page + $badge_url = $woocommerce->plugin_url() . '/assets/images/welcome/wc-badge.png'; + ?> + + version, 0, 3 ); + ?> +

+ +
+ +
+ +
version ); ?>
+ +

+ + + Tweet + +

+ + + +
+ + intro(); ?> + + + +
+ +

+ +
+ Sucuri Safe Plugin +

+

+
+ +

+ +
+ +
+ Product panel screenshot +

+

+
+ +
+ Order panel screenshot +

+

+
+ +
+ Download panel screenshot +

+

+
+ +
+ +

+ +
+ + Tax Options +
+

+

+
+ +
+

+

+
+ +
+ +

+ +
+ +
+ Sorting +

+

+
+ +
+ Pagination +

+

+
+ +
+ Ratings +

+

+
+ +
+ +
+ +
+

+ +
+
+

+

get_product() function.', 'woocommerce' ); ?>

+
+ +
+

+

+
+ +
+

+

WC-API now has real endpoints, and we\'ve optimised the gateways API significantly by only loading gateways when needed.', 'woocommerce' ); ?>

+
+
+
+ +
+

+

+
+ +
+

+

+
+ +
+

+

+
+ +
+
+ +
+

+

+
+ +
+

+

+
+ +
+

+

+
+ +
+
+ +
+ +
+
+ +
+ + intro(); ?> + +

Contribute to WooCommerce.', 'woocommerce' ); ?>

+ + contributors(); ?> + +
+ get_contributors(); + + if ( empty( $contributors ) ) + return ''; + + $contributor_list = ''; + + return $contributor_list; + } + + /** + * Retreive list of contributors from GitHub. + * + * @access public + * @return void + */ + public function get_contributors() { + $contributors = get_transient( 'woocommerce_contributors' ); + + if ( false !== $contributors ) + return $contributors; + + $response = wp_remote_get( 'https://api.github.com/repos/woothemes/woocommerce/contributors', array( 'sslverify' => false ) ); + + if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) + return array(); + + $contributors = json_decode( wp_remote_retrieve_body( $response ) ); + + if ( ! is_array( $contributors ) ) + return array(); + + set_transient( 'woocommerce_contributors', $contributors, 3600 ); + + return $contributors; + } + + /** + * Sends user to the welcome page on first activation + */ + public function welcome() { + + // Bail if no activation redirect transient is set + if ( ! get_transient( '_wc_activation_redirect' ) ) + return; + + // Delete the redirect transient + delete_transient( '_wc_activation_redirect' ); + + // Bail if we are waiting to install or update via the interface update/install links + if ( get_option( '_wc_needs_update' ) == 1 || get_option( '_wc_needs_pages' ) == 1 ) + return; + + // Bail if activating from network, or bulk, or within an iFrame + if ( is_network_admin() || isset( $_GET['activate-multi'] ) || defined( 'IFRAME_REQUEST' ) ) + return; + + if ( ( isset( $_GET['action'] ) && 'upgrade-plugin' == $_GET['action'] ) && ( isset( $_GET['plugin'] ) && strstr( $_GET['plugin'], 'woocommerce.php' ) ) ) + return; + + wp_safe_redirect( admin_url( 'index.php?page=wc-about' ) ); + exit; + } +} + +new WC_Welcome_Page(); \ No newline at end of file diff --git a/admin/post-types/product.php b/admin/post-types/product.php index b1de7ee125d..fd9a7a6788c 100644 --- a/admin/post-types/product.php +++ b/admin/post-types/product.php @@ -73,16 +73,17 @@ add_action( 'post_submitbox_start', 'woocommerce_duplicate_product_post_button' * @param mixed $columns * @return array */ -function woocommerce_edit_product_columns( $columns ) { +function woocommerce_edit_product_columns( $existing_columns ) { global $woocommerce; - if ( empty( $columns ) && ! is_array( $columns ) ) - $columns = array(); + if ( empty( $existing_columns ) && ! is_array( $existing_columns ) ) + $existing_columns = array(); - unset( $columns['title'], $columns['comments'], $columns['date'] ); + unset( $existing_columns['title'], $existing_columns['comments'], $existing_columns['date'] ); + $columns = array(); $columns["cb"] = ""; - $columns["thumb"] = __( 'Image', 'woocommerce' ); + $columns["thumb"] = '' . __( 'Image', 'woocommerce' ) . ''; $columns["name"] = __( 'Name', 'woocommerce' ); @@ -100,10 +101,10 @@ function woocommerce_edit_product_columns( $columns ) { $columns["product_type"] = '' . __( 'Type', 'woocommerce' ) . ''; $columns["date"] = __( 'Date', 'woocommerce' ); - return $columns; + return array_merge( $columns, $existing_columns ); } -add_filter('manage_edit-product_columns', 'woocommerce_edit_product_columns'); +add_filter( 'manage_edit-product_columns', 'woocommerce_edit_product_columns' ); /** @@ -114,12 +115,14 @@ add_filter('manage_edit-product_columns', 'woocommerce_edit_product_columns'); * @return void */ function woocommerce_custom_product_columns( $column ) { - global $post, $woocommerce; - $product = get_product($post); + global $post, $woocommerce, $the_product; + + if ( empty( $the_product ) || $the_product->id != $post->ID ) + $the_product = get_product( $post ); switch ($column) { case "thumb" : - echo $product->get_image(); + echo '' . $the_product->get_image() . ''; break; case "name" : $edit_link = get_edit_post_link( $post->ID ); @@ -145,24 +148,26 @@ function woocommerce_custom_product_columns( $column ) { $actions['id'] = 'ID: ' . $post->ID; if ( $can_edit_post && 'trash' != $post->post_status ) { - $actions['inline hide-if-no-js'] = '' . __( 'Quick Edit', 'woocommerce' ) . ''; + $actions['edit'] = '' . __( 'Edit' ) . ''; + $actions['inline hide-if-no-js'] = '' . __( 'Quick Edit' ) . ''; } 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' ) . ""; } if ( $post_type_object->public ) { - if ( in_array( $post->post_status, array( 'pending', 'draft' ) ) ) { + if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) { if ( $can_edit_post ) - $actions['view'] = '' . __( 'Preview', 'woocommerce' ) . ''; + $actions['view'] = '' . __( 'Preview' ) . ''; } elseif ( 'trash' != $post->post_status ) { - $actions['view'] = '' . __( 'View', 'woocommerce' ) . ''; + $actions['view'] = '' . __( 'View' ) . ''; } } + $actions = apply_filters( 'post_row_actions', $actions, $post ); echo '
'; @@ -183,51 +188,51 @@ function woocommerce_custom_product_columns( $column ) { echo ' '; 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 'yes'; - else echo 'no'; + 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 ''. __( 'yes', 'woocommerce' ) . ''; + } else { + echo ''. __( 'no', 'woocommerce' ) . ''; + } 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 = " + + + + 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 ''; } + } else { - $options = explode( '|', $attribute['value'] ); + + $options = array_map( 'trim', explode( '|', $attribute['value'] ) ); + foreach ( $options as $option ) { - echo ''; + echo ''; } + } 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 ); ?> @@ -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 ''; + echo ''; } } ?> @@ -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 ''; + echo ''; } } ?> @@ -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() ) . '. '; -

-

+ $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 ''; } ?> - -

- // 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 = {}; +

+ + + 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 ''; - } - echo ''; - ?> @@ -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 ''; - } - echo ''; - ?> - + $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 ) { -
  • - -
  •  [?] [?]  [?]
    + + + + + + + + + $tool) { ?> + + + + + + +
    +

    + + +

    +
    + ' + html + '
    '); + 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 ); ?>

    '; + } + + + /** + * 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() { - ?> -

    -

    - - is_valid_for_use() ) : + ?> +

    +

    + is_valid_for_use() ) : ?> + +
    + generate_settings_html(); + ?> +
    - else : - - ?> -

    :

    - - - +

    :

    + __( '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 @@ ... '))); ?> -
  • +
  • 'ShareYourCart™')); ?>

  • diff --git a/classes/shipping/class-wc-flat-rate.php b/classes/shipping/flat-rate/class-wc-shipping-flat-rate.php similarity index 60% rename from classes/shipping/class-wc-flat-rate.php rename to classes/shipping/flat-rate/class-wc-shipping-flat-rate.php index 20bde8e825f..7a0dff78a57 100644 --- a/classes/shipping/class-wc-flat-rate.php +++ b/classes/shipping/flat-rate/class-wc-shipping-flat-rate.php @@ -1,18 +1,18 @@ id = 'flat_rate'; - $this->method_title = __( 'Flat rate', 'woocommerce' ); - + $this->method_title = __( 'Flat Rate', 'woocommerce' ); $this->flat_rate_option = 'woocommerce_flat_rates'; - $this->admin_page_heading = __( 'Flat Rates', 'woocommerce' ); - $this->admin_page_description = __( 'Flat rates let you define a standard rate per item, or per order.', 'woocommerce' ); + $this->method_description = __( 'Flat rates let you define a standard rate per item, or per order.', 'woocommerce' ); - add_action( 'woocommerce_update_options_shipping_' . $this->id, array( &$this, 'process_admin_options' ) ); - add_action( 'woocommerce_update_options_shipping_' . $this->id, array( &$this, 'process_flat_rates' ) ); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_flat_rates' ) ); + add_filter( 'woocommerce_settings_api_sanitized_fields_' . $this->id, array( $this, 'save_default_costs' ) ); $this->init(); } - /** * init function. * @@ -42,27 +40,22 @@ class WC_Flat_Rate extends WC_Shipping_Method { * @return void */ function init() { - // 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']; - $this->title = $this->settings['title']; - $this->availability = $this->settings['availability']; - $this->countries = $this->settings['countries']; - $this->type = $this->settings['type']; - $this->tax_status = $this->settings['tax_status']; - $this->cost = $this->settings['cost']; - $this->cost_per_order = isset( $this->settings['cost_per_order'] ) ? $this->settings['cost_per_order'] : ''; - $this->fee = $this->settings['fee']; - $this->minimum_fee = isset( $this->settings['minimum_fee'] ) ? $this->settings['minimum_fee'] : ''; - $this->options = isset( $this->settings['options'] ) ? $this->settings['options'] : ''; - - // Get options - $this->options = (array) explode( "\n", $this->options ); + $this->title = $this->get_option( 'title' ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); + $this->type = $this->get_option( 'type' ); + $this->tax_status = $this->get_option( 'tax_status' ); + $this->cost = $this->get_option( 'cost' ); + $this->cost_per_order = $this->get_option( 'cost_per_order' ); + $this->fee = $this->get_option( 'fee' ); + $this->minimum_fee = $this->get_option( 'minimum_fee' ); + $this->options = (array) explode( "\n", $this->get_option( 'options' ) ); // Load Flat rates $this->get_flat_rates(); @@ -90,19 +83,10 @@ class WC_Flat_Rate extends WC_Shipping_Method { 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), 'default' => __( 'Flat Rate', 'woocommerce' ), - ), - 'cost_per_order' => array( - 'title' => __( 'Cost per order', 'woocommerce' ), - 'type' => 'number', - 'custom_attributes' => array( - 'step' => 'any', - 'min' => '0' - ), - 'description' => __( 'Enter a cost per order, e.g. 5.00. Leave blank to disable.', 'woocommerce' ), - 'default' => '', + 'desc_tip' => true ), 'availability' => array( - 'title' => __( 'Method availability', 'woocommerce' ), + 'title' => __( 'Availability', 'woocommerce' ), 'type' => 'select', 'default' => 'all', 'class' => 'availability', @@ -119,10 +103,43 @@ class WC_Flat_Rate extends WC_Shipping_Method { 'default' => '', 'options' => $woocommerce->countries->countries, ), - 'type' => array( - 'title' => __( 'Calculation Type', 'woocommerce' ), + 'tax_status' => array( + 'title' => __( 'Tax Status', 'woocommerce' ), + 'type' => 'select', + 'default' => 'taxable', + 'options' => array( + 'taxable' => __( 'Taxable', 'woocommerce' ), + 'none' => __( 'None', 'woocommerce' ), + ), + ), + 'cost_per_order' => array( + 'title' => __( 'Cost per order', 'woocommerce' ), + 'type' => 'number', + 'custom_attributes' => array( + 'step' => 'any', + 'min' => '0' + ), + 'description' => __( 'Enter a cost (excluding tax) per order, e.g. 5.00. Leave blank to disable.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '0.00' + ), + 'options' => array( + 'title' => __( 'Additional Rates', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Optional extra shipping options with additional costs (one per line): Option Name | Additional Cost | Per Cost Type (order, class, or item) Example: Priority Mail | 6.95 | order.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Option Name | Additional Cost | Per Cost Type (order, class, or item)', 'woocommerce' ) + ), + 'additional_costs' => array( + 'title' => __( 'Additional Costs', 'woocommerce' ), + 'type' => 'title', + 'description' => __( 'Additional costs can be added below - these will all be added to the per-order cost above.', 'woocommerce' ) + ), + 'type' => array( + 'title' => __( 'Costs Added...', 'woocommerce' ), 'type' => 'select', - 'description' => '', 'default' => 'order', 'options' => array( 'order' => __( 'Per Order - charge shipping for the entire order as a whole', 'woocommerce' ), @@ -130,34 +147,11 @@ class WC_Flat_Rate extends WC_Shipping_Method { 'class' => __( 'Per Class - charge shipping for each shipping class in an order', 'woocommerce' ), ), ), - 'tax_status' => array( - 'title' => __( 'Tax Status', 'woocommerce' ), - 'type' => 'select', - 'description' => '', - 'default' => 'taxable', - 'options' => array( - 'taxable' => __( 'Taxable', 'woocommerce' ), - 'none' => __( 'None', 'woocommerce' ), - ), - ), - 'cost' => array( - 'title' => __( 'Default Cost', 'woocommerce' ), - 'type' => 'number', - 'custom_attributes' => array( - 'step' => 'any', - 'min' => '0' - ), - 'description' => __( 'Cost excluding tax. Enter an amount, e.g. 2.50.', 'woocommerce' ), - 'default' => '', - ), - 'fee' => array( - 'title' => __( 'Default Handling Fee', 'woocommerce' ), - 'type' => 'text', - 'description' => __( 'Fee excluding tax. Enter an amount, e.g. 2.50, or a percentage, e.g. 5%. Leave blank to disable.', 'woocommerce' ), - 'default' => '', + 'additional_costs_table' => array( + 'type' => 'additional_costs_table' ), 'minimum_fee' => array( - 'title' => __( 'Minimum Fee', 'woocommerce' ), + 'title' => __( 'Minimum Handling Fee', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array( 'step' => 'any', @@ -165,12 +159,8 @@ class WC_Flat_Rate extends WC_Shipping_Method { ), 'description' => __( 'Enter a minimum fee amount. Fee\'s less than this will be increased. Leave blank to disable.', 'woocommerce' ), 'default' => '', - ), - 'options' => array( - 'title' => __( 'Shipping Options', 'woocommerce' ), - 'type' => 'textarea', - 'description' => __( 'Optional extra shipping options with additional costs (one per line). Example: Option Name|Cost|Per-order (yes or no). Example: Priority Mail|6.95|yes. If per-order is set to no, it will use the "Calculation Type" setting.', 'woocommerce' ), - 'default' => '', + 'desc_tip' => true, + 'placeholder' => '0.00' ), ); @@ -240,44 +230,54 @@ class WC_Flat_Rate extends WC_Shipping_Method { $this->add_rate( $rate ); // Add any extra rates - if ( sizeof( $this->options ) > 0) foreach ( $this->options as $option ) { + if ( sizeof( $this->options ) > 0) { - $this_option = preg_split( '~\s*\|\s*~', trim( $option ) ); + // Get item qty + $total_quantity = 0; - if ( sizeof( $this_option ) !== 3 ) continue; + foreach ( $package['contents'] as $item_id => $values ) + if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) + $total_quantity += $values['quantity']; - $extra_rate = $rate; + // Loop options + foreach ( $this->options as $option ) { - $extra_rate['id'] = $this->id . ':' . sanitize_title($this_option[0]); - $extra_rate['label'] = $this_option[0]; + $this_option = array_map( 'trim', explode( '|', $option ) ); - $per_order_cost = ( $this_option[2] == 'yes' ) ? 1 : 0; - $this_cost = $this_option[1]; + if ( sizeof( $this_option ) !== 3 ) continue; - if ( is_array( $extra_rate['cost'] ) ) { - if ( $per_order_cost ) { - $extra_rate['cost']['order'] = $this_cost; + $extra_rate = $rate; + + $extra_rate['id'] = $this->id . ':' . sanitize_title( $this_option[0] ); + $extra_rate['label'] = $this_option[0]; + $this_cost = $this_option[1]; + + // Backwards compat with yes and no + if ( $this_option[2] == 'yes' ) { + $this_type = 'order'; + } elseif ( $this_option[2] == 'no' ) { + $this_type = $this->type; } else { - $total_quantity = 0; - - // Shipping per item - foreach ( $package['contents'] as $item_id => $values ) - if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) - $total_quantity += $values['quantity']; - - // Per-product shipping - $extra_rate['cost']['order'] = $this_cost * $total_quantity; - } - } else { - // If using shipping per class, multiple the cost by the classes we found - if ( ! $per_order_cost && $this->type == 'class' ) { - $this_cost = $this_cost * $found_shipping_classes; + $this_type = $this_option[2]; } - $extra_rate['cost'] = $extra_rate['cost'] + $this_cost; + switch ( $this_type ) { + case 'class' : + $this_cost = $this_cost * $found_shipping_classes; + break; + case 'item' : + $this_cost = $this_cost * $total_quantity; + break; + } + + // Per item rates + if ( is_array( $extra_rate['cost'] ) ) $extra_rate['cost']['order'] = $extra_rate['cost']['order'] + $this_cost; + + // Per order or class rates + else $extra_rate['cost'] = $extra_rate['cost'] + $this_cost; + + $this->add_rate( $extra_rate ); } - - $this->add_rate( $extra_rate ); } } @@ -435,52 +435,59 @@ class WC_Flat_Rate extends WC_Shipping_Method { return null; } + /** + * validate_additional_costs_field function. + * + * @access public + * @param mixed $key + * @return void + */ + function validate_additional_costs_table_field( $key ) { + return false; + } - /** - * Admin Panel Options - * - Options for bits like 'title' and availability on a country-by-country basis - * - * @since 1.0.0 - * @access public - * @return void - */ - public function admin_options() { - global $woocommerce; - ?> -

    admin_page_heading; ?>

    -

    admin_page_description; ?>

    - - generate_settings_html(); - ?> - - - + + get_flat_rates(); } + /** + * save_default_costs function. + * + * @access public + * @param mixed $values + * @return void + */ + function save_default_costs( $fields ) { + $default_cost = woocommerce_clean( $_POST['default_cost'] ); + $default_fee = woocommerce_clean( $_POST['default_fee'] ); + + $fields['cost'] = $default_cost; + $fields['fee'] = $default_fee; + + return $fields; + } + /** * get_flat_rates function. @@ -603,20 +626,4 @@ class WC_Flat_Rate extends WC_Shipping_Method { $this->flat_rates = array_filter( (array) get_option( $this->flat_rate_option ) ); } -} - - -/** - * add_flat_rate_method function. - * - * @package WooCommerce/Classes/Shipping - * @access public - * @param array $methods - * @return array - */ -function add_flat_rate_method( $methods ) { - $methods[] = 'WC_Flat_Rate'; - return $methods; -} - -add_filter( 'woocommerce_shipping_methods', 'add_flat_rate_method' ); \ No newline at end of file +} \ No newline at end of file diff --git a/classes/shipping/class-wc-free-shipping.php b/classes/shipping/free-shipping/class-wc-shipping-free-shipping.php similarity index 79% rename from classes/shipping/class-wc-free-shipping.php rename to classes/shipping/free-shipping/class-wc-shipping-free-shipping.php index 800b7af5569..615ca32a255 100644 --- a/classes/shipping/class-wc-free-shipping.php +++ b/classes/shipping/free-shipping/class-wc-shipping-free-shipping.php @@ -1,18 +1,18 @@ init_form_fields(); // Load the settings. + $this->init_form_fields(); $this->init_settings(); // Define user set variables - $this->enabled = $this->settings['enabled']; - $this->title = $this->settings['title']; - $this->min_amount = $this->settings['min_amount'] ? $this->settings['min_amount'] : 0; - $this->availability = $this->settings['availability']; - $this->countries = $this->settings['countries']; - $this->requires = isset( $this->settings['requires'] ) ? $this->settings['requires'] : ''; - - // Backwards compat - if ( ! isset( $this->settings['requires'] ) ) { - if ( $this->settings['requires_coupon'] && $this->min_amount ) - $this->requires = 'either'; - elseif ( $this->settings['requires_coupon'] ) - $this->requires = 'coupon'; - elseif ( $this->min_amount ) - $this->requires = 'min_amount'; - } + $this->enabled = $this->get_option( 'enabled' ); + $this->title = $this->get_option( 'title' ); + $this->min_amount = $this->get_option( 'min_amount', 0 ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); + $this->requires = $this->get_option( 'requires' ); // Actions - add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options')); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); } @@ -71,6 +60,16 @@ class WC_Free_Shipping extends WC_Shipping_Method { function init_form_fields() { global $woocommerce; + // Backwards compat + if ( $this->get_option( 'requires_coupon' ) && $this->min_amount ) + $default_requires = 'either'; + elseif ( $this->get_option( 'requires_coupon' ) ) + $default_requires = 'coupon'; + elseif ( $this->min_amount ) + $default_requires = 'min_amount'; + else + $default_requires = ''; + $this->form_fields = array( 'enabled' => array( 'title' => __( 'Enable/Disable', 'woocommerce' ), @@ -82,7 +81,8 @@ class WC_Free_Shipping extends WC_Shipping_Method { 'title' => __( 'Method Title', 'woocommerce' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), - 'default' => __( 'Free Shipping', 'woocommerce' ) + 'default' => __( 'Free Shipping', 'woocommerce' ), + 'desc_tip' => true, ), 'availability' => array( 'title' => __( 'Method availability', 'woocommerce' ), @@ -105,7 +105,7 @@ class WC_Free_Shipping extends WC_Shipping_Method { 'requires' => array( 'title' => __( 'Free Shipping Requires...', 'woocommerce' ), 'type' => 'select', - 'default' => '', + 'default' => $default_requires, 'options' => array( '' => __( 'N/A', 'woocommerce' ), 'coupon' => __( 'A valid free shipping coupon', 'woocommerce' ), @@ -122,7 +122,9 @@ class WC_Free_Shipping extends WC_Shipping_Method { 'min' => '0' ), 'description' => __( 'Users will need to spend this amount to get free shipping (if enabled above).', 'woocommerce' ), - 'default' => '0' + 'default' => '0', + 'desc_tip' => true, + 'placeholder' => '0.00' ) ); @@ -187,7 +189,7 @@ class WC_Free_Shipping extends WC_Shipping_Method { foreach ($woocommerce->cart->applied_coupons as $code) { $coupon = new WC_Coupon( $code ); - if ( $coupon->enable_free_shipping() ) + if ( $coupon->is_valid() && $coupon->enable_free_shipping() ) $has_coupon = true; } } @@ -245,19 +247,4 @@ class WC_Free_Shipping extends WC_Shipping_Method { $this->add_rate( $args ); } -} - -/** - * add_free_shipping_method function. - * - * @package WooCommerce/Classes/Shipping - * @access public - * @param array $methods - * @return array - */ -function add_free_shipping_method( $methods ) { - $methods[] = 'WC_Free_Shipping'; - return $methods; -} - -add_filter('woocommerce_shipping_methods', 'add_free_shipping_method' ); \ No newline at end of file +} \ No newline at end of file diff --git a/classes/shipping/class-wc-international-delivery.php b/classes/shipping/international-delivery/class-wc-shipping-international-delivery.php similarity index 72% rename from classes/shipping/class-wc-international-delivery.php rename to classes/shipping/international-delivery/class-wc-shipping-international-delivery.php index 05eed998ab4..357225acd6d 100644 --- a/classes/shipping/class-wc-international-delivery.php +++ b/classes/shipping/international-delivery/class-wc-shipping-international-delivery.php @@ -1,18 +1,18 @@ id = 'international_delivery'; - $this->method_title = __( 'International Delivery', 'woocommerce' ); - $this->flat_rate_option = 'woocommerce_international_delivery_flat_rates'; - $this->admin_page_heading = __( 'International Delivery', 'woocommerce' ); - $this->admin_page_description = __( 'International delivery based on flat rate shipping.', 'woocommerce' ); + $this->method_title = __( 'International Delivery', 'woocommerce' ); + $this->method_description = __( 'International delivery based on flat rate shipping.', 'woocommerce' ); - add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options')); - add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_flat_rates')); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_flat_rates' ) ); $this->init(); } @@ -58,7 +56,8 @@ class WC_International_Delivery extends WC_Flat_Rate { 'title' => __( 'Method Title', 'woocommerce' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), - 'default' => __( 'International Delivery', 'woocommerce' ) + 'default' => __( 'International Delivery', 'woocommerce' ), + 'desc_tip' => true, ), 'availability' => array( 'title' => __( 'Availability', 'woocommerce' ), @@ -78,42 +77,56 @@ class WC_International_Delivery extends WC_Flat_Rate { 'default' => '', 'options' => $woocommerce->countries->countries ), - 'type' => array( - 'title' => __( 'Calculation Type', 'woocommerce' ), - 'type' => 'select', - 'description' => '', - 'default' => 'order', - 'options' => array( - 'order' => __( 'Per Order - charge shipping for the entire order as a whole', 'woocommerce' ), - 'item' => __( 'Per Item - charge shipping for each item individually', 'woocommerce' ), - 'class' => __( 'Per Class - charge shipping for each shipping class in an order', 'woocommerce' ) - ) - ), 'tax_status' => array( 'title' => __( 'Tax Status', 'woocommerce' ), 'type' => 'select', - 'description' => '', 'default' => 'taxable', 'options' => array( 'taxable' => __( 'Taxable', 'woocommerce' ), 'none' => __( 'None', 'woocommerce' ) ) ), + 'type' => array( + 'title' => __( 'Cost Added...', 'woocommerce' ), + 'type' => 'select', + 'default' => 'order', + 'options' => array( + 'order' => __( 'Per Order - charge shipping for the entire order as a whole', 'woocommerce' ), + 'item' => __( 'Per Item - charge shipping for each item individually', 'woocommerce' ), + 'class' => __( 'Per Class - charge shipping for each shipping class in an order', 'woocommerce' ), + ), + ), 'cost' => array( - 'title' => __( 'Default Cost', 'woocommerce' ), + 'title' => __( 'Cost', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array( 'step' => 'any', 'min' => '0' ), 'description' => __( 'Cost excluding tax. Enter an amount, e.g. 2.50.', 'woocommerce' ), - 'default' => '' + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '0.00' ), 'fee' => array( - 'title' => __( 'Default Handling Fee', 'woocommerce' ), + 'title' => __( 'Handling Fee', 'woocommerce' ), 'type' => 'text', 'description' => __( 'Fee excluding tax. Enter an amount, e.g. 2.50, or a percentage, e.g. 5%. Leave blank to disable.', 'woocommerce' ), - 'default' => '' + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '0.00' + ), + 'minimum_fee' => array( + 'title' => __( 'Minimum Handling Fee', 'woocommerce' ), + 'type' => 'number', + 'custom_attributes' => array( + 'step' => 'any', + 'min' => '0' + ), + 'description' => __( 'Enter a minimum fee amount. Fee\'s less than this will be increased. Leave blank to disable.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '0.00' ), ); @@ -149,19 +162,4 @@ class WC_International_Delivery extends WC_Flat_Rate { return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', true ); } -} - -/** - * add_international_delivery_method function. - * - * @package WooCommerce/Classes/Shipping - * @access public - * @param array $methods - * @return array - */ -function add_international_delivery_method( $methods ) { - $methods[] = 'WC_International_Delivery'; - return $methods; -} - -add_filter('woocommerce_shipping_methods', 'add_international_delivery_method' ); \ No newline at end of file +} \ No newline at end of file diff --git a/classes/shipping/class-wc-local-delivery.php b/classes/shipping/local-delivery/class-wc-shipping-local-delivery.php similarity index 81% rename from classes/shipping/class-wc-local-delivery.php rename to classes/shipping/local-delivery/class-wc-shipping-local-delivery.php index b86732453d2..c8decdde927 100644 --- a/classes/shipping/class-wc-local-delivery.php +++ b/classes/shipping/local-delivery/class-wc-shipping-local-delivery.php @@ -1,18 +1,18 @@ init_form_fields(); // Load the settings. + $this->init_form_fields(); $this->init_settings(); // Define user set variables - $this->enabled = empty( $this->settings['enabled'] ) ? 'no' : $this->settings['enabled']; - $this->title = empty( $this->settings['title'] ) ? '' : $this->settings['title']; - $this->type = $this->settings['type']; - $this->fee = empty( $this->settings['fee'] ) ? '' : $this->settings['fee']; - $this->type = empty( $this->settings['type'] ) ? '' : $this->settings['type']; - $this->codes = empty( $this->settings['codes'] ) ? '' : $this->settings['codes']; - $this->availability = empty( $this->settings['availability'] ) ? '' : $this->settings['availability']; - $this->countries = empty( $this->settings['countries'] ) ? '' : $this->settings['countries']; + $this->title = $this->get_option( 'title' ); + $this->type = $this->get_option( 'type' ); + $this->fee = $this->get_option( 'fee' ); + $this->type = $this->get_option( 'type' ); + $this->codes = $this->get_option( 'codes' ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); - add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options')); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); } /** @@ -106,7 +104,8 @@ class WC_Local_Delivery extends WC_Shipping_Method { 'title' => __( 'Title', 'woocommerce' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), - 'default' => __( 'Local Delivery', 'woocommerce' ) + 'default' => __( 'Local Delivery', 'woocommerce' ), + 'desc_tip' => true, ), 'type' => array( 'title' => __( 'Fee Type', 'woocommerce' ), @@ -118,6 +117,7 @@ class WC_Local_Delivery extends WC_Shipping_Method { 'percent' => __( 'Percentage of cart total', 'woocommerce' ), 'product' => __( 'Fixed amount per product', 'woocommerce' ), ), + 'desc_tip' => true, ), 'fee' => array( 'title' => __( 'Delivery Fee', 'woocommerce' ), @@ -127,13 +127,17 @@ class WC_Local_Delivery extends WC_Shipping_Method { 'min' => '0' ), 'description' => __( 'What fee do you want to charge for local delivery, disregarded if you choose free. Leave blank to disable.', 'woocommerce' ), - 'default' => '' + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '0.00' ), 'codes' => array( 'title' => __( 'Zip/Post Codes', 'woocommerce' ), 'type' => 'textarea', 'description' => __( 'What zip/post codes would you like to offer delivery to? Separate codes with a comma. Accepts wildcards, e.g. P* will match a postcode of PE30.', 'woocommerce' ), - 'default' => '' + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '12345, 56789 etc' ), 'availability' => array( 'title' => __( 'Method availability', 'woocommerce' ), @@ -218,7 +222,7 @@ class WC_Local_Delivery extends WC_Shipping_Method { return false; } - // Either post codes not setup, or post codes are in array... so lefts check countries for backwards compatability. + // Either post codes not setup, or post codes are in array... so lefts check countries for backwards compatibility. $ship_to_countries = ''; if ($this->availability == 'specific') : $ship_to_countries = $this->countries; @@ -248,19 +252,4 @@ class WC_Local_Delivery extends WC_Shipping_Method { return str_replace( '-', '', sanitize_title( $code ) ) . ( strstr( $code, '*' ) ? '*' : '' ); } -} - -/** - * add_local_delivery_method function. - * - * @package WooCommerce/Classes/Shipping - * @access public - * @param array $methods - * @return array - */ -function add_local_delivery_method($methods) { - $methods[] = 'WC_Local_Delivery'; - return $methods; -} - -add_filter('woocommerce_shipping_methods','add_local_delivery_method'); \ No newline at end of file +} \ No newline at end of file diff --git a/classes/shipping/class-wc-local-pickup.php b/classes/shipping/local-pickup/class-wc-shipping-local-pickup.php similarity index 82% rename from classes/shipping/class-wc-local-pickup.php rename to classes/shipping/local-pickup/class-wc-shipping-local-pickup.php index ebea0174c37..eb3c4c8b571 100644 --- a/classes/shipping/class-wc-local-pickup.php +++ b/classes/shipping/local-pickup/class-wc-shipping-local-pickup.php @@ -1,18 +1,18 @@ init_form_fields(); // Load the settings. + $this->init_form_fields(); $this->init_settings(); // Define user set variables - $this->enabled = $this->settings['enabled']; - $this->title = $this->settings['title']; - $this->codes = empty( $this->settings['codes'] ) ? '' : $this->settings['codes']; - $this->availability = $this->settings['availability']; - $this->countries = $this->settings['countries']; + $this->enabled = $this->get_option( 'enabled' ); + $this->title = $this->get_option( 'title' ); + $this->codes = $this->get_option( 'codes' ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); // Actions - add_action( 'woocommerce_update_options_shipping_' . $this->id, array( &$this, 'process_admin_options' ) ); - add_filter( 'woocommerce_customer_taxable_address', array( &$this, 'taxable_address' ) ); - add_action( 'woocommerce_shipping_method_chosen', array( &$this, 'method_chosen' ) ); + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + add_filter( 'woocommerce_customer_taxable_address', array( $this, 'taxable_address' ) ); + add_action( 'woocommerce_shipping_method_chosen', array( $this, 'method_chosen' ) ); } /** @@ -85,13 +84,16 @@ class WC_Local_Pickup extends WC_Shipping_Method { 'title' => __( 'Title', 'woocommerce' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), - 'default' => __( 'Local Pickup', 'woocommerce' ) + 'default' => __( 'Local Pickup', 'woocommerce' ), + 'desc_tip' => true, ), 'codes' => array( 'title' => __( 'Zip/Post Codes', 'woocommerce' ), 'type' => 'textarea', 'description' => __( 'What zip/post codes would you like to offer delivery to? Separate codes with a comma. Accepts wildcards, e.g. P* will match a postcode of PE30.', 'woocommerce' ), - 'default' => '' + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '12345, 56789 etc' ), 'availability' => array( 'title' => __( 'Method availability', 'woocommerce' ), @@ -221,7 +223,7 @@ class WC_Local_Pickup extends WC_Shipping_Method { global $woocommerce; if ( ! empty( $woocommerce->session->chosen_shipping_method ) && $woocommerce->session->chosen_shipping_method == 'local_pickup' ) { - if ( ! empty( $this->settings['apply_base_tax'] ) && $this->settings['apply_base_tax'] == 'yes' ) { + if ( $this->get_option( 'apply_base_tax' ) == 'yes' ) { $country = $woocommerce->countries->get_base_country(); $state = $woocommerce->countries->get_base_state(); @@ -241,7 +243,7 @@ class WC_Local_Pickup extends WC_Shipping_Method { function method_chosen( $method ) { global $woocommerce; - if ( $method == 'local_pickup' && ! empty( $this->settings['apply_base_tax'] ) && $this->settings['apply_base_tax'] == 'yes' ) { + if ( $method == 'local_pickup' && $this->get_option( 'apply_base_tax' ) == 'yes' ) { $woocommerce->cart->calculate_totals(); } } @@ -257,19 +259,4 @@ class WC_Local_Pickup extends WC_Shipping_Method { return str_replace( '-', '', sanitize_title( $code ) ) . ( strstr( $code, '*' ) ? '*' : '' ); } -} - -/** - * add_local_pickup_method function. - * - * @package WooCommerce/Classes/Shipping - * @access public - * @param array $methods - * @return array - */ -function add_local_pickup_method($methods) { - $methods[] = 'WC_Local_Pickup'; - return $methods; -} - -add_filter('woocommerce_shipping_methods','add_local_pickup_method'); \ No newline at end of file +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-cart.php b/classes/shortcodes/class-wc-shortcode-cart.php new file mode 100644 index 00000000000..70562fb4d6a --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-cart.php @@ -0,0 +1,90 @@ +nocache(); + + if ( ! defined( 'WOOCOMMERCE_CART' ) ) define( 'WOOCOMMERCE_CART', true ); + + // Add Discount + if ( ! empty( $_POST['apply_coupon'] ) ) { + + if ( ! empty( $_POST['coupon_code'] ) ) { + $woocommerce->cart->add_discount( sanitize_text_field( $_POST['coupon_code'] ) ); + } else { + $woocommerce->add_error( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ) ); + } + + // Remove Coupon Codes + } elseif ( isset( $_GET['remove_discounts'] ) ) { + + $woocommerce->cart->remove_coupons( $_GET['remove_discounts'] ); + + // Update Shipping + } elseif ( ! empty( $_POST['calc_shipping'] ) && $woocommerce->verify_nonce('cart') ) { + + $validation = $woocommerce->validation(); + + $woocommerce->shipping->reset_shipping(); + $woocommerce->customer->calculated_shipping( true ); + $country = $_POST['calc_shipping_country']; + $state = $_POST['calc_shipping_state']; + $postcode = $_POST['calc_shipping_postcode']; + + if ( $postcode && ! $validation->is_postcode( $postcode, $country ) ) { + $woocommerce->add_error( __( 'Please enter a valid postcode/ZIP.', 'woocommerce' ) ); + $postcode = ''; + } elseif ( $postcode ) { + $postcode = $validation->format_postcode( $postcode, $country ); + } + + if ( $country ) { + + // Update customer location + $woocommerce->customer->set_location( $country, $state, $postcode ); + $woocommerce->customer->set_shipping_location( $country, $state, $postcode ); + $woocommerce->add_message( __( 'Shipping costs updated.', 'woocommerce' ) ); + + } else { + + $woocommerce->customer->set_to_base(); + $woocommerce->customer->set_shipping_to_base(); + $woocommerce->add_message( __( 'Shipping costs updated.', 'woocommerce' ) ); + + } + + do_action( 'woocommerce_calculated_shipping' ); + } + + // Check cart items are valid + do_action('woocommerce_check_cart_items'); + + // Calc totals + $woocommerce->cart->calculate_totals(); + + if ( sizeof( $woocommerce->cart->get_cart() ) == 0 ) + woocommerce_get_template( 'cart/cart-empty.php' ); + else + woocommerce_get_template( 'cart/cart.php' ); + + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-change-password.php b/classes/shortcodes/class-wc-shortcode-change-password.php new file mode 100644 index 00000000000..d30412652cd --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-change-password.php @@ -0,0 +1,38 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + if ( ! is_user_logged_in() ) return; + + woocommerce_get_template( 'myaccount/form-change-password.php' ); + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-checkout.php b/classes/shortcodes/class-wc-shortcode-checkout.php new file mode 100644 index 00000000000..1ef05bfbc39 --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-checkout.php @@ -0,0 +1,70 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + // Prevent cache + $woocommerce->nocache(); + + // Show non-cart errors + $woocommerce->show_messages(); + + // Check cart has contents + if ( sizeof( $woocommerce->cart->get_cart() ) == 0 ) return; + + // Calc totals + $woocommerce->cart->calculate_totals(); + + // Check cart contents for errors + do_action('woocommerce_check_cart_items'); + + // Get checkout object + $checkout = $woocommerce->checkout(); + + if ( empty( $_POST ) && $woocommerce->error_count() > 0 ) { + + woocommerce_get_template( 'checkout/cart-errors.php', array( 'checkout' => $checkout ) ); + + } else { + + $non_js_checkout = ! empty( $_POST['woocommerce_checkout_update_totals'] ) ? true : false; + + if ( $woocommerce->error_count() == 0 && $non_js_checkout ) + $woocommerce->add_message( __( 'The order totals have been updated. Please confirm your order by pressing the Place Order button at the bottom of the page.', 'woocommerce' ) ); + + woocommerce_get_template( 'checkout/form-checkout.php', array( 'checkout' => $checkout ) ); + + } + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-edit-address.php b/classes/shortcodes/class-wc-shortcode-edit-address.php new file mode 100644 index 00000000000..c9c8c880126 --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-edit-address.php @@ -0,0 +1,67 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + + if ( ! is_user_logged_in() ) return; + + $load_address = self::get_address_to_edit(); + + $address = $woocommerce->countries->get_address_fields( get_user_meta( get_current_user_id(), $load_address . '_country', true ), $load_address . '_' ); + + woocommerce_get_template( 'myaccount/form-edit-address.php', array( + 'load_address' => $load_address, + 'address' => $address + ) ); + } + + /** + * Figure out which address is being viewed/edited. + * + * @access public + */ + public static function get_address_to_edit() { + + $load_address = ( isset( $_GET[ 'address' ] ) ) ? esc_attr( $_GET[ 'address' ] ) : ''; + + $load_address = ( $load_address == 'billing' || $load_address == 'shipping' ) ? $load_address : ''; + + return $load_address; + } + +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-lost-password.php b/classes/shortcodes/class-wc-shortcode-lost-password.php new file mode 100644 index 00000000000..61c263a610b --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-lost-password.php @@ -0,0 +1,234 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + + global $post; + + // arguments to pass to template + $args = array( 'form' => 'lost_password' ); + + // process lost password form + if( isset( $_POST['user_login'] ) ) { + + $woocommerce->verify_nonce( 'lost_password' ); + + self::retrieve_password(); + } + + // process reset key / login from email confirmation link + if( isset( $_GET['key'] ) && isset( $_GET['login'] ) ) { + + $user = self::check_password_reset_key( $_GET['key'], $_GET['login'] ); + + // reset key / login is correct, display reset password form with hidden key / login values + if( is_object( $user ) ) { + $args['form'] = 'reset_password'; + $args['key'] = esc_attr( $_GET['key'] ); + $args['login'] = esc_attr( $_GET['login'] ); + } + } + + // process reset password form + if( isset( $_POST['password_1'] ) && isset( $_POST['password_2'] ) && isset( $_POST['reset_key'] ) && isset( $_POST['reset_login'] ) ) : + + // verify reset key again + $user = self::check_password_reset_key( $_POST['reset_key'], $_POST['reset_login'] ); + + if( is_object( $user ) ) { + + // save these values into the form again in case of errors + $args['key'] = esc_attr( $_POST['reset_key'] ); + $args['login'] = esc_attr( $_POST['reset_login'] ); + + $woocommerce->verify_nonce( 'reset_password' ); + + if( empty( $_POST['password_1'] ) || empty( $_POST['password_2'] ) ) { + $woocommerce->add_error( __( 'Please enter your password.', 'woocommerce' ) ); + $args['form'] = 'reset_password'; + } + + if( $_POST[ 'password_1' ] !== $_POST[ 'password_2' ] ) { + $woocommerce->add_error( __( 'Passwords do not match.', 'woocommerce' ) ); + $args['form'] = 'reset_password'; + } + + if( 0 == $woocommerce->error_count() && ( $_POST['password_1'] == $_POST['password_2'] ) ) { + + self::reset_password( $user, esc_attr( $_POST['password_1'] ) ); + + do_action( 'woocommerce_customer_reset_password', $user ); + + $woocommerce->add_message( __( 'Your password has been reset.', 'woocommerce' ) . ' ' . __( 'Log in', 'woocommerce' ) . '' ); + } + } + + endif; + + woocommerce_get_template( 'myaccount/form-lost-password.php', $args ); + } + + /** + * Handles sending password retrieval email to customer. + * + * @access public + * @uses $wpdb WordPress Database object + * @return bool True: when finish. False: on error + */ + public static function retrieve_password() { + global $woocommerce,$wpdb; + + if ( empty( $_POST['user_login'] ) ) { + + $woocommerce->add_error( __( 'Enter a username or e-mail address.', 'woocommerce' ) ); + + } elseif ( strpos( $_POST['user_login'], '@' ) ) { + + $user_data = get_user_by( 'email', trim( $_POST['user_login'] ) ); + + if ( empty( $user_data ) ) + $woocommerce->add_error( __( 'There is no user registered with that email address.', 'woocommerce' ) ); + + } else { + + $login = trim( $_POST['user_login'] ); + + $user_data = get_user_by('login', $login ); + } + + do_action('lostpassword_post'); + + if( $woocommerce->error_count() > 0 ) + return false; + + if ( ! $user_data ) { + $woocommerce->add_error( __( 'Invalid username or e-mail.', 'woocommerce' ) ); + return false; + } + + // redefining user_login ensures we return the right case in the email + $user_login = $user_data->user_login; + $user_email = $user_data->user_email; + + do_action('retrieve_password', $user_login); + + $allow = apply_filters('allow_password_reset', true, $user_data->ID); + + if ( ! $allow ) { + + $woocommerce->add_error( __( 'Password reset is not allowed for this user') ); + + return false; + + } elseif ( is_wp_error( $allow ) ) { + + $woocommerce->add_error( $allow->get_error_message ); + + return false; + } + + $key = $wpdb->get_var( $wpdb->prepare( "SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login ) ); + + if ( empty( $key ) ) { + + // Generate something random for a key... + $key = wp_generate_password( 20, false ); + + do_action('retrieve_password_key', $user_login, $key); + + // Now insert the new md5 key into the db + $wpdb->update( $wpdb->users, array( 'user_activation_key' => $key ), array( 'user_login' => $user_login ) ); + } + + // Send email notification + $mailer = $woocommerce->mailer(); + do_action( 'woocommerce_reset_password_notification', $user_login, $key ); + + $woocommerce->add_message( __( 'Check your e-mail for the confirmation link.' ) ); + return true; + } + + /** + * Retrieves a user row based on password reset key and login + * + * @uses $wpdb WordPress Database object + * + * @access public + * @param string $key Hash to validate sending user's password + * @param string $login The user login + * @return object|bool User's database row on success, false for invalid keys + */ + public static function check_password_reset_key( $key, $login ) { + global $woocommerce,$wpdb; + + $key = preg_replace( '/[^a-z0-9]/i', '', $key ); + + if ( empty( $key ) || ! is_string( $key ) ) { + $woocommerce->add_error( __( 'Invalid key', 'woocommerce' ) ); + return false; + } + + if ( empty( $login ) || ! is_string( $login ) ) { + $woocommerce->add_error( __( 'Invalid key', 'woocommerce' ) ); + return false; + } + + $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $key, $login ) ); + + if ( empty( $user ) ) { + $woocommerce->add_error( __( 'Invalid key', 'woocommerce' ) ); + return false; + } + + return $user; + } + + /** + * Handles resetting the user's password. + * + * @access public + * @param object $user The user + * @param string $new_pass New password for the user in plaintext + * @return void + */ + public static function reset_password( $user, $new_pass ) { + do_action( 'password_reset', $user, $new_pass ); + + wp_set_password( $new_pass, $user->ID ); + + wp_password_change_notification( $user ); + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-my-account.php b/classes/shortcodes/class-wc-shortcode-my-account.php new file mode 100644 index 00000000000..e5d6f802a7f --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-my-account.php @@ -0,0 +1,56 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + + if ( ! is_user_logged_in() ) { + + woocommerce_get_template( 'myaccount/form-login.php' ); + + } else { + + extract( shortcode_atts( array( + 'order_count' => 5 + ), $atts ) ); + + woocommerce_get_template( 'myaccount/my-account.php', array( + 'current_user' => get_user_by( 'id', get_current_user_id() ), + 'order_count' => 'all' == $order_count ? -1 : $order_count + ) ); + + } + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-order-tracking.php b/classes/shortcodes/class-wc-shortcode-order-tracking.php new file mode 100644 index 00000000000..a030e676b76 --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-order-tracking.php @@ -0,0 +1,86 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + + extract(shortcode_atts(array( + ), $atts)); + + global $post; + + if ( ! empty( $_REQUEST['orderid'] ) ) { + + $woocommerce->verify_nonce( 'order_tracking' ); + + $order_id = empty( $_REQUEST['orderid'] ) ? 0 : esc_attr( $_REQUEST['orderid'] ); + $order_email = empty( $_REQUEST['order_email'] ) ? '' : esc_attr( $_REQUEST['order_email']) ; + + if ( ! $order_id ) { + + echo '

    ' . __( 'Please enter a valid order ID', 'woocommerce' ) . '

    '; + + } elseif ( ! $order_email ) { + + echo '

    ' . __( 'Please enter a valid order email', 'woocommerce' ) . '

    '; + + } else { + + $order = new WC_Order( apply_filters( 'woocommerce_shortcode_order_tracking_order_id', $order_id ) ); + + if ( $order->id && $order_email ) { + + if ( strtolower( $order->billing_email ) == strtolower( $order_email ) ) { + do_action( 'woocommerce_track_order', $order->id ); + woocommerce_get_template( 'order/tracking.php', array( + 'order' => $order + ) ); + + return; + } + + } else { + + echo '

    ' . sprintf( __( 'Sorry, we could not find that order id in our database.', 'woocommerce' ), get_permalink($post->ID ) ) . '

    '; + + } + + } + + } + + woocommerce_get_template( 'order/form-tracking.php' ); + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-pay.php b/classes/shortcodes/class-wc-shortcode-pay.php new file mode 100644 index 00000000000..f733ca80b34 --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-pay.php @@ -0,0 +1,136 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + + do_action( 'before_woocommerce_pay' ); + + $woocommerce->show_messages(); + + if ( isset( $_GET['pay_for_order'] ) && isset( $_GET['order'] ) && isset( $_GET['order_id'] ) ) { + + // Pay for existing order + $order_key = urldecode( $_GET[ 'order' ] ); + $order_id = absint( $_GET[ 'order_id' ] ); + $order = new WC_Order( $order_id ); + $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $order ); + + if ( $order->id == $order_id && $order->order_key == $order_key && in_array( $order->status, $valid_order_statuses ) ) { + + // Set customer location to order location + if ( $order->billing_country ) + $woocommerce->customer->set_country( $order->billing_country ); + if ( $order->billing_state ) + $woocommerce->customer->set_state( $order->billing_state ); + if ( $order->billing_postcode ) + $woocommerce->customer->set_postcode( $order->billing_postcode ); + + // Show form + woocommerce_get_template( 'checkout/form-pay.php', array( 'order' => $order ) ); + + } elseif ( ! in_array( $order->status, $valid_order_statuses ) ) { + + $woocommerce->add_error( __( 'Your order has already been paid for. Please contact us if you need assistance.', 'woocommerce' ) ); + $woocommerce->show_messages(); + + } else { + + $woocommerce->add_error( __( 'Invalid order.', 'woocommerce' ) ); + $woocommerce->show_messages(); + + } + + } else { + + // Pay for order after checkout step + $order_id = isset( $_GET['order'] ) ? absint( $_GET['order'] ) : 0; + $order_key = isset( $_GET['key'] ) ? woocommerce_clean( $_GET['key'] ) : ''; + + if ( $order_id > 0 ) { + + $order = new WC_Order( $order_id ); + $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $order ); + + if ( $order->order_key == $order_key && in_array( $order->status, $valid_order_statuses ) ) { + + ?> + + + payment_method, $order_id ); ?> + +
    + status, $valid_order_statuses ) ) { + + $woocommerce->add_error( __( 'Your order has already been paid for. Please contact us if you need assistance.', 'woocommerce' ) ); + $woocommerce->show_messages(); + + } + + } else { + + $woocommerce->add_error( __( 'Invalid order.', 'woocommerce' ) ); + $woocommerce->show_messages(); + + } + + } + + do_action( 'after_woocommerce_pay' ); + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-thankyou.php b/classes/shortcodes/class-wc-shortcode-thankyou.php new file mode 100644 index 00000000000..90d15bbdea2 --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-thankyou.php @@ -0,0 +1,57 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + $woocommerce->show_messages(); + + $order = false; + + // Get the order + $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET['order'] ) ? 0 : absint( $_GET['order'] ) ); + $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : woocommerce_clean( $_GET['key'] ) ); + + if ( $order_id > 0 ) { + $order = new WC_Order( $order_id ); + if ( $order->order_key != $order_key ) + unset( $order ); + } + + // Empty awaiting payment session + unset( $woocommerce->session->order_awaiting_payment ); + + woocommerce_get_template( 'checkout/thankyou.php', array( 'order' => $order ) ); + } +} \ No newline at end of file diff --git a/classes/shortcodes/class-wc-shortcode-view-order.php b/classes/shortcodes/class-wc-shortcode-view-order.php new file mode 100644 index 00000000000..9e43df747e7 --- /dev/null +++ b/classes/shortcodes/class-wc-shortcode-view-order.php @@ -0,0 +1,89 @@ +shortcode_wrapper( array( __CLASS__, 'output' ), $atts ); + } + + /** + * Output the shortcode. + * + * @access public + * @param array $atts + * @return void + */ + public static function output( $atts ) { + global $woocommerce; + + $woocommerce->nocache(); + + if ( ! is_user_logged_in() ) return; + + extract( shortcode_atts( array( + 'order_count' => 10 + ), $atts ) ); + + $user_id = get_current_user_id(); + $order_id = ( isset( $_GET['order'] ) ) ? $_GET['order'] : 0; + $order = new WC_Order( $order_id ); + + if ( $order_id == 0 ) { + woocommerce_get_template( 'myaccount/my-orders.php', array( 'order_count' => 'all' == $order_count ? -1 : $order_count ) ); + return; + } + + if ( $order->user_id != $user_id ) { + echo '
    ' . __( 'Invalid order.', 'woocommerce' ) . ' '. __( 'My Account →', 'woocommerce' ) .'' . '
    '; + return; + } + + $status = get_term_by('slug', $order->status, 'shop_order_status'); + + echo '

    ' + . sprintf( __( 'Order %s made on %s', 'woocommerce'), $order->get_order_number(), date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ) ) + . '. ' . sprintf( __( 'Order status: %s', 'woocommerce' ), __( $status->name, 'woocommerce' ) ) + . '.

    '; + + $notes = $order->get_customer_order_notes(); + if ($notes) : + ?> +

    +
      + +
    1. +
      +
      +

      comment_date)); ?>

      +
      + comment_content)); ?> +
      +
      +
      +
      +
      +
    2. + +
    + name, $cat ); diff --git a/classes/walkers/class-product-cat-list-walker.php b/classes/walkers/class-product-cat-list-walker.php index fc5a9f146e5..16d8085ba52 100644 --- a/classes/walkers/class-product-cat-list-walker.php +++ b/classes/walkers/class-product-cat-list-walker.php @@ -126,7 +126,7 @@ class WC_Product_Cat_List_Walker extends Walker { $id = $element->$id_field; - // descend only when the depth is right and there are childrens for this element + // descend only when the depth is right and there are children for this element if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) { foreach( $children_elements[ $id ] as $child ){ diff --git a/widgets/widget-best_sellers.php b/classes/widgets/class-wc-widget-best-sellers.php similarity index 82% rename from widgets/widget-best_sellers.php rename to classes/widgets/class-wc-widget-best-sellers.php index 24d8a6552bd..b7b7f991144 100644 --- a/widgets/widget-best_sellers.php +++ b/classes/widgets/class-wc-widget-best-sellers.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_Best_Sellers extends WP_Widget { +class WC_Widget_Best_Sellers extends WP_Widget { var $woo_widget_cssclass; var $woo_widget_description; @@ -24,7 +24,7 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_Best_Sellers() { + function WC_Widget_Best_Sellers() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_best_sellers'; @@ -38,9 +38,9 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget { /* Create the widget. */ $this->WP_Widget('best_sellers', $this->woo_widget_name, $widget_ops); - add_action( 'save_post', array(&$this, 'flush_widget_cache') ); - add_action( 'deleted_post', array(&$this, 'flush_widget_cache') ); - add_action( 'switch_theme', array(&$this, 'flush_widget_cache') ); + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); } @@ -101,26 +101,30 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget { $r = new WP_Query($query_args); - if ($r->have_posts()) : -?> - - - - -have_posts() ) { + + echo $before_widget; + + if ( $title ) + echo $before_title . $title . $after_title; + + echo ''; + + echo $after_widget; + } $content = ob_get_clean(); diff --git a/widgets/widget-cart.php b/classes/widgets/class-wc-widget-cart.php similarity index 83% rename from widgets/widget-cart.php rename to classes/widgets/class-wc-widget-cart.php index 845eafe0254..bccd3121139 100644 --- a/widgets/widget-cart.php +++ b/classes/widgets/class-wc-widget-cart.php @@ -7,13 +7,13 @@ * @author WooThemes * @category Widgets * @package WooCommerce/Widgets - * @version 1.6.4 + * @version 2.0.0 * @extends WP_Widget */ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_Cart extends WP_Widget { +class WC_Widget_Cart extends WP_Widget { var $woo_widget_cssclass; var $woo_widget_description; @@ -26,7 +26,7 @@ class WooCommerce_Widget_Cart extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_Cart() { + function WC_Widget_Cart() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_shopping_cart'; @@ -59,22 +59,30 @@ class WooCommerce_Widget_Cart extends WP_Widget { if ( is_cart() || is_checkout() ) return; $title = apply_filters('widget_title', empty( $instance['title'] ) ? __( 'Cart', 'woocommerce' ) : $instance['title'], $instance, $this->id_base ); - $hide_if_empty = empty( $instance['hide_if_empty'] ) ? 0 : 1; + $hide_if_empty = empty( $instance['hide_if_empty'] ) ? 0 : 1; echo $before_widget; if ( $title ) echo $before_title . $title . $after_title; - $woocommerce->mfunc_wrapper( 'woocommerce_mini_cart()', 'woocommerce_mini_cart', array( 'list_class' => $hide_if_empty ? 'hide_cart_widget_if_empty' : '' ) ); + if ( $hide_if_empty ) + echo '
    '; + + // Insert cart widget placeholder - code in woocommerce.js will update this on page load + echo '
    '; + + if ( $hide_if_empty ) + echo '
    '; echo $after_widget; if ( $hide_if_empty && sizeof( $woocommerce->cart->get_cart() ) == 0 ) { $woocommerce->add_inline_js( " - jQuery('.hide_cart_widget_if_empty').closest('.widget').hide(); + jQuery('.hide_cart_widget_if_empty').closest('.widget_shopping_cart').hide(); + jQuery('body').bind('adding_to_cart', function(){ - jQuery(this).find('.hide_cart_widget_if_empty').closest('.widget').fadeIn(); + jQuery('.hide_cart_widget_if_empty').closest('.widget_shopping_cart').fadeIn(); }); " ); } diff --git a/widgets/widget-featured_products.php b/classes/widgets/class-wc-widget-featured-products.php similarity index 93% rename from widgets/widget-featured_products.php rename to classes/widgets/class-wc-widget-featured-products.php index 845822e0b6b..ddc5a8aca2a 100644 --- a/widgets/widget-featured_products.php +++ b/classes/widgets/class-wc-widget-featured-products.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_Featured_Products extends WP_Widget { +class WC_Widget_Featured_Products extends WP_Widget { /** Variables to setup the widget. */ var $woo_widget_cssclass; @@ -28,7 +28,7 @@ class WooCommerce_Widget_Featured_Products extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_Featured_Products() { + function WC_Widget_Featured_Products() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_featured_products'; @@ -42,9 +42,9 @@ class WooCommerce_Widget_Featured_Products extends WP_Widget { /* Create the widget. */ $this->WP_Widget('featured-products', $this->woo_widget_name, $widget_ops); - add_action( 'save_post', array(&$this, 'flush_widget_cache') ); - add_action( 'deleted_post', array(&$this, 'flush_widget_cache') ); - add_action( 'switch_theme', array(&$this, 'flush_widget_cache') ); + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); } diff --git a/widgets/widget-layered_nav_filters.php b/classes/widgets/class-wc-widget-layered-nav-filters.php similarity index 64% rename from widgets/widget-layered_nav_filters.php rename to classes/widgets/class-wc-widget-layered-nav-filters.php index 7b8d026e478..5395f436820 100644 --- a/widgets/widget-layered_nav_filters.php +++ b/classes/widgets/class-wc-widget-layered-nav-filters.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_Layered_Nav_Filters extends WP_Widget { +class WC_Widget_Layered_Nav_Filters extends WP_Widget { var $woo_widget_cssclass; var $woo_widget_description; @@ -24,7 +24,7 @@ class WooCommerce_Widget_Layered_Nav_Filters extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_Layered_Nav_Filters() { + function WC_Widget_Layered_Nav_Filters() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_layered_nav_filters'; @@ -53,22 +53,25 @@ class WooCommerce_Widget_Layered_Nav_Filters extends WP_Widget { extract( $args ); - if ( ! is_post_type_archive( 'product' ) && ! is_tax( array_merge( $_attributes_array, array( 'product_cat', 'product_tag' ) ) ) ) + if ( ! is_post_type_archive( 'product' ) && is_array( $_attributes_array ) && ! is_tax( array_merge( $_attributes_array, array( 'product_cat', 'product_tag' ) ) ) ) return; $current_term = $_attributes_array && is_tax( $_attributes_array ) ? get_queried_object()->term_id : ''; $current_tax = $_attributes_array && is_tax( $_attributes_array ) ? get_queried_object()->taxonomy : ''; - $title = __( 'Active filters', 'woocommerce' ); - //$title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base ); + $title = ( ! isset( $instance['title'] ) ) ? __( 'Active filters', 'woocommerce' ) : $instance['title']; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base); // Price - $post_min = isset( $woocommerce->session->min_price ) ? $woocommerce->session->min_price : 0; - $post_max = isset( $woocommerce->session->max_price ) ? $woocommerce->session->max_price : 0; + $min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : 0; + $max_price = isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : 0; - if ( count( $_chosen_attributes ) > 0 || $post_min > 0 || $post_max > 0 ) { + if ( count( $_chosen_attributes ) > 0 || $min_price > 0 || $max_price > 0 ) { - echo $before_widget . $before_title . $title . $after_title; + echo $before_widget; + if ( $title ) { + echo $before_title . $title . $after_title; + } echo ""; diff --git a/widgets/widget-layered_nav.php b/classes/widgets/class-wc-widget-layered-nav.php similarity index 76% rename from widgets/widget-layered_nav.php rename to classes/widgets/class-wc-widget-layered-nav.php index ef52f501666..1e3c0012041 100644 --- a/widgets/widget-layered_nav.php +++ b/classes/widgets/class-wc-widget-layered-nav.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_Layered_Nav extends WP_Widget { +class WC_Widget_Layered_Nav extends WP_Widget { var $woo_widget_cssclass; var $woo_widget_description; @@ -24,7 +24,7 @@ class WooCommerce_Widget_Layered_Nav extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_Layered_Nav() { + function WC_Widget_Layered_Nav() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_layered_nav'; @@ -93,7 +93,7 @@ class WooCommerce_Widget_Layered_Nav extends WP_Widget { $taxonomy_filter = str_replace( 'pa_', '', $taxonomy ); - $found = true; + $found = false; echo '

    attribute_taxonomies; - if ( $attribute_taxonomies ) { - foreach ( $attribute_taxonomies as $tax ) { - - $attribute = sanitize_title( $tax->attribute_name ); - $taxonomy = $woocommerce->attribute_taxonomy_name( $attribute ); - - // create an array of product attribute taxonomies - $_attributes_array[] = $taxonomy; - - $name = 'filter_' . $attribute; - $query_type_name = 'query_type_' . $attribute; - - if ( ! empty( $_GET[ $name ] ) && taxonomy_exists( $taxonomy ) ) { - - $_chosen_attributes[ $taxonomy ]['terms'] = explode( ',', $_GET[ $name ] ); - - if ( ! empty( $_GET[ $query_type_name ] ) && $_GET[ $query_type_name ] == 'or' ) - $_chosen_attributes[ $taxonomy ]['query_type'] = 'or'; - else - $_chosen_attributes[ $taxonomy ]['query_type'] = 'and'; - - } - } - } - - add_filter('loop_shop_post_in', 'woocommerce_layered_nav_query'); - } -} - -add_action( 'init', 'woocommerce_layered_nav_init', 1 ); - - -/** - * Layered Nav post filter - * - * @package WooCommerce/Widgets - * @access public - * @param array $filtered_posts - * @return array - */ -function woocommerce_layered_nav_query( $filtered_posts ) { - global $_chosen_attributes, $woocommerce, $wp_query; - - if ( sizeof( $_chosen_attributes ) > 0 ) { - - $matched_products = array(); - $filtered_attribute = false; - - foreach ( $_chosen_attributes as $attribute => $data ) { - - $matched_products_from_attribute = array(); - $filtered = false; - - if ( sizeof( $data['terms'] ) > 0 ) { - foreach ( $data['terms'] as $value ) { - - $posts = get_posts( - array( - 'post_type' => 'product', - 'numberposts' => -1, - 'post_status' => 'publish', - 'fields' => 'ids', - 'no_found_rows' => true, - 'tax_query' => array( - array( - 'taxonomy' => $attribute, - 'terms' => $value, - 'field' => 'id' - ) - ) - ) - ); - - // AND or OR - if ( $data['query_type'] == 'or' ) { - - if ( ! is_wp_error( $posts ) && ( sizeof( $matched_products_from_attribute ) > 0 || $filtered ) ) - $matched_products_from_attribute = array_merge($posts, $matched_products_from_attribute); - elseif ( ! is_wp_error( $posts ) ) - $matched_products_from_attribute = $posts; - - } else { - - if ( ! is_wp_error( $posts ) && ( sizeof( $matched_products_from_attribute ) > 0 || $filtered ) ) - $matched_products_from_attribute = array_intersect($posts, $matched_products_from_attribute); - elseif ( ! is_wp_error( $posts ) ) - $matched_products_from_attribute = $posts; - } - - $filtered = true; - - } - } - - if ( sizeof( $matched_products ) > 0 || $filtered_attribute ) - $matched_products = array_intersect( $matched_products_from_attribute, $matched_products ); - else - $matched_products = $matched_products_from_attribute; - - $filtered_attribute = true; - - } - - if ( $filtered ) { - - $woocommerce->query->layered_nav_post__in = $matched_products; - $woocommerce->query->layered_nav_post__in[] = 0; - - if ( sizeof( $filtered_posts ) == 0 ) { - $filtered_posts = $matched_products; - $filtered_posts[] = 0; - } else { - $filtered_posts = array_intersect( $filtered_posts, $matched_products ); - $filtered_posts[] = 0; - } - - } - } - - return (array) $filtered_posts; } \ No newline at end of file diff --git a/widgets/widget-onsale.php b/classes/widgets/class-wc-widget-onsale.php similarity index 67% rename from widgets/widget-onsale.php rename to classes/widgets/class-wc-widget-onsale.php index e264e691d97..b334537df10 100644 --- a/widgets/widget-onsale.php +++ b/classes/widgets/class-wc-widget-onsale.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_On_Sale extends WP_Widget { +class WC_Widget_Onsale extends WP_Widget { var $woo_widget_cssclass; var $woo_widget_description; @@ -24,7 +24,7 @@ class WooCommerce_Widget_On_Sale extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_On_Sale() { + function WC_Widget_Onsale() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_onsale'; @@ -38,9 +38,9 @@ class WooCommerce_Widget_On_Sale extends WP_Widget { /* Create the widget. */ $this->WP_Widget('onsale', $this->woo_widget_name, $widget_ops); - add_action( 'save_post', array(&$this, 'flush_widget_cache') ); - add_action( 'deleted_post', array(&$this, 'flush_widget_cache') ); - add_action( 'switch_theme', array(&$this, 'flush_widget_cache') ); + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); } /** @@ -76,40 +76,7 @@ class WooCommerce_Widget_On_Sale extends WP_Widget { $number = 15; // Get products on sale - if ( false === ( $product_ids_on_sale = get_transient( 'wc_products_onsale' ) ) ) { - - $meta_query = array(); - - $meta_query[] = array( - 'key' => '_sale_price', - 'value' => 0, - 'compare' => '>', - 'type' => 'NUMERIC' - ); - - $on_sale = get_posts(array( - 'post_type' => array('product', 'product_variation'), - 'posts_per_page' => -1, - 'post_status' => 'publish', - 'meta_query' => $meta_query, - 'fields' => 'id=>parent' - )); - - $product_ids = array_keys( $on_sale ); - $parent_ids = array_values( $on_sale ); - - // Check for scheduled sales which have not started - foreach ( $product_ids as $key => $id ) - if ( get_post_meta( $id, '_sale_price_dates_from', true ) > current_time('timestamp') ) - unset( $product_ids[ $key ] ); - - $product_ids_on_sale = array_unique( array_merge( $product_ids, $parent_ids ) ); - - set_transient( 'wc_products_onsale', $product_ids_on_sale ); - - } - - $product_ids_on_sale[] = 0; + $product_ids_on_sale = woocommerce_get_product_ids_on_sale(); $meta_query = array(); $meta_query[] = $woocommerce->query->visibility_meta_query(); @@ -128,26 +95,30 @@ class WooCommerce_Widget_On_Sale extends WP_Widget { $r = new WP_Query($query_args); - if ( $r->have_posts() ) : -?> - - - - -have_posts() ) { + + echo $before_widget; + + if ( $title ) + echo $before_title . $title . $after_title; + + echo ''; + + echo $after_widget; + } $content = ob_get_clean(); diff --git a/widgets/widget-price_filter.php b/classes/widgets/class-wc-widget-price-filter.php similarity index 64% rename from widgets/widget-price_filter.php rename to classes/widgets/class-wc-widget-price-filter.php index abba0b66ae8..8fd3bd43ad3 100644 --- a/widgets/widget-price_filter.php +++ b/classes/widgets/class-wc-widget-price-filter.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -class WooCommerce_Widget_Price_Filter extends WP_Widget { +class WC_Widget_Price_Filter extends WP_Widget { var $woo_widget_cssclass; var $woo_widget_description; @@ -26,7 +26,7 @@ class WooCommerce_Widget_Price_Filter extends WP_Widget { * @access public * @return void */ - function WooCommerce_Widget_Price_Filter() { + function WC_Widget_Price_Filter() { /* Widget variable settings. */ $this->woo_widget_cssclass = 'woocommerce widget_price_filter'; @@ -60,13 +60,16 @@ class WooCommerce_Widget_Price_Filter extends WP_Widget { if ( sizeof( $woocommerce->query->unfiltered_product_ids ) == 0 ) return; // None shown - return + $min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : ''; + $max_price = isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : ''; + wp_enqueue_script( 'wc-price-slider' ); wp_localize_script( 'wc-price-slider', 'woocommerce_price_slider_params', array( 'currency_symbol' => get_woocommerce_currency_symbol(), 'currency_pos' => get_option( 'woocommerce_currency_pos' ), - 'min_price' => isset( $woocommerce->session->min_price ) ? $woocommerce->session->min_price : '', - 'max_price' => isset( $woocommerce->session->max_price ) ? $woocommerce->session->max_price : '' + 'min_price' => $min_price, + 'max_price' => $max_price ) ); $title = $instance['title']; @@ -119,9 +122,6 @@ class WooCommerce_Widget_Price_Filter extends WP_Widget { if ( $min == $max ) return; - if ( isset( $woocommerce->session->min_price ) ) $post_min = $woocommerce->session->min_price; - if ( isset( $woocommerce->session->max_price ) ) $post_max = $woocommerce->session->max_price; - echo $before_widget . $before_title . $title . $after_title; if ( get_option( 'permalink_structure' ) == '' ) @@ -133,8 +133,8 @@ class WooCommerce_Widget_Price_Filter extends WP_Widget {
    - - + +
    : - - - - - - - - - - - - - - - - - flat_rates ) { - foreach ( $this->flat_rates as $class => $rate ) { + /** + * generate_additional_costs_html function. + * + * @access public + * @return void + */ + function generate_additional_costs_table_html() { + global $woocommerce; + ob_start(); + ?> + + + - -
    [?] [?]
    : + + + + + + + + + + + + + + + + + + + + + + flat_rates ) { + foreach ( $this->flat_rates as $class => $rate ) { $i++; echo ' - + '; - } - } - ?> - -
    [?] [?]
    -
    - - id; ?>_flat_rates').on( 'click', 'a.remove', function(){ + var answer = confirm("") + if (answer) { + jQuery('#id; ?>_flat_rates table tbody tr td.check-column input:checked').each(function(i, el){ + jQuery(el).closest('tr').remove(); + }); + } + return false; + }); + }); + +
    @@ -93,7 +97,7 @@ global $woocommerce; $min = apply_filters( 'woocommerce_quantity_input_min', '', $_product ); $max = apply_filters( 'woocommerce_quantity_input_max', $_product->backorders_allowed() ? '' : $_product->get_stock_quantity(), $_product ); - $product_quantity = sprintf( '
    ', $cart_item_key, $step, $min, $max, esc_attr( $values['quantity'] ) ); + $product_quantity = sprintf( '
    ', $cart_item_key, $step, $min, $max, esc_attr( $values['quantity'] ) ); } echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key ); @@ -117,7 +121,7 @@ global $woocommerce;
    - + cart->coupons_enabled() ) { ?>
    @@ -138,8 +142,11 @@ global $woocommerce;
    + + +
    @@ -148,4 +155,6 @@ global $woocommerce; -
    \ No newline at end of file + + + \ No newline at end of file diff --git a/templates/cart/cross-sells.php b/templates/cart/cross-sells.php index b5055eddd1c..da2aec427eb 100644 --- a/templates/cart/cross-sells.php +++ b/templates/cart/cross-sells.php @@ -15,13 +15,18 @@ $crosssells = $woocommerce->cart->get_cross_sells(); if ( sizeof( $crosssells ) == 0 ) return; +$meta_query = array(); +$meta_query[] = $woocommerce->query->visibility_meta_query(); +$meta_query[] = $woocommerce->query->stock_status_meta_query(); + $args = array( - 'post_type' => 'product', - 'ignore_sticky_posts' => 1, - 'posts_per_page' => 2, - 'no_found_rows' => 1, - 'orderby' => 'rand', - 'post__in' => $crosssells + 'post_type' => 'product', + 'ignore_sticky_posts' => 1, + 'posts_per_page' => 2, + 'no_found_rows' => 1, + 'orderby' => 'rand', + 'post__in' => $crosssells, + 'meta_query' => $meta_query ); $products = new WP_Query( $args ); diff --git a/templates/cart/mini-cart.php b/templates/cart/mini-cart.php index 84b7546d43f..a1a57dda40a 100644 --- a/templates/cart/mini-cart.php +++ b/templates/cart/mini-cart.php @@ -13,6 +13,9 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly global $woocommerce; ?> + + +
      cart->get_cart() ) > 0 ) : ?> @@ -42,7 +45,7 @@ global $woocommerce; cart->get_item_data( $cart_item ); ?> - + ' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '', $cart_item, $cart_item_key ); ?> @@ -66,4 +69,6 @@ global $woocommerce;

      - \ No newline at end of file + + + diff --git a/templates/cart/shipping-calculator.php b/templates/cart/shipping-calculator.php index 2363ce529bc..6dc1d9baf58 100644 --- a/templates/cart/shipping-calculator.php +++ b/templates/cart/shipping-calculator.php @@ -19,7 +19,7 @@ if ( get_option('woocommerce_enable_shipping_calc')=='no' || ! $woocommerce->car

      -

      +

      -

      +

      customer->get_shipping_country(); $current_r = $woocommerce->customer->get_shipping_state(); @@ -39,7 +39,7 @@ if ( get_option('woocommerce_enable_shipping_calc')=='no' || ! $woocommerce->car // Hidden ?> - + car // Dropdown ?> - @@ -58,15 +58,14 @@ if ( get_option('woocommerce_enable_shipping_calc')=='no' || ! $woocommerce->car // Input ?> - +

      -

      - +

      diff --git a/templates/cart/shipping-methods.php b/templates/cart/shipping-methods.php index 8205ff75388..91478db31b5 100644 --- a/templates/cart/shipping-methods.php +++ b/templates/cart/shipping-methods.php @@ -20,17 +20,18 @@ if ( $available_methods ) { if ( $woocommerce->cart->tax_display_cart == 'excl' ) { $method->full_label .= ': ' . woocommerce_price( $method->cost ); if ( $method->get_shipping_tax() > 0 && $woocommerce->cart->prices_include_tax ) { - $method->full_label .= ' '.$woocommerce->countries->ex_tax_or_vat(); + $method->full_label .= ' ' . $woocommerce->countries->ex_tax_or_vat() . ''; } } else { $method->full_label .= ': ' . woocommerce_price( $method->cost + $method->get_shipping_tax() ); if ( $method->get_shipping_tax() > 0 && ! $woocommerce->cart->prices_include_tax ) { - $method->full_label .= ' '.$woocommerce->countries->inc_tax_or_vat(); + $method->full_label .= ' ' . $woocommerce->countries->inc_tax_or_vat() . ''; } } } elseif ( $method->id !== 'free_shipping' ) { $method->full_label .= ' (' . __( 'Free', 'woocommerce' ) . ')'; } + $method->full_label = apply_filters( 'woocommerce_cart_shipping_method_full_label', $method->full_label, $method ); } // Print a single available shipping method as plain text diff --git a/templates/cart/totals.php b/templates/cart/totals.php index 0590c57afb6..47e003f4aef 100644 --- a/templates/cart/totals.php +++ b/templates/cart/totals.php @@ -40,11 +40,15 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); cart->needs_shipping() && $woocommerce->cart->show_shipping() && ( $available_methods || get_option( 'woocommerce_enable_shipping_calc' ) == 'yes' ) ) : ?> + + $available_methods ) ); ?> + + cart->get_fees() as $fee ) : ?> @@ -119,6 +123,8 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); + + @@ -143,6 +149,8 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); + + @@ -162,7 +170,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); customer->get_shipping_state() || ! $woocommerce->customer->get_shipping_postcode() ) : ?> -
      +

      @@ -170,7 +178,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); -
      +

      countries->countries[ $woocommerce->customer->get_shipping_country() ] ); ?>

      diff --git a/templates/checkout/form-checkout.php b/templates/checkout/form-checkout.php index 40663df7fe8..ee8e123d092 100644 --- a/templates/checkout/form-checkout.php +++ b/templates/checkout/form-checkout.php @@ -13,7 +13,7 @@ global $woocommerce; $woocommerce->show_messages(); -do_action( 'woocommerce_before_checkout_form' ); +do_action( 'woocommerce_before_checkout_form', $checkout ); // If checkout registration is disabled and not logged in, the user cannot checkout if ( ! $checkout->enable_signup && ! $checkout->enable_guest_checkout && ! is_user_logged_in() ) { @@ -56,4 +56,4 @@ $get_checkout_url = apply_filters( 'woocommerce_get_checkout_url', $woocommerce- - \ No newline at end of file + \ No newline at end of file diff --git a/templates/checkout/form-coupon.php b/templates/checkout/form-coupon.php index 40709889358..b49327f8cb5 100644 --- a/templates/checkout/form-coupon.php +++ b/templates/checkout/form-coupon.php @@ -9,14 +9,17 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -if ( get_option( 'woocommerce_enable_coupons' ) == 'no' || get_option( 'woocommerce_enable_coupon_form_on_checkout' ) == 'no' ) return; +global $woocommerce; + +if ( ! $woocommerce->cart->coupons_enabled() ) + return; $info_message = apply_filters('woocommerce_checkout_coupon_message', __( 'Have a coupon?', 'woocommerce' )); ?> -

      +

      -
      +

      diff --git a/templates/checkout/form-login.php b/templates/checkout/form-login.php index f1eb3978e59..51d5568e471 100644 --- a/templates/checkout/form-login.php +++ b/templates/checkout/form-login.php @@ -11,16 +11,17 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly if ( is_user_logged_in() || ! $checkout->enable_signup ) return; -$info_message = apply_filters( 'woocommerce_checkout_login_message', __( 'Already registered?', 'woocommerce' ) ); +$info_message = apply_filters( 'woocommerce_checkout_login_message', __( 'Returning customer?', 'woocommerce' ) ); ?> -

      +

      __( 'If you have shopped with us before, please enter your details in the boxes below. If you are a new customer please proceed to the Billing & Shipping section.', 'woocommerce' ), - 'redirect' => get_permalink( woocommerce_get_page_id( 'checkout') ) + 'redirect' => get_permalink( woocommerce_get_page_id( 'checkout') ), + 'hidden' => true ) ); ?> \ No newline at end of file diff --git a/templates/checkout/form-pay.php b/templates/checkout/form-pay.php index d10f17b1bc5..ebe8762ef26 100644 --- a/templates/checkout/form-pay.php +++ b/templates/checkout/form-pay.php @@ -53,30 +53,31 @@ global $woocommerce; order_total > 0) : ?>
        payment_gateways->get_available_payment_gateways(); - if ($available_gateways) : + if ( $available_gateways = $woocommerce->payment_gateways->get_available_payment_gateways() ) { // Chosen Method - if (sizeof($available_gateways)) current($available_gateways)->set_current(); - foreach ($available_gateways as $gateway ) : + if ( sizeof( $available_gateways ) ) + current( $available_gateways )->set_current(); + + foreach ( $available_gateways as $gateway ) { ?>
      • chosen) echo 'checked="checked"'; ?> /> has_fields() || $gateway->get_description() ) : + if ( $gateway->has_fields() || $gateway->get_description() ) { echo ''; - endif; + } ?>
      • '.__( 'Sorry, it seems that there are no available payment methods for your location. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ).'

        '; - endif; + } ?>
      diff --git a/templates/checkout/review-order.php b/templates/checkout/review-order.php index c704be472a5..f7650a90664 100644 --- a/templates/checkout/review-order.php +++ b/templates/checkout/review-order.php @@ -19,21 +19,19 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); - - + - - + cart->get_cart_subtotal(); ?> cart->get_discounts_before_tax() ) : ?> - + -cart->get_discounts_before_tax(); ?> @@ -44,7 +42,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); - + $available_methods ) ); ?> @@ -55,7 +53,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); cart->get_fees() as $fee ) : ?> - name ?> + name ?> cart->tax_display_cart == 'excl' ) echo woocommerce_price( $fee->amount ); @@ -83,7 +81,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); } ?> - cart->tax->get_rate_label( $key ); ?> + cart->tax->get_rate_label( $key ); ?> shipping->get_available_shipping_methods(); if ( $has_compound_tax ) { ?> - - cart->get_cart_subtotal( true ); ?> + + cart->get_cart_subtotal( true ); ?> shipping->get_available_shipping_methods(); continue; ?> - cart->tax->get_rate_label( $key ); ?> + cart->tax->get_rate_label( $key ); ?> shipping->get_available_shipping_methods(); } elseif ( $woocommerce->cart->get_cart_tax() ) { ?> - + cart->get_cart_tax(); ?> shipping->get_available_shipping_methods(); cart->get_discounts_after_tax()) : ?> - + -cart->get_discounts_after_tax(); ?> - + - + cart->get_total(); ?> shipping->get_available_shipping_methods(); - + cart->get_cart())>0) : - foreach ($woocommerce->cart->get_cart() as $item_id => $values) : + foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) : $_product = $values['data']; if ($_product->exists() && $values['quantity']>0) : echo ' - - '.$_product->get_title().$woocommerce->cart->get_item_data( $values ).' - '.$values['quantity'].' - ' . apply_filters( 'woocommerce_checkout_item_subtotal', $woocommerce->cart->get_product_subtotal( $_product, $values['quantity'] ), $values, $item_id ) . ' + + ' . + apply_filters( 'woocommerce_checkout_product_title', $_product->get_title(), $_product ) . ' ' . + apply_filters( 'woocommerce_checkout_item_quantity', '× ' . $values['quantity'] . '', $values, $cart_item_key ) . + $woocommerce->cart->get_item_data( $values ) . + ' + ' . apply_filters( 'woocommerce_checkout_item_subtotal', $woocommerce->cart->get_product_subtotal( $_product, $values['quantity'] ), $values, $cart_item_key ) . ' '; endif; endforeach; endif; - do_action( 'woocommerce_cart_contents_review_order' ); + do_action( 'woocommerce_review_order_after_cart_contents' ); ?> @@ -186,25 +189,22 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
        payment_gateways->get_available_payment_gateways(); - if ($available_gateways) : + if ( ! empty( $available_gateways ) ) { + // Chosen Method - if (sizeof($available_gateways)) : - $default_gateway = get_option('woocommerce_default_gateway'); + if ( isset( $woocommerce->session->chosen_payment_method ) && isset( $available_gateways[ $woocommerce->session->chosen_payment_method ] ) ) { + $available_gateways[ $woocommerce->session->chosen_payment_method ]->set_current(); + } elseif ( isset( $available_gateways[ get_option( 'woocommerce_default_gateway' ) ] ) ) { + $available_gateways[ get_option( 'woocommerce_default_gateway' ) ]->set_current(); + } else { + current( $available_gateways )->set_current(); + } - if ( isset( $woocommerce->session->chosen_payment_method ) && isset( $available_gateways[ $woocommerce->session->chosen_payment_method ] ) ) { - $available_gateways[ $woocommerce->session->chosen_payment_method ]->set_current(); - } elseif ( isset( $available_gateways[ $default_gateway ] ) ) { - $available_gateways[ $default_gateway ]->set_current(); - } else { - current( $available_gateways )->set_current(); - } - - endif; - foreach ($available_gateways as $gateway ) : + foreach ( $available_gateways as $gateway ) { ?>
      • - chosen, true ); ?> /> - + chosen, true ); ?> /> + has_fields() || $gateway->get_description() ) : echo '
        chosen ? '' : 'style="display:none;"' ) . '>'; @@ -214,16 +214,15 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods(); ?>
      • customer->get_country() ) : - echo '

        '.__( 'Please fill in your details above to see available payment methods.', 'woocommerce' ).'

        '; - else : - echo '

        '.__( 'Sorry, it seems that there are no available payment methods for your state. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ).'

        '; - endif; + if ( ! $woocommerce->customer->get_country() ) + echo '

        ' . __( 'Please fill in your details above to see available payment methods.', 'woocommerce' ) . '

        '; + else + echo '

        ' . __( 'Sorry, it seems that there are no available payment methods for your state. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ) . '

        '; - endif; + } ?>
      @@ -253,4 +252,4 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
      -
      \ No newline at end of file +
      diff --git a/templates/checkout/thankyou.php b/templates/checkout/thankyou.php index cd46036ec3a..48b5fa1aa24 100644 --- a/templates/checkout/thankyou.php +++ b/templates/checkout/thankyou.php @@ -4,32 +4,30 @@ * * @author WooThemes * @package WooCommerce/Templates - * @version 1.6.4 + * @version 2.0.0 */ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly global $woocommerce; -?> - +if ( $order ) : ?> - status, array('failed'))) : ?> + status, array( 'failed' ) ) ) : ?>

      - - + +

      @@ -44,18 +42,16 @@ global $woocommerce;
    • - order_date)); ?> + order_date ) ); ?>
    • get_formatted_order_total(); ?>
    • - payment_method_title) : ?> + payment_method_title ) : ?>
    • - payment_method_title; - ?> + payment_method_title; ?>
    diff --git a/templates/content-product.php b/templates/content-product.php index 6927215a64c..7ed85859c71 100644 --- a/templates/content-product.php +++ b/templates/content-product.php @@ -21,19 +21,21 @@ if ( empty( $woocommerce_loop['loop'] ) ) if ( empty( $woocommerce_loop['columns'] ) ) $woocommerce_loop['columns'] = apply_filters( 'loop_shop_columns', 4 ); -// Ensure visibilty +// Ensure visibility if ( ! $product->is_visible() ) return; // Increase loop count $woocommerce_loop['loop']++; + +// Extra post classes +$classes = array(); +if ( 0 == ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 == $woocommerce_loop['columns'] ) + $classes[] = 'first'; +if ( 0 == $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) + $classes[] = 'last'; ?> -
  • +
  • > diff --git a/templates/content-single-product.php b/templates/content-single-product.php index 34f96990c1e..e930d06e9ff 100644 --- a/templates/content-single-product.php +++ b/templates/content-single-product.php @@ -10,7 +10,6 @@ */ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly - ?>

    -
    - \ No newline at end of file diff --git a/templates/emails/customer-reset-password.php b/templates/emails/customer-reset-password.php index f78351657f2..129d87f6638 100644 --- a/templates/emails/customer-reset-password.php +++ b/templates/emails/customer-reset-password.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>

    - +

    diff --git a/templates/emails/email-order-items.php b/templates/emails/email-order-items.php index 0acc4222ac4..214b951cc78 100644 --- a/templates/emails/email-order-items.php +++ b/templates/emails/email-order-items.php @@ -4,7 +4,7 @@ * * @author WooThemes * @package WooCommerce/Templates/Emails - * @version 1.6.4 + * @version 2.0.3 */ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly @@ -32,17 +32,25 @@ foreach ($items as $item) : echo ($show_sku && $_product->get_sku()) ? ' (#' . $_product->get_sku() . ')' : ''; // File URLs - if ( $show_download_links && $_product->exists() && $_product->is_downloadable() ) : + if ( $show_download_links && $_product->exists() && $_product->is_downloadable() ) { + $download_file_urls = $order->get_downloadable_file_urls( $item['product_id'], $item['variation_id'], $item ); - foreach ( $download_file_urls as $i => $download_file_url ) : + + $i = 0; + + foreach ( $download_file_urls as $file_url => $download_file_url ) { echo '
    '; + if ( count( $download_file_urls ) > 1 ) { echo sprintf( __('Download %d:', 'woocommerce' ), $i + 1 ); } elseif ( $i == 0 ) echo __( 'Download:', 'woocommerce' ); - echo ' ' . $download_file_url . ''; - endforeach; - endif; + + echo ' ' . basename( $file_url ) . '
    '; + + $i++; + } + } // Variation echo ($item_meta->meta) ? '
    ' . nl2br( $item_meta->display( true, true ) ) . '' : ''; diff --git a/templates/loop-shop.php b/templates/loop-shop.php index ecfa8b71f40..ab644e8aa0b 100644 --- a/templates/loop-shop.php +++ b/templates/loop-shop.php @@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly -_deprecated_file( basename(__FILE__), '1.6' ); +_deprecated_file( basename(__FILE__), '1.6', '', 'Use your own loop code, as well as the content-product.php template. loop-shop.php will be removed in WC 2.1.' ); ?> diff --git a/templates/loop/add-to-cart.php b/templates/loop/add-to-cart.php index aed058d1849..a01cb9ab9b9 100644 --- a/templates/loop/add-to-cart.php +++ b/templates/loop/add-to-cart.php @@ -10,8 +10,6 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly global $product; - -if ( ! $product->is_purchasable() ) return; ?> is_in_stock() ) : ?> @@ -21,28 +19,41 @@ if ( ! $product->is_purchasable() ) return; '', + 'label' => '', + 'class' => '' + ); - switch ( $product->product_type ) { + $handler = apply_filters( 'woocommerce_add_to_cart_handler', $product->product_type, $product ); + + switch ( $handler ) { case "variable" : - $link = apply_filters( 'variable_add_to_cart_url', get_permalink( $product->id ) ); - $label = apply_filters( 'variable_add_to_cart_text', __( 'Select options', 'woocommerce' ) ); + $link['url'] = apply_filters( 'variable_add_to_cart_url', get_permalink( $product->id ) ); + $link['label'] = apply_filters( 'variable_add_to_cart_text', __( 'Select options', 'woocommerce' ) ); break; case "grouped" : - $link = apply_filters( 'grouped_add_to_cart_url', get_permalink( $product->id ) ); - $label = apply_filters( 'grouped_add_to_cart_text', __( 'View options', 'woocommerce' ) ); + $link['url'] = apply_filters( 'grouped_add_to_cart_url', get_permalink( $product->id ) ); + $link['label'] = apply_filters( 'grouped_add_to_cart_text', __( 'View options', 'woocommerce' ) ); break; case "external" : - $link = apply_filters( 'external_add_to_cart_url', get_permalink( $product->id ) ); - $label = apply_filters( 'external_add_to_cart_text', __( 'Read More', 'woocommerce' ) ); + $link['url'] = apply_filters( 'external_add_to_cart_url', get_permalink( $product->id ) ); + $link['label'] = apply_filters( 'external_add_to_cart_text', __( 'Read More', 'woocommerce' ) ); break; default : - $link = apply_filters( 'add_to_cart_url', esc_url( $product->add_to_cart_url() ) ); - $label = apply_filters( 'add_to_cart_text', __( 'Add to cart', 'woocommerce' ) ); + if ( $product->is_purchasable() ) { + $link['url'] = apply_filters( 'add_to_cart_url', esc_url( $product->add_to_cart_url() ) ); + $link['label'] = apply_filters( 'add_to_cart_text', __( 'Add to cart', 'woocommerce' ) ); + $link['class'] = apply_filters( 'add_to_cart_class', 'add_to_cart_button' ); + } else { + $link['url'] = apply_filters( 'not_purchasable_url', get_permalink( $product->id ) ); + $link['label'] = apply_filters( 'not_purchasable_text', __( 'Read More', 'woocommerce' ) ); + } break; } - printf('%s', $link, $product->id, $product->product_type, $label); + echo apply_filters( 'woocommerce_loop_add_to_cart_link', sprintf('%s', esc_url( $link['url'] ), esc_attr( $product->id ), esc_attr( $product->get_sku() ), esc_attr( $link['class'] ), esc_attr( $product->product_type ), esc_html( $link['label'] ) ), $product, $link ); ?> - \ No newline at end of file + diff --git a/templates/loop/no-products-found.php b/templates/loop/no-products-found.php new file mode 100644 index 00000000000..dbbe1be4b4c --- /dev/null +++ b/templates/loop/no-products-found.php @@ -0,0 +1,14 @@ + +

    \ No newline at end of file diff --git a/templates/loop/orderby.php b/templates/loop/orderby.php new file mode 100644 index 00000000000..4cb9448ad78 --- /dev/null +++ b/templates/loop/orderby.php @@ -0,0 +1,52 @@ +found_posts || ! woocommerce_products_will_display() ) + return; +?> + + + $val ) { + if ( 'orderby' == $key ) + continue; + + if (is_array($val)) { + foreach($val as $innerVal) { + echo ''; + } + + } else { + echo ''; + } + } + ?> + diff --git a/templates/loop/pagination.php b/templates/loop/pagination.php index c2ead7bcbe6..7e1b324f165 100644 --- a/templates/loop/pagination.php +++ b/templates/loop/pagination.php @@ -14,7 +14,7 @@ global $wp_query; if ( $wp_query->max_num_pages <= 1 ) return; ?> -