| @@ -1,17 +1,21 @@ | ||
| 1 | 1 | <?php |
| 2 | + | |
| 2 | 3 | /** |
| 3 | 4 | * Admin class |
| 4 | - * | |
| 5 | + * | |
| 5 | 6 | * @package |
| 6 | 7 | */ |
| 8 | + | |
| 7 | 9 | namespace WPFunnels\Admin; |
| 8 | 10 | |
| 11 | +use WPFunnels\Admin\BatchProcessing\BatchProcessingController; | |
| 12 | +use WPFunnels\Admin\Migrations\MigrationManager; | |
| 9 | 13 | use WPFunnels\Wpfnl; |
| 10 | 14 | use WPFunnels\Wpfnl_functions; |
| 11 | -use Wpfnl_Pro_GB_Functions; | |
| 12 | -use WPFunnels\Frontend\Wpfnl_Frontend; | |
| 15 | +use MRM\Common\MrmCommon; | |
| 13 | 16 | |
| 17 | + | |
| 14 | 18 | /** |
| 15 | 19 | * The admin-specific functionality of the plugin. |
| 16 | 20 | * |
| 17 | 21 | * @link https://rextheme.com |
| @@ -38,8 +42,23 @@ | ||
| 38 | 42 | */ |
| 39 | 43 | const WPFNL_FEED_OPTION_KEY = 'wpfnl_remote_info_feed_data'; |
| 40 | 44 | |
| 41 | 45 | /** |
| 46 | + * Plugin file of the free Mail Mint plugin, as wordpress.org ships it. | |
| 47 | + */ | |
| 48 | + const MAIL_MINT_BASENAME = 'mail-mint/mail-mint.php'; | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * Plugin file of Mail Mint Pro. | |
| 52 | + */ | |
| 53 | + const MAIL_MINT_PRO_BASENAME = 'mail-mint-pro/mail-mint-pro.php'; | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Plugin file of WPFunnels Pro. | |
| 57 | + */ | |
| 58 | + const WPFNL_PRO_BASENAME = 'wpfunnels-pro/wpfnl-pro.php'; | |
| 59 | + | |
| 60 | + /** | |
| 42 | 61 | * The ID of this plugin. |
| 43 | 62 | * |
| 44 | 63 | * @since 1.0.0 |
| 45 | 64 | * @access private |
| @@ -60,20 +79,32 @@ | ||
| 60 | 79 | private $dependency_plugins; |
| 61 | 80 | |
| 62 | 81 | |
| 63 | 82 | /** |
| 64 | - * Page hooks | |
| 83 | + * Screens still rendered by the legacy PHP/Vue admin, which is what the | |
| 84 | + * legacy stylesheet and bundle are written against. | |
| 65 | 85 | * |
| 86 | + * NOTE: 'toplevel_page_wpfunnels' is deliberately absent. That screen is the | |
| 87 | + * React admin, which ships its own namespaced bundle and must not inherit | |
| 88 | + * the legacy admin CSS. The funnel list, its trash tab and the Templates | |
| 89 | + * page are routes of that same app now, so their hooks are gone from here | |
| 90 | + * too. | |
| 91 | + * | |
| 66 | 92 | * @var array |
| 67 | 93 | */ |
| 68 | 94 | private $page_hooks = [ |
| 69 | - 'toplevel_page_wp_funnels', | |
| 70 | - 'wp-funnels_page_wp_funnel_settings', | |
| 71 | - 'wp-funnels_page_edit_funnel', | |
| 72 | - 'wp-funnels_page_create_funnel', | |
| 73 | - 'wp-funnels_page_wpfnl_settings', | |
| 74 | - 'wp-funnels_page_wpf-license', | |
| 75 | - 'wp-funnels_page_email-builder', | |
| 95 | + 'wpfunnels_page_wpf_feature_comparison', | |
| 96 | + 'wpfunnels_page_wp_funnel_settings', | |
| 97 | + 'wpfunnels_page_wpfnl_settings', | |
| 98 | + 'wpfunnels_page_wp_global_store', | |
| 99 | + 'wpfunnels_page_edit_funnel', | |
| 100 | + 'wpfunnels_page_create_funnel', | |
| 101 | + 'wpfunnels_page_wpfnl_automations', | |
| 102 | + 'wpfunnels_page_wpfnl_addons', | |
| 103 | + 'wpfunnels_page_store_checkout', | |
| 104 | + 'wpfunnels_page_wpfunnels_integrations', | |
| 105 | + 'wpfunnels_page_wpf-license', | |
| 106 | + 'wpfunnels_page_email-builder', | |
| 76 | 107 | ]; |
| 77 | 108 | |
| 78 | 109 | /** |
| 79 | 110 | * Initialize the class and set its properties. |
| @@ -79,9 +110,9 @@ | ||
| 79 | 110 | * Initialize the class and set its properties. |
| 80 | 111 | * |
| 81 | 112 | * @param string $plugin_name The name of this plugin. |
| 82 | 113 | * @param string $version The version of this plugin. |
| 83 | - * | |
| 114 | + * | |
| 84 | 115 | * @since 1.0.0 |
| 85 | 116 | */ |
| 86 | 117 | public function __construct($plugin_name, $version) |
| 87 | 118 | { |
| @@ -86,31 +117,77 @@ | ||
| 86 | 117 | public function __construct($plugin_name, $version) |
| 87 | 118 | { |
| 88 | 119 | $this->plugin_name = $plugin_name; |
| 89 | 120 | $this->version = $version; |
| 90 | - | |
| 91 | - add_action( 'admin_enqueue_scripts', [$this, 'enqueue_styles'] ); | |
| 92 | - add_action( 'admin_enqueue_scripts', [$this, 'enqueue_scripts'] ); | |
| 93 | - add_filter( 'plugin_action_links_' . WPFNL_BASE, [$this, 'add_funnel_action_links'] ); | |
| 94 | - add_filter( 'locale', array($this, 'change_local_for_funnel_canvas') ); | |
| 95 | - if( is_admin() ) { | |
| 96 | - add_filter( 'wp_dropdown_pages', array( $this, 'show_funnel_steps_on_reading' ) ); | |
| 97 | - add_filter( 'gettext', [$this,'wpfnl_customizing_checkout_text'], 10, 3 ); | |
| 98 | - add_action( 'admin_init', [$this,'wpfnl_add_type_meta'] ); | |
| 99 | - add_action( 'deactivated_plugin', [$this, 'wpfnl_deactivated_plugin'] ); | |
| 100 | - add_action( 'activated_plugin', [$this, 'wpfnl_activated_plugin'] ); | |
| 101 | 121 | |
| 122 | + add_action('admin_enqueue_scripts', [$this, 'enqueue_styles']); | |
| 123 | + add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']); | |
| 124 | + add_filter('plugin_action_links_' . WPFNL_BASE, [$this, 'add_funnel_action_links']); | |
| 125 | + add_filter('locale', array($this, 'change_local_for_funnel_canvas')); | |
| 126 | + if (is_admin()) { | |
| 127 | + add_filter('admin_body_class', [$this, 'add_wpfunnels_admin_body_class']); | |
| 128 | + add_filter('wp_dropdown_pages', array($this, 'show_funnel_steps_on_reading')); | |
| 129 | + add_filter('gettext', [$this, 'wpfnl_customizing_checkout_text'], 10, 3); | |
| 130 | + add_action('admin_init', [$this, 'wpfnl_add_type_meta']); | |
| 131 | + add_action('admin_init', array($this, 'init_actions')); | |
| 132 | + add_action('deactivated_plugin', [$this, 'wpfnl_deactivated_plugin']); | |
| 133 | + add_action('activated_plugin', [$this, 'wpfnl_activated_plugin']); | |
| 134 | + | |
| 102 | 135 | // Register Dashboard Widgets. |
| 103 | - add_action( 'wp_dashboard_setup', [ $this, 'wpfnl_register_dashboard_widgets' ] ); | |
| 104 | - | |
| 136 | + add_action('wp_dashboard_setup', [$this, 'wpfnl_register_dashboard_widgets']); | |
| 137 | + | |
| 138 | + if (isset($_GET['page']) && 'edit_funnel' === $_GET['page']) { | |
| 139 | + wp_cache_flush(); | |
| 140 | + } | |
| 105 | 141 | } |
| 106 | 142 | |
| 107 | - add_action( 'admin_head', function() { | |
| 108 | - remove_submenu_page( WPFNL_MAIN_PAGE_SLUG, 'email-builder' ); | |
| 109 | - } ); | |
| 110 | - } | |
| 111 | - | |
| 143 | + add_action('admin_head', function () { | |
| 144 | + remove_submenu_page(WPFNL_MAIN_PAGE_SLUG, 'email-builder'); | |
| 145 | + }); | |
| 112 | 146 | |
| 147 | + | |
| 148 | + // Remove all admin notices from WPFunnels Dashboard | |
| 149 | + if ($this->is_current_page('wpfunnels')) { | |
| 150 | + remove_all_actions('admin_notices'); | |
| 151 | + } | |
| 152 | + | |
| 153 | + | |
| 154 | + /** | |
| 155 | + * @todo This piece of code will be removed after releasing 3.2.0. We need to introduced this because we have changed the funnel template creation strategy. | |
| 156 | + * | |
| 157 | + */ | |
| 158 | + add_action('admin_init', function () { | |
| 159 | + $current_version = get_option('wpfunnels_version'); | |
| 160 | + $is_already_synced = get_option('_is_wpfunnels_new_templates_synced', 'no'); | |
| 161 | + if (version_compare($current_version, '3.1.2', '>') && 'yes' != $is_already_synced) { | |
| 162 | + delete_option(WPFNL_TEMPLATES_OPTION_KEY . '_wc'); | |
| 163 | + delete_option(WPFNL_TEMPLATES_OPTION_KEY . '_lms'); | |
| 164 | + delete_transient('wpfunnels_remote_template_data_wc_' . WPFNL_VERSION); | |
| 165 | + delete_transient('wpfunnels_remote_template_data_lms_' . WPFNL_VERSION); | |
| 166 | + delete_transient('wpfunnels_remote_template_data_lead_' . WPFNL_VERSION); | |
| 167 | + delete_transient('wpfunnels_remote_template_data_store_checkout_' . WPFNL_VERSION); | |
| 168 | + update_option('_is_wpfunnels_new_templates_synced', 'yes'); | |
| 169 | + } | |
| 170 | + }); | |
| 171 | + | |
| 172 | + add_action('admin_init', array($this, 'attach_admin_capabilities')); | |
| 173 | + | |
| 174 | + add_action('wpfunnels_tracker_optin', array($this, 'wpfunnels_tracker_optin'), 10); | |
| 175 | + add_action('mint_before_sending_sms', array($this, 'create_mrm_contact'), 10); | |
| 176 | + } | |
| 177 | + | |
| 178 | + | |
| 179 | + public function init_actions() | |
| 180 | + { | |
| 181 | + $batch_processor = new BatchProcessingController(); | |
| 182 | + new MigrationManager($batch_processor); | |
| 183 | + | |
| 184 | + | |
| 185 | + // Run stat status sync migration directly (independent of Action Scheduler). | |
| 186 | + $stat_sync = new \WPFunnels\Admin\Migrations\StatStatusSyncMigration(); | |
| 187 | + $stat_sync->run(); | |
| 188 | + } | |
| 189 | + | |
| 113 | 190 | /** |
| 114 | 191 | * Register dashboard widgets. |
| 115 | 192 | * |
| 116 | 193 | * Adds a new WPFunnels widgets to WordPress dashboard. |
| @@ -118,10 +195,11 @@ | ||
| 118 | 195 | * Fired by `wp_dashboard_setup` action. |
| 119 | 196 | * |
| 120 | 197 | * @since 2.6.2 |
| 121 | 198 | */ |
| 122 | - public function wpfnl_register_dashboard_widgets() { | |
| 123 | - wp_add_dashboard_widget( 'wpfnl-dashboard-overview', esc_html__( 'WPFunnels Overview', 'wpfnl' ), [ $this, 'wpfnl_dashboard_overview_widget' ] ); | |
| 199 | + public function wpfnl_register_dashboard_widgets() | |
| 200 | + { | |
| 201 | + wp_add_dashboard_widget('wpfnl-dashboard-overview', esc_html__('WPFunnels Overview', 'wpfnl'), [$this, 'wpfnl_dashboard_overview_widget']); | |
| 124 | 202 | global $wp_meta_boxes; |
| 125 | 203 | |
| 126 | 204 | $dashboard = $wp_meta_boxes['dashboard']['normal']['core']; |
| 127 | 205 | $ours = [ |
| @@ -127,25 +205,39 @@ | ||
| 127 | 205 | $ours = [ |
| 128 | 206 | 'wpfnl-dashboard-overview' => $dashboard['wpfnl-dashboard-overview'], |
| 129 | 207 | ]; |
| 130 | 208 | |
| 131 | - $wp_meta_boxes['dashboard']['normal']['core'] = array_merge( $ours, $dashboard ); | |
| 209 | + $wp_meta_boxes['dashboard']['normal']['core'] = array_merge($ours, $dashboard); | |
| 132 | 210 | } |
| 133 | 211 | |
| 134 | 212 | |
| 135 | 213 | /** |
| 136 | - * Ppfunnels dashboard widget. | |
| 214 | + * WPFunnels dashboard widget. | |
| 137 | 215 | * |
| 138 | 216 | * Displays the wpfunnels dashboard widget. |
| 139 | - * | |
| 217 | + * | |
| 140 | 218 | * @since 2.6.2 |
| 141 | 219 | */ |
| 142 | - public function wpfnl_dashboard_overview_widget() { | |
| 143 | - $create_new_label = __( 'Create New Funnel', 'wpfnl' ); | |
| 220 | + public function wpfnl_dashboard_overview_widget() | |
| 221 | + { | |
| 222 | + $upgrade_to_pro = __('Upgrade to Pro', 'wpfnl'); | |
| 223 | + $install_activate = __('Install & Activate', 'wpfnl'); | |
| 224 | + $is_mail_mint_active = WPFnl_functions::is_mail_mint_free_active(); | |
| 144 | 225 | |
| 145 | 226 | $response = $this->get_wpfnl_feed_data(); |
| 146 | - | |
| 147 | - ?> | |
| 227 | + | |
| 228 | + $icons = [ | |
| 229 | + 'Total Orders' => '<svg width="16" height="17" fill="none" viewBox="0 0 16 17" xmlns="http://www.w3.org/2000/svg"><path fill="#B7A6E9" d="M12.061 8.04a4.015 4.015 0 01-3.478-6.03h-5.74l-.029-.236A2.01 2.01 0 00.82 0H.67a.67.67 0 000 1.34h.15a.67.67 0 01.665.592l.922 7.84a3.35 3.35 0 003.328 2.96h6.997a.67.67 0 000-1.341H5.734a2.01 2.01 0 01-1.89-1.34h7.987a3.35 3.35 0 003.298-2.756l.16-.884a4.01 4.01 0 01-3.228 1.63z"/><path fill="#B7A6E9" d="M10.542 5.994a1.254 1.254 0 00.901.402h.023a1.255 1.255 0 00.894-.37l2.863-2.863a.672.672 0 10-.95-.952l-2.806 2.81-.827-.887a.67.67 0 00-.98.915l.882.945zM4.69 16.082a1.34 1.34 0 100-2.68 1.34 1.34 0 000 2.68zm6.701 0a1.34 1.34 0 100-2.68 1.34 1.34 0 000 2.68z"/></svg>', | |
| 230 | + 'Total Revenue' => '<svg width="15" height="15" fill="none" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg"><path fill="#B7A6E9" d="M9.75 15h-4.5C1.5 15 0 13.5 0 9.75v-4.5C0 1.5 1.5 0 5.25 0h4.5C13.5 0 15 1.5 15 5.25v4.5C15 13.5 13.5 15 9.75 15z"/><path fill="#B7A6E9" d="M5.004 9.247c0 .968.742 1.748 1.665 1.748H8.55c.803 0 1.455-.683 1.455-1.523 0-.915-.397-1.237-.99-1.447l-3.022-1.05c-.593-.21-.99-.533-.99-1.448 0-.84.652-1.522 1.455-1.522H8.34c.923 0 1.665.78 1.665 1.747"/><path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" d="M5.004 9.247c0 .968.742 1.748 1.665 1.748H8.55c.803 0 1.455-.683 1.455-1.523 0-.915-.397-1.237-.99-1.447l-3.022-1.05c-.593-.21-.99-.533-.99-1.448 0-.84.652-1.522 1.455-1.522H8.34c.923 0 1.665.78 1.665 1.747"/><path fill="#B7A6E9" d="M7.5 3v9-9z"/><path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" d="M7.5 3v9"/></svg>', | |
| 231 | + 'Order Bump Revenue' => '<svg width="15" height="15" fill="none" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg"><path stroke="#B7A6E9" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.5" d="M5.376 1L3.05 3.333M9.475 1l2.327 2.333"/><path fill="#fff" stroke="#B7A6E9" stroke-width="1.5" d="M1 4.76c0-1.19.636-1.286 1.427-1.286h10c.791 0 1.428.097 1.428 1.286 0 1.382-.637 1.285-1.427 1.285H2.427C1.637 6.045 1 6.142 1 4.76z"/><path fill="#B7A6E9" d="M3.273 13.064L1.79 5.944h10.975l-.89 6.526c0 .712-1.582 1.286-2.373 1.484H5.35c-.237.237-1.483-.495-2.076-.89z"/><path stroke="#B7A6E9" stroke-linecap="round" stroke-width="1.5" d="M1.964 6.142l.906 5.553c.206 1.247.7 2.16 2.54 2.16h3.875c1.999 0 2.294-.874 2.526-2.082l1.08-5.63"/><path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" d="M8.91 9.504L7.425 8.021 5.943 9.504M7.426 8.02v3.56"/></svg>', | |
| 232 | + 'Upsell/Downsell Revenue' => '<svg width="15" height="15" fill="none" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg"><path fill="#B7A6E9" d="M5.25 15h4.5C13.5 15 15 13.5 15 9.75v-4.5C15 1.5 13.5 0 9.75 0h-4.5C1.5 0 0 1.5 0 5.25v4.5C0 13.5 1.5 15 5.25 15z"/><path fill="#B7A6E9" d="M6.379 5.25h3.37v3.371"/><path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M6.379 5.25h3.37v3.371M9.75 5.25l-4.5 4.5"/></svg>', | |
| 233 | + 'Total Leads' => '<svg width="13" height="13" fill="none" viewBox="0 0 13 13" xmlns="http://www.w3.org/2000/svg"><path fill="#B7A6E9" d="M8.45 0h-3.9C1.3 0 0 1.3 0 4.55v3.9c0 2.457.741 3.803 2.509 4.303.143-1.69 1.879-3.023 3.991-3.023 2.113 0 3.848 1.333 3.991 3.023C12.259 12.253 13 10.907 13 8.45v-3.9C13 1.3 11.7 0 8.45 0zM6.5 7.91a2.33 2.33 0 010-4.66 2.33 2.33 0 010 4.66z"/></svg>', | |
| 234 | + ]; | |
| 235 | + | |
| 236 | + | |
| 237 | + $pro_icon_svg = '<div class="pro-icon"><svg width="14" height="14" fill="none" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><circle cx="7" cy="7" r="7" fill="#66CB64"/><path fill="#fff" fill-rule="evenodd" d="M7.623 4.465a.69.69 0 00-1.15 0l-1.36 2.08-1.04-.59c-.52-.294-1.146.168-1.005.743l.706 2.88c.032.13.15.222.285.222h5.977a.292.292 0 00.285-.221l.706-2.88c.141-.576-.485-1.038-1.005-.743l-1.04.588-1.36-2.08zm-.493.312a.098.098 0 00-.165 0l-1.51 2.311a.296.296 0 01-.393.094l-1.28-.725a.097.097 0 00-.144.106l.652 2.659h5.515l.652-2.66a.096.096 0 00-.143-.105l-1.281.725a.296.296 0 01-.393-.094l-1.51-2.31z" clip-rule="evenodd"/><path fill="#fff" d="M4.312 10.377a.291.291 0 00-.293.29.29.29 0 00.293.288h5.472c.161 0 .293-.13.293-.289a.291.291 0 00-.293-.289H4.312z"/><circle cx="10.739" cy="4.987" r=".514" fill="#fff"/><circle cx="3.139" cy="4.987" r=".514" fill="#fff"/><circle cx="7.042" cy="3.139" r=".514" fill="#fff"/><path fill="#fff" d="M9.918 9.404h-5.65L3.241 6.22l1.952.616 1.849-2.465L8.993 6.94l1.746-.822-.821 3.287z"/></svg></div>'; | |
| 238 | + | |
| 239 | +?> | |
| 148 | 240 | <div class="wpfnl-dashboard-widget"> |
| 149 | 241 | <div class="wpfnl-overview__header"> |
| 150 | 242 | <div class="wpfnl-overview__logo"> |
| 151 | 243 | <div class="wpfnl-logo-wrapper"> |
| @@ -150,88 +242,349 @@ | ||
| 150 | 242 | <div class="wpfnl-overview__logo"> |
| 151 | 243 | <div class="wpfnl-logo-wrapper"> |
| 152 | 244 | <svg width="38" height="28" viewBox="0 0 38 28" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 153 | 245 | <path d="M7.01532 18H31.9847L34 11H5L7.01532 18Z" fill="#EE8134"></path> |
| 154 | - <path d="M11.9621 27.2975C12.0923 27.7154 12.4792 28 12.9169 28H26.0831C26.5208 28 26.9077 27.7154 27.0379 27.2975L29 21H10L11.9621 27.2975Z" fill="#6E42D3"></path> | |
| 155 | - <path d="M37.8161 0.65986C37.61 0.247888 37.2609 0 36.8867 0H1.11326C0.739128 0 0.390003 0.247888 0.183972 0.65986C-0.0220592 1.07193 -0.0573873 1.59277 0.0898627 2.04655L1.69781 7H36.3022L37.9102 2.04655C38.0574 1.59287 38.022 1.07193 37.8161 0.65986Z" fill="#6E42D3"></path> | |
| 246 | + <path | |
| 247 | + d="M11.9621 27.2975C12.0923 27.7154 12.4792 28 12.9169 28H26.0831C26.5208 28 26.9077 27.7154 27.0379 27.2975L29 21H10L11.9621 27.2975Z" | |
| 248 | + fill="#6E42D3"></path> | |
| 249 | + <path | |
| 250 | + d="M37.8161 0.65986C37.61 0.247888 37.2609 0 36.8867 0H1.11326C0.739128 0 0.390003 0.247888 0.183972 0.65986C-0.0220592 1.07193 -0.0573873 1.59277 0.0898627 2.04655L1.69781 7H36.3022L37.9102 2.04655C38.0574 1.59287 38.022 1.07193 37.8161 0.65986Z" | |
| 251 | + fill="#6E42D3"></path> | |
| 156 | 252 | </svg> |
| 157 | 253 | </div> |
| 158 | 254 | </div> |
| 159 | 255 | |
| 160 | - <div class="wpfnl-overview__versions"> | |
| 161 | - <span class="wpfnl-overview__version"><?php echo __( 'WPFunnels', 'wpfnl' ); ?> v<?php echo WPFNL_VERSION;?></span> | |
| 162 | - <?php if( Wpfnl_functions::is_pro_license_activated() ) { ?> | |
| 163 | - <span class="wpfnl-overview__version"><?php echo __( 'WPFunnels Pro', 'wpfnl' ); ?> v<?php echo WPFNL_PRO_VERSION;?></span> | |
| 164 | - <?php } ?> | |
| 256 | + <div class="wpfnl-overview__upgrade"> | |
| 257 | + <span><?php echo !Wpfnl_functions::is_pro_license_activated() ? __('Upgrade to Pro to get premium features such as one-click upsells, A/B testing and more!', 'wpfnl') : __('Start creating high converting landing pages, sales funnels, and checkout flows in minutes!', 'wpfnl'); ?></span> | |
| 165 | 258 | </div> |
| 166 | 259 | |
| 167 | - <div class="wpfnl-overview__create"> | |
| 168 | - <a href="<?php echo admin_url('admin.php?page=wp_funnels') ?>" target="_blank" class="button"><span aria-hidden="true" class="dashicons dashicons-plus"></span> <?php echo esc_html( $create_new_label ); ?></a> | |
| 169 | - </div> | |
| 170 | - | |
| 260 | + <?php if (!Wpfnl_functions::is_pro_license_activated()) { ?> | |
| 261 | + <div class="wpfnl-overview__create"> | |
| 262 | + <a href="https://getwpfunnels.com/pricing/" target="_blank" class="button"><span aria-hidden="true"></span> | |
| 263 | + <?php echo esc_html($upgrade_to_pro); ?></a> | |
| 264 | + </div> | |
| 265 | + <?php | |
| 266 | + }?> | |
| 267 | + | |
| 171 | 268 | </div> |
| 172 | - <?php if ( !is_wp_error( $response ) && !empty( $response ) ) : ?> | |
| 173 | - <div class="wpfnl-overview__recently-edited"> | |
| 174 | - <h3 class="wpfnl-heading wpfnl-divider_bottom"><?php echo __( 'News & Updates', 'wpfnl' ); ?></h3> | |
| 175 | - <ul class="wpfnl-overview__posts"> | |
| 269 | + | |
| 270 | + <!-- overview report --> | |
| 271 | + <div class="wpfnl-overview__report"> | |
| 272 | + <?php foreach ($response as $report): | |
| 273 | + $icon_html = $icons[$report['title']] ?? ''; | |
| 274 | +?> | |
| 275 | + <div class="report-item"> | |
| 276 | + <div class="icon"><?php echo $icon_html; ?></div> | |
| 277 | + <div class="text-wrapper"> | |
| 278 | + <p class="title"><?php echo esc_html($report['title']); ?></p> | |
| 279 | + <p class="amount"><?php echo $report['amount']; ?></p> | |
| 280 | + </div> | |
| 281 | + | |
| 282 | + <?php if ($report['show_pro'] && !Wpfnl_functions::is_pro_license_activated()): ?> | |
| 283 | + <?php echo $pro_icon_svg; ?> | |
| 176 | 284 | <?php |
| 177 | - foreach ( $response as $data ) : | |
| 178 | - ?> | |
| 179 | - <li class="wpfnl-overview__post"> | |
| 180 | - <a href="<?php echo esc_url( $data['link'] ); ?>" class="wpfnl-overview__post-link" target="_blank"> | |
| 181 | - <?php echo esc_html($data['title']['rendered']); ?> | |
| 182 | - </a> | |
| 183 | - <p class="wpfnl-overview__post-description"> | |
| 184 | - <?php | |
| 185 | - $text = explode(' ',strip_tags($data['content']['rendered']) ); | |
| 186 | - if (sizeof($text)>100) $text = array_slice($text,0,70); | |
| 187 | - echo implode(' ',$text).'.....'; | |
| 188 | - ?> | |
| 189 | - </p> | |
| 190 | - </li> | |
| 191 | - <?php endforeach; ?> | |
| 192 | - </ul> | |
| 285 | + endif; ?> | |
| 286 | + | |
| 287 | + </div> | |
| 288 | + <?php | |
| 289 | + endforeach; ?> | |
| 290 | + </div> | |
| 291 | + | |
| 292 | + <?php if (!Wpfnl_functions::is_mint_mrm_active()): ?> | |
| 293 | + <!-- install mail mint --> | |
| 294 | + <div | |
| 295 | + class="wpfnl-overview__mailmint <?php echo Wpfnl_functions::is_mint_mrm_active() ? 'is-active' : 'is-disabled'; ?>"> | |
| 296 | + <div class="icon-wrapper"> | |
| 297 | + <div class="icon"> | |
| 298 | + <svg width="34" height="34" fill="none" viewBox="0 0 34 34" xmlns="http://www.w3.org/2000/svg"> | |
| 299 | + <circle cx="17" cy="17" r="16.5" fill="#fff" stroke="#573BFF" /> | |
| 300 | + <path fill="#573BFF" | |
| 301 | + d="M24.084 14.876l-.634 8.778.905-1.267.996-10.225-9.23 6.153-2.082-2.172-5.972-5.067 7.601 8.868c.272.271.634.362.996.09l7.42-5.158z" /> | |
| 302 | + <path fill="#02C4FB" | |
| 303 | + d="M21.822 11.62c-3.891.814-7.24.904-8.416.814l.995 1.086c4.525-.272 6.697-.905 7.24-1.267.362-.272.271-.543.18-.634z" /> | |
| 304 | + <path fill="#573BFF" | |
| 305 | + d="M20.374 13.61c-2.444.724-4.525.905-5.249.905l.724.633c2.805-.362 4.163-.905 4.434-1.176.272-.181.181-.362.09-.362z" /> | |
| 306 | + <path fill="#573BFF" | |
| 307 | + d="M25.947 11.345c-.212-.033-.418.064-.596.184l-9.05 6.153-4.162-4.525-.749-.793-.79-.835c1.72.18 8.778-.09 12.67-.996 1.81-.452 1.447-1.267 1.266-1.176-8.415 1.176-15.745.452-15.745.452-.403-.034-.617.066-.815.362-.18.272-.09.634.09.905l.453.453 2.082 2.08 5.158 5.43c.271.272.633.272.995.09l8.054-5.52c-.453 4.073-.996 8.145-1.267 9.14-1.81.363-12.397.453-13.845.091-.453-.724-.996-4.253-1.358-7.963-.09-.543-.633-.905-1.176-.634 0 0-.362.177-.362.724.905 8.597 1.81 9.05 2.081 9.23.543.272 4.163.453 7.873.453s7.33-.181 7.873-.634c.18-.18.814-.723 1.9-11.401v-.091c.074-.736-.152-1.113-.58-1.18z" /> | |
| 308 | + <path fill="url(#paint0_linear_129_34)" d="M8.474 11.538h2.135l1.687 1.79H9.984l-1.51-1.79z" /> | |
| 309 | + <defs> | |
| 310 | + <linearGradient id="paint0_linear_129_34" x1="9.613" x2="10.654" y1="11.538" y2="13.37" | |
| 311 | + gradientUnits="userSpaceOnUse"> | |
| 312 | + <stop stop-color="#0C0632" /> | |
| 313 | + <stop offset="1" stop-color="#573BFF" /> | |
| 314 | + </linearGradient> | |
| 315 | + </defs> | |
| 316 | + </svg> | |
| 317 | + </div> | |
| 318 | + <div class="text-wrapper"> | |
| 319 | + <p class="description"> | |
| 320 | + <?php echo $is_mail_mint_active ? __('Use email marketing automation for your funnels easily with <b>Mail Mint</b>!', 'wpfnl') : __('Use email marketing automation for your funnels easily with <b>Mail Mint</b>!', 'wpfnl'); ?> | |
| 321 | + </p> | |
| 322 | + </div> | |
| 323 | + </div> | |
| 324 | + <div class="wpfnl-overview__install-mailmint"> | |
| 325 | + <?php if (Wpfnl_functions::is_mail_mint_free_active()): ?> | |
| 326 | + <a href="https://getwpfunnels.com/pricing/#mail-mint" target="_blank" class="button"> | |
| 327 | + <?php echo $upgrade_to_pro; ?> | |
| 328 | + </a> | |
| 329 | + <?php | |
| 330 | + else: ?> | |
| 331 | + <button id="pro-modal-dropdown-btn" class="button"> | |
| 332 | + <span class="loader" style="display:none;"></span> | |
| 333 | + <span class="btn-text"><?php echo $install_activate; ?></span> | |
| 334 | + </button> | |
| 335 | + <?php | |
| 336 | + endif; ?> | |
| 337 | + </div> | |
| 338 | + | |
| 193 | 339 | </div> |
| 194 | - <?php endif; ?> | |
| 195 | - | |
| 196 | - | |
| 340 | + <?php | |
| 341 | + endif; ?> | |
| 342 | + | |
| 197 | 343 | <div class="wpfnl-overview__footer wpfnl-divider_top"> |
| 198 | 344 | <ul> |
| 199 | - <?php foreach ( $this->get_wpfunnels_dashboard_overview_widget_footer_actions() as $action_id => $action ) : ?> | |
| 200 | - <li class="wpfnl-overview__<?php echo esc_attr( $action_id ); ?>"><a href="<?php echo esc_attr( $action['link'] ); ?>" target="_blank"><?php echo esc_html( $action['title'] ); ?> <span class="screen-reader-text"><?php echo esc_html__( '(opens in a new window)', 'wpfnl' ); ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></li> | |
| 201 | - <?php endforeach; ?> | |
| 345 | + <?php foreach ($this->get_wpfunnels_dashboard_overview_widget_footer_actions() as $action_id => $action): ?> | |
| 346 | + <li class="wpfnl-overview__<?php echo esc_attr($action_id); ?>"><a | |
| 347 | + href="<?php echo esc_attr($action['link']); ?>" | |
| 348 | + target="_blank"><?php echo esc_html($action['title']); ?> <span | |
| 349 | + class="screen-reader-text"><?php echo esc_html__('(opens in a new window)', 'wpfnl'); ?></span></a> | |
| 350 | + </li> | |
| 351 | + <?php | |
| 352 | + endforeach; ?> | |
| 202 | 353 | </ul> |
| 203 | 354 | </div> |
| 204 | 355 | |
| 356 | + <script> | |
| 357 | + (function ($) { | |
| 358 | + | |
| 359 | + const apiService = (path = "", method = "GET", data, content_type = "text/plain") => { | |
| 360 | + return new Promise((resolve, reject) => { | |
| 361 | + jQuery.ajax({ | |
| 362 | + url: wpApiSettings.root + path, | |
| 363 | + type: method, | |
| 364 | + data: data, | |
| 365 | + beforeSend: function (xhr) { | |
| 366 | + xhr.setRequestHeader("X-WP-Nonce", wpApiSettings.nonce); | |
| 367 | + }, | |
| 368 | + dataType: "json", | |
| 369 | + contentType: content_type, | |
| 370 | + success: resolve, | |
| 371 | + error: reject | |
| 372 | + }); | |
| 373 | + }); | |
| 374 | + }; | |
| 375 | + | |
| 376 | + $(document).ready(function () { | |
| 377 | + jQuery("#pro-modal-dropdown-btn").click((e) => { | |
| 378 | + e.preventDefault(); | |
| 379 | + var btn = $('#pro-modal-dropdown-btn'); | |
| 380 | + var loader = btn.find('.loader'); | |
| 381 | + var btnText = btn.find('.btn-text'); | |
| 382 | + loader.show(); | |
| 383 | + btn.prop('disabled', true); | |
| 384 | + btnText.text('Processing...'); | |
| 385 | + apiService("wpfunnels/v1/activate-plugin", 'POST', JSON.stringify({ | |
| 386 | + basename: 'mail-mint/mail-mint.php', | |
| 387 | + slug: 'mail-mint', | |
| 388 | + }), 'application/json').then((res) => { | |
| 389 | + var upgradeBtn = $( | |
| 390 | + '<a href="https://getwpfunnels.com/pricing/#mail-mint" target="_blank" class="button" style="margin-left:0;">' + | |
| 391 | + 'Upgrade to Pro' + | |
| 392 | + '</a>' | |
| 393 | + ); | |
| 394 | + btn.closest('.wpfnl-overview__install-mailmint').html(upgradeBtn); | |
| 395 | + $('.text-wrapper .title').text('Get Mail Mint Pro'); | |
| 396 | + $('.text-wrapper .description').html('Use email marketing automation for your funnels easily with <b>Mail Mint</b>!'); | |
| 397 | + }).catch((e) => { | |
| 398 | + btn.replaceWith(btnPrevState); | |
| 399 | + addClickEvent(); | |
| 400 | + }) | |
| 401 | + }); | |
| 402 | + }); | |
| 403 | + })(jQuery); | |
| 404 | + </script> | |
| 405 | + | |
| 205 | 406 | <style> |
| 206 | - .wpfnl-dashboard-widget .wpfnl-overview__header { | |
| 207 | - display: table; | |
| 208 | - width: 100%; | |
| 209 | - -webkit-box-shadow: 0 5px 8px rgb(0 0 0 / 5%); | |
| 210 | - box-shadow: 0 5px 8px rgb(0 0 0 / 5%); | |
| 211 | - margin: 0 -12px 8px; | |
| 212 | - padding: 0 12px 12px; | |
| 407 | + .wpfnl-dashboard-widget { | |
| 408 | + margin-top: -11px; | |
| 213 | 409 | } |
| 214 | - .wpfnl-dashboard-widget .wpfnl-overview__logo { | |
| 215 | - width: 30px; | |
| 410 | + | |
| 411 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint { | |
| 412 | + display: flex; | |
| 413 | + align-items: center; | |
| 414 | + justify-content: space-between; | |
| 415 | + padding: 16px 20px; | |
| 416 | + border: 1px solid #EEEAF8; | |
| 417 | + margin-bottom: 15px; | |
| 216 | 418 | } |
| 217 | - .wpfnl-dashboard-widget .wpfnl-overview__logo, | |
| 218 | - .wpfnl-dashboard-widget .wpfnl-overview__versions, | |
| 219 | - .wpfnl-dashboard-widget .wpfnl-overview__create { | |
| 220 | - display: table-cell; | |
| 419 | + | |
| 420 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint.is-active .wpfnl-overview__install-mailmint button { | |
| 421 | + pointer-events: none; | |
| 422 | + cursor: not-allowed; | |
| 423 | + } | |
| 424 | + | |
| 425 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .icon-wrapper { | |
| 426 | + display: flex; | |
| 427 | + gap: 12px; | |
| 428 | + align-items: center; | |
| 429 | + } | |
| 430 | + | |
| 431 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .wpfnl-overview__install-mailmint .button { | |
| 432 | + border-radius: 7px; | |
| 433 | + background: #573BFF; | |
| 434 | + color: #FFF; | |
| 435 | + text-align: center; | |
| 436 | + font-family: Inter; | |
| 437 | + font-size: 12px; | |
| 438 | + font-style: normal; | |
| 439 | + font-weight: 500; | |
| 440 | + line-height: 2.6; | |
| 441 | + border: none; | |
| 442 | + } | |
| 443 | + | |
| 444 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .wpfnl-overview__install-mailmint .button:focus { | |
| 445 | + box-shadow: unset; | |
| 446 | + } | |
| 447 | + | |
| 448 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .wpfnl-overview__install-mailmint .loader { | |
| 449 | + border: 2px solid #f3f3f3; | |
| 450 | + border-top: 2px solid #573BFF; | |
| 451 | + border-radius: 50%; | |
| 452 | + width: 12px; | |
| 453 | + height: 12px; | |
| 454 | + animation: spin 0.8s linear infinite; | |
| 455 | + display: inline-block; | |
| 221 | 456 | vertical-align: middle; |
| 457 | + margin-right: 4px; | |
| 222 | 458 | } |
| 459 | + | |
| 460 | + @keyframes spin { | |
| 461 | + 0% { | |
| 462 | + transform: rotate(0deg); | |
| 463 | + } | |
| 464 | + | |
| 465 | + 100% { | |
| 466 | + transform: rotate(360deg); | |
| 467 | + } | |
| 468 | + } | |
| 469 | + | |
| 470 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .wpfnl-overview__install-mailmint .button:disabled { | |
| 471 | + cursor: not-allowed; | |
| 472 | + opacity: 0.7; | |
| 473 | + background: #573BFF !important; | |
| 474 | + color: #FFF !important; | |
| 475 | + } | |
| 476 | + | |
| 477 | + | |
| 478 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .icon-wrapper .text-wrapper .title { | |
| 479 | + color: #2E3148; | |
| 480 | + font-size: 16px; | |
| 481 | + font-weight: 600; | |
| 482 | + line-height: 1; | |
| 483 | + letter-spacing: -0.32px; | |
| 484 | + margin: 0 0 8px; | |
| 485 | + } | |
| 486 | + | |
| 487 | + .wpfnl-dashboard-widget .wpfnl-overview__mailmint .icon-wrapper .text-wrapper .description { | |
| 488 | + margin: 0; | |
| 489 | + line-height: 1; | |
| 490 | + } | |
| 491 | + | |
| 492 | + .wpfnl-dashboard-widget .wpfnl-overview__report { | |
| 493 | + display: grid; | |
| 494 | + grid-template-columns: repeat(2, 1fr); | |
| 495 | + border: 1px solid #EEEAF8; | |
| 496 | + margin: 15px 0; | |
| 497 | + } | |
| 498 | + | |
| 499 | + .wpfnl-dashboard-widget .wpfnl-overview__report .report-item { | |
| 500 | + display: flex; | |
| 501 | + gap: 15px; | |
| 502 | + padding: 20px; | |
| 503 | + position: relative; | |
| 504 | + | |
| 505 | + } | |
| 506 | + | |
| 507 | + .wpfnl-dashboard-widget .wpfnl-overview__report .report-item:nth-child(odd)::before { | |
| 508 | + content: ""; | |
| 509 | + position: absolute; | |
| 510 | + right: 15%; | |
| 511 | + height: 36px; | |
| 512 | + width: 1px; | |
| 513 | + background: linear-gradient(180deg, rgba(238, 234, 248, 0.00) -2.78%, #EEEAF8 47.1%, rgba(238, 234, 248, 0.00) 104.17%); | |
| 514 | + } | |
| 515 | + | |
| 516 | + .wpfnl-dashboard-widget .wpfnl-overview__report .report-item .text-wrapper p { | |
| 517 | + margin: 0; | |
| 518 | + line-height: 1; | |
| 519 | + } | |
| 520 | + | |
| 521 | + .wpfnl-dashboard-widget .wpfnl-overview__report .report-item .text-wrapper p.title { | |
| 522 | + color: #2E3148; | |
| 523 | + font-size: 12px; | |
| 524 | + font-weight: 400; | |
| 525 | + margin-bottom: 8px; | |
| 526 | + } | |
| 527 | + | |
| 528 | + .wpfnl-dashboard-widget .wpfnl-overview__report .report-item .text-wrapper p.amount { | |
| 529 | + color: #2E3148; | |
| 530 | + font-size: 15px; | |
| 531 | + font-weight: 600; | |
| 532 | + line-height: normal; | |
| 533 | + } | |
| 534 | + | |
| 535 | + .wpfnl-dashboard-widget .wpfnl-overview__header { | |
| 536 | + display: flex; | |
| 537 | + align-items: center; | |
| 538 | + justify-content: space-between; | |
| 539 | + border-bottom: 1px solid #eee; | |
| 540 | + gap: 15px; | |
| 541 | + padding: 15px 15px; | |
| 542 | + margin: 0 -12px; | |
| 543 | + | |
| 544 | + } | |
| 545 | + | |
| 546 | + .wpfnl-dashboard-widget .wpfnl-overview__header .wpfnl-overview__upgrade { | |
| 547 | + padding: 0px 15px; | |
| 548 | + } | |
| 549 | + | |
| 223 | 550 | .wpfnl-dashboard-widget .wpfnl-overview__versions { |
| 224 | - padding: 0 10px; | |
| 225 | 551 | font-size: 0.9em; |
| 226 | 552 | line-height: 1.5; |
| 227 | 553 | } |
| 554 | + | |
| 228 | 555 | .wpfnl-dashboard-widget .wpfnl-overview__version { |
| 229 | 556 | display: block; |
| 230 | 557 | } |
| 231 | - .wpfnl-dashboard-widget .wpfnl-overview__create { | |
| 232 | - text-align: right; | |
| 558 | + | |
| 559 | + .wpfnl-dashboard-widget .wpfnl-overview__create a { | |
| 560 | + border-radius: 7px; | |
| 561 | + background: #6E42D3; | |
| 562 | + border: 1px solid #6E42D3; | |
| 563 | + font-style: normal; | |
| 564 | + line-height: 2.28; | |
| 565 | + color: #FFF; | |
| 566 | + text-align: center; | |
| 567 | + font-family: Inter; | |
| 568 | + font-size: 14px; | |
| 569 | + font-weight: 500; | |
| 233 | 570 | } |
| 571 | + | |
| 572 | + .wpfnl-dashboard-widget .wpfnl-overview__create a:hover { | |
| 573 | + background: #6E42D3; | |
| 574 | + color: #FFF; | |
| 575 | + box-shadow: unset; | |
| 576 | + border-color: transparent; | |
| 577 | + } | |
| 578 | + | |
| 579 | + .wpfnl-dashboard-widget .wpfnl-overview__create a:focus { | |
| 580 | + background: #6E42D3; | |
| 581 | + color: #FFF; | |
| 582 | + outline: none; | |
| 583 | + box-shadow: unset; | |
| 584 | + border-color: transparent; | |
| 585 | + } | |
| 586 | + | |
| 234 | 587 | .wpfnl-dashboard-widget .wpfnl-overview__create .dashicons { |
| 235 | 588 | font-size: 15px; |
| 236 | 589 | line-height: 1; |
| 237 | 590 | position: relative; |
| @@ -236,22 +589,26 @@ | ||
| 236 | 589 | line-height: 1; |
| 237 | 590 | position: relative; |
| 238 | 591 | top: 8px; |
| 239 | 592 | } |
| 593 | + | |
| 240 | 594 | .wpfnl-dashboard-widget .wpfnl-overview__recently-edited .wpfnl-heading { |
| 241 | - font-weight: 600!important; | |
| 595 | + font-weight: 600 !important; | |
| 242 | 596 | border-bottom: 1px solid #eee; |
| 243 | - margin: 0 -12px!important; | |
| 244 | - padding: 6px 12px!important; | |
| 245 | - margin-bottom: 13px!important; | |
| 597 | + margin: 0 -12px !important; | |
| 598 | + padding: 6px 12px !important; | |
| 599 | + margin-bottom: 13px !important; | |
| 246 | 600 | } |
| 601 | + | |
| 247 | 602 | .wpfnl-dashboard-widget .wpfnl-overview__post { |
| 248 | 603 | margin-top: 10px; |
| 249 | 604 | font-weight: 500; |
| 250 | 605 | } |
| 606 | + | |
| 251 | 607 | .wpfnl-dashboard-widget .wpfnl-overview__post-link { |
| 252 | 608 | display: inline-block; |
| 253 | 609 | } |
| 610 | + | |
| 254 | 611 | .wpfnl-dashboard-widget .wpfnl-overview__post-description { |
| 255 | 612 | margin: 0 0 1.5em; |
| 256 | 613 | } |
| 257 | 614 | |
| @@ -270,30 +627,51 @@ | ||
| 270 | 627 | list-style: none; |
| 271 | 628 | margin: 0; |
| 272 | 629 | padding: 0; |
| 273 | 630 | } |
| 631 | + | |
| 274 | 632 | .wpfnl-dashboard-widget .wpfnl-overview__footer ul li { |
| 275 | 633 | padding: 0 10px; |
| 276 | 634 | margin: 0; |
| 277 | - border-left: 1px solid #ddd; | |
| 635 | + position: relative; | |
| 278 | 636 | } |
| 637 | + | |
| 638 | + .wpfnl-dashboard-widget .wpfnl-overview__footer .wpfnl-overview__blog a, | |
| 639 | + .wpfnl-dashboard-widget .wpfnl-overview__footer .wpfnl-overview__changelog a, | |
| 640 | + .wpfnl-dashboard-widget .wpfnl-overview__footer .wpfnl-overview__help a { | |
| 641 | + color: #667085; | |
| 642 | + font-size: 12px; | |
| 643 | + font-weight: 400; | |
| 644 | + position: relative; | |
| 645 | + } | |
| 646 | + | |
| 647 | + .wpfnl-dashboard-widget .wpfnl-overview__footer .wpfnl-overview__blog a:hover, | |
| 648 | + .wpfnl-dashboard-widget .wpfnl-overview__footer .wpfnl-overview__changelog a:hover, | |
| 649 | + .wpfnl-dashboard-widget .wpfnl-overview__footer .wpfnl-overview__help a:hover { | |
| 650 | + color: #6846CE; | |
| 651 | + } | |
| 652 | + | |
| 653 | + .wpfnl-dashboard-widget .wpfnl-overview__footer ul li:not(:last-child)::before { | |
| 654 | + content: ""; | |
| 655 | + position: absolute; | |
| 656 | + right: 0; | |
| 657 | + top: 3px; | |
| 658 | + height: 16px; | |
| 659 | + width: 1px; | |
| 660 | + background: linear-gradient(180deg, rgba(238, 234, 248, 0.00) -2.78%, #EEEAF8 47.1%, rgba(238, 234, 248, 0.00) 104.17%); | |
| 661 | + } | |
| 662 | + | |
| 279 | 663 | .wpfnl-dashboard-widget .wpfnl-overview__footer ul li:first-child { |
| 280 | 664 | padding-left: 0; |
| 281 | 665 | border: none; |
| 282 | 666 | } |
| 283 | - .wpfnl-dashboard-widget .wpfnl-overview__footer ul li .dashicons { | |
| 284 | - font-size: 17px; | |
| 285 | - color: #606a73; | |
| 286 | - position: relative; | |
| 287 | - top: 1px; | |
| 288 | - } | |
| 667 | + | |
| 289 | 668 | .wpfnl-dashboard-widget .wpfnl-overview__footer ul li.wpfnl-overview__go-pro a { |
| 290 | - color: #ee8134; | |
| 291 | - font-weight: 700; | |
| 669 | + color: #DF8740; | |
| 670 | + font-size: 12px; | |
| 671 | + font-weight: 400; | |
| 672 | + line-height: normal; | |
| 292 | 673 | } |
| 293 | - .wpfnl-dashboard-widget .wpfnl-overview__footer ul li.wpfnl-overview__go-pro a .dashicons { | |
| 294 | - color: #ee8134; | |
| 295 | - } | |
| 296 | 674 | </style> |
| 297 | 675 | </div> |
| 298 | 676 | <?php |
| 299 | 677 | } |
| @@ -310,15 +688,11 @@ | ||
| 310 | 688 | * |
| 311 | 689 | * @return array Feed data. |
| 312 | 690 | * @since 2.7.16 |
| 313 | 691 | */ |
| 314 | - public function get_wpfnl_feed_data ( $force_update = false ){ | |
| 315 | - $feed = $this->get_wpfnl_info_data( $force_update ); | |
| 316 | - | |
| 317 | - if ( empty( $feed ) || !isset( $feed['data']) ){ | |
| 318 | - return []; | |
| 319 | - } | |
| 320 | - return $feed['data']; | |
| 692 | + public function get_wpfnl_feed_data($force_update = false) | |
| 693 | + { | |
| 694 | + return $this->get_wpfnl_info_data($force_update); | |
| 321 | 695 | } |
| 322 | 696 | |
| 323 | 697 | /** |
| 324 | 698 | * Get wpfunnles info data. |
| @@ -332,67 +706,77 @@ | ||
| 332 | 706 | * |
| 333 | 707 | * @return array|false Info data, or false. |
| 334 | 708 | * @since 2.7.16 |
| 335 | 709 | */ |
| 336 | - private function get_wpfnl_info_data ( $force_update ){ | |
| 337 | - $cache_key = 'wpfunnel_remote_feed_data_' . WPFNL_VERSION; | |
| 710 | + private function get_wpfnl_info_data($force_update) | |
| 711 | + { | |
| 712 | + global $wpdb; | |
| 713 | + $response = [ | |
| 714 | + [ | |
| 715 | + 'title' => 'Total Orders', | |
| 716 | + 'amount' => $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$wpdb->prefix}wpfnl_stats WHERE status = %s", 'completed')), | |
| 717 | + 'show_pro' => false | |
| 718 | + ], | |
| 719 | + [ | |
| 720 | + 'title' => 'Total Revenue', | |
| 721 | + 'amount' => Wpfnl_functions::is_wc_active() ? wc_price((int)$wpdb->get_var($wpdb->prepare("SELECT SUM(total_sales) FROM {$wpdb->prefix}wpfnl_stats WHERE status = %s", 'completed'))) : number_format(0, 2), | |
| 722 | + 'show_pro' => false | |
| 723 | + ], | |
| 724 | + [ | |
| 725 | + 'title' => 'Order Bump Revenue', | |
| 726 | + 'amount' => Wpfnl_functions::is_wc_active() ? wc_price((int)$wpdb->get_var($wpdb->prepare("SELECT SUM(orderbump_sales) FROM {$wpdb->prefix}wpfnl_stats WHERE status = %s", 'completed'))) : number_format(0, 2), | |
| 727 | + 'show_pro' => false | |
| 728 | + ], | |
| 729 | + [ | |
| 730 | + 'title' => 'Upsell/Downsell Revenue', | |
| 731 | + 'amount' => (Wpfnl_functions::is_pro_license_activated() && Wpfnl_functions::is_wc_active()) ? wc_price((int)$wpdb->get_var($wpdb->prepare("SELECT SUM(upsell_sales + downsell_sales) FROM {$wpdb->prefix}wpfnl_stats WHERE status = %s", 'completed'))) : number_format(0, 2), | |
| 732 | + 'show_pro' => true | |
| 733 | + ], | |
| 734 | + [ | |
| 735 | + 'title' => 'Total Leads', | |
| 736 | + 'amount' => $wpdb->get_var("SELECT COUNT(id) FROM {$wpdb->prefix}wpfnl_optin_entries"), | |
| 737 | + 'show_pro' => false | |
| 738 | + ], | |
| 739 | + ]; | |
| 338 | 740 | |
| 339 | - $info_data = get_transient( $cache_key ); | |
| 340 | - | |
| 341 | - if ( $force_update || false === $info_data || empty( $info_data ) ){ | |
| 342 | - $url = 'https://getwpfunnels.com/wp-json/wp/v2/posts'; | |
| 343 | - $params = [ | |
| 344 | - 'per_page' => 3, | |
| 345 | - ]; | |
| 346 | - $url = add_query_arg($params, $url); | |
| 347 | - $response = $this->remote_get($url); | |
| 348 | - | |
| 349 | - if ( is_wp_error( $response ) || empty( $response['data'] ) ){ | |
| 350 | - set_transient($cache_key, [], 2 * HOUR_IN_SECONDS); | |
| 351 | - return false; | |
| 352 | - } | |
| 353 | - | |
| 354 | - $info_data = $response; | |
| 355 | - set_transient( $cache_key, $info_data, 12 * HOUR_IN_SECONDS ); | |
| 356 | - | |
| 357 | - } | |
| 358 | - return $info_data; | |
| 741 | + return $response; | |
| 359 | 742 | } |
| 360 | 743 | |
| 361 | 744 | /** |
| 362 | 745 | * Get all post from url |
| 363 | - * | |
| 746 | + * | |
| 364 | 747 | * @param $url |
| 365 | 748 | * @param $args |
| 366 | - * | |
| 749 | + * | |
| 367 | 750 | * @return array |
| 368 | 751 | */ |
| 369 | - private function remote_get($url, $args = []) | |
| 370 | - { | |
| 371 | - $response = wp_remote_get($url, $args); | |
| 752 | + private function remote_get($url, $args = []) | |
| 753 | + { | |
| 754 | + $response = wp_remote_get($url, $args); | |
| 372 | 755 | |
| 373 | - if ( is_wp_error( $response ) || ! is_array( $response ) || ! isset( $response['body'] ) ) { | |
| 756 | + if (is_wp_error($response) || !is_array($response) || !isset($response['body'])) { | |
| 374 | 757 | return [ |
| 375 | 758 | 'success' => false, |
| 376 | 759 | 'message' => $response->get_error_message(), |
| 377 | - 'data' => $response, | |
| 760 | + 'data' => $response, | |
| 378 | 761 | ]; |
| 379 | 762 | } |
| 380 | 763 | |
| 381 | 764 | // Decode the results. |
| 382 | - $results = json_decode( $response['body'], true ); | |
| 765 | + $results = json_decode($response['body'], true); | |
| 383 | 766 | |
| 384 | - if ( ! is_array( $results ) ) { | |
| 385 | - return new \WP_Error( 'unexpected_data_format', 'Data was not returned in the expected format.' ); | |
| 767 | + if (!is_array($results)) { | |
| 768 | + return new \WP_Error('unexpected_data_format', 'Data was not returned in the expected format.'); | |
| 386 | 769 | } |
| 387 | 770 | |
| 388 | - return [ | |
| 389 | - 'success' => true, | |
| 390 | - 'message' => 'Data successfully retrieved', | |
| 391 | - 'data' => json_decode(wp_remote_retrieve_body($response), true), | |
| 392 | - ]; | |
| 393 | - } | |
| 771 | + return [ | |
| 772 | + 'success' => true, | |
| 773 | + 'message' => 'Data successfully retrieved', | |
| 774 | + 'data' => json_decode(wp_remote_retrieve_body($response), true), | |
| 775 | + ]; | |
| 776 | + } | |
| 394 | 777 | |
| 778 | + | |
| 395 | 779 | /** |
| 396 | 780 | * Get wpfunnels dashboard overview widget footer actions. |
| 397 | 781 | * |
| 398 | 782 | * Retrieves the footer action links displayed in wpfunnels dashboard widget. |
| @@ -399,30 +783,31 @@ | ||
| 399 | 783 | * |
| 400 | 784 | * @since 1.9.0 |
| 401 | 785 | * @access private |
| 402 | 786 | */ |
| 403 | - private function get_wpfunnels_dashboard_overview_widget_footer_actions() { | |
| 787 | + private function get_wpfunnels_dashboard_overview_widget_footer_actions() | |
| 788 | + { | |
| 404 | 789 | $actions = [ |
| 790 | + 'go-pro' => [ | |
| 791 | + 'title' => esc_html__('Upgrade to Pro', 'wpfnl'), | |
| 792 | + 'link' => 'https://getwpfunnels.com/pricing/', | |
| 793 | + ], | |
| 405 | 794 | 'blog' => [ |
| 406 | - 'title' => esc_html__( 'Blog', 'wpfnl' ), | |
| 795 | + 'title' => esc_html__('Blogs', 'wpfnl'), | |
| 407 | 796 | 'link' => 'https://getwpfunnels.com/blog/', |
| 408 | 797 | ], |
| 409 | 798 | 'changelog' => [ |
| 410 | - 'title' => esc_html__( 'Changelog', 'wpfnl' ), | |
| 799 | + 'title' => esc_html__('Changelogs', 'wpfnl'), | |
| 411 | 800 | 'link' => 'https://getwpfunnels.com/changelog/', |
| 412 | 801 | ], |
| 413 | - 'go-pro' => [ | |
| 414 | - 'title' => esc_html__( 'Upgrade', 'wpfnl' ), | |
| 415 | - 'link' => 'https://getwpfunnels.com/pricing/', | |
| 416 | - ], | |
| 417 | 802 | 'help' => [ |
| 418 | - 'title' => esc_html__( 'Help', 'wpfnl' ), | |
| 803 | + 'title' => esc_html__('Get Help', 'wpfnl'), | |
| 419 | 804 | 'link' => 'https://getwpfunnels.com/docs/getting-started-with-wpfunnels/', |
| 420 | 805 | ], |
| 421 | 806 | |
| 422 | 807 | ]; |
| 423 | 808 | |
| 424 | - if( Wpfnl_functions::is_pro_license_activated() ){ | |
| 809 | + if (Wpfnl_functions::is_pro_license_activated()) { | |
| 425 | 810 | unset($actions['go-pro']); |
| 426 | 811 | } |
| 427 | 812 | |
| 428 | 813 | return $actions; |
| @@ -439,8 +824,12 @@ | ||
| 439 | 824 | { |
| 440 | 825 | $documentation = array( |
| 441 | 826 | '<a href="https://getwpfunnels.com/docs/wpfunnels-wordpress-funnel-builder/" target="_blank" >Documentation</a>', |
| 442 | 827 | ); |
| 828 | + $is_pro_installed = Wpfnl_functions::is_plugin_installed('wpfunnels-pro/wpfnl-pro.php'); | |
| 829 | + if (!defined('WPFNL_PRO_VERSION') && !$is_pro_installed) { | |
| 830 | + $documentation[] = '<a href="https://getwpfunnels.com/pricing/" target="_blank" style="color:#6E42D3;font-weight:bold" >Upgrade to Pro</a>'; | |
| 831 | + } | |
| 443 | 832 | $actions = array_merge($actions, $documentation); |
| 444 | 833 | return $actions; |
| 445 | 834 | } |
| 446 | 835 | |
| @@ -462,20 +851,570 @@ | ||
| 462 | 851 | * The Wpfnl_Loader will then create the relationship |
| 463 | 852 | * between the defined hooks and the functions defined in this |
| 464 | 853 | * class. |
| 465 | 854 | */ |
| 466 | - if ( 'wp-funnels_page_email-builder' === $hook ) { | |
| 467 | - wp_enqueue_style($this->plugin_name .'-email-builder' , plugin_dir_url(__FILE__) . 'assets/dist/email-builder/email-builder.css', [], $this->version, 'all'); | |
| 855 | + if ('wpfunnels_page_email-builder' === $hook) { | |
| 856 | + wp_enqueue_style($this->plugin_name . '-email-builder', plugin_dir_url(__FILE__) . 'assets/dist/email-builder/email-builder.css', [], $this->version, 'all'); | |
| 468 | 857 | } |
| 858 | + | |
| 469 | 859 | if (in_array($hook, $this->page_hooks)) { |
| 470 | - wp_enqueue_style( 'wp-color-picker' ); | |
| 860 | + wp_enqueue_style('wp-color-picker'); | |
| 471 | 861 | wp_enqueue_style($this->plugin_name . '-jquery-ui', plugin_dir_url(__FILE__) . 'assets/css/jquery-ui.min.css', [], $this->version, 'all'); |
| 862 | + | |
| 472 | 863 | wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'assets/css/wpfnl-admin.css', [], $this->version, 'all'); |
| 864 | + | |
| 473 | 865 | do_action('wpfunnels_after_styles_loaded'); |
| 474 | 866 | } |
| 475 | 867 | } |
| 476 | 868 | |
| 477 | 869 | /** |
| 870 | + * Screen hooks the React single-page admin renders on — the WPFunnels | |
| 871 | + * dashboard, plus the alias slug it was first built under. | |
| 872 | + * | |
| 873 | + * The settings page is here too. It normally redirects to `#/settings` | |
| 874 | + * before this ever runs, so nothing loads on the way through; the entry | |
| 875 | + * matters for the case where that redirect is filtered off, when the page | |
| 876 | + * renders the app itself and needs the app's assets to do it. | |
| 877 | + * | |
| 878 | + * @return array Hook suffixes. | |
| 879 | + * @since 3.13.2 | |
| 880 | + */ | |
| 881 | + private function get_react_admin_hooks() | |
| 882 | + { | |
| 883 | + return array( | |
| 884 | + 'toplevel_page_' . WPFNL_MAIN_PAGE_SLUG, | |
| 885 | + 'wpfunnels_page_' . WPFNL_REACT_ADMIN_SLUG, | |
| 886 | + 'wpfunnels_page_' . WPFNL_GLOBAL_SETTINGS_SLUG, | |
| 887 | + ); | |
| 888 | + } | |
| 889 | + | |
| 890 | + | |
| 891 | + /** | |
| 892 | + * Resolve what the automation screen still needs before it can be used. | |
| 893 | + * | |
| 894 | + * Automations run on four things: WPFunnels and WPFunnels Pro with an | |
| 895 | + * activated licence, and Mail Mint and Mail Mint Pro with an activated | |
| 896 | + * licence. Each of the two Pro stacks walks the same ladder — not on the | |
| 897 | + * site, on the site but switched off, running but unlicensed, satisfied — | |
| 898 | + * and each rung needs a different next step, so the whole thing is resolved | |
| 899 | + * here rather than in the React app: only PHP can tell an uninstalled plugin | |
| 900 | + * from a deactivated one, and only PHP knows the licence state. | |
| 901 | + * | |
| 902 | + * @return array List of dependency descriptors, in the order they should be | |
| 903 | + * presented. | |
| 904 | + * @since 3.13.3 | |
| 905 | + */ | |
| 906 | + private function get_automation_dependencies() | |
| 907 | + { | |
| 908 | + return array( | |
| 909 | + $this->get_wpfnl_pro_dependency(), | |
| 910 | + $this->get_mail_mint_dependency(), | |
| 911 | + ); | |
| 912 | + } | |
| 913 | + | |
| 914 | + | |
| 915 | + /** | |
| 916 | + * Dependency descriptor for the WPFunnels Pro half of the ladder. | |
| 917 | + * | |
| 918 | + * WPFunnels Pro is not on wordpress.org, so the "not installed" rung is a | |
| 919 | + * purchase link rather than a one-click install. | |
| 920 | + * | |
| 921 | + * @return array Dependency descriptor. | |
| 922 | + * @since 3.13.3 | |
| 923 | + */ | |
| 924 | + private function get_wpfnl_pro_dependency() | |
| 925 | + { | |
| 926 | + $base = array( | |
| 927 | + 'id' => 'wpfunnels-pro', | |
| 928 | + 'name' => __('WPFunnels Pro', 'wpfnl'), | |
| 929 | + 'basename' => self::WPFNL_PRO_BASENAME, | |
| 930 | + 'slug' => 'wpfunnels-pro', | |
| 931 | + 'action' => '', | |
| 932 | + 'url' => '', | |
| 933 | + 'newTab' => false, | |
| 934 | + ); | |
| 935 | + | |
| 936 | + if ((bool) apply_filters('wpfunnels/is_pro_license_activated', false)) { | |
| 937 | + return array_merge($base, array( | |
| 938 | + 'state' => 'satisfied', | |
| 939 | + 'message' => '', | |
| 940 | + 'label' => '', | |
| 941 | + )); | |
| 942 | + } | |
| 943 | + | |
| 944 | + if (Wpfnl_functions::is_plugin_activated(self::WPFNL_PRO_BASENAME)) { | |
| 945 | + return array_merge($base, array( | |
| 946 | + 'state' => 'needs_license', | |
| 947 | + 'message' => __('WPFunnels Pro is active, but its license has not been activated yet.', 'wpfnl'), | |
| 948 | + 'label' => __('Activate License', 'wpfnl'), | |
| 949 | + 'url' => esc_url_raw(add_query_arg(array('page' => 'wpf-license'), admin_url('admin.php'))), | |
| 950 | + )); | |
| 951 | + } | |
| 952 | + | |
| 953 | + if (Wpfnl_functions::is_plugin_installed(self::WPFNL_PRO_BASENAME)) { | |
| 954 | + return array_merge($base, array( | |
| 955 | + 'state' => 'needs_activation', | |
| 956 | + 'message' => __('WPFunnels Pro is installed but currently inactive.', 'wpfnl'), | |
| 957 | + 'label' => __('Activate WPFunnels Pro', 'wpfnl'), | |
| 958 | + 'action' => 'activate', | |
| 959 | + )); | |
| 960 | + } | |
| 961 | + | |
| 962 | + return array_merge($base, array( | |
| 963 | + 'state' => 'not_installed', | |
| 964 | + 'message' => __('Automations need WPFunnels Pro, which is not installed on this site.', 'wpfnl'), | |
| 965 | + 'label' => __('Upgrade to Pro', 'wpfnl'), | |
| 966 | + 'url' => 'https://getwpfunnels.com/pricing/', | |
| 967 | + 'newTab' => true, | |
| 968 | + )); | |
| 969 | + } | |
| 970 | + | |
| 971 | + | |
| 972 | + /** | |
| 973 | + * Dependency descriptor for the Mail Mint half of the ladder. | |
| 974 | + * | |
| 975 | + * The free plugin comes from wordpress.org, so its first two rungs are | |
| 976 | + * one-click: wpfunnels/v1/activate-plugin installs the package when it is | |
| 977 | + * missing and activates it either way. Mail Mint Pro is a paid plugin, so | |
| 978 | + * its "not installed" rung is a purchase link. | |
| 979 | + * | |
| 980 | + * @return array Dependency descriptor. | |
| 981 | + * @since 3.13.3 | |
| 982 | + */ | |
| 983 | + private function get_mail_mint_dependency() | |
| 984 | + { | |
| 985 | + $base = array( | |
| 986 | + 'id' => 'mail-mint', | |
| 987 | + 'name' => __('Mail Mint', 'wpfnl'), | |
| 988 | + 'basename' => self::MAIL_MINT_BASENAME, | |
| 989 | + 'slug' => 'mail-mint', | |
| 990 | + 'action' => '', | |
| 991 | + 'url' => '', | |
| 992 | + 'newTab' => false, | |
| 993 | + ); | |
| 994 | + | |
| 995 | + if (Wpfnl_functions::is_mail_mint_pro_license_active() && Wpfnl_functions::is_mail_mint_free_active()) { | |
| 996 | + return array_merge($base, array( | |
| 997 | + 'state' => 'satisfied', | |
| 998 | + 'message' => '', | |
| 999 | + 'label' => '', | |
| 1000 | + )); | |
| 1001 | + } | |
| 1002 | + | |
| 1003 | + if (!Wpfnl_functions::is_plugin_installed(self::MAIL_MINT_BASENAME)) { | |
| 1004 | + return array_merge($base, array( | |
| 1005 | + 'state' => 'not_installed', | |
| 1006 | + 'message' => __('Automations need Mail Mint, which is not installed on this site.', 'wpfnl'), | |
| 1007 | + 'label' => __('Install Mail Mint', 'wpfnl'), | |
| 1008 | + 'action' => 'install', | |
| 1009 | + )); | |
| 1010 | + } | |
| 1011 | + | |
| 1012 | + if (!Wpfnl_functions::is_mail_mint_free_active()) { | |
| 1013 | + return array_merge($base, array( | |
| 1014 | + 'state' => 'needs_activation', | |
| 1015 | + 'message' => __('Mail Mint is installed but currently inactive.', 'wpfnl'), | |
| 1016 | + 'label' => __('Activate Mail Mint', 'wpfnl'), | |
| 1017 | + 'action' => 'activate', | |
| 1018 | + )); | |
| 1019 | + } | |
| 1020 | + | |
| 1021 | + // Mail Mint is running; the rest of the ladder is about its Pro plugin. | |
| 1022 | + if (Wpfnl_functions::is_plugin_activated(self::MAIL_MINT_PRO_BASENAME)) { | |
| 1023 | + return array_merge($base, array( | |
| 1024 | + 'state' => 'needs_license', | |
| 1025 | + 'name' => __('Mail Mint Pro', 'wpfnl'), | |
| 1026 | + 'basename' => self::MAIL_MINT_PRO_BASENAME, | |
| 1027 | + 'message' => __('Mail Mint Pro is active, but its license has not been activated yet.', 'wpfnl'), | |
| 1028 | + 'label' => __('Activate License', 'wpfnl'), | |
| 1029 | + 'url' => esc_url_raw(admin_url('admin.php?page=mrm-admin#/settings/license')), | |
| 1030 | + )); | |
| 1031 | + } | |
| 1032 | + | |
| 1033 | + if (Wpfnl_functions::is_plugin_installed(self::MAIL_MINT_PRO_BASENAME)) { | |
| 1034 | + return array_merge($base, array( | |
| 1035 | + 'state' => 'needs_activation', | |
| 1036 | + 'name' => __('Mail Mint Pro', 'wpfnl'), | |
| 1037 | + 'basename' => self::MAIL_MINT_PRO_BASENAME, | |
| 1038 | + 'slug' => 'mail-mint-pro', | |
| 1039 | + 'message' => __('Mail Mint Pro is installed but currently inactive.', 'wpfnl'), | |
| 1040 | + 'label' => __('Activate Mail Mint Pro', 'wpfnl'), | |
| 1041 | + 'action' => 'activate', | |
| 1042 | + )); | |
| 1043 | + } | |
| 1044 | + | |
| 1045 | + return array_merge($base, array( | |
| 1046 | + 'state' => 'not_installed', | |
| 1047 | + 'name' => __('Mail Mint Pro', 'wpfnl'), | |
| 1048 | + 'basename' => self::MAIL_MINT_PRO_BASENAME, | |
| 1049 | + 'slug' => 'mail-mint-pro', | |
| 1050 | + 'message' => __('Automations need Mail Mint Pro with an activated license.', 'wpfnl'), | |
| 1051 | + 'label' => __('Get Mail Mint Pro', 'wpfnl'), | |
| 1052 | + 'url' => 'https://getwpfunnels.com/pricing/#mail-mint', | |
| 1053 | + 'newTab' => true, | |
| 1054 | + )); | |
| 1055 | + } | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + /** | |
| 1059 | + * Work out what the header's Pro call to action should say and where it | |
| 1060 | + * should go. | |
| 1061 | + * | |
| 1062 | + * There are three ways an install can fall short of a licensed Pro, and each | |
| 1063 | + * needs a different next step — telling someone to buy Pro when the plugin is | |
| 1064 | + * sitting deactivated in their plugins list is a dead end. Resolved here | |
| 1065 | + * rather than in the React app because the activation link needs a nonce and | |
| 1066 | + * a capability check. | |
| 1067 | + * | |
| 1068 | + * @return array|null CTA descriptor, or null when Pro is fully licensed and | |
| 1069 | + * no call to action belongs in the header. | |
| 1070 | + * @since 3.13.2 | |
| 1071 | + */ | |
| 1072 | + private function get_pro_cta() | |
| 1073 | + { | |
| 1074 | + if (!function_exists('get_plugins')) { | |
| 1075 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; | |
| 1076 | + } | |
| 1077 | + | |
| 1078 | + $basename = 'wpfunnels-pro/wpfnl-pro.php'; | |
| 1079 | + | |
| 1080 | + if ((bool) apply_filters('wpfunnels/is_pro_license_activated', false)) { | |
| 1081 | + return null; | |
| 1082 | + } | |
| 1083 | + | |
| 1084 | + // Installed and running, but unlicensed — the features stay locked until | |
| 1085 | + // the licence is activated, so send them to the licence screen. | |
| 1086 | + if (Wpfnl_functions::is_plugin_activated($basename)) { | |
| 1087 | + return array( | |
| 1088 | + 'state' => 'needs_license', | |
| 1089 | + 'label' => __('Activate License', 'wpfnl'), | |
| 1090 | + 'title' => __('Activate your WPFunnels Pro license to unlock Pro features', 'wpfnl'), | |
| 1091 | + 'url' => esc_url_raw(add_query_arg(array('page' => 'wpf-license'), admin_url('admin.php'))), | |
| 1092 | + 'newTab' => false, | |
| 1093 | + ); | |
| 1094 | + } | |
| 1095 | + | |
| 1096 | + // Present but deactivated — one click away, no purchase needed. | |
| 1097 | + if (Wpfnl_functions::is_plugin_installed($basename)) { | |
| 1098 | + $plugins_url = admin_url('plugins.php'); | |
| 1099 | + $can_activate = current_user_can('activate_plugins'); | |
| 1100 | + | |
| 1101 | + /* | |
| 1102 | + * Built with add_query_arg rather than wp_nonce_url on purpose. | |
| 1103 | + * wp_nonce_url() returns esc_html()'d output, so its separators come | |
| 1104 | + * back as `&`. That is correct for a URL echoed straight into | |
| 1105 | + * markup — the HTML parser decodes it — but this one travels through | |
| 1106 | + * wp_localize_script and is applied by React with setAttribute, | |
| 1107 | + * where nothing decodes entities. The literal `&` would split | |
| 1108 | + * the query string into junk parameters, `plugin` and `_wpnonce` | |
| 1109 | + * would arrive empty, and WordPress would answer the click with | |
| 1110 | + * "The link you followed has expired." | |
| 1111 | + * | |
| 1112 | + * wp_localize_script's own html_entity_decode() does not save us | |
| 1113 | + * either: it only walks top-level scalars, and this URL is nested | |
| 1114 | + * inside the CTA array. | |
| 1115 | + * | |
| 1116 | + * Without the capability the one-click link would only bounce off a | |
| 1117 | + * permission check, so point at the plugins list instead. | |
| 1118 | + */ | |
| 1119 | + $url = $can_activate | |
| 1120 | + ? add_query_arg( | |
| 1121 | + array( | |
| 1122 | + 'action' => 'activate', | |
| 1123 | + 'plugin' => rawurlencode($basename), | |
| 1124 | + '_wpnonce' => wp_create_nonce('activate-plugin_' . $basename), | |
| 1125 | + ), | |
| 1126 | + $plugins_url | |
| 1127 | + ) | |
| 1128 | + : $plugins_url; | |
| 1129 | + | |
| 1130 | + return array( | |
| 1131 | + 'state' => 'needs_activation', | |
| 1132 | + 'label' => __('Activate Pro', 'wpfnl'), | |
| 1133 | + 'title' => __('WPFunnels Pro is installed but not active — activate it to unlock Pro features', 'wpfnl'), | |
| 1134 | + 'url' => esc_url_raw($url), | |
| 1135 | + 'newTab' => false, | |
| 1136 | + ); | |
| 1137 | + } | |
| 1138 | + | |
| 1139 | + // Not on the site at all. | |
| 1140 | + return array( | |
| 1141 | + 'state' => 'not_installed', | |
| 1142 | + 'label' => __('Upgrade to Pro', 'wpfnl'), | |
| 1143 | + 'title' => __('Upgrade to WPFunnels Pro', 'wpfnl'), | |
| 1144 | + 'url' => 'https://getwpfunnels.com/pricing/', | |
| 1145 | + 'newTab' => true, | |
| 1146 | + ); | |
| 1147 | + } | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + /** | |
| 1151 | + * Enqueue the React single-page admin bundle. | |
| 1152 | + * | |
| 1153 | + * Deliberately kept out of the `$page_hooks` group: the React admin ships | |
| 1154 | + * its own namespaced stylesheet (every class prefixed `rwpfnl`) and must not | |
| 1155 | + * inherit the legacy admin CSS, which is written against the Vue markup. | |
| 1156 | + * | |
| 1157 | + * @param string $hook Current admin screen hook suffix. | |
| 1158 | + * | |
| 1159 | + * @return void | |
| 1160 | + * @since 3.13.2 | |
| 1161 | + */ | |
| 1162 | + /** | |
| 1163 | + * Data the React template library screen needs. | |
| 1164 | + * | |
| 1165 | + * The same facts the Vue library read off `WPFunnelVars` and | |
| 1166 | + * `template_library_object`, narrowed to what the standalone Templates page | |
| 1167 | + * actually uses. The listing itself still comes from the REST API; this is | |
| 1168 | + * only the context the listing is read in. | |
| 1169 | + * | |
| 1170 | + * @return array Template library context. | |
| 1171 | + * @since 3.13.5 | |
| 1172 | + */ | |
| 1173 | + private function get_template_library_data() | |
| 1174 | + { | |
| 1175 | + $is_pro_license_active = (bool) apply_filters('wpfunnels/is_pro_license_activated', false); | |
| 1176 | + | |
| 1177 | + return array( | |
| 1178 | + 'builder' => Wpfnl_functions::get_builder_type(), | |
| 1179 | + 'isAnyPluginMissing' => Wpfnl_functions::is_any_plugin_missing(), | |
| 1180 | + 'dependencyPlugins' => Wpfnl_functions::get_dependency_plugins_status(), | |
| 1181 | + 'types' => Wpfnl_functions::get_template_types(), | |
| 1182 | + // Store Checkout funnels have their own allowance, so they are not | |
| 1183 | + // counted against this one. | |
| 1184 | + 'activeFunnels' => Wpfnl_functions::count_non_store_checkout_funnels(), | |
| 1185 | + // -1 once the licence lifts the cap. | |
| 1186 | + 'allowedFunnels' => $is_pro_license_active ? -1 : 3, | |
| 1187 | + // The remote-funnel add-on serves the library from elsewhere, and | |
| 1188 | + // this screen then has nothing of its own to fetch. | |
| 1189 | + 'isRemote' => Wpfnl_functions::maybe_remote_funnel(), | |
| 1190 | + ); | |
| 1191 | + } | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + private function enqueue_react_admin_assets($hook) | |
| 1195 | + { | |
| 1196 | + if (!in_array($hook, $this->get_react_admin_hooks(), true)) { | |
| 1197 | + return; | |
| 1198 | + } | |
| 1199 | + | |
| 1200 | + /* | |
| 1201 | + * A production build splits the webpack runtime into its own chunk that | |
| 1202 | + * every entry depends on, so it has to load first. A development build | |
| 1203 | + * (npm run start) keeps the runtime inside each entry and emits no such | |
| 1204 | + * file, hence the existence check rather than a hard dependency. | |
| 1205 | + */ | |
| 1206 | + $runtime_deps = array(); | |
| 1207 | + $runtime_path = WPFNL_DIR . '/admin/assets/dist/runtime/index.min.js'; | |
| 1208 | + | |
| 1209 | + if (file_exists($runtime_path)) { | |
| 1210 | + wp_enqueue_script( | |
| 1211 | + 'wpfnl-webpack-runtime', | |
| 1212 | + plugin_dir_url(__FILE__) . 'assets/dist/runtime/index.min.js', | |
| 1213 | + array(), | |
| 1214 | + $this->version, | |
| 1215 | + true | |
| 1216 | + ); | |
| 1217 | + | |
| 1218 | + $runtime_deps[] = 'wpfnl-webpack-runtime'; | |
| 1219 | + } | |
| 1220 | + | |
| 1221 | + wp_enqueue_script( | |
| 1222 | + 'wpfnl-react-admin', | |
| 1223 | + plugin_dir_url(__FILE__) . 'assets/dist/js/wpfnl-react-admin.min.js', | |
| 1224 | + $runtime_deps, | |
| 1225 | + $this->version, | |
| 1226 | + true | |
| 1227 | + ); | |
| 1228 | + | |
| 1229 | + Wpfnl_functions::enqueue_bundle_style('wpfnl-react-admin', 'wpfnl-react-admin-bundle'); | |
| 1230 | + | |
| 1231 | + // The React admin renders the whole header action group itself — the | |
| 1232 | + // AI Assistant drawer included (see src/admin/components/AiDrawer/) — | |
| 1233 | + // so the Vue global-ai-drawer bundle is NOT loaded on this screen: it | |
| 1234 | + // would find neither of its mount points (#wpfnl-header-actions, | |
| 1235 | + // #wpfnl-global-ai-drawer), and loading it anyway only shipped a second | |
| 1236 | + // copy of the group's markup and styles. | |
| 1237 | + $_is_pro_license_active = (bool) apply_filters('wpfunnels/is_pro_license_activated', false); | |
| 1238 | + | |
| 1239 | + /* | |
| 1240 | + * Everything after the page name in the title WordPress just printed — | |
| 1241 | + * separator, site name, " — WordPress". The React admin is one WordPress | |
| 1242 | + * page with its routes in the hash, so WordPress titles the tab once, | |
| 1243 | + * with this page's own name ("Dashboard"), and every route below it | |
| 1244 | + * inherits that. The app retitles itself per route (see | |
| 1245 | + * src/admin/utils/documentTitle.js) and needs this tail, which is | |
| 1246 | + * translatable and so cannot be rebuilt in JavaScript. | |
| 1247 | + * | |
| 1248 | + * `$admin_title` is built from `$title`, so it always starts with it; | |
| 1249 | + * the prefix check is only there in case an `admin_title` filter has | |
| 1250 | + * rewritten the whole thing, in which case the app keeps what WordPress | |
| 1251 | + * printed for the page name it resolves. Entities such as `‹` | |
| 1252 | + * survive here: wp_localize_script() decodes them on the way out. | |
| 1253 | + */ | |
| 1254 | + $_document_title_suffix = ''; | |
| 1255 | + | |
| 1256 | + if (isset($GLOBALS['title'], $GLOBALS['admin_title'])) { | |
| 1257 | + $_page_title = (string) $GLOBALS['title']; | |
| 1258 | + $_admin_title = (string) $GLOBALS['admin_title']; | |
| 1259 | + | |
| 1260 | + if ('' !== $_page_title && 0 === strpos($_admin_title, $_page_title)) { | |
| 1261 | + $_document_title_suffix = substr($_admin_title, strlen($_page_title)); | |
| 1262 | + } | |
| 1263 | + } | |
| 1264 | + | |
| 1265 | + // Mail Mint's install state is read from get_plugins() below. | |
| 1266 | + if (!function_exists('get_plugins')) { | |
| 1267 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; | |
| 1268 | + } | |
| 1269 | + | |
| 1270 | + /* | |
| 1271 | + * Core's plugin updater. The template library route offers to install | |
| 1272 | + * the page builder its templates are authored for when that plugin is | |
| 1273 | + * missing, and `wp.updates` is what does the installing. | |
| 1274 | + */ | |
| 1275 | + wp_enqueue_script('updates'); | |
| 1276 | + | |
| 1277 | + wp_localize_script( | |
| 1278 | + 'wpfnl-react-admin', | |
| 1279 | + 'RWPFNLAdmin', | |
| 1280 | + array( | |
| 1281 | + 'rest_api_url' => get_rest_url(), | |
| 1282 | + 'nonce' => wp_create_nonce('wp_rest'), | |
| 1283 | + 'security' => wp_create_nonce('wpfnl-admin'), | |
| 1284 | + 'admin_url' => admin_url(), | |
| 1285 | + 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 1286 | + // Base URL the bundle resolves its async chunks against — the | |
| 1287 | + // canvas editor is code-split (see src/admin/public-path.js). | |
| 1288 | + 'dist_url' => WPFNL_URL . 'admin/assets/dist/', | |
| 1289 | + 'priceConfig' => Wpfnl_functions::get_wc_price_config(), | |
| 1290 | + 'isProActivated' => apply_filters('wpfunnels/is_wpfnl_pro_active', false), | |
| 1291 | + 'isWPFIntegrationActive' => apply_filters('wpfunnels/is_integration_license_active', false), | |
| 1292 | + /* | |
| 1293 | + * Mail Mint's licence state, which decides whether the automation | |
| 1294 | + * route shows the promo screen at all or hands the visitor to the | |
| 1295 | + * legacy automation list. | |
| 1296 | + */ | |
| 1297 | + 'isMailMintProLicenseActive' => Wpfnl_functions::is_mail_mint_pro_license_active(), | |
| 1298 | + /* | |
| 1299 | + * What the automation screen still needs, rung by rung, with the | |
| 1300 | + * next step for each. Plugin-installing rungs carry a basename and | |
| 1301 | + * slug the screen posts to wpfunnels/v1/activate-plugin; the rest | |
| 1302 | + * carry a URL. | |
| 1303 | + */ | |
| 1304 | + 'automationDependencies' => $this->get_automation_dependencies(), | |
| 1305 | + 'canInstallPlugins' => current_user_can('install_plugins'), | |
| 1306 | + 'canActivatePlugins' => current_user_can('activate_plugins'), | |
| 1307 | + 'getText' => Wpfnl_functions::get_text(), | |
| 1308 | + 'startOfWeek' => (int) get_option('start_of_week', 0), | |
| 1309 | + /* | |
| 1310 | + * Whether the onboarding checklist was on show last time the | |
| 1311 | + * dashboard asked — 'yes', 'no', or absent when unknown. Only | |
| 1312 | + * decides whether to hold space for it while its real status | |
| 1313 | + * loads; the status itself still comes from the REST call. | |
| 1314 | + */ | |
| 1315 | + 'onboardingHint' => get_transient(\WPFunnels\Rest\Controllers\DashboardController::ONBOARDING_VISIBILITY_KEY), | |
| 1316 | + /* | |
| 1317 | + * Header action group data. It has to ride on this handle, not on | |
| 1318 | + * the AI-drawer handle the Vue group used: WordPress prints a | |
| 1319 | + * script's localized data immediately before that script's own | |
| 1320 | + * tag, and the React bundle is enqueued first — so anything | |
| 1321 | + * attached to the drawer does not exist yet when React renders. | |
| 1322 | + */ | |
| 1323 | + 'isProLicenseActive' => $_is_pro_license_active, | |
| 1324 | + 'upgradeUrl' => 'https://getwpfunnels.com/pricing/', | |
| 1325 | + 'proCta' => $this->get_pro_cta(), | |
| 1326 | + 'documentTitleSuffix' => $_document_title_suffix, | |
| 1327 | + /* | |
| 1328 | + * What the template library route runs on. Every value here is | |
| 1329 | + * something only PHP can answer — which page builder the site is | |
| 1330 | + * set up for and whether its plugin is actually there, how much | |
| 1331 | + * of an unlicensed install's funnel allowance is left, which | |
| 1332 | + * template types this install has. Arrives as a real object: | |
| 1333 | + * wp_localize_script only stringifies top-level scalars. | |
| 1334 | + */ | |
| 1335 | + 'templateLibrary' => $this->get_template_library_data(), | |
| 1336 | + /* | |
| 1337 | + * The two settings panels that are still Vue apps of their own, | |
| 1338 | + * fetched by the settings screen when one of them is opened. | |
| 1339 | + */ | |
| 1340 | + 'settingsPanelApps' => $this->get_settings_panel_apps(), | |
| 1341 | + ) | |
| 1342 | + ); | |
| 1343 | + | |
| 1344 | + $this->enqueue_settings_panel_apps(); | |
| 1345 | + } | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + /** | |
| 1349 | + * The two settings panels that are still Vue apps of their own. | |
| 1350 | + * | |
| 1351 | + * "AI Assistant" and "MCP for AI Agents" each own their fields and save them | |
| 1352 | + * through their own REST routes, so the React settings screen renders a | |
| 1353 | + * mount point and asks those bundles to mount into it rather than | |
| 1354 | + * reimplementing them (see src/admin/pages/Settings/VuePanel.jsx). The | |
| 1355 | + * bundles are unchanged — they still mount themselves on the legacy settings | |
| 1356 | + * page, where the mount point is printed by PHP. | |
| 1357 | + * | |
| 1358 | + * @return void | |
| 1359 | + * @since 3.13.8 | |
| 1360 | + */ | |
| 1361 | + private function enqueue_settings_panel_apps() | |
| 1362 | + { | |
| 1363 | + $_current_user = wp_get_current_user(); | |
| 1364 | + $_common = array( | |
| 1365 | + 'username' => $_current_user ? $_current_user->user_login : '', | |
| 1366 | + 'rest_url' => esc_url_raw(get_rest_url()), | |
| 1367 | + 'nonce' => wp_create_nonce('wp_rest'), | |
| 1368 | + 'admin_url' => esc_url_raw(admin_url()), | |
| 1369 | + ); | |
| 1370 | + | |
| 1371 | + /* | |
| 1372 | + * The globals the two bundles read, printed before the React bundle so | |
| 1373 | + * they are there whenever a bundle is pulled in later. They are a few | |
| 1374 | + * hundred bytes; the bundles themselves are megabytes, which is why | |
| 1375 | + * only the data is printed up front. | |
| 1376 | + */ | |
| 1377 | + wp_add_inline_script( | |
| 1378 | + 'wpfnl-react-admin', | |
| 1379 | + 'window.WPFnlMcpSettings = ' . wp_json_encode(array_merge($_common, array('site_url' => esc_url_raw(home_url())))) . ';' . | |
| 1380 | + 'window.WPFnlAiAssistantSettings = ' . wp_json_encode($_common) . ';', | |
| 1381 | + 'before' | |
| 1382 | + ); | |
| 1383 | + } | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + /** | |
| 1387 | + * Where the settings screen fetches its two Vue panels from. | |
| 1388 | + * | |
| 1389 | + * Neither bundle is enqueued: only one settings panel in the app needs | |
| 1390 | + * either of them, and the route is in the fragment, which the server never | |
| 1391 | + * sees — so loading them on every screen of the admin would cost every | |
| 1392 | + * screen megabytes for a panel most visitors never open. The panel loads | |
| 1393 | + * what it needs when it is opened (see pages/Settings/panels/VuePanel.jsx). | |
| 1394 | + * | |
| 1395 | + * The stylesheet is empty on a development build, which injects its styles | |
| 1396 | + * from JavaScript and emits none. | |
| 1397 | + * | |
| 1398 | + * @return array Script and stylesheet URL per panel. | |
| 1399 | + * @since 3.13.8 | |
| 1400 | + */ | |
| 1401 | + private function get_settings_panel_apps() | |
| 1402 | + { | |
| 1403 | + return array( | |
| 1404 | + 'aiAssistant' => array( | |
| 1405 | + 'script' => plugin_dir_url(__FILE__) . 'assets/dist/js/ai-assistant-settings.min.js', | |
| 1406 | + 'style' => Wpfnl_functions::get_bundle_style_url('ai-assistant-settings'), | |
| 1407 | + ), | |
| 1408 | + 'mcp' => array( | |
| 1409 | + 'script' => plugin_dir_url(__FILE__) . 'assets/dist/js/mcp-agent-settings.min.js', | |
| 1410 | + 'style' => Wpfnl_functions::get_bundle_style_url('mcp-agent-settings'), | |
| 1411 | + ), | |
| 1412 | + ); | |
| 1413 | + } | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + /** | |
| 478 | 1417 | * Register the JavaScript for the admin area. |
| 479 | 1418 | * |
| 480 | 1419 | * @since 1.0.0 |
| 481 | 1420 | */ |
| @@ -494,34 +1433,104 @@ | ||
| 494 | 1433 | */ |
| 495 | 1434 | |
| 496 | 1435 | |
| 497 | 1436 | $screen = get_current_screen(); |
| 498 | - | |
| 499 | - if('dashboard' === $screen->id || 'plugins' === $screen->id ){ | |
| 500 | - wp_enqueue_script( $this->plugin_name.'-global', plugin_dir_url(__FILE__) . 'assets/js/wpfnl-global.js', ['jquery', 'jquery-ui-sortable'], $this->version, true ); | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + $this->enqueue_react_admin_assets($hook); | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + if ('dashboard' === $screen->id || 'plugins' === $screen->id) { | |
| 1443 | + wp_enqueue_script($this->plugin_name . '-global', plugin_dir_url(__FILE__) . 'assets/js/wpfnl-global.js', ['jquery', 'jquery-ui-sortable'], $this->version, true); | |
| 501 | 1444 | } |
| 502 | 1445 | |
| 503 | - | |
| 504 | - if ( 'wp-funnels_page_email-builder' === $hook ) { | |
| 1446 | + if ('wpfunnels_page_email-builder' === $hook) { | |
| 1447 | + $is_wc_installed = 'no'; | |
| 1448 | + $is_wpfunnels_installed = 'no'; | |
| 1449 | + if (is_plugin_active('woocommerce/woocommerce.php')) { | |
| 1450 | + $is_wc_installed = 'yes'; | |
| 1451 | + } | |
| 1452 | + if (is_plugin_active('wpfunnels/wpfunnels.php')) { | |
| 1453 | + $is_wpfunnels_installed = 'yes'; | |
| 1454 | + } | |
| 505 | 1455 | $dependency = require_once WPFNL_PATH . '/admin/assets/dist/email-builder/main.min.asset.php'; |
| 506 | 1456 | wp_enqueue_script( |
| 507 | - $this->plugin_name . '-email-builder', | |
| 508 | - plugin_dir_url(__FILE__) . 'assets/dist/email-builder/main.min.js', | |
| 509 | - $dependency['dependencies'], | |
| 510 | - $this->version, | |
| 511 | - true | |
| 1457 | + $this->plugin_name . '-email-builder', | |
| 1458 | + plugin_dir_url(__FILE__) . 'assets/dist/email-builder/main.min.js', | |
| 1459 | + $dependency['dependencies'], | |
| 1460 | + $this->version, | |
| 1461 | + true | |
| 512 | 1462 | ); |
| 513 | - wp_localize_script( | |
| 514 | - $this->plugin_name . '-email-builder', | |
| 515 | - 'WPFEmailBuilderVars', | |
| 516 | - array( | |
| 517 | - 'editor_data_source' => $this->get_editor_source(), | |
| 518 | - ) | |
| 519 | - ); | |
| 1463 | + wp_localize_script( | |
| 1464 | + $this->plugin_name . '-email-builder', | |
| 1465 | + 'WPFEmailBuilderVars', | |
| 1466 | + array( | |
| 1467 | + 'editor_data_source' => $this->get_editor_source(), | |
| 1468 | + 'post_types' => MrmCommon::get_all_post_types(), | |
| 1469 | + 'is_wc_installed' => $is_wc_installed, | |
| 1470 | + 'is_mint_active' => Wpfnl_functions::is_mint_mrm_active(), | |
| 1471 | + ) | |
| 1472 | + ); | |
| 520 | 1473 | } |
| 521 | - if ( in_array($hook, $this->page_hooks ) ) { | |
| 522 | - | |
| 523 | - $is_wc_installed = 'no'; | |
| 1474 | + | |
| 1475 | + // Store Checkout without WooCommerce: power the "Plugin Required" modal | |
| 1476 | + // rendered by admin/modules/store-checkout/views/woocommerce-required.php. | |
| 1477 | + if ('wpfunnels_page_' . WPFNL_STORE_CHECKOUT_SLUG === $hook && !Wpfnl_functions::is_wc_active()) { | |
| 1478 | + $wc_plugin = 'woocommerce/woocommerce.php'; | |
| 1479 | + $wc_status = Wpfnl_functions::is_plugin_installed($wc_plugin) ? 'inactive' : 'not-installed'; | |
| 1480 | + $wc_label = 'not-installed' === $wc_status | |
| 1481 | + ? __('Install WooCommerce', 'wpfnl') | |
| 1482 | + : __('Activate WooCommerce', 'wpfnl'); | |
| 1483 | + | |
| 1484 | + wp_enqueue_script( | |
| 1485 | + $this->plugin_name . '-store-checkout-woo', | |
| 1486 | + plugin_dir_url(__FILE__) . 'assets/js/wpfnl-store-checkout-woo.js', | |
| 1487 | + ['jquery', 'updates'], | |
| 1488 | + $this->version, | |
| 1489 | + true | |
| 1490 | + ); | |
| 1491 | + wp_localize_script($this->plugin_name . '-store-checkout-woo', 'wpfnlStoreCheckoutWoo', array( | |
| 1492 | + 'ajaxUrl' => admin_url('admin-ajax.php'), | |
| 1493 | + 'nonce' => wp_create_nonce('wpfnl_activate_plugin_nonce'), | |
| 1494 | + 'plugin' => $wc_plugin, | |
| 1495 | + 'slug' => 'woocommerce', | |
| 1496 | + 'status' => $wc_status, | |
| 1497 | + 'buttonLabel' => $wc_label, | |
| 1498 | + 'i18n' => array( | |
| 1499 | + 'installing' => __('Installing', 'wpfnl'), | |
| 1500 | + 'activating' => __('Activating', 'wpfnl'), | |
| 1501 | + 'redirecting' => __('Redirecting', 'wpfnl'), | |
| 1502 | + 'error' => __('Something went wrong. Please install and activate WooCommerce manually.', 'wpfnl'), | |
| 1503 | + ), | |
| 1504 | + )); | |
| 1505 | + } | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + if (in_array($hook, $this->page_hooks)) { | |
| 1509 | + | |
| 1510 | + // Admin header actions — the Knowledge Base, AI Assistant, Settings | |
| 1511 | + // and Upgrade group rendered into #wpfnl-header-actions from every | |
| 1512 | + // legacy WPFunnels admin screen. The data goes out under the | |
| 1513 | + // WPFNAIFunnel global because that is the name | |
| 1514 | + // admin/src/copilot/services/ai.js reads, and the drawer shares | |
| 1515 | + // that client with what is left of the copilot bundle. | |
| 1516 | + $_settings_page_url = admin_url( 'admin.php?page=' . WPFNL_MAIN_PAGE_SLUG ) . '#/settings'; | |
| 1517 | + | |
| 1518 | + wp_enqueue_script('wpfnl-global-ai-drawer', plugin_dir_url(__FILE__) . 'assets/dist/js/global-ai-drawer.min.js', [], $this->version, true); | |
| 1519 | + Wpfnl_functions::enqueue_bundle_style( 'global-ai-drawer', 'wpfnl-global-ai-drawer-bundle' ); | |
| 1520 | + wp_localize_script('wpfnl-global-ai-drawer', 'WPFNAIFunnel', array( | |
| 1521 | + 'adminUrl' => esc_url_raw( admin_url( 'admin.php' ) ), | |
| 1522 | + 'settingsPageUrl' => esc_url_raw( $_settings_page_url ), | |
| 1523 | + 'isPro' => (bool) apply_filters( 'wpfunnels/is_pro_license_activated', false ), | |
| 1524 | + 'upgradeUrl' => 'https://getwpfunnels.com/pricing/', | |
| 1525 | + 'restApiUrl' => esc_url_raw( get_rest_url() ), | |
| 1526 | + 'restNonce' => wp_create_nonce( 'wp_rest' ), | |
| 1527 | + 'rest_url' => esc_url_raw( get_rest_url() ), | |
| 1528 | + 'nonce' => wp_create_nonce( 'wp_rest' ), | |
| 1529 | + 'rest_nonce' => wp_create_nonce( 'wp_rest' ), | |
| 1530 | + )); | |
| 1531 | + | |
| 1532 | + $is_wc_installed = 'no'; | |
| 524 | 1533 | $is_wpfunnels_installed = 'no'; |
| 525 | 1534 | if (is_plugin_active('woocommerce/woocommerce.php')) { |
| 526 | 1535 | $is_wc_installed = 'yes'; |
| 527 | 1536 | } |
| @@ -542,27 +1551,32 @@ | ||
| 542 | 1551 | } |
| 543 | 1552 | } |
| 544 | 1553 | } |
| 545 | 1554 | |
| 546 | - $funnel_id = ''; | |
| 547 | - $funnel_title = ''; | |
| 548 | - $step_id = ''; | |
| 1555 | + $funnel_id = ''; | |
| 1556 | + $funnel_title = ''; | |
| 1557 | + $step_id = ''; | |
| 549 | 1558 | if (isset($_GET['id'])) { |
| 550 | - $funnel_id = $_GET['id']; | |
| 551 | - $funnel_title = html_entity_decode(get_the_title($funnel_id)); | |
| 1559 | + $funnel_id = $_GET['id']; | |
| 1560 | + $funnel_title = html_entity_decode(get_the_title($funnel_id)); | |
| 552 | 1561 | if (isset($_GET['step_id'])) { |
| 553 | 1562 | $step_id = filter_input(INPUT_GET, 'step_id', FILTER_VALIDATE_INT); |
| 554 | 1563 | } |
| 1564 | + | |
| 1565 | + // For store checkout funnels, resolve the checkout step ID when not in URL. | |
| 1566 | + if ( empty( $step_id ) && 'store_checkout' === get_post_meta( $funnel_id, '_wpfnl_funnel_type', true ) ) { | |
| 1567 | + $step_id = \WPFunnels\WooCommerce\Wpfnl_Store_Checkout_Conditions::get_checkout_step_id_for_funnel( $funnel_id ); | |
| 1568 | + } | |
| 555 | 1569 | } |
| 556 | 1570 | |
| 557 | 1571 | /** |
| 558 | - * Get funnel preview link | |
| 559 | - */ | |
| 560 | - $steps = get_post_meta( $funnel_id, '_steps_order', true ); | |
| 561 | - $funnel_preview_link = '#'; | |
| 1572 | + * Get funnel preview link | |
| 1573 | + */ | |
| 1574 | + $steps = get_post_meta($funnel_id, '_steps_order', true); | |
| 1575 | + $funnel_preview_link = '#'; | |
| 562 | 1576 | $response['success'] = false; |
| 563 | 1577 | if ($steps) { |
| 564 | - if ( isset($steps[0]) && $steps[0]['id'] ) { | |
| 1578 | + if (isset($steps[0]) && $steps[0]['id']) { | |
| 565 | 1579 | $funnel_preview_link = get_post_permalink($steps[0]['id']); |
| 566 | 1580 | } |
| 567 | 1581 | } |
| 568 | 1582 | |
| @@ -571,205 +1585,293 @@ | ||
| 571 | 1585 | wp_enqueue_editor(); |
| 572 | 1586 | wp_enqueue_script('wp-color-picker'); |
| 573 | 1587 | wp_enqueue_media(); |
| 574 | 1588 | |
| 575 | - wp_enqueue_script( $this->plugin_name . '-jed', plugin_dir_url(__FILE__) . 'assets/js/jed.js', ['jquery'], $this->version, true ); | |
| 576 | - wp_enqueue_script( $this->plugin_name, plugin_dir_url(__FILE__) . 'assets/js/wpfnl-admin.js', ['jquery', 'jquery-ui-sortable'], $this->version, true ); | |
| 577 | - wp_enqueue_script( $this->plugin_name . '-runtime', plugin_dir_url(__FILE__) . 'assets/dist/runtime/index.min.js', ['jquery', 'wp-i18n', 'wp-util', 'updates', 'wp-color-picker', $this->plugin_name . '-jed'], $this->version, true ); | |
| 578 | - wp_enqueue_script( $this->plugin_name . '-funnel-window', plugin_dir_url(__FILE__) . 'assets/dist/js/funnel-components.min.js', ['jquery', 'wp-i18n', 'wp-util', 'updates', 'wp-color-picker', $this->plugin_name . '-jed', $this->plugin_name . '-runtime'], $this->version, true ); | |
| 579 | - wp_enqueue_script( $this->plugin_name . '-backbone-marionette', plugin_dir_url(__FILE__) . 'assets/lib/backbone/backbone.marionette.min.js', ['backbone'], $this->version, true ); | |
| 580 | - wp_enqueue_script( $this->plugin_name . '-backbone-radio', plugin_dir_url(__FILE__) . 'assets/lib/backbone/backbone.radio.min.js', ['backbone'], $this->version, true ); | |
| 1589 | + wp_enqueue_script($this->plugin_name . '-jed', plugin_dir_url(__FILE__) . 'assets/js/jed.js', ['jquery'], $this->version, true); | |
| 1590 | + wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'assets/js/wpfnl-admin.js', ['jquery', 'jquery-ui-sortable'], $this->version, true); | |
| 581 | 1591 | |
| 582 | - $general_settings = Wpfnl_functions::get_general_settings(); | |
| 583 | - $builder = $general_settings['builder']; | |
| 1592 | + wp_enqueue_script($this->plugin_name . '-runtime', plugin_dir_url(__FILE__) . 'assets/dist/runtime/index.min.js', ['jquery', 'wp-i18n', 'wp-util', 'updates', 'wp-color-picker', $this->plugin_name . '-jed'], $this->version, true); | |
| 1593 | + wp_enqueue_script($this->plugin_name . '-funnel-window', plugin_dir_url(__FILE__) . 'assets/dist/js/funnel-components.min.js', ['jquery', 'wp-i18n', 'wp-util', 'updates', 'wp-color-picker', $this->plugin_name . '-jed', $this->plugin_name . '-runtime'], $this->version, true); | |
| 1594 | + Wpfnl_functions::enqueue_bundle_style( 'funnel-components', $this->plugin_name . '-funnel-window-bundle' ); | |
| 1595 | + wp_enqueue_script($this->plugin_name . '-backbone-marionette', plugin_dir_url(__FILE__) . 'assets/lib/backbone/backbone.marionette.min.js', ['backbone'], $this->version, true); | |
| 1596 | + wp_enqueue_script($this->plugin_name . '-backbone-radio', plugin_dir_url(__FILE__) . 'assets/lib/backbone/backbone.radio.min.js', ['backbone'], $this->version, true); | |
| 584 | 1597 | |
| 1598 | + $general_settings = Wpfnl_functions::get_general_settings(); | |
| 1599 | + $builder = $general_settings['builder']; | |
| 1600 | + $funnel_builder_mode = Wpfnl_functions::get_default_funnel_builder_mode(); | |
| 1601 | + $canvas_view_mode = Wpfnl_functions::get_canvas_view_mode(); | |
| 1602 | + | |
| 585 | 1603 | /** |
| 586 | 1604 | * This code snippet will check if pro addons is activated or not. if not activated |
| 587 | 1605 | * Total number of funnels will be maximum 3, otherwise customer can add as more funnels |
| 588 | 1606 | * As they want |
| 589 | 1607 | */ |
| 590 | - $is_pro_active = apply_filters( 'wpfunnels/is_pro_license_activated', false ); | |
| 591 | - $count_funnels = wp_count_posts('wpfunnels')->publish + wp_count_posts('wpfunnels')->draft; | |
| 1608 | + $is_pro_active = apply_filters('wpfunnels/is_pro_license_activated', false); | |
| 1609 | + $count_funnels = Wpfnl_functions::count_non_store_checkout_funnels( array( 'publish', 'draft', 'trash' ) ); | |
| 1610 | + $count_active_funnels = Wpfnl_functions::count_non_store_checkout_funnels(); | |
| 592 | 1611 | $total_allowed_funnels = 3; |
| 593 | 1612 | if ($is_pro_active) { |
| 594 | 1613 | $total_allowed_funnels = -1; |
| 595 | 1614 | } |
| 1615 | + $count_store_checkouts = Wpfnl_functions::count_store_checkout_funnels(); | |
| 1616 | + $total_allowed_store_checkouts = $is_pro_active ? -1 : 3; | |
| 596 | 1617 | |
| 597 | 1618 | $wc_currency_symbol = '$'; |
| 598 | - if ( function_exists('get_woocommerce_currency_symbol') ) { | |
| 599 | - $wc_currency_symbol = html_entity_decode( get_woocommerce_currency_symbol() ); | |
| 1619 | + if (function_exists('get_woocommerce_currency_symbol')) { | |
| 1620 | + $wc_currency_symbol = html_entity_decode(get_woocommerce_currency_symbol()); | |
| 600 | 1621 | } |
| 601 | 1622 | $ld_currency_symbol = '$'; |
| 602 | - if ( function_exists('learndash_get_currency_symbol') ) { | |
| 603 | - $ld_currency_symbol = html_entity_decode( learndash_get_currency_symbol() ); | |
| 1623 | + if (function_exists('learndash_get_currency_symbol')) { | |
| 1624 | + $ld_currency_symbol = html_entity_decode(learndash_get_currency_symbol()); | |
| 604 | 1625 | } |
| 605 | 1626 | |
| 606 | - wp_localize_script( $this->plugin_name, 'WPFunnelVars', array( | |
| 607 | - 'ajaxurl' => admin_url( 'admin-ajax.php' ), | |
| 608 | - 'rest_api_url' => get_rest_url(), | |
| 609 | - 'security' => wp_create_nonce('wpfnl-admin'), | |
| 610 | - 'admin_url' => admin_url(), | |
| 611 | - 'edit_funnel_url' => admin_url('admin.php?page=edit_funnel'), | |
| 612 | - 'i18n' => array( 'wpfnl' => $this->get_jed_locale_data( 'wpfnl' ) ), | |
| 613 | - 'is_wc_installed' => $is_wc_installed, | |
| 614 | - 'is_wpfunnels_installed' => $is_wpfunnels_installed, | |
| 615 | - 'products' => $products, | |
| 616 | - 'funnel_id' => $funnel_id, | |
| 617 | - 'step_id' => $step_id, | |
| 618 | - 'funnel_title' => $funnel_title, | |
| 619 | - 'funnel_preview_link' => $funnel_preview_link, | |
| 620 | - 'site_url' => site_url(), | |
| 621 | - 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 622 | - 'placeholder_image_path' => WPFNL_URL . 'admin/assets/images/ob_placeholder.png', | |
| 623 | - 'nonce' => wp_create_nonce('wp_rest'), | |
| 624 | - 'isNewFunnel' => \Wpfnl_Activator::is_new_install() ? true : false, | |
| 625 | - 'isProActivated' => $is_pro_active, | |
| 626 | - 'totalFunnels' => $count_funnels, | |
| 627 | - 'totalAllowedFunnels' => $total_allowed_funnels, | |
| 628 | - 'builder' => $builder, | |
| 629 | - 'dependencyPlugins' => Wpfnl_functions::get_dependency_plugins_status(), | |
| 630 | - 'allCoupons' => Wpfnl_functions::get_all_coupons(), | |
| 631 | - 'isAnyPluginMissing' => Wpfnl_functions::is_any_plugin_missing(), | |
| 632 | - 'isGlobalFunnelActivated' => Wpfnl_functions::is_global_funnel_activated(), | |
| 633 | - 'isGlobalFunnel' => Wpfnl_functions::is_global_funnel( $funnel_id ), | |
| 634 | - 'GBFVersion' => defined('WPFNL_PRO_GB_VERSION') ? WPFNL_PRO_GB_VERSION : '', | |
| 635 | - 'isSkipOffer' => $this->is_skip_offer(), | |
| 636 | - 'paymentMethod' => $this->get_payment_method(), | |
| 637 | - 'shippingMethod' => $this->get_shipping_method(), | |
| 638 | - 'isGbf' => $this->maybe_gbf( $funnel_id ), | |
| 639 | - 'isLms' => $this->maybe_lms( $funnel_id ), | |
| 640 | - 'isLmsActivated' => Wpfnl_functions::is_lms_addon_active(), | |
| 641 | - 'isLmsSettings' => Wpfnl_functions::is_enable_lms_settings(), | |
| 642 | - 'isLmsDisbaled' => $this->maybe_lms_settings_disbaled(), | |
| 643 | - 'lmsVersion' => defined( 'WPFNL_PRO_LMS_VERSION' ) || defined( 'WPFUNNELS_PRO_LMS_VERSION' ) ? version_compare(LEARNDASH_VERSION, '4.2.1.1', '>=') : false, | |
| 644 | - 'global_funnel_type' => Wpfnl_functions::get_global_funnel_type(), | |
| 645 | - 'individual_funnel_type' => get_post_meta( $funnel_id, '_wpfnl_funnel_type', true ), | |
| 646 | - 'gbf_set_condition_steps' => $this->get_gbf_steps($funnel_id), | |
| 647 | - 'mint_steps' => $this->mint_step_settings($funnel_id), | |
| 648 | - 'mint_triggers' => Wpfnl_functions::get_mint_triggers(), | |
| 649 | - 'mint_actions' => Wpfnl_functions::get_mint_actions(), | |
| 650 | - 'mint_tags' => Wpfnl_functions::get_mint_contact_groups( 'tags' ), | |
| 651 | - 'mint_lists' => Wpfnl_functions::get_mint_contact_groups( 'lists' ), | |
| 652 | - 'mint_sequences' => Wpfnl_functions::get_sequences(), | |
| 653 | - 'obList' => Wpfnl_functions::get_all_ob( $funnel_id ), | |
| 654 | - 'upsellSteps' => Wpfnl_functions::get_selected_steps( 'upsell', $funnel_id ), | |
| 655 | - 'downsellSteps' => Wpfnl_functions::get_selected_steps( 'downsell', $funnel_id ), | |
| 656 | - 'landingAndCustomSteps' => Wpfnl_functions::get_selected_steps( 'landing', $funnel_id ), | |
| 657 | - 'customSteps' => Wpfnl_functions::get_selected_steps( 'custom', $funnel_id ), | |
| 658 | - 'onlySettingsSteps' => Wpfnl_functions::get_only_settings_steps(), | |
| 659 | - 'cfeDefault' => Wpfnl_functions::get_cfe_default_fields(), | |
| 660 | - 'adminEmail' => get_bloginfo( 'admin_email' ), | |
| 661 | - 'mailMintEmail' => Wpfnl_functions::get_mailmint_email(), | |
| 662 | - 'emailBuilderUrl' => admin_url().'admin.php?page=email-builder', | |
| 663 | - 'currentUrl' => (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", | |
| 664 | - 'wc_currency' => $wc_currency_symbol, | |
| 665 | - 'ld_currency' => $ld_currency_symbol, | |
| 1627 | + $product_url = esc_url_raw( | |
| 1628 | + add_query_arg( | |
| 1629 | + array( | |
| 1630 | + 'post_type' => 'product', | |
| 1631 | + 'wpfunnels' => 'yes', | |
| 1632 | + ), | |
| 1633 | + admin_url('post-new.php') | |
| 1634 | + ) | |
| 1635 | + ); | |
| 1636 | + | |
| 1637 | + wp_localize_script($this->plugin_name, 'WPFunnelVars', array( | |
| 1638 | + 'ajaxurl' => admin_url('admin-ajax.php'), | |
| 1639 | + 'rest_api_url' => get_rest_url(), | |
| 1640 | + 'security' => wp_create_nonce('wpfnl-admin'), | |
| 1641 | + 'import_nonce' => wp_create_nonce('wpfnl_import_funnels_nonce'), | |
| 1642 | + 'admin_url' => admin_url(), | |
| 1643 | + 'edit_funnel_url' => admin_url('admin.php?page=edit_funnel'), | |
| 1644 | + 'i18n' => array('wpfnl' => $this->get_jed_locale_data('wpfnl')), | |
| 1645 | + 'current_user_id' => get_current_user_id(), | |
| 1646 | + 'is_wc_installed' => $is_wc_installed, | |
| 1647 | + 'is_wpfunnels_installed' => $is_wpfunnels_installed, | |
| 1648 | + 'products' => $products, | |
| 1649 | + 'funnel_id' => $funnel_id, | |
| 1650 | + 'step_id' => $step_id, | |
| 1651 | + 'funnel_title' => $funnel_title, | |
| 1652 | + 'funnel_preview_link' => $funnel_preview_link, | |
| 1653 | + 'site_url' => site_url(), | |
| 1654 | + 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 1655 | + 'placeholder_image_path' => WPFNL_URL . 'admin/assets/images/ob_placeholder.png', | |
| 1656 | + 'nonce' => wp_create_nonce('wp_rest'), | |
| 1657 | + 'isNewFunnel' => \Wpfnl_Activator::is_new_install() ? true : false, | |
| 1658 | + 'isProActivated' => $is_pro_active, | |
| 1659 | + 'totalFunnels' => $count_funnels, | |
| 1660 | + 'count_active_funnels' => $count_active_funnels, | |
| 1661 | + 'totalStoreCheckouts' => $count_store_checkouts, | |
| 1662 | + 'totalAllowedStoreCheckouts' => $total_allowed_store_checkouts, | |
| 1663 | + 'product_url' => $product_url, | |
| 1664 | + 'totalAllowedFunnels' => $total_allowed_funnels, | |
| 1665 | + 'builder' => $builder, | |
| 1666 | + 'funnel_builder_mode' => $funnel_builder_mode, | |
| 1667 | + 'canvas_view_mode' => $canvas_view_mode, | |
| 1668 | + 'dependencyPlugins' => Wpfnl_functions::get_dependency_plugins_status(), | |
| 1669 | + 'isAnyPluginMissing' => Wpfnl_functions::is_any_plugin_missing(), | |
| 1670 | + 'isGlobalFunnelActivated' => Wpfnl_functions::is_global_funnel_activated(), | |
| 1671 | + 'isGlobalFunnel' => Wpfnl_functions::is_global_funnel($funnel_id), | |
| 1672 | + 'GBFVersion' => defined('WPFNL_PRO_GBF_VERSION') ? WPFNL_PRO_GBF_VERSION : ( defined('WPFNL_PRO_GB_VERSION') ? WPFNL_PRO_GB_VERSION : '' ), | |
| 1673 | + 'isSkipOffer' => $this->is_skip_offer(), | |
| 1674 | + 'paymentMethod' => $this->get_payment_method(), | |
| 1675 | + 'shippingMethod' => $this->get_shipping_method(), | |
| 1676 | + 'isGbf' => $this->maybe_gbf($funnel_id), | |
| 1677 | + 'isLms' => $this->maybe_lms($funnel_id), | |
| 1678 | + 'lmsProvider' => $this->get_lms_provider(), | |
| 1679 | + 'isLmsActivated' => Wpfnl_functions::is_lms_addon_active(), | |
| 1680 | + 'isAnyLmsPluginActive' => Wpfnl_functions::is_any_lms_plugin_active(), | |
| 1681 | + 'isLmsSettings' => Wpfnl_functions::is_enable_lms_settings(), | |
| 1682 | + 'isLmsDisbaled' => $this->maybe_lms_settings_disbaled(), | |
| 1683 | + 'lmsVersion' => (defined('WPFNL_PRO_LMS_VERSION') || defined('WPFUNNELS_PRO_LMS_VERSION')) && defined('LEARNDASH_VERSION') ? version_compare(LEARNDASH_VERSION, '4.2.1.1', '>=') : false, | |
| 1684 | + 'individual_funnel_type' => get_post_meta($funnel_id, '_wpfnl_funnel_type', true), | |
| 1685 | + 'isStoreCheckout' => get_post_meta($funnel_id, '_wpfnl_funnel_type', true) === 'store_checkout', | |
| 1686 | + 'isSaleFunnel' => get_post_meta($funnel_id, '_wpfnl_funnel_type', true) === 'wc' || get_post_meta($funnel_id, '_wpfnl_funnel_type', true) === 'store_checkout', | |
| 1687 | + 'gbf_set_condition_steps' => $this->get_gbf_steps($funnel_id), | |
| 1688 | + 'reconfigurable_condition_data' => $this->get_reconfigurable_condition_data($funnel_id), | |
| 1689 | + 'mint_steps' => $this->mint_step_settings($funnel_id), | |
| 1690 | + 'mint_tags' => Wpfnl_functions::get_mint_contact_groups('tags'), | |
| 1691 | + 'mint_lists' => Wpfnl_functions::get_mint_contact_groups('lists'), | |
| 1692 | + 'mint_sequences' => Wpfnl_functions::get_sequences(), | |
| 1693 | + 'obList' => Wpfnl_functions::get_all_ob($funnel_id), | |
| 1694 | + 'upsellSteps' => Wpfnl_functions::get_selected_steps('upsell', $funnel_id), | |
| 1695 | + 'downsellSteps' => Wpfnl_functions::get_selected_steps('downsell', $funnel_id), | |
| 1696 | + 'landingAndCustomSteps' => Wpfnl_functions::get_selected_steps('landing', $funnel_id), | |
| 1697 | + 'customSteps' => Wpfnl_functions::get_selected_steps('custom', $funnel_id), | |
| 1698 | + 'onlySettingsSteps' => Wpfnl_functions::get_only_settings_steps(), | |
| 1699 | + 'isWCML' => defined('WCML_VERSION'), | |
| 1700 | + 'cfeDefault' => Wpfnl_functions::get_cfe_default_fields(), | |
| 1701 | + 'adminEmail' => get_bloginfo('admin_email'), | |
| 1702 | + 'siteName' => get_option('blogname'), | |
| 1703 | + 'mailMintEmail' => Wpfnl_functions::get_mailmint_email(), | |
| 1704 | + 'email_settings' => Wpfnl_functions::get_mailmint_email_settings(), | |
| 1705 | + 'mint_twillo_settings' => Wpfnl_functions::get_mailmint_twillo_settings(), | |
| 1706 | + 'emailBuilderUrl' => admin_url() . 'admin.php?page=email-builder', | |
| 1707 | + 'currentUrl' => (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", | |
| 1708 | + 'wc_currency' => $wc_currency_symbol, | |
| 1709 | + 'ld_currency' => $ld_currency_symbol, | |
| 1710 | + 'getText' => Wpfnl_functions::get_text(), | |
| 1711 | + 'user_role_manager_data' => Wpfnl_functions::get_user_role_settings(), | |
| 1712 | + 'availableGateways' => Wpfnl_functions::get_enabled_payment_gateways(), | |
| 1713 | + 'guidedTour' => Wpfnl_functions::get_guided_tour(), | |
| 1714 | + 'isWPFIntegrationActive' => apply_filters( 'wpfunnels/is_integration_license_active', false ), | |
| 666 | 1715 | )); |
| 667 | - wp_localize_script( $this->plugin_name, 'template_library_object', | |
| 1716 | + wp_localize_script( | |
| 1717 | + $this->plugin_name, | |
| 1718 | + 'template_library_object', | |
| 668 | 1719 | array( |
| 669 | - 'ajaxurl' => esc_url_raw(admin_url('admin-ajax.php')), | |
| 670 | - 'rest_api_url' => esc_url_raw(get_rest_url()), | |
| 671 | - 'dashboard_url' => esc_url_raw(admin_url('admin.php?page=' . WPFNL_MAIN_PAGE_SLUG)), | |
| 672 | - 'settings_url' => esc_url_raw(admin_url('admin.php?page=settings')), | |
| 673 | - 'home_url' => esc_url_raw(home_url()), | |
| 674 | - 'funnel_id' => $funnel_id, | |
| 675 | - 'is_pro' => Wpfnl_functions::is_pro_license_activated(), | |
| 676 | - 'is_ab_tesing_available'=> defined('WPFNL_PRO_VERSION') ? version_compare( WPFNL_PRO_VERSION, "1.7.3", ">=" ) : false, | |
| 677 | - 'is_webhook_licensed' => Wpfnl_functions::is_webhook_license_activated(), | |
| 678 | - 'pro_url' => add_query_arg('wpfnl-dashboard', '1', GETWPFUNNEL_HOME_URL), | |
| 679 | - 'nonce' => wp_create_nonce('wp_rest'), | |
| 680 | - 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 681 | - 'template_type' => Wpfnl_functions::get_template_types(), | |
| 682 | - 'countries' => Wpfnl_functions::get_countries(), | |
| 683 | - 'supported_steps' => Wpfnl_functions::get_supported_step_type(), | |
| 684 | - 'is_mint_active' => Wpfnl_functions::is_mint_mrm_active(), | |
| 685 | - 'settingsSteps' => Wpfnl_functions::get_settings_steps(), | |
| 686 | - ) | |
| 1720 | + 'ajaxurl' => esc_url_raw(admin_url('admin-ajax.php')), | |
| 1721 | + 'rest_api_url' => esc_url_raw(get_rest_url()), | |
| 1722 | + 'dashboard_url' => ( $funnel_id && get_post_meta( $funnel_id, '_wpfnl_funnel_type', true ) === 'store_checkout' ) | |
| 1723 | + ? esc_url_raw(admin_url('admin.php?page=store_checkout')) | |
| 1724 | + : esc_url_raw(admin_url('admin.php?page=' . WPFNL_FUNNEL_PAGE_SLUG)), | |
| 1725 | + 'settings_url' => esc_url_raw(admin_url('admin.php?page=settings')), | |
| 1726 | + 'home_url' => esc_url_raw(home_url()), | |
| 1727 | + 'funnel_id' => $funnel_id, | |
| 1728 | + 'is_pro' => Wpfnl_functions::is_pro_license_activated(), | |
| 1729 | + 'is_ab_tesing_available' => defined('WPFNL_PRO_VERSION') ? version_compare(WPFNL_PRO_VERSION, "1.7.3", ">=") : false, | |
| 1730 | + 'is_webhook_licensed' => Wpfnl_functions::is_webhook_license_activated(), | |
| 1731 | + 'pro_url' => add_query_arg('wpfnl-dashboard', '1', GETWPFUNNEL_PRICING_URL), | |
| 1732 | + 'nonce' => wp_create_nonce('wp_rest'), | |
| 1733 | + 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 1734 | + 'template_type' => Wpfnl_functions::get_template_types(), | |
| 1735 | + 'countries' => Wpfnl_functions::get_countries(), | |
| 1736 | + 'supported_steps' => Wpfnl_functions::get_supported_step_type(), | |
| 1737 | + 'is_mint_active' => Wpfnl_functions::is_mint_mrm_active(), | |
| 1738 | + 'settingsSteps' => Wpfnl_functions::get_settings_steps(), | |
| 1739 | + 'isRemote' => Wpfnl_functions::maybe_remote_funnel(), | |
| 1740 | + 'isStoreCheckout' => 'wpfunnels_page_store_checkout' === $hook, | |
| 1741 | + ) | |
| 687 | 1742 | ); |
| 688 | - | |
| 689 | - wp_localize_script( $this->plugin_name, 'CheckoutStep', | |
| 1743 | + | |
| 1744 | + wp_localize_script( | |
| 1745 | + $this->plugin_name, | |
| 1746 | + 'CheckoutStep', | |
| 690 | 1747 | array( |
| 691 | - 'ajaxurl' => esc_url_raw(admin_url('admin-ajax.php')), | |
| 692 | - 'rest_api_url' => esc_url_raw(get_rest_url()), | |
| 693 | - 'wc_currency' => $wc_currency_symbol, | |
| 694 | - 'nonce' => wp_create_nonce('wp_rest'), | |
| 695 | - 'security' => wp_create_nonce('wpfnl-admin'), | |
| 696 | - 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 697 | - 'tooltipIcon' => WPFNL_URL . 'admin/partials/icons/question-tooltip-icon.php', | |
| 698 | - 'imageUploadIcon' => WPFNL_URL . 'admin/partials/icons/image-upload-icon.php', | |
| 699 | - 'step_id' => $step_id, | |
| 700 | - 'back' => add_query_arg( | |
| 701 | - array( | |
| 702 | - 'page' => WPFNL_EDIT_FUNNEL_SLUG, | |
| 703 | - 'id' => filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT), | |
| 704 | - 'step_id' => $step_id, | |
| 705 | - ), | |
| 706 | - admin_url('admin.php') | |
| 707 | - ) | |
| 708 | - ) | |
| 1748 | + 'ajaxurl' => esc_url_raw(admin_url('admin-ajax.php')), | |
| 1749 | + 'rest_api_url' => esc_url_raw(get_rest_url()), | |
| 1750 | + 'wc_currency' => $wc_currency_symbol, | |
| 1751 | + 'nonce' => wp_create_nonce('wp_rest'), | |
| 1752 | + 'security' => wp_create_nonce('wpfnl-admin'), | |
| 1753 | + 'image_path' => WPFNL_URL . 'admin/assets/images', | |
| 1754 | + 'tooltipIcon' => WPFNL_URL . 'admin/partials/icons/question-tooltip-icon.php', | |
| 1755 | + 'imageUploadIcon' => WPFNL_URL . 'admin/partials/icons/image-upload-icon.php', | |
| 1756 | + 'step_id' => $step_id, | |
| 1757 | + 'back' => add_query_arg( | |
| 1758 | + array( | |
| 1759 | + 'page' => WPFNL_EDIT_FUNNEL_SLUG, | |
| 1760 | + 'id' => filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT), | |
| 1761 | + 'step_id' => $step_id, | |
| 1762 | + ), | |
| 1763 | + admin_url('admin.php') | |
| 1764 | + ), | |
| 1765 | + 'priceConfig' => Wpfnl_functions::get_wc_price_config(), | |
| 1766 | + ) | |
| 709 | 1767 | ); |
| 710 | 1768 | |
| 711 | - wp_localize_script( $this->plugin_name, 'wpfnl_addons_vars', | |
| 1769 | + wp_localize_script( | |
| 1770 | + $this->plugin_name, | |
| 1771 | + 'wpfnl_addons_vars', | |
| 712 | 1772 | array( |
| 713 | - 'addons' => Wpfnl_functions::get_supported_addons(), | |
| 714 | - 'gbf_conditions' => Wpfnl_functions::get_supported_gbf_offer_condition(), | |
| 715 | - 'categories' => Wpfnl_functions::get_categories_gbf_offer_condition(), | |
| 716 | - 'role' => Wpfnl_functions::get_all_user_roles(), | |
| 717 | - 'tags' => Wpfnl_functions::get_all_tags(), | |
| 718 | - 'shippingClasses'=> Wpfnl_functions::get_shipping_classes(), | |
| 719 | - ) | |
| 1773 | + 'addons' => Wpfnl_functions::get_supported_addons(), | |
| 1774 | + 'gbf_conditions' => Wpfnl_functions::get_supported_gbf_offer_condition(), | |
| 1775 | + 'categories' => Wpfnl_functions::get_categories_gbf_offer_condition(), | |
| 1776 | + 'role' => Wpfnl_functions::get_all_user_roles(), | |
| 1777 | + 'tags' => Wpfnl_functions::get_all_tags(), | |
| 1778 | + 'shippingClasses' => Wpfnl_functions::get_shipping_classes(), | |
| 1779 | + ) | |
| 720 | 1780 | ); |
| 721 | 1781 | |
| 1782 | + | |
| 722 | 1783 | /** |
| 723 | 1784 | * Localize scripts for funnel window |
| 724 | - * | |
| 1785 | + * | |
| 725 | 1786 | * @var $localize |
| 726 | 1787 | */ |
| 727 | 1788 | |
| 728 | 1789 | $notices = $this->get_builder_notice(); |
| 729 | 1790 | |
| 730 | - $localize = apply_filters( 'wpfunnels/funnel_window_admin_localize', array() ); | |
| 731 | - wp_localize_script( $this->plugin_name . '-funnel-window', 'wpfunnels_funnel_localize', array($localize)); | |
| 732 | - do_action( 'wpfunnels_after_scripts_loaded' ); | |
| 1791 | + $localize = apply_filters('wpfunnels/funnel_window_admin_localize', array()); | |
| 1792 | + wp_localize_script($this->plugin_name . '-funnel-window', 'wpfunnels_funnel_localize', array($localize)); | |
| 1793 | + | |
| 1794 | + | |
| 1795 | + do_action('wpfunnels_after_scripts_loaded'); | |
| 733 | 1796 | } |
| 734 | 1797 | } |
| 735 | 1798 | |
| 736 | 1799 | |
| 1800 | + public function get_lms_provider() | |
| 1801 | + { | |
| 1802 | + $lms_settings = get_option('_wpfunnels_lms_settings', array()); | |
| 1803 | + $provider_id = isset($lms_settings['lms_provider']) ? $lms_settings['lms_provider'] : 'learndash'; | |
| 1804 | + return $provider_id; | |
| 1805 | + } | |
| 1806 | + | |
| 1807 | + | |
| 737 | 1808 | /** |
| 1809 | + * Get the reconfigurable condition data for a funnel | |
| 1810 | + */ | |
| 1811 | + public function get_reconfigurable_condition_data($funnel_id) | |
| 1812 | + { | |
| 1813 | + if (!$funnel_id) { | |
| 1814 | + return []; | |
| 1815 | + } | |
| 1816 | + $data = get_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', true); | |
| 1817 | + if (!is_array($data) || empty($data)) { | |
| 1818 | + return []; | |
| 1819 | + } | |
| 1820 | + return $data; | |
| 1821 | + } | |
| 1822 | + | |
| 1823 | + | |
| 1824 | + /** | |
| 738 | 1825 | * Get all setps where GBF conditions is already set |
| 739 | - * | |
| 1826 | + * | |
| 740 | 1827 | * @param Integer $funnel_id |
| 741 | - * | |
| 1828 | + * | |
| 742 | 1829 | * @since 2.6.1 |
| 743 | 1830 | */ |
| 744 | - private function get_gbf_steps( $funnel_id ){ | |
| 1831 | + private function get_gbf_steps($funnel_id) | |
| 1832 | + { | |
| 745 | 1833 | $gbf_steps = []; |
| 746 | - if( $funnel_id ){ | |
| 747 | - $is_gbf = get_post_meta($funnel_id, 'is_global_funnel', true); | |
| 748 | - if( 'yes' === $is_gbf ){ | |
| 749 | - $steps = Wpfnl_functions::get_steps( $funnel_id ); | |
| 750 | - if( is_array($steps) ){ | |
| 751 | - foreach($steps as $step ){ | |
| 752 | - if( isset($step['id'], $step['step_type']) ){ | |
| 753 | - if( 'checkout' === $step['step_type'] ){ | |
| 754 | - $conditions = get_post_meta( $funnel_id, 'global_funnel_start_condition', true ); | |
| 755 | - if( is_array($conditions) ){ | |
| 756 | - array_push( $gbf_steps, $step['id'] ); | |
| 1834 | + if ($funnel_id) { | |
| 1835 | + $funnel_type = get_post_meta($funnel_id, '_wpfnl_funnel_type', true); | |
| 1836 | + $is_gbf = get_post_meta($funnel_id, 'is_global_funnel', true); | |
| 1837 | + | |
| 1838 | + if ('yes' === $is_gbf) { | |
| 1839 | + $steps = Wpfnl_functions::get_steps($funnel_id); | |
| 1840 | + if (is_array($steps)) { | |
| 1841 | + foreach ($steps as $step) { | |
| 1842 | + if (isset($step['id'], $step['step_type'])) { | |
| 1843 | + if ('checkout' === $step['step_type']) { | |
| 1844 | + $conditions = get_post_meta($funnel_id, 'global_funnel_start_condition', true); | |
| 1845 | + if (is_array($conditions)) { | |
| 1846 | + array_push($gbf_steps, $step['id']); | |
| 757 | 1847 | } |
| 758 | - }elseif( 'upsell' === $step['step_type'] || 'downsell' === $step['step_type'] ){ | |
| 759 | - | |
| 760 | - $conditions = get_post_meta( $step['id'], 'global_funnel_'.$step['step_type'].'_rules', true ); | |
| 761 | - if( is_array($conditions) ){ | |
| 762 | - array_push( $gbf_steps, $step['id'] ); | |
| 1848 | + } | |
| 1849 | + elseif ('upsell' === $step['step_type'] || 'downsell' === $step['step_type']) { | |
| 1850 | + $conditions = get_post_meta($step['id'], 'global_funnel_' . $step['step_type'] . '_rules', true); | |
| 1851 | + if (is_array($conditions)) { | |
| 1852 | + array_push($gbf_steps, $step['id']); | |
| 763 | 1853 | } |
| 764 | 1854 | } |
| 765 | 1855 | } |
| 766 | - | |
| 767 | 1856 | } |
| 768 | 1857 | } |
| 1858 | + } elseif ('store_checkout' === $funnel_type) { | |
| 1859 | + $steps = Wpfnl_functions::get_steps($funnel_id); | |
| 1860 | + if (is_array($steps)) { | |
| 1861 | + foreach ($steps as $step) { | |
| 1862 | + if (isset($step['id'], $step['step_type']) && 'checkout' === $step['step_type']) { | |
| 1863 | + $raw = get_post_meta($step['id'], '_wpfnl_store_checkout_condition', true); | |
| 1864 | + $condition = is_string($raw) ? json_decode($raw, true) : $raw; | |
| 1865 | + if (is_array($condition) && isset($condition['condition_type']) && 'rules' === $condition['condition_type']) { | |
| 1866 | + array_push($gbf_steps, $step['id']); | |
| 1867 | + } | |
| 1868 | + } | |
| 1869 | + } | |
| 1870 | + } | |
| 769 | 1871 | } |
| 770 | 1872 | } |
| 771 | - | |
| 1873 | + | |
| 772 | 1874 | return $gbf_steps; |
| 773 | 1875 | } |
| 774 | 1876 | |
| 775 | 1877 | |
| @@ -779,34 +1881,36 @@ | ||
| 779 | 1881 | * @param string $domain Translation domain. |
| 780 | 1882 | * |
| 781 | 1883 | * @return array |
| 782 | 1884 | */ |
| 783 | - public function get_jed_locale_data( $domain, $language_dir = null ) { | |
| 784 | - $plugin_translations = $this->get_translations_for_plugin_domain( $domain, $language_dir ); | |
| 785 | - $translations = get_translations_for_domain( $domain ); | |
| 1885 | + public function get_jed_locale_data($domain, $language_dir = null) | |
| 1886 | + { | |
| 1887 | + $plugin_translations = $this->get_translations_for_plugin_domain($domain, $language_dir); | |
| 1888 | + $translations = get_translations_for_domain($domain); | |
| 786 | 1889 | |
| 787 | 1890 | $locale = array( |
| 788 | - 'domain' => $domain, | |
| 1891 | + 'domain' => $domain, | |
| 789 | 1892 | 'locale_data' => array( |
| 790 | 1893 | $domain => array( |
| 791 | 1894 | '' => array( |
| 792 | 1895 | 'domain' => $domain, |
| 793 | - 'lang' => is_admin() ? get_user_locale() : get_locale(), | |
| 1896 | + 'lang' => is_admin() ? get_user_locale() : get_locale(), | |
| 794 | 1897 | ), |
| 795 | 1898 | ), |
| 796 | 1899 | ), |
| 797 | 1900 | ); |
| 798 | 1901 | |
| 799 | - if ( ! empty( $translations->headers['Plural-Forms'] ) ) { | |
| 800 | - $locale['locale_data'][ $domain ]['']['plural_forms'] = $translations->headers['Plural-Forms']; | |
| 801 | - } else if ( ! empty( $plugin_translations['header'] ) ) { | |
| 802 | - $locale['locale_data'][ $domain ]['']['plural_forms'] = $plugin_translations['header']['Plural-Forms']; | |
| 1902 | + if (!empty($translations->headers['Plural-Forms'])) { | |
| 1903 | + $locale['locale_data'][$domain]['']['plural_forms'] = $translations->headers['Plural-Forms']; | |
| 803 | 1904 | } |
| 1905 | + else if (!empty($plugin_translations['header'])) { | |
| 1906 | + $locale['locale_data'][$domain]['']['plural_forms'] = $plugin_translations['header']['Plural-Forms']; | |
| 1907 | + } | |
| 804 | 1908 | |
| 805 | - $entries = array_merge( $plugin_translations['translations'], $translations->entries ); | |
| 1909 | + $entries = array_merge($plugin_translations['translations'], $translations->entries); | |
| 806 | 1910 | |
| 807 | - foreach ( $entries as $msgid => $entry ) { | |
| 808 | - $locale['locale_data'][ $domain ][ $msgid ] = $entry->translations; | |
| 1911 | + foreach ($entries as $msgid => $entry) { | |
| 1912 | + $locale['locale_data'][$domain][$msgid] = $entry->translations; | |
| 809 | 1913 | } |
| 810 | 1914 | |
| 811 | 1915 | return $locale; |
| 812 | 1916 | } |
| @@ -819,26 +1923,27 @@ | ||
| 819 | 1923 | * @param string $language_dir |
| 820 | 1924 | * |
| 821 | 1925 | * @return array |
| 822 | 1926 | */ |
| 823 | - public function get_translations_for_plugin_domain( $domain, $language_dir = null ) { | |
| 824 | - if ( $language_dir == null ) { | |
| 825 | - $language_dir = WPFNL_PATH . '/languages/'; | |
| 1927 | + public function get_translations_for_plugin_domain($domain, $language_dir = null) | |
| 1928 | + { | |
| 1929 | + if ($language_dir == null) { | |
| 1930 | + $language_dir = WPFNL_PATH . '/languages/'; | |
| 826 | 1931 | } |
| 827 | - $languages = get_available_languages( $language_dir ); | |
| 1932 | + $languages = get_available_languages($language_dir); | |
| 828 | 1933 | $get_site_lang = is_admin() ? get_user_locale() : get_locale(); |
| 829 | - $mo_file_name = $domain . '-' . $get_site_lang; | |
| 830 | - $translations = []; | |
| 1934 | + $mo_file_name = $domain . '-' . $get_site_lang; | |
| 1935 | + $translations = []; | |
| 831 | 1936 | |
| 832 | - if ( in_array( $mo_file_name, $languages ) && file_exists( $language_dir . $mo_file_name . '.mo' ) ) { | |
| 1937 | + if (in_array($mo_file_name, $languages) && file_exists($language_dir . $mo_file_name . '.mo')) { | |
| 833 | 1938 | $mo = new \MO(); |
| 834 | - if ( $mo->import_from_file( $language_dir . $mo_file_name . '.mo' ) ) { | |
| 1939 | + if ($mo->import_from_file($language_dir . $mo_file_name . '.mo')) { | |
| 835 | 1940 | $translations = $mo->entries; |
| 836 | 1941 | } |
| 837 | 1942 | } |
| 838 | 1943 | |
| 839 | 1944 | return [ |
| 840 | - 'header' => isset( $mo ) ? $mo->headers : '', | |
| 1945 | + 'header' => isset($mo) ? $mo->headers : '', | |
| 841 | 1946 | 'translations' => $translations, |
| 842 | 1947 | ]; |
| 843 | 1948 | } |
| 844 | 1949 | |
| @@ -845,26 +1950,32 @@ | ||
| 845 | 1950 | |
| 846 | 1951 | /** |
| 847 | 1952 | * Check GBF version for skip offer |
| 848 | 1953 | */ |
| 849 | - public function is_skip_offer(){ | |
| 850 | - if( defined('WPFNL_PRO_GB_VERSION') ){ | |
| 851 | - return version_compare( WPFNL_PRO_GB_VERSION, "1.0.9", ">=" ); | |
| 1954 | + public function is_skip_offer() | |
| 1955 | + { | |
| 1956 | + // GBF is now built into WPFunnels Pro — always available when GBF is activated. | |
| 1957 | + if ( Wpfnl_functions::is_global_funnel_activated() ) { | |
| 1958 | + return true; | |
| 852 | 1959 | } |
| 1960 | + // Legacy: standalone addon still active. | |
| 1961 | + if ( defined('WPFNL_PRO_GB_VERSION') ) { | |
| 1962 | + return version_compare( WPFNL_PRO_GB_VERSION, '1.0.9', '>=' ); | |
| 1963 | + } | |
| 853 | 1964 | return false; |
| 854 | 1965 | } |
| 855 | 1966 | |
| 856 | - public function mint_step_settings( $funnel_id ){ | |
| 857 | - $steps = get_post_meta( $funnel_id, '_steps', true ); | |
| 1967 | + public function mint_step_settings($funnel_id) | |
| 1968 | + { | |
| 1969 | + $steps = get_post_meta($funnel_id, '_steps', true); | |
| 858 | 1970 | $mint_steps = []; |
| 859 | - if( is_array($steps) ){ | |
| 860 | - foreach( $steps as $step ){ | |
| 1971 | + if (is_array($steps)) { | |
| 1972 | + foreach ($steps as $step) { | |
| 861 | 1973 | $mint_settings['stepID'] = $step['id']; |
| 862 | - $value = get_post_meta( $step['id'], '_wpfnl_automation_steps', true ); | |
| 1974 | + $value = get_post_meta($step['id'], '_wpfnl_automation_steps', true); | |
| 863 | 1975 | $mint_settings['value'] = is_array($value) ? $value : []; |
| 864 | - array_push($mint_steps,$mint_settings); | |
| 1976 | + array_push($mint_steps, $mint_settings); | |
| 865 | 1977 | } |
| 866 | - | |
| 867 | 1978 | } |
| 868 | 1979 | return $mint_steps; |
| 869 | 1980 | } |
| 870 | 1981 | |
| @@ -870,15 +1981,15 @@ | ||
| 870 | 1981 | |
| 871 | 1982 | |
| 872 | 1983 | /** |
| 873 | 1984 | * Define w2cloud routes |
| 874 | - * | |
| 1985 | + * | |
| 875 | 1986 | * @return array |
| 876 | 1987 | */ |
| 877 | 1988 | public function get_wpfnl_routes() |
| 878 | 1989 | { |
| 879 | 1990 | $routes = array( |
| 880 | - array( | |
| 1991 | + array( | |
| 881 | 1992 | 'path' => '/', |
| 882 | 1993 | 'name' => 'home', |
| 883 | 1994 | 'component' => 'Home' |
| 884 | 1995 | ) |
| @@ -887,19 +1998,20 @@ | ||
| 887 | 1998 | } |
| 888 | 1999 | |
| 889 | 2000 | /** |
| 890 | 2001 | * Get all active Payment Method |
| 891 | - * | |
| 2002 | + * | |
| 892 | 2003 | * @return array |
| 893 | 2004 | */ |
| 894 | - public function get_payment_method(){ | |
| 895 | - if( Wpfnl_functions::is_wc_active() ) { | |
| 2005 | + public function get_payment_method() | |
| 2006 | + { | |
| 2007 | + if (Wpfnl_functions::is_wc_active()) { | |
| 896 | 2008 | $gateways = WC()->payment_gateways->get_available_payment_gateways(); |
| 897 | 2009 | $enabled_gateways = []; |
| 898 | 2010 | |
| 899 | - if( $gateways ) { | |
| 900 | - foreach( $gateways as $key => $gateway ) { | |
| 901 | - if( $gateway->enabled == 'yes' ) { | |
| 2011 | + if ($gateways) { | |
| 2012 | + foreach ($gateways as $key => $gateway) { | |
| 2013 | + if ($gateway->enabled == 'yes') { | |
| 902 | 2014 | $enabled_gateways[$key] = $gateway->method_title; |
| 903 | 2015 | } |
| 904 | 2016 | } |
| 905 | 2017 | } |
| @@ -909,17 +2021,18 @@ | ||
| 909 | 2021 | } |
| 910 | 2022 | |
| 911 | 2023 | /** |
| 912 | 2024 | * Get all shipping methods |
| 913 | - * | |
| 2025 | + * | |
| 914 | 2026 | * @return array |
| 915 | 2027 | */ |
| 916 | - public function get_shipping_method(){ | |
| 917 | - if( Wpfnl_functions::is_wc_active() ) { | |
| 2028 | + public function get_shipping_method() | |
| 2029 | + { | |
| 2030 | + if (Wpfnl_functions::is_wc_active()) { | |
| 918 | 2031 | $available_shipping = WC()->shipping()->get_shipping_methods(); |
| 919 | 2032 | $enabled_shipping = []; |
| 920 | - if( $available_shipping ) { | |
| 921 | - foreach( $available_shipping as $key => $shipping ) { | |
| 2033 | + if ($available_shipping) { | |
| 2034 | + foreach ($available_shipping as $key => $shipping) { | |
| 922 | 2035 | $enabled_shipping[$key] = $shipping->method_title; |
| 923 | 2036 | } |
| 924 | 2037 | } |
| 925 | 2038 | return $enabled_shipping; |
| @@ -929,17 +2042,18 @@ | ||
| 929 | 2042 | |
| 930 | 2043 | |
| 931 | 2044 | /** |
| 932 | 2045 | * Show funnel steps on reading |
| 933 | - * | |
| 2046 | + * | |
| 934 | 2047 | * @param $output |
| 935 | - * | |
| 2048 | + * | |
| 936 | 2049 | * @return mixed |
| 937 | 2050 | */ |
| 938 | - public function show_funnel_steps_on_reading( $output ) { | |
| 2051 | + public function show_funnel_steps_on_reading($output) | |
| 2052 | + { | |
| 939 | 2053 | global $pagenow; |
| 940 | - if ( ( 'options-reading.php' === $pagenow || 'customize.php' === $pagenow ) && preg_match( '#page_on_front#', $output ) ) { | |
| 941 | - $output = $this->show_steps_options( $output ); | |
| 2054 | + if (('options-reading.php' === $pagenow || 'customize.php' === $pagenow) && preg_match('#page_on_front#', $output)) { | |
| 2055 | + $output = $this->show_steps_options($output); | |
| 942 | 2056 | } |
| 943 | 2057 | return $output; |
| 944 | 2058 | } |
| 945 | 2059 | |
| @@ -947,45 +2061,46 @@ | ||
| 947 | 2061 | /** |
| 948 | 2062 | * Show steps pages on reading |
| 949 | 2063 | * |
| 950 | 2064 | * @param $output |
| 951 | - * | |
| 2065 | + * | |
| 952 | 2066 | * @return string |
| 953 | 2067 | */ |
| 954 | - private function show_steps_options( $output ) { | |
| 955 | - $options = ''; | |
| 2068 | + private function show_steps_options($output) | |
| 2069 | + { | |
| 2070 | + $options = ''; | |
| 956 | 2071 | |
| 957 | 2072 | $steps = get_posts( |
| 958 | 2073 | array( |
| 959 | - 'post_type' => WPFNL_STEPS_POST_TYPE, | |
| 960 | - 'posts_per_page' => - 1, | |
| 961 | - 'numberposts' => 100, | |
| 962 | - 'orderby' => 'title', | |
| 963 | - 'order' => 'ASC', | |
| 964 | - 'post_status' => 'publish', | |
| 965 | - 'meta_query' => array( | |
| 966 | - 'relation' => 'OR', | |
| 2074 | + 'post_type' => WPFNL_STEPS_POST_TYPE, | |
| 2075 | + 'posts_per_page' => -1, | |
| 2076 | + 'numberposts' => 100, | |
| 2077 | + 'orderby' => 'title', | |
| 2078 | + 'order' => 'ASC', | |
| 2079 | + 'post_status' => 'publish', | |
| 2080 | + 'meta_query' => array( | |
| 2081 | + 'relation' => 'OR', | |
| 967 | 2082 | array( |
| 968 | - 'key' => '_step_type', | |
| 969 | - 'value' => 'landing', | |
| 970 | - ), | |
| 2083 | + 'key' => '_step_type', | |
| 2084 | + 'value' => 'landing', | |
| 2085 | + ), | |
| 971 | 2086 | array( |
| 972 | - 'key' => '_step_type', | |
| 973 | - 'value' => 'checkout', | |
| 974 | - ) | |
| 975 | - ), | |
| 976 | - ) | |
| 2087 | + 'key' => '_step_type', | |
| 2088 | + 'value' => 'checkout', | |
| 2089 | + ) | |
| 2090 | + ), | |
| 2091 | + ) | |
| 977 | 2092 | ); |
| 978 | 2093 | |
| 979 | - if( $steps && is_array( $steps ) ) { | |
| 980 | - $front_page_id = get_option( 'page_on_front' ); | |
| 981 | - foreach ( $steps as $step ) { | |
| 982 | - $selected = selected( $front_page_id, $step->ID, false ); | |
| 983 | - $post_type_obj = get_post_type_object( $step->post_type ); | |
| 984 | - $options .= "<option value=\"{$step->ID}\"{$selected}>{$step->post_title} (WPFunnels {$post_type_obj->labels->singular_name})</option>"; | |
| 2094 | + if ($steps && is_array($steps)) { | |
| 2095 | + $front_page_id = get_option('page_on_front'); | |
| 2096 | + foreach ($steps as $step) { | |
| 2097 | + $selected = selected($front_page_id, $step->ID, false); | |
| 2098 | + $post_type_obj = get_post_type_object($step->post_type); | |
| 2099 | + $options .= "<option value=\"{$step->ID}\"{$selected}>{$step->post_title} (WPFunnels {$post_type_obj->labels->singular_name})</option>"; | |
| 985 | 2100 | } |
| 986 | - $options .= '</select>'; | |
| 987 | - $output = str_replace( '</select>', $options, $output ); | |
| 2101 | + $options .= '</select>'; | |
| 2102 | + $output = str_replace('</select>', $options, $output); | |
| 988 | 2103 | } |
| 989 | 2104 | return $output; |
| 990 | 2105 | } |
| 991 | 2106 | |
| @@ -994,12 +2109,13 @@ | ||
| 994 | 2109 | * Get notice for builder |
| 995 | 2110 | * |
| 996 | 2111 | * @return array |
| 997 | 2112 | */ |
| 998 | - public function get_builder_notice() { | |
| 2113 | + public function get_builder_notice() | |
| 2114 | + { | |
| 999 | 2115 | $builder = Wpfnl_functions::get_builder_type(); |
| 1000 | 2116 | $notices = array(); |
| 1001 | - if( 'divi-builder' === $builder ) { | |
| 2117 | + if ('divi-builder' === $builder) { | |
| 1002 | 2118 | $notices['notices'][] = array(); |
| 1003 | 2119 | } |
| 1004 | 2120 | return $notices; |
| 1005 | 2121 | } |
| @@ -1007,13 +2123,14 @@ | ||
| 1007 | 2123 | |
| 1008 | 2124 | /** |
| 1009 | 2125 | * Change text in order details page |
| 1010 | 2126 | */ |
| 1011 | - public function wpfnl_customizing_checkout_text( $translated_text, $untranslated_text, $domain ){ | |
| 2127 | + public function wpfnl_customizing_checkout_text($translated_text, $untranslated_text, $domain) | |
| 2128 | + { | |
| 1012 | 2129 | |
| 1013 | - if( is_admin() ){ | |
| 1014 | - if ( $translated_text == 'Coupon(s):' ) { | |
| 1015 | - $translated_text = __( 'Discount:', 'wpfnl' ); | |
| 2130 | + if (is_admin()) { | |
| 2131 | + if ($translated_text == 'Coupon(s):') { | |
| 2132 | + $translated_text = __('Discount:', 'wpfnl'); | |
| 1016 | 2133 | } |
| 1017 | 2134 | } |
| 1018 | 2135 | |
| 1019 | 2136 | return $translated_text; |
| @@ -1023,15 +2140,16 @@ | ||
| 1023 | 2140 | /** |
| 1024 | 2141 | * Change local for if this is funnel canvas window |
| 1025 | 2142 | * |
| 1026 | 2143 | * @param $local |
| 1027 | - * | |
| 2144 | + * | |
| 1028 | 2145 | * @return string |
| 1029 | 2146 | * |
| 1030 | 2147 | * @since 2.3.8 |
| 1031 | 2148 | */ |
| 1032 | - public function change_local_for_funnel_canvas($local) { | |
| 1033 | - if( Wpfnl_functions::is_funnel_canvas_window() ) { | |
| 2149 | + public function change_local_for_funnel_canvas($local) | |
| 2150 | + { | |
| 2151 | + if (Wpfnl_functions::is_funnel_canvas_window()) { | |
| 1034 | 2152 | return 'en_US'; |
| 1035 | 2153 | } |
| 1036 | 2154 | return $local; |
| 1037 | 2155 | } |
| @@ -1041,11 +2159,11 @@ | ||
| 1041 | 2159 | * Add type meta |
| 1042 | 2160 | * |
| 1043 | 2161 | * @since 2.4.4 |
| 1044 | 2162 | */ |
| 1045 | - public function wpfnl_add_type_meta(){ | |
| 2163 | + public function wpfnl_add_type_meta() | |
| 2164 | + { | |
| 1046 | 2165 | Wpfnl_functions::add_type_meta(); |
| 1047 | - | |
| 1048 | 2166 | } |
| 1049 | 2167 | |
| 1050 | 2168 | |
| 1051 | 2169 | /** |
| @@ -1051,18 +2169,19 @@ | ||
| 1051 | 2169 | /** |
| 1052 | 2170 | * Maybe Global funnel |
| 1053 | 2171 | * |
| 1054 | 2172 | * @param String |
| 1055 | - * | |
| 2173 | + * | |
| 1056 | 2174 | * @return Bool |
| 1057 | 2175 | * @since 2.4.11 |
| 1058 | 2176 | */ |
| 1059 | - public function maybe_gbf( $funnel_id ){ | |
| 2177 | + public function maybe_gbf($funnel_id) | |
| 2178 | + { | |
| 1060 | 2179 | |
| 1061 | - if( is_plugin_active( 'wpfunnels-pro-gbf/wpfnl-pro-gb.php' )){ | |
| 1062 | - if( $funnel_id ){ | |
| 1063 | - $is_gbf = get_post_meta($funnel_id,'is_global_funnel',true); | |
| 1064 | - if( 'yes' == $is_gbf ){ | |
| 2180 | + if ( Wpfnl_functions::is_global_funnel_activated() ) { | |
| 2181 | + if ($funnel_id) { | |
| 2182 | + $is_gbf = get_post_meta($funnel_id, 'is_global_funnel', true); | |
| 2183 | + if ('yes' == $is_gbf) { | |
| 1065 | 2184 | return true; |
| 1066 | 2185 | } |
| 1067 | 2186 | } |
| 1068 | 2187 | } |
| @@ -1074,12 +2193,13 @@ | ||
| 1074 | 2193 | * Check funnel type is lms or not by funnel_id |
| 1075 | 2194 | * |
| 1076 | 2195 | * @return Bool |
| 1077 | 2196 | */ |
| 1078 | - public function maybe_lms( $funnel_id ){ | |
| 2197 | + public function maybe_lms($funnel_id) | |
| 2198 | + { | |
| 1079 | 2199 | |
| 1080 | - $type = get_post_meta($funnel_id,'_wpfnl_funnel_type',true); | |
| 1081 | - if( 'lms' === $type ){ | |
| 2200 | + $type = get_post_meta($funnel_id, '_wpfnl_funnel_type', true); | |
| 2201 | + if ('lms' === $type) { | |
| 1082 | 2202 | return true; |
| 1083 | 2203 | } |
| 1084 | 2204 | return false; |
| 1085 | 2205 | } |
| @@ -1086,9 +2206,10 @@ | ||
| 1086 | 2206 | |
| 1087 | 2207 | /** |
| 1088 | 2208 | * May be lms settings is disbaled |
| 1089 | 2209 | */ |
| 1090 | - public function maybe_lms_settings_disbaled(){ | |
| 2210 | + public function maybe_lms_settings_disbaled() | |
| 2211 | + { | |
| 1091 | 2212 | return Wpfnl_functions::is_wc_active() && Wpfnl_functions::is_lms_addon_active(); |
| 1092 | 2213 | } |
| 1093 | 2214 | |
| 1094 | 2215 | |
| @@ -1093,144 +2214,294 @@ | ||
| 1093 | 2214 | |
| 1094 | 2215 | |
| 1095 | 2216 | /** |
| 1096 | 2217 | * Trigger when any plugin is deactivated |
| 1097 | - * | |
| 2218 | + * | |
| 1098 | 2219 | * @param $filename |
| 1099 | - * | |
| 2220 | + * | |
| 1100 | 2221 | * @since 2.5.1 |
| 1101 | 2222 | */ |
| 1102 | - public function wpfnl_deactivated_plugin( $filename ){ | |
| 1103 | - | |
| 1104 | - if( 'woocommerce/woocommerce.php' === $filename ){ | |
| 1105 | - if( !Wpfnl_functions::is_lms_addon_active() ){ | |
| 1106 | - Wpfnl_functions::update_funnel_type_to_lead(); | |
| 1107 | - } | |
| 2223 | + public function wpfnl_deactivated_plugin($filename) | |
| 2224 | + { | |
| 2225 | + if ('woocommerce/woocommerce.php' === $filename) { | |
| 1108 | 2226 | Wpfnl_functions::wpfnl_delete_transient(); |
| 1109 | - }elseif( 'sfwd-lms/sfwd_lms.php' === $filename ){ | |
| 1110 | - if( !Wpfnl_functions::is_wc_active() ){ | |
| 1111 | - Wpfnl_functions::update_funnel_type_to_lead(); | |
| 1112 | - } | |
| 2227 | + } | |
| 2228 | + elseif ('sfwd-lms/sfwd_lms.php' === $filename) { | |
| 1113 | 2229 | Wpfnl_functions::wpfnl_delete_transient(); |
| 1114 | - }elseif( 'wpfunnels-pro-lms/wpfunnels-pro-lms.php' === $filename ){ | |
| 2230 | + } | |
| 2231 | + elseif ('wpfunnels-pro-lms/wpfunnels-pro-lms.php' === $filename) { | |
| 1115 | 2232 | Wpfnl_functions::wpfnl_delete_transient(); |
| 1116 | 2233 | } |
| 1117 | - | |
| 2234 | + elseif ('qubely/qubely.php' === $filename) { | |
| 2235 | + Wpfnl_functions::wpfnl_delete_transient(); | |
| 2236 | + delete_option(WPFNL_TEMPLATES_OPTION_KEY . '_wc'); | |
| 2237 | + delete_option(WPFNL_TEMPLATES_OPTION_KEY . '_lms'); | |
| 2238 | + delete_transient('wpfunnels_remote_template_data_wc_' . WPFNL_VERSION); | |
| 2239 | + delete_transient('wpfunnels_remote_template_data_lms_' . WPFNL_VERSION); | |
| 2240 | + delete_transient('wpfunnels_remote_template_data_lead_' . WPFNL_VERSION); | |
| 2241 | + delete_transient('wpfunnels_remote_template_data_store_checkout_' . WPFNL_VERSION); | |
| 2242 | + } | |
| 1118 | 2243 | } |
| 1119 | 2244 | |
| 1120 | 2245 | |
| 1121 | 2246 | /** |
| 1122 | 2247 | * Trigger when any plugin is activated |
| 1123 | - * | |
| 2248 | + * | |
| 1124 | 2249 | * @param $filename |
| 1125 | - * | |
| 2250 | + * | |
| 1126 | 2251 | * @since 2.5.1 |
| 1127 | 2252 | */ |
| 1128 | - public function wpfnl_activated_plugin( $filename ){ | |
| 1129 | - if( 'woocommerce/woocommerce.php' === $filename ){ | |
| 2253 | + public function wpfnl_activated_plugin($filename) | |
| 2254 | + { | |
| 2255 | + if ('woocommerce/woocommerce.php' === $filename) { | |
| 1130 | 2256 | Wpfnl_functions::wpfnl_delete_transient(); |
| 1131 | - }elseif( 'sfwd-lms/sfwd_lms.php' === $filename ){ | |
| 1132 | - if( Wpfnl_functions::is_lms_addon_active() ){ | |
| 2257 | + } | |
| 2258 | + elseif ('sfwd-lms/sfwd_lms.php' === $filename) { | |
| 2259 | + if (Wpfnl_functions::is_lms_addon_active()) { | |
| 1133 | 2260 | Wpfnl_functions::wpfnl_delete_transient(); |
| 1134 | 2261 | } |
| 1135 | - }elseif( 'wpfunnels-pro-lms/wpfunnels-pro-lms.php' === $filename ){ | |
| 2262 | + } | |
| 2263 | + elseif ('wpfunnels-pro-lms/wpfunnels-pro-lms.php' === $filename) { | |
| 1136 | 2264 | Wpfnl_functions::wpfnl_delete_transient(); |
| 1137 | 2265 | } |
| 2266 | + elseif ('qubely/qubely.php' === $filename) { | |
| 2267 | + Wpfnl_functions::wpfnl_delete_transient(); | |
| 2268 | + delete_option(WPFNL_TEMPLATES_OPTION_KEY . '_wc'); | |
| 2269 | + delete_option(WPFNL_TEMPLATES_OPTION_KEY . '_lms'); | |
| 2270 | + delete_transient('wpfunnels_remote_template_data_wc_' . WPFNL_VERSION); | |
| 2271 | + delete_transient('wpfunnels_remote_template_data_lms_' . WPFNL_VERSION); | |
| 2272 | + delete_transient('wpfunnels_remote_template_data_lead_' . WPFNL_VERSION); | |
| 2273 | + delete_transient('wpfunnels_remote_template_data_store_checkout_' . WPFNL_VERSION); | |
| 2274 | + } | |
| 1138 | 2275 | } |
| 1139 | 2276 | |
| 1140 | 2277 | |
| 1141 | 2278 | |
| 1142 | - /** | |
| 1143 | - * Get editor source data | |
| 1144 | - * | |
| 1145 | - * @return array | |
| 1146 | - * @since 1.0.0 | |
| 1147 | - */ | |
| 1148 | - private function get_editor_source() { | |
| 1149 | - // get product categories for email builder. | |
| 1150 | - $wc_categories = $this->get_formatted_wc_categories(); | |
| 1151 | - $wp_categories = $this->get_formatted_wp_post_categories(); | |
| 2279 | + /** | |
| 2280 | + * Get editor source data | |
| 2281 | + * | |
| 2282 | + * @return array | |
| 2283 | + * @since 1.0.0 | |
| 2284 | + */ | |
| 2285 | + private function get_editor_source() | |
| 2286 | + { | |
| 2287 | + // get product categories for email builder. | |
| 2288 | + $wc_categories = $this->get_formatted_wc_categories(); | |
| 2289 | + $wp_categories = $this->get_formatted_wp_post_categories(); | |
| 1152 | 2290 | |
| 1153 | - return apply_filters( | |
| 1154 | - 'plugin_hook_name', | |
| 1155 | - array( | |
| 1156 | - 'product_categories' => $wc_categories, | |
| 1157 | - 'post_categories' => $wp_categories, | |
| 1158 | - 'placeholder_image' => '' | |
| 1159 | - ) | |
| 1160 | - ); | |
| 1161 | - } | |
| 2291 | + return apply_filters( | |
| 2292 | + 'plugin_hook_name', | |
| 2293 | + array( | |
| 2294 | + 'product_categories' => $wc_categories, | |
| 2295 | + 'post_categories' => $wp_categories, | |
| 2296 | + 'placeholder_image' => '' | |
| 2297 | + ) | |
| 2298 | + ); | |
| 2299 | + } | |
| 1162 | 2300 | |
| 1163 | 2301 | |
| 1164 | 2302 | |
| 1165 | - /** | |
| 1166 | - * Get the WooCommerce product categories | |
| 1167 | - * | |
| 1168 | - * @return array | |
| 1169 | - * @since 1.0.0 | |
| 1170 | - */ | |
| 1171 | - private function get_formatted_wc_categories() { | |
| 1172 | - $taxonomy = 'product_cat'; | |
| 1173 | - $orderby = 'name'; | |
| 1174 | - $show_count = 0; | |
| 1175 | - $pad_counts = 0; | |
| 1176 | - $hierarchical = 1; | |
| 1177 | - $title = ''; | |
| 1178 | - $empty = 0; | |
| 2303 | + /** | |
| 2304 | + * Get the WooCommerce product categories | |
| 2305 | + * | |
| 2306 | + * @return array | |
| 2307 | + * @since 1.0.0 | |
| 2308 | + */ | |
| 2309 | + private function get_formatted_wc_categories() | |
| 2310 | + { | |
| 2311 | + $taxonomy = 'product_cat'; | |
| 2312 | + $orderby = 'name'; | |
| 2313 | + $show_count = 0; | |
| 2314 | + $pad_counts = 0; | |
| 2315 | + $hierarchical = 1; | |
| 2316 | + $title = ''; | |
| 2317 | + $empty = 0; | |
| 1179 | 2318 | |
| 1180 | - $args = array( | |
| 1181 | - 'taxonomy' => $taxonomy, | |
| 1182 | - 'orderby' => $orderby, | |
| 1183 | - 'show_count' => $show_count, | |
| 1184 | - 'pad_counts' => $pad_counts, | |
| 1185 | - 'hierarchical' => $hierarchical, | |
| 1186 | - 'title_li' => $title, | |
| 1187 | - 'hide_empty' => $empty, | |
| 1188 | - ); | |
| 1189 | - $product_categories = get_categories( $args ); | |
| 1190 | - $wc_categories = array(); | |
| 1191 | - foreach ( $product_categories as $product_cat ) { | |
| 1192 | - $wc_categories[] = array( | |
| 1193 | - 'value' => $product_cat->term_id, | |
| 1194 | - 'label' => $product_cat->name, | |
| 1195 | - ); | |
| 1196 | - } | |
| 2319 | + $args = array( | |
| 2320 | + 'taxonomy' => $taxonomy, | |
| 2321 | + 'orderby' => $orderby, | |
| 2322 | + 'show_count' => $show_count, | |
| 2323 | + 'pad_counts' => $pad_counts, | |
| 2324 | + 'hierarchical' => $hierarchical, | |
| 2325 | + 'title_li' => $title, | |
| 2326 | + 'hide_empty' => $empty, | |
| 2327 | + ); | |
| 2328 | + $product_categories = get_categories($args); | |
| 2329 | + $wc_categories = array(); | |
| 2330 | + foreach ($product_categories as $product_cat) { | |
| 2331 | + $wc_categories[] = array( | |
| 2332 | + 'value' => $product_cat->term_id, | |
| 2333 | + 'label' => $product_cat->name, | |
| 2334 | + ); | |
| 2335 | + } | |
| 1197 | 2336 | |
| 1198 | - return $wc_categories; | |
| 1199 | - } | |
| 2337 | + return $wc_categories; | |
| 2338 | + } | |
| 1200 | 2339 | |
| 1201 | 2340 | |
| 1202 | - /** | |
| 1203 | - * Get the WordPress post categories | |
| 1204 | - * | |
| 1205 | - * @return array | |
| 1206 | - * @since 1.0.0 | |
| 1207 | - */ | |
| 1208 | - private function get_formatted_wp_post_categories() { | |
| 1209 | - $taxonomy = 'category'; | |
| 1210 | - $orderby = 'name'; | |
| 1211 | - $show_count = 0; | |
| 1212 | - $pad_counts = 0; | |
| 1213 | - $hierarchical = 1; | |
| 1214 | - $title = ''; | |
| 1215 | - $empty = 0; | |
| 2341 | + /** | |
| 2342 | + * Get the WordPress post categories | |
| 2343 | + * | |
| 2344 | + * @return array | |
| 2345 | + * @since 1.0.0 | |
| 2346 | + */ | |
| 2347 | + private function get_formatted_wp_post_categories() | |
| 2348 | + { | |
| 2349 | + $taxonomy = 'category'; | |
| 2350 | + $orderby = 'name'; | |
| 2351 | + $show_count = 0; | |
| 2352 | + $pad_counts = 0; | |
| 2353 | + $hierarchical = 1; | |
| 2354 | + $title = ''; | |
| 2355 | + $empty = 0; | |
| 1216 | 2356 | |
| 1217 | - $args = array( | |
| 1218 | - 'taxonomy' => $taxonomy, | |
| 1219 | - 'orderby' => $orderby, | |
| 1220 | - 'show_count' => $show_count, | |
| 1221 | - 'pad_counts' => $pad_counts, | |
| 1222 | - 'hierarchical' => $hierarchical, | |
| 1223 | - 'title_li' => $title, | |
| 1224 | - 'hide_empty' => $empty, | |
| 1225 | - ); | |
| 1226 | - $post_categories = get_categories( $args ); | |
| 1227 | - $categories = array(); | |
| 1228 | - foreach ( $post_categories as $post_cat ) { | |
| 1229 | - $categories[] = array( | |
| 1230 | - 'value' => $post_cat->term_id, | |
| 1231 | - 'label' => $post_cat->name, | |
| 1232 | - ); | |
| 1233 | - } | |
| 1234 | - return $categories; | |
| 1235 | - } | |
| 1236 | -} | |
| 2357 | + $args = array( | |
| 2358 | + 'taxonomy' => $taxonomy, | |
| 2359 | + 'orderby' => $orderby, | |
| 2360 | + 'show_count' => $show_count, | |
| 2361 | + 'pad_counts' => $pad_counts, | |
| 2362 | + 'hierarchical' => $hierarchical, | |
| 2363 | + 'title_li' => $title, | |
| 2364 | + 'hide_empty' => $empty, | |
| 2365 | + ); | |
| 2366 | + $post_categories = get_categories($args); | |
| 2367 | + $categories = array(); | |
| 2368 | + foreach ($post_categories as $post_cat) { | |
| 2369 | + $categories[] = array( | |
| 2370 | + 'value' => $post_cat->term_id, | |
| 2371 | + 'label' => $post_cat->name, | |
| 2372 | + ); | |
| 2373 | + } | |
| 2374 | + return $categories; | |
| 2375 | + } | |
| 2376 | + | |
| 2377 | + | |
| 2378 | + /** | |
| 2379 | + * Add custom capabilities to administrator role | |
| 2380 | + * | |
| 2381 | + * @since 3.1.3 | |
| 2382 | + */ | |
| 2383 | + public function attach_admin_capabilities() | |
| 2384 | + { | |
| 2385 | + global $wp_roles; | |
| 2386 | + $capabilities = array( | |
| 2387 | + 'wpf_manage_funnels', | |
| 2388 | + ); | |
| 2389 | + foreach ($capabilities as $cap) { | |
| 2390 | + $wp_roles->add_cap('administrator', $cap); | |
| 2391 | + } | |
| 2392 | + } | |
| 2393 | + | |
| 2394 | + /** | |
| 2395 | + * Checks if the current page slug matches the provided slug. | |
| 2396 | + * | |
| 2397 | + * @param $slug | |
| 2398 | + * @return bool | |
| 2399 | + * @since 3.5.0 | |
| 2400 | + */ | |
| 2401 | + public function is_current_page($slug) | |
| 2402 | + { | |
| 2403 | + if (empty($slug)) { | |
| 2404 | + return false; | |
| 2405 | + } | |
| 2406 | + $current_page_slug = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : ''; | |
| 2407 | + if ($slug === $current_page_slug) { | |
| 2408 | + return true; | |
| 2409 | + } | |
| 2410 | + return false; | |
| 2411 | + } | |
| 2412 | + | |
| 2413 | + /** | |
| 2414 | + * Add body class for WPFunnels admin pages. | |
| 2415 | + * | |
| 2416 | + * @param string $classes Current body classes. | |
| 2417 | + * @return string Modified body classes. | |
| 2418 | + * @since 3.9.5 | |
| 2419 | + */ | |
| 2420 | + public function add_wpfunnels_admin_body_class($classes) | |
| 2421 | + { | |
| 2422 | + // Check if we're on a WPFunnels admin page. | |
| 2423 | + $screen = get_current_screen(); | |
| 2424 | + | |
| 2425 | + if ($screen && (in_array($screen->id, $this->page_hooks) || 'wpfunnels_page_' . WPFNL_AI_FUNNEL_PAGE_SLUG === $screen->id)) { | |
| 2426 | + $classes .= ' wpfunnels-body'; | |
| 2427 | + } | |
| 2428 | + | |
| 2429 | + // The React admin styles the WordPress content column itself, so it gets | |
| 2430 | + // its own class instead of the legacy one. | |
| 2431 | + if ($screen && in_array($screen->id, $this->get_react_admin_hooks(), true)) { | |
| 2432 | + $classes .= ' rwpfnl-page'; | |
| 2433 | + } | |
| 2434 | + | |
| 2435 | + return $classes; | |
| 2436 | + } | |
| 2437 | + | |
| 2438 | + | |
| 2439 | + /** | |
| 2440 | + * Create contact on mailmint when user allows to track data | |
| 2441 | + * | |
| 2442 | + * @param array $data | |
| 2443 | + * | |
| 2444 | + * @since 3.3.1 | |
| 2445 | + */ | |
| 2446 | + public function wpfunnels_tracker_optin($data) | |
| 2447 | + { | |
| 2448 | + if (isset($data['admin_email'], $data['first_name'], $data['last_name'])) { | |
| 2449 | + $json_body_data = json_encode([ | |
| 2450 | + 'email' => $data['admin_email'], | |
| 2451 | + 'first_name' => $data['first_name'], | |
| 2452 | + 'last_name' => $data['last_name'], | |
| 2453 | + ]); | |
| 2454 | + | |
| 2455 | + $webHookUrl = [ | |
| 2456 | + 'https://staging-useraccount.kinsta.cloud/?mailmint=1&route=webhook&topic=contact&hash=b258136d-6759-4e91-bbab-0b7397af6dc7' | |
| 2457 | + ]; | |
| 2458 | + | |
| 2459 | + try { | |
| 2460 | + if (!empty($webHookUrl)) { | |
| 2461 | + foreach ($webHookUrl as $url) { | |
| 2462 | + wp_remote_request($url, [ | |
| 2463 | + 'method' => 'POST', | |
| 2464 | + 'headers' => [ | |
| 2465 | + 'Content-Type' => 'application/json', | |
| 2466 | + ], | |
| 2467 | + 'body' => $json_body_data | |
| 2468 | + ]); | |
| 2469 | + } | |
| 2470 | + } | |
| 2471 | + } | |
| 2472 | + catch (\Exception $e) { | |
| 2473 | + } | |
| 2474 | + } | |
| 2475 | + } | |
| 2476 | + | |
| 2477 | + /** | |
| 2478 | + * Creates a new MRM contact. | |
| 2479 | + * | |
| 2480 | + * @param array $data The data for the contact. | |
| 2481 | + * @return void | |
| 2482 | + */ | |
| 2483 | + public function create_mrm_contact($data) | |
| 2484 | + { | |
| 2485 | + if (!isset($data['data']['user_email'])) { | |
| 2486 | + return; | |
| 2487 | + } | |
| 2488 | + // Get double opt-in settings. | |
| 2489 | + $default = \MRM\Common\MrmCommon::double_optin_default_configuration(); | |
| 2490 | + $settings = get_option('_mrm_optin_settings', $default); | |
| 2491 | + $enable = isset($settings['enable']) ? $settings['enable'] : false; | |
| 2492 | + | |
| 2493 | + $user_data = array( | |
| 2494 | + 'email' => $data['data']['user_email'], | |
| 2495 | + 'first_name' => isset($data['data']['first_name']) ? $data['data']['first_name'] : '', | |
| 2496 | + 'last_name' => isset($data['data']['last_name']) ? $data['data']['last_name'] : '', | |
| 2497 | + 'meta_fields' => array( | |
| 2498 | + 'phone_number' => isset($data['data']['phone_number']) ? $data['data']['phone_number'] : '', | |
| 2499 | + ), | |
| 2500 | + 'status' => $enable ? 'pending' : 'subscribed', | |
| 2501 | + 'source' => 'WPFunnels', | |
| 2502 | + ); | |
| 2503 | + | |
| 2504 | + $mail_mint_object = new \WPFunnels\Integrations\MailMint($user_data); | |
| 2505 | + $mail_mint_object->create_or_update_contact(); | |
| 2506 | + } | |
| 2507 | +} | |