PHPackages                             caspahouzer/license-checker - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. caspahouzer/license-checker

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

caspahouzer/license-checker
===========================

A comprehensive WordPress license checking and management module with LemonSqueezy integration, automatic validation, admin UI integration, and multi-plugin support.

1.0.1(4mo ago)01GPL-2.0-or-laterPHPPHP &gt;=8.0CI passing

Since Jan 8Pushed 4mo agoCompare

[ Source](https://github.com/caspahouzer/license-checker)[ Packagist](https://packagist.org/packages/caspahouzer/license-checker)[ Docs](https://github.com/caspahouzer/license-checker)[ RSS](/packages/caspahouzer-license-checker/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (2)Versions (3)Used By (0)

License Manager Module
======================

[](#license-manager-module)

License module with hook-based admin menu integration for WordPress plugins.

Namespace
---------

[](#namespace)

`SLK\LicenseChecker`

Classes
-------

[](#classes)

- **LicenseChecker** - Main singleton controller for license management
- **LicenseHelper** - HTTP API client for license server communication
- **LicenseAdminPage** - Admin interface renderer for license page

Features
--------

[](#features)

- ✅ License activation/deactivation/validation
- ✅ **Automatic validation every 12 hours** (transient-based)
- ✅ REST API integration with license server
- ✅ WordPress admin UI integration
- ✅ Secure form handling with nonces
- ✅ Data storage via WordPress Options API
- ✅ **Hook-based menu registration** (new architecture)
- ✅ **Separate licenses per plugin** with unique option names

API Configuration
-----------------

[](#api-configuration)

- **Base URL:** `https://slk-communications.de/`
- **Endpoints:**
    - `POST /activate` - Activate license
    - `POST /deactivate` - Deactivate license
    - `POST /validate` - Validate license

Installation &amp; Setup
------------------------

[](#installation--setup)

### 1. Instantiating LicenseChecker

[](#1-instantiating-licensechecker)

In your plugin main file or bootstrap:

```
// In your plugin file (e.g., slk-my-plugin.php)
if (file_exists(__DIR__ . '/modules/LicenseChecker/LicenseChecker.php')) {
    require_once __DIR__ . '/modules/LicenseChecker/LicenseChecker.php';

    if (class_exists('\SLK\LicenseChecker\LicenseChecker')) {
        // Instantiate with your own text domain
        \SLK\LicenseChecker\LicenseChecker::instance('my-plugin-domain');
    }
}
```

### 2. Hook-based Menu Registration

[](#2-hook-based-menu-registration)

The module automatically triggers the `TEXTDOMAIN_WITH_UNDERSCORES_admin_menu` hook. Register a handler in your admin setup:

```
// In the admin_menu hook or later
do_action('slk_content_bitch_admin_menu', $parent_slug);
```

**Or simpler:** Let the fallback system do it automatically - if no handler is registered, it will handle it itself!

Usage
-----

[](#usage)

### Check License Status via PHP

[](#check-license-status-via-php)

```
// Check license for your plugin
if (\SLK\LicenseChecker\LicenseChecker::is_active('my-plugin-domain')) {
    // License is active for your plugin
} else {
    // License is not activated or expired
}

// Or use the instance directly
$license = \SLK\LicenseChecker\LicenseChecker::instance('my-plugin-domain');
if ($license->get_license_status() === 'active') {
    // Your plugin is licensed
}
```

### Access Admin Page

[](#access-admin-page)

The license admin page is automatically registered as a submenu under the parent menu:

```
Admin Menu
└── Your Menu
    ├── Menu Item 1
    ├── Menu Item 2
    └── License (at the end)  ← Automatically positioned

```

### Manual Registration (optional)

[](#manual-registration-optional)

If you need more control:

```
$license_manager = \SLK\LicenseChecker\LicenseChecker::instance('my-plugin-domain');
$license_manager->register_submenu('edit.php?post_type=my_cpt');
```

Option Names
------------

[](#option-names)

Each plugin stores its license data with a unique prefix:

```
slk_{plugin_slug}_license_checker_license_key
slk_{plugin_slug}_license_checker_license_status
slk_{plugin_slug}_license_checker_activation_hash
slk_{plugin_slug}_license_checker_license_counts

```

**Example for `slk-content-bitch`:**

```
slk_content_bitch_license_checker_license_key
slk_content_bitch_license_checker_license_status
slk_content_bitch_license_checker_activation_hash
slk_content_bitch_license_checker_license_counts

```

Hooks &amp; Actions
-------------------

[](#hooks--actions)

### `slk_register_license_submenu`

[](#slk_register_license_submenu)

Triggers license submenu registration:

```
do_action('slk_register_license_submenu', $parent_slug, $license_manager);
```

**Parameters:**

- `$parent_slug` (string) - Parent menu slug (e.g., 'edit.php?post\_type=my\_cpt')
- `$license_manager` (LicenseChecker) - LicenseChecker instance

**Example:**

```
add_action('slk_register_license_submenu', function($parent_slug, $license_manager) {
    $license_manager->register_submenu($parent_slug);
}, 10, 2);
```

### `slk_register_license_submenu_done_{option_prefix}`

[](#slk_register_license_submenu_done_option_prefix)

Triggers after successful submenu registration:

```
do_action('slk_register_license_submenu_done_slk_content_bitch_license_checker');
```

AJAX Actions
------------

[](#ajax-actions)

JavaScript communication uses the following AJAX actions (varies per plugin):

- **slk-license-manager:** `slk_license_manager_manage_license`
- **slk-content-bitch:** `slk_content_bitch_manage_license`

These are automatically registered by the module based on the plugin context.

LicenseChecker Class Methods
----------------------------

[](#licensechecker-class-methods)

### Public Methods

[](#public-methods)

```
// Get singleton instance
$instance = LicenseChecker::instance($text_domain = 'slk-license-checker');

// Activate license
$result = $instance->activate_license('license-key-here');

// Deactivate license
$result = $instance->deactivate_license($license_key, $activation_hash);

// Validate license
$result = $instance->validate_license($license_key);

// Get license status ('active', 'inactive', 'invalid')
$status = $instance->get_license_status();

// Get activation counts
$counts = $instance->get_license_counts(); // ['activated' => 1, 'limit' => 5]

// Register admin menu (orchestrates hook-based registration)
$instance->add_admin_menu($parent_slug);

// Register submenu directly
$instance->register_submenu($parent_slug);

// Render license page (used internally)
$instance->render_license_form();
```

### Static Methods

[](#static-methods)

```
// Check if license is active (with plugin support)
if (LicenseChecker::is_active('my-plugin-domain')) {
    // ...
}

// Check for current plugin (uses default)
if (LicenseChecker::is_active()) {
    // ...
}
```

Menu Registration Architecture
------------------------------

[](#menu-registration-architecture)

### Hook-based Design

[](#hook-based-design)

The new architecture uses a clean hook-based structure:

```
1. Plugin calls do_action('slk_license_manager_admin_menu', $parent_slug)
   ↓
2. LicenseChecker triggers do_action('slk_register_license_submenu', $parent_slug, $this)
   ↓
3. Plugin registers hook handler for 'slk_register_license_submenu'
   ↓
4. Hook handler calls $license_manager->register_submenu($parent_slug)
   ↓
5. License submenu is registered
   ↓
6. Menu is moved to the end (reorder_submenu_to_end)
   ↓
7. Active menu item is highlighted (register_active_menu_handler)

```

Separate Licenses per Plugin (Multi-Plugin Setup)
-------------------------------------------------

[](#separate-licenses-per-plugin-multi-plugin-setup)

Both plugins can be active simultaneously with **separate and independent licenses:**

```
// In slk-license-manager/slk-license-manager.php
\SLK\LicenseChecker\LicenseChecker::instance('slk-license-manager');

// In slk-content-bitch/slk-content-bitch.php
\SLK\LicenseChecker\LicenseChecker::instance('slk-content-bitch');

// Each plugin has its own license
if (\SLK\LicenseChecker\LicenseChecker::is_active('slk-license-manager')) {
    // License Manager is licensed
}

if (\SLK\LicenseChecker\LicenseChecker::is_active('slk-content-bitch')) {
    // Content Bitch is licensed
}
```

Debugging
---------

[](#debugging)

Enable the `SLK_DEBUG` constant for logging:

```
define('SLK_DEBUG', true);
```

Logs are output via `error_log()` (check wp-content/debug.log).

Auto-loading
------------

[](#auto-loading)

Classes are automatically loaded via PSR-4 autoloader. No manual `require` needed, except when initially loading the module.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance77

Regular maintenance activity

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

125d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a928ac87d97f5f0027b108ad866079a671e95c5bdb21341564ab67dc09228f16?d=identicon)[caspahouzer](/maintainers/caspahouzer)

---

Top Contributors

[![caspahouzer](https://avatars.githubusercontent.com/u/1126641?v=4)](https://github.com/caspahouzer "caspahouzer (39 commits)")

---

Tags

pluginvalidationwordpresslicenselicense-managementlemon squeezylicense-checker

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/caspahouzer-license-checker/health.svg)

```
[![Health](https://phpackages.com/badges/caspahouzer-license-checker/health.svg)](https://phpackages.com/packages/caspahouzer-license-checker)
```

###  Alternatives

[phpexperts/datatype-validator

An easy to use data type validator (both strict and fuzzy).

141.1M2](/packages/phpexperts-datatype-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
