<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/*
Sample response from WHMCS:

Array
(
    [status] => Active
    [registeredname] => Oliver Hellwig
    [email] => oliver.hellwig@data443.com
    [serviceid] => 2015
    [productid] => 45
    [productname] => testlicense
    [regdate] => 2021-04-23 00:00:00
    [nextduedate] => 0000-00-00
    [billingcycle] => Free Account
    [validdomain] => gdpr-1041.local,www.gdpr-1041.local
    [validip] => 127.0.0.1
    [validdirectory] => C:\Users\OliverHellwig\Local Sites\gdpr-1041\app\public\wp-content\plugins\intelly-welcome-bar-pro\includes\classes\utils
    [customfields] => Count=50
    [md5hash] => 4990220a9c74db299a286bfc380f1bac
    [checkdate] => 20210426
    [localkey] => ==QfiYjM0ATMyAjMiojIlRXYkt2Ylh2YiwiIjFmYxYGM4MzYmJmN4ITY5kjMiRGN3MWOhBjMyATO5QjI
6ICazFGa1QWbiwiIzxWa0VHXcNXZzNXYsNGXcNXZkVHbj5Wacx1byBXLyFmYtUWbvNGbldXL5xGblRnb
pxFXz5WanVHbwxFX05WZ052bj1Cc3xFXjlGbiVHccxFcwFGXcFDNwETLyBHZnxFXzVGdpNFIsF2YvxEX
cdWa3xGblhkclZXas9EXcNnclNXVcxlODJiOikncvR3YlJXakRWasFmdiwiIx4CMuAjL3ITMiojIwlGZ
pxWY2JCLiwWYj9GbuEDNwETLyBHZn5yd3dHLsF2YvxmLxQDMx0icwR2ZiojIulWYt9GZklGbhZnIsICd
uV3bjNWQgUWZyZkI6ISZsNWejdmbpxGbpJmIsICMw0CMw0CMwADMiojIlRXYkVWdkRHel5mIsICMwoDM
woDMwAyMy0CNw0SMyAjMiojIlRXYkdWZyJCLiU2cuV2YpxGdzVGdiojIl1WYuR3Y1R2byBnIsISN0IiO
iQWa0NWdk9mcwJCLiUTMwIjI6ICZpV2YpZnclNnIsISbvNmLzQDNhRXYkB0ZpdHbsVGauIXZ2lGbvJiO
iwWah1WZiwiInl2dsxWZIBiclZXas9kI6ISZtFmbkVmclR3cpdWZyJCLiUmdpR3YBJiOiMXd0FGdzJye
6088cb198a9fe1ddd2f84f38a1142526733af0d7903f5dca294f64b8cc0e0852
    [remotecheck] => 1
)

*/

class IRPP_WHMCS_License {

    public function __construct() {
    }

    function type()
    {
        return 'WHMCS';
    }

    public function init() {
        //add_filter( 'cron_schedules', array( $this, 'add_schedules'   ) );
        //add_action( 'wp',             array( $this, 'schedule_Events' ) );
        //add_action('irpp_daily_scheduled_events', array($this, 'checkLicense'));
        add_action('admin_init', array($this, 'pluginUpdater'));
    }

    function pluginUpdater() {
        global $irpp;
		
		if ( $irpp->Options->getExpiredLicense() == true )
			return;

		$args=array(
            'version' => IRPP_PLUGIN_VERSION
            , 'license'=> $irpp->Options->getLicenseKey()
            , 'item_name' => IRPP_EDD_NAME
            , 'author' 	=> IRPP_PLUGIN_AUTHOR
        );
        $irppUpdater = new IRPP_EDD_SL_Plugin_Updater(IRPP_LICENSE_SERVER, IRPP_PLUGIN_FILE, $args);
    
	}

