=== DP Country Gate ===
Contributors: decisiveplugins
Donate link: https://decisiveplugins.com/
Tags: country, geoip, geolocation, block, allowlist, security, firewall, cloudflare
Requires at least: 5.2
Tested up to: 6.7
Requires PHP: 7.4
Stable tag: 1.6.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Block or allow access to your WordPress site by visitor country using Cloudflare headers, server GEOIP variables, or a lightweight remote IP API with caching.

== Description ==

DP Country Gate lets you control who can access your site based on visitor **country** — before most of WordPress loads.

You can run the plugin in either:

* **Blocklist mode** – “block these countries”
* **Allowlist mode** – “allow only these countries; block everything else”

The plugin detects visitor country using:

1. **Cloudflare**’s `CF-IPCountry` header (if you’re behind Cloudflare)
2. Common **server GEOIP** variables (e.g. `GEOIP_COUNTRY_CODE`)
3. An optional **remote lookup** via [ipapi.co](https://ipapi.co) with transient caching

You can also:

* Exempt **logged-in users**
* Exempt specific **user roles** (e.g. Administrators, Editors)
* Define **bypass paths** (e.g. `/wp-login.php`, `/wp-admin/*`, `/wp-json/*`)
* Choose the **response type** when blocking:
  * `403 Forbidden`
  * `451 Unavailable For Legal Reasons`
  * `302 Redirect` to a custom URL
* Customize the **block message** (HTML allowed)

DP Country Gate is designed as a lightweight core for country-based access control.  
The free version will always remain fully functional for standard country blocking and allowing.  
Future add-ons may extend it with advanced rules, analytics, and integrations.

= How It Works =

On each front-end request, DP Country Gate:

1. Checks if the request hits a **bypass path**  
2. Checks if the user is **logged in** or has an **exempt role**  
3. Detects the visitor’s **country code**  
4. Compares that country to your configured **blocklist** or **allowlist**  
5. If blocked:
   * Sends the chosen **HTTP status code**, and  
   * Either redirects to a URL (for 302) or shows your **block message** in a minimal error page

If the plugin cannot reliably detect a country code, it **fails open** (allows access).

= Privacy Notice =

If you enable the **Remote IP Lookup** option, visitor IP addresses are sent to the third-party service [ipapi.co](https://ipapi.co) solely for the purpose of retrieving a 2-letter country code.  
Only that country code is cached in your WordPress site using transients. No other personal data is stored by this plugin.

If you do not enable the remote lookup, DP Country Gate only uses headers and server variables already present in your environment.

== Installation ==

1. Upload the `dp-country-gate` folder to the `/wp-content/plugins/` directory, or install via the **Plugins → Add New** screen.
2. Activate the plugin via **Plugins → Installed Plugins**.
3. Go to **Settings → Country Gate** to configure:
   * Mode (blocklist or allowlist)
   * Country codes
   * Logged-in / role exemptions
   * Bypass paths
   * Remote IP lookup
   * Response status and message

== Frequently Asked Questions ==

= Does this support both blocklist and allowlist modes? =

Yes.

* In **blocklist** mode, the countries you specify are blocked, and everyone else is allowed.
* In **allowlist** mode, only the countries you specify are allowed, and everyone else is blocked.

= How do I enter country codes? =

Use a comma-separated list of **ISO 3166-1 alpha-2** country codes, for example:

`US, CA, GB, FR`

The plugin automatically uppercases and cleans up the list.

= What data sources are used for detecting the country? =

DP Country Gate checks, in this order:

1. The **Cloudflare** header `CF-IPCOUNTRY` (if present)  
2. Common **GEOIP server variables** (e.g. `GEOIP_COUNTRY_CODE`, `HTTP_X_GEOIP2_COUNTRY`)  
3. If enabled, a **remote lookup** via [ipapi.co](https://ipapi.co)

If none of these return a valid 2-letter country code, the plugin does not block the visitor.

= Do I have to use Cloudflare? =

No. The plugin will use other GEOIP headers or the optional remote IP API if Cloudflare is not present.

= What happens if the country cannot be determined? =

The plugin is designed to **fail open** (allow access) if it cannot detect a country code from Cloudflare, GEOIP variables, or the remote API (if enabled).

= Will this block access to my WordPress admin area? =

By default, the **bypass paths** setting includes entries like:

* `/wp-login.php`
* `/wp-admin/*`
* `/wp-json/*`

You can adjust this list. If you remove these defaults, then the country gate may apply to backend requests as well. Use caution and be sure to leave yourself a way in.

= Does this affect logged-in users or admins? =

By default, DP Country Gate allows all **logged-in users**. You can also specify **roles** that should always be exempt (e.g. Administrator, Editor).

If you uncheck “Allow logged-in users” and remove all exempt roles, then everyone—including admins—will be subject to the country rules.

= What are the available response types? =

You can choose how the site responds when a visitor is blocked:

* **403 Forbidden** – standard access denied response
* **451 Unavailable For Legal Reasons** – commonly used for geo/legal blocks
* **302 Redirect** – redirect the visitor to a specified URL (e.g. a legal notice or alternate site)

When using 302, you can set the **Block Redirect URL**. The plugin uses `wp_safe_redirect()` for security.

= Does the plugin clean up its settings on uninstall? =

Yes. When you uninstall (not just deactivate) the plugin from the Plugins screen, the main option `dds_country_gate_options` is deleted.

Cached country codes are stored as transients and will naturally expire over time.

= Is this plugin translation-ready? =

Yes. The plugin loads its text domain `dp-country-gate` from the `/languages` folder and wraps all user-facing strings in WordPress i18n functions. You can create translation files (`.po`, `.mo`) for your language.

== Developers ==

DP Country Gate includes a few filters so developers and add-ons (including a future Pro version) can extend its behavior:

* `dp_country_gate_options`  
  Filter the resolved options array after defaults and database values are merged.

* `dp_country_gate_detected_country`  
  Filter the detected two-letter country code before rules are applied.  
  Receives the country code and the options array.

* `dp_country_gate_should_block`  
  Filter whether the current visitor should be blocked.  
  Receives a boolean `$should_block`, the detected country code, the configured country list, and the options array.

* `dp_country_gate_block_status`  
  Filter the HTTP status code used when blocking a visitor (403, 451, or 302).

These hooks allow add-ons to add new detection methods, override decisions, or integrate with logging/analytics tools without modifying the core plugin.

== Screenshots ==

1. **Settings screen** – mode, country codes, and bypass paths.
2. **Block options** – response type, redirect URL, and custom block message.

== Changelog ==

= 1.6.1 =
* Prepared for WordPress.org repository submission
* Added full internationalization (i18n) for all user-facing strings
* Added uninstall routine to clean up plugin options on removal
* Ensured redirects use `wp_safe_redirect()` for secure blocking
* Added developer filters for options, detected country, block decisions, and status code
* Improved privacy messaging around remote IP lookup and caching

= 1.6.0 =
* Initial public release of DP Country Gate
* Blocklist / allowlist country modes
* Cloudflare + GEOIP detection
* Optional remote IP lookup with transient caching
* Bypass paths and role/logged-in exemptions
* Configurable block status and message

== Upgrade Notice ==

= 1.6.1 =
This version prepares DP Country Gate for the WordPress.org plugin repository with improved internationalization, safer redirects, developer hooks, and a clearer uninstall routine. Please review your settings—especially the Remote IP Lookup option and bypass paths—after upgrading.
