diff --git a/admin/woocommerce-admin-attributes.php b/admin/woocommerce-admin-attributes.php
index 9c3d7f2751a..d8e6a475888 100644
--- a/admin/woocommerce-admin-attributes.php
+++ b/admin/woocommerce-admin-attributes.php
@@ -16,79 +16,156 @@
* The added attributes are stored in the database and can be used for layered navigation.
*/
function woocommerce_attributes() {
-
global $wpdb, $woocommerce;
- if (isset($_POST['add_new_attribute']) && $_POST['add_new_attribute']) :
+ if ( ! empty( $_POST['add_new_attribute'] ) ) {
+
check_admin_referer( 'woocommerce-add-new_attribute' );
- $attribute_name = (string) sanitize_title($_POST['attribute_name']);
- $attribute_type = (string) $_POST['attribute_type'];
- $attribute_label = (string) $_POST['attribute_label'];
- if (!$attribute_label) $attribute_label = ucwords($attribute_name);
+ $attribute_name = sanitize_title( esc_attr( $_POST['attribute_name'] ) );
+ $attribute_type = esc_attr( $_POST['attribute_type'] );
+ $attribute_label = esc_attr( $_POST['attribute_label'] );
- if (!$attribute_name) $attribute_name = sanitize_title($attribute_label);
+ if ( ! $attribute_label )
+ $attribute_label = ucwords( $attribute_name );
- if ($attribute_name && strlen($attribute_name)<30 && $attribute_type && !taxonomy_exists( $woocommerce->attribute_taxonomy_name($attribute_name) )) :
+ if ( ! $attribute_name )
+ $attribute_name = sanitize_title( $attribute_label );
- $wpdb->insert( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_name' => $attribute_name, 'attribute_label' => $attribute_label, 'attribute_type' => $attribute_type ), array( '%s', '%s' ) );
+ if ( $attribute_name && strlen( $attribute_name ) < 30 && $attribute_type && ! taxonomy_exists( $woocommerce->attribute_taxonomy_name( $attribute_name ) ) ) {
+
+ $wpdb->insert(
+ $wpdb->prefix . "woocommerce_attribute_taxonomies",
+ array(
+ 'attribute_name' => $attribute_name,
+ 'attribute_label' => $attribute_label,
+ 'attribute_type' => $attribute_type
+ )
+ );
wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
exit;
-
- endif;
+ }
- elseif (isset($_POST['save_attribute']) && $_POST['save_attribute'] && isset($_GET['edit'])) :
+ } elseif ( ! empty( $_POST['save_attribute'] ) && ! empty( $_GET['edit'] ) ) {
- $edit = absint($_GET['edit']);
+ $edit = absint( $_GET['edit'] );
check_admin_referer( 'woocommerce-save-attribute_' . $edit );
- if ($edit>0) :
- $attribute_type = $_POST['attribute_type'];
- $attribute_label = (string) $_POST['attribute_label'];
+ $attribute_name = sanitize_title( esc_attr( $_POST['attribute_name'] ) );
+ $attribute_type = esc_attr( $_POST['attribute_type'] );
+ $attribute_label = esc_attr( $_POST['attribute_label'] );
+
+ if ( ! $attribute_label )
+ $attribute_label = ucwords( $attribute_name );
- $wpdb->update( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_type' => $attribute_type, 'attribute_label' => $attribute_label ), array( 'attribute_id' => $_GET['edit'] ), array( '%s', '%s' ) );
-
- endif;
-
- wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
- exit;
+ if ( ! $attribute_name )
+ $attribute_name = sanitize_title( $attribute_label );
- elseif (isset($_GET['delete'])) :
- check_admin_referer( 'woocommerce-delete-attribute_' . absint( $_GET['delete'] ) );
- $delete = absint($_GET['delete']);
+ $old_attribute_name = sanitize_title( $wpdb->get_var( "SELECT attribute_name FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = $edit" ) );
- if ($delete>0) :
-
- $att_name = $wpdb->get_var("SELECT attribute_name FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$delete'");
+ if ( $old_attribute_name != $attribute_name && taxonomy_exists( $woocommerce->attribute_taxonomy_name( $attribute_name ) ) ) {
- if ($att_name && $wpdb->query("DELETE FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$delete'")) :
-
- $taxonomy = $woocommerce->attribute_taxonomy_name($att_name);
-
- if (taxonomy_exists($taxonomy)) :
-
- $terms = get_terms($taxonomy, 'orderby=name&hide_empty=0');
- foreach ($terms as $term) {
- wp_delete_term( $term->term_id, $taxonomy );
- }
-
- endif;
-
- wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
- exit;
-
- endif;
+ echo '
' . __( 'Taxonomy exists - please change the slug', 'woocommerce' ) . '
';
- endif;
-
- endif;
+ } elseif ( $attribute_name && strlen( $attribute_name ) < 30 && $attribute_type ) {
- if (isset($_GET['edit']) && $_GET['edit'] > 0) :
+ $wpdb->update(
+ $wpdb->prefix . "woocommerce_attribute_taxonomies",
+ array(
+ 'attribute_name' => $attribute_name,
+ 'attribute_label' => $attribute_label,
+ 'attribute_type' => $attribute_type
+ ),
+ array(
+ 'attribute_id' => $edit
+ )
+ );
+
+ if ( $old_attribute_name != $attribute_name && ! empty( $old_attribute_name ) ) {
+
+ // Update taxonomies in the wp term taxonomy table
+ $wpdb->update(
+ $wpdb->term_taxonomy,
+ array(
+ 'taxonomy' => $woocommerce->attribute_taxonomy_name( $attribute_name )
+ ),
+ array(
+ 'taxonomy' => $woocommerce->attribute_taxonomy_name( $old_attribute_name )
+ )
+ );
+
+ // Update taxonomy ordering term meta
+ $wpdb->update(
+ $wpdb->prefix . "woocommerce_termmeta",
+ array(
+ 'meta_key' => 'order_pa_' . sanitize_title( $attribute_name )
+ ),
+ array(
+ 'meta_key' => 'order_pa_' . sanitize_title( $old_attribute_name )
+ )
+ );
+
+ // Update product attributes which use this taxonomy
+ $old_attribute_name_length = strlen($old_attribute_name) + 3;
+ $attribute_name_length = strlen($attribute_name) + 3;
+
+ $wpdb->query( "
+ UPDATE {$wpdb->postmeta}
+ SET meta_value = replace( meta_value, 's:{$old_attribute_name_length}:\"pa_{$old_attribute_name}\"', 's:{$attribute_name_length}:\"pa_{$attribute_name}\"' )
+ WHERE meta_key = '_product_attributes'"
+ );
+
+ // Update variations which use this taxonomy
+ $wpdb->update(
+ $wpdb->postmeta,
+ array(
+ 'meta_key' => 'attribute_' . sanitize_title( $attribute_name )
+ ),
+ array(
+ 'meta_key' => 'attribute_' . sanitize_title( $old_attribute_name )
+ )
+ );
+
+ // Clear post cache
+ wp_cache_flush();
+ }
+
+ wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
+ exit;
+
+ }
+
+ } elseif ( ! empty( $_GET['delete'] ) ) {
+
+ $delete = absint( $_GET['delete'] );
+ check_admin_referer( 'woocommerce-delete-attribute_' . $delete );
+
+ $att_name = $wpdb->get_var( "SELECT attribute_name FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = $delete" );
+
+ if ( $att_name && $wpdb->query( "DELETE FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = $delete" ) ) {
+
+ $taxonomy = $woocommerce->attribute_taxonomy_name( $att_name );
+
+ if ( taxonomy_exists( $taxonomy ) ) {
+
+ $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0');
+ foreach ( $terms as $term )
+ wp_delete_term( $term->term_id, $taxonomy );
+
+ }
+
+ wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
+ exit;
+
+ }
+
+ }
+
+ if ( ! empty( $_GET['edit'] ) && $_GET['edit'] > 0 )
woocommerce_edit_attribute();
- else :
+ else
woocommerce_add_attribute();
- endif;
}
@@ -98,13 +175,15 @@ function woocommerce_attributes() {
* Shows the interface for changing an attributes type between select and text
*/
function woocommerce_edit_attribute() {
-
global $wpdb;
- $edit = absint($_GET['edit']);
+ $edit = absint( $_GET['edit'] );
- $att_type = $wpdb->get_var("SELECT attribute_type FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$edit'");
- $att_label = $wpdb->get_var("SELECT attribute_label FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$edit'");
+ $attribute_to_edit = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$edit'");
+
+ $att_type = $attribute_to_edit->attribute_type;
+ $att_label = $attribute_to_edit->attribute_label;
+ $att_name = $attribute_to_edit->attribute_name;
?>
@@ -121,14 +200,23 @@ function woocommerce_edit_attribute() {
+
+
+
+
+
+
+
+
+
- >
- >
+ >
+ >
Text allows manual entry via the product page, whereas select attribute terms can be defined from this section. If you plan on using an attribute for variations use select .', 'woocommerce'); ?>
@@ -221,7 +309,7 @@ function woocommerce_add_attribute() {
diff --git a/classes/class-wc-email.php b/classes/class-wc-email.php
index 2861ed23599..99df7485636 100644
--- a/classes/class-wc-email.php
+++ b/classes/class-wc-email.php
@@ -195,7 +195,7 @@ class WC_Email {
$email_heading = __('Order Complete', 'woocommerce');
endif;
- $email_heading = apply_filters( 'woocommerce_completed_order_customer_notification_subject', $email_heading );
+ $email_heading = apply_filters( 'woocommerce_email_heading_customer_completed_order', $email_heading );
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
diff --git a/readme.txt b/readme.txt
index 83034132d0e..48a33c95379 100644
--- a/readme.txt
+++ b/readme.txt
@@ -159,6 +159,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Templating - Introduced content-product.php and content-product_cat.php for use in loops. Loop-shop is gone.
* Templating - Dumped woocommerce_single_product_content(), woocommerce_archive_product_content(), woocommerce_product_taxonomy_content() in favour of the new content templates.
* Templating - Documented templates listing hooked in functions.
+* Tweak - Allowed the editing of attribute slugs after creation
* Tweak - get_order_item_totals() total_rows have fixed indexes for easier manipulation
* Tweak - order_note comment type for future order notes, allowing you to filter in the comments section.
* Tweak - Better WC_Product::get_image() function. Fixed instances where we were not echo'ing.
@@ -171,6 +172,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Tweak - woocommerce_attribute filter if needed
* Tweak - Orders page is now the first item in the WooCommerce menu
* Tweak - If all variations are the same price, don't show the variation price.
+* Tweak - woocommerce_completed_order_customer_notification_subject hook renamed to for more sense: woocommerce_email_heading_customer_completed_order
* Fix - Widget init function conflict with widget logic
* Fix - PLN currency code
* Fix - Variation get shipping class ID