| @@ -20,8 +20,12 @@ | ||
| 20 | 20 | public static function init() { |
| 21 | 21 | |
| 22 | 22 | // Load ref classes. |
| 23 | 23 | add_action( 'init', array( __CLASS__, 'load_ref_classes' ), 1 ); |
| 24 | + | |
| 25 | + // Refresh paid customer option when plugins state changes. | |
| 26 | + add_action( 'activated_plugin', array( __CLASS__, 'update_paid_customer_status_option' ) ); | |
| 27 | + add_action( 'deactivated_plugin', array( __CLASS__, 'update_paid_customer_status_option' ), 99 ); | |
| 24 | 28 | } |
| 25 | 29 | |
| 26 | 30 | /** |
| 27 | 31 | * Load ref classes |
| @@ -68,8 +72,23 @@ | ||
| 68 | 72 | $object = WPSC_Customer::get_anonymous_customer(); |
| 69 | 73 | } |
| 70 | 74 | break; |
| 71 | 75 | |
| 76 | + case 'wpsc_ticket': | |
| 77 | + if ( $value && isset( self::$ref_classes[ $ref_class ] ) ) { | |
| 78 | + $class = self::$ref_classes[ $ref_class ]['class']; | |
| 79 | + $object = new $class( $value ); | |
| 80 | + // A ticket referenced from another record (a todo, a thread, a timer log, ...) | |
| 81 | + // may have since been archived - archived tickets are moved out of the live | |
| 82 | + // tickets table entirely, so the lookup above resolves to an empty object. Fall | |
| 83 | + // back to the archived-ticket table rather than silently returning a blank | |
| 84 | + // ticket (blank id, blank subject, blank link) to every caller. | |
| 85 | + if ( ! $object->id ) { | |
| 86 | + $object = new WPSC_Archive_Ticket( $value ); | |
| 87 | + } | |
| 88 | + } | |
| 89 | + break; | |
| 90 | + | |
| 72 | 91 | default: |
| 73 | 92 | $object = apply_filters( 'wpsc_fun_get_object', $value, $ref_class ); |
| 74 | 93 | if ( ! is_object( $object ) && isset( self::$ref_classes[ $ref_class ] ) ) { |
| 75 | 94 | $class = self::$ref_classes[ $ref_class ]['class']; |
| @@ -1298,9 +1317,9 @@ | ||
| 1298 | 1317 | ), |
| 1299 | 1318 | get_permalink( $support_page ) |
| 1300 | 1319 | ); |
| 1301 | 1320 | |
| 1302 | - } elseif ( $ticket_url_page === 'open-ticket-page' && $open_page && ! empty( $ticket->auth_code ) ) { | |
| 1321 | + } elseif ( $ticket_url_page === 'open-ticket-page' && $open_page && $ticket->auth_code ) { | |
| 1303 | 1322 | |
| 1304 | 1323 | $url = add_query_arg( |
| 1305 | 1324 | array( |
| 1306 | 1325 | 'ticket-id' => $ticket_id, |
| @@ -1310,9 +1329,9 @@ | ||
| 1310 | 1329 | ); |
| 1311 | 1330 | } |
| 1312 | 1331 | } |
| 1313 | 1332 | |
| 1314 | - if ( empty( $url ) ) { | |
| 1333 | + if ( ! $url ) { | |
| 1315 | 1334 | $url = $admin_url; |
| 1316 | 1335 | } |
| 1317 | 1336 | |
| 1318 | 1337 | return apply_filters( 'wpsc_get_ticket_url_by_view', $url, $ticket_id, $view ); |
| @@ -1343,8 +1362,160 @@ | ||
| 1343 | 1362 | } |
| 1344 | 1363 | ) |
| 1345 | 1364 | ); |
| 1346 | 1365 | return array_map( 'strval', $closed_statuses ); // Ensure indexed array. |
| 1366 | + } | |
| 1367 | + | |
| 1368 | + /** | |
| 1369 | + * Check whether any SupportCandy addon is active. | |
| 1370 | + * | |
| 1371 | + * @return bool | |
| 1372 | + */ | |
| 1373 | + public static function is_paid_customer() { | |
| 1374 | + | |
| 1375 | + $cache_key = 'wpsc_is_paid_customer'; | |
| 1376 | + $cached_status = get_option( $cache_key, null ); | |
| 1377 | + | |
| 1378 | + if ( null !== $cached_status ) { | |
| 1379 | + return (bool) $cached_status; | |
| 1380 | + } | |
| 1381 | + | |
| 1382 | + return self::update_paid_customer_status_option(); | |
| 1383 | + } | |
| 1384 | + | |
| 1385 | + /** | |
| 1386 | + * Update the paid customer status option based on active addons. | |
| 1387 | + * | |
| 1388 | + * @param string $plugin - Optional plugin path to exclude from check (used during activation/deactivation). | |
| 1389 | + * @return bool Updated paid customer status. | |
| 1390 | + */ | |
| 1391 | + public static function update_paid_customer_status_option( $plugin = '' ) { | |
| 1392 | + $cache_key = 'wpsc_is_paid_customer'; | |
| 1393 | + | |
| 1394 | + $addon_plugins = array( | |
| 1395 | + 'wpsc-agentgroup/wpsc-agentgroup.php', | |
| 1396 | + 'wpsc-assign-agent-rules/wpsc-assign-agent-rules.php', | |
| 1397 | + 'wpsc-automatic-close-ticket/wpsc-automatic-close-ticket.php', | |
| 1398 | + 'wpsc-canned-reply/wpsc-canned-reply.php', | |
| 1399 | + 'wpsc-edd/wpsc-edd.php', | |
| 1400 | + 'wpsc-email-marketing-tools/wpsc-email-marketing-tools-integration.php', | |
| 1401 | + 'wpsc-email-piping/wpsc-email-piping.php', | |
| 1402 | + 'wpsc-export-ticket/wpsc-export-ticket.php', | |
| 1403 | + 'wpsc-gravity-forms/wpsc-gravity-form-integration.php', | |
| 1404 | + 'wpsc-lms/wpsc-lms.php', | |
| 1405 | + 'wpsc-pressapps-knowledge-base/wpsc-pressapps-knowledge-base.php', | |
| 1406 | + 'wpsc-print-ticket/wpsc-print-ticket.php', | |
| 1407 | + 'wpsc-private-credentials/wpsc_private_credentials.php', | |
| 1408 | + 'wpsc-productivity-suite/wpsc-productivity-suite.php', | |
| 1409 | + 'wpsc-reports/wpsc-reports.php', | |
| 1410 | + 'wpsc-satisfaction-survey/wpsc-satisfaction-survey.php', | |
| 1411 | + 'wpsc-schedule-tickets/wpsc-schedule-tickets.php', | |
| 1412 | + 'wpsc-sla/wpsc-sla.php', | |
| 1413 | + 'wpsc-slack/wpsc-slack.php', | |
| 1414 | + 'wpsc-timer/wpsc-timer.php', | |
| 1415 | + 'wpsc-ultimate-faq/wpsc-ultimate-faq.php', | |
| 1416 | + 'wpsc-usergroup/wpsc-usergroup.php', | |
| 1417 | + 'wpsc-webhooks/wpsc-webhooks.php', | |
| 1418 | + 'wpsc-woocommerce/wpsc-woocommerce.php', | |
| 1419 | + 'wpsc-workflows/wpsc-workflows.php', | |
| 1420 | + ); | |
| 1421 | + | |
| 1422 | + $active_plugins = (array) get_option( 'active_plugins', array() ); | |
| 1423 | + | |
| 1424 | + if ( current_filter() === 'deactivated_plugin' && ! empty( $plugin ) ) { | |
| 1425 | + $active_plugins = array_diff( $active_plugins, array( $plugin ) ); | |
| 1426 | + } | |
| 1427 | + | |
| 1428 | + if ( is_multisite() ) { | |
| 1429 | + $active_network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() ); | |
| 1430 | + $active_plugins = array_merge( $active_plugins, array_keys( $active_network_plugins ) ); | |
| 1431 | + } | |
| 1432 | + | |
| 1433 | + $is_paid_customer = ! empty( array_intersect( $addon_plugins, $active_plugins ) ); | |
| 1434 | + update_option( $cache_key, $is_paid_customer ? 1 : 0 ); | |
| 1435 | + return (bool) $is_paid_customer; | |
| 1436 | + } | |
| 1437 | + | |
| 1438 | + /** | |
| 1439 | + * Whether SupportCandy front-end scripts/styles should load on the current page, | |
| 1440 | + * based on Settings -> General -> Page settings -> Load scripts. | |
| 1441 | + * | |
| 1442 | + * Translation aware: if the current page is a WPML or Polylang translation of a | |
| 1443 | + * page selected in the 'Custom' list, scripts still load - the settings screen can | |
| 1444 | + * only ever store the ID of the page in the language active while saving. | |
| 1445 | + * | |
| 1446 | + * @return bool | |
| 1447 | + */ | |
| 1448 | + public static function is_load_scripts_page() { | |
| 1449 | + | |
| 1450 | + $page_settings = get_option( 'wpsc-gs-page-settings' ); | |
| 1451 | + | |
| 1452 | + $load = true; | |
| 1453 | + | |
| 1454 | + if ( isset( $page_settings['load-scripts'] ) && $page_settings['load-scripts'] === 'custom' ) { | |
| 1455 | + | |
| 1456 | + $current_id = get_the_id(); | |
| 1457 | + $pages = isset( $page_settings['load-script-pages'] ) ? (array) $page_settings['load-script-pages'] : array(); | |
| 1458 | + | |
| 1459 | + $load = $current_id && self::page_id_in_pages_or_translations( $current_id, $pages ); | |
| 1460 | + } | |
| 1461 | + | |
| 1462 | + return (bool) apply_filters( 'wpsc_load_frontend_scripts', $load, $page_settings ); | |
| 1463 | + } | |
| 1464 | + | |
| 1465 | + /** | |
| 1466 | + * Check if given post id matches (directly or via translation) any of the given page ids. | |
| 1467 | + * | |
| 1468 | + * @param int $current_id current post id. | |
| 1469 | + * @param array $page_ids selected page ids from settings. | |
| 1470 | + * @return bool | |
| 1471 | + */ | |
| 1472 | + private static function page_id_in_pages_or_translations( $current_id, $page_ids ) { | |
| 1473 | + | |
| 1474 | + if ( in_array( $current_id, $page_ids ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict | |
| 1475 | + return true; | |
| 1476 | + } | |
| 1477 | + | |
| 1478 | + foreach ( $page_ids as $page_id ) { | |
| 1479 | + | |
| 1480 | + // WPML. | |
| 1481 | + if ( has_filter( 'wpml_object_id' ) ) { | |
| 1482 | + $translated_id = apply_filters( 'wpml_object_id', $page_id, 'page', false ); | |
| 1483 | + if ( $translated_id && (int) $translated_id === (int) $current_id ) { | |
| 1484 | + return true; | |
| 1485 | + } | |
| 1486 | + } | |
| 1487 | + | |
| 1488 | + // Polylang. | |
| 1489 | + if ( function_exists( 'pll_get_post_translations' ) ) { | |
| 1490 | + $translations = pll_get_post_translations( $page_id ); | |
| 1491 | + if ( in_array( $current_id, $translations ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict | |
| 1492 | + return true; | |
| 1493 | + } | |
| 1494 | + } | |
| 1495 | + } | |
| 1496 | + | |
| 1497 | + return false; | |
| 1498 | + } | |
| 1499 | + | |
| 1500 | + /** | |
| 1501 | + * Get current active language code, if a multilingual plugin is active. | |
| 1502 | + * | |
| 1503 | + * @return string|null | |
| 1504 | + */ | |
| 1505 | + public static function get_current_language_code() { | |
| 1506 | + | |
| 1507 | + if ( has_filter( 'wpml_current_language' ) ) { | |
| 1508 | + $lang = apply_filters( 'wpml_current_language', null ); | |
| 1509 | + return $lang ? $lang : null; | |
| 1510 | + } | |
| 1511 | + | |
| 1512 | + if ( function_exists( 'pll_current_language' ) ) { | |
| 1513 | + $lang = pll_current_language(); | |
| 1514 | + return $lang ? $lang : null; | |
| 1515 | + } | |
| 1516 | + | |
| 1517 | + return null; | |
| 1347 | 1518 | } |
| 1348 | 1519 | } |
| 1349 | 1520 | endif; |
| 1350 | 1521 | |