PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.3.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.3.0
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
← All changes | classes/class-cartflows-admin.php +298 -239 1.0.4 → 3.3.0 View file →
@@ -4,8 +4,12 @@
4 4 *
5 5 * @package CartFlows
6 6 */
7 7
8 +// Exit if accessed directly.
9 +if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 +}
8 12 /**
9 13 * Class Cartflows_Admin.
10 14 */
11 15 class Cartflows_Admin {
@@ -10,214 +14,272 @@
10 14 */
11 15 class Cartflows_Admin {
12 16
13 17 /**
14 - * Calls on initialization
18 + * Instance
15 19 *
20 + * @access private
21 + * @var object Class object.
16 22 * @since 1.0.0
17 23 */
18 - public static function init() {
24 + private static $instance;
19 25
20 - self::initialise_plugin();
21 - self::init_hooks();
26 + /**
27 + * Initiator
28 + *
29 + * @since 1.0.0
30 + * @return object initialized object of class.
31 + */
32 + public static function get_instance() {
33 + if ( ! isset( self::$instance ) ) {
34 + self::$instance = new self();
35 + }
36 + return self::$instance;
22 37 }
23 38
24 39 /**
40 + * Constructor
41 + */
42 + public function __construct() {
43 +
44 + $this->init_hooks();
45 + }
46 +
47 + /**
25 48 * Init Hooks.
26 49 *
27 50 * @since 1.0.0
28 51 * @return void
29 52 */
30 - static public function init_hooks() {
53 + public function init_hooks() {
31 54
32 55 if ( ! is_admin() ) {
33 56 return;
34 57 }
35 58
36 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
59 + /* Add lite version class to body */
60 + add_action( 'admin_body_class', array( $this, 'add_admin_body_class' ) );
37 61
38 - // Add CARTFLOWS menu option to admin.
39 - add_action( 'network_admin_menu', __CLASS__ . '::menu' );
40 - add_action( 'admin_menu', __CLASS__ . '::menu' );
41 - add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
62 + add_filter( 'plugin_action_links_' . CARTFLOWS_BASE, array( $this, 'add_action_links' ) );
42 63
43 - add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
64 + add_action( 'admin_init', array( $this, 'flush_rules_after_save_permalinks' ) );
44 65
45 - // Enqueue admin scripts.
46 - if ( isset( $_REQUEST['page'] ) && CARTFLOWS_SETTINGS == $_REQUEST['page'] ) {
66 + add_filter( 'post_row_actions', array( $this, 'remove_flow_actions' ), 99, 2 );
47 67
48 - add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
68 + add_action( 'wp_dashboard_setup', array( $this, 'dashboard_widget' ) );
49 69
50 - self::save_settings();
51 - }
70 + add_action( 'init', array( $this, 'run_scheduled_docs_job' ) );
71 + add_action( 'cartflows_update_knowledge_base_data', array( $this, 'cartflows_update_knowledge_base_data' ) );
72 + add_action( 'admin_post_cartflows_rollback', array( $this, 'post_cartflows_rollback' ) );
52 73
53 - /* Global Addmin Script */
54 - add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
74 + $this->do_not_cache_admin_pages_actions();
55 75
56 - add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
76 + // Provide pointer configuration via filter.
77 + add_filter( 'cartflows_pointer_config', array( $this, 'get_pointer_config' ) );
57 78 }
58 79
59 80 /**
60 - * Initialises the Plugin Name.
81 + * Do not cache admin pages actions.
61 82 *
62 - * @since 1.0.0
83 + * @since 1.6.13
63 84 * @return void
64 85 */
65 - static public function initialise_plugin() {
86 + public function do_not_cache_admin_pages_actions() {
66 87
67 - $name = 'Cartflows';
68 - $short_name = 'Cflows';
69 -
70 - define( 'CARTFLOWS_PLUGIN_NAME', $name );
71 - define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
88 + add_action( 'admin_init', array( $this, 'add_admin_cache_restrict_const' ) );
89 + add_action( 'admin_head', array( $this, 'add_admin_cache_restrict_meta' ) );
72 90 }
73 91
74 92 /**
75 - * Renders the admin settings menu.
93 + * Run scheduled job for CartFLows knowledge base data.
76 94 *
77 - * @since 1.0.0
95 + * @since 2.0.0
78 96 * @return void
79 97 */
80 - static public function menu() {
98 + public function run_scheduled_docs_job() {
81 99
82 - if ( ! current_user_can( 'manage_options' ) ) {
100 + if ( wp_installing() ) {
83 101 return;
84 102 }
85 103
86 - add_menu_page(
87 - 'CartFlows',
88 - 'CartFlows',
89 - 'manage_options',
90 - CARTFLOWS_SLUG,
91 - __CLASS__ . '::render',
92 - 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),
93 - 39.7
94 - );
104 + // Only the legacy admin renders the Knowledge Base screen that consumes this data.
105 + if ( ! defined( 'CARTFLOWS_LEGACY_ADMIN' ) || ! CARTFLOWS_LEGACY_ADMIN ) {
106 + return;
107 + }
95 108
109 + if ( false === as_next_scheduled_action( 'cartflows_update_knowledge_base_data' ) ) {
110 + as_schedule_recurring_action( time(), WEEK_IN_SECONDS, 'cartflows_update_knowledge_base_data' );
111 + }
96 112 }
97 113
98 114 /**
99 - * Add submenu to admin menu.
115 + * Cartflows's REST knowledge base data.
100 116 *
101 - * @since 1.0.0
117 + * @since 2.0.0
118 + * @return mixed
102 119 */
103 - static function submenu() {
120 + public static function cartflows_update_knowledge_base_data() {
121 + $docs_json = json_decode( wp_remote_retrieve_body( wp_remote_get( 'https://cartflows.com//wp-json/powerful-docs/v1/get-docs' ) ) );
104 122
105 - $parent_slug = CARTFLOWS_SLUG;
106 - $page_title = __( 'Settings', 'cartflows' );
107 - $menu_title = __( 'Settings', 'cartflows' );
108 - $capability = 'manage_options';
109 - $menu_slug = 'cartflows_settings';
110 - $callback = __CLASS__ . '::render';
111 -
112 - add_submenu_page(
113 - $parent_slug,
114 - $page_title,
115 - $menu_title,
116 - $capability,
117 - $menu_slug,
118 - $callback
119 - );
123 + // Never autoload — this payload runs to hundreds of KB and only the Knowledge Base screen reads it.
124 + update_option( 'cartflows_docs_data', $docs_json, false );
120 125 }
121 126
122 127 /**
123 - * Renders the admin settings.
124 - *
125 - * @since 1.0.0
126 - * @return void
128 + * Init dashboard widgets.
127 129 */
128 - static public function render() {
129 - $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
130 - $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
131 - $action = str_replace( '_', '-', $action );
130 + public function dashboard_widget() {
132 131
133 - // Enable header icon filter below.
134 - $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
135 -
136 - include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
132 + if ( current_user_can( 'manage_options' ) && '1' === get_option( 'wcf_setup_skipped', false ) && '1' !== get_option( 'wcf_setup_complete', false ) ) {
133 + wp_add_dashboard_widget(
134 + 'cartFlows_setup_dashboard_widget',
135 + __( 'CartFlows Setup', 'cartflows' ),
136 + array( $this, 'status_widget' )
137 + );
138 + }
137 139 }
138 140
139 141 /**
140 - * Renders the admin settings content.
141 - *
142 - * @since 1.0.0
143 - * @return void
142 + * Show status widget.
144 143 */
145 - static public function render_content() {
144 + public function status_widget() {
146 145
147 - $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
148 - $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
149 - $action = str_replace( '_', '-', $action );
150 - $action = 'general';
146 + $admin_url = admin_url( 'index.php' ) . '?page=cartflows-onboarding&';
151 147
152 - $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
148 + $steps = array(
149 + 'welcome' => $admin_url . 'step=welcome',
150 + 'page-builder' => $admin_url . 'step=page-builder',
151 + 'plugin-install' => $admin_url . 'step=plugin-install',
152 + 'global-checkout' => $admin_url . 'step=global-checkout',
153 + 'optin' => $admin_url . 'step=optin',
154 + 'ready' => $admin_url . 'step=ready',
155 + );
153 156
154 - include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
157 + $exit_step = get_option( 'wcf_exit_setup_step', 'welcome' );
158 +
159 + $incompleted_steps = array_search( $exit_step, array_keys( $steps ), true );
160 + $remianing_steps = array_slice( $steps, 0, $incompleted_steps );
161 +
162 + $completed_tasks_count = count( $remianing_steps ) + 1;
163 + $tasks_count = count( $steps );
164 + $button_link = ! empty( $exit_step ) ? $steps[ $exit_step ] : '';
165 +
166 + $progress_percentage = ( $completed_tasks_count / $tasks_count ) * 100;
167 + $circle_r = 6.5;
168 + $circle_dashoffset = ( ( 100 - $progress_percentage ) / 100 ) * ( pi() * ( $circle_r * 2 ) );
169 +
170 + wp_enqueue_style( 'cartflows-dashboard-widget', CARTFLOWS_URL . 'admin/assets/css/admin-widget.css', array(), CARTFLOWS_VER );
171 +
172 + ?>
173 +
174 + <div class="cartflows-dashboard-widget-finish-setup">
175 + <span class='progress-wrapper'>
176 + <svg class="circle-progress" width="17" height="17" version="1.1" xmlns="http://www.w3.org/2000/svg">
177 + <circle r="6.5" cx="10" cy="10" fill="transparent" stroke-dasharray="40.859" stroke-dashoffset="0"></circle>
178 + <circle class="bar" r="6.5" cx="190" cy="10" fill="transparent" stroke-dasharray="40.859" stroke-dashoffset="<?php echo esc_attr( $circle_dashoffset ); ?>" transform='rotate(-90 100 100)'></circle>
179 + </svg>
180 + <span><?php echo esc_html_e( 'Step', 'cartflows' ); ?> <?php echo esc_html( $completed_tasks_count ); ?> <?php echo esc_html_e( 'of', 'cartflows' ); ?> <?php echo esc_html( $tasks_count ); ?></span>
181 + </span>
182 +
183 + <div class="description">
184 + <div class="wcf-left-column">
185 + <p>
186 + <?php echo esc_html_e( 'You\'re almost there! Once you complete CartFlows setup you can start receiving orders from flows.', 'cartflows' ); ?>
187 + </p>
188 + <a href='<?php echo esc_url( $button_link ); ?>' class='button button-primary'><?php echo esc_html_e( 'Complete Setup', 'cartflows' ); ?></a>
189 + </div>
190 + <div class="wcf-right-column">
191 + <img src="<?php echo esc_url( CARTFLOWS_URL . 'admin/assets/images/cartflows-home-widget.svg' ); ?>" />
192 + </div>
193 + </div>
194 + </div>
195 + <?php
155 196 }
156 197
157 198 /**
158 - * Save Global Setting options.
199 + * Add the clone link to action list for flows row actions
159 200 *
160 - * @since 1.0.0
201 + * @param array $actions Actions array.
202 + * @param object $post Post object.
203 + *
204 + * @return array
161 205 */
162 - static public function save_common_settings() {
206 + public function remove_flow_actions( $actions, $post ) {
163 207
164 - if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( $_POST['cartflows-common-settings-nonce'], 'cartflows-common-settings' ) ) {
208 + if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
165 209
166 - $url = $_SERVER['REQUEST_URI'];
167 - $input_settings = array();
168 - $new_settings = array();
210 + if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
211 + unset( $actions['duplicate'] );
212 + }
169 213
170 - if ( isset( $_POST['_cartflows_common'] ) ) {
171 -
172 - $input_settings = $_POST['_cartflows_common'];
173 -
174 - // Loop through the input and sanitize each of the values.
175 - foreach ( $input_settings as $key => $val ) {
176 -
177 - if ( is_array( $val ) ) {
178 - foreach ( $val as $k => $v ) {
179 - $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
180 - }
181 - } else {
182 - $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
183 - }
184 - }
214 + if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
215 + unset( $actions['edit_as_new_draft'] );
185 216 }
217 + }
186 218
187 - Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, true );
219 + return $actions;
220 + }
188 221
189 - $query = array(
190 - 'message' => 'saved',
191 - );
222 + /**
223 + * After save of permalinks.
224 + */
225 + public static function flush_rules_after_save_permalinks() {
192 226
193 - $redirect_to = add_query_arg( $query, $url );
194 -
195 - wp_redirect( $redirect_to );
196 - exit;
197 - } // End if statement.
227 + $has_saved_permalinks = get_option( 'cartflows_permalink_refresh' );
228 + if ( $has_saved_permalinks ) {
229 + // Required to flush rules when permalink changes.
230 + flush_rewrite_rules(); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.flush_rewrite_rules_flush_rewrite_rules
231 + delete_option( 'cartflows_permalink_refresh' );
232 + }
198 233 }
199 234
200 235 /**
201 - * Check is cartflows admin.
236 + * Show action on plugin page.
202 237 *
203 - * @since 1.0.0
204 - * @return boolean
238 + * @param array $links links.
239 + * @return array
205 240 */
206 - static public function is_global_admin() {
241 + public function add_action_links( $links ) {
207 242
208 - $current_screen = get_current_screen();
243 + $mylinks = array(
244 + '<a target="_blank" href="' . esc_url(
245 + Cartflows_Helper::get_kb_doc_link(
246 + 'https://cartflows.com/docs/',
247 + array(
248 + 'utm_source' => 'plugin-page',
249 + 'utm_campaign' => 'go-pro',
250 + )
251 + )
252 + ) . '">' . __( 'Docs', 'cartflows' ) . '</a>',
253 + );
209 254
210 - if (
211 - is_object( $current_screen ) &&
212 - isset( $current_screen->post_type ) &&
213 - ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
214 - CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
215 - )
216 - ) {
217 - return true;
255 + if ( current_user_can( 'cartflows_manage_settings' ) ) {
256 +
257 + $is_legacy_admin = defined( 'CARTFLOWS_LEGACY_ADMIN' ) && CARTFLOWS_LEGACY_ADMIN;
258 +
259 + $settings_args = array( 'page' => CARTFLOWS_SLUG );
260 +
261 + if ( $is_legacy_admin ) {
262 + $settings_args['settings'] = true;
263 + } else {
264 + $settings_args['path'] = 'settings';
265 + }
266 +
267 + $default_url = add_query_arg( $settings_args, admin_url( 'admin.php' ) );
268 +
269 + array_unshift( $mylinks, '<a href="' . esc_url( $default_url ) . '">' . __( 'Settings', 'cartflows' ) . '</a>' );
218 270 }
219 - return false;
271 +
272 + if ( ! _is_cartflows_pro() ) {
273 + array_push(
274 + $mylinks,
275 + '<a style="color: #39b54a; font-weight: 700;" target="_blank" href="' . esc_url(
276 + Cartflows_Helper::get_upgrade_to_pro_link( 'pricing', '', array( 'utm_source' => 'plugin-page' ) )
277 + ) . '"> ' . __( 'Get CartFlows Pro', 'cartflows' ) . ' </a>'
278 + );
279 + }
280 +
281 + return array_merge( $links, $mylinks );
220 282 }
221 283
222 284 /**
223 285 * Check is flow admin.
@@ -224,9 +286,9 @@
224 286 *
225 287 * @since 1.0.0
226 288 * @return boolean
227 289 */
228 - static public function is_flow_edit_admin() {
290 + public static function is_flow_edit_admin() {
229 291
230 292 $current_screen = get_current_screen();
231 293
232 294 if (
@@ -241,158 +303,155 @@
241 303 return false;
242 304 }
243 305
244 306 /**
245 - * Global Admin Scripts.
307 + * Admin body classes.
246 308 *
247 - * @since 1.0.0
309 + * Body classes to be added to <body> tag in admin page
310 + *
311 + * @param String $classes body classes returned from the filter.
312 + * @return String body classes to be added to <body> tag in admin page
248 313 */
249 - static public function global_admin_scripts() {
314 + public function add_admin_body_class( $classes ) {
250 315
251 - $localize = array(
252 - 'ajaxurl' => admin_url( 'admin-ajax.php' ),
253 - 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
254 - );
316 + $classes .= ' cartflows-' . CARTFLOWS_VER;
255 317
256 - wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
318 + if ( isset( $_GET['action'] ) && 'wcf-license' === sanitize_text_field( wp_unslash( $_GET['action'] ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
319 + $classes .= ' wcf-debug-page ';
320 + }
257 321
258 - if ( self::is_global_admin() ) {
259 -
260 - // Styles.
261 - wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
262 - wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
263 -
264 - wp_enqueue_script(
265 - 'wcf-global-admin',
266 - CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
267 - array( 'jquery' ),
268 - CARTFLOWS_VER,
269 - true
270 - );
271 -
272 - do_action( 'cartflows_global_admin_scripts' );
273 - }
322 + return $classes;
274 323 }
275 324
276 325 /**
277 - * Global Admin Data.
326 + * Check allowed screen for notices.
278 327 *
279 328 * @since 1.0.0
329 + * @return bool
280 330 */
281 - static public function global_admin_data() {
331 + public function allowed_screen_for_notices() {
282 332
283 - $current_screen = get_current_screen();
333 + $screen = get_current_screen();
334 + $screen_id = $screen ? $screen->id : '';
335 + $allowed_screens = array(
336 + 'toplevel_page_cartflows',
337 + 'edit-cartflows_flow',
338 + );
284 339
285 - if ( CARTFLOWS_FLOW_POST_TYPE !== $current_screen->post_type ) {
286 - return;
340 + if ( in_array( $screen_id, $allowed_screens, true ) ) {
341 + return true;
287 342 }
288 343
289 - ?>
290 -
291 - <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
292 - <div class="wcf-templates-popup-content">
293 - <div class="spinner"></div>
294 - <div class="wcf-templates-wrap wcf-templates-wrap-flows">
295 -
296 - <div id="wcf-remote-flow-actions" class="wcf-template-header">
297 - <div class="wcf-template-logo-wrap">
298 - <span class="wcf-cartflows-logo-img">
299 - <span class="cartflows-icon"></span>
300 - </span>
301 - <span class="wcf-cartflows-title"><?php _e( 'Flows Library', 'cartflows' ); ?></span>
302 - </div>
303 - <div class="wcf-tab-wrapper">
304 - <div id="wcf-page-builders">
305 - <ul class="wcf-page-builder-links filter-links">
306 - <li><a href="#" class="current" data-id="elementor"><?php _e( 'Elementor', 'cartflows' ); ?></a></li>
307 - <li><a href="#" data-id="divi"><?php _e( 'Divi', 'cartflows' ); ?></a></li>
308 - <li><a href="#" data-id="bb"><?php _e( 'Beaver Builder', 'cartflows' ); ?></a></li>
309 - </ul>
310 - </div>
311 - <!-- <div id="wcf-remote-flow-filters">
312 - <div id="cartflows-flow-funnel-type"></div>
313 - </div> -->
314 - </div>
315 - <div class="wcf-popup-close-wrap">
316 - <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
317 - </div>
318 - </div>
319 - <!-- <div class="wcf-search-form">
320 - <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
321 - <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
322 - </div> -->
323 -
324 - <div id="wcf-remote-content">
325 - <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"></div>
326 - <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
327 - </div>
328 - </div>
329 - </div>
330 - </div>
331 -
332 - <?php
344 + return false;
333 345 }
334 346
335 347 /**
336 - * Enqueues the needed CSS/JS for the builder's admin settings page.
348 + * Function to add the meta and headers for not to cache the CartFlows wp-admin page.
337 349 *
338 - * @since 1.0.0
350 + * @return void
339 351 */
340 - static public function styles_scripts() {
352 + public function add_admin_cache_restrict_meta() {
341 353
342 - // Styles.
343 - wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
344 - wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
354 + if ( ! $this->allowed_screen_for_notices() ) {
355 + return;
356 + }
345 357
346 - // Script.
347 - wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER );
348 -
349 - $localize = array(
350 - 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
351 - );
352 -
353 - wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
358 + echo '<!-- Added by CartFlows -->';
359 + echo '<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" />';
360 + echo '<!-- Added by CartFlows -->';
354 361 }
355 362
356 363 /**
357 - * Save All admin settings here
364 + * Function to add the Do Not Cache Constants on the CartFlows admin pages.
365 + *
366 + * @return void
358 367 */
359 - static public function save_settings() {
360 -
361 - // Only admins can save settings.
362 - if ( ! current_user_can( 'manage_options' ) ) {
363 - return;
368 + public function add_admin_cache_restrict_const() {
369 + // Ignoring nonce verification as using SuperGlobal variables on WordPress hooks.
370 + if ( isset( $_GET['page'] ) && ( 'cartflows' === sanitize_text_field( $_GET['page'] ) || false !== strpos( sanitize_text_field( $_GET['page'] ), 'cartflows_' ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
371 + wcf()->utils->get_cache_headers();
364 372 }
365 -
366 - self::save_common_settings();
367 -
368 - // Let extensions hook into saving.
369 - do_action( 'cartflows_admin_settings_save' );
370 373 }
371 374
372 375 /**
373 - * Get and return page URL
376 + * CartFlows version rollback.
374 377 *
375 - * @param string $menu_slug Menu name.
376 - * @since 1.0.0
377 - * @return string page url
378 + * Rollback to previous CartFlows version.
379 + *
380 + * Fired by `admin_post_cartflows_rollback` action.
381 + *
382 + * @since 2.1.6
383 + * @access public
384 + * @return void
378 385 */
379 - static public function get_page_url( $menu_slug ) {
386 + public function post_cartflows_rollback() {
380 387
381 - $parent_page = self::$default_menu_position;
388 + if ( ! current_user_can( 'install_plugins' ) ) {
389 + wp_die(
390 + esc_html__( 'You do not have permission to access this page.', 'cartflows' ),
391 + esc_html__( 'Rollback to Previous Version', 'cartflows' ),
392 + array(
393 + 'response' => 200,
394 + )
395 + );
396 + }
382 397
383 - if ( strpos( $parent_page, '?' ) !== false ) {
384 - $query_var = '&page=' . self::$plugin_slug;
385 - } else {
386 - $query_var = '?page=' . self::$plugin_slug;
398 + check_admin_referer( 'cartflows_rollback' );
399 +
400 + $rollback_versions = \Cartflows_Helper::get_rollback_versions();
401 + $update_version = isset( $_GET['version'] ) ? sanitize_text_field( $_GET['version'] ) : '';
402 +
403 + if ( empty( $update_version ) || ! in_array( $update_version, $rollback_versions, true ) ) {
404 + wp_die( esc_html__( 'Error occurred, The version selected is invalid. Try selecting different version.', 'cartflows' ) );
387 405 }
388 406
389 - $parent_page_url = admin_url( $parent_page . $query_var );
407 + $plugin_slug = basename( CARTFLOWS_FILE, '.php' );
390 408
391 - $url = $parent_page_url . '&action=' . $menu_slug;
409 + $rollback = new Cartflows_Rollback(
410 + array(
411 + 'version' => $update_version,
412 + 'plugin_name' => CARTFLOWS_BASE,
413 + 'plugin_slug' => $plugin_slug,
414 + 'package_url' => sprintf( 'https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $update_version ),
415 + )
416 + );
392 417
393 - return esc_url( $url );
418 + $rollback->run();
419 +
420 + wp_die(
421 + '',
422 + esc_html__( 'Rollback to Previous Version', 'cartflows' ),
423 + array(
424 + 'response' => 200,
425 + )
426 + );
394 427 }
395 428
429 + /**
430 + * Provide CartFlows Pointer configuration via filter.
431 + *
432 + * @param array<string, mixed> $config Existing configuration.
433 + * @return array<string, mixed> Pointer configuration.
434 + */
435 + public function get_pointer_config( $config ) {
436 + return array(
437 + 'option_name' => 'cartflows_pointer_data',
438 + 'title' => __( 'CartFlows is waiting for you!', 'cartflows' ),
439 + 'content' => sprintf(
440 + /* translators: %1$s opening <strong> tag, %2$s closing </strong> tag */
441 + __( '%1$sLaunch your first funnel in minutes.%2$s Follow a guided setup to start capturing leads or sales immediately.', 'cartflows' ),
442 + '<strong>',
443 + '</strong>'
444 + ),
445 + 'button_text' => __( 'Create My First Funnel', 'cartflows' ),
446 + 'button_url' => admin_url( 'admin.php?page=cartflows' ),
447 + 'dismiss_text' => __( 'Dismiss', 'cartflows' ),
448 + 'target_selector' => '#toplevel_page_cartflows',
449 + 'fallback_target' => '#menu-plugins',
450 + 'allowed_pages' => array( 'index.php', 'plugins.php' ),
451 + 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
452 + 'max_posts' => 0,
453 + );
454 + }
396 455 }
397 456
398 -Cartflows_Admin::init();
457 +Cartflows_Admin::get_instance();