[Product CRUD] Grouped Handling (#12151)

* Handle grouped product saving

* Update routine
This commit is contained in:
Mike Jolley 2016-10-24 09:19:29 +01:00 committed by GitHub
parent 880dc53ac9
commit b1dbfd9c5b
5 changed files with 50 additions and 135 deletions

View File

@ -506,7 +506,6 @@ class WC_Meta_Box_Product_Data {
<div id="linked_product_data" class="panel woocommerce_options_panel hidden">
<div class="options_group">
<p class="form-field">
<label for="upsell_ids"><?php _e( 'Up-sells', 'woocommerce' ); ?></label>
<input type="hidden" class="wc-product-search" style="width: 50%;" id="upsell_ids" name="upsell_ids" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
@ -540,31 +539,23 @@ class WC_Meta_Box_Product_Data {
echo esc_attr( json_encode( $json_ids ) );
?>" value="<?php echo implode( ',', array_keys( $json_ids ) ); ?>" /> <?php echo wc_help_tip( __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' ) ); ?>
</p>
</div>
<div class="options_group grouping show_if_simple show_if_external">
<p class="form-field show_if_grouped">
<label for="grouped_products"><?php _e( 'Grouped products', 'woocommerce' ); ?></label>
<input type="hidden" class="wc-product-search" style="width: 50%;" id="grouped_products" name="grouped_products" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
$product_ids = array_filter( array_map( 'absint', (array) get_post_meta( $post->ID, '_children', true ) ) );
$json_ids = array();
<p class="form-field">
<label for="parent_id"><?php _e( 'Grouping', 'woocommerce' ); ?></label>
<input type="hidden" class="wc-product-search" style="width: 50%;" id="parent_id" name="parent_id" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_grouped_products" data-allow_clear="true" data-multiple="false" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
$parent_id = absint( $post->post_parent );
if ( $parent_id ) {
$parent = wc_get_product( $parent_id );
if ( is_object( $parent ) ) {
$parent_title = wp_kses_post( html_entity_decode( $parent->get_formatted_name(), ENT_QUOTES, get_bloginfo( 'charset' ) ) );
}
echo esc_attr( $parent_title );
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
$json_ids[ $product_id ] = wp_kses_post( html_entity_decode( $product->get_formatted_name(), ENT_QUOTES, get_bloginfo( 'charset' ) ) );
}
?>" value="<?php echo $parent_id ? $parent_id : ''; ?>" /> <?php echo wc_help_tip( __( 'Set this option to make this product part of a grouped product.', 'woocommerce' ) ); ?>
}
echo esc_attr( json_encode( $json_ids ) );
?>" value="<?php echo implode( ',', array_keys( $json_ids ) ); ?>" /> <?php echo wc_help_tip( __( 'This lets you choose which products are part of this group.', 'woocommerce' ) ); ?>
</p>
<?php
woocommerce_wp_hidden_input( array( 'id' => 'previous_parent_id', 'value' => absint( $post->post_parent ) ) );
do_action( 'woocommerce_product_options_grouping' );
?>
</div>
<?php do_action( 'woocommerce_product_options_related' ); ?>
@ -1054,47 +1045,6 @@ class WC_Meta_Box_Product_Data {
}
}
// Update parent if grouped so price sorting works and stays in sync with the cheapest child
if ( $post->post_parent > 0 || 'grouped' === $product_type || $_POST['previous_parent_id'] > 0 ) {
$clear_parent_ids = array();
if ( $post->post_parent > 0 ) {
$clear_parent_ids[] = $post->post_parent;
}
if ( 'grouped' === $product_type ) {
$clear_parent_ids[] = $post_id;
}
if ( $_POST['previous_parent_id'] > 0 ) {
$clear_parent_ids[] = absint( $_POST['previous_parent_id'] );
}
if ( ! empty( $clear_parent_ids ) ) {
foreach ( $clear_parent_ids as $clear_id ) {
$children_by_price = get_posts( array(
'post_parent' => $clear_id,
'orderby' => 'meta_value_num',
'order' => 'asc',
'meta_key' => '_price',
'posts_per_page' => 1,
'post_type' => 'product',
'fields' => 'ids',
) );
if ( $children_by_price ) {
foreach ( $children_by_price as $child ) {
$child_price = get_post_meta( $child, '_price', true );
update_post_meta( $clear_id, '_price', $child_price );
}
}
wc_delete_product_transients( $clear_id );
}
}
}
// Sold Individually
if ( ! empty( $_POST['_sold_individually'] ) ) {
update_post_meta( $post_id, '_sold_individually', 'yes' );
@ -1143,15 +1093,17 @@ class WC_Meta_Box_Product_Data {
wc_update_product_stock_status( $post_id, wc_clean( $_POST['_stock_status'] ) );
}
// Cross sells and upsells
$upsells = isset( $_POST['upsell_ids'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['upsell_ids'] ) ) ) : array();
$crosssells = isset( $_POST['crosssell_ids'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['crosssell_ids'] ) ) ) : array();
// Cross sells, upsells, and grouped products.
$upsells = isset( $_POST['upsell_ids'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['upsell_ids'] ) ) ) : array();
$crosssells = isset( $_POST['crosssell_ids'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['crosssell_ids'] ) ) ) : array();
$grouped_products = isset( $_POST['grouped_products'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['grouped_products'] ) ) ) : array();
update_post_meta( $post_id, '_upsell_ids', $upsells );
update_post_meta( $post_id, '_crosssell_ids', $crosssells );
update_post_meta( $post_id, '_children', $grouped_products );
// Downloadable options
if ( 'yes' == $is_downloadable ) {
if ( 'yes' === $is_downloadable ) {
$_download_limit = absint( $_POST['_download_limit'] );
if ( ! $_download_limit ) {
@ -1235,7 +1187,7 @@ class WC_Meta_Box_Product_Data {
}
// Product url
if ( 'external' == $product_type ) {
if ( 'external' === $product_type ) {
if ( isset( $_POST['_product_url'] ) ) {
update_post_meta( $post_id, '_product_url', esc_url_raw( $_POST['_product_url'] ) );
@ -1246,9 +1198,8 @@ class WC_Meta_Box_Product_Data {
}
}
// Save variations
if ( 'variable' == $product_type ) {
// Update parent if variable so price sorting works and stays in sync with the cheapest child
// Sync related products.
if ( 'variable' === $product_type ) {
WC_Product_Variable::sync( $post_id );
WC_Product_Variable::sync_stock_status( $post_id );
}

View File

@ -128,7 +128,6 @@ class WC_AJAX {
'delete_order_note' => false,
'json_search_products' => false,
'json_search_products_and_variations' => false,
'json_search_grouped_products' => false,
'json_search_downloadable_products_and_variations' => false,
'json_search_customers' => false,
'term_ordering' => false,
@ -1599,68 +1598,6 @@ class WC_AJAX {
self::json_search_products( '', array( 'product', 'product_variation' ) );
}
/**
* Search for grouped products and return json.
*/
public static function json_search_grouped_products() {
ob_start();
check_ajax_referer( 'search-products', 'security' );
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
$exclude = array();
if ( empty( $term ) ) {
die();
}
if ( ! empty( $_GET['exclude'] ) ) {
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
}
$found_products = array();
if ( $grouped_term = get_term_by( 'slug', 'grouped', 'product_type' ) ) {
$posts_in = array_unique( (array) get_objects_in_term( $grouped_term->term_id, 'product_type' ) );
if ( sizeof( $posts_in ) > 0 ) {
$args = array(
'post_type' => 'product',
'post_status' => 'any',
'numberposts' => -1,
'orderby' => 'title',
'order' => 'asc',
'post_parent' => 0,
'suppress_filters' => 0,
'include' => $posts_in,
's' => $term,
'fields' => 'ids',
'exclude' => $exclude,
);
$posts = get_posts( $args );
if ( ! empty( $posts ) ) {
foreach ( $posts as $post ) {
$product = wc_get_product( $post );
if ( ! current_user_can( 'read_product', $post ) ) {
continue;
}
$found_products[ $post ] = rawurldecode( $product->get_formatted_name() );
}
}
}
}
$found_products = apply_filters( 'woocommerce_json_search_found_grouped_products', $found_products );
wp_send_json( $found_products );
}
/**
* Search for downloadable product variations and return json.
*

View File

@ -74,6 +74,7 @@ class WC_Install {
),
'2.7.0' => array(
'wc_update_270_webhooks',
'wc_update_270_grouped_products',
),
);

View File

@ -174,7 +174,16 @@ class WC_Product_Grouped extends WC_Product {
* Helper method that updates all the post meta for a grouped product.
*/
protected function update_post_meta() {
if ( update_post_meta( $this->get_id(), '_children', $this->get_children() ) ) {
$child_prices = array();
foreach ( $this->get_children() as $child_id ) {
$child = wc_get_product( $child_id );
$child_prices[] = $child->get_price();
}
delete_post_meta( $this->get_id(), '_price' );
add_post_meta( $this->get_id(), '_price', min( $child_prices ) );
add_post_meta( $this->get_id(), '_price', max( $child_prices ) );
}
parent::update_post_meta();
update_post_meta( $this->get_id(), '_children', $this->get_children() );
}
}

View File

@ -1001,3 +1001,20 @@ function wc_update_270_comment_type_index() {
$wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_type (comment_type)" );
}
function wc_update_270_grouped_products() {
global $wpdb;
$parents = $wpdb->get_col( "SELECT DISTINCT( post_parent ) FROM {$wpdb->posts} WHERE post_parent > 0 AND post_type = 'product';" );
foreach ( $parents as $parent_id ) {
$parent = wc_get_product( $parent_id );
if ( $parent && $parent->is_type( 'grouped' ) ) {
$children_ids = get_posts( array(
'post_parent' => $parent_id,
'posts_per_page' => -1,
'post_type' => 'product',
'fields' => 'ids',
) );
add_post_meta( $parent_id, '_children', $children_ids, true );
}
}
}