Prevent variations being created/returned without parents

Nasty bug discovered by @RiaanKnoetze where it would get a variation
without parent, and due to the return, it wouldn’t be ‘seen’ as a
variation, therefore creating fatal errors when props are called.

To prevent this, lets allow product constructors to throw exceptions.
If they do, the factory class will catch them and return false instead
of an invalid product object.

@claudiosmweb Thoughts on this one before merge?
This commit is contained in:
Mike Jolley 2016-05-13 19:06:16 +01:00
parent 6e94df6ee5
commit d42d7c13b6
2 changed files with 22 additions and 17 deletions

View File

@ -18,30 +18,35 @@ if ( ! defined( 'ABSPATH' ) ) {
class WC_Product_Factory { class WC_Product_Factory {
/** /**
* Get product. * Get a product.
* *
* @param bool $the_product (default: false) * @param bool $the_product (default: false)
* @param array $args (default: array()) * @param array $args (default: array())
* @return WC_Product|bool false if the product cannot be loaded * @return WC_Product|bool false if the product cannot be loaded
*/ */
public function get_product( $the_product = false, $args = array() ) { public function get_product( $the_product = false, $args = array() ) {
$the_product = $this->get_product_object( $the_product ); try {
$the_product = $this->get_product_object( $the_product );
if ( ! $the_product ) { if ( ! $the_product ) {
throw new Exception( 'Product object does not exist', 422 );
}
$classname = $this->get_product_class( $the_product, $args );
if ( ! $classname ) {
throw new Exception( 'Missing classname', 422 );
}
if ( ! class_exists( $classname ) ) {
$classname = 'WC_Product_Simple';
}
return new $classname( $the_product, $args );
} catch ( Exception $e ) {
return false; return false;
} }
$classname = $this->get_product_class( $the_product, $args );
if ( ! $classname ) {
return false;
}
if ( ! class_exists( $classname ) ) {
$classname = 'WC_Product_Simple';
}
return new $classname( $the_product, $args );
} }
/** /**

View File

@ -80,9 +80,9 @@ class WC_Product_Variation extends WC_Product {
/* Get main product data from parent (args) */ /* Get main product data from parent (args) */
$this->id = ! empty( $args['parent_id'] ) ? intval( $args['parent_id'] ) : wp_get_post_parent_id( $this->variation_id ); $this->id = ! empty( $args['parent_id'] ) ? intval( $args['parent_id'] ) : wp_get_post_parent_id( $this->variation_id );
// The post doesn't have a parent id, therefore its invalid. // The post doesn't have a parent id, therefore its invalid and we should prevent this being created.
if ( empty( $this->id ) ) { if ( empty( $this->id ) ) {
return; throw new Exception( sprintf( 'No parent product set for variation #%d', $this->variation_id ), 422 );
} }
$this->product_type = 'variation'; $this->product_type = 'variation';