diff --git a/src/BigCommerce/Post_Types/Product/Product.php b/src/BigCommerce/Post_Types/Product/Product.php index 54ffb652..375941b4 100644 --- a/src/BigCommerce/Post_Types/Product/Product.php +++ b/src/BigCommerce/Post_Types/Product/Product.php @@ -777,12 +777,76 @@ public static function by_product_id( $product_id, \WP_Term $channel = null, $qu ]; } + return self::query($args, $query_args); + } + + /** + * Gets a BigCommerce Product by SKU and returns matching Product object + * + * @param int $product_sku + * + * @param \WP_Term|null $channel + * + * @param array $query_args + * + * @return Product|array + */ + public static function by_product_sku( $product_sku, \WP_Term $channel = null, $query_args = [] ) { + + if ( empty( $product_sku ) ) { + throw new \InvalidArgumentException( __( 'Product SKU must be a provided', 'bigcommerce' ) ); + } + + $args = [ + 'meta_query' => [ + [ + 'key' => 'bigcommerce_sku', + 'value' => sanitize_text_field($product_sku), + ], + ], + 'post_type' => self::NAME, + 'posts_per_page' => 1, + ]; + + if ( $channel === null ) { + // use the current channel + $connections = new Connections(); + $channel = $connections->current(); + } + + if ( $channel ) { + $args['tax_query'] = [ + [ + 'taxonomy' => Channel::NAME, + 'field' => 'term_id', + 'terms' => [ (int) $channel->term_id ], + 'operator' => 'IN', + ], + ]; + } + + return self::query($args, $query_args); + } + + /** + * Executes WP_Query and returns matching Product object + * + * @param int $product_sku + * + * @param \WP_Term|null $channel + * + * @param array $query_args + * + * @return Product|array + */ + private static function query($args, $query_args = [] ) { + $args = array_merge( $args, $query_args ); $posts = get_posts( $args ); if ( empty( $posts ) ) { - throw new Product_Not_Found_Exception( sprintf( __( 'No product found matching BigCommerce ID %d', 'bigcommerce' ), $product_id ) ); + throw new Product_Not_Found_Exception( sprintf( __( 'No product found matching key "%s" with value "%s"', 'bigcommerce' ), $args['meta_query'][0]['key'], $args['meta_query'][0]['value'] ) ); } return new Product( $posts[0]->ID ); diff --git a/src/BigCommerce/Shortcodes/Product_Components.php b/src/BigCommerce/Shortcodes/Product_Components.php index 922b849e..3722a493 100644 --- a/src/BigCommerce/Shortcodes/Product_Components.php +++ b/src/BigCommerce/Shortcodes/Product_Components.php @@ -26,10 +26,11 @@ class Product_Components implements Shortcode { */ public static function default_attributes() { return [ - 'id' => 0, // BigCommerce product ID - 'post_id' => 0, // WordPress post ID + 'id' => 0, // BigCommerce product ID + 'sku' => '', // BigCommerce product SKU + 'post_id' => 0, // WordPress post ID 'type' => '', // Type of product component - 'preview' => 0, // internal use: set to 1 to remove interactive elements + 'preview' => 0, // internal use: set to 1 to remove interactive elements ]; } @@ -43,6 +44,14 @@ public function render( $attributes, $instance ) { } catch ( \Exception $e ) { return $this->product_not_found(); } + } else if ( ! empty( $attr['sku'] ) ) { + // The $attr['sku'] is the BC product SKU + try { + $product = Product::by_product_sku($attr['sku']); + } + catch ( \Exception $e ) { + return $this->product_not_found(); + } } else { $post_id = empty( $attr['post_id'] ) ? get_the_ID() : absint( $attr['post_id'] ); if ( empty( $post_id ) || get_post_type( $post_id ) !== Product::NAME ) {