| @@ -8,11 +8,13 @@ | ||
| 8 | 8 | * @license https://opensource.org/licenses/gpl-license GNU Public License |
| 9 | 9 | * @since 1.0 |
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | -// Exit if accessed directly. | |
| 13 | 12 | use Give\License\PremiumAddonsListManager; |
| 13 | +use Give\License\Repositories\LicenseRepository; | |
| 14 | +use Give\License\ValueObjects\LicenseOptionKeys; | |
| 14 | 15 | |
| 16 | +// Exit if accessed directly. | |
| 15 | 17 | if ( ! defined( 'ABSPATH' ) ) { |
| 16 | 18 | exit; |
| 17 | 19 | } |
| 18 | 20 | |
| @@ -144,42 +146,53 @@ | ||
| 144 | 146 | * Get User IP |
| 145 | 147 | * |
| 146 | 148 | * Returns the IP address of the current visitor |
| 147 | 149 | * |
| 150 | + * @since 2.33.5 Add $single param. | |
| 151 | + * @since 1.0 | |
| 152 | + * | |
| 148 | 153 | * @return string $ip User's IP address |
| 149 | - * @since 1.0 | |
| 150 | 154 | */ |
| 151 | -function give_get_ip() { | |
| 155 | +function give_get_ip($single = true) | |
| 156 | +{ | |
| 157 | + $ip_addresses = '127.0.0.1'; | |
| 158 | + $header_type = ''; | |
| 152 | 159 | |
| 153 | - $ip = '127.0.0.1'; | |
| 154 | - | |
| 155 | 160 | if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { |
| 156 | 161 | // check ip from share internet |
| 157 | - $ip = $_SERVER['HTTP_CLIENT_IP']; | |
| 162 | + $ip_addresses = $_SERVER['HTTP_CLIENT_IP']; | |
| 163 | + $header_type = 'HTTP_CLIENT_IP'; | |
| 158 | 164 | } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { |
| 159 | 165 | // to check ip is pass from proxy |
| 160 | - $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; | |
| 166 | + $ip_addresses = $_SERVER['HTTP_X_FORWARDED_FOR']; | |
| 167 | + $header_type = 'HTTP_X_FORWARDED_FOR'; | |
| 161 | 168 | } elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { |
| 162 | - $ip = $_SERVER['REMOTE_ADDR']; | |
| 169 | + $ip_addresses = $_SERVER['REMOTE_ADDR']; | |
| 170 | + $header_type = 'REMOTE_ADDR'; | |
| 163 | 171 | } |
| 164 | 172 | |
| 165 | 173 | /** |
| 166 | 174 | * Filter the IP |
| 167 | 175 | * |
| 168 | - * @since 1.0 | |
| 176 | + * @since 2.33.5 Add $single and $header_type params. | |
| 177 | + * @since 1.0 | |
| 169 | 178 | */ |
| 170 | - $ip = apply_filters( 'give_get_ip', $ip ); | |
| 179 | + $ip_addresses = apply_filters('give_get_ip', $ip_addresses, $single, $header_type); | |
| 171 | 180 | |
| 172 | 181 | // Filter empty values. |
| 173 | - if ( false !== strpos( $ip, ',' ) ) { | |
| 174 | - $ip = give_clean( explode( ',', $ip ) ); | |
| 175 | - $ip = array_filter( $ip ); | |
| 176 | - $ip = implode( ',', $ip ); | |
| 182 | + if (false !== strpos($ip_addresses, ',')) { | |
| 183 | + $ip_addresses = give_clean(explode(',', $ip_addresses)); | |
| 184 | + $ip_addresses = array_filter($ip_addresses); | |
| 185 | + $ip_addresses = implode(',', $ip_addresses); | |
| 177 | 186 | } else { |
| 178 | - $ip = give_clean( $ip ); | |
| 187 | + $ip_addresses = give_clean($ip_addresses); | |
| 179 | 188 | } |
| 180 | 189 | |
| 181 | - return $ip; | |
| 190 | + if ($single && false !== strpos($ip_addresses, ',')) { | |
| 191 | + return explode(',', $ip_addresses)[0]; | |
| 192 | + } | |
| 193 | + | |
| 194 | + return $ip_addresses; | |
| 182 | 195 | } |
| 183 | 196 | |
| 184 | 197 | |
| 185 | 198 | /** |
| @@ -679,8 +692,10 @@ | ||
| 679 | 692 | * |
| 680 | 693 | * @param int $donation_id Donation ID. |
| 681 | 694 | * |
| 682 | 695 | * @return bool Whether the receipt is visible or not. |
| 696 | + | |
| 697 | + * @since 4.16.6 Require the give_nl cookie to be a scalar string before using it as a donor lookup token. | |
| 683 | 698 | * @since 1.3.2 |
| 684 | 699 | */ |
| 685 | 700 | function give_can_view_receipt( $donation_id ) { |
| 686 | 701 | |
| @@ -731,9 +746,13 @@ | ||
| 731 | 746 | } |
| 732 | 747 | |
| 733 | 748 | // Check whether it is receipt access session? |
| 734 | 749 | $receipt_session = give_get_receipt_session(); |
| 735 | - $email_access_token = ! empty( $_COOKIE['give_nl'] ) ? give_clean( $_COOKIE['give_nl'] ) : false; | |
| 750 | + // The give_nl cookie must be a scalar string token; give_clean() does not coerce arrays | |
| 751 | + // to a string, so require is_string() explicitly before treating it as a token. | |
| 752 | + $email_access_token = ! empty( $_COOKIE['give_nl'] ) && is_string( $_COOKIE['give_nl'] ) | |
| 753 | + ? give_clean( $_COOKIE['give_nl'] ) | |
| 754 | + : false; | |
| 736 | 755 | |
| 737 | 756 | if ( |
| 738 | 757 | ! empty( $receipt_session ) || |
| 739 | 758 | ( |
| @@ -1152,12 +1171,14 @@ | ||
| 1152 | 1171 | * |
| 1153 | 1172 | * @param string $type Context for table |
| 1154 | 1173 | * |
| 1155 | 1174 | * @return null|array |
| 1175 | + * | |
| 1176 | + * @since 4.9.0 rename function - PHP 8 compatibility | |
| 1156 | 1177 | * @since 2.0 |
| 1157 | 1178 | * @global wpdb $wpdb |
| 1158 | 1179 | */ |
| 1159 | -function __give_v20_bc_table_details( $type ) { | |
| 1180 | +function give_v20_bc_table_details( $type ) { | |
| 1160 | 1181 | global $wpdb; |
| 1161 | 1182 | $table = []; |
| 1162 | 1183 | |
| 1163 | 1184 | // Bailout. |
| @@ -1621,9 +1642,9 @@ | ||
| 1621 | 1642 | */ |
| 1622 | 1643 | function give_ignore_user_abort() { |
| 1623 | 1644 | ignore_user_abort( true ); |
| 1624 | 1645 | |
| 1625 | - if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { | |
| 1646 | + if ( ! give_is_func_disabled( 'set_time_limit' )) { | |
| 1626 | 1647 | set_time_limit( 0 ); |
| 1627 | 1648 | } |
| 1628 | 1649 | } |
| 1629 | 1650 | |
| @@ -1841,11 +1862,13 @@ | ||
| 1841 | 1862 | * |
| 1842 | 1863 | * @param string $banner_addon_name Give add-on name. |
| 1843 | 1864 | * |
| 1844 | 1865 | * @return array |
| 1866 | + * | |
| 1867 | + * @since 4.9.0 rename function - PHP 8 compatibility | |
| 1845 | 1868 | * @since 2.1.0 |
| 1846 | 1869 | */ |
| 1847 | -function __give_get_active_by_user_meta( $banner_addon_name ) { | |
| 1870 | +function give_get_active_by_user_meta( $banner_addon_name ) { | |
| 1848 | 1871 | global $wpdb; |
| 1849 | 1872 | |
| 1850 | 1873 | // Get the option key. |
| 1851 | 1874 | $option_name = Give_Addon_Activation_Banner::get_banner_user_meta_key( $banner_addon_name ); |
| @@ -1880,8 +1903,78 @@ | ||
| 1880 | 1903 | return $data; |
| 1881 | 1904 | } |
| 1882 | 1905 | |
| 1883 | 1906 | /** |
| 1907 | + * Store recently activated Give's addons to wp options. | |
| 1908 | + * | |
| 1909 | + * @since 4.16.7.1 Moved from includes/admin/plugins.php so the listener is registered on every | |
| 1910 | + * request, and fall back to the plugin file passed by the `activated_plugin` | |
| 1911 | + * action so add-ons activated outside of plugins.php (REST, WP-CLI, | |
| 1912 | + * programmatic `activate_plugin()`, etc.) are recorded too. | |
| 1913 | + * @since 2.1.0 | |
| 1914 | + * | |
| 1915 | + * @param string $activated_plugin Plugin file passed by the `activated_plugin` action. | |
| 1916 | + */ | |
| 1917 | +function give_recently_activated_addons( $activated_plugin = '' ) { | |
| 1918 | + $plugins = []; | |
| 1919 | + | |
| 1920 | + // Check if action is set. | |
| 1921 | + if ( isset( $_REQUEST['action'] ) ) { | |
| 1922 | + $plugin_action = ( '-1' !== $_REQUEST['action'] ) ? $_REQUEST['action'] : ( isset( $_REQUEST['action2'] ) ? $_REQUEST['action2'] : '' ); | |
| 1923 | + | |
| 1924 | + switch ( $plugin_action ) { | |
| 1925 | + case 'activate': // Single add-on activation. | |
| 1926 | + $plugins[] = $_REQUEST['plugin']; | |
| 1927 | + break; | |
| 1928 | + case 'activate-selected': // If multiple add-ons activated. | |
| 1929 | + $plugins = $_REQUEST['checked']; | |
| 1930 | + break; | |
| 1931 | + } | |
| 1932 | + } | |
| 1933 | + | |
| 1934 | + /** | |
| 1935 | + * Activations that do not come from the plugins.php form (Harbor's feature manager, | |
| 1936 | + * WP-CLI, plugin dependencies, any direct `activate_plugin()` call) have no matching | |
| 1937 | + * request parameters, so use the plugin file the action itself provides. | |
| 1938 | + */ | |
| 1939 | + if ( empty( $plugins ) && ! empty( $activated_plugin ) ) { | |
| 1940 | + $plugins[] = $activated_plugin; | |
| 1941 | + } | |
| 1942 | + | |
| 1943 | + if ( ! empty( $plugins ) ) { | |
| 1944 | + | |
| 1945 | + $give_addons = give_get_recently_activated_addons(); | |
| 1946 | + | |
| 1947 | + foreach ( $plugins as $plugin ) { | |
| 1948 | + // Get plugins which has 'Give-' as prefix. | |
| 1949 | + if ( stripos( $plugin, 'Give-' ) !== false ) { | |
| 1950 | + $give_addons[] = $plugin; | |
| 1951 | + } | |
| 1952 | + } | |
| 1953 | + | |
| 1954 | + if ( ! empty( $give_addons ) ) { | |
| 1955 | + // Update the Give's activated add-ons. | |
| 1956 | + update_option( 'give_recently_activated_addons', $give_addons, false ); | |
| 1957 | + } | |
| 1958 | + } | |
| 1959 | +} | |
| 1960 | + | |
| 1961 | +// Add add-on plugins to wp option table. | |
| 1962 | +add_action( 'activated_plugin', 'give_recently_activated_addons', 10 ); | |
| 1963 | + | |
| 1964 | +/** | |
| 1965 | + * Get list of add-on last activated. | |
| 1966 | + * | |
| 1967 | + * @since 4.16.7.1 Moved from includes/admin/plugins.php. | |
| 1968 | + * @since 2.1.3 | |
| 1969 | + * | |
| 1970 | + * @return mixed|array list of recently activated add-on | |
| 1971 | + */ | |
| 1972 | +function give_get_recently_activated_addons() { | |
| 1973 | + return get_option( 'give_recently_activated_addons', [] ); | |
| 1974 | +} | |
| 1975 | + | |
| 1976 | +/** | |
| 1884 | 1977 | * Get time interval for which nonce is valid |
| 1885 | 1978 | * |
| 1886 | 1979 | * @return int |
| 1887 | 1980 | * @since 2.1.3 |
| @@ -1915,12 +2008,14 @@ | ||
| 1915 | 2008 | |
| 1916 | 2009 | /** |
| 1917 | 2010 | * Display/Return a formatted goal for a donation form |
| 1918 | 2011 | * |
| 2012 | + * @since 3.16.0 Add form_id to the array return | |
| 2013 | + * @since 2.1 | |
| 2014 | + * | |
| 1919 | 2015 | * @param int|Give_Donate_Form $form Form ID or Form Object. |
| 1920 | 2016 | * |
| 1921 | 2017 | * @return array |
| 1922 | - * @since 2.1 | |
| 1923 | 2018 | */ |
| 1924 | 2019 | function give_goal_progress_stats( $form ) { |
| 1925 | 2020 | |
| 1926 | 2021 | if ( ! $form instanceof Give_Donate_Form ) { |
| @@ -1930,9 +2025,8 @@ | ||
| 1930 | 2025 | $goal_format = give_get_form_goal_format( $form->ID ); |
| 1931 | 2026 | |
| 1932 | 2027 | /** |
| 1933 | 2028 | * Filter the form. |
| 1934 | - * | |
| 1935 | 2029 | * @since 1.8.8 |
| 1936 | 2030 | */ |
| 1937 | 2031 | $total_goal = apply_filters( 'give_goal_amount_target_output', round( give_maybe_sanitize_amount( $form->goal ), 2 ), $form->ID, $form ); |
| 1938 | 2032 | |
| @@ -1958,14 +2052,16 @@ | ||
| 1958 | 2052 | */ |
| 1959 | 2053 | $actual = apply_filters( 'give_goal_donors_target_output', give_get_form_donor_count( $form->ID ), $form->ID, $form ); |
| 1960 | 2054 | break; |
| 1961 | 2055 | default: |
| 1962 | - /** | |
| 1963 | - * Filter the form income. | |
| 1964 | - * | |
| 1965 | - * @since 1.8.8 | |
| 1966 | - */ | |
| 1967 | - $actual = apply_filters( 'give_goal_amount_raised_output', $form->earnings, $form->ID, $form ); | |
| 2056 | + /** | |
| 2057 | + * Filter the form income. | |
| 2058 | + * | |
| 2059 | + * @since 3.16.0 Revert changes implemented on the 3.14.0 version | |
| 2060 | + * @since 3.14.0 Replace "$form->earnings" with (new DonationQuery())->form($form->ID)->sumIntendedAmount() | |
| 2061 | + * @since 1.8.8 | |
| 2062 | + */ | |
| 2063 | + $actual = apply_filters( 'give_goal_amount_raised_output', $form->earnings, $form->ID, $form ); | |
| 1968 | 2064 | break; |
| 1969 | 2065 | } |
| 1970 | 2066 | |
| 1971 | 2067 | $progress = $total_goal ? round( ( $actual / $total_goal ) * 100, 2 ) : 0; |
| @@ -2005,8 +2101,9 @@ | ||
| 2005 | 2101 | 'progress' => $progress, |
| 2006 | 2102 | 'actual' => $actual, |
| 2007 | 2103 | 'goal' => $total_goal, |
| 2008 | 2104 | 'format' => $goal_format, |
| 2105 | + 'form_id' => $form->ID | |
| 2009 | 2106 | ], |
| 2010 | 2107 | $stats_array |
| 2011 | 2108 | ); |
| 2012 | 2109 | |
| @@ -2406,8 +2503,11 @@ | ||
| 2406 | 2503 | |
| 2407 | 2504 | /** |
| 2408 | 2505 | * Refresh all givewp license. |
| 2409 | 2506 | * |
| 2507 | + * @since 4.15.0 add support for Harbor unified licenses | |
| 2508 | + * @since 4.8.0 Update active license date after license refresh when active license is found | |
| 2509 | + * @since 4.3.0 updated to store platform fee percentage | |
| 2410 | 2510 | * @since 2.27.0 delete update_plugins transient instead of invalidate it |
| 2411 | 2511 | * @since 2.5.0 |
| 2412 | 2512 | * |
| 2413 | 2513 | * @param bool $wp_check_updates |
| @@ -2424,9 +2524,14 @@ | ||
| 2424 | 2524 | } |
| 2425 | 2525 | |
| 2426 | 2526 | $license_keys = $give_licenses ? implode( ',', array_keys( $give_licenses ) ) : ''; |
| 2427 | 2527 | |
| 2428 | - $unlicensed_give_addon = $give_addons | |
| 2528 | + // Exclude addons already licensed via Harbor from the unlicensed list sent to the legacy API. | |
| 2529 | + $legacy_unlicensed_addons = array_filter( $give_addons, static function ( $plugin ) { | |
| 2530 | + return ! $plugin['License']; | |
| 2531 | + } ); | |
| 2532 | + | |
| 2533 | + $unlicensed_give_addon = $legacy_unlicensed_addons | |
| 2429 | 2534 | ? array_values( |
| 2430 | 2535 | array_diff( |
| 2431 | 2536 | array_map( |
| 2432 | 2537 | function ( $plugin_name ) { |
| @@ -2431,9 +2536,9 @@ | ||
| 2431 | 2536 | array_map( |
| 2432 | 2537 | function ( $plugin_name ) { |
| 2433 | 2538 | return trim( str_replace( 'Give - ', '', $plugin_name ) ); |
| 2434 | 2539 | }, |
| 2435 | - wp_list_pluck( $give_addons, 'Name', true ) | |
| 2540 | + wp_list_pluck( $legacy_unlicensed_addons, 'Name', true ) | |
| 2436 | 2541 | ), |
| 2437 | 2542 | wp_list_pluck( $give_licenses, 'item_name', true ) |
| 2438 | 2543 | ) |
| 2439 | 2544 | ) |
| @@ -2438,8 +2543,13 @@ | ||
| 2438 | 2543 | ) |
| 2439 | 2544 | ) |
| 2440 | 2545 | : []; |
| 2441 | 2546 | |
| 2547 | + // Nothing for the legacy API to check. | |
| 2548 | + if ( empty( $give_licenses ) && empty( $unlicensed_give_addon ) ) { | |
| 2549 | + return []; | |
| 2550 | + } | |
| 2551 | + | |
| 2442 | 2552 | $tmp = Give_License::request_license_api( |
| 2443 | 2553 | [ |
| 2444 | 2554 | 'edd_action' => 'check_licenses', |
| 2445 | 2555 | 'licenses' => $license_keys, |
| @@ -2503,8 +2613,21 @@ | ||
| 2503 | 2613 | $refresh['time'] = time(); |
| 2504 | 2614 | |
| 2505 | 2615 | update_option( 'give_licenses_refreshed_last_checked', $refresh, 'no' ); |
| 2506 | 2616 | |
| 2617 | + $platform_fee_percentage = get_platform_fee_from_licenses(); | |
| 2618 | + | |
| 2619 | + if (!is_null($platform_fee_percentage)) { | |
| 2620 | + update_option( LicenseOptionKeys::PLATFORM_FEE_PERCENTAGE, $platform_fee_percentage, 'no' ); | |
| 2621 | + } | |
| 2622 | + | |
| 2623 | + // Update active license date after license refresh when active license is found | |
| 2624 | + $active_license_date = get_active_license_date(); | |
| 2625 | + | |
| 2626 | + if(!is_null($active_license_date)) { | |
| 2627 | + update_option(LicenseOptionKeys::LAST_ACTIVE_LICENSE_DATE, $active_license_date, 'no'); | |
| 2628 | + } | |
| 2629 | + | |
| 2507 | 2630 | // Tell WordPress to look for updates. |
| 2508 | 2631 | if ( $wp_check_updates ) { |
| 2509 | 2632 | delete_site_transient('update_plugins'); |
| 2510 | 2633 | } |
| @@ -2515,8 +2638,32 @@ | ||
| 2515 | 2638 | ]; |
| 2516 | 2639 | } |
| 2517 | 2640 | |
| 2518 | 2641 | /** |
| 2642 | + * Get platform fee from stored licenses | |
| 2643 | + */ | |
| 2644 | +function get_platform_fee_from_licenses(): ?float | |
| 2645 | +{ | |
| 2646 | + /** @var LicenseRepository $repository */ | |
| 2647 | + $repository = give(LicenseRepository::class); | |
| 2648 | + | |
| 2649 | + return $repository->findLowestPlatformFeePercentageFromActiveLicenses(); | |
| 2650 | +} | |
| 2651 | + | |
| 2652 | +/** | |
| 2653 | + * Set Active License Date | |
| 2654 | + * | |
| 2655 | + * @since 4.8.0 | |
| 2656 | + */ | |
| 2657 | +function get_active_license_date(): ?int | |
| 2658 | +{ | |
| 2659 | + /** @var LicenseRepository $repository */ | |
| 2660 | + $repository = give(LicenseRepository::class); | |
| 2661 | + | |
| 2662 | + return $repository->getCurrentActiveLicenseDate(); | |
| 2663 | +} | |
| 2664 | + | |
| 2665 | +/** | |
| 2519 | 2666 | * Check add-ons updates |
| 2520 | 2667 | * Note: only for internal use |
| 2521 | 2668 | * |
| 2522 | 2669 | * @param stdClass $_transient_data Plugin updates information |
| @@ -2530,8 +2677,13 @@ | ||
| 2530 | 2677 | } |
| 2531 | 2678 | |
| 2532 | 2679 | $update_plugins = get_option( 'give_get_versions', [] ); |
| 2533 | 2680 | $check_licenses = get_option( 'give_licenses', [] ); |
| 2681 | + | |
| 2682 | + // Skip legacy update checks when Harbor is managing licensing and no legacy licenses exist. | |
| 2683 | + if ( empty( $check_licenses ) && lw_harbor_is_product_license_active( 'give' ) ) { | |
| 2684 | + return $_transient_data; | |
| 2685 | + } | |
| 2534 | 2686 | |
| 2535 | 2687 | if ( ! $update_plugins ) { |
| 2536 | 2688 | $data = give_refresh_licenses( false ); |
| 2537 | 2689 | |