Completed
Push — master ( 15aa29...17da96 )
by Claudio
18:39 queued 11s
created

includes/class-wc-product-factory.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Product Factory
4
 *
5
 * The WooCommerce product factory creating the right product object.
6
 *
7
 * @package WooCommerce/Classes
8
 * @version 3.0.0
9
 */
10
11
defined( 'ABSPATH' ) || exit;
12
13
/**
14
 * Product factory class.
15
 */
16
class WC_Product_Factory {
17
18
	/**
19
	 * Get a product.
20
	 *
21
	 * @param mixed $product_id WC_Product|WP_Post|int|bool $product Product instance, post instance, numeric or false to use global $post.
22
	 * @param array $deprecated Previously used to pass arguments to the factory, e.g. to force a type.
23
	 * @return WC_Product|bool Product object or false if the product cannot be loaded.
24
	 */
25 375
	public function get_product( $product_id = false, $deprecated = array() ) {
26 375
		$product_id = $this->get_product_id( $product_id );
27
28 375
		if ( ! $product_id ) {
29 12
			return false;
30
		}
31
32 372
		$product_type = $this->get_product_type( $product_id );
33
34
		// Backwards compatibility.
35 372
		if ( ! empty( $deprecated ) ) {
36
			wc_deprecated_argument( 'args', '3.0', 'Passing args to the product factory is deprecated. If you need to force a type, construct the product class directly.' );
37
38
			if ( isset( $deprecated['product_type'] ) ) {
39
				$product_type = $this->get_classname_from_product_type( $deprecated['product_type'] );
40
			}
41
		}
42
43 372
		$classname = $this->get_product_classname( $product_id, $product_type );
0 ignored issues
show
It seems like $product_type can also be of type false; however, WC_Product_Factory::get_product_classname() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
44
45
		try {
46 372
			return new $classname( $product_id, $deprecated );
47 4
		} catch ( Exception $e ) {
48 4
			return false;
49
		}
50
	}
51
52
	/**
53
	 * Gets a product classname and allows filtering. Returns WC_Product_Simple if the class does not exist.
54
	 *
55
	 * @since  3.0.0
56
	 * @param  int    $product_id   Product ID.
57
	 * @param  string $product_type Product type.
58
	 * @return string
59
	 */
60 372
	public static function get_product_classname( $product_id, $product_type ) {
61 372
		$classname = apply_filters( 'woocommerce_product_class', self::get_classname_from_product_type( $product_type ), $product_type, 'variation' === $product_type ? 'product_variation' : 'product', $product_id );
62
63 372
		if ( ! $classname || ! class_exists( $classname ) ) {
64 2
			$classname = 'WC_Product_Simple';
65
		}
66
67 372
		return $classname;
68
	}
69
70
	/**
71
	 * Get the product type for a product.
72
	 *
73
	 * @since 3.0.0
74
	 * @param  int $product_id Product ID.
75
	 * @return string|false
76
	 */
77 401
	public static function get_product_type( $product_id ) {
78
		// Allow the overriding of the lookup in this function. Return the product type here.
79 401
		$override = apply_filters( 'woocommerce_product_type_query', false, $product_id );
80 401
		if ( ! $override ) {
81 401
			return WC_Data_Store::load( 'product' )->get_product_type( $product_id );
82
		} else {
83
			return $override;
84
		}
85
	}
86
87
	/**
88
	 * Create a WC coding standards compliant class name e.g. WC_Product_Type_Class instead of WC_Product_type-class.
89
	 *
90
	 * @param  string $product_type Product type.
91
	 * @return string|false
92
	 */
93 373
	public static function get_classname_from_product_type( $product_type ) {
94 373
		return $product_type ? 'WC_Product_' . implode( '_', array_map( 'ucfirst', explode( '-', $product_type ) ) ) : false;
95
	}
96
97
	/**
98
	 * Get the product ID depending on what was passed.
99
	 *
100
	 * @since  3.0.0
101
	 * @param  WC_Product|WP_Post|int|bool $product Product instance, post instance, numeric or false to use global $post.
102
	 * @return int|bool false on failure
103
	 */
104 375 View Code Duplication
	private function get_product_id( $product ) {
105
		global $post;
106
107 375
		if ( false === $product && isset( $post, $post->ID ) && 'product' === get_post_type( $post->ID ) ) {
108
			return absint( $post->ID );
109 375
		} elseif ( is_numeric( $product ) ) {
110 369
			return $product;
111 33
		} elseif ( $product instanceof WC_Product ) {
112
			return $product->get_id();
113 33
		} elseif ( ! empty( $product->ID ) ) {
114 33
			return $product->ID;
115
		} else {
116
			return false;
117
		}
118
	}
119
}
120