PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.8.0
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.8.0
2.8.0 2.7.0 2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 All 44 releases
← All changes | includes/block-editor/blocks/checkout/helper.php +129 -71 2.6.0 → 2.8.0 View file →
@@ -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">