WC_Admin_Duplicate_Product::generate_unique_sku
Generates a unique sku for a given product.
Method of the class: WC_Admin_Duplicate_Product{}
Hooks from the method
Returns
null. Nothing (null).
Usage
// private - for code of main (parent) class only $result = $this->generate_unique_sku( $product );
- $product(WC_Product) (required)
- The product to generate a sku for.
Changelog
| Since 10.5.0 | Introduced. |
WC_Admin_Duplicate_Product::generate_unique_sku() WC Admin Duplicate Product::generate unique sku code WC 10.7.0
private function generate_unique_sku( $product ) {
global $wpdb;
// We want to remove the suffix from the sku so that we can find the maximum suffix using this root sku.
// This will allow us to find the next-highest suffix that is unique. While this does not support gap
// filling, this shouldn't matter for our use-case.
$root_sku = preg_replace( '/-[0-9]+$/', '', $product->get_sku() );
// If the parent product has no SKU, don't do anything.
if ( ! $root_sku ) {
return;
}
$existing_skus = $wpdb->get_col(
$wpdb->prepare(
"SELECT lookup.sku
FROM {$wpdb->posts} as posts
INNER JOIN {$wpdb->wc_product_meta_lookup} AS lookup ON posts.ID = lookup.product_id
WHERE posts.post_type IN ( 'product', 'product_variation' )
AND lookup.sku LIKE %s",
$wpdb->esc_like( $root_sku ) . '%'
)
);
// The sku is already unique!
if ( empty( $existing_skus ) ) {
$product->set_sku( $root_sku );
return;
}
// Find the maximum suffix so we can ensure uniqueness.
$max_suffix = 0;
foreach ( $existing_skus as $existing_sku ) {
// Pull a numerical suffix off the sku after the last hyphen.
$suffix = intval( substr( $existing_sku, strrpos( $existing_sku, '-', -1 ) + 1 ) );
if ( $suffix > $max_suffix ) {
$max_suffix = $suffix;
}
}
// We set a limit of SKUs to try in order to avoid infinite loops.
$limit = $max_suffix + 100;
$product_id = $product->get_id();
while ( $max_suffix < $limit ) {
$new_sku = $root_sku . '-' . ( $max_suffix + 1 );
/**
* Gives plugins an opportunity to verify SKU uniqueness themselves. Filter added to keep backwards
* compatibility with `wc_product_has_unique_sku()`.
* See: https://github.com/woocommerce/woocommerce/pull/62628
*
* @since 10.5.0
*
* @param bool|null $has_unique_sku Set to a boolean value to short-circuit the default SKU check.
* @param int $product_id The ID of the current product.
* @param string $sku The SKU to check for uniqueness.
*/
$pre_has_unique_sku = apply_filters( 'wc_product_pre_has_unique_sku', true, $product_id, $new_sku );
if ( $pre_has_unique_sku ) {
/**
* Gives plugins an opportunity to verify SKU uniqueness themselves. Filter added to keep backwards
* compatibility with `wc_product_has_unique_sku()`.
* See: https://github.com/woocommerce/woocommerce/pull/62628
*
* @since 10.5.0
*
* @param bool|null $sku_found Set to a boolean value to short-circuit the default SKU check.
* @param int $product_id The ID of the current product.
* @param string $sku The SKU to check for uniqueness.
*/
$sku_found = apply_filters( 'wc_product_has_unique_sku', false, $product_id, $new_sku );
if ( ! $sku_found ) {
$product->set_sku( $new_sku );
return;
}
}
++$max_suffix;
}
}