From f8447c7a465c6258e860fa252d1ee028810677aa Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Oct 2011 18:32:30 +0100 Subject: [PATCH] Drag and drop term ordering (so variation options can be sorted) Closes #57. --- admin/admin-init.php | 52 +++++++++--------- admin/admin-taxonomies.php | 53 ++++++++----------- ...ategories-ordering.js => term-ordering.js} | 4 +- classes/order.class.php | 17 ++++++ classes/product.class.php | 2 +- readme.txt | 9 ++-- woocommerce.php | 6 +-- woocommerce_emails.php | 10 +++- woocommerce_taxonomy.php | 17 ++++-- woocommerce_template_functions.php | 24 +++++---- 10 files changed, 115 insertions(+), 79 deletions(-) rename assets/js/admin/{categories-ordering.js => term-ordering.js} (92%) diff --git a/admin/admin-init.php b/admin/admin-init.php index 033fd0d18d5..e5ce514a9b7 100644 --- a/admin/admin-init.php +++ b/admin/admin-init.php @@ -54,7 +54,7 @@ function woocommerce_admin_scripts() { $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; // Register scripts - wp_register_script( 'woocommerce_admin', $woocommerce->plugin_url() . '/assets/js/admin/woocommerce_admin'.$suffix.'.js', array('jquery', 'jquery-ui-widget'), '1.0' ); + wp_register_script( 'woocommerce_admin', $woocommerce->plugin_url() . '/assets/js/admin/woocommerce_admin'.$suffix.'.js', array('jquery', 'jquery-ui-widget', 'jquery-ui-core'), '1.0' ); wp_register_script( 'jquery-ui-datepicker', $woocommerce->plugin_url() . '/assets/js/admin/ui-datepicker.js', array('jquery','jquery-ui-core'), '1.0' ); wp_register_script( 'woocommerce_writepanel', $woocommerce->plugin_url() . '/assets/js/admin/write-panels'.$suffix.'.js', array('jquery', 'jquery-ui-datepicker') ); @@ -107,6 +107,22 @@ function woocommerce_admin_scripts() { wp_localize_script( 'woocommerce_writepanel', 'woocommerce_writepanel_params', $woocommerce_witepanel_params ); endif; + + // Term ordering + if ($screen->id=='edit-product_cat' || strstr($screen->id, 'edit-pa_')) : + + wp_register_script( 'woocommerce_term_ordering', $woocommerce->plugin_url() . '/assets/js/admin/term-ordering.js', array('jquery-ui-sortable') ); + wp_enqueue_script( 'woocommerce_term_ordering' ); + + $taxonomy = (isset($_GET['taxonomy'])) ? $_GET['taxonomy'] : ''; + + $woocommerce_term_order_params = array( + 'taxonomy' => $taxonomy + ); + + wp_localize_script( 'woocommerce_term_ordering', 'woocommerce_term_ordering_params', $woocommerce_term_order_params ); + + endif; // Reports pages if ($screen->id=='woocommerce_page_woocommerce_reports') : @@ -119,6 +135,7 @@ function woocommerce_admin_scripts() { } add_action('admin_enqueue_scripts', 'woocommerce_admin_scripts'); + /** * Queue admin CSS */ @@ -201,45 +218,32 @@ function woocommerce_admin_head() { } add_action('admin_head', 'woocommerce_admin_head'); -/** - * Categories ordering scripts - */ -function woocommerce_categories_scripts() { - global $woocommerce; - - if( !isset($_GET['taxonomy']) || $_GET['taxonomy'] !== 'product_cat') return; - - wp_register_script('woocommerce-categories-ordering', $woocommerce->plugin_url() . '/assets/js/admin/categories-ordering.js', array('jquery-ui-sortable')); - wp_print_scripts('woocommerce-categories-ordering'); - -} -add_action('admin_footer-edit-tags.php', 'woocommerce_categories_scripts'); - /** * Ajax request handling for categories ordering */ -function woocommerce_categories_ordering() { - +function woocommerce_term_ordering() { global $wpdb; - $id = (int)$_POST['id']; + $id = (int) $_POST['id']; $next_id = isset($_POST['nextid']) && (int) $_POST['nextid'] ? (int) $_POST['nextid'] : null; + $taxonomy = isset($_POST['thetaxonomy']) ? esc_attr( $_POST['thetaxonomy'] ) : null; + $term = get_term_by('id', $id, $taxonomy); - if( ! $id || ! $term = get_term_by('id', $id, 'product_cat') ) die(0); + if( !$id || !$term || !$taxonomy ) die(0); - woocommerce_order_categories( $term, $next_id ); + woocommerce_order_terms( $term, $next_id, $taxonomy ); + + $children = get_terms($taxonomy, "child_of=$id&menu_order=ASC&hide_empty=0"); - $children = get_terms('product_cat', "child_of=$id&menu_order=ASC&hide_empty=0"); if( $term && sizeof($children) ) { echo 'children'; die; } - } -add_action('wp_ajax_woocommerce-categories-ordering', 'woocommerce_categories_ordering'); +add_action('wp_ajax_woocommerce-term-ordering', 'woocommerce_term_ordering'); /** - * Search by SKU ro ID for products. Adapted from code by BenIrvin (Admin Search by ID) + * Search by SKU or ID for products. Adapted from code by BenIrvin (Admin Search by ID) */ if (is_admin()) : add_action('parse_request', 'woocommerce_admin_product_search'); diff --git a/admin/admin-taxonomies.php b/admin/admin-taxonomies.php index 8e738b76f35..7eb1e1a06c1 100644 --- a/admin/admin-taxonomies.php +++ b/admin/admin-taxonomies.php @@ -134,45 +134,39 @@ function woocommerce_category_thumbnail_field_save( $term_id, $tt_id, $taxonomy /** - * Categories ordering + * Category/Term ordering */ /** - * Reorder on category insertion - * - * @param int $term_id + * Reorder on term insertion */ -add_action("create_product_cat", 'woocommerce_create_product_cat'); +add_action("create_term", 'woocommerce_create_term'); -function woocommerce_create_product_cat ($term_id) { +function woocommerce_create_term( $term_id, $tt_id, $taxonomy ) { $next_id = null; - $term = get_term($term_id, 'product_cat'); + $term = get_term($term_id, $taxonomy); // gets the sibling terms - $siblings = get_terms('product_cat', "parent={$term->parent}&menu_order=ASC&hide_empty=0"); + $siblings = get_terms($taxonomy, "parent={$term->parent}&menu_order=ASC&hide_empty=0"); foreach ($siblings as $sibling) { if( $sibling->term_id == $term_id ) continue; - $next_id = $sibling->term_id; // first sibling term of the hierachy level + $next_id = $sibling->term_id; // first sibling term of the hierarchy level break; } // reorder - woocommerce_order_categories ( $term, $next_id ); - + woocommerce_order_terms( $term, $next_id, $taxonomy ); } - /** * Delete terms metas on deletion - * - * @param int $term_id */ -add_action("delete_product_cat", 'woocommerce_delete_product_cat'); +add_action("delete_product_term", 'woocommerce_delete_term'); -function woocommerce_delete_product_cat($term_id) { +function woocommerce_delete_term( $term_id, $tt_id, $taxonomy ) { $term_id = (int) $term_id; @@ -183,18 +177,17 @@ function woocommerce_delete_product_cat($term_id) { } - /** - * Move a category before the a given element of its hierarchy level + * Move a term before the a given element of its hierarchy level * * @param object $the_term * @param int $next_id the id of the next slibling element in save hierachy level * @param int $index * @param int $terms */ -function woocommerce_order_categories ( $the_term, $next_id, $index=0, $terms=null ) { +function woocommerce_order_terms( $the_term, $next_id, $taxonomy, $index=0, $terms=null ) { - if( ! $terms ) $terms = get_terms('product_cat', 'menu_order=ASC&hide_empty=0&parent=0'); + if( ! $terms ) $terms = get_terms($taxonomy, 'menu_order=ASC&hide_empty=0&parent=0'); if( empty( $terms ) ) return $index; $id = $the_term->term_id; @@ -210,50 +203,50 @@ function woocommerce_order_categories ( $the_term, $next_id, $index=0, $terms=nu // the nextid of our term to order, lets move our term here if(null !== $next_id && $term->term_id == $next_id) { $index++; - $index = woocommerce_set_category_order($id, $index, true); + $index = woocommerce_set_term_order($id, $index, $taxonomy, true); } // set order $index++; - $index = woocommerce_set_category_order($term->term_id, $index); + $index = woocommerce_set_term_order($term->term_id, $index, $taxonomy); // if that term has children we walk through them - $children = get_terms('product_cat', "parent={$term->term_id}&menu_order=ASC&hide_empty=0"); + $children = get_terms($taxonomy, "parent={$term->term_id}&menu_order=ASC&hide_empty=0"); if( !empty($children) ) { - $index = woocommerce_order_categories ( $the_term, $next_id, $index, $children ); + $index = woocommerce_order_terms( $the_term, $next_id, $taxonomy, $index, $children ); } } // no nextid meaning our term is in last position if( $term_in_level && null === $next_id ) - $index = woocommerce_set_category_order($id, $index+1, true); + $index = woocommerce_set_term_order($id, $index+1, $taxonomy, true); return $index; } /** - * Set the sort order of a category + * Set the sort order of a term * * @param int $term_id * @param int $index * @param bool $recursive */ -function woocommerce_set_category_order ($term_id, $index, $recursive=false) { +function woocommerce_set_term_order($term_id, $index, $taxonomy, $recursive=false) { global $wpdb; $term_id = (int) $term_id; $index = (int) $index; - update_metadata('woocommerce_term', $term_id, 'order', $index); + update_woocommerce_term_meta( $term_id, 'order', $index ); if( ! $recursive ) return $index; - $children = get_terms('product_cat', "parent=$term_id&menu_order=ASC&hide_empty=0"); + $children = get_terms($taxonomy, "parent=$term_id&menu_order=ASC&hide_empty=0"); foreach ( $children as $term ) { $index ++; - $index = woocommerce_set_category_order ($term->term_id, $index, true); + $index = woocommerce_set_term_order($term->term_id, $index, $taxonomy, true); } return $index; diff --git a/assets/js/admin/categories-ordering.js b/assets/js/admin/term-ordering.js similarity index 92% rename from assets/js/admin/categories-ordering.js rename to assets/js/admin/term-ordering.js index ab60f688f7b..f36c60cce4e 100644 --- a/assets/js/admin/categories-ordering.js +++ b/assets/js/admin/term-ordering.js @@ -7,7 +7,7 @@ jQuery(document).ready(function($) { items: 'tr:not(.inline-edit-row)', cursor: 'move', axis: 'y', - containment: 'table.widefat', + //containment: 'table.widefat', placeholder: 'product-cat-placeholder', scrollSensitivity: 40, helper: function(e, ui) { @@ -53,7 +53,7 @@ jQuery(document).ready(function($) { ui.item.find('.check-column input').hide().after('processing'); // go do the sorting stuff via ajax - $.post( ajaxurl, { action: 'woocommerce-categories-ordering', id: termid, nextid: nexttermid }, function(response){ + $.post( ajaxurl, { action: 'woocommerce-term-ordering', id: termid, nextid: nexttermid, thetaxonomy: woocommerce_term_ordering_params.taxonomy }, function(response){ if ( response == 'children' ) window.location.reload(); else { ui.item.find('.check-column input').show().siblings('img').remove(); diff --git a/classes/order.class.php b/classes/order.class.php index 39dcada71ed..a5d1ac0d0fd 100644 --- a/classes/order.class.php +++ b/classes/order.class.php @@ -272,6 +272,23 @@ class woocommerce_order { } + /** Returns true if the order contains a downloadable product */ + function has_downloadable_item() { + $has_downloadable_item = false; + + foreach($this->items as $item) : + + $_product = $this->get_product_from_item( $item ); + + if ($_product->exists && $_product->is_type('downloadable')) : + $has_downloadable_item = true; + endif; + + endforeach; + + return $has_downloadable_item; + } + /** Generates a URL so that a customer can checkout/pay for their (unpaid - pending) order via a link */ function get_checkout_payment_url() { diff --git a/classes/product.class.php b/classes/product.class.php index c60639c9eb4..0803c208908 100644 --- a/classes/product.class.php +++ b/classes/product.class.php @@ -762,7 +762,7 @@ class woocommerce_product { $values = $options; } - + $available_attributes[$attribute['name']] = array_unique($values); } diff --git a/readme.txt b/readme.txt index a51d42157ef..714cbcf4d9e 100644 --- a/readme.txt +++ b/readme.txt @@ -2,8 +2,8 @@ Contributors: woothemes Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, store, shop, shopping, cart, checkout, widgets, reports, shipping, tax, paypal, inventory Requires at least: 3.1 -Tested up to: 3.2 -Stable tag: 1.0.3 +Tested up to: 3.3 +Stable tag: 1.1 An e-commerce toolkit that helps you sell anything. Beautifully. @@ -57,7 +57,8 @@ For further documentation on using WooCommerce, please sign up for free at http: == Changelog == -= 1.1 - xx/10/2011 = += 1.1 - 12/10/2011 = +* Tested and working with WordPress 3.3 beta-1 * Added a hook for payment complete order status * Added woocommerce term meta api * Added ability to upload category thumbnails @@ -74,9 +75,11 @@ For further documentation on using WooCommerce, please sign up for free at http: * Password field type for gateways API * Front page shop improvements/correct title tags * Added option for controlling product permalinks +* Shop page title option * Load admin css only where needed * Admin JS cleanup * Removed error message when clicking buttons to view variations/grouped +* Drag and drop term ordering (so variation options can be sorted) = 1.0.3 - 06/10/2011 = * Several minor fixes/tweaks diff --git a/woocommerce.php b/woocommerce.php index 54dcb3bdb2d..84383438d21 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -3,11 +3,11 @@ Plugin Name: WooCommerce Plugin URI: http://www.woothemes.com/woocommerce/ Description: An eCommerce plugin for wordpress. -Version: 1.0.3 +Version: 1.1 Author: WooThemes Author URI: http://woothemes.com Requires at least: 3.1 -Tested up to: 3.2 +Tested up to: 3.3 */ if (!session_id()) session_start(); @@ -21,7 +21,7 @@ load_plugin_textdomain('woothemes', false, dirname( plugin_basename( __FILE__ ) * Constants **/ if (!defined('WOOCOMMERCE_TEMPLATE_URL')) define('WOOCOMMERCE_TEMPLATE_URL', 'woocommerce/'); -if (!defined("WOOCOMMERCE_VERSION")) define("WOOCOMMERCE_VERSION", "1.0.3"); +if (!defined("WOOCOMMERCE_VERSION")) define("WOOCOMMERCE_VERSION", "1.1"); if (!defined("PHP_EOL")) define("PHP_EOL", "\r\n"); /** diff --git a/woocommerce_emails.php b/woocommerce_emails.php index 68cad005850..38b813f22ad 100644 --- a/woocommerce_emails.php +++ b/woocommerce_emails.php @@ -159,9 +159,15 @@ function woocommerce_completed_order_customer_notification( $id ) { $order = &new woocommerce_order( $order_id ); - $email_heading = __('Order Complete', 'woothemes'); + if ($order->has_downloadable_item()) : + $email_heading = __('Order Complete/Download Links', 'woothemes'); + else : + $email_heading = __('Order Complete', 'woothemes'); + endif; + + $email_heading = apply_filters('woocommerce_completed_order_customer_notification_subject', $email_heading); - $subject = '[' . get_bloginfo('name') . '] ' . __('Order Complete', 'woothemes'); + $subject = '[' . get_bloginfo('name') . '] ' . $email_heading; // Buffer ob_start(); diff --git a/woocommerce_taxonomy.php b/woocommerce_taxonomy.php index d32feaea9ef..cddd3c85622 100644 --- a/woocommerce_taxonomy.php +++ b/woocommerce_taxonomy.php @@ -320,7 +320,7 @@ add_filter( 'post_type_link', 'woocommerce_product_cat_filter_post_link', 10, 4 /** - * Add product_cat ordering to get_terms + * Add term ordering to get_terms * * It enables the support a 'menu_order' parameter to get_terms for the product_cat taxonomy. * By default it is 'ASC'. It accepts 'DESC' too @@ -331,11 +331,18 @@ add_filter( 'post_type_link', 'woocommerce_product_cat_filter_post_link', 10, 4 add_filter( 'terms_clauses', 'woocommerce_terms_clauses', 10, 3); function woocommerce_terms_clauses($clauses, $taxonomies, $args ) { - global $wpdb; - - // wordpress should give us the taxonomies asked when calling the get_terms function - if( !in_array('product_cat', (array)$taxonomies) ) return $clauses; + global $wpdb, $woocommerce; + // wordpress should give us the taxonomies asked when calling the get_terms function. Only apply to categories and pa_ attributes + $found = false; + foreach ((array) $taxonomies as $taxonomy) : + if ($taxonomy=='product_cat' || strstr($taxonomy, 'pa_')) : + $found = true; + break; + endif; + endforeach; + if (!$found) return $clauses; + // query order if( isset($args['menu_order']) && !$args['menu_order']) return $clauses; // menu_order is false so we do not add order clause diff --git a/woocommerce_template_functions.php b/woocommerce_template_functions.php index d9f7f5b2da5..def23ff69aa 100644 --- a/woocommerce_template_functions.php +++ b/woocommerce_template_functions.php @@ -395,22 +395,28 @@ if (!function_exists('woocommerce_variable_add_to_cart')) {
- $options) :?> + $options) : ?>