=== EMM Multi Sport Schedule ===
Contributors: endurancemultimedia
Tags: sports, schedule, calendar, fixtures, live scores
Requires at least: 5.8
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.28.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Displays an auto-updating sports schedule on your site, with visitor email subscriptions and full style customization.

== Description ==

EMM Multi Sport Schedule shows an always-current schedule of upcoming sports fixtures on your WordPress site — perfect for sports bars, fan sites, and hospitality venues that want to let visitors know what's on and when.

**Key features**

* Choose from a wide range of sports and leagues
* Light and dark themes, with per-element font and color customization
* Configurable opening hours — only show events during the times your venue is actually open
* Boxing broadcaster filtering — only show boxing events available on the broadcasters you select
* Tennis (ATP and WTA) with the tour and draw shown on every item (e.g. "Men's Singles"), tournaments listed across every day they run, and match times shown only once they're confirmed
* A Tennis Settings tab to choose how many individual tennis matches are listed: quarterfinals onward, or also the next 2 days of confirmed matches
* Events that have a date but no known start time show "All day" or "TBA" instead of a guessed time
* A separate time filter for boxing — boxing cards often start outside normal opening hours, so boxing is exempt from the general opening hours and can have its own window instead
* Visitors can subscribe to a daily or weekly email digest of upcoming events for their chosen sports
* Native Gutenberg block and Elementor widget, in addition to a simple shortcode
* 1 sport free forever — no license key, no credit card, no expiration; purchase a license for 5, 10, or unlimited sports

= How it works =

All of the plugin's code — the settings screens, the shortcode, the block, the Elementor widget, and the calendar display itself (including the "Get schedule by email" sign-up form) — is included in this plugin. The schedule data it displays is retrieved from the Sports Schedule Pro Hub, a data service operated by Endurance Multimedia. 1 sport is available permanently free of charge with no license key; a paid license is required for 5, 10, or unlimited sports. See "External services" below for exactly what is sent and why.

== External services ==

**1. Sports Schedule Pro Hub (required)**

This plugin connects to an external API operated by Endurance Multimedia, the "Sports Schedule Pro Hub", at https://endurancemultimedia.com, in order to retrieve sports schedule data. The service gathers fixtures from third-party sports data sources, caches them, and returns them to your site. Schedule data cannot be displayed without it.

What is sent, and when:

* Whenever a page containing the calendar is viewed, the visitor's browser requests schedule data from the service. The request includes your site's URL and your license key (or an empty key on the free 1-sport tier), so the service can validate the license and return the right data. The settings screen makes the same kind of request to list the sports available to your license, and when you click "Test connection". When a calendar is displayed, your site's server also asks the service for that list of available sports (so newly added sports work without a plugin update); the result is stored on your site for up to 6 hours, so this happens only a few times a day per site, not once per visitor.
* No visitor personal data is included in these schedule requests.

**2. Email schedule sign-up (optional, visitor-initiated)**

The calendar includes an optional "Get schedule by email" form. The form and its code are part of this plugin (see `assets/calendar.js`, functions `openSubscribeModal` and its submit handler). Nothing is sent unless a visitor fills in the form and submits it. When they do, the visitor's email address, chosen sports, delivery frequency (daily or weekly), the schedule's timezone offset, and your site's URL and name are sent to the same service (the `/wp-json/sports-relay/v1/subscribe` endpoint). The service stores them, sends a confirmation email, and — only after the visitor confirms — sends the digest emails and an unsubscribe link in each one. Sending scheduled email is performed by the service rather than by your WordPress site.

**3. Google Fonts (font files only)**

The calendar loads font files (Montserrat by default, plus any fonts you choose in the Style tab) from Google Fonts at fonts.googleapis.com, so visitors' browsers request those files directly from Google. No other Google service is used. Google's terms: https://policies.google.com/terms — privacy policy: https://policies.google.com/privacy

**4. Credit link (optional, off by default)**

If — and only if — you tick "Show credit link" in the plugin's Display settings, a small "Powered by Endurance Multimedia" link to https://endurancemultimedia.com is shown below the calendar. It is never shown by default.

