# wt-security/3.0.1/lib/API.php

WebTotem Security, version 3.0.1. 1,288 lines.

- Page: https://pluginprobe.com/plugins/wt-security/3.0.1/code/lib/API.php
- Raw: https://pluginprobe.com/plugins/wt-security/3.0.1/raw/lib/API.php
- Modified: 2026-05-15T03:23:06+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wt-security/3.0.1/code/lib/API.php#L10-L20`.

```php
<?php

if (!defined('WEBTOTEM_INIT') || WEBTOTEM_INIT !== true) {
    if (!headers_sent()) {
        header('HTTP/1.1 403 Forbidden');
    }
    die("Protected By WebTotem!");
}

/**
 * WebTotem API class.
 *
 * Mostly contains wrappers for API methods. Check and send methods.
 *
 * @version 1.0
 * @copyright (C) 2022 WebTotem team (http://wtotem.com)
 * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
 */
class WebTotemAPI extends WebTotem
{

    /**
     * Method for getting an auth token.
     *
     * @param string $api_key
     *   Application programming interface key.
     *
     * @return bool|string
     *   Returns auth status
     */
    public static function auth($api_key, $repeat = FALSE)
    {
        $domain = WEBTOTEM_SITE_DOMAIN;

        if (empty($api_key)) {
            return FALSE;
        }

        $data = ['api_key' => $api_key, 'site' => $domain];
        $result = self::sendRequest('auth/sign-in/api-key', $data, 'POST', FALSE, TRUE);

        if($result === null){
            WebTotemOption::setNotification('warning' , __('Authorization failed. The server may be temporarily unavailable', 'wtotem'));
        }

        if (isset($result['access_token'])) {
            $auth_token = $result['access_token'];
            if(!WebTotemOption::isActivated()){
                WebTotemOption::login(['token' => $auth_token, 'api_key' => $api_key]);
                WebTotemAgentManager::postdelete();
            } else {
                WebTotemOption::refreshToken($auth_token);
            }

            return 'success';
        } elseif (isset($result['message']) and $result['message'] == 'invalid credentials') {
            WebTotemOption::logout();
        }

        if($repeat == false){
            //self::checkEndpoint();
            return self::auth($api_key, true);
        }

        return FALSE;
    }

    /**
     * Method for getting API url.
     *
     * @return string|bool
     *   API url
     */
    public static function getApiUrl()
    {
        return 'https://app.wtotem.com';
    }


    /**
     * Get site info from API server.
     *
     * @param string $attempt
     *   Is the request an attempt to get host data.
     *
     * @return array
     *   Returns host data.
     */
    public static function siteInfo($attempt = FALSE)
    {
        if (self::isMultiSite()) {
            $host['id'] = WebTotemOption::getSessionOption('host_id');
            $host['name'] = WebTotemOption::getSessionOption('host_name');

            if ($host['id']) {
                return $host;
            }
        }

        $host = WebTotemOption::getHost();

        if ($host['id']) {
            return $host;
        }

//        if (self::isMultiSite()) {
//            $sites = get_sites();
//            foreach ($sites as $site) {
//                $domain = untrailingslashit($site->domain . $site->path);
//                self::addSite($domain);
//            }
//
//            if (!$attempt) {
//                return self::siteInfo(TRUE);
//            }
//        } else {
//            $domain = WEBTOTEM_SITE_DOMAIN;
//            return self::addSite($domain);
//        }
        $domain = WEBTOTEM_SITE_DOMAIN;
        return self::addSite($domain);

//        return [];
    }

    /**
     * Method for adding a site to the WebTotem platform.
     *
     * @param string $domain
     *   Domain to add.
     *
     * @return array
     *   Returns host data.
     */
    public static function addSite($domain)
    {
        if (function_exists('idn_to_utf8')) {
            $domain = idn_to_utf8($domain);
        }

        // Checking if the site has been added to the WebTotem.
        if(!$host = self::getHostID($domain)){
            $host = self::getHostID('www.' . $domain);
        }

        if($host['id']){
            return [
                'id' => $host['id'],
                'name' => $host['hostname'],
            ];
        }
        
        // If the site is not added then try to add.
        $data = ['hosts' => [$domain]];
        $response = self::sendRequest('hosts', $data, 'POST', TRUE);

        if (isset($response['message'])) {
            WebTotemOption::setNotification('error', __('Failed to add the site to the WebTotem platform.', 'wtotem'));
        } else {
            if ($response['data']['added']) {
                // If it added, save site ID.
                $host = self::getHostID($domain);
                WebTotemOption::setHost($domain, $host['id']);
                return [
                    'id' => $host['id'],
                    'name' => $host['hostname'],
                ];
            }
        }
        return [];
    }

    /**
     * Get all sites from API.
     *
     * @param string $page_num
     *   Mark for loading data.
     * @param string $limit
     *   Limit of sites to loading.
     *
     * @return array
     *   Returns host data.
     */
    public static function getSites($page_num = 1, $page_size = 15, $status = 'active')
    {
        $result = self::sendRequest('hosts', ['page_num' => $page_num, 'page_size' => $page_size, 'status' => $status], 'GET', TRUE);

        if (isset($result['Data'])) {
            return $result['Data'];
        }

        return [];
    }

    /**
     * Check the site's presence in the list on the API side.
     *
     * @param string $site
     *   The domain we want to check.
     *
     * @return array
     *   Returns host data.
     */
    public static function getHostID($site)
    {
        $result = self::sendRequest('hosts/id', ['hostname' => $site], 'GET', TRUE);

        if (isset($result['data'])) {
            WebTotemOption::setOptions(['config_id' => $result['data']['config_id']]);
            return ['id' => $result['data']['host_id'], 'hostname' => $site];
        }

        return ['id' => '', 'hostname' => ''];
    }


    /**
     * Method to get the agents file names and AM file link.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array
     *   Returns agents files data.
     */
    public static function getAgentsFiles($host_id)
    {

//        if (WebTotem::isMultiSite()) {
//            $all_hosts = WebTotemOption::getOption('all_hosts');
//            $all_hosts = $all_hosts ? json_decode($all_hosts, true) : [];
//
//            $siteIdsArray = $all_hosts ? array_values($all_hosts) : [];
//            $siteIds = $siteIdsArray ? addslashes(WebTotem::convertArrayToString($siteIdsArray)) : '';
//
//            $payload = '{"query":"mutation { auth { am { installMultisite(mainSiteId: \"' . $host_id . '\", siteIds: [' . $siteIds . ']){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
//            $response = self::sendRequest($payload, TRUE);
//
//            if (isset($response['data']['auth']['am']['installMultisite'])) {
//                return $response['data']['auth']['am']['installMultisite'];
//            }
//        } else {
            $response = self::sendRequest('/agents/' . $host_id . '/install', [], 'POST', TRUE);

            if (isset($response['data'])) {
                return $response['data'];
            }
//        }
        return [];
    }

    /**
     * Add secondary MultiSite host.
     *
     * @param $new_sites
     *   An array with sites to add.
     *
     * @return void.
     */
    public static function addMultiSiteNewSites($new_sites)
    {

    }

    /**
     * Get the date of creation of the site.
     *
     * @param string $site
     *   The domain we want to check.
     *
     * @return string|bool
     *   Returns host data.
     */
    public static function getGetSiteAddedDate($site)
    {
        $payload = '{"query": "query getSites { auth { viewer { sites { list(filter: { search: \"'. $site .'\" }) {  edges{ node{ createdAt } } } } } } }" }';
        $result = self::sendRequest($payload, true);

        if (isset($result['data']['auth']['viewer']['sites']['list']['edges'][0]['node']['createdAt'])) {
            return $result['data']['auth']['viewer']['sites']['list']['edges'][0]['node']['createdAt'];
        }

        return false;
    }

    /**
     * Remove secondary MultiSite host.
     *
     * @param $host_id
     *   Host id on WebTotem.
     *
     * @return bool
     *    Returns result removing host.
     */
    public static function removeMultiSiteHost($host_id)
    {

        return false;
    }

    /**
     * Method to get agents (AM, WAF, AV) statuses.
     *
     * @return array
     *   Returns agents statuses data.
     */
    public static function getAgentsStatusesFromAPI()
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/agents/' . $config_id . '/status', [], 'GET', TRUE);

        if (isset($response['data'])) {
            return $response['data'];
        }

        return [];
    }

    /**
     * Method to get user time zone.
     *
     * @return string|bool
     *   Returns time zone data.
     */
    public static function getTimeZone()
    {
        $payload = '{"query":"query { auth { viewer{ timezone } } } "}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['timezone'])) {
            return $response['data']['auth']['viewer']['timezone'];
        }
        return FALSE;
    }

    /**
     * Method for get monitoring data.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param int|array $days
     *   For what period data is needed.
     *
     * @return array
     *   Returns all data.
     */
    public static function getMonitoringData($host_id, $days = 7)
    {
        $response = self::sendRequest('/dashboard/monitoring/' . $host_id . '/results', [], 'GET', TRUE);

        if (isset($response['data'])) {
            return $response['data'];
        }

        return [];
    }


    /**
     * Method for get all the site security data.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array
     *   Returns all data.
     */
    public static function getMonitoring($host_id)
    {

        $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) {  domain { lastScanResult { isTaken hasSite redirectLink isLocal protection ips { ip location } status time  } } sslResults{ results{ certStatus certIssuerName certExpiryDate certIssueDate } } ssl { status daysLeft expiryDate issueDate } reputation { status lastTest { time } virusList { virus{ type path } antiVirus } } } } } } }","variables":{"id":"' . $host_id . '"}}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one'])) {
            return $response['data']['auth']['viewer']['sites']['one'];
        }

        return [];
    }

    /**
     * Method to get firewall data.
     *
     * @param int $limit
     *   Limit on the number of records.
     * @param string $page
     *   Page for loading data.
     * @param int|array $days
     *   For what period data is needed.
     *
     * @return array
     *   Returns firewall data.
     */
    public static function getFirewall($limit = 20, $page = 1, $days = 365)
    {
        $period = WebTotem::getPeriod($days);

        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/firewall/' . $config_id . '/logs', [
            'page_num' => $page,
            'page_size' => $limit,
            'from' => $period['from'],
            'to' => $period['to']
        ], 'GET', TRUE);


        if (isset($response['data'])) {
            return $response['data'];
        }

        return [];
    }

    /**
     * Method to get firewall chart data.
     *
     * @param int $days
     *   For what period data is needed.
     *
     * @return array
     *   Returns firewall chart data.
     */
    public static function getFirewallStatistics($days = 7)
    {
        $period = WebTotem::getPeriod($days);

        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/firewall/' . $config_id . '/statistics', [
            'from' => $period['from'],
            'to' => $period['to']
        ], 'GET', TRUE);


        if (isset($response['data'])) {
            return $response['data'];
        }

        return [];
    }

    /**
     * Method to get firewall settings.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function getFirewallSettings()
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response =  self::sendRequest('/dashboard/firewall/' . $config_id . '/configs', [], 'GET', TRUE);
        if (isset($response['data'])) {
            return $response['data'];
        }

        return [];
    }

    /**
     * Method to set firewall settings.
     *
     * @param array $settings
     *   User-specified settings.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function setFirewallSettings(array $settings)
    {
        $config_id = WebTotemOption::getOption('config_id');
        return self::sendRequest('/dashboard/firewall/' . $config_id . '/configs', $settings, 'PATCH', TRUE);
    }


    /**
     * Method to get antivirus history data.
     *
     * @param int $page_num
     *   Page number.
     * @param int $page_size
     *   Number of entries per page.
     *
     * @return array
     *   Returns antivirus history data.
     */
    public static function getAntivirusHistory($page_num = 1, $page_size = 10)
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/antivirus/' . $config_id . '/history', [
            'page_num' => $page_num,
            'page_size' => $page_size
        ], 'GET', TRUE);

        if (isset($response['data'])) {
            return $response['data'];
        }
        return [];
    }

    /**
     * Method to get antivirus history details data.
     *
     * @param int $scan_id
     *    Scan ID.
     * @param int $page_num
     *   Page number.
     * @param int $page_size
     *   Number of entries per page.
     *
     * @return array
     *   Returns antivirus history data.
     */
    public static function getAntivirusHistoryDetails($scan_id, $page_num = 1, $page_size = 10)
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/antivirus/' . $config_id . '/history/' . $scan_id . '/details', [
            'page_num' => $page_num,
            'page_size' => $page_size
        ], 'GET', TRUE);


        if (isset($response['data'])) {
            return $response['data'];
        }
        return [];
    }

    /**
     * Method to get quarantine data.
     *
     * @param int $page_num
     *   Page number.
     * @param int $page_size
     *   Number of entries per page.
     *
     * @return array
     *   Returns quarantine data.
     */
    public static function getAntivirusCurrentDetails($page_num = 1, $page_size = 5)
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/antivirus/' . $config_id . '/current/details', [
            'page_num' => $page_num,
            'page_size' => $page_size
        ], 'GET', TRUE);

        if (isset($response['data'])) {
            return $response['data'];
        }
        return [];
    }


    /**
     * Method to force check Antivirus.
     *
     * @return mixed
     *   Returns information whether the request was successful.
     */
    public static function forceCheckAV()
    {
        $config_id = WebTotemOption::getOption('config_id');
        return self::sendRequest('/dashboard/antivirus/' . $config_id . '/check', [], 'POST', TRUE);
    }


    /**
     * Method to force check services.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param string $module_name
     *   Service that needs to be checked.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function forceCheck($host_id, $module_name)
    {
        return self::sendRequest('/dashboard/hosts/' . $host_id . '/check', ['module_name' => $module_name], 'POST', TRUE);
    }

    /**
     * Method to get quarantine data.
     *
     * @param int $page_num
     *   Page number.
     * @param int $page_size
     *   Number of entries per page.
     *
     * @return array
     *   Returns quarantine data.
     */
    public static function getQuarantineList($page_num = 1, $page_size = 5)
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/antivirus/' . $config_id . '/quarantine', [
            'page_num' => $page_num,
            'page_size' => $page_size
        ], 'GET', TRUE);

        if (isset($response['data'])) {
            return $response['data'];
        }
        return [];
    }

    /**
     * Method to move file to quarantine.
     *
     * @param string $path
     *   Path to the file.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function moveToQuarantine($path)
    {
        $config_id = WebTotemOption::getOption('config_id');

        return self::sendRequest('/dashboard/antivirus/' . $config_id . '/quarantine/' . $path . '/to-quarantine',
            [], 'POST', TRUE);
    }

    /**
     * Method to move file from quarantine.
     *
     * @param string $path
     *   Path to the file.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function moveFromQuarantine($path)
    {
        $config_id = WebTotemOption::getOption('config_id');
        return self::sendRequest('/dashboard/antivirus/' . $config_id . '/quarantine/' . $path . '/from-quarantine',
            [], 'POST', TRUE);
    }

    /**
     * Method to get server status data.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param int|array $days
     *   For what period data is needed.
     *
     * @return array
     *   Returns server status data.
     */
    public static function getServerStatusData($host_id, $days = 7)
    {
        $period = WebTotem::getPeriod($days);
        $payload = '{ "query":"query($id: ID!, $dateRange: DateRangeInput!) { auth { viewer { sites { one(id: $id) { serverStatus { info { phpVersion phpServerUser phpServerSoftware phpGatewayInterface phpServerProtocol osInfo cpuCount cpuModel CpuFreq cpuFamily lsCpu maxExecTime mathLibraries } ramChart(dateRange: $dateRange){ total value time } cpuChart(dateRange: $dateRange){ value time } } } } } } }", "variables":{"id":"' . $host_id . '","dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} } }';

        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one']['serverStatus'])) {
            return $response['data']['auth']['viewer']['sites']['one']['serverStatus'];
        }

        return [];
    }

    /**
     * Method to remove port from ignore list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param string $port
     *   User specified port.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function removeIgnorePort($host_id, $port)
    {
        $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . $port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { removeIgnorePort(input: $input) } } } }"} ';
        return self::sendRequest($payload, TRUE);
    }

    /**
     * Method to add port to ignore list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param string $port
     *   User specified port.
     *
     * @return array
     *   Returns information whether the request was successful.
     */
    public static function addIgnorePort($host_id, $port)
    {
        $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . (int)$port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { addIgnorePort(input: $input) } } } }"} ';
        return self::sendRequest($payload, TRUE);
    }

    /**
     * Method to get all ports list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array
     *   Returns ports data.
     */
    public static function getAllPortsList($host_id)
    {
        $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { ports { status lastTest { time } ignorePorts TCPResults{ port technology version cveList{id summary } } UDPResults { port technology version cveList{id summary } } }  } } } } } ","variables":{"id":"' . $host_id . '"}}';

        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one']['ports'])) {
            return $response['data']['auth']['viewer']['sites']['one']['ports'];
        }

        return [];
    }

    /**
     * Method to get all ports list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array
     *   Returns ports data.
     */
    public static function getOpenPaths($host_id)
    {
        $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { openPathSearch { time paths { httpCode severity path } }  } } } } } ","variables":{"id":"' . $host_id . '"}}';

        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one']['openPathSearch'])) {
            return $response['data']['auth']['viewer']['sites']['one']['openPathSearch'];
        }

        return [];
    }

    /**
     * Method to get all reports.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param int $limit
     *   Limit on the number of records.
     * @param string $cursor
     *   Mark for loading data.
     *
     * @return array
     *   Returns reports data.
     */
    public static function getAllReports($host_id, $limit = 10, $cursor = NULL)
    {
        $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
        $payload = '{"variables":{"filter": { "order": { "direction": "DESC", "field": "created_at"}, "siteId":"' . $host_id . '", "pagination":{"first":' . $limit . ', "cursor":' . $cursor . '} } },"query":"query ReportsQuery($filter: ReportListFilter!) { auth { viewer { reports { list(filter: $filter) { edges { node { id site { hostname } createdAt wa dc ps rc sc av waf } cursor } pageInfo { endCursor hasNextPage } } } } } }"}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['reports']['list']['edges'])) {
            return $response['data']['auth']['viewer']['reports']['list'];
        }

        return [];
    }

    /**
     * Method to generate report.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param int|array $days
     *   For what period data is needed.
     * @param array $services
     *   User-specified module settings.
     *
     * @return string|bool
     *   Returns report download link.
     */
    public static function generateReport(string $host_id, $days, array $services)
    {
        $period = WebTotem::getPeriod($days);
        $language = WebTotem::getLanguage();

        $payload = '{"query":"query ($input: GenerateReportInput) { auth { viewer { reports { generate(input: $input) } } } }", "variables":{ "input": { "siteId": "' . $host_id . '", "from": ' . $period['from'] . ', "to": ' . $period['to'] . ', "wa": ' . $services['wa'] . ', "dc": ' . $services['dc'] . ', "ps": ' . $services['ps'] . ', "rc": ' . $services['rc'] . ', "sc": ' . $services['sc'] . ', "av": ' . $services['av'] . ', "waf": ' . $services['waf'] . ', "language": "' . $language . '" } } }';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['reports']['generate'])) {
            return $response['data']['auth']['viewer']['reports']['generate'];
        }

        return FALSE;
    }

    /**
     * Method to download report.
     *
     * @param string $id
     *   Assigned to the report.
     *
     * @return string|bool
     *   Returns report download link.
     */
    public static function downloadReport($id)
    {
        $payload = '{"query": "query { auth { viewer { reports { download(id: \"' . $id . '\") } } } }"}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['reports']['download'])) {
            return $response['data']['auth']['viewer']['reports']['download'];
        }

        return FALSE;
    }

    /**
     * Method to get configs data.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array|bool
     *   Returns configs data.
     */
    public static function getConfigs($host_id)
    {
        $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"' . $host_id . '\"){ configs{ ... on WaConfig { id service isActive notifications } ... on WafConfig { id service isActive notifications } ... on AvConfig { id service isActive notifications } ... on DcConfig { id service isActive notifications } ... on DecConfig { id service isActive } ... on RcConfig { id service isActive notifications} ... on CmsConfig { id service isActive } ... on PsConfig { id service isActive notifications } ... on SsConfig { id service isActive } ... on ScConfig { id service isActive } } } } } } }  "}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one']['configs'])) {
            return $response['data']['auth']['viewer']['sites']['one']['configs'];
        }

        return FALSE;
    }

    /**
     * Method to toggle modules config.
     *
     * @param string $service_id
     *   Service id that we enable or disable.
     *
     * @return string|bool
     *   Returns information whether the request was successful.
     */
    public static function toggleConfigs($service_id)
    {
        $payload = '{"query":"mutation{ auth{ configs{ toggle(id: \"' . $service_id . '\"){ ... on WaConfig { service isActive } ... on AvConfig { service isActive } ... on DcConfig { service isActive } ... on DecConfig { service isActive } ... on RcConfig { service isActive } ... on CmsConfig { service isActive } ... on PsConfig { service isActive } ... on WafConfig { service isActive } } } } }   "}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['configs']['toggle'])) {
            return $response['data']['auth']['configs']['toggle'];
        }

        return FALSE;
    }

    /**
     * Method to toggle modules notification.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param string $service
     *   Service id in which we enable or disable notifications.
     *
     * @return string|bool
     *   Returns information whether the request was successful.
     */
    public static function toggleNotifications($host_id, $service)
    {
        $payload = '{"query":"mutation{ auth{ sites{ toggleNotifications(siteId: \"' . $host_id . '\", service: ' . $service . ') } } }"}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['sites']['toggleNotifications'])) {
            return $response;//['data']['auth']['sites']['toggleNotifications'];
        }

        return FALSE;
    }

    /**
     * Method to get allow/deny ip list.
     *
     * @param string $type
     *   Type of ip list
     *
     * @return array|bool
     *   Returns ip allow/deny lists.
     */
    public static function getIpLists($type = 'blacklist')
    {
        $config_id = WebTotemOption::getOption('config_id');
        $response = self::sendRequest('/dashboard/firewall/' . $config_id . '/configs/iplist', [
            'type' => $type,
        ], 'GET', TRUE);

        if (isset($response['data'])) {
            return $response['data'];
        }

        return [];
    }

    /**
     * Method to add ip to allow/deny list.
     *
     * @param string $ip
     *   Ip address.
     * @param string $type
     *   Allow or deny type.
     *
     * @return bool
     *   Returns information whether the request was successful.
     */
    public static function addIpToList($ips, $type)
    {
        $config_id = WebTotemOption::getOption('config_id');
        self::sendRequest('/dashboard/firewall/' . $config_id . '/configs/iplist?type=' . $type, [
            'ip' => array_filter($ips),
        ], 'POST', TRUE);

        return true;
    }

    /**
     * Method to remove ip from allow/deny list by id.
     *
     * @param string $ip
     *   Ip address.
     * @param string $type
     *   Allow or deny type.
     *
     * @return bool
     *   Returns information whether the request was successful.
     */
    public static function removeIpFromList($ip, $type)
    {
        $config_id = WebTotemOption::getOption('config_id');
        self::sendRequest('/dashboard/firewall/' . $config_id . '/configs/iplist?type=' . $type, [
            'ip' => $ip,
        ], 'DELETE', TRUE);

        return true;
    }

    /**
     * Method to get allow url list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array
     *   Returns url allow lists.
     */
    public static function getAllowUrlList($host_id)
    {
        $payload = '{"query":"query { auth { viewer { sites { one(id: \"' . $host_id . '\"){ firewall{ urlWhiteList{ id url createdAt } } } } } } }"} ';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'])) {
            return $response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'];
        }

        return [];
    }

    /**
     * Method to add url to allow list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param string $url
     *   User-specified url.
     *
     * @return bool|string
     *   Returns information whether the request was successful.
     */
    public static function addUrlToAllowList($host_id, $url)
    {
        $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "url": "' . $url . '" } }, "query":"mutation($input: WafUrlWhiteListInput!) { auth { sites { waf { addToUrlWhiteList(input: $input) } } } }"} ';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['sites']['waf']['addToUrlWhiteList'])) {
            return $response['data']['auth']['sites']['waf']['addToUrlWhiteList'];
        }

        return FALSE;
    }

    /**
     * Method to remove url from allow list.
     *
     * @param string $id
     *   Id assignment to url address.
     *
     * @return bool|string
     *   Returns information whether the request was successful.
     */
    public static function removeUrlFromAllowList($id)
    {
        $payload = '{"variables":{ "id": "' . $id . '" }, "query":"mutation($id: ID!) { auth { sites { waf { removeFromUrlWhiteList(id: $id) } } } }"} ';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'])) {
            return $response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'];
        }

        return FALSE;
    }

    /**
     * Method to get blocked countries list.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     *
     * @return array
     *   Returns blocked countries list.
     */
    public static function getBlockedCountries($host_id)
    {
        $period = WebTotem::getPeriod(7);
        $payload = '{"variables":{"dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '}} , "query":"query($dateRange: DateRangeInput!){ auth { viewer { sites { one(id: \"' . $host_id . '\"){ firewall{ blockedCountries map(dateRange: $dateRange) { attacks, country, location { country { nameEn } } }  } } } } } }"}';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
            return $response['data']['auth']['viewer']['sites']['one']['firewall'];
        }

        return [];
    }

    /**
     * Method for synchronizing data on the list of blocked countries.
     *
     * @param string $host_id
     *   Host id on WebTotem.
     * @param array $countries
     *   Array of countries to block.
     *
     * @return bool|string
     *   Returns information whether the request was successful.
     */
    public static function syncBlockedCountries($host_id, $countries)
    {

        $countries = $countries ? WebTotem::convertArrayToString($countries) : '';
        $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "countries": [' . $countries . '] } }, "query":"mutation($input: WafBlockedCountriesInput!) { auth { sites { waf { syncBlockedCountries(input: $input) } } } }"} ';
        $response = self::sendRequest($payload, TRUE);

        if (isset($response['data']['auth']['sites']['waf']['syncBlockedCountries'])) {
            return $response['data']['auth']['sites']['waf']['syncBlockedCountries'];
        }

        return FALSE;
    }

    /**
     * Method to get user's email.
     *
     * @return string
     *   Returns user's email.
     */
    public static function getEmail()
    {
        $payload = '{"query":"query { auth { viewer { email  }  } }"}';
        $response = self::sendRequest($payload, true);

        return $response['data']['auth']['viewer']['email'];
    }

    /**
     * Method to get user's email.
     *
     * @param string $plugin_list
     *   List of plugins and their versions.
     *
     * @return array
     *   Returns cve list.
     */
    public static function getCVE($plugin_list)
    {
        $payload = '{"variables":{ "params": [' . $plugin_list . '] }, "query":"query searchByTechnologyAndVersion($params: [SearchByTechnologyAndVersionInput!]) { auth { viewer { cve { searchByTechnologyAndVersion(params: $params) { cves { cve_id id  summary published reference } technology version } } } } }"}';
        $response = self::sendRequest($payload, true);

        if (isset($response['data']['auth']['viewer']['cve']['searchByTechnologyAndVersion'])) {
            return $response['data']['auth']['viewer']['cve']['searchByTechnologyAndVersion'];
        }

        return [];
    }

    /**
     * Method to get user's feedback.
     *
     * @return array
     */
    public static function getFeedback()
    {
        return self::sendFeedbackRequest("GET");
    }

    /**
     * Method to set user's feedback.
     *
     * @return array
     */
    public static function setFeedback($data)
    {
        return self::sendFeedbackRequest("POST", $data);
    }

    /**
     * Function sends data request to endpoint.
     *
     * @param array $data
     *   Data array to be sent to endpoint.
     *
     * @return array
     *   Returns response from WebTotem endpoint.
     */
    protected static function sendFeedbackRequest($method, $data = [])
    {
        $url = 'https://nps.wtotem.com/user-score';
        $email = WebTotem::getUserEmail();

        if (!$email) {
            return [];
        }

        if ($method == "GET") {

            $args = [
                'timeout' => '30',
                'sslverify' => FALSE,
            ];

            $response = wp_remote_get($url . '?email=' . urlencode($email), $args);

        } else {
            $data['email'] = $email;
            $data['platform'] = 'WORDPRESS';
            $data = json_encode($data);

            $args = [
                'body' => $data,
                'timeout' => '30',
                'sslverify' => FALSE,
                'headers' => [
                    'Content-Type' => 'application/json',
                ],
            ];

            $response = wp_remote_post($url, $args);
        }


        $http_code = wp_remote_retrieve_response_code($response);

        if ($http_code < 200) {
            // WebTotemOption::setNotification('error', __('Could not connect to feedback endpoint.', 'wtotem'));
            return [];
        }

        $response_body = wp_remote_retrieve_body($response);
        return json_decode($response_body, true);
    }

    /**
     * Sends a REST API request to the WebTotem API server.
     *
     * @param string $endpoint
     *   REST API endpoint (e.g., 'scan', 'status', etc.).
     * @param array $data
     *   Associative array of data to send as JSON body or query parameters.
     * @param string $method
     *   HTTP method: GET, POST, PUT, DELETE (default is POST).
     * @param bool $useToken
     *   Whether to include the auth token.
     * @param bool $retry
     *   Used to prevent recursion on token renewal.
     *
     * @return array|null
     *   API response as an associative array, or null on failure.
     */
    protected static function sendRequest($endpoint, $data = [], $method = 'POST', $useToken = false, $retry = false)
    {
        $api_key = WebTotemOption::getOption('api_key');

        // Get or initialize the API URL.
        $api_url = WebTotemOption::getOption('api_url');
        if (!$api_url) {
            $api_url = self::getApiUrl();
            WebTotemOption::setOptions(['api_url' => $api_url]);
        }

        $auth_token = null;
        if ($useToken) {
            $auth_token = WebTotemOption::getOption('auth_token');
            $auth_token_expired = WebTotemOption::getOption('auth_token_expired');

            if ($auth_token_expired <= time() && !$retry) {
                $result = self::auth($api_key);
                if ($result === 'success') {
                    return self::sendRequest($endpoint, $data, $method, $useToken, true);
                } elseif (isset($result['message'])) {
                    $message = WebTotem::messageForHuman($result['message']);
//                    WebTotemOption::setNotification('info', '$endpoint: ' . $endpoint);
                    WebTotemOption::setNotification('error', $message);
                }
            }
        }

        $url = rtrim($api_url, '/') . '/api/v1/' . ltrim($endpoint, '/');

        $args = [
            'timeout' => 60,
            'sslverify' => false,
            'headers' => [
                'Accept' => 'application/json',
                'Content-Type' => 'application/json',
                'source' => 'WORDPRESS',
            ],
        ];

        if ($auth_token) {
            $args['headers']['Authorization'] = "Bearer $auth_token";
        }

        if (strtoupper($method) === 'GET') {
            $url = add_query_arg($data, $url);
        } else {
            $args['body'] = json_encode($data);
        }

        $response = wp_remote_request($url, array_merge($args, ['method' => strtoupper($method)]));

        $errors = ['status' => false];
        if (is_wp_error($response)) {
            $errors =  [
                'status' => true,
                'message' => 'SERVER UNAVAILABLE: ' . $response->get_error_message(),
            ];
        }

        $body = wp_remote_retrieve_body($response);
        $decoded = json_decode($body, true);

        if (isset($decoded['message']) or $errors['status']) {
            $errorMessage = $errors['status'] ? $errors['message'] : $decoded['message'];

            if (stripos($errorMessage, "Password expired") !== false) {
                wtotem_error_page(['errors' => 'PASSWORD_EXPIRED']);
                exit();
            } elseif (stripos($errorMessage, "API_KEY_DEACTIVATED") !== false) {
                wtotem_error_page(['errors' => 'TARIFF_EXPIRED']);
                exit();
            }

            $message = WebTotem::messageForHuman($errorMessage);
            if ($errorMessage == "invalid credentials" && !$retry) {

                if (self::auth($api_key) === 'success') {

                    return self::sendRequest($endpoint, $data, $method, $useToken, true);
                }
            } elseif (stripos($errorMessage, "USERHOST_NOT_BELONG_TO_USER") !== false) {
                if (WebTotem::isMultiSite()) {
                    WebTotemOption::clearAllHosts();
                }
                WebTotemOption::clearOptions(['host_id', 'host_name']);
            } else {
//                WebTotemOption::setNotification('info', '$endpoint: ' . $endpoint);
                WebTotemOption::setNotification('error', $message);
            }
        }

//        if (empty($decoded)) {
//            self::checkEndpoint();
//        }

        return $decoded;
    }

}

```
