|
6 | 6 | *
|
7 | 7 | * For the full copyright and license information, please view the LICENSE
|
8 | 8 | * file that was distributed with this source code.
|
| 9 | + * |
| 10 | + * This file was written by J.Moore to replace the existing Stock.php file which had |
| 11 | + * multiple issues: this version takes a different approach |
9 | 12 | */
|
10 | 13 |
|
11 | 14 | namespace Hyyan\WPI\Product;
|
12 | 15 |
|
13 | 16 | use Hyyan\WPI\Utilities;
|
14 | 17 | use Hyyan\WPI\Product\Variation;
|
15 |
| -use Hyyan\WPI\Admin\Settings; |
16 |
| -use Hyyan\WPI\Admin\MetasList; |
17 |
| - |
18 |
| -/** |
19 |
| - * Product Stock. |
20 |
| - * |
21 |
| - * Handle stock sync |
22 |
| - * |
23 |
| - * @author Hyyan Abo Fakher <[email protected]> |
24 |
| - */ |
25 |
| -class Stock |
26 |
| -{ |
27 |
| - const STOCK_REDUCE_ACTION = 'reduce'; |
28 |
| - const STOCK_INCREASE_ACTION = 'increase'; |
29 |
| - |
30 |
| - /** |
31 |
| - * Construct object. |
32 |
| - */ |
33 |
| - public function __construct() |
34 |
| - { |
35 |
| - // sync stock |
36 |
| - add_action( |
37 |
| - 'woocommerce_reduce_order_stock', array($this, 'reduceStock') |
38 |
| - ); |
39 |
| - add_filter( |
40 |
| - 'woocommerce_restore_order_stock_quantity', array($this, 'increaseStock') |
41 |
| - ); |
42 |
| - } |
43 |
| - |
44 |
| - /** |
45 |
| - * Reduce stock for product and its translation. |
46 |
| - * |
47 |
| - * @param \WC_Order $order |
48 |
| - */ |
49 |
| - public function reduceStock($order) |
50 |
| - { |
51 |
| - |
52 |
| - /* Get array of ordered products */ |
53 |
| - $items = $order->get_items(); |
54 |
| - |
55 |
| - /* Reduce stock */ |
56 |
| - foreach ($items as $item) { |
57 |
| - $this->change($item, self::STOCK_REDUCE_ACTION); |
58 |
| - } |
59 |
| - } |
60 |
| - |
61 |
| - /** |
62 |
| - * Increase stock for product and its translation. |
63 |
| - * |
64 |
| - * @param int $change the stock change |
65 |
| - * |
66 |
| - * @return int stock change |
67 |
| - */ |
68 |
| - public function increaseStock($change) |
69 |
| - { |
70 |
| - $orderId = absint($_POST['order_id']); |
71 |
| - $order = new \WC_Order($orderId); |
72 |
| - |
73 |
| - /* Get array of ordered products */ |
74 |
| - $items = $order->get_items(); |
75 |
| - |
76 |
| - /* Increase stock */ |
77 |
| - foreach ($items as $item) { |
78 |
| - $item->change = $change; |
79 |
| - $this->change($item, self::STOCK_INCREASE_ACTION); |
80 |
| - } |
81 |
| - } |
82 |
| - |
83 |
| - /** |
84 |
| - * Change the product stock in the given order item. |
85 |
| - * |
86 |
| - * @param array $item the order data |
87 |
| - * @param string $action STOCK_REDUCE_ACTION | STOCK_INCREASE_ACTION |
88 |
| - */ |
89 |
| - protected function change(\WC_Order_Item_Product $item, $action = self::STOCK_REDUCE_ACTION) |
90 |
| - { |
91 |
| - $productID = Utilities::get_order_item_productid($item); |
92 |
| - $productObject = wc_get_product($productID); |
93 |
| - //$productLang = pll_get_post_language($productID); //#184 |
94 |
| - $orderLang = pll_get_post_language($item->get_order_id()); |
95 |
| - $variationID = Utilities::get_order_item_variationid($item); |
96 |
| - |
97 |
| - /* Handle Products */ |
98 |
| - if ($productObject && $orderLang) { |
99 |
| - |
100 |
| - /* Get the translations IDS */ |
101 |
| - $translations = Utilities::getProductTranslationsArrayByObject( |
102 |
| - $productObject |
103 |
| - ); |
104 |
| - |
105 |
| - $method = ($action === self::STOCK_REDUCE_ACTION) ? |
106 |
| - 'decrease' : |
107 |
| - 'increase'; |
108 |
| - $change = ($action === self::STOCK_REDUCE_ACTION) ? |
109 |
| - Utilities::get_order_item_quantity($item) : |
110 |
| - Utilities::get_order_item_change($item); |
111 |
| - |
112 |
| - |
113 |
| - $isManageStock = $productObject->managing_stock(); |
114 |
| - $isVariation = $variationID && $variationID > 0; |
115 |
| - |
116 |
| - //in 3.0.8 at least, current lang item must not be removed from array if is variable |
117 |
| - if ($isManageStock && (!$isVariation)) { |
118 |
| - /* Remove the current product from translation array */ |
119 |
| - unset($translations[$orderLang]); |
120 |
| - } |
121 |
| - |
122 |
| - /* Sync stock for all translation */ |
123 |
| - foreach ($translations as $ID) { |
124 |
| - |
125 |
| - /* Only if product is managing stock |
126 |
| - * including variation with stock managed at product level*/ |
127 |
| - if ($isManageStock) { |
128 |
| - if (($translation = wc_get_product($ID))) { |
129 |
| - \wc_update_product_stock($translation, $change, $method); |
130 |
| - } |
131 |
| - } |
132 |
| - |
133 |
| - $general = Settings::getOption( |
134 |
| - 'general', MetasList::getID(), array('total_sales') |
135 |
| - ); |
136 |
| - if (in_array('total_sales', $general)) { |
137 |
| - update_post_meta( |
138 |
| - $ID, 'total_sales', get_post_meta($productID, 'total_sales', true) |
139 |
| - ); |
140 |
| - } |
141 |
| - } |
142 | 18 |
|
143 |
| - /* Handle variation stock UNLESS stock is managed on the parent |
144 |
| - * there is a function for this $variation->get_stock_managed_by_id() however in woo-poly-context |
145 |
| - * this returns the master language id of either the variation of the parent. |
146 |
| - */ |
147 |
| - if (($isVariation) && !($isManageStock)) { |
148 |
| - //unfortunately pll functions can't be used as the |
149 |
| - //variations are not currently linked using pll_save_post_translations |
150 |
| - //still it might be more sensible to get master in base language, and synchronise from that |
151 |
| - //$variationMaster = (pll_get_post_language($variationID) == pll_default_language()) ? |
152 |
| - // wc_get_product($variationID) : Utilities::getProductTranslationByID($variationID, pll_default_language()); |
| 19 | +class Stock { |
| 20 | + public function __construct() { |
| 21 | + // sync stock |
| 22 | + add_action( |
| 23 | + 'woocommerce_product_set_stock', array( __CLASS__, 'SyncStockSimple' ) |
| 24 | + ); |
| 25 | + add_action( |
| 26 | + 'woocommerce_variation_set_stock', array( __CLASS__, 'SyncStockVariation' ) |
| 27 | + ); |
| 28 | + } |
| 29 | + |
| 30 | + /* |
| 31 | + * Unhook the action, synchronise the stock and rehook the action |
| 32 | + * |
| 33 | + * @param \WC_Product $product the product which has had stock updated |
| 34 | + */ |
| 35 | + public static function SyncStockSimple( \WC_Product $product ) { |
| 36 | + //first remove this action to avoid recusive call when setting translation stock |
| 37 | + remove_action( 'woocommerce_product_set_stock', array( __CLASS__, __FUNCTION__ ), 10 ); |
| 38 | + static::SyncStock( $product ); |
| 39 | + add_action( 'woocommerce_product_set_stock', array( __CLASS__, __FUNCTION__ ), 10 ); |
| 40 | + } |
| 41 | + |
| 42 | + /* |
| 43 | + * Unhook the action, synchronise the stock and rehook the action |
| 44 | + * |
| 45 | + * @param \WC_Product $product the product which has had stock updated |
| 46 | + */ |
| 47 | + public static function SyncStockVariation( \WC_Product $product ) { |
| 48 | + //first remove this action to avoid recusive call when setting translation stock |
| 49 | + remove_action( 'woocommerce_variation_set_stock', array( __CLASS__, __FUNCTION__ ), 10 ); |
| 50 | + static::SyncStock( $product ); |
| 51 | + add_action( 'woocommerce_variation_set_stock', array( __CLASS__, __FUNCTION__ ), 10 ); |
| 52 | + } |
| 53 | + |
| 54 | + /* |
| 55 | + * Synchronise stock levels across translations any time stock is updated |
| 56 | + * through the product api [always now via wc_update_product_stock()] |
| 57 | + * |
| 58 | + * @param \WC_Product $product the product which has had stock updated |
| 59 | + */ |
| 60 | + public static function SyncStock( \WC_Product $product ) { |
| 61 | + //use same logic as wc_update_product_stock to get the product which is actually managing the stock |
| 62 | + $product_id_with_stock = $product->get_stock_managed_by_id(); |
| 63 | + $product_with_stock = $product_id_with_stock !== $product->get_id() ? wc_get_product( $product_id_with_stock ) : $product; |
| 64 | + |
| 65 | + if ( $product_with_stock ) { |
| 66 | + $targetValue = $product_with_stock->get_stock_quantity(); |
| 67 | + |
| 68 | + //update all the translations to the same stock level.. |
| 69 | + $product_translations = ($product_with_stock->is_type( 'variation' )) ? |
| 70 | + Variation::getRelatedVariation( get_post_meta( $product_with_stock->get_id(), Variation::DUPLICATE_KEY, true ), true ) : |
| 71 | + Utilities::getProductTranslationsArrayByObject( $product_with_stock ); |
| 72 | + |
| 73 | + foreach ( $product_translations as $product_translation ) { |
| 74 | + if ( $product_translation != $product_with_stock->get_id() ) { |
| 75 | + $translation = wc_get_product( $product_translation ); |
| 76 | + if ( $translation ) { |
| 77 | + wc_update_product_stock( $translation, $targetValue ); |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + } |
153 | 83 |
|
154 |
| - $variationMasterID = get_post_meta($variationID, Variation::DUPLICATE_KEY, true); |
155 |
| - $variationMaster = wc_get_product($variationMasterID); |
156 |
| - if ($variationMaster) { |
157 |
| - $variationMasterManagerStock = $variationMaster->managing_stock(); |
158 |
| - if ($variationMasterManagerStock) { |
159 |
| - //$posts = Utilities::getProductTranslationsArrayByObject($variationMaster); |
160 |
| - $posts = Variation::getRelatedVariation($variationMasterID); |
161 |
| - foreach ($posts as $post) { |
162 |
| - $variation = wc_get_product($post); |
163 |
| - if ($variation) { |
164 |
| - //tested with orderlang, actually here it is the product language as currently variation item |
165 |
| - //is added and handled in original language even if order switched language |
166 |
| - if (pll_get_post_language($variation->get_parent_id()) != pll_get_post_language($productID)) { |
167 |
| - \wc_update_product_stock($variation, $change, $method); |
168 |
| - } |
169 |
| - } |
170 |
| - } |
171 |
| - } |
172 |
| - } |
173 |
| - } |
174 |
| - } |
175 |
| - } |
176 | 84 | }
|
0 commit comments