    //activate the new license key
    function activate($key) {
        global $irpp;

        $licensekey = $key;
        $localkey = $irpp->Options->getLocalKey();
        $this->deactivate();
        
        // Validate the license key information
        $results = $this->wb_whmcs_check_license($licensekey, $localkey);
        
        // Raw output of results for debugging purpose
        //echo '<textarea cols="100" rows="20">' . print_r($results, true) . '</textarea>';
        
        // Interpret response
        $result = false;
        switch ($results['status']) {
            case "Active":
                // get new local key and save it somewhere
                $localkeydata = $results['localkey'];
                $result = true;
                $irpp->Options->setLicenseKey($licensekey);
                $irpp->Options->setLocalKey($localkeydata);
                $irpp->Options->setLicenseSuccess(true);
                $results['description'] = "Successful license activation";
                break;
            case "Invalid":
                $results['description'] = "License key is Invalid";
                break;
            case "Expired":
                $results['description'] = "License key is Expired";
                break;
            case "Suspended":
                $results['description'] = "License key is Suspended";
                break;
            default:
                $results['description'] = "Invalid Response";
                break;
        }
        $irpp->Options->setLicense($results);
        return $result;
    }

    //deactivate the installed license
    function deactivate() {
        global $irpp;
        $irpp->Options->setLicenseKey('');
        $irpp->Options->setLocalKey(false);
        $irpp->Options->setLicense(FALSE);
        $irpp->Options->setLicenseSuccess(FALSE);
        $irpp->Options->setExpiredLicense(FALSE);
        $data=array(
            'status'=> 'Deactivated'
        );
        $irpp->Options->setLicense($data);
        return true;
    }

    //retrieve if the current license used is stil valid or not
    public function hasPremium($override=FALSE) {
        return $this->check();
    }

    public function check() {
        global $irpp;
        $licensekey = $irpp->Options->getLicenseKey();
        $localkey = $irpp->Options->getLocalKey();
        $results = $this->wb_whmcs_check_license($licensekey, $localkey);
        return $results['status'] == 'Active';
    }

