Digital License Manager provides a way for developers to extend the default Generators algorithm for generating the license keys.
To implement your own Generator class you need to hook into the dlm_generator_class
, for more details follow the guide below:
1. Custom Generator Class
Create a PHP class somewhere that will hold your Generator’s logic, this class should extend the base Generator class IdeoLogix\DigitalLicenseManager\Abstracts\AbstractGenerator
.
The following implementation is the exact same StandardGenerator class but with additional error_log() call that will output the generated license in the error log stack (debug.log) for demonstration purposes.
<?php
use IdeoLogix\DigitalLicenseManager\Abstracts\AbstractGenerator;
class MyCustomGenerator extends AbstractGenerator {
/**
* Generate list of licenses needed.
*
* @param $amount - Needed amount of licenses
* @param array $licenses - List of existing licenses
*
* @return WP_Error|array
*/
public function generate( $amount, $licenses = [] ) {
// check if it's possible to create as many combinations using the input args
$uniqueCharacters = count( array_unique( str_split( $this->generator->getCharset() ) ) );
$maxPossibleKeys = pow( $uniqueCharacters, $this->generator->getChunks() * $this->generator->getChunkLength() );
if ( $amount > $maxPossibleKeys ) {
return new WP_Error( 'data_error', __( 'It\'s not possible to generate that many keys with the given parameters, there are not enough combinations. Please review your inputs.', 'digital-license-manager' ), array( 'code' => 422 ) );
}
// Generate the license strings
for ( $i = 0; $i < $amount; $i ++ ) {
$licenses[] = $this->generate_licenses(
$this->generator->getCharset(),
$this->generator->getChunks(),
$this->generator->getChunkLength(),
$this->generator->getSeparator(),
$this->generator->getPrefix(),
$this->generator->getSuffix()
);
}
// Remove duplicate entries from the array
$licenses = array_unique( $licenses );
// check if any licenses have been removed
if ( count( $licenses ) < $amount ) {
// regenerate removed license keys, repeat until there are no duplicates
while ( count( $licenses ) < $amount ) {
$licenses = $this->generate( ( $amount - count( $licenses ) ), $licenses );
}
}
// Reindex and return the array
return array_values( $licenses );
}
/**
* The algorithm for generating licenses based on the generator options
*
* @param $charset
* @param $chunks
* @param $chunkLength
* @param $separator
* @param $prefix
* @param $suffix
*
* @return string
*/
private function generate_licenses( $charset, $chunks, $chunkLength, $separator, $prefix, $suffix ) {
$charsetLength = strlen( $charset );
$licenseString = $prefix;
// loop through the chunks
for ( $i = 0; $i < $chunks; $i ++ ) {
// add n random characters from $charset to chunk, where n = $chunkLength
for ( $j = 0; $j < $chunkLength; $j ++ ) {
$licenseString .= $charset[ rand( 0, $charsetLength - 1 ) ];
}
// do not add the separator on the last iteration
if ( $i < $chunks - 1 ) {
$licenseString .= $separator;
}
}
$licenseString .= $suffix;
error_log( 'Generated License: ' . $licenseString );
return $licenseString;
}
}
2. Register the generator class with a filter
Once you set up your logic, now it’s a time to put our new Generator class to a good use. For that purpose we will hook into the filter called dlm_generator_clas
s
The below code is just a very simple / minimum code on how this should look, feel free to set up your own logic, you can even conditionally use different Generator by manipulating with the generator, order, product parameters.
<?php
/**
* This is a custom generator class that overrides the default DLM functionality.
*
* This is just a very simple example, but you can also use the parameters to set up
* your logic and conditionally change the generator.
*
* @param string $className
* @param \IdeoLogix\DigitalLicenseManager\Database\Models\Resources\Generator $generator
* @param \WC_Order|null $order
* @param \WC_Product|null $product
*
* @return string
*/
function dlm_custom_generator_class( $className, $generator, $order, $product ) {
require_once get_template_directory() . '/includes/dlm-custom-generator.php';
return MyCustomGenerator::class;
}
add_filter( 'dlm_generator_class', 'dlm_custom_generator_class', 10, 4 );
Once this is done, the generator class should be used, to test that, try to invoke the Generator by placing a new order or generating licenses from the Generator edit page in the admin screen.