How licensing works
OC_License is the only class that reads and writes wp_orravo_licenses and talks to OC_API. State is cached in the orravo_license_cache transient with a 6-hour TTL so repeated is_licensed() calls inside a single request are essentially free.
phpOC_License::is_licensed( 'oforms' ); // bool
OC_License::get_data(); // full license array or null
OC_License::status(); // canonical state for admin viewsAn empty products array on the row means "site-wide license," so is_licensed( $slug ) returns true for every product.
Activate / deactivate
From the admin: License tab, paste key, click Activate. From CLI:
bashwp orravo activate oa_xxxxxxxxxxxx
wp orravo deactivateAJAX endpoints (called by the admin UI):
oc_activate_keyoc_deactivate_keyoc_refresh_statusoc_transfer_licenseoc_repair_license_tableoc_reveal_keyoc_toggle_dev_site
Self-healing
On plugins_loaded, Orravo Core checks if the license table actually exists in the database. If it does not, or if oc_db_version is stale, it runs OC_DB::install() to recreate the schema. This avoids the "License Active but DB Table Missing" contradiction that previous versions could report.
Notifications
Three banners can appear: unlicensed, in grace period, and renewal upcoming. Dismiss persists per user via oc_dismiss_unlicensed_notice AJAX.

