| 1 |
<?php |
| 2 |
/** |
| 3 |
* CartFlows Admin Menu. |
| 4 |
* |
| 5 |
* @package CartFlows |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace CartflowsAdmin\AdminCore\Inc; |
| 9 |
|
| 10 |
use CartflowsAdmin\AdminCore\Inc\AdminHelper; |
| 11 |
use CartflowsAdmin\AdminCore\Inc\LogStatus; |
| 12 |
|
| 13 |
|
| 14 |
// Exit if accessed directly. |
| 15 |
if ( ! defined( 'ABSPATH' ) ) { |
| 16 |
exit; |
| 17 |
} |
| 18 |
|
| 19 |
/** |
| 20 |
* Class Admin_Menu. |
| 21 |
*/ |
| 22 |
class AdminMenu { |
| 23 |
|
| 24 |
/** |
| 25 |
* Instance |
| 26 |
* |
| 27 |
* @access private |
| 28 |
* @var object Class object. |
| 29 |
* @since 1.0.0 |
| 30 |
*/ |
| 31 |
private static $instance; |
| 32 |
|
| 33 |
/** |
| 34 |
* For Gutenberg |
| 35 |
* |
| 36 |
* @var $is_gutenberg_editor_active |
| 37 |
*/ |
| 38 |
private $is_gutenberg_editor_active = false; |
| 39 |
|
| 40 |
/** |
| 41 |
* Initiator |
| 42 |
* |
| 43 |
* @since 1.0.0 |
| 44 |
* @return object initialized object of class. |
| 45 |
*/ |
| 46 |
public static function get_instance() { |
| 47 |
if ( ! isset( self::$instance ) ) { |
| 48 |
self::$instance = new self(); |
| 49 |
} |
| 50 |
return self::$instance; |
| 51 |
} |
| 52 |
|
| 53 |
/** |
| 54 |
* Instance |
| 55 |
* |
| 56 |
* @access private |
| 57 |
* @var string Class object. |
| 58 |
* @since 1.0.0 |
| 59 |
*/ |
| 60 |
private $menu_slug; |
| 61 |
|
| 62 |
/** |
| 63 |
* Constructor |
| 64 |
* |
| 65 |
* @since 1.0.0 |
| 66 |
*/ |
| 67 |
public function __construct() { |
| 68 |
$this->menu_slug = 'cartflows'; |
| 69 |
|
| 70 |
$this->initialize_hooks(); |
| 71 |
} |
| 72 |
|
| 73 |
/** |
| 74 |
* Init Hooks. |
| 75 |
* |
| 76 |
* @since 1.0.0 |
| 77 |
* @return void |
| 78 |
*/ |
| 79 |
public function initialize_hooks() { |
| 80 |
|
| 81 |
add_action( 'admin_menu', array( $this, 'setup_menu' ) ); |
| 82 |
add_action( 'admin_init', array( $this, 'settings_admin_scripts' ) ); |
| 83 |
add_action( 'admin_init', array( $this, 'add_capabilities_to_admin' ) ); |
| 84 |
|
| 85 |
/* Flow content view */ |
| 86 |
add_action( 'cartflows_render_admin_page_content', array( $this, 'render_content' ), 10, 2 ); |
| 87 |
|
| 88 |
add_action( 'edit_form_after_title', array( $this, 'new_admin_flow_setting_redirection' ), 10, 1 ); |
| 89 |
|
| 90 |
/* To check the status of gutenberg */ |
| 91 |
add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) ); |
| 92 |
add_action( 'admin_footer', array( $this, 'back_to_new_step_ui_for_gutenberg' ), 999 ); |
| 93 |
|
| 94 |
add_action( 'admin_notices', array( $this, 'back_to_new_step_ui_for_classic_editor' ) ); |
| 95 |
|
| 96 |
add_action( 'wp_ajax_cartflows_fetch_whats_new_data', array( $this, 'fetch_whats_new_data' ) ); |
| 97 |
} |
| 98 |
|
| 99 |
/** |
| 100 |
* Display admin notices. |
| 101 |
* |
| 102 |
* @since 1.0.0 |
| 103 |
* |
| 104 |
* @return void |
| 105 |
*/ |
| 106 |
public function back_to_new_step_ui_for_classic_editor() { |
| 107 |
|
| 108 |
if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) { |
| 109 |
return; |
| 110 |
} |
| 111 |
|
| 112 |
$flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true ); |
| 113 |
$step_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 114 |
|
| 115 |
if ( $flow_id && $step_id ) { |
| 116 |
$path = \Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ) === $flow_id ? 'store-checkout' : 'flows'; |
| 117 |
|
| 118 |
$flow_redirect_url = esc_url( admin_url() . 'admin.php?page=' . $this->menu_slug . '&path= ' . $path . '&action=wcf-edit-flow&flow_id=' . $flow_id ); // phpcs:igmore Generic.Strings.UnnecessaryStringConcat.Found. |
| 119 |
?> |
| 120 |
<div class="wcf-notice-back-edit-step"> |
| 121 |
<p> |
| 122 |
<a href="<?php echo esc_url( $flow_redirect_url ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;"> |
| 123 |
<?php esc_html_e( 'Edit Funnel', 'cartflows' ); ?> |
| 124 |
</a> |
| 125 |
</p> |
| 126 |
</div> |
| 127 |
<?php |
| 128 |
} |
| 129 |
} |
| 130 |
|
| 131 |
/** |
| 132 |
* Set status true for gutenberg. |
| 133 |
* |
| 134 |
* @return void |
| 135 |
*/ |
| 136 |
public function set_block_editor_status() { |
| 137 |
|
| 138 |
if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) { |
| 139 |
return; |
| 140 |
} |
| 141 |
|
| 142 |
// Set gutenberg status here. |
| 143 |
$this->is_gutenberg_editor_active = true; |
| 144 |
} |
| 145 |
|
| 146 |
/** |
| 147 |
* Back to flow button gutenberg template |
| 148 |
* |
| 149 |
* @return void |
| 150 |
*/ |
| 151 |
public function back_to_new_step_ui_for_gutenberg() { |
| 152 |
|
| 153 |
// Exit if block editor is not enabled. |
| 154 |
if ( ! $this->is_gutenberg_editor_active ) { |
| 155 |
return; |
| 156 |
} |
| 157 |
|
| 158 |
wp_enqueue_script( 'cartflows-admin-common-script', CARTFLOWS_ADMIN_CORE_URL . 'assets/js/common.js', array( 'jquery' ), CARTFLOWS_VER, false ); |
| 159 |
|
| 160 |
if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) { |
| 161 |
return; |
| 162 |
} |
| 163 |
|
| 164 |
$flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true ); |
| 165 |
$step_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 166 |
|
| 167 |
if ( $flow_id && $step_id ) { |
| 168 |
$path = \Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ) === $flow_id ? 'store-checkout' : 'flows'; |
| 169 |
$flow_redirect_url = esc_url( admin_url() . 'admin.php?page=' . $this->menu_slug . '&path=' . $path . '&action=wcf-edit-flow&flow_id=' . $flow_id ); |
| 170 |
?> |
| 171 |
<script id="wcf-gutenberg-back-step-button" type="text/html"> |
| 172 |
<div class="wcf-notice-back-edit-step gutenberg-button" style="display: flex; margin: 2px 5px;"> |
| 173 |
<a href="<?php echo esc_url( $flow_redirect_url ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none; font-size: 13px; line-height: 2.5;"><?php esc_html_e( 'Edit Funnel', 'cartflows' ); ?></a> |
| 174 |
</div> |
| 175 |
</script> |
| 176 |
<script> |
| 177 |
window.addEventListener('load', function () { |
| 178 |
( function( window, wp ){ |
| 179 |
var link = document.querySelector('a.components-button.edit-post-fullscreen-mode-close'); |
| 180 |
if (link) { |
| 181 |
link.setAttribute('href', "<?php echo htmlspecialchars_decode( esc_url( $flow_redirect_url ) );//phpcs:ignore ?>") |
| 182 |
} |
| 183 |
|
| 184 |
} )( window, wp ) |
| 185 |
}); |
| 186 |
</script> |
| 187 |
<?php |
| 188 |
} |
| 189 |
} |
| 190 |
|
| 191 |
|
| 192 |
/** |
| 193 |
* Back to flow button |
| 194 |
* |
| 195 |
* @param array $meta meta data. |
| 196 |
* |
| 197 |
* @return void |
| 198 |
*/ |
| 199 |
public function new_admin_flow_setting_redirection( $meta ) { |
| 200 |
|
| 201 |
$flow_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 202 |
|
| 203 |
$post_type = get_post_type(); |
| 204 |
|
| 205 |
if ( CARTFLOWS_FLOW_POST_TYPE === $post_type && 0 !== $flow_id ) { |
| 206 |
|
| 207 |
$redirect_url = esc_url( admin_url() . 'admin.php?page=' . $this->menu_slug . '&path=flows&action=wcf-edit-flow&flow_id=' . $flow_id ); |
| 208 |
$btn_markup = '<div class="wcf-flow-editing-action" style="padding: 50px;text-align: center;">'; |
| 209 |
$btn_markup .= '<a class="button button-primary button-hero" href="' . $redirect_url . '">' . __( 'Go to Funnel Editing', 'cartflows' ) . '</a>'; |
| 210 |
$btn_markup .= '</div>'; |
| 211 |
|
| 212 |
echo wp_kses_post( $btn_markup ); |
| 213 |
} |
| 214 |
} |
| 215 |
|
| 216 |
/** |
| 217 |
* Initialize after Cartflows pro get loaded. |
| 218 |
*/ |
| 219 |
public function settings_admin_scripts() { |
| 220 |
|
| 221 |
// Enqueue admin scripts. |
| 222 |
// Ignoring nonce verification as using SuperGlobal variables on WordPress hooks. |
| 223 |
if ( isset( $_GET['page'] ) && ( 'cartflows' === sanitize_text_field( $_GET['page'] ) || false !== strpos( sanitize_text_field( $_GET['page'] ), 'cartflows_' ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 224 |
|
| 225 |
add_action( 'admin_enqueue_scripts', array( $this, 'styles_scripts' ) ); |
| 226 |
} |
| 227 |
} |
| 228 |
|
| 229 |
/** |
| 230 |
* Add submenu to admin menu. |
| 231 |
* |
| 232 |
* @since 1.0.0 |
| 233 |
*/ |
| 234 |
public function setup_menu() { |
| 235 |
global $submenu; |
| 236 |
|
| 237 |
if ( current_user_can( 'cartflows_manage_flows_steps' ) ) { |
| 238 |
$parent_slug = $this->menu_slug; |
| 239 |
$capability = 'cartflows_manage_flows_steps'; |
| 240 |
$menu_priority = apply_filters( 'cartflows_menu_priority', ! defined( 'ASTRA_THEME_VERSION' ) ? 40 : 3 ); |
| 241 |
|
| 242 |
add_menu_page( |
| 243 |
'CartFlows', |
| 244 |
'CartFlows', |
| 245 |
$capability, |
| 246 |
$parent_slug, |
| 247 |
array( $this, 'render' ), |
| 248 |
'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ), |
| 249 |
$menu_priority |
| 250 |
); |
| 251 |
|
| 252 |
// Add settings menu. |
| 253 |
add_submenu_page( |
| 254 |
$parent_slug, |
| 255 |
__( 'Funnels', 'cartflows' ), |
| 256 |
__( 'Funnels', 'cartflows' ), |
| 257 |
$capability, |
| 258 |
'admin.php?page=' . $this->menu_slug . '&path=flows' |
| 259 |
); |
| 260 |
|
| 261 |
$global_checkout_id = absint( \Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ) ); |
| 262 |
$global_checkout_param = ( empty( $global_checkout_id ) ) ? 'path=store-checkout' : 'path=store-checkout&action=wcf-edit-flow&flow_id=' . $global_checkout_id; |
| 263 |
|
| 264 |
add_submenu_page( |
| 265 |
$parent_slug, |
| 266 |
__( 'Store Checkout', 'cartflows' ), |
| 267 |
__( 'Store Checkout', 'cartflows' ), |
| 268 |
$capability, |
| 269 |
'admin.php?page=' . $this->menu_slug . '&' . $global_checkout_param |
| 270 |
); |
| 271 |
|
| 272 |
add_submenu_page( |
| 273 |
$parent_slug, |
| 274 |
__( 'Analytics', 'cartflows' ), |
| 275 |
__( 'Analytics', 'cartflows' ), |
| 276 |
$capability, |
| 277 |
'admin.php?page=' . $this->menu_slug . '&path=analytics' |
| 278 |
); |
| 279 |
|
| 280 |
if ( current_user_can( 'cartflows_manage_settings' ) ) { |
| 281 |
|
| 282 |
add_submenu_page( |
| 283 |
$parent_slug, |
| 284 |
__( 'Learn', 'cartflows' ), |
| 285 |
__( 'Learn', 'cartflows' ), |
| 286 |
$capability, |
| 287 |
'admin.php?page=' . $this->menu_slug . '&path=learn' |
| 288 |
); |
| 289 |
|
| 290 |
if ( ! _is_cartflows_pro() ) { |
| 291 |
add_submenu_page( |
| 292 |
$parent_slug, |
| 293 |
__( 'Get CartFlows Pro', 'cartflows' ), |
| 294 |
__( 'Get CartFlows Pro', 'cartflows' ), |
| 295 |
$capability, |
| 296 |
\Cartflows_Helper::get_upgrade_to_pro_link() |
| 297 |
); |
| 298 |
} |
| 299 |
} |
| 300 |
|
| 301 |
// Rename to Home menu. |
| 302 |
// Disable phpcs since we need to override submenu name. |
| 303 |
$submenu[ $parent_slug ][0][0] = __( 'Dashboard', 'cartflows' ); //phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited |
| 304 |
} |
| 305 |
} |
| 306 |
|
| 307 |
/** |
| 308 |
* Add custom capabilities to Admin user. |
| 309 |
*/ |
| 310 |
public function add_capabilities_to_admin() { |
| 311 |
|
| 312 |
global $wp_roles; |
| 313 |
// Add custom capabilities to admin by default. |
| 314 |
$capabilities = array( |
| 315 |
'cartflows_manage_settings', |
| 316 |
'cartflows_manage_flows_steps', |
| 317 |
); |
| 318 |
|
| 319 |
foreach ( $capabilities as $cap ) { |
| 320 |
$wp_roles->add_cap( 'administrator', $cap ); |
| 321 |
} |
| 322 |
} |
| 323 |
|
| 324 |
/** |
| 325 |
* Renders the admin settings. |
| 326 |
* |
| 327 |
* @since 1.0.0 |
| 328 |
* @return void |
| 329 |
*/ |
| 330 |
public function render() { |
| 331 |
$menu_page_slug = ( isset( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : CARTFLOWS_SETTINGS; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 332 |
$page_action = ''; |
| 333 |
|
| 334 |
if ( isset( $_GET['action'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 335 |
$page_action = sanitize_text_field( wp_unslash( $_GET['action'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 336 |
$page_action = str_replace( '_', '-', $page_action ); |
| 337 |
} |
| 338 |
|
| 339 |
include_once CARTFLOWS_ADMIN_CORE_DIR . 'views/admin-base.php'; |
| 340 |
} |
| 341 |
|
| 342 |
/** |
| 343 |
* Renders the admin settings content. |
| 344 |
* |
| 345 |
* @since 1.0.0 |
| 346 |
* @param sting $menu_page_slug current page name. |
| 347 |
* @param sting $page_action current page action. |
| 348 |
* |
| 349 |
* @return void |
| 350 |
*/ |
| 351 |
public function render_content( $menu_page_slug, $page_action ) { |
| 352 |
|
| 353 |
if ( 'cartflows' === $menu_page_slug ) { |
| 354 |
if ( $this->is_current_page( 'cartflows' ) ) { |
| 355 |
include_once CARTFLOWS_ADMIN_CORE_DIR . 'views/settings-app.php'; |
| 356 |
} elseif ( $this->is_current_page( 'cartflows', array( 'wcf-edit-flow' ) ) ) { |
| 357 |
include_once CARTFLOWS_ADMIN_CORE_DIR . 'views/editor-app.php'; |
| 358 |
} elseif ( $this->is_current_page( 'cartflows', array( 'wcf-log' ) ) ) { |
| 359 |
include_once CARTFLOWS_ADMIN_CORE_DIR . 'views/debugger.php'; |
| 360 |
} elseif ( $this->is_current_page( 'cartflows', array( 'wcf-license' ) ) && _is_cartflows_pro() ) { |
| 361 |
do_action( 'cartflows_admin_log', 'wcf-license' ); |
| 362 |
} else { |
| 363 |
include_once CARTFLOWS_ADMIN_CORE_DIR . 'views/404-error.php'; |
| 364 |
} |
| 365 |
} |
| 366 |
} |
| 367 |
|
| 368 |
/** |
| 369 |
* Enqueues the needed CSS/JS for the builder's admin settings page. |
| 370 |
* |
| 371 |
* @since 1.0.0 |
| 372 |
*/ |
| 373 |
public function styles_scripts() { |
| 374 |
|
| 375 |
$admin_slug = 'cartflows-admin'; |
| 376 |
|
| 377 |
// Load the custom font for admin area. |
| 378 |
wp_enqueue_style( $admin_slug . '-font', 'https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600;700&display=swap', array(), CARTFLOWS_VER ); |
| 379 |
|
| 380 |
// Styles. |
| 381 |
wp_enqueue_style( $admin_slug . '-common', CARTFLOWS_ADMIN_CORE_URL . 'assets/css/common.css', array(), CARTFLOWS_VER ); |
| 382 |
wp_style_add_data( $admin_slug . '-common', 'rtl', 'replace' ); |
| 383 |
|
| 384 |
wp_enqueue_script( $admin_slug . '-common-script', CARTFLOWS_ADMIN_CORE_URL . 'assets/js/common.js', array( 'jquery' ), CARTFLOWS_VER, false ); |
| 385 |
|
| 386 |
wp_enqueue_script( $admin_slug . '-suretriggers-integration', CARTFLOWS_SURETRIGGERS_INTEGRATION_BASE_URL . 'js/v2/embed.js', array(), CARTFLOWS_VER, true ); |
| 387 |
|
| 388 |
$current_flow_steps = array(); |
| 389 |
$flow_id = isset( $_GET['flow_id'] ) ? intval( $_GET['flow_id'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 390 |
if ( $flow_id ) { |
| 391 |
$current_flow_steps = AdminHelper::get_flow_meta_options( $flow_id ); |
| 392 |
} |
| 393 |
|
| 394 |
$product_src = esc_url_raw( |
| 395 |
add_query_arg( |
| 396 |
array( |
| 397 |
'post_type' => 'product', |
| 398 |
'wcf-woo-iframe' => 'true', |
| 399 |
), |
| 400 |
admin_url( 'post-new.php' ) |
| 401 |
) |
| 402 |
); |
| 403 |
|
| 404 |
|
| 405 |
$page_builder = \Cartflows_Helper::get_common_setting( 'default_page_builder' ); |
| 406 |
$page_builder_name = \Cartflows_Helper::get_page_builder_name( $page_builder ); |
| 407 |
|
| 408 |
$global_checkout_id = \Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ); |
| 409 |
|
| 410 |
$flow_action = 'wcf-edit-flow'; |
| 411 |
$step_action = 'wcf-edit-step'; |
| 412 |
|
| 413 |
$flows_and_steps = \Cartflows_Helper::get_instance()->get_flows_and_steps(); |
| 414 |
|
| 415 |
$cf_pro_status = $this->get_cartflows_pro_plugin_status(); |
| 416 |
$cf_pro_type_inactive = ''; |
| 417 |
if ( 'inactive' === $cf_pro_status || 'not-installed' === $cf_pro_status ) { |
| 418 |
|
| 419 |
if ( ! function_exists( 'get_plugins' ) ) { |
| 420 |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 421 |
} |
| 422 |
|
| 423 |
$plugin = get_plugins(); |
| 424 |
$cf_pro_type_inactive = isset( $plugin['cartflows-pro/cartflows-pro.php']['Name'] ) ? $plugin['cartflows-pro/cartflows-pro.php']['Name'] : ''; |
| 425 |
} |
| 426 |
|
| 427 |
$order_url = '#'; |
| 428 |
|
| 429 |
if ( wcf()->is_woo_active && class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) ) { |
| 430 |
$order_url = \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ? admin_url( 'admin.php?page=wc-orders' ) : admin_url( 'edit.php?post_type=shop_order' ); |
| 431 |
} |
| 432 |
|
| 433 |
$localize = apply_filters( |
| 434 |
'cartflows_admin_localized_vars', |
| 435 |
array( |
| 436 |
'current_user' => ! empty( wp_get_current_user()->user_firstname ) ? wp_get_current_user()->user_firstname : wp_get_current_user()->display_name, |
| 437 |
'cf_pro_status' => $cf_pro_status, |
| 438 |
'cf_pro_type' => 'free', |
| 439 |
'cf_pro_type_inactive' => $cf_pro_type_inactive, |
| 440 |
'woocommerce_status' => $this->get_plugin_status( 'woocommerce/woocommerce.php' ), |
| 441 |
'default_page_builder' => $page_builder, |
| 442 |
'required_plugins' => \Cartflows_Helper::get_plugins_groupby_page_builders(), |
| 443 |
'required_plugins_data' => $this->get_required_plugins_data(), |
| 444 |
'is_any_required_plugins_missing' => $this->get_any_required_plugins_status(), |
| 445 |
'admin_base_slug' => $this->menu_slug, |
| 446 |
'admin_base_url' => admin_url(), |
| 447 |
'title_length' => apply_filters( |
| 448 |
'cartflows_flows_steps_title_length', |
| 449 |
array( |
| 450 |
'max' => 50, |
| 451 |
'display_length' => 40, |
| 452 |
) |
| 453 |
), |
| 454 |
'plugin_dir' => CARTFLOWS_URL, |
| 455 |
'admin_url' => admin_url( 'admin.php' ), |
| 456 |
'ajax_url' => admin_url( 'admin-ajax.php' ), |
| 457 |
'is_rtl' => is_rtl(), |
| 458 |
'home_slug' => $this->menu_slug, |
| 459 |
'is_pro' => _is_cartflows_pro(), |
| 460 |
'is_file_mod_disabled' => function_exists( 'wcf_file_mod_disabled' ) ? wcf_file_mod_disabled() : false, // Keep false by default if function not exists. |
| 461 |
'page_builder' => $page_builder, |
| 462 |
'page_builder_name' => $page_builder_name, |
| 463 |
'global_checkout' => \Cartflows_Helper::get_common_setting( 'global_checkout' ), |
| 464 |
'flows_count' => 1, // Removing the flow count condition. |
| 465 |
'currentFlowSteps' => $current_flow_steps, |
| 466 |
// Delete this code after 3 major update. Added in 1.10.4. |
| 467 |
'license_status' => \_is_cartflows_pro_license_activated(), |
| 468 |
'license_popup_url' => admin_url( 'admin.php?page=cartflows&path=settings&tab=license' ), |
| 469 |
'store_checkout_show_product_tab' => \Cartflows_Helper::display_product_tab_in_store_checkout(), |
| 470 |
'cf_domain_url' => CARTFLOWS_DOMAIN_URL, |
| 471 |
'cf_upgrade_to_pro_url' => \Cartflows_Helper::get_upgrade_to_pro_link(), |
| 472 |
'logo_url' => esc_url_raw( CARTFLOWS_URL . 'assets/images/cartflows-logo.svg' ), |
| 473 |
'create_product_src' => $product_src, |
| 474 |
'cf_font_family' => AdminHelper::get_font_family(), |
| 475 |
'flows_and_steps' => ! empty( $flows_and_steps ) ? $flows_and_steps : '', |
| 476 |
'store_checkout_flows_and_steps' => \Cartflows_Helper::get_instance()->get_flows_and_steps( '', 'store-checkout' ), |
| 477 |
'woo_currency' => function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : '', |
| 478 |
'template_library_url' => wcf()->get_site_url(), |
| 479 |
'image_placeholder' => esc_url_raw( CARTFLOWS_URL . 'admin-core/assets/images/image-placeholder.png' ), |
| 480 |
'google_fonts' => \CartFlows_Font_Families::get_google_fonts(), |
| 481 |
'system_fonts' => \CartFlows_Font_Families::get_system_fonts(), |
| 482 |
'font_weights' => array( |
| 483 |
'100' => __( 'Thin 100', 'cartflows' ), |
| 484 |
'200' => __( 'Extra-Light 200', 'cartflows' ), |
| 485 |
'300' => __( 'Light 300', 'cartflows' ), |
| 486 |
'400' => __( 'Normal 400', 'cartflows' ), |
| 487 |
'500' => __( 'Medium 500', 'cartflows' ), |
| 488 |
'600' => __( 'Semi-Bold 600', 'cartflows' ), |
| 489 |
'700' => __( 'Bold 700', 'cartflows' ), |
| 490 |
'800' => __( 'Extra-Bold 800', 'cartflows' ), |
| 491 |
'900' => __( 'Ultra-Bold 900', 'cartflows' ), |
| 492 |
), |
| 493 |
'global_checkout_id' => $global_checkout_id ? absint( $global_checkout_id ) : '', |
| 494 |
'flow_action' => $flow_action, |
| 495 |
'step_action' => $step_action, |
| 496 |
'old_global_checkout' => get_option( '_cartflows_old_global_checkout', false ), |
| 497 |
'woopayments_status' => $this->get_plugin_status( 'woocommerce-payments/woocommerce-payments.php' ), |
| 498 |
'ca_status' => $this->get_plugin_status( 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' ), |
| 499 |
'suretriggers_status' => $this->get_plugin_status( 'suretriggers/suretriggers.php' ), |
| 500 |
'moderncart_status' => $this->get_plugin_status( 'modern-cart/modern-cart.php' ), |
| 501 |
'cpsw_connection_status' => 'success' === get_option( 'cpsw_test_con_status', false ) || 'success' === get_option( 'cpsw_con_status', false ), |
| 502 |
'current_user_can_manage_cartflows' => current_user_can( 'cartflows_manage_settings' ), |
| 503 |
'is_set_report_email_ids' => get_option( 'cartflows_stats_report_email_ids', false ), |
| 504 |
'cf_docs_data' => get_option( 'cartflows_docs_data', false ), |
| 505 |
'woo_order_url' => $order_url, |
| 506 |
'integrations' => $this->get_recommendation_integrations(), |
| 507 |
'plugin_installer_nonce' => wp_create_nonce( 'updates' ), |
| 508 |
'instant_checkout_notice_status' => \Cartflows_Helper::get_admin_settings_option( 'wcf-instant-checkout-notice-skipped', false, false ), |
| 509 |
'cartflows_admin_notices' => $this->cartflows_admin_notices(), |
| 510 |
'whats_new_rss_feed' => $this->get_whats_new_rss_feeds_data(), |
| 511 |
'cartflows_current_version' => CARTFLOWS_VER, |
| 512 |
'cartflows_previous_versions' => \Cartflows_Helper::get_rollback_versions_options(), |
| 513 |
'rollback_url' => esc_url( add_query_arg( 'version', 'VERSION', wp_nonce_url( admin_url( 'admin-post.php?action=cartflows_rollback' ), 'cartflows_rollback' ) ) ), |
| 514 |
'utm_param_pro_plans' => 'utm_source=carflows-dashboard&utm_medium=free-cartflows&utm_campaign=go-pro', |
| 515 |
) |
| 516 |
); |
| 517 |
|
| 518 |
// Load the codemirror for code editor. |
| 519 |
wp_enqueue_code_editor( |
| 520 |
array( |
| 521 |
'type' => 'text/javascript', |
| 522 |
) |
| 523 |
); |
| 524 |
wp_enqueue_code_editor( |
| 525 |
array( |
| 526 |
'type' => 'text/css', |
| 527 |
) |
| 528 |
); |
| 529 |
|
| 530 |
wp_enqueue_script( 'wp-code-editor' ); |
| 531 |
wp_enqueue_style( 'wp-codemirror' ); |
| 532 |
|
| 533 |
if ( $this->is_current_page( $this->menu_slug ) ) { |
| 534 |
$this->settings_app_scripts( $localize ); |
| 535 |
} elseif ( $this->is_current_page( 'cartflows', array( 'wcf-edit-flow' ) ) ) { |
| 536 |
wp_enqueue_media(); |
| 537 |
wp_enqueue_editor(); // Require for Order Bump Desc WP Editor/ tinymce field. |
| 538 |
$this->editor_app_scripts( $localize ); |
| 539 |
} |
| 540 |
} |
| 541 |
|
| 542 |
/** |
| 543 |
* Get recommendation integrations. |
| 544 |
* |
| 545 |
* @since 1.11.8 |
| 546 |
* |
| 547 |
* @return array |
| 548 |
*/ |
| 549 |
public function cartflows_admin_notices() { |
| 550 |
$notices = array(); |
| 551 |
|
| 552 |
$notices = $this->page_builder_plugin_notices( $notices ); |
| 553 |
$notices = apply_filters( 'cartflows_admin_notices', $notices ); |
| 554 |
|
| 555 |
return $notices; |
| 556 |
} |
| 557 |
|
| 558 |
/** |
| 559 |
* Get builder plugin notices. |
| 560 |
* |
| 561 |
* @since 1.11.8 |
| 562 |
* @param array $notices Notices array. |
| 563 |
* @return array |
| 564 |
*/ |
| 565 |
public function page_builder_plugin_notices( $notices ) { |
| 566 |
$required_plugins_missing = $this->get_any_required_plugins_status(); |
| 567 |
$default_page_builder = \Cartflows_Helper::get_common_setting( 'default_page_builder' ); |
| 568 |
$required_plugins = array(); |
| 569 |
if ( isset( \Cartflows_Helper::get_plugins_groupby_page_builders()[ $default_page_builder ] ) ) { |
| 570 |
$required_plugins = \Cartflows_Helper::get_plugins_groupby_page_builders()[ $default_page_builder ]; |
| 571 |
} |
| 572 |
|
| 573 |
$page_builder_plugins = isset( $required_plugins['plugins'] ) ? $required_plugins['plugins'] : array(); |
| 574 |
$any_inactive = false; |
| 575 |
if ( ! empty( $page_builder_plugins ) ) { |
| 576 |
foreach ( $page_builder_plugins as $plugin ) { |
| 577 |
if ( 'activated' !== $plugin['status'] ) { |
| 578 |
$any_inactive = true; |
| 579 |
break; // Stop checking if we found an active plugin. |
| 580 |
} |
| 581 |
} |
| 582 |
} |
| 583 |
|
| 584 |
// Get the titles. |
| 585 |
$titles = $this->generate_plugin_titles( $page_builder_plugins ); |
| 586 |
|
| 587 |
if ( 'yes' === $required_plugins_missing && $any_inactive ) { |
| 588 |
$notices[] = '<div class="wcf-payment-gateway-notice--text"><p class="text-sm text-yellow-700">' . wp_kses_post( |
| 589 |
sprintf( |
| 590 |
// Translators: %1$s is the required page builder title, %2$s is the opening anchor tag to plugins.php, %3$s is the closing anchor tag, %4$s is the plugin title. |
| 591 |
__( 'The default page builder is set to %1$s. Please %2$sinstall & activate%3$s the %4$s to start editing the steps.', 'cartflows' ), //phpcs:ignore |
| 592 |
'<span class="capitalize">' . esc_html( $required_plugins['title'] ) . '</span>', |
| 593 |
'<span class="font-medium"><a href="' . esc_url( admin_url() . 'plugins.php' ) . '" class="underline text-yellow-700 hover:text-yellow-600" target="_blank">', |
| 594 |
'</a></span>', |
| 595 |
'<span class="capitalize">' . esc_html( implode( ', ', $titles ) ) . '</span>' |
| 596 |
) |
| 597 |
) . '</p></div>'; |
| 598 |
|
| 599 |
} |
| 600 |
return $notices; |
| 601 |
} |
| 602 |
|
| 603 |
/** |
| 604 |
* Get required plugin titles from their slugs. |
| 605 |
* |
| 606 |
* @since 2.1.6 |
| 607 |
* @param array $plugins plugins array. |
| 608 |
* @return array |
| 609 |
*/ |
| 610 |
public function generate_plugin_titles( $plugins ) { |
| 611 |
$titles = array(); |
| 612 |
|
| 613 |
if ( ! is_array( $plugins ) || empty( $plugins ) ) { |
| 614 |
return $titles; |
| 615 |
} |
| 616 |
|
| 617 |
foreach ( $plugins as $plugin ) { |
| 618 |
|
| 619 |
if ( 'ultimate-addons-for-gutenberg' === $plugin['slug'] ) { |
| 620 |
$title = 'Spectra'; // Don't add this for translation as it is a plugin name. |
| 621 |
} else { |
| 622 |
$slug_parts = explode( '-', $plugin['slug'] ); |
| 623 |
$title = implode( ' ', array_map( 'ucfirst', $slug_parts ) ); // Convert each part to title case. |
| 624 |
} |
| 625 |
|
| 626 |
$titles[] = $title; |
| 627 |
} |
| 628 |
|
| 629 |
return $titles; |
| 630 |
} |
| 631 |
|
| 632 |
|
| 633 |
/** |
| 634 |
* Get required plugin status. |
| 635 |
*/ |
| 636 |
public function get_required_plugins_data() { |
| 637 |
|
| 638 |
$missing_plugins_data = array(); |
| 639 |
|
| 640 |
$page_builder_plugins = \Cartflows_Helper::get_plugins_groupby_page_builders(); |
| 641 |
|
| 642 |
foreach ( $page_builder_plugins as $slug => $data ) { |
| 643 |
|
| 644 |
$missing_plugins_data[ $slug ] = 'no'; |
| 645 |
$current_page_builder_data = $page_builder_plugins[ $slug ]; |
| 646 |
|
| 647 |
foreach ( $current_page_builder_data['plugins'] as $plugin ) { |
| 648 |
if ( 'activate' === $plugin['status'] || 'install' === $plugin['status'] ) { |
| 649 |
$missing_plugins_data[ $slug ] = 'yes'; |
| 650 |
} |
| 651 |
} |
| 652 |
|
| 653 |
// Divi. |
| 654 |
if ( 'divi' === $slug ) { |
| 655 |
if ( 'activate' === $current_page_builder_data['theme-status'] ) { |
| 656 |
$missing_plugins_data[ $slug ] = 'yes'; |
| 657 |
} |
| 658 |
} |
| 659 |
} |
| 660 |
|
| 661 |
return $missing_plugins_data; |
| 662 |
} |
| 663 |
/** |
| 664 |
* Get required plugin status |
| 665 |
*/ |
| 666 |
public function get_any_required_plugins_status() { |
| 667 |
|
| 668 |
$default_page_builder = \Cartflows_Helper::get_common_setting( 'default_page_builder' ); |
| 669 |
$any_inactive = 'no'; |
| 670 |
|
| 671 |
$page_builder_plugins = \Cartflows_Helper::get_plugins_groupby_page_builders(); |
| 672 |
|
| 673 |
if ( isset( $page_builder_plugins[ $default_page_builder ] ) ) { |
| 674 |
|
| 675 |
$current_page_builder_data = $page_builder_plugins[ $default_page_builder ]; |
| 676 |
|
| 677 |
foreach ( $current_page_builder_data['plugins'] as $plugin ) { |
| 678 |
if ( 'activate' === $plugin['status'] || 'install' === $plugin['status'] ) { |
| 679 |
$any_inactive = 'yes'; |
| 680 |
} |
| 681 |
} |
| 682 |
|
| 683 |
// Divi. |
| 684 |
if ( 'divi' === $default_page_builder ) { |
| 685 |
if ( 'activate' === $current_page_builder_data['theme-status'] ) { |
| 686 |
$any_inactive = 'yes'; |
| 687 |
} |
| 688 |
} |
| 689 |
} |
| 690 |
|
| 691 |
return $any_inactive; |
| 692 |
} |
| 693 |
|
| 694 |
/** |
| 695 |
* Get CartFlows plugin status |
| 696 |
* |
| 697 |
* @since 1.11.8 |
| 698 |
* |
| 699 |
* @return string |
| 700 |
*/ |
| 701 |
public function get_cartflows_pro_plugin_status() { |
| 702 |
|
| 703 |
$status = $this->get_plugin_status( 'cartflows-pro/cartflows-pro.php' ); |
| 704 |
|
| 705 |
if ( 'active' === $status && ! _is_cartflows_pro() ) { |
| 706 |
|
| 707 |
$status = 'inactive'; |
| 708 |
} |
| 709 |
|
| 710 |
return $status; |
| 711 |
} |
| 712 |
|
| 713 |
/** |
| 714 |
* Get plugin status |
| 715 |
* |
| 716 |
* @since 1.1.4 |
| 717 |
* |
| 718 |
* @param string $plugin_init_file Plguin init file. |
| 719 |
* @return mixed |
| 720 |
*/ |
| 721 |
public function get_plugin_status( $plugin_init_file ) { |
| 722 |
|
| 723 |
$installed_plugins = get_plugins(); |
| 724 |
|
| 725 |
if ( ! isset( $installed_plugins[ $plugin_init_file ] ) ) { |
| 726 |
return 'not-installed'; |
| 727 |
} elseif ( is_plugin_active( $plugin_init_file ) ) { |
| 728 |
return 'active'; |
| 729 |
} else { |
| 730 |
return 'inactive'; |
| 731 |
} |
| 732 |
} |
| 733 |
|
| 734 |
/** |
| 735 |
* Get plugin status |
| 736 |
* |
| 737 |
* @since 1.1.4 |
| 738 |
* |
| 739 |
* @param string $theme_name Theme slug file. |
| 740 |
* @return string |
| 741 |
*/ |
| 742 |
public function get_themes_status( $theme_name ) { |
| 743 |
|
| 744 |
$theme = wp_get_theme(); |
| 745 |
|
| 746 |
// Theme installed and activate. |
| 747 |
if ( $theme_name === $theme->name || $theme_name === $theme->parent_theme ) { |
| 748 |
return 'active'; |
| 749 |
} |
| 750 |
|
| 751 |
// Theme installed but not activate. |
| 752 |
foreach ( (array) wp_get_themes() as $theme_dir => $theme ) { |
| 753 |
if ( $theme_name === $theme->name || $theme_name === $theme->parent_theme ) { |
| 754 |
return 'inactive'; |
| 755 |
} |
| 756 |
} |
| 757 |
|
| 758 |
// If none of the above conditions are found then the theme is not installed. |
| 759 |
return 'not-installed'; |
| 760 |
} |
| 761 |
|
| 762 |
/** |
| 763 |
* Settings app scripts |
| 764 |
* |
| 765 |
* @param array $localize Variable names. |
| 766 |
*/ |
| 767 |
public function settings_app_scripts( $localize ) { |
| 768 |
$handle = 'wcf-react-settings'; |
| 769 |
$build_path = CARTFLOWS_ADMIN_CORE_DIR . 'assets/build/'; |
| 770 |
$build_url = CARTFLOWS_ADMIN_CORE_URL . 'assets/build/'; |
| 771 |
$script_asset_path = $build_path . 'settings-app.asset.php'; |
| 772 |
$script_info = file_exists( $script_asset_path ) |
| 773 |
? include $script_asset_path |
| 774 |
: array( |
| 775 |
'dependencies' => array(), |
| 776 |
'version' => CARTFLOWS_VER, |
| 777 |
); |
| 778 |
|
| 779 |
$script_dep = array_merge( $script_info['dependencies'], array( 'updates' ) ); |
| 780 |
|
| 781 |
wp_register_script( |
| 782 |
$handle, |
| 783 |
$build_url . 'settings-app.js', |
| 784 |
$script_dep, |
| 785 |
$script_info['version'], |
| 786 |
true |
| 787 |
); |
| 788 |
|
| 789 |
wp_register_style( |
| 790 |
$handle, |
| 791 |
$build_url . 'settings-app.css', |
| 792 |
array(), |
| 793 |
CARTFLOWS_VER |
| 794 |
); |
| 795 |
|
| 796 |
wp_enqueue_script( $handle ); |
| 797 |
|
| 798 |
wp_set_script_translations( $handle, 'cartflows' ); |
| 799 |
|
| 800 |
wp_enqueue_style( $handle ); |
| 801 |
wp_style_add_data( $handle, 'rtl', 'replace' ); |
| 802 |
|
| 803 |
$localize['is_flows_limit'] = false; // Removed the flow count condition. |
| 804 |
|
| 805 |
$localize = $this->debugger_scripts( $localize ); |
| 806 |
|
| 807 |
$localize['save_learn_completed_nonce'] = wp_create_nonce( 'cartflows_save_learn_completed' ); |
| 808 |
$localize['activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' ); |
| 809 |
|
| 810 |
wp_localize_script( $handle, 'cartflows_admin', $localize ); |
| 811 |
} |
| 812 |
|
| 813 |
/** |
| 814 |
* Settings app scripts |
| 815 |
* |
| 816 |
* @param array $localize Variable names. |
| 817 |
*/ |
| 818 |
public function editor_app_scripts( $localize ) { |
| 819 |
$handle = 'wcf-editor-app'; |
| 820 |
$build_path = CARTFLOWS_ADMIN_CORE_DIR . 'assets/build/'; |
| 821 |
$build_url = CARTFLOWS_ADMIN_CORE_URL . 'assets/build/'; |
| 822 |
$script_asset_path = $build_path . 'editor-app.asset.php'; |
| 823 |
$script_info = file_exists( $script_asset_path ) |
| 824 |
? include $script_asset_path |
| 825 |
: array( |
| 826 |
'dependencies' => array(), |
| 827 |
'version' => CARTFLOWS_VER, |
| 828 |
); |
| 829 |
|
| 830 |
wp_register_script( |
| 831 |
$handle, |
| 832 |
$build_url . 'editor-app.js', |
| 833 |
$script_info['dependencies'], |
| 834 |
$script_info['version'], |
| 835 |
true |
| 836 |
); |
| 837 |
|
| 838 |
wp_register_style( |
| 839 |
$handle, |
| 840 |
$build_url . 'editor-app.css', |
| 841 |
array(), |
| 842 |
CARTFLOWS_VER |
| 843 |
); |
| 844 |
|
| 845 |
wp_enqueue_script( $handle ); |
| 846 |
|
| 847 |
wp_set_script_translations( $handle, 'cartflows' ); |
| 848 |
|
| 849 |
wp_enqueue_style( $handle ); |
| 850 |
wp_style_add_data( $handle, 'rtl', 'replace' ); |
| 851 |
|
| 852 |
$localize['flow_id'] = isset( $_GET['flow_id'] ) ? intval( $_GET['flow_id'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 853 |
|
| 854 |
$step_id = isset( $_GET['step_id'] ) ? intval( $_GET['step_id'] ) : false; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 855 |
|
| 856 |
if ( $step_id ) { |
| 857 |
|
| 858 |
$meta_options = AdminHelper::get_step_meta_options( $step_id ); |
| 859 |
$localize['options'] = $meta_options['options']; |
| 860 |
} |
| 861 |
|
| 862 |
wp_localize_script( $handle, 'cartflows_admin', $localize ); |
| 863 |
} |
| 864 |
|
| 865 |
/** |
| 866 |
* Debugger scripts. |
| 867 |
* |
| 868 |
* @param array $localize Variable names. |
| 869 |
*/ |
| 870 |
public function debugger_scripts( $localize ) { |
| 871 |
|
| 872 |
$logs = LogStatus::get_instance()->get_log_files(); |
| 873 |
$viewed_log = ''; |
| 874 |
$viewed_log_file = ''; |
| 875 |
|
| 876 |
// Calling this function on CartFlows action hook. Hence ignoring nonce. |
| 877 |
if ( ! empty( $_REQUEST['log_file'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 878 |
|
| 879 |
$filename = sanitize_text_field( wp_unslash( $_REQUEST['log_file'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 880 |
|
| 881 |
if ( isset( $logs[ $filename ] ) ) { |
| 882 |
$viewed_log = $filename; |
| 883 |
$viewed_log_file = $viewed_log . '.log'; |
| 884 |
} |
| 885 |
} elseif ( ! empty( $logs ) ) { |
| 886 |
$viewed_log = current( $logs ) ? pathinfo( current( $logs ), PATHINFO_FILENAME ) : ''; |
| 887 |
$viewed_log_file = $viewed_log . '.log'; |
| 888 |
} |
| 889 |
|
| 890 |
if ( ! empty( $viewed_log_file ) ) { |
| 891 |
$file_content = file_get_contents( CARTFLOWS_LOG_DIR . $viewed_log_file ); |
| 892 |
$localize['file_content'] = $file_content; |
| 893 |
$localize['log_key'] = $viewed_log; |
| 894 |
|
| 895 |
} |
| 896 |
$localize['logs'] = $logs; |
| 897 |
return $localize; |
| 898 |
} |
| 899 |
|
| 900 |
|
| 901 |
/** |
| 902 |
* CHeck if it is current page by parameters |
| 903 |
* |
| 904 |
* @param string $page_slug Menu name. |
| 905 |
* @param string $action Menu name. |
| 906 |
* |
| 907 |
* @return string page url |
| 908 |
*/ |
| 909 |
public function is_current_page( $page_slug = '', $action = '' ) { |
| 910 |
|
| 911 |
$page_matched = false; |
| 912 |
|
| 913 |
if ( empty( $page_slug ) ) { |
| 914 |
return false; |
| 915 |
} |
| 916 |
|
| 917 |
$current_page_slug = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 918 |
$current_action = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 919 |
|
| 920 |
if ( ! is_array( $action ) ) { |
| 921 |
$action = explode( ' ', $action ); |
| 922 |
} |
| 923 |
|
| 924 |
if ( $page_slug === $current_page_slug && in_array( $current_action, $action, true ) ) { |
| 925 |
$page_matched = true; |
| 926 |
} |
| 927 |
|
| 928 |
return $page_matched; |
| 929 |
} |
| 930 |
|
| 931 |
/** |
| 932 |
* Get CartFlows recommended integrations. |
| 933 |
* |
| 934 |
* @return array |
| 935 |
*/ |
| 936 |
public function get_recommendation_integrations() { |
| 937 |
|
| 938 |
return array( |
| 939 |
'plugins' => apply_filters( |
| 940 |
'cartflows_admin_integrated_plugins', |
| 941 |
array( |
| 942 |
array( |
| 943 |
'title' => __( 'WooCommerce', 'cartflows' ), |
| 944 |
'subtitle' => __( 'WooCommerce is a customizable, open-source ecommerce platform built on WordPress.', 'cartflows' ), |
| 945 |
'isPro' => false, |
| 946 |
'status' => $this->get_plugin_status( 'woocommerce/woocommerce.php' ), |
| 947 |
'slug' => 'woocommerce', |
| 948 |
'path' => 'woocommerce/woocommerce.php', |
| 949 |
'redirection' => admin_url( 'admin.php?page=wc-admin' ), |
| 950 |
'logoPath' => array( |
| 951 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/woo.svg', |
| 952 |
), |
| 953 |
), |
| 954 |
array( |
| 955 |
'title' => __( 'Power Coupons', 'cartflows' ), |
| 956 |
'subtitle' => __( 'Create powerful coupon rules with advanced conditions, discount types, and usage restrictions for WooCommerce.', 'cartflows' ), |
| 957 |
'isPro' => false, |
| 958 |
'status' => $this->get_plugin_status( 'power-coupons/power-coupons.php' ), |
| 959 |
'slug' => 'power-coupons', |
| 960 |
'path' => 'power-coupons/power-coupons.php', |
| 961 |
'redirection' => admin_url( 'admin.php?page=power-coupons' ), |
| 962 |
'logoPath' => array( |
| 963 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/power-coupons.svg', |
| 964 |
), |
| 965 |
), |
| 966 |
array( |
| 967 |
'title' => __( 'Modern Cart for WooCommerce', 'cartflows' ), |
| 968 |
'subtitle' => __( 'A fast, customizable cart built to boost conversions, maximise profits, and elevate the shopping experience.', 'cartflows' ), |
| 969 |
'isPro' => false, |
| 970 |
'status' => $this->get_plugin_status( 'modern-cart/modern-cart.php' ), |
| 971 |
'slug' => 'modern-cart', |
| 972 |
'path' => 'modern-cart/modern-cart.php', |
| 973 |
'redirection' => admin_url( 'admin.php?page=moderncart_settings' ), |
| 974 |
'logoPath' => array( |
| 975 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/modern-cart-for-woocommerce.svg', |
| 976 |
), |
| 977 |
'hot_badge' => true, |
| 978 |
), |
| 979 |
array( |
| 980 |
'title' => __( 'Cart Abandonment Recovery', 'cartflows' ), |
| 981 |
'subtitle' => __( 'Recover abandonded carts with ease in less than 10 minutes.', 'cartflows' ), |
| 982 |
'isPro' => false, |
| 983 |
'status' => $this->get_plugin_status( 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' ), |
| 984 |
'slug' => 'woo-cart-abandonment-recovery', |
| 985 |
'path' => 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php', |
| 986 |
'redirection' => admin_url( 'admin.php?page=woo-cart-abandonment-recovery' ), |
| 987 |
'logoPath' => array( |
| 988 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/wcar.svg', |
| 989 |
), |
| 990 |
'hot_badge' => true, |
| 991 |
), |
| 992 |
array( |
| 993 |
'title' => __( 'Variation Swatches for WooCommerce', 'cartflows' ), |
| 994 |
'subtitle' => __( 'Convert dropdown boxes into highly engaging variation swatches.', 'cartflows' ), |
| 995 |
'isPro' => false, |
| 996 |
'status' => $this->get_plugin_status( 'variation-swatches-woo/variation-swatches-woo.php' ), |
| 997 |
'slug' => 'variation-swatches-woo', |
| 998 |
'path' => 'variation-swatches-woo/variation-swatches-woo.php', |
| 999 |
'redirection' => admin_url( 'admin.php?page=cfvsw_settings' ), |
| 1000 |
'logoPath' => array( |
| 1001 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/variation-swatches-woo.svg', |
| 1002 |
), |
| 1003 |
'hot_badge' => true, |
| 1004 |
), |
| 1005 |
array( |
| 1006 |
'title' => __( 'WooPayments: Integrated WooCommerce Payments', 'cartflows' ), |
| 1007 |
'subtitle' => __( 'Payments made simple, with no monthly fees – designed exclusively for WooCommerce stores.', 'cartflows' ), |
| 1008 |
'isPro' => false, |
| 1009 |
'status' => $this->get_plugin_status( 'woocommerce-payments/woocommerce-payments.php' ), |
| 1010 |
'redirection' => admin_url( 'admin.php?page=wc-admin&path=/payments/connect' ), |
| 1011 |
'slug' => 'woocommerce-payments', |
| 1012 |
'path' => 'woocommerce-payments/woocommerce-payments.php', |
| 1013 |
'logoPath' => array( |
| 1014 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/woocommere-payments.png', |
| 1015 |
), |
| 1016 |
), |
| 1017 |
array( |
| 1018 |
'title' => __( 'OttoKit', 'cartflows' ), |
| 1019 |
'subtitle' => __( 'OttoKit helps people automate their work by integrating multiple apps and plugins, allowing them to share data and perform tasks automatically.', 'cartflows' ), |
| 1020 |
'isPro' => true, |
| 1021 |
'status' => $this->get_plugin_status( 'suretriggers/suretriggers.php' ), |
| 1022 |
'slug' => 'suretriggers', |
| 1023 |
'path' => 'suretriggers/suretriggers.php', |
| 1024 |
'link' => 'https://ottokit.com/pricing/', |
| 1025 |
'redirection' => admin_url( 'admin.php?page=suretriggers' ), |
| 1026 |
'logoPath' => array( |
| 1027 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/suretriggers-emblem.svg', |
| 1028 |
), |
| 1029 |
), |
| 1030 |
array( |
| 1031 |
'title' => __( 'Ultimate addons for Elementor', 'cartflows' ), |
| 1032 |
'subtitle' => __( 'Powerful Elementor addon with InfoCard, Fancy Heading, Before/After Slider, Price Box, FAQ Schema, WooCommerce widgets & Header-Footer builder.', 'cartflows' ), |
| 1033 |
'isPro' => false, |
| 1034 |
'status' => $this->get_plugin_status( 'header-footer-elementor/header-footer-elementor.php' ), |
| 1035 |
'slug' => 'header-footer-elementor', |
| 1036 |
'path' => 'header-footer-elementor/header-footer-elementor.php', |
| 1037 |
'redirection' => admin_url( 'admin.php?page=hfe#dashboard' ), |
| 1038 |
'logoPath' => array( |
| 1039 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/uael.png', |
| 1040 |
), |
| 1041 |
), |
| 1042 |
array( |
| 1043 |
'title' => __( 'Spectra', 'cartflows' ), |
| 1044 |
'subtitle' => __( 'Power-up the Gutenberg editor with advanced and powerful blocks.', 'cartflows' ), |
| 1045 |
'isPro' => false, |
| 1046 |
'status' => $this->get_plugin_status( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ), |
| 1047 |
'slug' => 'ultimate-addons-for-gutenberg', |
| 1048 |
'path' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php', |
| 1049 |
'redirection' => admin_url( 'options-general.php?page=spectra' ), |
| 1050 |
'logoPath' => array( |
| 1051 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/spectra.svg', |
| 1052 |
), |
| 1053 |
), |
| 1054 |
array( |
| 1055 |
'title' => __( 'SureForms', 'cartflows' ), |
| 1056 |
'subtitle' => __( 'Transform your WordPress form-building experience with stunning designs, ai integration, and no-code flexibility.', 'cartflows' ), |
| 1057 |
'isPro' => false, |
| 1058 |
'status' => $this->get_plugin_status( 'sureforms/sureforms.php' ), |
| 1059 |
'slug' => 'sureforms', |
| 1060 |
'path' => 'sureforms/sureforms.php', |
| 1061 |
'redirection' => admin_url( 'admin.php?page=sureforms_menu' ), |
| 1062 |
'logoPath' => array( |
| 1063 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/sureforms.svg', |
| 1064 |
), |
| 1065 |
), |
| 1066 |
array( |
| 1067 |
'title' => __( 'SureMembers', 'cartflows' ), |
| 1068 |
'subtitle' => __( 'A simple yet powerful way to add content restriction to your website.', 'cartflows' ), |
| 1069 |
'isPro' => true, |
| 1070 |
'status' => $this->get_plugin_status( 'suremembers/suremembers.php' ), |
| 1071 |
'slug' => 'suremembers', |
| 1072 |
'path' => 'suremembers/suremembers.php', |
| 1073 |
'link' => 'https://suremembers.com/pricing/', |
| 1074 |
'redirection' => admin_url( 'edit.php?post_type=wsm_access_group' ), |
| 1075 |
'logoPath' => array( |
| 1076 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/plugins/suremembers.svg', |
| 1077 |
), |
| 1078 |
), |
| 1079 |
) |
| 1080 |
), |
| 1081 |
'themes' => apply_filters( |
| 1082 |
'cartflows_admin_integrated_themes', |
| 1083 |
array( |
| 1084 |
array( |
| 1085 |
'title' => __( 'Astra', 'cartflows' ), |
| 1086 |
'subtitle' => __( 'Astra is fast, fully customizable & beautiful WordPress theme suitable for blog, personal portfolio, business website and WooCommerce storefront.', 'cartflows' ), |
| 1087 |
'isPro' => false, |
| 1088 |
'status' => $this->get_themes_status( 'Astra' ), |
| 1089 |
'slug' => 'astra', |
| 1090 |
'redirection' => admin_url( 'admin.php?page=wc-admin' ), |
| 1091 |
'logoPath' => array( |
| 1092 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/themes/astra-icon.svg', |
| 1093 |
), |
| 1094 |
), |
| 1095 |
array( |
| 1096 |
'title' => __( 'Spectra One', 'cartflows' ), |
| 1097 |
'subtitle' => __( 'Spectra One is a beautiful and modern WordPress theme built with the Full Site Editing (FSE) feature. It\'s a versatile theme that can be used for blogs, portfolios, businesses, and more.', 'cartflows' ), |
| 1098 |
'isPro' => false, |
| 1099 |
'status' => $this->get_themes_status( 'Spectra One' ), |
| 1100 |
'slug' => 'spectra-one', |
| 1101 |
'redirection' => admin_url( 'admin.php?page=wc-admin' ), |
| 1102 |
'logoPath' => array( |
| 1103 |
'icon_path' => CARTFLOWS_ADMIN_CORE_URL . 'assets/images/themes/spectra-one.svg', |
| 1104 |
), |
| 1105 |
), |
| 1106 |
) |
| 1107 |
), |
| 1108 |
); |
| 1109 |
} |
| 1110 |
|
| 1111 |
/** |
| 1112 |
* Prepare the array of RSS Feeds of CartFlows for Whats New slide-our pannel. |
| 1113 |
* |
| 1114 |
* @since 2.1.6 |
| 1115 |
* @return array The prepared array of RSS feeds. |
| 1116 |
*/ |
| 1117 |
public function get_whats_new_rss_feeds_data() { |
| 1118 |
return array( |
| 1119 |
array( |
| 1120 |
'key' => 'cartflows', |
| 1121 |
'label' => 'CartFlows', |
| 1122 |
'url' => add_query_arg( |
| 1123 |
array( |
| 1124 |
'action' => 'cartflows_fetch_whats_new_data', |
| 1125 |
'nonce' => wp_create_nonce( 'cartflows_fetch_whats_new_data' ), |
| 1126 |
), |
| 1127 |
admin_url( 'admin-ajax.php' ) |
| 1128 |
), // 'https://cartflows.com/whats-new/feed/' |
| 1129 |
), |
| 1130 |
); |
| 1131 |
} |
| 1132 |
|
| 1133 |
/** |
| 1134 |
* Fetch the Whats New RSS feed from the URL. |
| 1135 |
* |
| 1136 |
* @since 1.0.3 |
| 1137 |
* @return void |
| 1138 |
*/ |
| 1139 |
public function fetch_whats_new_data() { |
| 1140 |
if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_GET['nonce'] ), 'cartflows_fetch_whats_new_data' ) ) { |
| 1141 |
// Verify the nonce, if it fails, return an error. |
| 1142 |
wp_send_json_error( array( 'message' => __( 'Nonce verification failed.', 'cartflows' ) ) ); |
| 1143 |
} |
| 1144 |
|
| 1145 |
// Security: Require admin capability to access RSS feed proxy. |
| 1146 |
if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) { |
| 1147 |
wp_send_json_error( array( 'message' => __( 'Permission denied.', 'cartflows' ) ) ); |
| 1148 |
} |
| 1149 |
|
| 1150 |
// Fetch the RSS feed from the URL. This saves us from the CORS issue. |
| 1151 |
$feed = wp_remote_retrieve_body( wp_safe_remote_get( 'https://cartflows.com/product/cartflows/feed/' ) ); // phpcs:ignore -- This is a valid use case cannot use VIP rules here. |
| 1152 |
|
| 1153 |
// Security: Set proper content type header and strip script tags to prevent XSS. |
| 1154 |
echo $feed; // phpcs:ignore -- RSS feed content sanitized via wp_kses_post. |
| 1155 |
exit; |
| 1156 |
} |
| 1157 |
} |
| 1158 |
|
| 1159 |
AdminMenu::get_instance(); |
| 1160 |
|