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
cartflows / classes / class-cartflows-admin.php

class-cartflows-admin.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.3.0, at classes/class-cartflows-admin.php

458 lines 13.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * CartFlows Admin.
4 *
5 * @package CartFlows
6 */
7
8 // Exit if accessed directly.
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12 /**
13 * Class Cartflows_Admin.
14 */
15 class Cartflows_Admin {
16
17 /**
18 * Instance
19 *
20 * @access private
21 * @var object Class object.
22 * @since 1.0.0
23 */
24 private static $instance;
25
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;
37 }
38
39 /**
40 * Constructor
41 */
42 public function __construct() {
43
44 $this->init_hooks();
45 }
46
47 /**
48 * Init Hooks.
49 *
50 * @since 1.0.0
51 * @return void
52 */
53 public function init_hooks() {
54
55 if ( ! is_admin() ) {
56 return;
57 }
58
59 /* Add lite version class to body */
60 add_action( 'admin_body_class', array( $this, 'add_admin_body_class' ) );
61
62 add_filter( 'plugin_action_links_' . CARTFLOWS_BASE, array( $this, 'add_action_links' ) );
63
64 add_action( 'admin_init', array( $this, 'flush_rules_after_save_permalinks' ) );
65
66 add_filter( 'post_row_actions', array( $this, 'remove_flow_actions' ), 99, 2 );
67
68 add_action( 'wp_dashboard_setup', array( $this, 'dashboard_widget' ) );
69
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' ) );
73
74 $this->do_not_cache_admin_pages_actions();
75
76 // Provide pointer configuration via filter.
77 add_filter( 'cartflows_pointer_config', array( $this, 'get_pointer_config' ) );
78 }
79
80 /**
81 * Do not cache admin pages actions.
82 *
83 * @since 1.6.13
84 * @return void
85 */
86 public function do_not_cache_admin_pages_actions() {
87
88 add_action( 'admin_init', array( $this, 'add_admin_cache_restrict_const' ) );
89 add_action( 'admin_head', array( $this, 'add_admin_cache_restrict_meta' ) );
90 }
91
92 /**
93 * Run scheduled job for CartFLows knowledge base data.
94 *
95 * @since 2.0.0
96 * @return void
97 */
98 public function run_scheduled_docs_job() {
99
100 if ( wp_installing() ) {
101 return;
102 }
103
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 }
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 }
112 }
113
114 /**
115 * Cartflows's REST knowledge base data.
116 *
117 * @since 2.0.0
118 * @return mixed
119 */
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' ) ) );
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 );
125 }
126
127 /**
128 * Init dashboard widgets.
129 */
130 public function dashboard_widget() {
131
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 }
139 }
140
141 /**
142 * Show status widget.
143 */
144 public function status_widget() {
145
146 $admin_url = admin_url( 'index.php' ) . '?page=cartflows-onboarding&';
147
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
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
196 }
197
198 /**
199 * Add the clone link to action list for flows row actions
200 *
201 * @param array $actions Actions array.
202 * @param object $post Post object.
203 *
204 * @return array
205 */
206 public function remove_flow_actions( $actions, $post ) {
207
208 if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
209
210 if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
211 unset( $actions['duplicate'] );
212 }
213
214 if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
215 unset( $actions['edit_as_new_draft'] );
216 }
217 }
218
219 return $actions;
220 }
221
222 /**
223 * After save of permalinks.
224 */
225 public static function flush_rules_after_save_permalinks() {
226
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 }
233 }
234
235 /**
236 * Show action on plugin page.
237 *
238 * @param array $links links.
239 * @return array
240 */
241 public function add_action_links( $links ) {
242
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 );
254
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>' );
270 }
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 );
282 }
283
284 /**
285 * Check is flow admin.
286 *
287 * @since 1.0.0
288 * @return boolean
289 */
290 public static function is_flow_edit_admin() {
291
292 $current_screen = get_current_screen();
293
294 if (
295 is_object( $current_screen ) &&
296 isset( $current_screen->post_type ) &&
297 ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
298 isset( $current_screen->base ) &&
299 ( 'post' === $current_screen->base )
300 ) {
301 return true;
302 }
303 return false;
304 }
305
306 /**
307 * Admin body classes.
308 *
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
313 */
314 public function add_admin_body_class( $classes ) {
315
316 $classes .= ' cartflows-' . CARTFLOWS_VER;
317
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 }
321
322 return $classes;
323 }
324
325 /**
326 * Check allowed screen for notices.
327 *
328 * @since 1.0.0
329 * @return bool
330 */
331 public function allowed_screen_for_notices() {
332
333 $screen = get_current_screen();
334 $screen_id = $screen ? $screen->id : '';
335 $allowed_screens = array(
336 'toplevel_page_cartflows',
337 'edit-cartflows_flow',
338 );
339
340 if ( in_array( $screen_id, $allowed_screens, true ) ) {
341 return true;
342 }
343
344 return false;
345 }
346
347 /**
348 * Function to add the meta and headers for not to cache the CartFlows wp-admin page.
349 *
350 * @return void
351 */
352 public function add_admin_cache_restrict_meta() {
353
354 if ( ! $this->allowed_screen_for_notices() ) {
355 return;
356 }
357
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 -->';
361 }
362
363 /**
364 * Function to add the Do Not Cache Constants on the CartFlows admin pages.
365 *
366 * @return void
367 */
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();
372 }
373 }
374
375 /**
376 * CartFlows version rollback.
377 *
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
385 */
386 public function post_cartflows_rollback() {
387
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 }
397
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' ) );
405 }
406
407 $plugin_slug = basename( CARTFLOWS_FILE, '.php' );
408
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
418 $rollback->run();
419
420 wp_die(
421 '',
422 esc_html__( 'Rollback to Previous Version', 'cartflows' ),
423 array(
424 'response' => 200,
425 )
426 );
427 }
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 }
455 }
456
457 Cartflows_Admin::get_instance();
458