The Sports Schedule Pro Hub's terms of use and privacy policy are available at: https://endurancemultimedia.com/plugin-privacy-policy/

== Installation ==

1. Upload the plugin files to `/wp-content/plugins/emm-multi-sport-schedule`, or install directly through the WordPress plugins screen.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Go to EMM Multi Sport Schedule in your WordPress admin menu.
4. Leave the license key blank to use the free tier (1 sport, no expiration), or enter a purchased license key for 5, 10, or unlimited sports.
5. Select which sports to display under "Sports to display".
6. Add the `[emms_schedule_calendar]` shortcode to any page or post, or use the Sports Schedule Calendar block/widget.

== Frequently Asked Questions ==

= Do I need a license key to use this plugin? =

No — leaving the license key field blank runs the plugin on a permanent free tier covering 1 sport, with no expiration. A license key is only required if you want more than 1 sport (5, 10, or unlimited).

= Where do I get a license key? =

https://endurancemultimedia.com/product/emm-multi-sport-schedule/

= Can I change which sports are shown? =

Yes, under EMM Multi Sport Schedule → Sports to display.

= Does this plugin track my visitors? =

Only if a visitor voluntarily uses the "Get schedule by email" feature, in which case their email address and sport preferences are sent to the Sports Schedule Pro Hub service in order to deliver the emails they've requested. See "External services" above for full detail, and https://endurancemultimedia.com/plugin-privacy-policy/ for our full privacy policy.

== Screenshots ==

1. The sports schedule calendar in dark theme, with the sport filter dropdown open.
2. The sports schedule calendar in light theme.
3. The Sports to display settings tab.
4. The Display Settings tab, showing the default theme, timezone, opening hours, and disclaimer text options.
5. The Style tab, showing font and color customization options.

== Disclaimer ==

The schedule and event information displayed by this plugin is provided for general informational and entertainment purposes only. While every effort is made to keep this information accurate and up to date, sports schedules, fixtures, and event details are subject to change at any time — including last-minute postponements, cancellations, rescheduling, and venue changes — often with little or no advance notice from the organizations involved.

We make no warranties or guarantees, express or implied, regarding the accuracy, completeness, timeliness, or reliability of any schedule data shown. No responsibility or liability is accepted for any loss, damage, or financial harm — including but not limited to lost income, wasted travel, missed events, or losses arising from betting or wagering activity — resulting from reliance on this information.

Users should independently verify all schedule information against official league, team, venue, or broadcaster sources before making any plans, purchases, bookings, or financial decisions.

== Changelog ==

= 1.28.0 =
* Team badges for the football leagues that now come from UEFA's and ESPN's own data (the Champions League, Europa League, Nations League, Premier League, Scottish Premiership, Bundesliga, Ligue 1, Serie A, LaLiga and MLS): UEFA's own crests and flags, and ESPN's logos. The calendar only displays badge images from TheSportsDB, UEFA and ESPN, in their exact expected address forms, and sizes only TheSportsDB's.

= 1.27.0 =
* The Premier League, Scottish Premiership, Bundesliga, Ligue 1, Serie A, LaLiga and Major League Soccer now take their schedules and results from ESPN's scoreboard data instead of TheSportsDB. A finished match shows its final score in place of "Vs", like rugby, and a fixture whose kick-off time has not been confirmed shows as an all-day "TBA" entry on its date instead of a made-up time. A match decided by a penalty shootout or extra time says so under the score.

= 1.26.0 =
* The UEFA Champions League, Europa League and Nations League now take their schedules and results from UEFA's own match feed. A finished match shows its final score in place of "Vs", like rugby, with a line under it for extra time, a penalty shootout ("Paris win 4-3 on penalties") or the aggregate of a two-legged tie, and stays for three hours after it finishes (longer after extra time or penalties).

= 1.25.0 =
* All cricket (Test, One Day International, Twenty20 International, Big Bash League and International League T20) now comes from the ICC's own schedule feed. A finished match stays on the calendar for three hours after it ends, with its result shown under it, such as "Qatar beat Bhutan by 9 wickets". A Test that ends early shows the result on the day it ended.

