├── README.md └── SoftwareLicenseManager.class.php /README.md: -------------------------------------------------------------------------------- 1 | # Software License Manager PHP Class # 2 | This class can be used in a PHP application to contact a WordPress based license server using the free [Software License Manager Plugin](https://wordpress.org/plugins/software-license-manager/). 3 | ## Usage ## 4 | - Install WordPress on your license server 5 | - Install the Software License Manager Plugin on that server 6 | - Configure the plugin, e.g. setting the secret key for validation 7 | - Include my class in your PHP application 8 | - Change the const variables in the class to match your license server settings 9 | - Instantiate the class in your script, e.g. `$LIC = new SoftwareLicenseManager();` 10 | - Set the license key property, e.g. `$LIC->setKey('5766474b540');` 11 | - Load the details for that license from the license server, e.g. `$LIC->load();` 12 | - Use other methods as needed, e.g.: 13 | - `$LIC->activate();` 14 | - `$LIC->daysToExpiry();` 15 | - `$LIC->deactivate();` 16 | - `$LIC->domainRegistered();` 17 | - `$LIC->getKey();` 18 | - `$LIC->load();` 19 | - `$LIC->readKey();` 20 | - `$LIC->saveKey();` 21 | - `$LIC->setKey('5766474b540');` 22 | - `$LIC->show();` 23 | - `$LIC->status();` 24 | ## $LIC->activate() ## 25 | This method will sumbit the license key in $this->key to the license server for activation plus domain registration. Example: 26 | ```php 27 | $LIC->setKey('5766474b540'); 28 | $LIC->activate(); 29 | ``` 30 | ## $LIC->daysToExpiry() ## 31 | This method will count and return the number of days from 'today' to the expiry date of the license. Example: 32 | ```php 33 | $LIC->setKey('5766474b540'); 34 | $LIC->load(); 35 | echo $LIC->daysToExpiry(); 36 | ``` 37 | ## $LIC->deactivate() ## 38 | This method will sumbit the license key in $this->key to the license server for deactivation. Example: 39 | ```php 40 | $LIC->setKey('5766474b540'); 41 | $LIC->deactivate(); 42 | ``` 43 | ## $LIC->domainRegistered() ## 44 | This method will check whether the current domain is registered for the license. Example: 45 | ```php 46 | $LIC->setKey('5766474b540'); 47 | $LIC->load(); 48 | if ($LIC->domainRegistered()) { 49 | echo "Domain is registered"; 50 | else { 51 | echo "Domain is not registered"; 52 | } 53 | ``` 54 | ## $LIC->getKey() ## 55 | This method will retrieve the class viarable 'key' that is supposed to hold the license key. Example: 56 | ```php 57 | $LIC->setKey('5766474b540'); 58 | echo $LIC->getKey(); 59 | ``` 60 | ## $LIC->load() ## 61 | This method will load the license details from the license server. Example: 62 | ```php 63 | $LIC->setKey('5766474b540'); 64 | $LIC->load(); 65 | ``` 66 | ## $LIC->readKey() ## 67 | This method is a placeholder for code you might want to add to read the license key from your own database. 68 | ## $LIC->saveKey() ## 69 | This method is a placeholder for code you might want to add to save the license key to your own database. 70 | ## $LIC->setKey() ## 71 | This method will set the class viarable 'key' that is supposed to hold the license key. Example: 72 | ```php 73 | $LIC->setKey('5766474b540'); 74 | ``` 75 | ## $LIC->show() ## 76 | This method assumes that you use Bootstrap 4 in your PHP application. It will display the license status in a Bootstrap 4 alert box. 77 | If you set the second parameter to 'true', a table with the license details will be shown as well inside that box. 78 | Example: 79 | ```php 80 | $LIC->setKey('5766474b540'); 81 | $LIC->load(); 82 | $LIC->show($LIC->details, true); 83 | ``` 84 | ## $LIC->status() ## 85 | The status() method returns one of these these values: 86 | - _active_ (the license is active and registered for the domain the validation request came from) 87 | - _blocked_ (the license is blocked) 88 | - _expired_ (the license is expired) 89 | - _invalid_ (an empty or invalid license key was submitted) 90 | - _pending_ (the license is valid but not activated yet) 91 | - _unregisterd_ (the license is active but not registered for the domain the validation request came from) 92 | Example: 93 | ```php 94 | $LIC->setKey('5766474b540'); 95 | $LIC->load(); 96 | echo $LIC->status(); 97 | ``` 98 | ## Credits ## 99 | Thanks to [Tips and Tricks HQ](https://www.tipsandtricks-hq.com/software-license-manager-plugin-for-wordpress) for the Software License Manager Plugin for WordPress 100 | 101 | -------------------------------------------------------------------------------- /SoftwareLicenseManager.class.php: -------------------------------------------------------------------------------- 1 | 10 | * @source https://github.com/glewe/software-license-manager-class 11 | * @license https://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * You can use this class in any PHP application to communicate with a WordPress 14 | * based license server using the Software License Manager plugin: 15 | * https://www.tipsandtricks-hq.com/software-license-manager-plugin-for-wordpress 16 | * 17 | */ 18 | 19 | class SoftwareLicenseManager 20 | { 21 | /** 22 | * The secret key. 23 | * 24 | * This variable specifies the value which is set in the license manager 25 | * plugin settings page as: "Secret Key for License Verification Requests". 26 | * 27 | * @since 1.0.0 28 | * @var SECRET_KEY The host REST URI 29 | */ 30 | const SECRET_KEY = '5421048138b321.90068894'; 31 | 32 | /** 33 | * The license server URL. 34 | * 35 | * This variable specifies the URL of your server where the license manager 36 | * plugin is installed on. Your plugin from a customer’s site will be 37 | * communicating with this server to activate or deactivate license keys. 38 | * 39 | * @since 1.0.0 40 | * @var LICENSE_SERVER The host REST URI 41 | */ 42 | const LICENSE_SERVER = 'https://mylicenseserver.com'; 43 | 44 | /** 45 | * This variable provides a reference label for the licenses which will be 46 | * issued. Therefore you should enter something specific to describe what 47 | * the licenses issued are pertaining to. 48 | * 49 | * @since 1.0.0 50 | * @var ITEM_REFERENCE The licensed product or item 51 | */ 52 | const ITEM_REFERENCE = 'My Licensed Item'; 53 | 54 | /** 55 | * The license key. 56 | * Private variable holding the linces key itself. 57 | * Set with setKey(), read with getKey() method. 58 | * 59 | * @since 1.0.0 60 | * @access private 61 | * @var string $key The license key 62 | */ 63 | private $key = ''; 64 | 65 | /** 66 | * Language array for thje details display. 67 | * 68 | * @since 1.0.0 69 | * @access private 70 | * @var array $lang The license key 71 | */ 72 | private $lang = array(); 73 | 74 | /** 75 | * JSON reponse from the license server. 76 | * 77 | * @since 1.0.0 78 | * @access public 79 | * @var JSON $details JSON reposnse 80 | */ 81 | public $details; 82 | 83 | // --------------------------------------------------------------------- 84 | /** 85 | * Constructor. 86 | */ 87 | public function __construct() 88 | { 89 | // 90 | // Fill language array 91 | // 92 | $this->lang['lic_active'] = 'Active License'; 93 | $this->lang['lic_active_subject'] = 'This is an active license for this domain. Awesome!'; 94 | $this->lang['lic_active_unregistered_subject'] = 'This is an active license but not registered for this domain.'; 95 | $this->lang['lic_alert_activation_fail'] = 'The following error occurred while trying to activate your license:'; 96 | $this->lang['lic_alert_activation_success'] = 'Your license was successfully activated for this domain.'; 97 | $this->lang['lic_alert_registration_fail'] = 'The following error occurred while trying to register your domain to your license:'; 98 | $this->lang['lic_alert_registration_success'] = 'Your domain was successfully registered to your license.'; 99 | $this->lang['lic_alert_deregistration_fail'] = 'The following error occurred while trying to deregister your domain from your license:'; 100 | $this->lang['lic_alert_deregistration_success'] = 'Your domain was successfully deregistered from your license.'; 101 | $this->lang['lic_blocked'] = 'Blocked License'; 102 | $this->lang['lic_blocked_subject'] = 'This license is blocked.'; 103 | $this->lang['lic_blocked_help'] = 'Please contact your administrator to unblock this license.'; 104 | $this->lang['close_this_message'] = 'Close this message'; 105 | $this->lang['lic_company'] = 'Company'; 106 | $this->lang['lic_date_created'] = 'Date Created'; 107 | $this->lang['lic_date_expiry'] = 'Date Expiry'; 108 | $this->lang['lic_date_renewed'] = 'Date Renewed'; 109 | $this->lang['lic_daysleft'] = 'days left'; 110 | $this->lang['lic_details'] = 'License Details'; 111 | $this->lang['lic_email'] = 'E-mail'; 112 | $this->lang['lic_expired'] = 'Expired License'; 113 | $this->lang['lic_expired_subject'] = 'This license has expired.'; 114 | $this->lang['lic_expired_help'] = 'Please contact your administrator to renew this license.'; 115 | $this->lang['lic_expiringsoon'] = 'License Expiry Warning'; 116 | $this->lang['lic_expiringsoon_subject'] = 'Your license will expire in %d days.'; 117 | $this->lang['lic_expiringsoon_help'] = 'Please contact your administrator to renew this license in time.'; 118 | $this->lang['lic_invalid'] = 'Invalid License'; 119 | $this->lang['lic_invalid_subject'] = 'No license key was found or it is invalid.'; 120 | $this->lang['lic_invalid_text'] = 'This instance is unregistered or a ucfirst license key was not entered and activated yet.'; 121 | $this->lang['lic_invalid_help'] = 'Please contact the administrator to obtain a valid license.'; 122 | $this->lang['lic_key'] = 'License Key'; 123 | $this->lang['lic_name'] = 'Licensee'; 124 | $this->lang['lic_max_allowed_domains'] = 'Maximum Allowed Domains'; 125 | $this->lang['lic_pending'] = 'Pending License'; 126 | $this->lang['lic_pending_subject'] = 'This license is registered but not activated yet.'; 127 | $this->lang['lic_pending_help'] = 'Please contact your administrator to activate this license.'; 128 | $this->lang['lic_registered_domains'] = 'Registered Domains'; 129 | $this->lang['lic_status'] = 'Status'; 130 | $this->lang['lic_product'] = 'Product'; 131 | $this->lang['lic_unregistered'] = 'Unregistered License'; 132 | $this->lang['lic_unregistered_subject'] = 'The license key of this instance is not registered for this domain.'; 133 | $this->lang['lic_unregistered_help'] = 'Please contact the administrator to register this domain or obtain a valid license.'; 134 | } 135 | 136 | // --------------------------------------------------------------------------- 137 | /** 138 | * Activates a license (and registers the domain the request is coming from). 139 | * 140 | * @return JSON 141 | */ 142 | function activate() 143 | { 144 | $parms = array( 145 | 'slm_action' => 'slm_activate', 146 | 'secret_key' => self::SECRET_KEY, 147 | 'license_key' => $this->key, 148 | 'registered_domain' => $_SERVER['SERVER_NAME'], 149 | 'item_reference' => urlencode(self::ITEM_REFERENCE), 150 | ); 151 | 152 | $response = $this->callAPI('GET', self::LICENSE_SERVER, $parms); 153 | $response = json_decode((string)$response); 154 | 155 | if (!$response) { 156 | $response = (object) array('result' => 'error', 'message' => 'Unexpected Error! The activation request returned with an error.'); 157 | } 158 | 159 | return $response; 160 | } 161 | 162 | // --------------------------------------------------------------------------- 163 | /** 164 | * API Call. 165 | * 166 | * @param string $method POST, PUT, GET, ... 167 | * @param string $url API host URL 168 | * @param array $data URL paramater: array("param" => "value") ==> index.php?param=value 169 | * @return JSON 170 | */ 171 | function callAPI($method, $url, $data = false) 172 | { 173 | $curl = curl_init(); 174 | 175 | switch (strtoupper($method)) { 176 | case "POST": 177 | curl_setopt($curl, CURLOPT_POST, 1); 178 | if ($data) 179 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 180 | break; 181 | case "PUT": 182 | curl_setopt($curl, CURLOPT_PUT, 1); 183 | break; 184 | default: 185 | if ($data) 186 | $url = sprintf("%s?%s", $url, http_build_query($data)); 187 | } 188 | 189 | // Optional Authentication: 190 | // curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 191 | // curl_setopt($curl, CURLOPT_USERPWD, "username:password"); 192 | 193 | // Optional Debugging: 194 | // $query = LICENSE_SERVER . '?slm_action=' . $data['slm_action'] . '&secret_key=' . $data['secret_key'] . '&license_key=' . $data['license_key'] . '&registered_domain=' . $data['registered_domain'] . '&item_reference=' . $data['item_reference']; 195 | // die($query); 196 | 197 | curl_setopt($curl, CURLOPT_URL, $url); 198 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 199 | $result = curl_exec($curl); 200 | curl_close($curl); 201 | 202 | return $result; 203 | } 204 | 205 | // --------------------------------------------------------------------------- 206 | /** 207 | * Deactivates a license (deregisters the domain the request is coming from). 208 | * 209 | * @return JSON 210 | */ 211 | function deactivate() 212 | { 213 | $parms = array( 214 | 'slm_action' => 'slm_deactivate', 215 | 'secret_key' => self::SECRET_KEY, 216 | 'license_key' => $this->key, 217 | 'registered_domain' => $_SERVER['SERVER_NAME'], 218 | 'item_reference' => urlencode(self::ITEM_REFERENCE), 219 | ); 220 | 221 | $response = $this->callAPI('GET', self::LICENSE_SERVER, $parms); 222 | $response = json_decode((string)$response); 223 | 224 | if (!$response) { 225 | $response = (object) array('result' => 'error', 'message' => 'Unexpected Error! The deactivation request returned with an error.'); 226 | } 227 | 228 | return $response; 229 | } 230 | 231 | // --------------------------------------------------------------------------- 232 | /** 233 | * Checks whether the current domain is registered. 234 | * 235 | * @return boolean 236 | */ 237 | function domainRegistered() 238 | { 239 | // if (!$this->readKey()) return false; // Enable if using the readKey() method 240 | 241 | if (count($this->details->registered_domains)) { 242 | foreach ($this->details->registered_domains as $domain) { 243 | if ($domain->registered_domain == $_SERVER['SERVER_NAME']) return true; 244 | } 245 | return false; 246 | } else { 247 | return false; 248 | } 249 | } 250 | 251 | // --------------------------------------------------------------------------- 252 | /** 253 | * Returns the days until expiry. 254 | * 255 | * @return integer 256 | */ 257 | function daysToExpiry() 258 | { 259 | $todayDate = new DateTime('now'); 260 | $expiryDate = new DateTime($this->details->date_expiry); 261 | $daysToExpiry = $todayDate->diff($expiryDate); 262 | 263 | return intval($daysToExpiry->format('%R%a')); 264 | } 265 | 266 | // --------------------------------------------------------------------------- 267 | /** 268 | * Loads the license information from license server. 269 | * 270 | * @return JSON Saved in $this->details 271 | */ 272 | function load() 273 | { 274 | $parms = array( 275 | 'slm_action' => 'slm_check', 276 | 'secret_key' => self::SECRET_KEY, 277 | 'license_key' => $this->key, 278 | ); 279 | 280 | $response = $this->callAPI('GET', self::LICENSE_SERVER, $parms); 281 | $response = json_decode((string)$response); 282 | 283 | $this->details = $response; 284 | } 285 | 286 | // --------------------------------------------------------------------------- 287 | /** 288 | * Reads the class license key. 289 | * 290 | * @return string 291 | */ 292 | function getKey() 293 | { 294 | return $this->key; 295 | } 296 | 297 | // --------------------------------------------------------------------- 298 | /** 299 | * Reads the license key from the database. 300 | */ 301 | function readKey() 302 | { 303 | // 304 | // You may want to use this method to read the license key from elsewhere 305 | // e.g. from a database with this pseudo code 306 | // $this->key = read_key_from_db(); 307 | // 308 | } 309 | 310 | // --------------------------------------------------------------------- 311 | /** 312 | * Saves the license key to the database. 313 | */ 314 | function saveKey($value) 315 | { 316 | // 317 | // You may want to use this method to save the license key elsewhere 318 | // e.g. to a database with this pseudo code 319 | // save_key_to_db($this->key); 320 | // 321 | } 322 | 323 | // --------------------------------------------------------------------------- 324 | /** 325 | * Sets the class license key. 326 | * 327 | * @param string $key The license key 328 | */ 329 | function setKey($key) 330 | { 331 | $this->key = $key; 332 | } 333 | 334 | // --------------------------------------------------------------------------- 335 | /** 336 | * Creates a table with license details and displays it inside a Bootstrap 337 | * alert box. This method assumes that your application uses Bootstrap 4. 338 | * 339 | * @param object $data License information array 340 | * @return string HTML 341 | */ 342 | function show($data, $showDetails = false) 343 | { 344 | if (isset($data->result) && $data->result == "error") { 345 | $alert['type'] = 'danger'; 346 | $alert['title'] = $this->lang['lic_invalid']; 347 | $alert['subject'] = $this->lang['lic_invalid_subject']; 348 | $alert['text'] = $this->lang['lic_invalid_text']; 349 | $alert['help'] = $this->lang['lic_invalid_help']; 350 | $details = ""; 351 | } else 352 | { 353 | $domains = ""; 354 | if (count($data->registered_domains)) { 355 | foreach ($data->registered_domains as $domain) { 356 | $domains .= $domain->registered_domain . ', '; 357 | } 358 | $domains = substr($domains, 0, -2); // Remove last comma and blank 359 | } 360 | $daysleft = ""; 361 | if ($daysToExpiry = $this->daysToExpiry()) { 362 | $daysleft = " (" . $daysToExpiry . " " . $this->lang['lic_daysleft'] . ")"; 363 | } 364 | 365 | $details = "
"; 366 | $details .= " 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 |
" . $this->lang['lic_product'] . ":" . $data->product_ref . "
" . $this->lang['lic_key'] . ":" . $data->license_key . "
" . $this->lang['lic_name'] . ":" . $data->first_name . " " . $data->last_name . "
" . $this->lang['lic_email'] . ":" . $data->email . "
" . $this->lang['lic_company'] . ":" . $data->company_name . "
" . $this->lang['lic_date_created'] . ":" . $data->date_created . "
" . $this->lang['lic_date_renewed'] . ":" . $data->date_renewed . "
" . $this->lang['lic_date_expiry'] . ":" . $data->date_expiry . $daysleft . "
" . $this->lang['lic_registered_domains'] . ":" . $domains . "
"; 377 | 378 | switch ($this->status()) { 379 | case "active": 380 | $title = $this->lang['lic_active']; 381 | $alert['type'] = 'success'; 382 | $alert['title'] = $title . '' . ucfirst($data->status) . ''; 383 | $alert['subject'] = $this->lang['lic_active_subject']; 384 | $alert['text'] = ''; 385 | $alert['help'] = ''; 386 | break; 387 | 388 | case "expired": 389 | $title = $this->lang['lic_expired']; 390 | $alert['type'] = 'warning'; 391 | $alert['title'] = $title . '' . ucfirst($data->status) . ''; 392 | $alert['subject'] = $this->lang['lic_expired_subject']; 393 | $alert['help'] = $this->lang['lic_expired_help']; 394 | break; 395 | 396 | case "blocked": 397 | $alert['type'] = 'warning'; 398 | $title = $this->lang['lic_blocked']; 399 | $alert['title'] = $title . '' . ucfirst($data->status) . ''; 400 | $alert['subject'] = $this->lang['lic_blocked_subject']; 401 | $alert['text'] = ''; 402 | $alert['help'] = $this->lang['lic_blocked_help']; 403 | break; 404 | 405 | case "pending": 406 | $alert['type'] = 'warning'; 407 | $title = $this->lang['lic_pending']; 408 | $alert['title'] = $title . '' . ucfirst($data->status) . ''; 409 | $alert['subject'] = $this->lang['lic_pending_subject']; 410 | $alert['text'] = ''; 411 | $alert['help'] = $this->lang['lic_pending_help']; 412 | break; 413 | 414 | case "unregistered": 415 | $title = $this->lang['lic_active']; 416 | $alert['type'] = 'warning'; 417 | $alert['title'] = $title . '' . ucfirst($data->status) . ''; 418 | $alert['subject'] = $this->lang['lic_active_unregistered_subject']; 419 | $alert['text'] = ''; 420 | $alert['help'] = ''; 421 | break; 422 | } 423 | } 424 | 425 | $alertBox = ' 426 |
427 | 428 |

' . $alert['title'] . '

429 |
430 |

' . $alert['subject'] . '

431 |

' . $alert['text'] . '

432 | ' . (strlen($alert['help']) ? "

" . $alert['help'] . "

" : "") . (($showDetails) ? $details : '') . ' 433 |
'; 434 | 435 | return $alertBox; 436 | } 437 | 438 | // --------------------------------------------------------------------------- 439 | /** 440 | * Get license status. 441 | * 442 | * @return string active/blocked/invalid/expired/pending/unregistered 443 | */ 444 | function status() 445 | { 446 | if ($this->details->result == 'error') return "invalid"; 447 | 448 | switch ($this->details->status) { 449 | case "active": 450 | if (!$this->domainRegistered()) return 'unregistered'; 451 | return 'active'; 452 | break; 453 | case "expired": 454 | return 'expired'; 455 | break; 456 | case "blocked": 457 | return 'blocked'; 458 | break; 459 | case "pending": 460 | return 'pending'; 461 | break; 462 | } 463 | } 464 | } 465 | --------------------------------------------------------------------------------