IngotForge Opening Hours Indicator displays whether your business is open or closed. Create independent schedules for multiple locations, with their own timezones, labels and appearance.
Existing [business_status] and [opening_status] shortcodes, schedule IDs, weekly hours, manual holiday closures and typography/color settings are retained. Legacy appearance remains the default. See Installation for the removal of misspelled prerelease identifiers.
Main features:
Open Opening Hours > Manual & tutorials for the complete local instructions, examples, rule priority, troubleshooting and developer reference.
External providers may require an account, a paid plan, sponsorship, attribution or a storage license. Coverage and availability are provider-specific. The plugin does not supply paid credentials, circumvent provider limits or promise compatibility with every date/time API. See External services below.
This package uses ingotforge-opening-hours-indicator as its proposed submission slug, matching the requested IngotForge spelling. The ZIP has one root folder with that name, the main plugin file is ingotforge-opening-hours-indicator.php, and all translation calls use the same domain. The translation template is languages/ingotforge-opening-hours-indicator.pot.
This package does not reserve or confirm a WordPress.org permalink. Match the exact slug shown in your submission confirmation. For an existing pending submission with a different slug, request/confirm the change through that submission rather than creating a duplicate submission. Do not change an already approved slug through a local folder rename. New internal identifiers use IFGOHI/ifgohi or the IngotForge PHP namespace. Misspelled prerelease shortcodes, namespaces, routes, events, admin-page aliases and export-format identifiers are not registered or accepted.
[business_status id=”1″]
[opening_status id=”1″]
[ingotforge_hours id=”1″ show_next=”true” live=”true”]
The current and legacy status aliases support id, show_next (default false) and live (default true). live=”false” disables status polling.
[ingotforge_schedule id=”1″ caption=”Office opening hours”]
[ingotforge_clock id=”1″ seconds=”true” format=”24″]
seconds defaults to false; format accepts 12 or 24. Invalid, missing, deleted or private schedule IDs return no output.
All integrations are optional. New and imported schedules require administrator authorization. Existing explicit provider selections are retained during the 1.x upgrade; administrators can disable authorization at any time.
Requests occur only on administrator refresh or scheduled WordPress cron. Normal shortcode/REST display does not initiate external requests. Saving configuration does not fetch a provider. Requests use WordPress’s safe HTTP API, HTTPS, certificate verification, no redirects, a five-second timeout and a 1 MB response limit.
Holiday providers receive the configured country, optional subdivision, requested year/date and applicable filtering parameters. Clock providers receive a UTC timezone identifier and the account key where required. Each operator also sees the server’s source IP, request time and plugin-version user agent. The plugin does not send visitor IPs, cookies, names, emails, page content or WordPress login data to providers. Provider keys may be transmitted in query parameters when that provider requires it; protect server/proxy logs accordingly.
Custom endpoints receive only the configured placeholders and authentication value. Do not put personal data or credentials directly into their URL. Only public HTTPS GET JSON, none/header/query/Bearer authentication and dot-separated field mappings are supported; not OAuth flows, signed requests, POST-only APIs, XML or NTP.
Responses are normalized to holiday dates or a clock correction; the raw provider response is not stored. HolidayAPI cache use is capped at 24 hours, Calendarific at 30 days, and other newly dated holiday caches at 400 days. Expired entries are ignored on reading; physical deletion runs during refresh/cron or explicit cache clearing. WP-Cron depends on traffic, so arrange reliable server cron and a backup-retention policy when your provider has deletion deadlines. Clear service caches on plan cancellation. Licenses can change; these safeguards do not replace your provider agreement.
Nager.Date / Nager.Holidays
Uses https://nagerholidays.com/api/v4/Holidays/{country}/{year}. Keyless annual holiday dates, with national/subdivision filtering. Commercial hosted-service use requires active sponsorship under current terms.
Documentation: https://nagerholidays.com/api
Terms: https://nagerholidays.com/legal/termsofservice
Privacy: https://nagerholidays.com/legal/privacy
OpenHolidays API
Uses https://openholidaysapi.org/PublicHolidays with countryIsoCode, languageIsoCode, validFrom, validTo and optional subdivisionCode. Keyless selected-country public holidays. The data is ODbL-licensed; observe attribution and other applicable data-license requirements.
Documentation: https://www.openholidaysapi.org/en/
Terms / ODbL permitted use: https://www.openholidaysapi.org/en/faq/
Operator privacy policy: https://www.stueber.de/en/legal/privacy.php
HolidayAPI-compatible configured adapter
No HolidayAPI endpoint is preconfigured or contacted automatically in this release. The administrator supplies the authorized HTTPS endpoint plus the actual terms and privacy-policy URLs from their service agreement. Missing policy information pauses requests without deleting saved schedules or keys. This avoids representing an unverified privacy URL as a verified service policy.
When enabled, this adapter sends key, country/subdivision, year and optional public filtering to that configured operator on refresh/cron. Its HolidayAPI response parser, actual/observed/both modes and 24-hour cache cap are retained. Plan coverage and storage permission must be checked with the operator. The current service documentation is https://holidayapi.com/docs (an informational link, not a runtime endpoint or substitute for operator policies).
Calendarific
Uses https://calendarific.com/api/v2/holidays with api_key, country, year, optional location and holiday type. Free/paid access is plan-dependent. Its terms require visible attribution unless your agreement waives it. Add the provider’s required credit to your About/terms or relevant page; the plugin does not inject a forced public backlink. Stored holiday data expires within 30 days of the original fetch timestamp.
Documentation: https://calendarific.com/api-documentation
Terms: https://calendarific.com/terms
Privacy: https://calendarific.com/privacy
Abstract Holidays
Uses https://holidays.abstractapi.com/v1/ with api_key, country, year and, in daily mode, month/day. Select daily mode for plans requiring a complete date. Annual mode requires a plan permitting year-only requests. Daily responses cover only checked dates, not the full year; midnight/cron gaps can occur.
Documentation: https://docs.abstractapi.com/api/holidays
Terms: https://www.abstractapi.com/legal/legal#terms
Privacy: https://www.abstractapi.com/legal/legal#privacy
API Ninjas Holidays
Uses https://api.api-ninjas.com/v2/holidays with country, year, optional type and X-Api-Key. This cache-based integration requires storage permission, currently Business or above. Free and Developer plans do not permit the plugin’s cache. An explicit account-entitlement confirmation is required before requests.
Documentation: https://api-ninjas.com/api/holidays
Plans/storage: https://api-ninjas.com/pricing
Terms: https://api-ninjas.com/tos
Privacy: https://api-ninjas.com/privacy
Enrico-compatible configured adapter
There is no default connection to Kayaposoft’s hosted Enrico service. No verified hosted-service terms/privacy URLs were established for that previous preset, so this release does not silently use it or equate its source-code license with a hosted-service policy.
The Enrico date/range parser is retained for a licensed or self-hosted Enrico-compatible HTTPS endpoint. Enter that endpoint, its real operator terms and privacy URLs, and confirm that querying/caching is permitted. The configuration is required even for an old saved Enrico selection. On refresh/cron, requests send action=getHolidaysForYear, year, country, optional region, holidayType and any configured authentication to the chosen operator. Existing manually entered holidays remain independent. Previously cached good dates are retained within their normal expiry rules.
Project/self-hosting information: https://kayaposoft.com/enrico/
Protocol reference: https://kayaposoft.com/enrico/json/v2.0/docs.php
These informational links do not cause automatic service requests and are not terms/privacy policies for the endpoint you configure. Obtain those policies from your actual operator, or choose another documented preset.
TimeAPI-compatible configured adapter
The TimeAPI dateTime parser is retained, without a default hosted endpoint. Configure the authorized HTTPS endpoint, the operator’s actual permitted-use terms and privacy-policy URLs, then confirm the policies. On refresh/cron it sends timeZone=Etc/UTC and any configured authentication to that endpoint. Separate hosted API-use terms were not verified for the former preset; a privacy document is not treated as permission to use or cache an API.
Protocol reference: https://timeapi.io/swagger/
Published website privacy information: https://www.timeapi.io/Home/Privacy
These are reference links, not a substitute for the terms and privacy URLs required for your chosen endpoint.
TimeZoneDB
Uses https://api.timezonedb.com/v2.1/get-time-zone with key, format=json, by=zone and zone=Etc/UTC. Requires a key and HTTPS-capable access. Free service is personal/non-commercial; commercial use needs premium. Observe rate limits and relevant database attribution obligations.
Documentation: https://timezonedb.com/references/get-time-zone
Terms and privacy: https://timezonedb.com/terms-of-use
API Ninjas World Time
Uses https://api.api-ninjas.com/v1/worldtime with timezone=Etc/UTC and X-Api-Key. The same storage-plan requirement and explicit confirmation apply as for API Ninjas Holidays; paid account credentials are not bundled.
Documentation: https://api-ninjas.com/api/worldtime
Plans: https://api-ninjas.com/pricing
Terms: https://api-ninjas.com/tos
Privacy: https://api-ninjas.com/privacy
IPGeolocation.io Time Zone
Uses https://api.ipgeolocation.io/v3/timezone with apiKey and tz=Etc/UTC. It does not perform visitor IP geolocation. Free access is non-commercial; obtain the license appropriate for commercial/customer-facing use.
Documentation: https://ipgeolocation.io/documentation/timezone-api.html
Terms: https://ipgeolocation.io/tos.html
Privacy: https://ipgeolocation.io/privacy.html
timezone.io WorldTime compatibility
Uses https://worldtime.timezone.io/api/timezone/Etc/UTC. This is timezone.io’s keyless compatibility service, not the retired service previously operated as WorldTimeAPI. Public-service availability is not guaranteed.
Documentation: https://www.timezone.io/docs/worldtimeapi
Terms: https://www.timezone.io/legal/terms
Privacy: https://www.timezone.io/legal/privacy
Custom holiday or clock service
There is no preselected custom service. An administrator supplies the public HTTPS GET URL, JSON field mappings, authentication mode, actual operator terms and privacy URLs, and explicitly confirms authorization plus permitted caching. The plugin stores those policy links locally and shows them in the schedule editor; it does not fetch or certify the policy documents. Display the chosen provider and links in your own site privacy notice where appropriate. Do not invent policy links or use a documentation page instead. A self-hosted endpoint needs the real operator’s policies too.
The endpoint receives the literal administrator-supplied URL parameters, expanded {year}, {country}, {region}, {date} or {timezone} placeholders and the selected authentication value. Only holiday requests supply a year/date; clock timezone is Etc/UTC. The configured operator also receives the server IP, request time and plugin user agent. No visitor data is added by the plugin. Requests occur only after authorization on refresh/cron. API keys use separate encrypted fields. Changing an endpoint clears its old credential; imports and duplicates reset policy confirmation and authorization.
Placeholder URLs using example.com in the manual or field hints are fictional examples, not providers, active endpoints, policies or accounts. JSON adapters do not support OAuth, signed requests, POST-only endpoints, XML or NTP.
The plugin does not collect visitor profiles, analytics or telemetry, and does not set tracking cookies. It stores business schedules, appearance settings, encrypted credentials where supported, normalized service caches and refresh state in your WordPress database. Public schedules expose their display status, colors and timezone through a read-only endpoint; set a schedule private to remove its public output.
Suggested site privacy-policy text (adapt to your actual services):
“Our opening-hours display uses the schedules configured on this website. It can refresh displayed status through our own website. Where we enable an external holiday or clock provider, our server sends that provider the configured country/date or UTC timezone and our service credential. The plugin does not send visitors’ personal details or visitor IP addresses to those providers. Providers and our hosting infrastructure may independently retain ordinary request logs.”
This wording is a starting point, not a statement about other plugins, your hosting logs, a custom endpoint or a provider’s own practices.
Use the IngotForge\OpeningHours namespace, IFGOHI_VERSION / IFGOHI_PATH / IFGOHI_URL constants and ifgohi-prefixed declarations. The former global OHI_* aliases and ohi_run_plugin() are intentionally no longer declared: their three-letter prefix was flagged in review. Replace OHI_VERSION/PATH/URL with IFGOHI_VERSION/PATH/URL; replace ohi_run_plugin() with IngotForge\OpeningHours\Plugin::boot(). Replace OHI_Frontend, OHI_Core, OHI_Activator, OHI_API and OHI_Admin with the corresponding namespaced LegacyFrontend, LegacyCore, LegacyActivator, LegacyAPI and LegacyAdmin classes. Do not expose raw rows, which include protected credentials.
Only the IngotForge\OpeningHours PHP namespace is provided. Branded shortcodes are ingotforge_hours, ingotforge_schedule and ingotforge_clock. The original business_status and opening_status tags remain supported; registration does not overwrite a tag already owned by another plugin. The REST namespace is ingotforge-hours/v1 and the browser refresh event is ingotforge:hours:refresh. There are no misspelled prerelease aliases. The timetable and clock attribute filters are shortcode_atts_ingotforge_schedule and shortcode_atts_ingotforge_clock; the status renderer retains its original shortcode_atts_business_status filter. Update custom integrations that used the retired spellings.
Export and import use the ingotforge-opening-hours format identifier with schema 1. For an older export bearing a misspelled format identifier, back up the JSON file and correct only its top-level format value to ingotforge-opening-hours before importing. The schedules payload is unchanged, imports still create new IDs and omit credentials, and same-site upgrades do not require an import.
The active table is now {$wpdb->prefix}ifgohi_schedules. Read its name through Store::table(), not a hardcoded name. The administrative page is ingotforge-opening-hours-indicator; all command actions and nonces use ifgohi_. Reload old editor forms after upgrading. Read-only bookmarks using the original opening-hours-indicator page are redirected, never executed as write commands. Misspelled prerelease bookmarks must be replaced.
There are no public write endpoints, remote executable libraries or bundled third-party JavaScript dependencies. All distributed source files are readable and editable. The plugin code is GPLv2-or-later; provider data/account terms are separate.