PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.3.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.3.0
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
← All changes | classes/class-cartflows-helper.php +76 -77 3.1.1 → 3.3.0 View file →
@@ -881,75 +881,8 @@
881 881 return self::$snapchat;
882 882 }
883 883
884 884 /**
885 - * Prepare response data for facebook.
886 - *
887 - * @todo Remove this function in 1.6.18 as it is added in cartflows-tracking file.
888 - * @param int $order_id order_id.
889 - * @param array $offer_data offer data.
890 - * @return void
891 - */
892 - public static function send_fb_response_if_enabled( $order_id, $offer_data = array() ) {
893 -
894 - _deprecated_function( __METHOD__, '1.6.15' );
895 -
896 - // Stop Execution if WooCommerce is not installed & don't set the cookie.
897 - if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
898 - return;
899 - }
900 -
901 - // @Since 1.6.15 It will only trigger offer purchase event.
902 - $fb_settings = self::get_facebook_settings();
903 - if ( 'enable' === $fb_settings['facebook_pixel_tracking'] ) {
904 - setcookie( 'wcf_order_details', wp_json_encode( self::prepare_purchase_data_fb_response( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/', COOKIE_DOMAIN, CARTFLOWS_HTTPS, true ); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.cookies_setcookie
905 - }
906 - }
907 -
908 - /**
909 - * Prepare purchase response for facebook purcase event.
910 - *
911 - * @todo Remove this function in 1.6.18 as it is added in cartflows-tracking file.
912 - *
913 - * @param integer $order_id order id.
914 - * @param array $offer_data offer data.
915 - * @return mixed
916 - */
917 - public static function prepare_purchase_data_fb_response( $order_id, $offer_data ) {
918 -
919 - _deprecated_function( __METHOD__, '1.6.15' );
920 -
921 - $purchase_data = array();
922 -
923 - if ( empty( $offer_data ) ) {
924 - return $purchase_data;
925 - }
926 -
927 - if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
928 - return $purchase_data;
929 - }
930 -
931 - $order = wc_get_order( $order_id );
932 -
933 - if ( ! $order ) {
934 - return $purchase_data;
935 - }
936 -
937 - $purchase_data['content_type'] = 'product';
938 - $purchase_data['currency'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_currency' );
939 - $purchase_data['userAgent'] = wcf()->options->get_checkout_meta_value( $order_id, '_customer_user_agent' );
940 - $purchase_data['plugin'] = 'CartFlows-Offer';
941 -
942 - $purchase_data['content_ids'][] = (string) $offer_data['id'];
943 - $purchase_data['content_names'][] = $offer_data['name'];
944 - $purchase_data['content_category'][] = wp_strip_all_tags( wc_get_product_category_list( $offer_data['id'] ) );
945 - $purchase_data['value'] = $offer_data['total'];
946 - $purchase_data['transaction_id'] = $order_id;
947 -
948 - return $purchase_data;
949 - }
950 -
951 - /**
952 885 * Get the image url of size.
953 886 *
954 887 * @param int $post_id post id.
955 888 * @param array $key key.
@@ -1223,8 +1156,19 @@
1223 1156
1224 1157 $product = wc_get_product( $product_id );
1225 1158 }
1226 1159
1160 + if ( $product && $product->is_type( 'bundle' ) && method_exists( $product, 'get_bundle_price' ) ) {
1161 + /*
1162 + * A bundle's own price is only its container base price, which is 0 or empty as soon
1163 + * as the bundled items are priced individually — leaving the step showing just a
1164 + * currency symbol. Use the bundle's minimum price instead: the "from" price the
1165 + * customer would pay, mirroring how a variable product resolves to a variation price
1166 + * above. Kept scalar because callers run discount maths on this value.
1167 + */
1168 + return $product->get_bundle_price( 'min', false );
1169 + }
1170 +
1227 1171 if ( $product ) {
1228 1172 $custom_price = $product->get_price( 'edit' );
1229 1173 }
1230 1174
@@ -1747,27 +1691,48 @@
1747 1691 return apply_filters( 'cartflows_show_store_checkout_product_tab', false );
1748 1692 }
1749 1693
1750 1694 /**
1751 - * Function get the CartFlows upgrade to PRO link.
1695 + * Common UTM defaults shared across PHP and JS — single source of truth.
1752 1696 *
1753 - * @param string $page The page name which needs to be displayed.
1754 - * @param string $custom_url The Another URL if wish to send.
1755 - * @return string $url The modified URL.
1697 + * @return array<string,string>
1756 1698 */
1757 - public static function get_upgrade_to_pro_link( $page = 'cartflows-pricing-plans', $custom_url = '' ) {
1699 + public static function get_utm_defaults() {
1700 + return array(
1701 + 'source' => 'dashboard',
1702 + 'medium' => 'free-cartflows',
1703 + );
1704 + }
1758 1705
1759 - $base_url = CARTFLOWS_DOMAIN_URL . $page . '/';
1760 - $url = empty( $custom_url ) ? $base_url : esc_url( $custom_url );
1706 + /**
1707 + * Build a cartflows.com URL with the common UTM parameters appended.
1708 + * Single source of truth for utm_source and utm_medium defaults.
1709 + *
1710 + * @param string $base_url Destination URL.
1711 + * @param array<string,string> $args Optional UTM overrides (utm_source, utm_medium, utm_campaign, utm_content, utm_term).
1712 + * @return string The final URL — UTM-stamped, partner-aware, BSF-referer-aware.
1713 + */
1714 + public static function get_utm_url( $base_url, $args = array() ) {
1761 1715
1762 1716 $partner_id = get_option( 'cartflows_partner_url_param', '' );
1763 1717 $partner_id = is_string( $partner_id ) ? sanitize_text_field( $partner_id ) : '';
1764 1718
1765 1719 if ( ! empty( $partner_id ) ) {
1766 - return add_query_arg( array( 'cf' => $partner_id ), $url );
1720 + return esc_url( add_query_arg( array( 'cf' => $partner_id ), $base_url ) );
1767 1721 }
1768 1722
1769 - // Modify the utm_source parameter using the UTM ready link function to include tracking information.
1723 + $defaults = self::get_utm_defaults();
1724 + $utm_args = wp_parse_args(
1725 + $args,
1726 + array(
1727 + 'utm_source' => $defaults['source'],
1728 + 'utm_medium' => $defaults['medium'],
1729 + )
1730 + );
1731 +
1732 + $url = add_query_arg( $utm_args, $base_url );
1733 +
1734 + // BSF analytics overrides utm_source when a cross-product referer is set; no-op otherwise.
1770 1735 if ( class_exists( '\BSF_UTM_Analytics' ) && is_callable( '\BSF_UTM_Analytics::get_utm_ready_link' ) ) {
1771 1736 $url = \BSF_UTM_Analytics::get_utm_ready_link( $url, 'cartflows' );
1772 1737 }
1773 1738
@@ -1774,8 +1739,42 @@
1774 1739 return esc_url( $url );
1775 1740 }
1776 1741
1777 1742 /**
1743 + * Build a CartFlows upgrade-to-pro / pricing URL with UTM params.
1744 + * Thin wrapper around get_utm_url() with utm_campaign defaulted to 'go-pro'.
1745 + *
1746 + * @param string $page Page slug appended to the domain (used when $custom_url is empty).
1747 + * @param string $custom_url Optional full URL to use instead of building from $page.
1748 + * @param array<string,string> $args Optional UTM overrides.
1749 + * @return string The modified URL.
1750 + */
1751 + public static function get_upgrade_to_pro_link( $page = 'pricing', $custom_url = '', $args = array() ) {
1752 +
1753 + $base_url = CARTFLOWS_DOMAIN_URL . $page . '/';
1754 + $url = empty( $custom_url ) ? $base_url : $custom_url;
1755 +
1756 + $args = wp_parse_args( $args, array( 'utm_campaign' => 'go-pro' ) );
1757 +
1758 + return self::get_utm_url( $url, $args );
1759 + }
1760 +
1761 + /**
1762 + * Build a CartFlows knowledgebase / docs URL with UTM params.
1763 + * Thin wrapper around get_utm_url() with utm_campaign defaulted to 'docs'.
1764 + *
1765 + * @param string $base_url Destination docs URL.
1766 + * @param array<string,string> $args Optional UTM overrides.
1767 + * @return string The modified URL.
1768 + */
1769 + public static function get_kb_doc_link( $base_url, $args = array() ) {
1770 +
1771 + $args = wp_parse_args( $args, array( 'utm_campaign' => 'docs' ) );
1772 +
1773 + return self::get_utm_url( $base_url, $args );
1774 + }
1775 +
1776 + /**
1778 1777 * Get current page's template
1779 1778 *
1780 1779 * @param int $post_id The current page id.
1781 1780 * @return string
@@ -1930,9 +1929,9 @@
1930 1929 *
1931 1930 * @return array<string> Allowed file extensions.
1932 1931 */
1933 1932 public static function get_allowed_file_extensions() {
1934 - return array( 'jpg', 'jpeg', 'png', 'gif', 'webp', 'ico', 'pdf', 'mp3', 'm4a', 'wav', 'mp4', 'm4v', 'mov' );
1933 + return array( 'jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf', 'mp3', 'm4a', 'wav', 'mp4', 'm4v', 'mov' );
1935 1934 }
1936 1935
1937 1936 /**
1938 1937 * Sanitize accepted file types input against the master allowlist.