= 1.24.0 =
* One Day International and Twenty20 International series, the Big Bash League and the International League T20 now take their schedules from the ICC's own schedule feed and from ESPN's cricket data instead of TheSportsDB, with team logos from TheSportsDB. Each match is one entry, such as "Afghanistan v Zimbabwe, 3rd T20I", with its series and venue; a match whose time isn't confirmed shows as TBA.
* A match that has started now stays on the calendar for as long as it is played (about 8 hours for an ODI, 4 for a T20) instead of disappearing 2 hours after its start.

= 1.23.0 =
* Formula 1, the FIM Superbike World Championship, the British Superbike Championship and the World Rally Championship now take their calendars and session times from each series' own official source instead of TheSportsDB. Every session is its own timed entry, such as "Singapore: Sprint Qualifying" or "Estoril: Superpole Race"; rallies show the shakedown, the first stage of each day and the Power Stage, or an all-day line until the itinerary is published. No setup is needed; your selections carry over.
* The sports list built into the calendar script was refreshed to match.

= 1.22.4 =
* Finished matches now follow the Opening hours setting like every other event: a match that kicked off outside your opening hours (for example 1:45 AM) is no longer shown, even with its final score. This reverses a change made in 1.22.2.
* A finished match that shows its final score is now removed three hours after it finishes (previously it stayed for a day). The service doesn't say when a match ended, so "finished" is taken as the kick-off plus two hours.

= 1.22.3 =
* The competition badge no longer repeats the sport name. Under "United Rugby Championship" the badge now reads just "League" (or "Round 3", "Semi-Finals" and so on) instead of "United Rugby Championship · League"; the same applies to "Premiership Rugby" and any other sport whose badge begins with its own name.

= 1.22.2 =
* Fixed: on a site using the Opening hours setting, finished matches never appeared, because a match that kicked off outside the opening hours (for example a 7:45 PM UK kick-off, which is 1:45 AM in Vietnam) was filtered out along with the upcoming ones. A finished match that shows its final score is now exempt from the opening hours, since a result is worth seeing whenever the match was played. Upcoming matches are still filtered as before.

= 1.22.1 =
* Fixed: when a finished match showed its final score in place of "Vs", the score overlapped the team names and logos. The score now has room of its own. On phones the team logos scale down a little and long names wrap, so even a three-digit score fits on a narrow screen.

= 1.22.0 =
* Every league now appears under its official name, on each schedule row, in the sport filter and in the Sports To Display list: for example "Supercars Championship" (was "V8 Supercars"), "United Rugby Championship", "Premiership Rugby", "Bundesliga", "Ligue 1", "Serie A", "LaLiga", "PGA Tour", "UCI World Tour", "Big Bash League" and "World Rally Championship". Sponsor names are left out, since they change; leagues whose official name is an acronym (NBA, NFL, NRL, AFL, UFC...) keep it. Your saved choices and licences are not affected.
* The competition badge uses official names too ("United Rugby Championship", "Six Nations Championship", "ATP Tour & WTA Tour"). A badge that would only repeat the sport name is no longer shown.

