| 1 |
<?php |
| 2 |
/** |
| 3 |
* CartFlows Admin Helper. |
| 4 |
* |
| 5 |
* @package CartFlows |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace CartflowsAdmin\AdminCore\Inc; |
| 9 |
|
| 10 |
use Automattic\WooCommerce\Utilities\OrderUtil; |
| 11 |
|
| 12 |
// Exit if accessed directly. |
| 13 |
if ( ! defined( 'ABSPATH' ) ) { |
| 14 |
exit; |
| 15 |
} |
| 16 |
|
| 17 |
/** |
| 18 |
* Class AdminHelper. |
| 19 |
*/ |
| 20 |
class AdminHelper { |
| 21 |
|
| 22 |
/** |
| 23 |
* Meta_options. |
| 24 |
* |
| 25 |
* @var object instance |
| 26 |
*/ |
| 27 |
public static $meta_options = array(); |
| 28 |
/** |
| 29 |
* Common. |
| 30 |
* |
| 31 |
* @var object instance |
| 32 |
*/ |
| 33 |
public static $common = null; |
| 34 |
|
| 35 |
/** |
| 36 |
* Permalink setting. |
| 37 |
* |
| 38 |
* @var object instance |
| 39 |
*/ |
| 40 |
public static $permalink_setting = null; |
| 41 |
|
| 42 |
/** |
| 43 |
* Facebook. |
| 44 |
* |
| 45 |
* @var object instance |
| 46 |
*/ |
| 47 |
public static $facebook = null; |
| 48 |
|
| 49 |
/** |
| 50 |
* TikTok. |
| 51 |
* |
| 52 |
* @var object instance |
| 53 |
*/ |
| 54 |
public static $tiktok = null; |
| 55 |
|
| 56 |
/** |
| 57 |
* Snapchat. |
| 58 |
* |
| 59 |
* @var object instance |
| 60 |
*/ |
| 61 |
public static $snapchat = null; |
| 62 |
|
| 63 |
/** |
| 64 |
* Google_analytics_settings. |
| 65 |
* |
| 66 |
* @var object instance |
| 67 |
*/ |
| 68 |
public static $google_analytics_settings = null; |
| 69 |
|
| 70 |
/** |
| 71 |
* Google_analytics_settings. |
| 72 |
* |
| 73 |
* @var object instance |
| 74 |
*/ |
| 75 |
public static $pinterest = null; |
| 76 |
|
| 77 |
/** |
| 78 |
* Google_ads_settings. |
| 79 |
* |
| 80 |
* @since 2.1.0 |
| 81 |
* @var object instance |
| 82 |
*/ |
| 83 |
public static $google_ads_settings_data = null; |
| 84 |
|
| 85 |
/** |
| 86 |
* Options. |
| 87 |
* |
| 88 |
* @var object instance |
| 89 |
*/ |
| 90 |
public static $options = null; |
| 91 |
|
| 92 |
/** |
| 93 |
* Get flow meta options. |
| 94 |
* |
| 95 |
* @param int $post_id post id. |
| 96 |
* @return array. |
| 97 |
*/ |
| 98 |
public static function get_flow_meta_options( $post_id ) { |
| 99 |
|
| 100 |
if ( ! isset( self::$meta_options[ $post_id ] ) ) { |
| 101 |
|
| 102 |
/** |
| 103 |
* Set metabox options |
| 104 |
*/ |
| 105 |
|
| 106 |
$default_meta = wcf()->options->get_flow_fields( $post_id ); |
| 107 |
$stored_meta = get_post_meta( $post_id ); |
| 108 |
|
| 109 |
/** |
| 110 |
* Get options |
| 111 |
*/ |
| 112 |
self::$meta_options[ $post_id ] = self::get_prepared_meta_options( $default_meta, $stored_meta ); |
| 113 |
} |
| 114 |
|
| 115 |
return self::$meta_options[ $post_id ]; |
| 116 |
} |
| 117 |
|
| 118 |
/** |
| 119 |
* Get step meta options. |
| 120 |
* |
| 121 |
* @param int $step_id step id. |
| 122 |
* @return array. |
| 123 |
*/ |
| 124 |
public static function get_step_meta_options( $step_id ) { |
| 125 |
|
| 126 |
if ( ! isset( self::$meta_options[ $step_id ] ) ) { |
| 127 |
|
| 128 |
$step_type = wcf_get_step_type( $step_id ); |
| 129 |
$step_fields = array(); |
| 130 |
$step_tabs = array(); |
| 131 |
|
| 132 |
$default_meta = self::get_step_default_meta( $step_type, $step_id ); |
| 133 |
|
| 134 |
$stored_meta = get_post_meta( $step_id ); |
| 135 |
|
| 136 |
$prepared_options = self::get_prepared_meta_options( $default_meta, $stored_meta ); |
| 137 |
|
| 138 |
$prepared_options = apply_filters( 'cartflows_admin_' . $step_type . '_step_meta_fields', $prepared_options, $step_id ); |
| 139 |
|
| 140 |
$step_tabs = apply_filters( 'cartflows_admin_' . $step_type . '_step_tabs', $step_tabs ); |
| 141 |
|
| 142 |
/** |
| 143 |
* Get options |
| 144 |
*/ |
| 145 |
self::$meta_options[ $step_id ]['type'] = $step_type; |
| 146 |
self::$meta_options[ $step_id ]['tabs'] = $step_tabs; |
| 147 |
self::$meta_options[ $step_id ]['options'] = $prepared_options; |
| 148 |
} |
| 149 |
|
| 150 |
return self::$meta_options[ $step_id ]; |
| 151 |
} |
| 152 |
|
| 153 |
/** |
| 154 |
* Merge default and saved meta options. |
| 155 |
* |
| 156 |
* @param array $default_meta Default meta. |
| 157 |
* @param array $stored_meta Saved meta. |
| 158 |
* @return array. |
| 159 |
*/ |
| 160 |
public static function get_prepared_meta_options( $default_meta, $stored_meta ) { |
| 161 |
|
| 162 |
$meta_options = array(); |
| 163 |
|
| 164 |
// Set stored and override defaults. |
| 165 |
foreach ( $default_meta as $key => $value ) { |
| 166 |
|
| 167 |
$meta_options[ $key ] = ( isset( $stored_meta[ $key ][0] ) ) ? maybe_unserialize( $stored_meta[ $key ][0] ) : $default_meta[ $key ]['default']; |
| 168 |
} |
| 169 |
|
| 170 |
return $meta_options; |
| 171 |
} |
| 172 |
|
| 173 |
/** |
| 174 |
* Get Common settings. |
| 175 |
* |
| 176 |
* @return array |
| 177 |
*/ |
| 178 |
public static function get_common_settings() { |
| 179 |
|
| 180 |
$options = array(); |
| 181 |
|
| 182 |
$common_default = apply_filters( |
| 183 |
'cartflows_common_settings_default', |
| 184 |
array( |
| 185 |
'global_checkout' => '', |
| 186 |
'override_global_checkout' => 'enable', |
| 187 |
'disallow_indexing' => 'disable', |
| 188 |
'default_page_builder' => 'elementor', |
| 189 |
) |
| 190 |
); |
| 191 |
|
| 192 |
$common = self::get_admin_settings_option( '_cartflows_common', false, false ); |
| 193 |
|
| 194 |
$common = wp_parse_args( $common, $common_default ); |
| 195 |
|
| 196 |
foreach ( $common as $key => $data ) { |
| 197 |
$options[ '_cartflows_common[' . $key . ']' ] = $data; |
| 198 |
} |
| 199 |
|
| 200 |
return $options; |
| 201 |
} |
| 202 |
|
| 203 |
/** |
| 204 |
* Get admin settings. |
| 205 |
* |
| 206 |
* Note: Use this function to access any properties to backend-end of the website i:e in admin-core. |
| 207 |
* |
| 208 |
* @param string $key key. |
| 209 |
* @param bool $default key. |
| 210 |
* @param bool $network_override key. |
| 211 |
* |
| 212 |
* @return array. |
| 213 |
*/ |
| 214 |
public static function get_admin_settings_option( $key, $default = false, $network_override = false ) { |
| 215 |
|
| 216 |
// Get the site-wide option if we're in the network admin. |
| 217 |
if ( $network_override && is_multisite() ) { |
| 218 |
$value = get_site_option( $key, $default ); |
| 219 |
} else { |
| 220 |
$value = get_option( $key, $default ); |
| 221 |
} |
| 222 |
|
| 223 |
return $value; |
| 224 |
} |
| 225 |
|
| 226 |
/** |
| 227 |
* Update admin settings. |
| 228 |
* |
| 229 |
* Note: Use this function to access any properties to backend-end of the website i:e in admin-core. |
| 230 |
* |
| 231 |
* @param string $key key. |
| 232 |
* @param mixed $value key. |
| 233 |
* @param bool $network network. |
| 234 |
* @return void |
| 235 |
*/ |
| 236 |
public static function update_admin_settings_option( $key, $value, $network = false ) { |
| 237 |
|
| 238 |
// Update the site-wide option since we're in the network admin. |
| 239 |
if ( $network && is_multisite() ) { |
| 240 |
update_site_option( $key, $value ); |
| 241 |
} else { |
| 242 |
update_option( $key, $value ); |
| 243 |
} |
| 244 |
} |
| 245 |
|
| 246 |
/** |
| 247 |
* Get Common settings. |
| 248 |
* |
| 249 |
* @return array |
| 250 |
*/ |
| 251 |
public static function get_permalink_settings() { |
| 252 |
|
| 253 |
$options = array(); |
| 254 |
|
| 255 |
$permalink_default = apply_filters( |
| 256 |
'cartflows_permalink_settings_default', |
| 257 |
array( |
| 258 |
'permalink' => CARTFLOWS_STEP_PERMALINK_SLUG, |
| 259 |
'permalink_flow_base' => CARTFLOWS_FLOW_PERMALINK_SLUG, |
| 260 |
'permalink_structure' => '', |
| 261 |
|
| 262 |
) |
| 263 |
); |
| 264 |
|
| 265 |
$permalink_data = self::get_admin_settings_option( '_cartflows_permalink', false, true ); |
| 266 |
|
| 267 |
$permalink_data = wp_parse_args( $permalink_data, $permalink_default ); |
| 268 |
|
| 269 |
foreach ( $permalink_data as $key => $data ) { |
| 270 |
$options[ '_cartflows_permalink[' . $key . ']' ] = $data; |
| 271 |
} |
| 272 |
|
| 273 |
return $options; |
| 274 |
} |
| 275 |
|
| 276 |
/** |
| 277 |
* Get Common settings. |
| 278 |
* |
| 279 |
* @return array |
| 280 |
*/ |
| 281 |
public static function get_facebook_settings() { |
| 282 |
|
| 283 |
$options = array(); |
| 284 |
|
| 285 |
$facebook_default = array( |
| 286 |
'facebook_pixel_id' => '', |
| 287 |
'facebook_pixel_add_to_cart' => 'enable', |
| 288 |
'facebook_pixel_view_content' => 'enable', |
| 289 |
'facebook_pixel_initiate_checkout' => 'enable', |
| 290 |
'facebook_pixel_add_payment_info' => 'enable', |
| 291 |
'facebook_pixel_purchase_complete' => 'enable', |
| 292 |
'facebook_pixel_optin_lead' => 'enable', |
| 293 |
'facebook_pixel_tracking' => 'disable', |
| 294 |
'facebook_pixel_tracking_for_site' => 'disable', |
| 295 |
); |
| 296 |
|
| 297 |
$facebook = self::get_admin_settings_option( '_cartflows_facebook', false, true ); |
| 298 |
|
| 299 |
$facebook = wp_parse_args( $facebook, $facebook_default ); |
| 300 |
|
| 301 |
$facebook = apply_filters( 'cartflows_facebook_settings_default', $facebook ); |
| 302 |
|
| 303 |
foreach ( $facebook as $key => $data ) { |
| 304 |
$options[ '_cartflows_facebook[' . $key . ']' ] = $data; |
| 305 |
} |
| 306 |
|
| 307 |
return $options; |
| 308 |
} |
| 309 |
|
| 310 |
/** |
| 311 |
* Get Common settings. |
| 312 |
* |
| 313 |
* @return array |
| 314 |
*/ |
| 315 |
public static function get_google_analytics_settings() { |
| 316 |
|
| 317 |
$options = array(); |
| 318 |
|
| 319 |
$google_analytics_settings_default = apply_filters( |
| 320 |
'cartflows_google_analytics_settings_default', |
| 321 |
array( |
| 322 |
'enable_google_analytics' => 'disable', |
| 323 |
'enable_google_analytics_for_site' => 'disable', |
| 324 |
'google_analytics_id' => '', |
| 325 |
'enable_begin_checkout' => 'disable', |
| 326 |
'enable_add_to_cart' => 'disable', |
| 327 |
'enable_add_payment_info' => 'disable', |
| 328 |
'enable_purchase_event' => 'disable', |
| 329 |
) |
| 330 |
); |
| 331 |
|
| 332 |
$google_analytics_settings_data = self::get_admin_settings_option( '_cartflows_google_analytics', false, false ); |
| 333 |
|
| 334 |
$google_analytics_settings_data = wp_parse_args( $google_analytics_settings_data, $google_analytics_settings_default ); |
| 335 |
|
| 336 |
foreach ( $google_analytics_settings_data as $key => $data ) { |
| 337 |
$options[ '_cartflows_google_analytics[' . $key . ']' ] = $data; |
| 338 |
} |
| 339 |
|
| 340 |
return $options; |
| 341 |
} |
| 342 |
|
| 343 |
/** |
| 344 |
* Get Common settings. |
| 345 |
* |
| 346 |
* @return array |
| 347 |
*/ |
| 348 |
public static function get_tiktok_settings() { |
| 349 |
|
| 350 |
$options = array(); |
| 351 |
|
| 352 |
$tiktok_default = array( |
| 353 |
'tiktok_pixel_id' => '', |
| 354 |
'enable_tiktok_begin_checkout' => 'disable', |
| 355 |
'enable_tiktok_add_to_cart' => 'disable', |
| 356 |
'enable_tiktok_view_content' => 'disable', |
| 357 |
'enable_tiktok_add_payment_info' => 'disable', |
| 358 |
'enable_tiktok_purchase_event' => 'disable', |
| 359 |
'enable_tiktok_optin_lead' => 'disable', |
| 360 |
'tiktok_pixel_tracking' => 'disable', |
| 361 |
'tiktok_pixel_tracking_for_site' => 'disable', |
| 362 |
); |
| 363 |
|
| 364 |
$tiktok = self::get_admin_settings_option( '_cartflows_tiktok', false, false ); |
| 365 |
|
| 366 |
$tiktok = wp_parse_args( $tiktok, $tiktok_default ); |
| 367 |
|
| 368 |
$tiktok = apply_filters( 'cartflows_tiktok_settings_default', $tiktok ); |
| 369 |
|
| 370 |
foreach ( $tiktok as $key => $data ) { |
| 371 |
$options[ '_cartflows_tiktok[' . $key . ']' ] = $data; |
| 372 |
} |
| 373 |
|
| 374 |
return $options; |
| 375 |
} |
| 376 |
|
| 377 |
/** |
| 378 |
* Get Common settings of pinterest. |
| 379 |
* |
| 380 |
* @return array |
| 381 |
*/ |
| 382 |
public static function get_pinterest_settings() { |
| 383 |
|
| 384 |
$options = array(); |
| 385 |
|
| 386 |
$pinterest_default = array( |
| 387 |
'pinterest_tag_id' => '', |
| 388 |
'enable_pinterest_consent' => 'disable', |
| 389 |
'enable_pinterest_begin_checkout' => 'disable', |
| 390 |
'enable_pinterest_add_to_cart' => 'disable', |
| 391 |
'enable_pinterest_add_payment_info' => 'disable', |
| 392 |
'enable_pinterest_purchase_event' => 'disable', |
| 393 |
'enable_pinterest_optin_lead' => 'disable', |
| 394 |
'enable_pinterest_signup' => 'disable', |
| 395 |
'pinterest_tag_tracking' => 'disable', |
| 396 |
'pinterest_tag_tracking_for_site' => 'disable', |
| 397 |
); |
| 398 |
|
| 399 |
$pinterest = self::get_admin_settings_option( '_cartflows_pinterest', false, false ); |
| 400 |
|
| 401 |
$pinterest = wp_parse_args( $pinterest, $pinterest_default ); |
| 402 |
|
| 403 |
$pinterest = apply_filters( 'cartflows_pinterest_settings_default', $pinterest ); |
| 404 |
|
| 405 |
foreach ( $pinterest as $key => $data ) { |
| 406 |
$options[ '_cartflows_pinterest[' . $key . ']' ] = $data; |
| 407 |
} |
| 408 |
|
| 409 |
return $options; |
| 410 |
} |
| 411 |
|
| 412 |
/** |
| 413 |
* Get Common settings. |
| 414 |
* |
| 415 |
* @since 2.1.0 |
| 416 |
* @return array |
| 417 |
*/ |
| 418 |
public static function get_google_ads_settings() { |
| 419 |
|
| 420 |
$options = array(); |
| 421 |
|
| 422 |
$google_ads_settings_default = apply_filters( |
| 423 |
'cartflows_google_ads_settings_default', |
| 424 |
array( |
| 425 |
'google_ads_id' => '', |
| 426 |
'google_ads_label' => '', |
| 427 |
'enable_google_ads_begin_checkout' => 'disable', |
| 428 |
'enable_google_ads_add_to_cart' => 'disable', |
| 429 |
'enable_google_ads_view_content' => 'disable', |
| 430 |
'enable_google_ads_add_payment_info' => 'disable', |
| 431 |
'enable_google_ads_purchase_event' => 'disable', |
| 432 |
'enable_google_ads_optin_lead' => 'disable', |
| 433 |
'google_ads_tracking' => 'disable', |
| 434 |
'google_ads_for_site' => 'disable', |
| 435 |
) |
| 436 |
); |
| 437 |
|
| 438 |
$google_ads_settings_data = self::get_admin_settings_option( '_cartflows_google_ads', false, false ); |
| 439 |
|
| 440 |
$google_ads_settings_data = wp_parse_args( $google_ads_settings_data, $google_ads_settings_default ); |
| 441 |
|
| 442 |
foreach ( $google_ads_settings_data as $key => $data ) { |
| 443 |
$options[ '_cartflows_google_ads[' . $key . ']' ] = $data; |
| 444 |
} |
| 445 |
|
| 446 |
return $options; |
| 447 |
} |
| 448 |
|
| 449 |
/** |
| 450 |
* Get Snapchat settings. |
| 451 |
* |
| 452 |
* @since 2.1.0 |
| 453 |
* @return array |
| 454 |
*/ |
| 455 |
public static function get_snapchat_settings() { |
| 456 |
|
| 457 |
$options = array(); |
| 458 |
|
| 459 |
$snapchat_settings_default = apply_filters( |
| 460 |
'cartflows_snapchat_settings_default', |
| 461 |
array( |
| 462 |
'snapchat_pixel_id' => '', |
| 463 |
'enable_snapchat_begin_checkout' => 'disable', |
| 464 |
'enable_snapchat_add_to_cart' => 'disable', |
| 465 |
'enable_snapchat_view_content' => 'disable', |
| 466 |
'enable_snapchat_purchase_event' => 'disable', |
| 467 |
'enable_snapchat_optin_lead' => 'disable', |
| 468 |
'enable_snapchat_subscribe_event' => 'disable', |
| 469 |
'snapchat_pixel_tracking' => 'disable', |
| 470 |
'snapchat_pixel_for_site' => 'disable', |
| 471 |
) |
| 472 |
); |
| 473 |
|
| 474 |
$snapchat_settings_data = self::get_admin_settings_option( '_cartflows_snapchat', false, false ); |
| 475 |
|
| 476 |
$snapchat_settings_data = wp_parse_args( $snapchat_settings_data, $snapchat_settings_default ); |
| 477 |
|
| 478 |
foreach ( $snapchat_settings_data as $key => $data ) { |
| 479 |
$options[ '_cartflows_snapchat[' . $key . ']' ] = $data; |
| 480 |
} |
| 481 |
|
| 482 |
return $options; |
| 483 |
} |
| 484 |
|
| 485 |
/** |
| 486 |
* Get User role settings. |
| 487 |
* |
| 488 |
* @return array |
| 489 |
*/ |
| 490 |
public static function get_user_role_management_settings() { |
| 491 |
global $wp_roles; |
| 492 |
|
| 493 |
$options = array(); |
| 494 |
|
| 495 |
// Get all user roles. |
| 496 |
$roles_names_array = array_keys( $wp_roles->get_names() ); |
| 497 |
$roles_names_array = array_diff( $roles_names_array, array( 'administrator' ) ); |
| 498 |
$user_role_management_default = array(); |
| 499 |
|
| 500 |
foreach ( $roles_names_array as $role_name ) { |
| 501 |
$user_role_management_default[ $role_name ] = 'no_access'; |
| 502 |
} |
| 503 |
|
| 504 |
$user_role_management = self::get_admin_settings_option( '_cartflows_roles', false, false ); |
| 505 |
|
| 506 |
$user_role_management = wp_parse_args( $user_role_management, $user_role_management_default ); |
| 507 |
|
| 508 |
$user_role_management = apply_filters( 'cartflows_user_role_default_settings', $user_role_management ); |
| 509 |
|
| 510 |
foreach ( $user_role_management as $key => $data ) { |
| 511 |
$options[ '_cartflows_roles[' . $key . ']' ] = $data; |
| 512 |
} |
| 513 |
|
| 514 |
return $options; |
| 515 |
} |
| 516 |
|
| 517 |
/** |
| 518 |
* Get Google Auto-Address Fields settings. |
| 519 |
* |
| 520 |
* @return array |
| 521 |
*/ |
| 522 |
public static function get_google_auto_fields_settings() { |
| 523 |
$options = array(); |
| 524 |
|
| 525 |
$google_auto_fields_setting_default = apply_filters( |
| 526 |
'cartflows_google_auto_fields_setting_default', |
| 527 |
array( |
| 528 |
'google_map_api_key' => '', |
| 529 |
) |
| 530 |
); |
| 531 |
|
| 532 |
$google_auto_fields_settings_data = self::get_admin_settings_option( '_cartflows_google_auto_address', false, false ); |
| 533 |
|
| 534 |
$google_auto_fields_settings_data = wp_parse_args( $google_auto_fields_settings_data, $google_auto_fields_setting_default ); |
| 535 |
|
| 536 |
foreach ( $google_auto_fields_settings_data as $key => $data ) { |
| 537 |
$options[ '_cartflows_google_auto_address[' . $key . ']' ] = $data; |
| 538 |
} |
| 539 |
|
| 540 |
return $options; |
| 541 |
} |
| 542 |
|
| 543 |
/** |
| 544 |
* Get Global CSS & Scripts settings. |
| 545 |
* |
| 546 |
* @return array. |
| 547 |
*/ |
| 548 |
public static function get_global_scripts_settings() { |
| 549 |
$options = array(); |
| 550 |
|
| 551 |
$default = array( |
| 552 |
'global_css' => '', |
| 553 |
'global_js' => '', |
| 554 |
); |
| 555 |
|
| 556 |
$global_scripts = self::get_admin_settings_option( '_cartflows_global_scripts', false, false ); |
| 557 |
|
| 558 |
$global_scripts = wp_parse_args( $global_scripts, $default ); |
| 559 |
|
| 560 |
foreach ( $global_scripts as $key => $data ) { |
| 561 |
$options[ '_cartflows_global_scripts[' . $key . ']' ] = $data; |
| 562 |
} |
| 563 |
|
| 564 |
return $options; |
| 565 |
} |
| 566 |
|
| 567 |
/** |
| 568 |
* Clear Page Builder Cache |
| 569 |
*/ |
| 570 |
public static function clear_cache() { |
| 571 |
|
| 572 |
// Clear 'Elementor' file cache. |
| 573 |
if ( class_exists( '\Elementor\Plugin' ) ) { |
| 574 |
\Elementor\Plugin::$instance->files_manager->clear_cache(); |
| 575 |
} |
| 576 |
} |
| 577 |
|
| 578 |
/** |
| 579 |
* Get Flows count. |
| 580 |
*/ |
| 581 |
public static function get_flows_count() { |
| 582 |
|
| 583 |
$flow_posts = get_posts( |
| 584 |
array( |
| 585 |
'posts_per_page' => 4, |
| 586 |
'post_type' => CARTFLOWS_FLOW_POST_TYPE, |
| 587 |
'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ), |
| 588 |
) |
| 589 |
); |
| 590 |
|
| 591 |
return count( $flow_posts ); |
| 592 |
} |
| 593 |
|
| 594 |
/** |
| 595 |
* Font family field. |
| 596 |
* |
| 597 |
* @return array field. |
| 598 |
*/ |
| 599 |
public static function get_font_family() { |
| 600 |
|
| 601 |
$font_family[0] = array( |
| 602 |
'value' => '', |
| 603 |
'label' => __( 'Default', 'cartflows' ), |
| 604 |
); |
| 605 |
|
| 606 |
$system_font_family = array(); |
| 607 |
$google_font_family = array(); |
| 608 |
|
| 609 |
foreach ( \CartFlows_Font_Families::get_system_fonts() as $name => $variants ) { |
| 610 |
array_push( |
| 611 |
$system_font_family, |
| 612 |
array( |
| 613 |
'value' => $name, |
| 614 |
'label' => esc_attr( $name ), |
| 615 |
) |
| 616 |
); |
| 617 |
} |
| 618 |
|
| 619 |
$font_family[1] = array( |
| 620 |
'label' => __( 'System Fonts', 'cartflows' ), |
| 621 |
'options' => $system_font_family, |
| 622 |
); |
| 623 |
|
| 624 |
foreach ( \CartFlows_Font_Families::get_google_fonts() as $name => $single_font ) { |
| 625 |
$variants = wcf_get_prop( $single_font, 'variants' ); |
| 626 |
$category = wcf_get_prop( $single_font, 'category' ); |
| 627 |
$font_value = '\'' . esc_attr( $name ) . '\', ' . esc_attr( $category ); |
| 628 |
array_push( |
| 629 |
$google_font_family, |
| 630 |
array( |
| 631 |
'value' => $font_value, |
| 632 |
'label' => esc_attr( $name ), |
| 633 |
) |
| 634 |
); |
| 635 |
} |
| 636 |
|
| 637 |
$font_family[2] = array( |
| 638 |
'label' => __( 'Google Fonts', 'cartflows' ), |
| 639 |
'options' => $google_font_family, |
| 640 |
); |
| 641 |
|
| 642 |
return $font_family; |
| 643 |
} |
| 644 |
|
| 645 |
/** |
| 646 |
* Get step default meta. |
| 647 |
* |
| 648 |
* @param string $step_type type. |
| 649 |
* @param int $step_id id. |
| 650 |
*/ |
| 651 |
public static function get_step_default_meta( $step_type, $step_id ) { |
| 652 |
|
| 653 |
$step_default_fields = array(); |
| 654 |
|
| 655 |
switch ( $step_type ) { |
| 656 |
case 'landing': |
| 657 |
$step_default_fields = wcf()->options->get_landing_fields( $step_id ); |
| 658 |
break; |
| 659 |
|
| 660 |
case 'checkout': |
| 661 |
$step_default_fields = wcf()->options->get_checkout_fields( $step_id ); |
| 662 |
break; |
| 663 |
|
| 664 |
case 'thankyou': |
| 665 |
$step_default_fields = wcf()->options->get_thankyou_fields( $step_id ); |
| 666 |
break; |
| 667 |
|
| 668 |
case 'optin': |
| 669 |
$step_default_fields = wcf()->options->get_optin_fields( $step_id ); |
| 670 |
break; |
| 671 |
|
| 672 |
default: |
| 673 |
break; |
| 674 |
} |
| 675 |
$step_default_fields = apply_filters( 'cartflows_admin_' . $step_type . '_step_default_meta_fields', $step_default_fields, $step_id ); |
| 676 |
return $step_default_fields; |
| 677 |
} |
| 678 |
|
| 679 |
/** |
| 680 |
* Get options. |
| 681 |
*/ |
| 682 |
public static function get_options() { |
| 683 |
|
| 684 |
$general_settings = self::get_common_settings(); |
| 685 |
$permalink_settings = self::get_permalink_settings(); |
| 686 |
$fb_settings = self::get_facebook_settings(); |
| 687 |
$tik_settings = self::get_tiktok_settings(); |
| 688 |
$ga_settings = self::get_google_analytics_settings(); |
| 689 |
$pin_settings = self::get_pinterest_settings(); |
| 690 |
$gads_settings = self::get_google_ads_settings(); |
| 691 |
$snap_settings = self::get_snapchat_settings(); |
| 692 |
$urm_settings = self::get_user_role_management_settings(); |
| 693 |
$auto_fields = self::get_google_auto_fields_settings(); |
| 694 |
$global_scripts = self::get_global_scripts_settings(); |
| 695 |
$options = array_merge( $general_settings, $permalink_settings, $fb_settings, $tik_settings, $ga_settings, $gads_settings, $pin_settings, $snap_settings, $urm_settings, $auto_fields, $global_scripts ); |
| 696 |
$options = apply_filters( 'cartflows_admin_global_data_options', $options ); |
| 697 |
|
| 698 |
return $options; |
| 699 |
} |
| 700 |
|
| 701 |
|
| 702 |
|
| 703 |
/** |
| 704 |
* Prepare step data. |
| 705 |
* |
| 706 |
* @param int $flow_id Flow id. |
| 707 |
* @param array $meta_options Meta data. |
| 708 |
* |
| 709 |
* @return array |
| 710 |
*/ |
| 711 |
public static function prepare_step_data( $flow_id, $meta_options ) { |
| 712 |
|
| 713 |
$steps = $meta_options['wcf-steps']; |
| 714 |
|
| 715 |
if ( is_array( $steps ) && ! empty( $steps ) ) { |
| 716 |
|
| 717 |
foreach ( $steps as $in => $step ) { |
| 718 |
$step_id = $step['id']; |
| 719 |
$steps[ $in ]['title'] = get_the_title( $step_id ); |
| 720 |
$steps[ $in ]['is_product_assigned'] = \Cartflows_Helper::has_product_assigned( $step_id ); |
| 721 |
$steps[ $in ]['step_disabled'] = get_post_meta( $step_id, 'wcf-disable-step', true ) === 'yes'; |
| 722 |
|
| 723 |
$steps[ $in ]['actions'] = self::get_step_actions( $flow_id, $step_id ); |
| 724 |
$steps[ $in ]['menu_actions'] = self::get_step_actions( $flow_id, $step_id, 'menu' ); |
| 725 |
|
| 726 |
$steps[ $in ]['page_builder_edit'] = \Cartflows_Helper::get_page_builder_edit_link( $step_id ); |
| 727 |
|
| 728 |
/* Add variation data */ |
| 729 |
if ( ! empty( $steps[ $in ]['ab-test-variations'] ) ) { |
| 730 |
|
| 731 |
$ab_test_variations = $steps[ $in ]['ab-test-variations']; |
| 732 |
|
| 733 |
foreach ( $ab_test_variations as $variation_in => $variation ) { |
| 734 |
|
| 735 |
$ab_test_variations[ $variation_in ]['title'] = get_the_title( $variation['id'] ); |
| 736 |
$ab_test_variations[ $variation_in ]['actions'] = self::get_ab_test_step_actions( $flow_id, $variation['id'] ); |
| 737 |
$ab_test_variations[ $variation_in ]['menu_actions'] = self::get_ab_test_step_actions( $flow_id, $variation['id'], 'menu' ); |
| 738 |
$ab_test_variations[ $variation_in ]['is_product_assigned'] = \Cartflows_Helper::has_product_assigned( $variation['id'] ); |
| 739 |
$ab_test_variations[ $variation_in ]['step_disabled'] = get_post_meta( $variation['id'], 'wcf-disable-step', true ) === 'yes'; |
| 740 |
} |
| 741 |
|
| 742 |
$steps[ $in ]['ab-test-variations'] = $ab_test_variations; |
| 743 |
} |
| 744 |
|
| 745 |
if ( ! empty( $steps[ $in ]['ab-test-archived-variations'] ) ) { |
| 746 |
|
| 747 |
$ab_test_archived_variations = $steps[ $in ]['ab-test-archived-variations']; |
| 748 |
|
| 749 |
foreach ( $ab_test_archived_variations as $variation_in => $variation ) { |
| 750 |
|
| 751 |
// Don't add hidden archived steps. |
| 752 |
if ( get_post_meta( $variation['id'], 'wcf-hide-step', true ) ) { |
| 753 |
unset( $ab_test_archived_variations[ $variation_in ] ); |
| 754 |
continue; |
| 755 |
} |
| 756 |
|
| 757 |
$ab_test_archived_variations[ $variation_in ]['actions'] = self::get_ab_test_step_archived_actions( $flow_id, $variation['id'], $variation['deleted'] ); |
| 758 |
$ab_test_archived_variations[ $variation_in ]['hide'] = get_post_meta( $variation['id'], 'wcf-hide-step', true ); |
| 759 |
} |
| 760 |
|
| 761 |
$steps[ $in ]['ab-test-archived-variations'] = array_values( $ab_test_archived_variations ); |
| 762 |
} |
| 763 |
} |
| 764 |
|
| 765 |
$steps = apply_filters( 'cartflows_admin_flows_step_data', $steps ); |
| 766 |
} |
| 767 |
|
| 768 |
return $steps; |
| 769 |
} |
| 770 |
|
| 771 |
/** |
| 772 |
* Get step actions. |
| 773 |
* |
| 774 |
* @param int $flow_id Flow id. |
| 775 |
* @param int $step_id Step id. |
| 776 |
* @param string $type type. |
| 777 |
* |
| 778 |
* @return array |
| 779 |
*/ |
| 780 |
public static function get_step_actions( $flow_id, $step_id, $type = 'inline' ) { |
| 781 |
|
| 782 |
if ( 'menu' === $type ) { |
| 783 |
$actions = array( |
| 784 |
'clone' => array( |
| 785 |
'slug' => 'clone', |
| 786 |
'class' => 'wcf-step-clone', |
| 787 |
'icon_class' => 'dashicons dashicons-admin-page', |
| 788 |
'text' => __( 'Duplicate', 'cartflows' ), |
| 789 |
'pro' => true, |
| 790 |
'link' => '#', |
| 791 |
'ajaxcall' => 'cartflows_clone_step', |
| 792 |
), |
| 793 |
'abtest' => array( |
| 794 |
'slug' => 'abtest', |
| 795 |
'class' => 'wcf-step-abtest', |
| 796 |
'icon_class' => 'dashicons dashicons-forms', |
| 797 |
'text' => __( 'A/B Test', 'cartflows' ), |
| 798 |
'pro' => true, |
| 799 |
'link' => '#', |
| 800 |
), |
| 801 |
'delete' => array( |
| 802 |
'slug' => 'delete', |
| 803 |
'class' => 'wcf-step-delete', |
| 804 |
'icon_class' => 'dashicons dashicons-trash', |
| 805 |
'text' => __( 'Delete', 'cartflows' ), |
| 806 |
'link' => '#', |
| 807 |
'ajaxcall' => 'cartflows_delete_step', |
| 808 |
), |
| 809 |
); |
| 810 |
|
| 811 |
if ( current_user_can( 'cartflows_manage_settings' ) ) { |
| 812 |
// Show Automation action only if suretriggers is connected. |
| 813 |
$is_suretriggers_connected = _is_suretriggers_connected(); |
| 814 |
$automation_link = $is_suretriggers_connected ? '#' : admin_url( 'admin.php?page=' . CARTFLOWS_SLUG . '&path=automations' ); |
| 815 |
|
| 816 |
$actions = array_merge( |
| 817 |
array( |
| 818 |
'automation' => array( |
| 819 |
'slug' => 'automation', |
| 820 |
'class' => 'wcf-step-automation', |
| 821 |
'icon_class' => 'dashicons dashicons-editor-code', |
| 822 |
'text' => __( 'Automation', 'cartflows' ), |
| 823 |
'pro' => false, |
| 824 |
'link' => $automation_link, |
| 825 |
'tag' => ! $is_suretriggers_connected ? __( '(Connect)', 'cartflows' ) : '', |
| 826 |
'ajaxcall' => 'cartflows_automation_step', |
| 827 |
), |
| 828 |
), |
| 829 |
$actions |
| 830 |
); |
| 831 |
} |
| 832 |
} else { |
| 833 |
$actions = array( |
| 834 |
'view' => array( |
| 835 |
'slug' => 'view', |
| 836 |
'class' => 'wcf-step-view', |
| 837 |
'icon_class' => 'dashicons dashicons-visibility', |
| 838 |
'target' => 'blank', |
| 839 |
'link' => get_permalink( $step_id ), |
| 840 |
), |
| 841 |
'edit' => array( |
| 842 |
'slug' => 'edit', |
| 843 |
'class' => 'wcf-step-edit', |
| 844 |
'icon_class' => 'dashicons dashicons-edit', |
| 845 |
'link' => \Cartflows_Helper::get_page_builder_edit_link( $step_id ), |
| 846 |
), |
| 847 |
); |
| 848 |
} |
| 849 |
return $actions; |
| 850 |
} |
| 851 |
|
| 852 |
/** |
| 853 |
* Get step actions. |
| 854 |
* |
| 855 |
* @param int $flow_id Flow id. |
| 856 |
* @param int $step_id Step id. |
| 857 |
* @param string $type type. |
| 858 |
* |
| 859 |
* @return array |
| 860 |
*/ |
| 861 |
public static function get_ab_test_step_actions( $flow_id, $step_id, $type = 'inline' ) { |
| 862 |
|
| 863 |
if ( 'menu' === $type ) { |
| 864 |
|
| 865 |
$actions = array( |
| 866 |
'clone' => array( |
| 867 |
'slug' => 'clone', |
| 868 |
'class' => 'wcf-ab-test-step-clone', |
| 869 |
'icon_class' => 'dashicons dashicons-admin-page', |
| 870 |
'text' => __( 'Duplicate', 'cartflows' ), |
| 871 |
'link' => '#', |
| 872 |
'pro' => true, |
| 873 |
'ajaxcall' => 'cartflows_clone_ab_test_step', |
| 874 |
), |
| 875 |
'delete' => array( |
| 876 |
'slug' => 'delete', |
| 877 |
'class' => 'wcf-ab-test-step-delete', |
| 878 |
'icon_class' => 'dashicons dashicons-trash', |
| 879 |
'text' => __( 'Delete', 'cartflows' ), |
| 880 |
'link' => '#', |
| 881 |
'ajaxcall' => 'cartflows_delete_ab_test_step', |
| 882 |
), |
| 883 |
'archived' => array( |
| 884 |
'slug' => 'archived', |
| 885 |
'class' => 'wcf-ab-test-step-archived', |
| 886 |
'icon_class' => 'dashicons dashicons-archive', |
| 887 |
'text' => __( 'Archive', 'cartflows' ), |
| 888 |
'link' => '#', |
| 889 |
), |
| 890 |
'winner' => array( |
| 891 |
'slug' => 'winner', |
| 892 |
'class' => 'wcf-declare-winner', |
| 893 |
'icon_class' => 'dashicons dashicons-yes-alt', |
| 894 |
'text' => __( 'Declare as Winner', 'cartflows' ), |
| 895 |
'link' => '#', |
| 896 |
), |
| 897 |
); |
| 898 |
|
| 899 |
} else { |
| 900 |
$action_slug = apply_filters( 'cartflows_admin_action_slug', 'wcf-edit-step', $flow_id ); |
| 901 |
$actions = array( |
| 902 |
'view' => array( |
| 903 |
'slug' => 'view', |
| 904 |
'class' => 'wcf-step-view', |
| 905 |
'icon_class' => 'dashicons dashicons-visibility', |
| 906 |
'target' => 'blank', |
| 907 |
'link' => get_permalink( $step_id ), |
| 908 |
), |
| 909 |
'edit' => array( |
| 910 |
'slug' => 'edit', |
| 911 |
'class' => 'wcf-step-edit', |
| 912 |
'icon_class' => 'dashicons dashicons-edit', |
| 913 |
'link' => \Cartflows_Helper::get_page_builder_edit_link( $step_id ), |
| 914 |
), |
| 915 |
); |
| 916 |
} |
| 917 |
|
| 918 |
return $actions; |
| 919 |
} |
| 920 |
|
| 921 |
/** |
| 922 |
* Get ab test step action. |
| 923 |
* |
| 924 |
* @param int $flow_id Flow id. |
| 925 |
* @param int $step_id Step id. |
| 926 |
* @param bool $deleted Step deleted or archived. |
| 927 |
* @return array |
| 928 |
*/ |
| 929 |
public static function get_ab_test_step_archived_actions( $flow_id, $step_id, $deleted ) { |
| 930 |
|
| 931 |
if ( $deleted ) { |
| 932 |
$actions = array( |
| 933 |
'archive-hide' => array( |
| 934 |
'slug' => 'hide', |
| 935 |
'class' => 'wcf-step-archive-hide', |
| 936 |
'icon_class' => '', |
| 937 |
'target' => 'blank', |
| 938 |
'before_text' => __( 'Deleted variation can\'t be restored.', 'cartflows' ), |
| 939 |
'text' => __( 'Hide', 'cartflows' ), |
| 940 |
'link' => '#', |
| 941 |
), |
| 942 |
'archive-delete' => array( |
| 943 |
'slug' => 'deleteArch', |
| 944 |
'class' => 'wcf-step-archive-delete', |
| 945 |
'icon_class' => '', |
| 946 |
'target' => 'blank', |
| 947 |
'text' => __( 'Delete', 'cartflows' ), |
| 948 |
'link' => '#', |
| 949 |
), |
| 950 |
); |
| 951 |
} else { |
| 952 |
|
| 953 |
$actions = array( |
| 954 |
'archive-restore' => array( |
| 955 |
'slug' => 'restore', |
| 956 |
'class' => 'wcf-step-archive-restore', |
| 957 |
'icon_class' => '', |
| 958 |
'target' => 'blank', |
| 959 |
'text' => __( 'Restore', 'cartflows' ), |
| 960 |
'link' => '#', |
| 961 |
), |
| 962 |
'archive-delete' => array( |
| 963 |
'slug' => 'delete', |
| 964 |
'class' => 'wcf-step-archive-delete', |
| 965 |
'icon_class' => '', |
| 966 |
'target' => 'blank', |
| 967 |
'text' => __( 'Delete', 'cartflows' ), |
| 968 |
'link' => '#', |
| 969 |
), |
| 970 |
); |
| 971 |
} |
| 972 |
|
| 973 |
return $actions; |
| 974 |
} |
| 975 |
|
| 976 |
/** |
| 977 |
* Calculate earning. |
| 978 |
* |
| 979 |
* @param string $start_date start date. |
| 980 |
* @param string $end_date end date. |
| 981 |
* @param string $flow_id flow id. |
| 982 |
* @param string $screen_type screen_type. |
| 983 |
* @param string $comparison_range_type comparison range type - 'previous-period' | 'previous-year'. |
| 984 |
* |
| 985 |
* @return array |
| 986 |
*/ |
| 987 |
public static function get_earnings( $start_date, $end_date, $flow_id = '', $screen_type = 'funnels', $comparison_range_type = '' ) { |
| 988 |
|
| 989 |
$currency_symbol = function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : ''; |
| 990 |
|
| 991 |
$start_date = $start_date ? $start_date : gmdate( 'Y-m-d' ); |
| 992 |
$end_date = $end_date ? $end_date : gmdate( 'Y-m-d' ); |
| 993 |
|
| 994 |
$start_date = gmdate( 'Y-m-d H:i:s', strtotime( $start_date . '00:00:00' ) ); |
| 995 |
$end_date = gmdate( 'Y-m-d H:i:s', strtotime( $end_date . '23:59:59' ) ); |
| 996 |
|
| 997 |
|
| 998 |
if ( _is_cartflows_pro() && is_wcf_pro_plan() ) { |
| 999 |
// Return All Stats. |
| 1000 |
return apply_filters( |
| 1001 |
'cartflows_home_page_analytics', |
| 1002 |
array( |
| 1003 |
'order_currency' => $currency_symbol, |
| 1004 |
'total_orders' => '0', |
| 1005 |
'total_revenue' => '0', |
| 1006 |
'total_bump_revenue' => '0', |
| 1007 |
'total_offers_revenue' => '0', |
| 1008 |
'total_visits' => '0', |
| 1009 |
), |
| 1010 |
$start_date, |
| 1011 |
$end_date, |
| 1012 |
$flow_id, |
| 1013 |
$screen_type, |
| 1014 |
$comparison_range_type |
| 1015 |
); |
| 1016 |
} |
| 1017 |
|
| 1018 |
$orders = self::get_orders_by_flow( $start_date, $end_date, $flow_id ); |
| 1019 |
$gross_sale = 0; |
| 1020 |
$order_count = 0; |
| 1021 |
|
| 1022 |
if ( ! empty( $orders ) ) { |
| 1023 |
|
| 1024 |
foreach ( $orders as $order ) { |
| 1025 |
|
| 1026 |
$order_id = $order->ID; |
| 1027 |
$order = wc_get_order( $order_id ); |
| 1028 |
$order_total = $order ? $order->get_total() : 0; |
| 1029 |
|
| 1030 |
$order_count++; |
| 1031 |
|
| 1032 |
if ( $order && ! $order->has_status( 'cancelled' ) ) { |
| 1033 |
$gross_sale += (float) $order_total; |
| 1034 |
} |
| 1035 |
} |
| 1036 |
} |
| 1037 |
|
| 1038 |
// Return All Stats. |
| 1039 |
return array( |
| 1040 |
'order_currency' => $currency_symbol, |
| 1041 |
'total_orders' => $order_count, |
| 1042 |
'total_revenue_raw' => $gross_sale, |
| 1043 |
'total_revenue' => str_replace( ' ', '', wc_price( (float) $gross_sale ) ), |
| 1044 |
'total_bump_revenue' => '0', |
| 1045 |
'total_offers_revenue' => '0', |
| 1046 |
'total_visits' => '0', |
| 1047 |
); |
| 1048 |
} |
| 1049 |
|
| 1050 |
|
| 1051 |
|
| 1052 |
/** |
| 1053 |
* Get orders data for flow. |
| 1054 |
* |
| 1055 |
* @since 1.6.15 |
| 1056 |
* |
| 1057 |
* @param string $start_date start date. |
| 1058 |
* @param string $end_date end date. |
| 1059 |
* @param string $flow_id flow id. |
| 1060 |
* @return wc_order object. |
| 1061 |
*/ |
| 1062 |
public static function get_orders_by_flow( $start_date, $end_date, $flow_id = '' ) { |
| 1063 |
|
| 1064 |
global $wpdb; |
| 1065 |
|
| 1066 |
if ( class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) && OrderUtil::custom_orders_table_usage_is_enabled() ) { |
| 1067 |
// HPOS usage is enabled. |
| 1068 |
$conditions = array( |
| 1069 |
'tb1.type' => 'shop_order', |
| 1070 |
); |
| 1071 |
|
| 1072 |
$order_date_key = 'date_created_gmt'; |
| 1073 |
$order_status_key = 'status'; |
| 1074 |
$order_id_key = 'order_id'; |
| 1075 |
$order_table = $wpdb->prefix . 'wc_orders'; |
| 1076 |
$order_meta_table = $wpdb->prefix . 'wc_orders_meta'; |
| 1077 |
|
| 1078 |
} else { |
| 1079 |
// Traditional CPT-based orders are in use. |
| 1080 |
|
| 1081 |
$conditions = array( |
| 1082 |
'tb1.post_type' => 'shop_order', |
| 1083 |
); |
| 1084 |
|
| 1085 |
$order_date_key = 'post_date'; |
| 1086 |
$order_status_key = 'post_status'; |
| 1087 |
$order_id_key = 'post_id'; |
| 1088 |
$order_table = $wpdb->prefix . 'posts'; |
| 1089 |
$order_meta_table = $wpdb->prefix . 'postmeta'; |
| 1090 |
} |
| 1091 |
|
| 1092 |
$where = self::get_items_query_where( $conditions ); |
| 1093 |
|
| 1094 |
if ( ! empty( $flow_id ) ) { |
| 1095 |
$where .= $wpdb->prepare( ' AND tb2.meta_value = %s', $flow_id ); |
| 1096 |
} |
| 1097 |
|
| 1098 |
// Security: Use $wpdb->prepare() for date parameters to prevent SQL injection. |
| 1099 |
$where .= $wpdb->prepare( |
| 1100 |
' AND ( tb1.' . $order_date_key . " BETWEEN IF (tb2.meta_key='wcf-analytics-reset-date'>%s, tb2.meta_key, %s) AND %s )", // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 1101 |
$start_date, |
| 1102 |
$start_date, |
| 1103 |
$end_date |
| 1104 |
); |
| 1105 |
$where .= " AND ( ( tb2.meta_key = '_wcf_flow_id' ) OR ( tb2.meta_key = '_cartflows_parent_flow_id' ) )"; |
| 1106 |
$where .= ' AND tb1.' . $order_status_key . " IN ( 'wc-completed', 'wc-processing' )"; |
| 1107 |
|
| 1108 |
$query = 'SELECT tb1.ID, DATE( tb1.' . $order_date_key . ' ) date, tb2.meta_value FROM ' . $order_table . ' tb1 |
| 1109 |
INNER JOIN ' . $order_meta_table . ' tb2 |
| 1110 |
ON tb1.ID = tb2.' . $order_id_key . ' ' |
| 1111 |
. $where; |
| 1112 |
|
| 1113 |
return $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery |
| 1114 |
} |
| 1115 |
|
| 1116 |
/** |
| 1117 |
* Prepare where items for query. |
| 1118 |
* |
| 1119 |
* @param array $conditions conditions to prepare WHERE query. |
| 1120 |
* @return string |
| 1121 |
*/ |
| 1122 |
public static function get_items_query_where( $conditions ) { |
| 1123 |
|
| 1124 |
global $wpdb; |
| 1125 |
|
| 1126 |
$where_conditions = array(); |
| 1127 |
|
| 1128 |
foreach ( $conditions as $key => $condition ) { |
| 1129 |
|
| 1130 |
if ( false !== stripos( $key, 'IN' ) ) { |
| 1131 |
$where_conditions[] = $key . $wpdb->prepare( '( %s )', $condition ); |
| 1132 |
} else { |
| 1133 |
$where_conditions[] = $key . $wpdb->prepare( '= %s', $condition ); |
| 1134 |
} |
| 1135 |
} |
| 1136 |
|
| 1137 |
if ( ! empty( $where_conditions ) ) { |
| 1138 |
return 'WHERE 1 = 1 AND ' . implode( ' AND ', $where_conditions ); |
| 1139 |
} else { |
| 1140 |
return ''; |
| 1141 |
} |
| 1142 |
} |
| 1143 |
|
| 1144 |
/** |
| 1145 |
* Check is error in the received response. |
| 1146 |
* |
| 1147 |
* @param object $response Received API Response. |
| 1148 |
* @return array $result Error result. |
| 1149 |
* @since 1.11.8 |
| 1150 |
*/ |
| 1151 |
public static function has_api_error( $response ) { |
| 1152 |
|
| 1153 |
$result = array( |
| 1154 |
'error' => false, |
| 1155 |
'error_message' => __( 'Ooops! Something went wrong. Please open a support ticket from the website.', 'cartflows' ), |
| 1156 |
'call_to_action' => __( 'No error found.', 'cartflows' ), |
| 1157 |
'error_code' => 0, |
| 1158 |
); |
| 1159 |
|
| 1160 |
if ( is_wp_error( $response ) ) { |
| 1161 |
|
| 1162 |
$msg = $response->get_error_message(); |
| 1163 |
$error_code = $response->get_error_code(); |
| 1164 |
|
| 1165 |
if ( 'http_request_failed' === $error_code ) { |
| 1166 |
/* translators: %1$s: HTML, %2$s: HTML */ |
| 1167 |
$msg = $msg . '<br>' . sprintf( __( 'Request timeout error. Please check if the firewall or any security plugin is blocking the outgoing HTTP/HTTPS requests to templates.cartflows.com or not. %1$1sTo resolve this issue, please check this %2$2sarticle%3$3s.', 'cartflows' ), '<br><br>', '<a target="_blank" href="' . esc_url( \Cartflows_Helper::get_kb_doc_link( 'https://cartflows.com/docs/request-timeout-error-while-importing-the-flow-step-templates/' ) ) . '">', '</a>' ); |
| 1168 |
} |
| 1169 |
|
| 1170 |
$result['error'] = true; |
| 1171 |
$result['call_to_action'] = $msg; |
| 1172 |
$result['error_code'] = $error_code; |
| 1173 |
|
| 1174 |
} elseif ( ! empty( wp_remote_retrieve_response_code( $response ) ) && ! in_array( wp_remote_retrieve_response_code( $response ), array( 200, 201, 204 ), true ) ) { |
| 1175 |
|
| 1176 |
$error_message = ! empty( wp_remote_retrieve_response_message( $response ) ) ? wp_remote_retrieve_response_message( $response ) : ''; |
| 1177 |
$error_body = ! empty( wp_remote_retrieve_body( $response ) ) ? wp_kses( wp_remote_retrieve_body( $response ), '<p>' ) : ''; |
| 1178 |
|
| 1179 |
if ( false !== strpos( $error_body, 'MalCare' ) ) { |
| 1180 |
/* translators: %1$s: HTML, %2$s: HTML, %3$s: HTML */ |
| 1181 |
$error_message = $error_message . '<br>' . sprintf( __( 'Sorry for the inconvenience, but your website seems to be having trouble connecting to our server. %1$s Please open a technical %2$ssupport ticket%3$s and share the server\'s outgoing IP address.', 'cartflows' ), '<br><br>', '<a href="' . esc_url( \Cartflows_Helper::get_utm_url( 'https://cartflows.com/support', array( 'utm_campaign' => 'support' ) ) ) . '" target="_blank">', '</a>' ); |
| 1182 |
$ip_address = self::get_valid_ip_address(); |
| 1183 |
$result['message'] = ! empty( $ip_address ) ? __( 'Server\'s outgoing IP address: ', 'cartflows' ) . $ip_address : ''; |
| 1184 |
} |
| 1185 |
|
| 1186 |
$result['error'] = true; |
| 1187 |
$result['call_to_action'] = $error_message; |
| 1188 |
$result['error_code'] = wp_remote_retrieve_response_code( $response ); |
| 1189 |
} else { |
| 1190 |
$result['response_code'] = wp_remote_retrieve_response_code( $response ); |
| 1191 |
} |
| 1192 |
|
| 1193 |
return $result; |
| 1194 |
} |
| 1195 |
|
| 1196 |
/** |
| 1197 |
* Convert the array format in the WooCommerce's expected format for display. |
| 1198 |
* Received array format is array( 0=>key, 1=>Key_value ) expected is array( key=>key_value ) |
| 1199 |
* This is because of the core rules structure which we have created. |
| 1200 |
* |
| 1201 |
* @param array $options Array of key & value in the array format. |
| 1202 |
* @return array $options |
| 1203 |
*/ |
| 1204 |
public static function sanitize_array_values( $options ) { |
| 1205 |
|
| 1206 |
if ( is_array( $options ) ) { |
| 1207 |
|
| 1208 |
$sanitized_options = array(); |
| 1209 |
|
| 1210 |
foreach ( $options as $option_key => $option_value ) { |
| 1211 |
$sanitized_options[ trim( $option_value ) ] = trim( $option_value ); |
| 1212 |
} |
| 1213 |
|
| 1214 |
$options = $sanitized_options; |
| 1215 |
} |
| 1216 |
|
| 1217 |
return $options; |
| 1218 |
} |
| 1219 |
|
| 1220 |
/** |
| 1221 |
* Get the IP address of the user's server. |
| 1222 |
* To check weather the IP is not blocked by any firewall. |
| 1223 |
* |
| 1224 |
* Note: This IP address is not stored any where in the database. |
| 1225 |
* |
| 1226 |
* @return string A valid IP address. |
| 1227 |
*/ |
| 1228 |
public static function get_valid_ip_address() { |
| 1229 |
|
| 1230 |
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { //phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders |
| 1231 |
return self::validate_ip_address( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ) ); |
| 1232 |
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) { //phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders |
| 1233 |
return self::validate_ip_address( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) ); //phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders, WordPressVIPMinimum.Variables.RestrictedVariables.cache_constraints___SERVER__REMOTE_ADDR__ |
| 1234 |
} elseif ( isset( $_SERVER['SERVER_ADDR'] ) ) { //phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders |
| 1235 |
return self::validate_ip_address( sanitize_text_field( wp_unslash( $_SERVER['SERVER_ADDR'] ) ) ); |
| 1236 |
} else { |
| 1237 |
return ''; |
| 1238 |
} |
| 1239 |
} |
| 1240 |
|
| 1241 |
/** |
| 1242 |
* Validate the provided IP address safe to printing. |
| 1243 |
* |
| 1244 |
* @param string $ip_address IP address to validate. |
| 1245 |
* @return string $ip_address Validated IP address for display/use. |
| 1246 |
*/ |
| 1247 |
public static function validate_ip_address( $ip_address ) { |
| 1248 |
|
| 1249 |
$ip_address = filter_var( $ip_address, FILTER_VALIDATE_IP, array() ); |
| 1250 |
|
| 1251 |
return $ip_address ? $ip_address : ''; |
| 1252 |
} |
| 1253 |
|
| 1254 |
/** |
| 1255 |
* Track funnel creation method for analytics. |
| 1256 |
* |
| 1257 |
* @param string $creation_method The method used to create the funnel (e.g., 'scratch', 'ready_made_template'). |
| 1258 |
* @return void |
| 1259 |
*/ |
| 1260 |
public static function track_funnel_creation_method( $creation_method ) { |
| 1261 |
$funnel_creation_stats = get_option( |
| 1262 |
'cartflows_funnel_creation_method', |
| 1263 |
array( |
| 1264 |
'scratch' => 0, |
| 1265 |
'ready_made_template' => 0, |
| 1266 |
) |
| 1267 |
); |
| 1268 |
|
| 1269 |
if ( isset( $funnel_creation_stats[ $creation_method ] ) ) { |
| 1270 |
$funnel_creation_stats[ $creation_method ]++; |
| 1271 |
} |
| 1272 |
|
| 1273 |
update_option( 'cartflows_funnel_creation_method', $funnel_creation_stats ); |
| 1274 |
} |
| 1275 |
|
| 1276 |
/** |
| 1277 |
* Determine whether to show the CodeMirror code editor fields. |
| 1278 |
* |
| 1279 |
* Returns true when the custom script migration status is 'completed', |
| 1280 |
* meaning users should see the new separate JS and CSS code editors |
| 1281 |
* instead of the old combined textarea. |
| 1282 |
* |
| 1283 |
* @since 2.2.2 |
| 1284 |
* @return bool |
| 1285 |
*/ |
| 1286 |
public static function should_show_code_editor() { |
| 1287 |
return 'completed' === \CartFlows_Helper::get_script_migration_status(); |
| 1288 |
} |
| 1289 |
|
| 1290 |
/** |
| 1291 |
* Get the field type for custom script fields based on migration status. |
| 1292 |
* |
| 1293 |
* Returns 'code' after migration is completed, 'textarea' otherwise. |
| 1294 |
* |
| 1295 |
* @since 2.2.2 |
| 1296 |
* @return string 'code' or 'textarea' |
| 1297 |
*/ |
| 1298 |
public static function get_custom_script_field_type() { |
| 1299 |
return self::should_show_code_editor() ? 'code' : 'textarea'; |
| 1300 |
} |
| 1301 |
} |
| 1302 |
|