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 +294 -274 1.1.10 → 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,217 +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 );
57 -
58 - /* Add lite version class to body */
59 - add_action( 'admin_body_class', __CLASS__ . '::add_admin_body_class' );
76 + // Provide pointer configuration via filter.
77 + add_filter( 'cartflows_pointer_config', array( $this, 'get_pointer_config' ) );
60 78 }
61 79
62 80 /**
63 - * Initialises the Plugin Name.
81 + * Do not cache admin pages actions.
64 82 *
65 - * @since 1.0.0
83 + * @since 1.6.13
66 84 * @return void
67 85 */
68 - static public function initialise_plugin() {
86 + public function do_not_cache_admin_pages_actions() {
69 87
70 - $name = 'Cartflows';
71 - $short_name = 'Cflows';
72 -
73 - define( 'CARTFLOWS_PLUGIN_NAME', $name );
74 - 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' ) );
75 90 }
76 91
77 92 /**
78 - * Renders the admin settings menu.
93 + * Run scheduled job for CartFLows knowledge base data.
79 94 *
80 - * @since 1.0.0
95 + * @since 2.0.0
81 96 * @return void
82 97 */
83 - static public function menu() {
98 + public function run_scheduled_docs_job() {
84 99
85 - if ( ! current_user_can( 'manage_options' ) ) {
100 + if ( wp_installing() ) {
86 101 return;
87 102 }
88 103
89 - add_menu_page(
90 - 'CartFlows',
91 - 'CartFlows',
92 - 'manage_options',
93 - CARTFLOWS_SLUG,
94 - __CLASS__ . '::render',
95 - 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),
96 - 39.7
97 - );
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 + }
98 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 + }
99 112 }
100 113
101 114 /**
102 - * Add submenu to admin menu.
115 + * Cartflows's REST knowledge base data.
103 116 *
104 - * @since 1.0.0
117 + * @since 2.0.0
118 + * @return mixed
105 119 */
106 - 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' ) ) );
107 122
108 - $parent_slug = CARTFLOWS_SLUG;
109 - $page_title = __( 'Settings', 'cartflows' );
110 - $menu_title = __( 'Settings', 'cartflows' );
111 - $capability = 'manage_options';
112 - $menu_slug = 'cartflows_settings';
113 - $callback = __CLASS__ . '::render';
114 -
115 - add_submenu_page(
116 - $parent_slug,
117 - $page_title,
118 - $menu_title,
119 - $capability,
120 - $menu_slug,
121 - $callback
122 - );
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 );
123 125 }
124 126
125 127 /**
126 - * Renders the admin settings.
127 - *
128 - * @since 1.0.0
129 - * @return void
128 + * Init dashboard widgets.
130 129 */
131 - static public function render() {
132 - $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
133 - $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
134 - $action = str_replace( '_', '-', $action );
130 + public function dashboard_widget() {
135 131
136 - // Enable header icon filter below.
137 - $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
138 -
139 - 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 + }
140 139 }
141 140
142 141 /**
143 - * Renders the admin settings content.
144 - *
145 - * @since 1.0.0
146 - * @return void
142 + * Show status widget.
147 143 */
148 - static public function render_content() {
144 + public function status_widget() {
149 145
150 - $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
151 - $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
152 - $action = str_replace( '_', '-', $action );
153 - $action = 'general';
146 + $admin_url = admin_url( 'index.php' ) . '?page=cartflows-onboarding&';
154 147
155 - $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 + );
156 156
157 - 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
158 196 }
159 197
160 198 /**
161 - * Save Global Setting options.
199 + * Add the clone link to action list for flows row actions
162 200 *
163 - * @since 1.0.0
201 + * @param array $actions Actions array.
202 + * @param object $post Post object.
203 + *
204 + * @return array
164 205 */
165 - static public function save_common_settings() {
206 + public function remove_flow_actions( $actions, $post ) {
166 207
167 - 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 ) {
168 209
169 - $url = $_SERVER['REQUEST_URI'];
170 - $input_settings = array();
171 - $new_settings = array();
210 + if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
211 + unset( $actions['duplicate'] );
212 + }
172 213
173 - if ( isset( $_POST['_cartflows_common'] ) ) {
174 -
175 - $input_settings = $_POST['_cartflows_common'];
176 -
177 - // Loop through the input and sanitize each of the values.
178 - foreach ( $input_settings as $key => $val ) {
179 -
180 - if ( is_array( $val ) ) {
181 - foreach ( $val as $k => $v ) {
182 - $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
183 - }
184 - } else {
185 - $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
186 - }
187 - }
214 + if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
215 + unset( $actions['edit_as_new_draft'] );
188 216 }
217 + }
189 218
190 - Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, true );
219 + return $actions;
220 + }
191 221
192 - $query = array(
193 - 'message' => 'saved',
194 - );
222 + /**
223 + * After save of permalinks.
224 + */
225 + public static function flush_rules_after_save_permalinks() {
195 226
196 - $redirect_to = add_query_arg( $query, $url );
197 -
198 - wp_redirect( $redirect_to );
199 - exit;
200 - } // 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 + }
201 233 }
202 234
203 235 /**
204 - * Check is cartflows admin.
236 + * Show action on plugin page.
205 237 *
206 - * @since 1.0.0
207 - * @return boolean
238 + * @param array $links links.
239 + * @return array
208 240 */
209 - static public function is_global_admin() {
241 + public function add_action_links( $links ) {
210 242
211 - $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 + );
212 254
213 - if (
214 - is_object( $current_screen ) &&
215 - isset( $current_screen->post_type ) &&
216 - ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
217 - CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
218 - )
219 - ) {
220 - 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>' );
221 270 }
222 - 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 );
223 282 }
224 283
225 284 /**
226 285 * Check is flow admin.
@@ -227,9 +286,9 @@
227 286 *
228 287 * @since 1.0.0
229 288 * @return boolean
230 289 */
231 - static public function is_flow_edit_admin() {
290 + public static function is_flow_edit_admin() {
232 291
233 292 $current_screen = get_current_screen();
234 293
235 294 if (
@@ -244,194 +303,155 @@
244 303 return false;
245 304 }
246 305
247 306 /**
248 - * Global Admin Scripts.
307 + * Admin body classes.
249 308 *
250 - * @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
251 313 */
252 - static public function global_admin_scripts() {
314 + public function add_admin_body_class( $classes ) {
253 315
254 - $localize = array(
255 - 'ajaxurl' => admin_url( 'admin-ajax.php' ),
256 - 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
257 - );
316 + $classes .= ' cartflows-' . CARTFLOWS_VER;
258 317
259 - 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 + }
260 321
261 - if ( self::is_global_admin() ) {
262 -
263 - // Styles.
264 - wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
265 - wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
266 -
267 - wp_enqueue_script(
268 - 'wcf-global-admin',
269 - CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
270 - array( 'jquery' ),
271 - CARTFLOWS_VER,
272 - true
273 - );
274 -
275 - do_action( 'cartflows_global_admin_scripts' );
276 - }
322 + return $classes;
277 323 }
278 324
279 325 /**
280 - * Global Admin Data.
326 + * Check allowed screen for notices.
281 327 *
282 328 * @since 1.0.0
329 + * @return bool
283 330 */
284 - static public function global_admin_data() {
331 + public function allowed_screen_for_notices() {
285 332
286 - $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 + );
287 339
288 - if ( ! $current_screen ) {
289 - return;
340 + if ( in_array( $screen_id, $allowed_screens, true ) ) {
341 + return true;
290 342 }
291 343
292 - if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
293 - return;
294 - }
295 -
296 - $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
297 - ?>
298 -
299 - <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
300 - <div class="wcf-templates-popup-content">
301 - <div class="spinner"></div>
302 - <div class="wcf-templates-wrap wcf-templates-wrap-flows">
303 -
304 - <div id="wcf-remote-flow-actions" class="wcf-template-header">
305 - <div class="wcf-template-logo-wrap">
306 - <span class="wcf-cartflows-logo-img">
307 - <span class="cartflows-icon"></span>
308 - </span>
309 - <span class="wcf-cartflows-title"><?php _e( 'Flows Library', 'cartflows' ); ?></span>
310 - </div>
311 - <div class="wcf-tab-wrapper">
312 - <?php if ( 'other' !== $default_page_builder ) { ?>
313 - <div id="wcf-get-started-steps">
314 - <ul class="filter-links ">
315 - <li>
316 - <a href="#" class="current" data-slug="ready-templates" data-title="<?php _e( 'Ready Templates', 'cartflows' ); ?>"><?php _e( 'Ready Templates', 'cartflows' ); ?></a>
317 - </li>
318 - <li>
319 - <a href="#" data-slug="canvas" data-title="<?php _e( 'Create Your Own', 'cartflows' ); ?>"><?php _e( 'Create Your Own', 'cartflows' ); ?></a>
320 - </li>
321 - </ul>
322 - </div>
323 - <?php } ?>
324 - </div>
325 - <div class="wcf-popup-close-wrap">
326 - <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
327 - </div>
328 - </div>
329 - <!-- <div class="wcf-search-form">
330 - <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
331 - <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
332 - </div> -->
333 -
334 - <div id="wcf-remote-content">
335 - <?php if ( 'other' !== $default_page_builder ) { ?>
336 - <div id="wcf-ready-templates">
337 - <div id="wcf-remote-filters">
338 - <div id="wcf-page-builders"></div>
339 - <div id="wcf-categories"></div>
340 - </div>
341 - <div class="wcf-page-builder-notice"></div>
342 - <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
343 - <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
344 - </div>
345 - <?php } ?>
346 - <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
347 - <div class="inner">
348 - <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php _e( 'Design Your Flow', 'cartflows' ); ?></a>
349 - <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php _e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
350 - </div>
351 - </div>
352 - </div>
353 - </div>
354 - </div>
355 - </div>
356 -
357 - <?php
344 + return false;
358 345 }
359 346
360 347 /**
361 - * 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.
362 349 *
363 - * @since 1.0.0
350 + * @return void
364 351 */
365 - static public function styles_scripts() {
352 + public function add_admin_cache_restrict_meta() {
366 353
367 - // Styles.
368 - wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
369 - wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
354 + if ( ! $this->allowed_screen_for_notices() ) {
355 + return;
356 + }
370 357
371 - // Script.
372 - wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER );
373 -
374 - $localize = array(
375 - 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
376 - );
377 -
378 - 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 -->';
379 361 }
380 362
381 363 /**
382 - * Save All admin settings here
364 + * Function to add the Do Not Cache Constants on the CartFlows admin pages.
365 + *
366 + * @return void
383 367 */
384 - static public function save_settings() {
385 -
386 - // Only admins can save settings.
387 - if ( ! current_user_can( 'manage_options' ) ) {
388 - 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();
389 372 }
390 -
391 - self::save_common_settings();
392 -
393 - // Let extensions hook into saving.
394 - do_action( 'cartflows_admin_settings_save' );
395 373 }
396 374
397 375 /**
398 - * Get and return page URL
376 + * CartFlows version rollback.
399 377 *
400 - * @param string $menu_slug Menu name.
401 - * @since 1.0.0
402 - * @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
403 385 */
404 - static public function get_page_url( $menu_slug ) {
386 + public function post_cartflows_rollback() {
405 387
406 - $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 + }
407 397
408 - if ( strpos( $parent_page, '?' ) !== false ) {
409 - $query_var = '&page=' . self::$plugin_slug;
410 - } else {
411 - $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' ) );
412 405 }
413 406
414 - $parent_page_url = admin_url( $parent_page . $query_var );
407 + $plugin_slug = basename( CARTFLOWS_FILE, '.php' );
415 408
416 - $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 + );
417 417
418 - 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 + );
419 427 }
420 428
421 429 /**
422 - * Admin body classes.
430 + * Provide CartFlows Pointer configuration via filter.
423 431 *
424 - * Body classes to be added to <body> tag in admin page
425 - *
426 - * @param String $classes body classes returned from the filter.
427 - * @return String body classes to be added to <body> tag in admin page
432 + * @param array<string, mixed> $config Existing configuration.
433 + * @return array<string, mixed> Pointer configuration.
428 434 */
429 - static public function add_admin_body_class( $classes ) {
430 -
431 - $classes .= ' cartflows-' . CARTFLOWS_VER;
432 -
433 - return $classes;
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 + );
434 454 }
435 455 }
436 456
437 -Cartflows_Admin::init();
457 +Cartflows_Admin::get_instance();