| @@ -57,15 +57,8 @@ | ||
| 57 | 57 | */ |
| 58 | 58 | private $is_accept_reject_button_registered = false; |
| 59 | 59 | |
| 60 | 60 | /** |
| 61 | - * List of upsell product with price | |
| 62 | - * | |
| 63 | - * @var array | |
| 64 | - */ | |
| 65 | - private static $sellkit_upsell_products; | |
| 66 | - | |
| 67 | - /** | |
| 68 | 61 | * Class constructor. |
| 69 | 62 | * |
| 70 | 63 | * @since 2.3.0 |
| 71 | 64 | */ |
| @@ -912,13 +905,9 @@ | ||
| 912 | 905 | if ( $item_id === $product_id ) { |
| 913 | 906 | $discount_type = isset( $product_details['discountType'] ) ? $product_details['discountType'] : ''; |
| 914 | 907 | $discount_value = isset( $product_details['discount'] ) ? $product_details['discount'] : ''; |
| 915 | 908 | |
| 916 | - $price = $this->calculate_discount( $item_id, $discount_type, $discount_value ); | |
| 917 | - | |
| 918 | - if ( 'upsell' === $source ) { | |
| 919 | - self::$sellkit_upsell_products[ $product_id ] = $price; | |
| 920 | - } | |
| 909 | + $price = self::calculate_discount( $item_id, $discount_type, $discount_value ); | |
| 921 | 910 | } |
| 922 | 911 | } |
| 923 | 912 | |
| 924 | 913 | if ( false !== $price ) { |
| @@ -1148,69 +1137,35 @@ | ||
| 1148 | 1137 | if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 && wp_doing_ajax() ) { |
| 1149 | 1138 | return; |
| 1150 | 1139 | } |
| 1151 | 1140 | |
| 1152 | - // Gather checkout id. | |
| 1153 | - $checkout_id = get_queried_object_id(); | |
| 1141 | + $checkout_id = self::get_valid_checkout_id(); | |
| 1154 | 1142 | |
| 1155 | - if ( wp_doing_ajax() ) { | |
| 1156 | - // First try to catch id using our ajax call. | |
| 1157 | - $checkout_id = filter_input( INPUT_POST, 'related_checkout', FILTER_SANITIZE_NUMBER_INT ); | |
| 1158 | - | |
| 1159 | - // Second try to catch id using woocommerce ajax. | |
| 1160 | - if ( empty( $checkout_id ) ) { | |
| 1161 | - $checkout_id = filter_input( INPUT_POST, 'sellkit_current_page_id', FILTER_SANITIZE_NUMBER_INT ); | |
| 1162 | - } | |
| 1163 | - | |
| 1164 | - // Catch id after pressing place order button. none of above methods worked. | |
| 1165 | - if ( empty( $checkout_id ) ) { | |
| 1166 | - $data = filter_input( INPUT_POST, 'post_data', FILTER_DEFAULT ); | |
| 1167 | - | |
| 1168 | - if ( ! empty( $data ) ) { | |
| 1169 | - parse_str( $data, $data ); | |
| 1170 | - } | |
| 1171 | - | |
| 1172 | - if ( is_array( $data ) && array_key_exists( 'sellkit_current_page_id', $data ) ) { | |
| 1173 | - $checkout_id = $data['sellkit_current_page_id']; | |
| 1174 | - } | |
| 1175 | - } | |
| 1176 | - } | |
| 1177 | - | |
| 1178 | - // Empty id ? no action. | |
| 1179 | - if ( empty( $checkout_id ) ) { | |
| 1143 | + if ( 0 === $checkout_id ) { | |
| 1180 | 1144 | return; |
| 1181 | 1145 | } |
| 1182 | 1146 | |
| 1183 | - $checkout_id = (int) $checkout_id; | |
| 1184 | - | |
| 1185 | 1147 | // Apply funnel prices. |
| 1186 | 1148 | $this->apply_discounted_prices( wc()->cart, $checkout_id ); |
| 1187 | 1149 | $this->apply_discounted_prices( wc()->cart, $checkout_id, 'bumps' ); |
| 1188 | 1150 | |
| 1189 | 1151 | // Apply upsell discount. |
| 1190 | - $sellkit_upsell_prices = null; | |
| 1152 | + $sellkit_upsell_ids = null; | |
| 1191 | 1153 | if ( isset( $_POST['woocommerce-process-checkout-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['woocommerce-process-checkout-nonce'] ) ), 'woocommerce-process_checkout' ) ) { |
| 1192 | - $sellkit_upsell_prices = isset( $_POST['sellkit_product_prices'] ) ? sanitize_textarea_field( wp_unslash( $_POST['sellkit_product_prices'] ) ) : null; | |
| 1154 | + $sellkit_upsell_ids = isset( $_POST['sellkit_upsell_ids'] ) ? sanitize_textarea_field( wp_unslash( $_POST['sellkit_upsell_ids'] ) ) : null; | |
| 1193 | 1155 | } |
| 1194 | - $upsell_product_ids; | |
| 1195 | 1156 | |
| 1196 | - if ( isset( $sellkit_upsell_prices ) && ! empty( $sellkit_upsell_prices ) ) { | |
| 1197 | - $sellkit_upsell_prices = json_decode( $sellkit_upsell_prices, true ); | |
| 1198 | - $upsell_product_ids = array_keys( $sellkit_upsell_prices ); | |
| 1199 | - } | |
| 1157 | + if ( ! empty( $sellkit_upsell_ids ) ) { | |
| 1158 | + $upsell_ids = explode( ',', $sellkit_upsell_ids ); | |
| 1159 | + $list = self::upsell_downsell_ids_of_funnel( $checkout_id ); | |
| 1200 | 1160 | |
| 1201 | - if ( isset( $upsell_product_ids ) ) { | |
| 1202 | - foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { | |
| 1203 | - $product = $cart_item['data']; | |
| 1204 | - $product_name = $product->get_name(); | |
| 1205 | - $product_id = $product->get_id(); | |
| 1161 | + if ( ! empty( $list ) ) { | |
| 1162 | + foreach ( $upsell_ids as $id ) { | |
| 1206 | 1163 | |
| 1207 | - if ( in_array( $product_id, $upsell_product_ids, true ) ) { | |
| 1208 | - $upsell_price = $sellkit_upsell_prices[ $product_id ]; | |
| 1209 | - $product->set_price( $upsell_price ); | |
| 1164 | + if ( in_array( $id, $list, true ) ) { | |
| 1165 | + self::applay_upsell_downsell_discount( $id ); | |
| 1166 | + } | |
| 1210 | 1167 | } |
| 1211 | - | |
| 1212 | - $price = $product->get_price(); | |
| 1213 | 1168 | } |
| 1214 | 1169 | } |
| 1215 | 1170 | |
| 1216 | 1171 | // We should re apply coupons after each price changes. to make sure everything is correct. |
| @@ -1227,8 +1182,111 @@ | ||
| 1227 | 1182 | } |
| 1228 | 1183 | } |
| 1229 | 1184 | |
| 1230 | 1185 | /** |
| 1186 | + * Extract upsell and downsell ids from funnel. | |
| 1187 | + * | |
| 1188 | + * @since 2.8.0 | |
| 1189 | + * | |
| 1190 | + * @param int $checkout_id id of checkout. | |
| 1191 | + * | |
| 1192 | + * @return array | |
| 1193 | + */ | |
| 1194 | + private static function upsell_downsell_ids_of_funnel( $checkout_id ) { | |
| 1195 | + $step_data = get_post_meta( $checkout_id, 'step_data', true ); | |
| 1196 | + $funnel_id = $step_data['funnel_id']; | |
| 1197 | + $nodes = get_post_meta( $funnel_id, 'nodes', true ); | |
| 1198 | + $ids = []; | |
| 1199 | + | |
| 1200 | + foreach ( $nodes as $node ) { | |
| 1201 | + if ( isset( $node['type'] ) && in_array( $node['type']['key'], [ 'upsell', 'downsell' ], true ) ) { | |
| 1202 | + $ids[] = $node['page_id']; | |
| 1203 | + } | |
| 1204 | + } | |
| 1205 | + | |
| 1206 | + return $ids; | |
| 1207 | + } | |
| 1208 | + | |
| 1209 | + /** | |
| 1210 | + * Apply discount to upsell or downsell. | |
| 1211 | + * | |
| 1212 | + * @since 2.8.0 | |
| 1213 | + * | |
| 1214 | + * @param int $id id of upsell or downsell. | |
| 1215 | + */ | |
| 1216 | + private static function applay_upsell_downsell_discount( $id ) { | |
| 1217 | + $upsell_data = get_post_meta( $id, 'step_data', true ); | |
| 1218 | + $product = $upsell_data['data']['products']['list']; | |
| 1219 | + | |
| 1220 | + foreach ( $product as $key => $value ) { | |
| 1221 | + foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { | |
| 1222 | + $product = $cart_item['data']; | |
| 1223 | + $product_id = $product->get_id(); | |
| 1224 | + | |
| 1225 | + if ( $key === $product_id ) { | |
| 1226 | + $discount_type = isset( $value['discountType'] ) ? $value['discountType'] : ''; | |
| 1227 | + $discount_value = isset( $value['discount'] ) ? $value['discount'] : ''; | |
| 1228 | + | |
| 1229 | + $price = self::calculate_discount( $product_id, $discount_type, $discount_value ); | |
| 1230 | + $product->set_price( $price ); | |
| 1231 | + } | |
| 1232 | + } | |
| 1233 | + } | |
| 1234 | + } | |
| 1235 | + | |
| 1236 | + /** | |
| 1237 | + * Get the checkout step associated with the current visitor. | |
| 1238 | + * | |
| 1239 | + * @since 2.8.0 | |
| 1240 | + * | |
| 1241 | + * @return int | |
| 1242 | + * | |
| 1243 | + * @SuppressWarnings(PHPMD.NPathComplexity) | |
| 1244 | + */ | |
| 1245 | + private static function get_valid_checkout_id() { | |
| 1246 | + $checkout_id = get_queried_object_id(); | |
| 1247 | + | |
| 1248 | + if ( wp_doing_ajax() ) { | |
| 1249 | + $checkout_id = filter_input( INPUT_POST, 'related_checkout', FILTER_SANITIZE_NUMBER_INT ); | |
| 1250 | + | |
| 1251 | + if ( empty( $checkout_id ) ) { | |
| 1252 | + $checkout_id = filter_input( INPUT_POST, 'sellkit_current_page_id', FILTER_SANITIZE_NUMBER_INT ); | |
| 1253 | + } | |
| 1254 | + | |
| 1255 | + if ( empty( $checkout_id ) ) { | |
| 1256 | + $data = filter_input( INPUT_POST, 'post_data', FILTER_DEFAULT ); | |
| 1257 | + | |
| 1258 | + if ( ! empty( $data ) ) { | |
| 1259 | + parse_str( $data, $data ); | |
| 1260 | + } | |
| 1261 | + | |
| 1262 | + if ( is_array( $data ) && array_key_exists( 'sellkit_current_page_id', $data ) ) { | |
| 1263 | + $checkout_id = $data['sellkit_current_page_id']; | |
| 1264 | + } | |
| 1265 | + } | |
| 1266 | + } | |
| 1267 | + | |
| 1268 | + $checkout_id = absint( $checkout_id ); | |
| 1269 | + $step_data = get_post_meta( $checkout_id, 'step_data', true ); | |
| 1270 | + | |
| 1271 | + if ( | |
| 1272 | + 0 === $checkout_id || | |
| 1273 | + 'publish' !== get_post_status( $checkout_id ) || | |
| 1274 | + ! is_array( $step_data ) || | |
| 1275 | + ! isset( $step_data['type']['key'] ) || | |
| 1276 | + 'checkout' !== $step_data['type']['key'] | |
| 1277 | + ) { | |
| 1278 | + return 0; | |
| 1279 | + } | |
| 1280 | + | |
| 1281 | + if ( wp_doing_ajax() && ! function_exists( 'WC' ) ) { | |
| 1282 | + return 0; | |
| 1283 | + } | |
| 1284 | + | |
| 1285 | + return $checkout_id; | |
| 1286 | + } | |
| 1287 | + | |
| 1288 | + /** | |
| 1231 | 1289 | * Check sellkit step through ajax. |
| 1232 | 1290 | * And in order decide to show upsell or downsell steps through a popup. |
| 1233 | 1291 | * |
| 1234 | 1292 | * @since 2.3.0 |
| @@ -1432,9 +1490,9 @@ | ||
| 1432 | 1490 | wp_send_json_success( |
| 1433 | 1491 | [ |
| 1434 | 1492 | 'next_id' => $funnel->end_node_step_data['page_id'], |
| 1435 | 1493 | 'next_type' => $funnel->end_node_step_data['type']['key'], |
| 1436 | - 'upsell_prices' => wp_json_encode( self::$sellkit_upsell_products ), | |
| 1494 | + 'upsell_ids' => $upsell_id, | |
| 1437 | 1495 | ] |
| 1438 | 1496 | ); |
| 1439 | 1497 | } |
| 1440 | 1498 | |
| @@ -1445,9 +1503,9 @@ | ||
| 1445 | 1503 | |
| 1446 | 1504 | $response = [ |
| 1447 | 1505 | 'next_id' => $next_step['page_id'], |
| 1448 | 1506 | 'next_type' => $next_step['type']['key'], |
| 1449 | - 'upsell_prices' => wp_json_encode( self::$sellkit_upsell_products ), | |
| 1507 | + 'upsell_ids' => $upsell_id, | |
| 1450 | 1508 | ]; |
| 1451 | 1509 | |
| 1452 | 1510 | wp_send_json_success( $response ); |
| 1453 | 1511 | } |
| @@ -1716,30 +1774,30 @@ | ||
| 1716 | 1774 | </div> |
| 1717 | 1775 | <div class="sellkit-bump-order-right-header"> |
| 1718 | 1776 | <span class="sellkit-checkout-order-bump-price"> |
| 1719 | 1777 | <?php |
| 1720 | - $discounted_price = $this->calculate_discount( (int) $ids_string, $type, $discount ); | |
| 1778 | + $discounted_price = self::calculate_discount( (int) $ids_string, $type, $discount ); | |
| 1721 | 1779 | $sale_price = $product->get_sale_price(); |
| 1722 | 1780 | $regular_price = $product->get_regular_price(); |
| 1723 | 1781 | $main_price = ( strpos( $type, 'sale' ) !== false ) ? $sale_price : $regular_price; |
| 1724 | 1782 | |
| 1725 | 1783 | if ( floatval( $main_price ) > floatval( $discounted_price ) ) { |
| 1726 | - ?> | |
| 1784 | + ?> | |
| 1727 | 1785 | <del aria-hidden="true"> |
| 1728 | 1786 | <span class="woocommerce-Price-amount amount"> |
| 1729 | 1787 | <bdi> |
| 1730 | 1788 | <span class="woocommerce-Price-currencySymbol"> |
| 1731 | - <?php echo wc_price( $main_price ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> | |
| 1789 | + <?php echo wc_price( $main_price ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> | |
| 1732 | 1790 | </span> |
| 1733 | 1791 | </bdi> |
| 1734 | 1792 | </span> |
| 1735 | 1793 | </del> |
| 1736 | 1794 | <bdi class="bump-price-bolded"><?php echo wc_price( $discounted_price ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></bdi> |
| 1737 | - <?php | |
| 1795 | + <?php | |
| 1738 | 1796 | } else { |
| 1739 | - ?> | |
| 1797 | + ?> | |
| 1740 | 1798 | <bdi><?php echo wc_price( $main_price ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></bdi> |
| 1741 | - <?php | |
| 1799 | + <?php | |
| 1742 | 1800 | } |
| 1743 | 1801 | ?> |
| 1744 | 1802 | </span> |
| 1745 | 1803 | </div> |
| @@ -1787,9 +1845,9 @@ | ||
| 1787 | 1845 | * @param int $value discount value. |
| 1788 | 1846 | * @return int|boolean |
| 1789 | 1847 | * @since 2.3.0 |
| 1790 | 1848 | */ |
| 1791 | - public function calculate_discount( $id, $type, $value ) { | |
| 1849 | + public static function calculate_discount( $id, $type, $value ) { | |
| 1792 | 1850 | if ( false === $type && false === $value ) { |
| 1793 | 1851 | return false; |
| 1794 | 1852 | } |
| 1795 | 1853 | |
| @@ -1832,9 +1890,9 @@ | ||
| 1832 | 1890 | } |
| 1833 | 1891 | |
| 1834 | 1892 | echo '<input type="hidden" id="sellkit_funnel_has_upsell" value="upsell" >'; |
| 1835 | 1893 | echo '<input type="hidden" id="sellkit_funnel_popup_step_id" value="0" >'; |
| 1836 | - echo '<input type="hidden" id="sellkit_product_prices" autocomplete="off" name="sellkit_product_prices" value="0" >'; | |
| 1894 | + echo '<input type="hidden" id="sellkit_upsell_ids" autocomplete="off" name="sellkit_upsell_ids" value="0" >'; | |
| 1837 | 1895 | } |
| 1838 | 1896 | |
| 1839 | 1897 | /** |
| 1840 | 1898 | * Checks if funnel includes upsell step. |
| @@ -2104,9 +2162,9 @@ | ||
| 2104 | 2162 | <tbody> |
| 2105 | 2163 | <?php foreach ( $products as $cart_item_key => $cart_item ) : ?> |
| 2106 | 2164 | <?php |
| 2107 | 2165 | if ( in_array( $cart_item_key, $this->in_cart, true ) ) { |
| 2108 | - continue; | |
| 2166 | + continue; | |
| 2109 | 2167 | } |
| 2110 | 2168 | |
| 2111 | 2169 | $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); |
| 2112 | 2170 | $default = $_product->get_id(); |
| @@ -2114,13 +2172,13 @@ | ||
| 2114 | 2172 | $unique_id = 'bundle-unique-id-' . $default; |
| 2115 | 2173 | $checked = ''; |
| 2116 | 2174 | |
| 2117 | 2175 | if ( 'checkbox' === $fields_type ) { |
| 2118 | - $checked = 'checked'; | |
| 2176 | + $checked = 'checked'; | |
| 2119 | 2177 | } |
| 2120 | 2178 | |
| 2121 | 2179 | if ( 'radio' === $fields_type && array_key_last( $products ) === $cart_item_key ) { |
| 2122 | - $checked = 'checked'; | |
| 2180 | + $checked = 'checked'; | |
| 2123 | 2181 | } |
| 2124 | 2182 | ?> |
| 2125 | 2183 | <tr class="sellkit-checkout-bundled-products-item"> |
| 2126 | 2184 | <td class="sellkit-checkout-bundled-title"> |