= 1.21.0 =
* Rugby union (English Premiership, United Rugby Championship, Rugby Union internationals, Rugby Nations, Pacific Nations Cup and the Women's Rugby World Cup) now takes its fixtures from World Rugby's official data instead of TheSportsDB. Each match shows the competition (for example "Nations Championship" or "Bledisloe Cup") with the venue and city, and team logos are kept. NRL is unchanged.
* A completed rugby match now shows its final score in place of "Vs" and stays on the calendar for a day.
* Matches involving A teams, XV sides, the Barbarians, the Maori All Blacks or "Emerging" sides carry a small "A/XV" badge. A new setting under Display Settings, "Rugby: hide A-team / XV matches" (off by default), removes them.
* The sports list built into the calendar script was refreshed to match.

= 1.20.4 =
* Supercars now takes its calendar and track schedule from the Supercars website itself instead of TheSportsDB. Each session — practice, qualifying, Top Ten Shootout, warm up and race — is its own timed entry, such as "Gold Coast: Race 31", with the broadcasters listed. A round whose timetable isn't published yet shows as an all-day line. No setup needed; your Supercars selection carries over.
* The sports list built into the calendar script was refreshed to match.

= 1.20.3 =
* MotoGP now takes its calendar and session times from the official MotoGP source instead of TheSportsDB, so session times are correct (the old source had some a whole hour out, and Free Practice 2 listed after Qualifying 1). Each session — Free Practice, Practice, Qualifying 1 and 2, Sprint, Warm Up and Race — is its own timed entry, such as "Indonesia: Sprint". A weekend whose timetable hasn't been published yet shows as an all-day line. No setup needed; your MotoGP selection carries over.
* The sports list built into the calendar script was refreshed to match.

= 1.20.2 =
* Fixed: a sport the service added after the plugin was installed (for example WTA Tour, Test Cricket or International League T20) could be ticked under Sports To Display yet be missing from the calendar and its Sport filter, on sites where the service was slow to answer. The plugin now asks the service for its sports list through a quick dedicated route with a longer timeout, refreshes a stored list that doesn't know a sport you've ticked, and refreshes it whenever you open the settings page.
* The sports list built into the calendar script (used only if the service can't be reached at all) was brought up to date. It still had "ATP World Tour" and "ICC Cricket" and lacked WTA Tour, Test Cricket and International League T20.
* After updating, clear any page cache (a caching plugin or Cloudflare): cached pages keep the sports list they were built with.

= 1.20.1 =
* Fixed: clicking the Tennis Settings tab took you back to Sports To Display instead of opening it.

= 1.20.0 =
* New "Tennis Settings" tab, after Boxing Settings, to choose how many individual tennis matches are listed for ATP Tour and WTA Tour. Option 1: quarterfinals onward (player names only for the quarterfinals, semifinals and finals). Option 2: confirmed matches in the next 2 days, plus quarterfinals onward, with a checkbox to include doubles. Tournaments always appear as an all-day line on every day they run, whichever option you choose.
* Behaviour change on update: tennis now defaults to Option 1, which lists the fewest events. If you were seeing early-round matches listed, choose Option 2 in Tennis Settings. (Requires the matching service update, which is released together with this version; against an older service, nothing is hidden.)

= 1.19.1 =
* Long labels on an event (such as a cricket series name — "Australia tour of South Africa 2026/27 – 1st Test · Day 2") now wrap neatly instead of stretching the row. On phones the label sits on its own line inside the sport pill rather than running off the edge of the card.
* The service now also offers Test Cricket (international Tests, shown across every day of the match). It appears in the Sports to display list automatically — no setup needed.

= 1.19.0 =
* Tennis now covers both tours: "ATP Tour" and a new "WTA Tour" sport. Schedule data comes from the service, which now reads it from ESPN. WTA Tour appears in the Sports to display list automatically.
* Every tennis item shows a small badge for its tour or draw (e.g. "Men's Singles", "Women's Doubles", or "ATP & WTA" on events that run both tours).
* Tournaments are listed on every day they run, as all-day events. Individual matches are listed from the quarterfinals onward, with their real start time once it is confirmed and "TBA" until then.
* Events from any sport that have a date but no known start time now show "All day" or "TBA" instead of a made-up time (previously these showed a misleading 7:00 AM). They also ignore the opening-hours filters, since there is no time of day to compare, and are no longer shifted by timezone.

= 1.18.0 =
* Boxing now has its own time filter, separate from the general opening hours. Boxing cards often start well outside a venue's normal hours even when the main event is later, so boxing is no longer affected by the opening hours in Display Settings. Set an optional boxing-only window on the Boxing Settings tab instead (supports windows that cross midnight). With no boxing window set, boxing shows at any time.
* The "Boxing Broadcasters" settings tab is now called "Boxing Settings", and holds both the broadcaster filter and the new boxing time filter.
* Behaviour change on update: sites that used the general opening hours previously had boxing filtered by them too. Boxing will now show at all times until a boxing window is set on the Boxing Settings tab.

= 1.17.1 =
* Added "Kayo" to the boxing broadcaster filter (Settings → Boxing Broadcasters), so Australian boxing events shown on Kayo can be selected. Sites that already use the broadcaster filter will keep hiding Kayo events until they tick it.

= 1.17.0 =
* Addressed WordPress.org plugin review feedback: the calendar's front-end script (which contains the "Get schedule by email" sign-up form) is now bundled inside the plugin as `assets/calendar.js` instead of being loaded from the service's server. The plugin's code is now entirely contained in the plugin; only schedule data and email sign-ups are exchanged with the service.
* The calendar now takes its list of available sports from the service's catalog (cached on your site for up to 6 hours), so sports added to the service appear without a plugin update. The list bundled in the script remains as an offline fallback.
* The "Powered by Endurance Multimedia" credit link under the calendar is now opt-in (new "Show credit link" checkbox in Display settings, off by default). Previously it was always shown.
* Renamed the calendar script's global (`EMMSScheduleCalendar`) and CSS class prefix (`emmscal-`) to match this plugin's unique prefix. Visitors' saved light/dark theme preference resets once as a result.
* Expanded the readme's "External services" section: exact service address, the email sign-up flow and where its code lives, and the Google Fonts disclosure.

= 1.16.0 =
* Addressed WordPress.org plugin review feedback. This is a clean break with no backward compatibility for old names — both live installs will be fully reinstalled, so nothing needed to keep working unchanged.
* Renamed every internal PHP function/class/option/define/nonce/transient name from the old "ssd"/"SSD_" prefix (3 characters — too short/generic per review guidelines) to "emms"/"EMMS_" throughout the codebase, to avoid naming collisions with other plugins.
* Renamed the shortcode tags: `[sport_schedule_calendar]` → `[emms_schedule_calendar]`, `[sports_schedule]` → `[emms_schedule]`. Also renamed the Gutenberg block's internal type (`ssd/calendar` → `emms/calendar`) and the Elementor widget's internal type (`ssd_calendar` → `emms_calendar`). Any page using the old shortcodes, block, or widget will need those re-added after updating.
* Replaced 4 raw `<script>` tags in the settings page with properly registered/enqueued scripts via `wp_register_script()` and `wp_add_inline_script()`, as required by the review — no behavior change for 3 of the 4; the 4th (the "Vs" image uploader) no longer waits on a `DOMContentLoaded` listener that would never fire once the script moved to the page footer, and runs immediately instead, which is the correct equivalent for a footer-placed script.

= 1.15.0 =
* Renamed the plugin from "Sports Schedule Pro" to "EMM Multi Sport Schedule" — the previous name was rejected on WordPress.org submission as too generic. Slug, main plugin file, and Text Domain all changed together (sports-schedule-pro → emm-multi-sport-schedule) to match. WordPress will treat this as a new plugin install — deactivate and delete the old "Sports Schedule Pro" install first, then install this one. All settings carry over automatically (they're stored independently of the plugin folder name), so nothing needs reconfiguring.
* Corrected outdated "Sports Pro Relay Hub" references in this readme to the hub's current name, "Sports Schedule Pro Hub".

= 1.14.3 =
* Added a Text Domain header (sports-schedule-pro), matching the plugin slug as required for WordPress.org submission.

= 1.14.2 =
* Updated the calendar script's source path to match the relay hub's own rename (to "Sports Schedule Pro Hub"). Requires the matching hub update to be installed — the two are released together.

= 1.14.1 =
* Renamed the plugin folder and main file to sports-schedule-pro, matching the display name. WordPress will treat this as a new plugin install — deactivate and delete the old "Sports Pro Schedule Display" install first, then install this one. All settings carry over automatically (they're stored independently of the plugin folder name), so nothing needs reconfiguring.

= 1.14.0 =
* Renamed the plugin from "Sports Pro Schedule Display" to "Sports Schedule Pro" for consistency with its product/purchase page branding. Purely a display-name change — settings, options, and shortcodes are unaffected.

= 1.13.0 =
* Replaced the 7-day free trial with a permanent free tier: 1 sport is now free forever, with no license key and no expiration. Paid licenses (5, 10, or unlimited sports) are unchanged.

= 1.9.1 =
* Fixed a bug preventing the Boxing Broadcasters settings tab from loading.

= 1.9.0 =
* Added Boxing Broadcasters filtering.

= 1.8.0 =
* Added free 7-day trial mode (no license key required to start).

= 1.7.1 =
* Added configurable opening hours filtering.

= 1.0.0 =
* Initial release.

== Upgrade Notice ==

= 1.28.0 =
Football team badges from UEFA and ESPN.

= 1.27.0 =
Seven domestic football leagues now show final scores, and unconfirmed kick-offs show as TBA.

= 1.26.0 =
UEFA competitions now show final scores like rugby, from UEFA's own feed.

= 1.25.0 =
Cricket results now show for three hours after a match ends, and all cricket uses one official source.

= 1.24.0 =
ODI, T20I, Big Bash and ILT20 now use official schedules, and a match in progress stays on the calendar.

= 1.23.0 =
F1, WorldSBK, British Superbikes and WRC now use each series' official schedule, with every session as its own entry.

= 1.22.4 =
Finished matches now respect your opening hours and disappear three hours after they finish.

= 1.22.3 =
Badges no longer repeat the sport name, e.g. 'League' instead of 'United Rugby Championship · League'.

= 1.22.2 =
Finished matches with a final score are no longer hidden by the Opening hours setting.

= 1.22.1 =
Fixes the final score overlapping the team names and logos on finished matches.

= 1.22.0 =
Leagues now show their official names (e.g. Supercars Championship, United Rugby Championship, Serie A). Your settings are unchanged.

= 1.21.0 =
Rugby union now uses World Rugby's official fixtures: competition names, venues, final scores and an A/XV badge, with a new option to hide A/XV matches.

= 1.20.4 =
Supercars now uses the Supercars website's own schedule: each session its own entry (e.g. Race 31), with broadcasters. No action needed.

= 1.20.3 =
MotoGP now uses the official source: correct session times, each session its own entry (e.g. Sprint, Race). No action needed.

= 1.20.2 =
Fixes newly added sports (WTA Tour, Test Cricket...) missing from the calendar when the schedule service is slow. Clear your page cache after updating.

= 1.20.1 =
Fixes the Tennis Settings tab, which sent you back to Sports To Display when clicked.

= 1.20.0 =
New Tennis Settings tab. Tennis now lists quarterfinals onward by default; choose "Next 2 days, plus quarterfinals onward" there if you want early-round matches shown as well.

= 1.19.1 =
Fixes long event labels overflowing on phones. Test Cricket is now available in the Sports to display list.

= 1.19.0 =
Adds WTA Tour and moves ATP to a better data source. Tennis items now show a tour/draw badge, and events with no known start time show "All day" or "TBA" instead of a guessed time.

= 1.18.0 =
Boxing is no longer limited by the general opening hours. It now has its own optional time window on the renamed Boxing Settings tab. Until you set one, boxing shows at all times.

= 1.17.1 =
Adds Kayo to the boxing broadcaster filter. If you filter boxing by broadcaster, tick Kayo under Boxing Broadcasters to show those events.

= 1.17.0 =
The calendar script now ships inside the plugin instead of loading from a remote server, and the "Powered by" credit link is now off by default (enable it under Display settings if you want it). No other action needed.

= 1.16.0 =
Shortcode, block, and widget names all changed (e.g. [sport_schedule_calendar] -> [emms_schedule_calendar]) with no backward compatibility. Re-add the shortcode/block/widget on any page using the old names after updating.

= 1.15.0 =
Renamed to "EMM Multi Sport Schedule" (new slug) — WordPress treats this as a new install. Delete the old plugin folder entirely, then install this one; your settings carry over automatically.

= 1.13.0 =
The 7-day trial is gone, replaced by a permanent free tier: 1 sport, no license key, no expiration. If you were relying on the old trial's unlimited-sports access, you'll need a paid license to keep more than 1 sport after updating.

= 1.9.1 =
Fixes the Boxing Broadcasters tab not loading. Recommended update for all users.
