WordPress Integration (3-Class)
The standard integration bundles three PHP files with your plugin or theme. Each class handles a single responsibility: license operations, admin UI, and automatic updates.
Files
Copy the following three files into your plugin or theme (typically inside an includes/ directory):
| File | Class | Purpose |
|---|---|---|
class-wplf-client.php |
WPLF_Client |
Core license API: activate, deactivate, validate, feature checks, caching |
class-wplf-client-admin.php |
WPLF_Client_Admin |
WordPress admin page with license input, status display, and notices |
class-wplf-client-updater.php |
WPLF_Client_Updater |
Hooks into WordPress update transient for automatic plugin/theme updates |
Initialization
Include all three files and instantiate them in your plugin's main file. The WPLF_Client constructor accepts either positional arguments or an associative array.
Positional arguments
require_once __DIR__ . '/includes/class-wplf-client.php';
require_once __DIR__ . '/includes/class-wplf-client-admin.php';
require_once __DIR__ . '/includes/class-wplf-client-updater.php';
$client = new WPLF_Client( 'my-plugin', 'https://licences.example.com', __FILE__ );
$admin = new WPLF_Client_Admin( $client );
$updater = new WPLF_Client_Updater( $client );
| Parameter | Type | Description |
|---|---|---|
$product_slug |
string | The product slug as defined in your LicenceForge dashboard. |
$api_url |
string | Base URL of your LicenceForge installation (no trailing slash). |
$plugin_file |
string | Full path to the main plugin file. Pass __FILE__ from the plugin's root file. |
Array configuration
For additional options, pass an associative array as the sole argument:
$client = new WPLF_Client( [
'product_slug' => 'my-plugin',
'api_url' => 'https://licences.example.com',
'plugin_file' => __FILE__,
'cache_duration' => 7200, // Optional. Default: 3600 (1 hour).
'api_key' => 'lf_pk_abc123', // Optional. Required if server enforces API key auth.
] );
| Key | Type | Default | Description |
|---|---|---|---|
product_slug |
string | — | Required. Product slug from LicenceForge. |
api_url |
string | — | Required. Base URL of your LicenceForge server. |
plugin_file |
string | — | Required. Absolute path to the main plugin or theme file. |
cache_duration |
int | 3600 |
Seconds to cache the validation result in a WordPress transient. |
api_key |
string | null |
Public API key. Sent as X-LicenceForge-Key header. Required only if the server has Require API Key enabled. |
Note
The cache_duration controls how often the client re-validates the license with your server. Lower values increase API traffic but detect revocations faster. For most products, the 3600-second default strikes a good balance.
WPLF_Client methods
The core class provides the following public methods:
License operations
| Method | Returns | Description |
|---|---|---|
get_license_key() |
string|null |
Returns the stored license key, or null if no key has been entered. |
set_license_key( $key ) |
void |
Stores the license key in a WordPress option. Does not activate it. |
activate() |
array|WP_Error |
Sends an activation request to the server for the current site URL. |
deactivate() |
array|WP_Error |
Sends a deactivation request, freeing the activation slot. |
validate( $force = false ) |
array|WP_Error |
Validates the license. Returns cached result unless $force is true or the cache has expired. |
is_active() |
bool |
Returns true if the license is valid and active. Uses cached validation. |
clear_cache() |
void |
Deletes the cached validation transient, forcing a fresh check on next call. |
get_license_info() |
array|null |
Returns the full cached license data array, or null if unavailable. |
mask_key( $key ) |
string |
Masks a key for display, e.g. ****-****-****-7FGH. |
Feature and tier methods
| Method | Returns | Description |
|---|---|---|
has_feature( $slug ) |
bool |
Returns true if the current tier includes the specified feature. |
get_features() |
array |
Returns all feature slugs available on the current tier. |
get_tier_label() |
string|null |
Returns the tier display name (e.g. "Pro", "Enterprise"). |
Trial methods
| Method | Returns | Description |
|---|---|---|
is_trial() |
bool |
Returns true if the license is in trial status. |
get_trial_end() |
string|null |
ISO 8601 date string for the trial end date, or null if not a trial. |
get_trial_days_remaining() |
int |
Number of days remaining in the trial period. Returns 0 if not a trial or if expired. |
Utility methods
| Method | Returns | Description |
|---|---|---|
check_update() |
object|false |
Queries the server for available updates. Returns an update object or false. |
get_plugin_file() |
string |
Returns the path passed as $plugin_file during construction. |
get_product_slug() |
string |
Returns the product slug. |
get_version() |
string |
Returns the currently installed version string, read from the plugin/theme headers. |
WPLF_Client_Admin
The admin class creates a license management page in the WordPress admin panel and handles user interactions for activation and deactivation.
Constructor
$admin = new WPLF_Client_Admin( $client, [
'page_title' => 'My Plugin Licence',
'menu_title' => 'Licence',
'menu_slug' => 'my-plugin-licence',
'parent_slug' => 'options-general.php', // Place under Settings
'brand_name' => 'Acme Corp',
'brand_color' => '#4F46E5',
'brand_logo' => plugins_url( 'assets/logo.svg', __FILE__ ),
] );
| Option | Type | Default | Description |
|---|---|---|---|
page_title |
string | "Licence" |
The browser title and heading of the admin page. |
menu_title |
string | "Licence" |
Label displayed in the admin sidebar menu. |
menu_slug |
string | "{slug}-licence" |
URL slug for the admin page. |
parent_slug |
string | "options-general.php" |
Parent menu. Use "options-general.php" for Settings, or a custom top-level slug. |
brand_name |
string | null |
Company name displayed on the license page header. |
brand_color |
string | null |
Hex colour for the page accent (header bar, buttons). |
brand_logo |
string | null |
URL to a logo image displayed on the license page. |
Admin page features
The generated admin page at Settings > Licence (or your configured location) provides:
- A license key input field with Activate, Deactivate, and Refresh buttons.
- Current license status display: active, expired, inactive, or trial with days remaining.
- Tier name and feature list for the current license.
- Masked key display after activation (e.g.
****-****-****-7FGH).
Admin notices
WPLF_Client_Admin displays persistent admin notices when a license requires attention:
- Expired license -- Warning notice prompting the user to renew.
- No license key -- Info notice on the plugin's own pages only, with a link to the license page.
- Approaching expiration -- Notice shown 14 days before expiry.
WPLF_Client_Updater
The updater class hooks into the WordPress plugin update system to deliver new versions to licensed users.
Constructor
$updater = new WPLF_Client_Updater( $client );
No additional configuration is needed. The updater reads the product slug, API URL, and plugin file from the WPLF_Client instance.
WordPress hooks
The updater registers two filters:
pre_set_site_transient_update_plugins-- Injects update data into the WordPress update transient when a newer version is available on the server.plugins_api-- Provides detailed plugin information (changelog, banners, icons) for the WordPress update modal.
Hash verification
Every package download is verified against a SHA-256 hash provided by the server. If the downloaded file's hash does not match the expected value, the update is aborted and the file is discarded. See Auto-Updates for the full verification flow.
Inactive license badge
When the license is not active, the updater adds a "Licence: Inactive" badge to the plugin's row on the Plugins page. This provides a visible reminder without blocking the plugin's normal operation.
Complete initialization example
Below is a complete example for a plugin called "AcmeForms Pro". This would typically live in the plugin's main PHP file.
<?php
/**
* Plugin Name: AcmeForms Pro
* Version: 2.4.1
* Description: Advanced form builder with conditional logic.
* Author: Acme Corp
* Requires PHP: 7.4
*/
defined( 'ABSPATH' ) || exit;
// ------------------------------------------------------------------
// 1. Include the LicenceForge client files
// ------------------------------------------------------------------
require_once __DIR__ . '/includes/class-wplf-client.php';
require_once __DIR__ . '/includes/class-wplf-client-admin.php';
require_once __DIR__ . '/includes/class-wplf-client-updater.php';
// ------------------------------------------------------------------
// 2. Initialize the client with array configuration
// ------------------------------------------------------------------
$acme_client = new WPLF_Client( [
'product_slug' => 'acmeforms-pro',
'api_url' => 'https://licences.acmecorp.com',
'plugin_file' => __FILE__,
'cache_duration' => 3600,
'api_key' => 'lf_pk_acme_xxxxxxxxxxxx',
] );
// ------------------------------------------------------------------
// 3. Initialize the admin page with branding
// ------------------------------------------------------------------
$acme_admin = new WPLF_Client_Admin( $acme_client, [
'page_title' => 'AcmeForms Pro Licence',
'menu_title' => 'Licence',
'menu_slug' => 'acmeforms-licence',
'parent_slug' => 'acmeforms-settings',
'brand_name' => 'Acme Corp',
'brand_color' => '#2563EB',
'brand_logo' => plugins_url( 'assets/acme-logo.svg', __FILE__ ),
] );
// ------------------------------------------------------------------
// 4. Initialize the updater
// ------------------------------------------------------------------
$acme_updater = new WPLF_Client_Updater( $acme_client );
// ------------------------------------------------------------------
// 5. Gate features based on license tier
// ------------------------------------------------------------------
function acmeforms_has_conditional_logic() {
global $acme_client;
return $acme_client->has_feature( 'conditional-logic' );
}
function acmeforms_has_payment_fields() {
global $acme_client;
return $acme_client->has_feature( 'payment-fields' );
}
Tip
Store the $client instance in a way that is accessible to the rest of your plugin. A global variable is shown here for simplicity, but a singleton class or dependency injection container is preferable in larger codebases.
Theme integration
The 3-class system works with themes as well as plugins. Pass the theme's functions.php path as $plugin_file and set parent_slug to "themes.php" to place the license page under the Appearance menu:
// In functions.php of your theme
require_once get_template_directory() . '/includes/class-wplf-client.php';
require_once get_template_directory() . '/includes/class-wplf-client-admin.php';
require_once get_template_directory() . '/includes/class-wplf-client-updater.php';
$theme_client = new WPLF_Client( 'my-theme', 'https://licences.example.com', __FILE__ );
$theme_admin = new WPLF_Client_Admin( $theme_client, [
'page_title' => 'Theme Licence',
'parent_slug' => 'themes.php',
] );
$theme_updater = new WPLF_Client_Updater( $theme_client );
Next steps
- Feature Checking -- Gate functionality based on tier and trial status
- Auto-Updates -- Understand the update delivery and verification pipeline
- Hooks and Filters -- Customise client behaviour with actions and filters