    function wb_whmcs_check_license($licensekey, $localkey='') {
        $results = array();
        $results['status'] = 'Active';
        return $results;
        // -----------------------------------
        //  -- Configuration Values --
        // -----------------------------------
    
        // Enter the url to your WHMCS installation here
        $whmcsurl = 'https://orders.data443.com/';
        // Must match what is specified in the MD5 Hash Verification field
        // of the licensing product that will be used with this check.
        $licensing_secret_key = 'inline';
        // The number of days to wait between performing remote license checks
        $localkeydays = 1;
        // The number of days to allow failover for after local key expiry
        $allowcheckfaildays = 5;
    
        // -----------------------------------
        //  -- Do not edit below this line --
        // -----------------------------------
    
        $check_token = time() . md5(mt_rand(100000000, mt_getrandmax()) . $licensekey);
        $checkdate = date("Ymd");
        $domain = $_SERVER['SERVER_NAME'];
        $usersip = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['LOCAL_ADDR'];
        $dirpath = dirname(__FILE__);
        $verifyfilepath = 'modules/servers/licensing/verify.php';
        $localkeyvalid = false;
        if ($localkey) {
            $localkey = str_replace("\n", '', $localkey); # Remove the line breaks
            $localdata = substr($localkey, 0, strlen($localkey) - 32); # Extract License Data
            $md5hash = substr($localkey, strlen($localkey) - 32); # Extract MD5 Hash
            if ($md5hash == md5($localdata . $licensing_secret_key)) {
                $localdata = strrev($localdata); # Reverse the string
                $md5hash = substr($localdata, 0, 32); # Extract MD5 Hash
                $localdata = substr($localdata, 32); # Extract License Data
                $localdata = base64_decode($localdata);
                $localkeyresults = json_decode($localdata, true);
                $originalcheckdate = $localkeyresults['checkdate'];
                if ($md5hash == md5($originalcheckdate . $licensing_secret_key)) {
                    $localexpiry = date("Ymd", mktime(0, 0, 0, date("m"), date("d") - $localkeydays, date("Y")));
                    if ($originalcheckdate > $localexpiry) {
                        $localkeyvalid = true;
                        $results = $localkeyresults;
                        $validdomains = explode(',', $results['validdomain']);
                        if (!in_array($_SERVER['SERVER_NAME'], $validdomains)) {
                            $localkeyvalid = false;
                            $localkeyresults['status'] = "Invalid";
                            $results = array();
                        }
                        $validips = explode(',', $results['validip']);
                        if (!in_array($usersip, $validips)) {
                            $localkeyvalid = false;
                            $localkeyresults['status'] = "Invalid";
                            $results = array();
                        }
                        $validdirs = explode(',', $results['validdirectory']);
                        if (!in_array($dirpath, $validdirs)) {
                            $localkeyvalid = false;
                            $localkeyresults['status'] = "Invalid";
                            $results = array();
                        }
                    }
                }
            }
        }
        if (!$localkeyvalid) {
            $responseCode = 0;
            $postfields = array(
                'licensekey' => $licensekey,
                'domain' => $domain,
                'ip' => $usersip,
                'dir' => $dirpath,
            );
            if ($check_token) $postfields['check_token'] = $check_token;
            $query_string = '';
            foreach ($postfields AS $k=>$v) {
                $query_string .= $k.'='.urlencode($v).'&';
            }
            if (function_exists('curl_exec')) {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $whmcsurl . $verifyfilepath);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
                curl_setopt($ch, CURLOPT_TIMEOUT, 30);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                if ($usersip == '127.0.0.1') {
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                }
                $data = curl_exec($ch);
                $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);
            } else {
                $responseCodePattern = '/^HTTP\/\d+\.\d+\s+(\d+)/';
                $fp = @fsockopen($whmcsurl, 80, $errno, $errstr, 5);
                if ($fp) {
                    $newlinefeed = "\r\n";
                    $header = "POST ".$whmcsurl . $verifyfilepath . " HTTP/1.0" . $newlinefeed;
                    $header .= "Host: ".$whmcsurl . $newlinefeed;
                    $header .= "Content-type: application/x-www-form-urlencoded" . $newlinefeed;
                    $header .= "Content-length: ".@strlen($query_string) . $newlinefeed;
                    $header .= "Connection: close" . $newlinefeed . $newlinefeed;
                    $header .= $query_string;
                    $data = $line = '';
                    @stream_set_timeout($fp, 20);
                    @fputs($fp, $header);
                    $status = @socket_get_status($fp);
                    while (!@feof($fp)&&$status) {
                        $line = @fgets($fp, 1024);
                        $patternMatches = array();
                        if (!$responseCode
                            && preg_match($responseCodePattern, trim($line), $patternMatches)
                        ) {
                            $responseCode = (empty($patternMatches[1])) ? 0 : $patternMatches[1];
                        }
                        $data .= $line;
                        $status = @socket_get_status($fp);
                    }
                    @fclose ($fp);
                }
            }
            if ($responseCode != 200) {
                $localexpiry = date("Ymd", mktime(0, 0, 0, date("m"), date("d") - ($localkeydays + $allowcheckfaildays), date("Y")));
                if ($originalcheckdate > $localexpiry) {
                    $results = $localkeyresults;
                } else {
                    $results = array();
                    $results['status'] = "Invalid";
                    $results['description'] = "Remote Check Failed";
                    return $results;
                }
            } else {
                preg_match_all('/<(.*?)>([^<]+)<\/\\1>/i', $data, $matches);
                $results = array();
                foreach ($matches[1] AS $k=>$v) {
                    $results[$v] = $matches[2][$k];
                }
            }
            if (!is_array($results)) {
                die("Invalid License Server Response");
            }
            if ($results['md5hash']) {
                if ($results['md5hash'] != md5($licensing_secret_key . $check_token)) {
                    $results['status'] = "Invalid";
                    $results['description'] = "MD5 Checksum Verification Failed";
                    return $results;
                }
            }
            if ($results['status'] == "Active") {
                $results['checkdate'] = $checkdate;
                $data_encoded = json_encode($results);
                $data_encoded = base64_encode($data_encoded);
                $data_encoded = md5($checkdate . $licensing_secret_key) . $data_encoded;
                $data_encoded = strrev($data_encoded);
                $data_encoded = $data_encoded . md5($data_encoded . $licensing_secret_key);
                $data_encoded = wordwrap($data_encoded, 80, "\n", true);
                $results['localkey'] = $data_encoded;
            }
            $results['remotecheck'] = true;
        }
        unset($postfields,$data,$matches,$whmcsurl,$licensing_secret_key,$checkdate,$usersip,$localkeydays,$allowcheckfaildays,$md5hash);
        return $results;
    }
}