=== RacerPacer Clubs ===
Contributors: racerpacer
Tags: clubs, running, link in bio, directory, community
Requires at least: 6.3
Tested up to: 7.1
Requires PHP: 8.0
Stable tag: 1.7.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Free link-page style pages for running clubs: an owner signs up, an admin approves, and each club gets its own address on the site.

== Description ==

Each club gets a single page at `/<club-name>/` with its logo, a short description, links, social accounts, weekly meet-ups and an optional GPX route per meet-up.

* **Sign-up** at `/join/`. Owners get the `club_owner` role and one club per account. New clubs start as pending until an admin approves them under Clubs.
* **Owners never see wp-admin.** They edit their club at `/my-club/`: details, links, meet-ups, routes, logo and a colour theme.
* **Uploads are limited on purpose.** The logo is the only image (JPG, PNG or WebP, no SVG, re-encoded to 512px). Each meet-up can carry one GPX route, parsed once on upload for distance, climb and an elevation profile.
* **Addresses can change.** Owners pick their address at sign-up and can change it later. Old addresses redirect to the new one and stay reserved for that club.
* **Spam protection** with a honeypot, a timing token and per-IP limits, plus optional Cloudflare Turnstile.
* **Reporting.** Every club page links to a report form that emails the notification address set in Clubs → Settings.
* **Directory and SEO.** A club directory, a sitemap entry per approved club, and a share image per club.

Club pages are standalone documents. They don't use the active theme, so they look the same whatever theme is installed.

== Installation ==

1. Upload the `racerpacer-clubs` folder to `/wp-content/plugins/` and activate it.
2. Go to Clubs → Settings and press **Create pages** to add the join, dashboard and report pages.
3. Optional: fill in the Turnstile keys and the analytics fields under Clubs → Settings.
4. Visit `/join/` to sign up a first club, then approve it under Clubs.

== Frequently Asked Questions ==

= Can owners upload photos? =

No. The logo is the only image, to keep copyright questions off the site. GPX routes are data, not artwork.

= Can I switch routes off? =

Yes. Clubs → Settings → Routes turns the feature off, and with it the only request a club page makes to another server.

= Can I change the name at the bottom of emails? =

Yes. Emails are signed with the Site Title. To use a person's name instead:

    add_filter( 'racerpacer_clubs_email_signoff', function () {
        return "Sam\nNorthfell Trail Runners";
    } );

= What does deleting the plugin remove? =

The clubs, their logos and GPX routes, the plugin's settings, the club_owner role and the club-logos, club-routes and club-og upload folders. Owner accounts stay (with no role), and so do the Terms and Privacy pages.

== External services ==

The plugin works without any of these. Each one is used only when stated.

= OpenFreeMap (map tiles) =

When a visitor opens a meet-up's route on a club page, the map loads its style and tiles from OpenFreeMap (`tiles.openfreemap.org`). The browser sends the usual request data (IP address, user agent, the map area being viewed). Nothing is requested until the visitor opens a route, and Clubs → Settings → Routes turns the feature off. The style URL can be changed in the same place. MapLibre GL, which draws the map, is bundled with the plugin and loads nothing from elsewhere.
Terms: https://openfreemap.org/tos/ · Privacy: https://openfreemap.org/privacy/

= Cloudflare Turnstile (spam check) =

Off unless a site key and secret key are entered under Clubs → Settings. When on, the join, dashboard and report forms load Cloudflare's challenge script from `challenges.cloudflare.com`, and on submit the plugin sends the challenge token and the visitor's IP address to Cloudflare to verify it. Cloudflare requires the script to be loaded from its own servers.
Terms: https://www.cloudflare.com/website-terms/ · Privacy: https://www.cloudflare.com/privacypolicy/

= Cloudflare Web Analytics =

Off unless a beacon token is entered under Clubs → Settings. When on, every page (including club pages) loads `static.cloudflareinsights.com/beacon.min.js`, which reports page views and performance timings to Cloudflare. It sets no cookies.
Terms: https://www.cloudflare.com/website-terms/ · Privacy: https://www.cloudflare.com/privacypolicy/

= Google Analytics 4 =

Off unless a measurement ID is entered under Clubs → Settings, and only loaded when the Working Detail Cookies plugin is active to hold it back until the visitor accepts the Analytics category. It is never loaded on club pages. When allowed, the page loads `www.googletagmanager.com/gtag/js` and sends page views to Google with IP anonymisation on.
Terms: https://marketingplatform.google.com/about/analytics/terms/us/ · Privacy: https://policies.google.com/privacy

== Changelog ==

= 1.7.0 =
* Ready for other sites: the site name comes from Settings → General → Site Title, every contact address from the notification email in Clubs → Settings, and emails are signed with the site name (change it with the `racerpacer_clubs_email_signoff` filter).
* The test club button creates "Test Club", owned by a "+club" alias of the admin email. Change it with the `racerpacer_clubs_seed_club` filter.
* uninstall.php: deleting the plugin removes the clubs, their logos and routes, the plugin's settings, the club_owner role and the upload folders. User accounts and the Terms and Privacy pages are kept.

= 1.6.0 =
* **Breaking for custom code:** filters, actions and constants now use the full `racerpacer_clubs_` / `RACERPACER_CLUBS_` prefix (three-letter prefixes fail the WordPress coding standards). `rpc_club_types` becomes `racerpacer_clubs_club_types`, and so on for `pace_units`, `routes_enabled`, `gpx_max_bytes`, `map_style_url`, `map_credit`, `club_saved`, `club_slug_changed` and `logo_changed`; `RPC_VERSION`/`RPC_DIR`/`RPC_URL`/`RPC_FILE` likewise. Stored data, shortcodes and CSS classes are unchanged.
* Listens for the Working Detail Cookies 1.2.0 filter name.

= 1.5.1 =
* Plugin Check fixes: uploads through `wp_handle_upload()`, files removed with `wp_delete_file()`, the club page's own CSS and JS registered and printed by handle, analytics tags printed with `wp_print_script_tag()`, input sanitised where it is read.
* The wp_head clean-up (emoji, generator, RSD, shortlink) moved here from the theme.
* Bundled the SIL Open Font License texts for Epunda Sans and Epunda Slab.

= 1.5.0 =
* GPX routes per meet-up, with a map and an elevation profile.
