Merge pull request #20870 from woocommerce/add/export-products-based-on-category
Add category filter to product export functionality.
This commit is contained in:
commit
11911aa2ea
|
@ -44,6 +44,7 @@
|
|||
selected_columns = $( '.woocommerce-exporter-columns' ).val(),
|
||||
export_meta = $( '#woocommerce-exporter-meta:checked' ).length ? 1: 0,
|
||||
export_types = $( '.woocommerce-exporter-types' ).val();
|
||||
export_category = $( '.woocommerce-exporter-category' ).val();
|
||||
|
||||
$.ajax( {
|
||||
type: 'POST',
|
||||
|
@ -56,6 +57,7 @@
|
|||
selected_columns : selected_columns,
|
||||
export_meta : export_meta,
|
||||
export_types : export_types,
|
||||
export_category : export_category,
|
||||
filename : filename,
|
||||
security : wc_product_export_params.export_nonce
|
||||
},
|
||||
|
|
|
@ -150,6 +150,10 @@ class WC_Admin_Exporters {
|
|||
$exporter->set_product_types_to_export( wp_unslash( $_POST['export_types'] ) ); // WPCS: input var ok, sanitization ok.
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['export_category'] ) && is_array( $_POST['export_category'] ) ) {// WPCS: input var ok.
|
||||
$exporter->set_product_category_to_export( wp_unslash( array_values( $_POST['export_category'] ) ) ); // WPCS: input var ok, sanitization ok.
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['filename'] ) ) { // WPCS: input var ok.
|
||||
$exporter->set_filename( wp_unslash( $_POST['filename'] ) ); // WPCS: input var ok, sanitization ok.
|
||||
}
|
||||
|
|
|
@ -57,6 +57,19 @@ $exporter = new WC_Product_CSV_Exporter();
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="woocommerce-exporter-category"><?php esc_html_e( 'Which product category should be exported?', 'woocommerce' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<select id="woocommerce-exporter-category" class="woocommerce-exporter-category wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all categories', 'woocommerce' ); ?>">
|
||||
<?php
|
||||
foreach ( get_categories( array( 'taxonomy' => 'product_cat' ) ) as $category ) {
|
||||
echo '<option value="' . esc_attr( $category->slug ) . '">' . esc_html( $category->name ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="woocommerce-exporter-meta"><?php esc_html_e( 'Export custom meta?', 'woocommerce' ); ?></label>
|
||||
|
|
|
@ -43,6 +43,13 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
|
|||
*/
|
||||
protected $product_types_to_export = array();
|
||||
|
||||
/**
|
||||
* Products belonging to what category should be exported.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $product_category_to_export = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
|
@ -71,6 +78,17 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
|
|||
$this->product_types_to_export = array_map( 'wc_clean', $product_types_to_export );
|
||||
}
|
||||
|
||||
/**
|
||||
* Product category to export
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @param string $product_category_to_export Product category slug to export, empty string exports all.
|
||||
* @return void
|
||||
*/
|
||||
public function set_product_category_to_export( $product_category_to_export ) {
|
||||
$this->product_category_to_export = array_map( 'wc_clean', $product_category_to_export );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of columns to export.
|
||||
*
|
||||
|
@ -131,8 +149,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
|
|||
* @since 3.1.0
|
||||
*/
|
||||
public function prepare_data_to_export() {
|
||||
$columns = $this->get_column_names();
|
||||
$args = apply_filters( "woocommerce_product_export_{$this->export_type}_query_args", array(
|
||||
$args = array(
|
||||
'status' => array( 'private', 'publish', 'draft', 'future', 'pending' ),
|
||||
'type' => $this->product_types_to_export,
|
||||
'limit' => $this->get_limit(),
|
||||
|
@ -142,45 +159,85 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
|
|||
),
|
||||
'return' => 'objects',
|
||||
'paginate' => true,
|
||||
) );
|
||||
$products = wc_get_products( $args );
|
||||
);
|
||||
|
||||
$this->total_rows = $products->total;
|
||||
$this->row_data = array();
|
||||
if ( ! empty( $this->product_category_to_export ) ) {
|
||||
$args['category'] = $this->product_category_to_export;
|
||||
}
|
||||
$products = wc_get_products( apply_filters( "woocommerce_product_export_{$this->export_type}_query_args", $args ) );
|
||||
|
||||
$this->total_rows = $products->total;
|
||||
$this->row_data = array();
|
||||
$variable_products = array();
|
||||
|
||||
foreach ( $products->products as $product ) {
|
||||
$row = array();
|
||||
foreach ( $columns as $column_id => $column_name ) {
|
||||
$column_id = strstr( $column_id, ':' ) ? current( explode( ':', $column_id ) ) : $column_id;
|
||||
$value = '';
|
||||
// Check if the category is set, this means we need to fetch variations seperately as they are not tied to a category.
|
||||
if ( ! empty( $args['category'] ) && $product->is_type( 'variable' ) ) {
|
||||
$variable_products[] = $product->get_id();
|
||||
}
|
||||
|
||||
// Skip some columns if dynamically handled later or if we're being selective.
|
||||
if ( in_array( $column_id, array( 'downloads', 'attributes', 'meta' ), true ) || ! $this->is_column_exporting( $column_id ) ) {
|
||||
$this->row_data[] = $this->generate_row_data( $product );
|
||||
}
|
||||
|
||||
// If a category was selected we loop through the variations as they are not tied to a category so will be excluded by default.
|
||||
if ( ! empty( $variable_products ) ) {
|
||||
foreach ( $variable_products as $parent_id ) {
|
||||
$products = wc_get_products( array(
|
||||
'parent' => $parent_id,
|
||||
'type' => array( 'variation' ),
|
||||
'return' => 'objects',
|
||||
'limit' => -1,
|
||||
) );
|
||||
|
||||
if ( ! $products ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( has_filter( "woocommerce_product_export_{$this->export_type}_column_{$column_id}" ) ) {
|
||||
// Filter for 3rd parties.
|
||||
$value = apply_filters( "woocommerce_product_export_{$this->export_type}_column_{$column_id}", '', $product, $column_id );
|
||||
|
||||
} elseif ( is_callable( array( $this, "get_column_value_{$column_id}" ) ) ) {
|
||||
// Handle special columns which don't map 1:1 to product data.
|
||||
$value = $this->{"get_column_value_{$column_id}"}( $product );
|
||||
|
||||
} elseif ( is_callable( array( $product, "get_{$column_id}" ) ) ) {
|
||||
// Default and custom handling.
|
||||
$value = $product->{"get_{$column_id}"}( 'edit' );
|
||||
foreach ( $products as $product ) {
|
||||
$this->row_data[] = $this->generate_row_data( $product );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$row[ $column_id ] = $value;
|
||||
/**
|
||||
* Take a product and generate row data from it for export.
|
||||
*
|
||||
* @param WC_Product $product WC_Product object.
|
||||
* @return array
|
||||
*/
|
||||
protected function generate_row_data( $product ) {
|
||||
$columns = $this->get_column_names();
|
||||
$row = array();
|
||||
foreach ( $columns as $column_id => $column_name ) {
|
||||
$column_id = strstr( $column_id, ':' ) ? current( explode( ':', $column_id ) ) : $column_id;
|
||||
$value = '';
|
||||
|
||||
// Skip some columns if dynamically handled later or if we're being selective.
|
||||
if ( in_array( $column_id, array( 'downloads', 'attributes', 'meta' ), true ) || ! $this->is_column_exporting( $column_id ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->prepare_downloads_for_export( $product, $row );
|
||||
$this->prepare_attributes_for_export( $product, $row );
|
||||
$this->prepare_meta_for_export( $product, $row );
|
||||
if ( has_filter( "woocommerce_product_export_{$this->export_type}_column_{$column_id}" ) ) {
|
||||
// Filter for 3rd parties.
|
||||
$value = apply_filters( "woocommerce_product_export_{$this->export_type}_column_{$column_id}", '', $product, $column_id );
|
||||
|
||||
$this->row_data[] = apply_filters( 'woocommerce_product_export_row_data', $row, $product );
|
||||
} elseif ( is_callable( array( $this, "get_column_value_{$column_id}" ) ) ) {
|
||||
// Handle special columns which don't map 1:1 to product data.
|
||||
$value = $this->{"get_column_value_{$column_id}"}( $product );
|
||||
|
||||
} elseif ( is_callable( array( $product, "get_{$column_id}" ) ) ) {
|
||||
// Default and custom handling.
|
||||
$value = $product->{"get_{$column_id}"}( 'edit' );
|
||||
}
|
||||
|
||||
$row[ $column_id ] = $value;
|
||||
}
|
||||
|
||||
$this->prepare_downloads_for_export( $product, $row );
|
||||
$this->prepare_attributes_for_export( $product, $row );
|
||||
$this->prepare_meta_for_export( $product, $row );
|
||||
return apply_filters( 'woocommerce_product_export_row_data', $row, $product );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -119,6 +119,7 @@ class WC_Tests_Product_CSV_Exporter extends WC_Unit_Test_Case {
|
|||
WC_Helper_Product::create_grouped_product();
|
||||
WC_Helper_Product::create_variation_product();
|
||||
|
||||
$exporter->set_product_category_to_export( array() );
|
||||
$exporter->prepare_data_to_export();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue