Changeset 3442828
- Timestamp:
- 01/19/2026 10:14:21 PM (2 months ago)
- Location:
- groundhogg
- Files:
-
- 4 deleted
- 20 edited
- 1 copied
-
tags/4.2.11 (copied) (copied from groundhogg/trunk)
-
tags/4.2.11/README.txt (modified) (2 diffs)
-
tags/4.2.11/admin/contacts/parts/edit.php (modified) (1 diff)
-
tags/4.2.11/admin/settings/settings-page.php (modified) (3 diffs)
-
tags/4.2.11/assets/lib/chart/Chart.bundle.js (deleted)
-
tags/4.2.11/assets/lib/chart/Chart.bundle.min.js (deleted)
-
tags/4.2.11/groundhogg.php (modified) (2 diffs)
-
tags/4.2.11/includes/classes/broadcast.php (modified) (1 diff)
-
tags/4.2.11/includes/classes/contact.php (modified) (1 diff)
-
tags/4.2.11/includes/classes/step.php (modified) (1 diff)
-
tags/4.2.11/includes/functions.php (modified) (1 diff)
-
tags/4.2.11/includes/scripts.php (modified) (1 diff)
-
tags/4.2.11/includes/utils/location.php (modified) (4 diffs)
-
trunk/README.txt (modified) (2 diffs)
-
trunk/admin/contacts/parts/edit.php (modified) (1 diff)
-
trunk/admin/settings/settings-page.php (modified) (3 diffs)
-
trunk/assets/lib/chart/Chart.bundle.js (deleted)
-
trunk/assets/lib/chart/Chart.bundle.min.js (deleted)
-
trunk/groundhogg.php (modified) (2 diffs)
-
trunk/includes/classes/broadcast.php (modified) (1 diff)
-
trunk/includes/classes/contact.php (modified) (1 diff)
-
trunk/includes/classes/step.php (modified) (1 diff)
-
trunk/includes/functions.php (modified) (1 diff)
-
trunk/includes/scripts.php (modified) (1 diff)
-
trunk/includes/utils/location.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
groundhogg/tags/4.2.11/README.txt
r3422142 r3442828 294 294 295 295 ### Geolocation services 296 Groundhogg will attempt to use the free service [ipquery.io](https://ipquery.io) to determine a contact's location and timezone using their IP address.296 Groundhogg will attempt (if licensed) to geolocate a contact (country, region, timezone, etc...) based on their IP address using our Geolocation service `https://ipinfo.groundhogg.io`. No data is stored remotely and no PII is used. We use a third party based in Romania to provide geolocation services. 297 297 298 298 [](http://coderisk.com/wp/plugin/groundhogg/RIPS-RLU9faYUDI) … … 378 378 379 379 == Changelog == 380 381 = 4.2.11 (2026-01-19) = 382 * ADDED Setting in **Settings » Misc » Features** to disable geolocation services. 383 * TWEAKED IP geolocation is now a licensed feature since there are no longer any free geolocation providers. 384 * TWEAKED Use local `moment.js` for the chart library. 385 * FIXED Possible infinite recursion fatal error when editing flows. 380 386 381 387 = 4.2.10 (2025-12-12) = -
groundhogg/tags/4.2.11/admin/contacts/parts/edit.php
r3343709 r3442828 40 40 } 41 41 42 $country = $contact->get_meta( 'country' ); 43 $ip_address = $contact->get_ip_address(); 44 45 // automatically attempt to extrapolate the location of a contact... 46 if ( $ip_address && ! $country ){ 47 $contact->extrapolate_location(); 48 } 49 42 50 ?> 43 51 <div class="contact-record"> -
groundhogg/tags/4.2.11/admin/settings/settings-page.php
r3347592 r3442828 518 518 'id' => 'interface', 519 519 'title' => _x( 'Interface', 'settings_sections', 'groundhogg' ), 520 'tab' => 'misc' 521 ], 522 'features' => [ 523 'id' => 'features', 524 'title' => _x( 'Features', 'settings_sections', 'groundhogg' ), 520 525 'tab' => 'misc' 521 526 ], … … 1009 1014 ], 1010 1015 ], 1016 'gh_disable_geolocation_services' => [ 1017 'id' => 'gh_disable_geolocation_services', 1018 'section' => 'features', 1019 'label' => _x( 'Disable geolocation services', 'settings', 'groundhogg' ), 1020 /* translators: the plugin/brand name */ 1021 'desc' => sprintf( _x( 'By default, %s will attempt to determine the contact\'s country of origin and timezone based on their IP address.', 'settings', 'groundhogg' ), white_labeled_name() ), 1022 'type' => 'checkbox', 1023 'atts' => [ 1024 'label' => __( 'Disable', 'groundhogg' ), 1025 'name' => 'gh_disable_geolocation_services', 1026 'id' => 'gh_disable_geolocation_services', 1027 'value' => 'on', 1028 ], 1029 ], 1011 1030 'gh_ignore_user_precedence' => [ 1012 1031 'id' => 'gh_ignore_user_precedence', … … 1788 1807 1789 1808 // Dependent settings 1809 if ( ! get_master_license() ){ 1810 unset( $settings['gh_disable_geolocation_services'] ); // don't show if unlicensed 1811 } 1790 1812 1791 1813 return apply_filters( 'groundhogg/admin/settings/settings', $settings ); -
groundhogg/tags/4.2.11/groundhogg.php
r3422142 r3442828 4 4 * Plugin URI: https://www.groundhogg.io/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash 5 5 * Description: CRM and marketing automation for WordPress 6 * Version: 4.2.1 06 * Version: 4.2.11 7 7 * Author: Groundhogg Inc. 8 8 * Author URI: https://www.groundhogg.io/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash … … 25 25 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly 26 26 27 define( 'GROUNDHOGG_VERSION', '4.2.1 0' );28 define( 'GROUNDHOGG_PREVIOUS_STABLE_VERSION', '4.2. 9' );27 define( 'GROUNDHOGG_VERSION', '4.2.11' ); 28 define( 'GROUNDHOGG_PREVIOUS_STABLE_VERSION', '4.2.10' ); 29 29 30 30 define( 'GROUNDHOGG__FILE__', __FILE__ ); -
groundhogg/tags/4.2.11/includes/classes/broadcast.php
r3386122 r3442828 902 902 return array_merge( parent::get_as_array(), [ 903 903 'object' => $this->get_object(), 904 'date_sent_pretty' => $date->wpDateTimeFormat() 904 'date_sent_pretty' => $date->wpDateTimeFormat(), 905 'title' => $this->get_title(), 905 906 ] ); 906 907 } -
groundhogg/tags/4.2.11/includes/classes/contact.php
r3422142 r3442828 1071 1071 * Extrapolate the contact's location from an IP. 1072 1072 * 1073 * @param bool$override1073 * @param bool $override 1074 1074 * 1075 1075 * @return array|bool 1076 1076 */ 1077 1077 public function extrapolate_location( $override = false ) { 1078 1079 // don't check if geolocation is disabled. 1080 $disabled = is_option_enabled( 'gh_disable_geolocation_services' ); // should be false unless disabled in settings 1081 1082 /** 1083 * Filter geolocation functionality 1084 * 1085 * @param $enablaed bool whether to disable geolocation 1086 */ 1087 if ( ! apply_filters( 'groundhogg/should_extrapolate_location', ! $disabled ) ){ 1088 return false; 1089 } 1090 1078 1091 $ip_address = $this->get_ip_address(); 1079 1092 -
groundhogg/tags/4.2.11/includes/classes/step.php
r3422142 r3442828 184 184 */ 185 185 public function get_level() { 186 $level = absint( $this->step_level ); 187 188 // level has not been initialized yet, maybe the upgrade script didn't run? 189 if ( $level < 1 ) { 190 $this->get_funnel()->set_step_levels(); 191 $this->pull(); 192 $level = absint( $this->step_level ); 193 } 194 195 return $level; 186 return absint( $this->step_level ); 196 187 } 197 188 -
groundhogg/tags/4.2.11/includes/functions.php
r3422142 r3442828 1855 1855 function extrapolate_location_after_signup( $contact ) { 1856 1856 // Update their location based on the current IP address. 1857 if ( apply_filters( 'groundhogg/should_extrapolate_location', true ) &&$contact->update_meta( 'ip_address', utils()->location->get_real_ip() ) ) {1857 if ( $contact->update_meta( 'ip_address', utils()->location->get_real_ip() ) ) { 1858 1858 $contact->extrapolate_location(); 1859 1859 } -
groundhogg/tags/4.2.11/includes/scripts.php
r3400645 r3442828 236 236 237 237 //chartjs 238 wp_register_script( 'groundhogg-chart-js', GROUNDHOGG_ASSETS_URL . 'lib/chart/Chart.bundle.min.js' ); 238 wp_register_script( 'groundhogg-chart-js', GROUNDHOGG_ASSETS_URL . 'lib/chart/Chart.min.js', [ 239 'moment' 240 ] ); 239 241 240 242 // wp_register_script( 'moment-js', GROUNDHOGG_ASSETS_URL . 'lib/calendar/js/moment.min.js' ); -
groundhogg/tags/4.2.11/includes/utils/location.php
r3394550 r3442828 521 521 * Get Geolocated information about an IP address 522 522 * 523 * @param null $ip524 * @param string $purpose525 * @param bool $deep_detect523 * @param null|string $ip the contact's ip address to check 524 * @param string $purpose what to return, accepts location, cc, city, region, etc... 525 * @param null $unused unused now 526 526 * 527 527 * @return array|string|object 528 528 */ 529 public function ip_info( $ip = null, $purpose = "location", $deep_detect = true ) { 529 public function ip_info( $ip = null, $purpose = "location", $unused = null ) { 530 531 // from now on ip info will require having an active and installed master license 532 if ( ! get_master_license() ) { 533 return false; 534 } 530 535 531 536 $output = null; … … 559 564 if ( in_array( $purpose, $support ) ) { 560 565 561 $ip_data = wp_remote_get( "https://api.ipquery.io/" . $ip, [ 562 'headers' => [ 563 'Referer' => home_url() 564 ] 565 ] ); 566 $ip_data = wp_remote_get( add_query_arg( [ 567 'ip' => $ip, 568 'license' => get_master_license() 569 ], "https://ipinfo.groundhogg.io" ) ); 566 570 567 571 if ( is_wp_error( $ip_data ) || ! $ip_data || wp_remote_retrieve_response_code( $ip_data ) !== 200 ) { … … 576 580 } 577 581 578 if ( @strlen( trim( $ip_data-> location->country_code ) ) == 2 ) {582 if ( @strlen( trim( $ip_data->countryCode ) ) == 2 ) { 579 583 switch ( $purpose ) { 580 584 case 'raw': … … 583 587 case 'location': 584 588 $output = array( 585 "city" => @$ip_data->location->city, 586 "region" => @$ip_data->location->state, 587 "country" => @$ip_data->location->country, 588 "country_code" => @$ip_data->location->country_code, 589 "time_zone" => @$ip_data->location->timezone, 589 "city" => @$ip_data->city, 590 "region" => @$ip_data->regionName, 591 "region_code" => @$ip_data->region, 592 "country" => @$ip_data->country, 593 "country_code" => @$ip_data->countryCode, 594 "time_zone" => @$ip_data->timezone, 590 595 ); 591 596 break; 592 597 case 'address': 593 $address = array( $ip_data-> location->country );594 if ( @strlen( $ip_data-> location->state ) >= 1 ) {595 $address[] = $ip_data-> location->state;598 $address = array( $ip_data->country ); 599 if ( @strlen( $ip_data->regionName ) >= 1 ) { 600 $address[] = $ip_data->regionName; 596 601 } 597 if ( @strlen( $ip_data-> location->city ) >= 1 ) {598 $address[] = $ip_data-> location->city;602 if ( @strlen( $ip_data->city ) >= 1 ) { 603 $address[] = $ip_data->city; 599 604 } 600 605 $output = implode( ", ", array_reverse( $address ) ); 601 606 break; 602 607 case 'city': 603 $output = @$ip_data-> location->city;608 $output = @$ip_data->city; 604 609 break; 605 610 case 'region': 606 611 case 'province': 607 612 case 'state': 608 $output = @$ip_data->location->state;613 $output = @$ip_data->regionName; 609 614 break; 610 615 case 'country': 611 $output = @$ip_data-> location->country;616 $output = @$ip_data->country; 612 617 break; 613 618 case 'countrycode': 614 619 case 'country_code': 615 620 case 'cc': 616 $output = @$ip_data->location->country_code;621 $output = @$ip_data->countryCode; 617 622 break; 618 623 case 'time_zone': 619 624 case 'timezone': 620 625 case 'tz': 621 $output = @$ip_data->location->timezone;626 $output = @$ip_data->timezone; 622 627 break; 623 628 } -
groundhogg/trunk/README.txt
r3422142 r3442828 294 294 295 295 ### Geolocation services 296 Groundhogg will attempt to use the free service [ipquery.io](https://ipquery.io) to determine a contact's location and timezone using their IP address.296 Groundhogg will attempt (if licensed) to geolocate a contact (country, region, timezone, etc...) based on their IP address using our Geolocation service `https://ipinfo.groundhogg.io`. No data is stored remotely and no PII is used. We use a third party based in Romania to provide geolocation services. 297 297 298 298 [](http://coderisk.com/wp/plugin/groundhogg/RIPS-RLU9faYUDI) … … 378 378 379 379 == Changelog == 380 381 = 4.2.11 (2026-01-19) = 382 * ADDED Setting in **Settings » Misc » Features** to disable geolocation services. 383 * TWEAKED IP geolocation is now a licensed feature since there are no longer any free geolocation providers. 384 * TWEAKED Use local `moment.js` for the chart library. 385 * FIXED Possible infinite recursion fatal error when editing flows. 380 386 381 387 = 4.2.10 (2025-12-12) = -
groundhogg/trunk/admin/contacts/parts/edit.php
r3343709 r3442828 40 40 } 41 41 42 $country = $contact->get_meta( 'country' ); 43 $ip_address = $contact->get_ip_address(); 44 45 // automatically attempt to extrapolate the location of a contact... 46 if ( $ip_address && ! $country ){ 47 $contact->extrapolate_location(); 48 } 49 42 50 ?> 43 51 <div class="contact-record"> -
groundhogg/trunk/admin/settings/settings-page.php
r3347592 r3442828 518 518 'id' => 'interface', 519 519 'title' => _x( 'Interface', 'settings_sections', 'groundhogg' ), 520 'tab' => 'misc' 521 ], 522 'features' => [ 523 'id' => 'features', 524 'title' => _x( 'Features', 'settings_sections', 'groundhogg' ), 520 525 'tab' => 'misc' 521 526 ], … … 1009 1014 ], 1010 1015 ], 1016 'gh_disable_geolocation_services' => [ 1017 'id' => 'gh_disable_geolocation_services', 1018 'section' => 'features', 1019 'label' => _x( 'Disable geolocation services', 'settings', 'groundhogg' ), 1020 /* translators: the plugin/brand name */ 1021 'desc' => sprintf( _x( 'By default, %s will attempt to determine the contact\'s country of origin and timezone based on their IP address.', 'settings', 'groundhogg' ), white_labeled_name() ), 1022 'type' => 'checkbox', 1023 'atts' => [ 1024 'label' => __( 'Disable', 'groundhogg' ), 1025 'name' => 'gh_disable_geolocation_services', 1026 'id' => 'gh_disable_geolocation_services', 1027 'value' => 'on', 1028 ], 1029 ], 1011 1030 'gh_ignore_user_precedence' => [ 1012 1031 'id' => 'gh_ignore_user_precedence', … … 1788 1807 1789 1808 // Dependent settings 1809 if ( ! get_master_license() ){ 1810 unset( $settings['gh_disable_geolocation_services'] ); // don't show if unlicensed 1811 } 1790 1812 1791 1813 return apply_filters( 'groundhogg/admin/settings/settings', $settings ); -
groundhogg/trunk/groundhogg.php
r3422142 r3442828 4 4 * Plugin URI: https://www.groundhogg.io/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash 5 5 * Description: CRM and marketing automation for WordPress 6 * Version: 4.2.1 06 * Version: 4.2.11 7 7 * Author: Groundhogg Inc. 8 8 * Author URI: https://www.groundhogg.io/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash … … 25 25 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly 26 26 27 define( 'GROUNDHOGG_VERSION', '4.2.1 0' );28 define( 'GROUNDHOGG_PREVIOUS_STABLE_VERSION', '4.2. 9' );27 define( 'GROUNDHOGG_VERSION', '4.2.11' ); 28 define( 'GROUNDHOGG_PREVIOUS_STABLE_VERSION', '4.2.10' ); 29 29 30 30 define( 'GROUNDHOGG__FILE__', __FILE__ ); -
groundhogg/trunk/includes/classes/broadcast.php
r3386122 r3442828 902 902 return array_merge( parent::get_as_array(), [ 903 903 'object' => $this->get_object(), 904 'date_sent_pretty' => $date->wpDateTimeFormat() 904 'date_sent_pretty' => $date->wpDateTimeFormat(), 905 'title' => $this->get_title(), 905 906 ] ); 906 907 } -
groundhogg/trunk/includes/classes/contact.php
r3422142 r3442828 1071 1071 * Extrapolate the contact's location from an IP. 1072 1072 * 1073 * @param bool$override1073 * @param bool $override 1074 1074 * 1075 1075 * @return array|bool 1076 1076 */ 1077 1077 public function extrapolate_location( $override = false ) { 1078 1079 // don't check if geolocation is disabled. 1080 $disabled = is_option_enabled( 'gh_disable_geolocation_services' ); // should be false unless disabled in settings 1081 1082 /** 1083 * Filter geolocation functionality 1084 * 1085 * @param $enablaed bool whether to disable geolocation 1086 */ 1087 if ( ! apply_filters( 'groundhogg/should_extrapolate_location', ! $disabled ) ){ 1088 return false; 1089 } 1090 1078 1091 $ip_address = $this->get_ip_address(); 1079 1092 -
groundhogg/trunk/includes/classes/step.php
r3422142 r3442828 184 184 */ 185 185 public function get_level() { 186 $level = absint( $this->step_level ); 187 188 // level has not been initialized yet, maybe the upgrade script didn't run? 189 if ( $level < 1 ) { 190 $this->get_funnel()->set_step_levels(); 191 $this->pull(); 192 $level = absint( $this->step_level ); 193 } 194 195 return $level; 186 return absint( $this->step_level ); 196 187 } 197 188 -
groundhogg/trunk/includes/functions.php
r3422142 r3442828 1855 1855 function extrapolate_location_after_signup( $contact ) { 1856 1856 // Update their location based on the current IP address. 1857 if ( apply_filters( 'groundhogg/should_extrapolate_location', true ) &&$contact->update_meta( 'ip_address', utils()->location->get_real_ip() ) ) {1857 if ( $contact->update_meta( 'ip_address', utils()->location->get_real_ip() ) ) { 1858 1858 $contact->extrapolate_location(); 1859 1859 } -
groundhogg/trunk/includes/scripts.php
r3400645 r3442828 236 236 237 237 //chartjs 238 wp_register_script( 'groundhogg-chart-js', GROUNDHOGG_ASSETS_URL . 'lib/chart/Chart.bundle.min.js' ); 238 wp_register_script( 'groundhogg-chart-js', GROUNDHOGG_ASSETS_URL . 'lib/chart/Chart.min.js', [ 239 'moment' 240 ] ); 239 241 240 242 // wp_register_script( 'moment-js', GROUNDHOGG_ASSETS_URL . 'lib/calendar/js/moment.min.js' ); -
groundhogg/trunk/includes/utils/location.php
r3394550 r3442828 521 521 * Get Geolocated information about an IP address 522 522 * 523 * @param null $ip524 * @param string $purpose525 * @param bool $deep_detect523 * @param null|string $ip the contact's ip address to check 524 * @param string $purpose what to return, accepts location, cc, city, region, etc... 525 * @param null $unused unused now 526 526 * 527 527 * @return array|string|object 528 528 */ 529 public function ip_info( $ip = null, $purpose = "location", $deep_detect = true ) { 529 public function ip_info( $ip = null, $purpose = "location", $unused = null ) { 530 531 // from now on ip info will require having an active and installed master license 532 if ( ! get_master_license() ) { 533 return false; 534 } 530 535 531 536 $output = null; … … 559 564 if ( in_array( $purpose, $support ) ) { 560 565 561 $ip_data = wp_remote_get( "https://api.ipquery.io/" . $ip, [ 562 'headers' => [ 563 'Referer' => home_url() 564 ] 565 ] ); 566 $ip_data = wp_remote_get( add_query_arg( [ 567 'ip' => $ip, 568 'license' => get_master_license() 569 ], "https://ipinfo.groundhogg.io" ) ); 566 570 567 571 if ( is_wp_error( $ip_data ) || ! $ip_data || wp_remote_retrieve_response_code( $ip_data ) !== 200 ) { … … 576 580 } 577 581 578 if ( @strlen( trim( $ip_data-> location->country_code ) ) == 2 ) {582 if ( @strlen( trim( $ip_data->countryCode ) ) == 2 ) { 579 583 switch ( $purpose ) { 580 584 case 'raw': … … 583 587 case 'location': 584 588 $output = array( 585 "city" => @$ip_data->location->city, 586 "region" => @$ip_data->location->state, 587 "country" => @$ip_data->location->country, 588 "country_code" => @$ip_data->location->country_code, 589 "time_zone" => @$ip_data->location->timezone, 589 "city" => @$ip_data->city, 590 "region" => @$ip_data->regionName, 591 "region_code" => @$ip_data->region, 592 "country" => @$ip_data->country, 593 "country_code" => @$ip_data->countryCode, 594 "time_zone" => @$ip_data->timezone, 590 595 ); 591 596 break; 592 597 case 'address': 593 $address = array( $ip_data-> location->country );594 if ( @strlen( $ip_data-> location->state ) >= 1 ) {595 $address[] = $ip_data-> location->state;598 $address = array( $ip_data->country ); 599 if ( @strlen( $ip_data->regionName ) >= 1 ) { 600 $address[] = $ip_data->regionName; 596 601 } 597 if ( @strlen( $ip_data-> location->city ) >= 1 ) {598 $address[] = $ip_data-> location->city;602 if ( @strlen( $ip_data->city ) >= 1 ) { 603 $address[] = $ip_data->city; 599 604 } 600 605 $output = implode( ", ", array_reverse( $address ) ); 601 606 break; 602 607 case 'city': 603 $output = @$ip_data-> location->city;608 $output = @$ip_data->city; 604 609 break; 605 610 case 'region': 606 611 case 'province': 607 612 case 'state': 608 $output = @$ip_data->location->state;613 $output = @$ip_data->regionName; 609 614 break; 610 615 case 'country': 611 $output = @$ip_data-> location->country;616 $output = @$ip_data->country; 612 617 break; 613 618 case 'countrycode': 614 619 case 'country_code': 615 620 case 'cc': 616 $output = @$ip_data->location->country_code;621 $output = @$ip_data->countryCode; 617 622 break; 618 623 case 'time_zone': 619 624 case 'timezone': 620 625 case 'tz': 621 $output = @$ip_data->location->timezone;626 $output = @$ip_data->timezone; 622 627 break; 623 628 }
Note: See TracChangeset
for help on using the changeset viewer.