# wt-security/2.1.7/routes.php

WebTotem Security, version 2.1.7. 633 lines.

- Page: https://pluginprobe.com/plugins/wt-security/2.1.7/code/routes.php
- Raw: https://pluginprobe.com/plugins/wt-security/2.1.7/raw/routes.php
- Modified: 2020-07-13T13:03:04+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/2.1.7/code/routes.php#L10-L20`.

```php
<?php defined('ABSPATH') or die("Protected By WT!");

add_action('admin_menu', 'wtsec_add_menu_link');
add_action('wp_ajax_change_status', 'wtsec_ajax_changeStatus');
add_action('admin_post_change_status', 'wtsec_changeStatus');
add_action('wp_ajax_cmd', 'wtsec_cmd_ajax');
add_action('admin_post_login_form', 'wtsec_login_form');
add_action('admin_post_ajax_cmd', 'wtsec_cmd_ajax');

function wtsec_add_menu_link()
{
    add_menu_page(
        WTSEC_PAGE_TITLE,
        WTSEC_MENU_TITLE,
        'manage_options',
        wtsec_getRoute('dashboard'),
        'wtsec_index_page',
        '',
        '1'
    );
    $parent = wtsec_getRoute('dashboard');
    if (WTSEC_LIBRARY_App::authorized()) {
        $capability = 'manage_options';
        foreach (wtsec_pages() as $page => $arguments) {
            add_submenu_page($parent, $arguments['page_title'], $arguments['menu_title'], $capability, wtsec_getRoute($page), $arguments['function']);
        }
        add_submenu_page(null, WTSEC_LIBRARY_Localization::lmsg('sign_in'), WTSEC_LIBRARY_Localization::lmsg('sign_in'), 'manage_options', wtsec_getRoute('login'), 'wtsec_login');
        add_submenu_page($parent, WTSEC_LIBRARY_Localization::lmsg('logout'), WTSEC_LIBRARY_Localization::lmsg('logout'), 'manage_options', wtsec_getRoute('logout'), 'wtsec_logout');
    } else {
        $capability = 'manage_options';
        foreach (wtsec_pages() as $page => $arguments) {
            add_submenu_page(null, $arguments['page_title'], $arguments['menu_title'], $capability, wtsec_getRoute($page), function () {
                wp_safe_redirect(wtsec_getUrl('login'));
            });
        }
        add_submenu_page($parent, WTSEC_LIBRARY_Localization::lmsg('sign_in'), WTSEC_LIBRARY_Localization::lmsg('sign_in'), 'manage_options', wtsec_getRoute('login'), 'wtsec_login');
        add_submenu_page(null, WTSEC_LIBRARY_Localization::lmsg('logout'), WTSEC_LIBRARY_Localization::lmsg('logout'), 'manage_options', wtsec_getRoute('logout'), 'wtsec_logout');
    }
}

function dd($vl)
{
    echo '<pre>';
    print_r($vl);
    echo '</pre>';
    die();
}

function myGrading($score)
{
    if ($score < 0 || $score > 100) return ['grade' => '','color' => ''];
    if ($score == 100) return ['grade' => 'A+','color' => 'green'];
    $decimal = $score % 10;
    $score = $score / 10;
    $scores = ['F', 'F', 'F', 'F', 'F', 'F', 'C', 'B', 'B', 'A'];
    $colors = ['red', 'red', 'red', 'red', 'red', 'red', 'orange', 'orange', 'orange', 'green'];
    $grade = $scores[$score];
    $color = $colors[$score];
    if ($grade != 'F') {
        if ($decimal <= 2) $grade .= '-';
        else if ($decimal >= 7) $grade .= '+';
    }
    return ['grade' => $grade,'color' => $color];
}


function convertTimeToReadable($date)
{
    $lang = get_locale();
    //enable russian language
    if ($lang === "ru_RU") {
        $lang .= ".UTF-8";
        setlocale(LC_ALL, $lang);
    }
    if(strpos($date, ".") !== false){
        $date = substr($date, 0, strpos($date, "."));
    }
    return strftime("%B %e, %Y / %R", strtotime($date." UTC"));
}


function convertToCurrentTime($date)
{
    $lang = get_locale();
    //enable russian language
    if ($lang === "ru_RU") {
        $lang .= ".UTF-8";
        setlocale(LC_ALL, $lang);
    }
    if(strpos($date, ".") !== false){
        $date = substr($date, 0, strpos($date, "."));
    }
    $date .= " UTC";
    $current_time = strtotime($date);
    return ['date' => date("Y-m-d", $current_time),'time' => date("H:i:s",$current_time)];
}

function wtsec_index_page()
{
    $host = WTSEC_LIBRARY_WT::getOwnSite();
    $services = [];
    if (!empty($host)) {
        $services = [
            "settings" => [
                "token" => WTSEC_LIBRARY_App::getToken(),
                "site_id" => $host['id'],
            ],
            "score" => [
                "total_score" => 0,
                "tested_on" => "",
                "server_ip" => "",
                "location" => "",
                "description" => wtsec_locale("score.description"),
                "information" => "",
                "grade" => "",
            ],
        ];

        $score = json_decode(WTSEC_LIBRARY_WT::getScore(), true);
        if (!empty($score)) {
            $total_score = round($score['totalScore']);
            $my_grading = myGrading($total_score);
            $services["score"] = [
                "total_score" => $total_score."%",
                "tested_on" => convertTimeToReadable($score['date']),
                "server_ip" => $score['ip'],
                "location" => $score['country'],
                "description" => wtsec_locale("score.description"),
                "information" => wtsec_locale("score.higher_than_percent", ['percent' => $score['ishigherthan']]),
                "grade" => $my_grading['grade'],
                "color" => $my_grading['color'],
            ];
        }

        $checks = WTSEC_LIBRARY_WT::getAllChecks($host['id']);
        foreach ($checks as $service => $site) {
            if (empty($site) || !is_array($site)) {
                continue;
            }
            switch ($service) {
                case "availability":
                    $services["wa"] = [
//                        "pause" => wtsec_getStatusStartPauseIcon($site['config']['isActive'], $site['config']['id'], $host['id']),
                        "pause" => "",
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "response_time" => ceil($site['responseTime'] / 1000000) . ' ' . WTSEC_LIBRARY_Localization::lmsg('ms'),
                        "availability" => $site['percent'] . '%',
                        "availability_percent" => $site['percent'],
                        "last_test" => convertTimeToReadable($site['lastTest']['time']),
                        "downtime" => ceil($site['downTime'] / 1000000) . ' ' . WTSEC_LIBRARY_Localization::lmsg('ms'),
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.availability')
                    ];
                    break;
                case "ssl":
                    if ((int)$site['expiryDate'] === 0) {
                        $days_left = 0;
                    } else {
                        $earlier = new DateTime();
                        $later = new DateTime($site['expiryDate']);
                        $days_left = $later->diff($earlier)->format("%a");
                    }
                    $services["ssl"] = [
                        "pause" => "",
                        "information" => wtsec_getInformation($service, $site['status']),
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "days_left" => $days_left,
                        "issue_date" => $site['issueDate'],
                        "expiry_date" => $site['expiryDate'],
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.ssl'),
                        "solve_it" => in_array($site['status'],['clean','pending']) ? '' : wtsec_locale('solve_it'),
                    ];
                    break;
                case "domain":
                    if ((int)$site['expiredDate'] === 0) {
                        $days_left = 0;
                    } else {
                        $earlier = new DateTime();
                        $later = new DateTime($site['expiredDate']);
                        $days_left = $later->diff($earlier)->format("%a");
                    }

                    $services["dec"] = [
                        "pause" => "",
                        "registrar" => $site['registrar'],
                        "owner" => $site['owner'],
                        "information" => wtsec_getInformation($service, $site['status']),
                        "email" => $site['email'],
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "days_left" => $days_left,
                        "created" => $site['createdDate'],
                        "expiry_date" => $site['expiredDate'],
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.domain')
                    ];
                    break;
                case "reputation":
                    $count = 0;
                    if ($site['status'] != "clean") {
                        foreach ($site['virusList'] as &$list) {
                            if (!empty($list['viruses'])) {
                                $count++;
                            }
                        }
                    }
                    $services["av"] = [
                        "pause" => "",
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "time_of_the_last_test" => convertTimeToReadable($site['lastTest']['time']),
                        "blacklists_entries" => $count,
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.reputation'),
                        "reputation" => $site['status'] === "infected" ? wtsec_locale('bad_reputation') : wtsec_locale('good_reputation'),
                    ];
                    break;
                case "maliciousScript":
                    $services["cms"] = [
                        "pause" => "",
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "time_of_the_last_test" => $site['lastTest']['time'],
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.malicious')
                    ];
                    break;
                case "deface":
                    $services["dc"] = [
                        "pause" => "",
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "time_of_the_last_test" => convertTimeToReadable($site['lastTest']['time']),
                        "number" => $site['count'],
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.deface')
                    ];
                    break;
                case "ports":
                    $services["ps"] = [
                        "pause" => "",
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "ip" => $site['ip'],
                        "last_test" => convertTimeToReadable($site['lastTest']['time']),
                        "number" => count($site['tcp']),
                        "tcp" => !empty($site['tcp']) ? implode(",", $site['tcp']) : '',
                        "udp" => "",
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.port')
                    ];
                    break;
                case "firewall":
                    $service = "WAF";
                    $_service = strtolower($service);
                    $domain = $host['hostname'];
                    $uid = $host['id'];

                    $chart = generateChart($site['chart']);
//                    $status = wtsec_checkStatus($uid, $service);

                    $data = WTSEC_LIBRARY_WT::getFirewall($host['id']);
                    $data = $data['data']['auth']['viewer']['sites']['one']['firewall'];

                    $countryAttacks = getCountryAttacks($data['map'], $chart['count_attacks']);
                    $edges = $data['logs']['edges'];

                    $services["waf"] = [
                        "pause" => "",
                        "site_address" => $domain,
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "_status" => $site['status'],
                        "installed_status" => in_array($site['status'], ["not_installed", "error", "down", "not_supported", "not_registered"]) ? false : true,
                        "time_of_the_last_check" => convertTimeToReadable($site['lastTest']['time']),
                        "attacks" => $chart['count_attacks'],
                        "blocking" => $chart['count_blocks'],
                        "non-blocking" => $chart['count_attacks'] - $chart['count_blocks'],
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.firewall'),
                        "actions" => wtsec_generateButtons($uid, $_service, $service, $site['status'], WTSEC_SITE_URL),
                        "chart" => json_encode($chart['chart'], true),
                        "edges" => $edges,
                        "countryAttacks" => $countryAttacks,
                    ];
                    break;
                case "antivirus":
                    $service = "AV";
                    $_service = strtolower($service);
                    $domain = $host['hostname'];
                    $uid = $host['id'];
//                    $status = wtsec_checkStatus($uid, $service);
                    $services["vc"] = [
                        "pause" => "",
                        "site_address" => $domain,
                        "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                        "installed_status" => in_array($site['status'], ["not_installed", "error", "down", "not_supported", "not_registered"]) ? false : true,
                        "_status" => $site['status'],
                        "signatures" => (int)$site['stats']['infected'],
                        "changes" => (int)$site['stats']['changed'],
                        "scanned" => (int)$site['stats']['scaned'],
                        "deleted" => (int)$site['stats']['deleted'],
                        "list" => $site['stats']["infected"],
                        "actions" => wtsec_generateButtons($uid, $_service, $service, $site['status'], WTSEC_SITE_URL),
                        "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.antivirus')
                    ];
                    break;
            }
        }


        //check AM, if not installed , run install
        $process = "installing";
        $check_am_file = wtsec_checkInstalledFile("AM");
        $am_installed = $check_am_file["status"];
        $am_installed_status = wtsec_app()->get('am_installed');
        if (!$am_installed && !$am_installed_status) {
            $am_is_installed = wtsec_cmd("am_install", "AM", "am", $host['id'], [], WTSEC_SITE_URL);
            if (!$am_is_installed) {
                $process = "failed";
                wtsec_app()->set('am_installed', false);
            } else {
                wtsec_app()->set('am_installed', true);
            }
        } elseif ($services["vc"]["_status"] === "not_installed" || $services["waf"]["_status"] === "not_installed") {
            $process = "installing";
        } else {
            $process = "installed";
        }

        $services["am"] = [
            "status" => WTSEC_LIBRARY_WT::getStatusIcon($am_installed ? "working" : "not_installed"),
            "actions" => wtsec_generateButtons($host['id'], "am", "AM", ["active" => $check_am_file], WTSEC_SITE_URL),
            "process_status" => $process,
            "installed" => $am_installed,
        ];
    }

    wtsec_layout("dashboard", $services);
}

function getCountryAttacks($map, $countAttacks){

    if($map){
        $attackKey = array_search(max(array_column($map, 'attacks')), array_column($map, 'attacks'));
        $map[$attackKey]['percent'] = round($map[$attackKey]['attacks'] / $countAttacks * 100);
        $map[$attackKey]['country'] = wtsec_locale("countries.".$map[$attackKey]['country']);
        return $map[$attackKey];
    }

    return ['percent' => 0, 'country' => false];

}

function generateChart($charts)
{
    $count_attacks = 0;
    $count_blocks = 0;
    $d = date("d");
    $m = date("m");
    $y = date("Y");
    $c = [];
    $first_day = $d - 6;
    if ($first_day < 1) {
        $lastmonth = (int)date('d', strtotime('last day of previous month'));
        $lastmonth_day = $lastmonth;
        $lastmonth_month = (int)date('m', strtotime('last day of previous month'));
        $lastmonth_year = (int)date('Y', strtotime('last day of previous month'));
        $lastmonth = $lastmonth - ($first_day * -1);
        for ($i = $lastmonth; $i <= $lastmonth_day; $i++) {
            $c[$i] = [
                'date' => $lastmonth_year.'-'.$lastmonth_month.'-'.$lastmonth_day,
                'count' => 0,
                'attacks' => 0,
                'blocked' => 0,
            ];
        }
        $first_day = 1;
    }
    for ($i = $first_day; $i <= $d; $i++) {
        $c[$i] = [
            'date' => $y.'-'.$m.'-'.$i,
            'count' => 0,
            'attacks' => 0,
            'blocked' => 0,
        ];
    }
    foreach ($charts as $chart) {
        $d = (int)date("d", strtotime($chart['time']));
        $c[$d]['count'] = $chart['blocked'];
        $c[$d]['attacks'] = $chart['attacks'];
        $c[$d]['blocked'] = $chart['blocked'];
        $count_attacks += $chart['attacks'];
        $count_blocks += $chart['blocked'];
    }

    //unset keys, because the js parser sorting by key in integer
    $result = [];
    foreach ($c as $d) {
        $result[] = $d;
    }
    return ['chart' => $result, 'count_attacks' => $count_attacks, 'count_blocks' => $count_blocks];
}

function wtsec_getInformation($service, $status)
{
    $information = [
        "ssl" => [
            WTSEC_LIBRARY_Localization::lmsg("statuses.ok"),
            WTSEC_LIBRARY_Localization::lmsg("statuses.invalid"),
            WTSEC_LIBRARY_Localization::lmsg("statuses.expired"),
            WTSEC_LIBRARY_Localization::lmsg("statuses.expires"),
            "unknown_status" => WTSEC_LIBRARY_Localization::lmsg("statuses.missing"),
        ],
        "domain" => [
            WTSEC_LIBRARY_Localization::lmsg("statuses.ok"),
            WTSEC_LIBRARY_Localization::lmsg("statuses.expires"),
            "unknown_status" => WTSEC_LIBRARY_Localization::lmsg("statuses.error"),
        ]
    ];
    return isset($information[$service][$status]) ? $information[$service][$status] : $information[$service]["unknown_status"];
}

function wtsec_getStatusStartPauseIcon($status, $config_id, $host_id)
{
    $icon = '';
    switch ($status) {
        case "1":
            $icon = '<div class="v-pause ww-icon ww-icon--pause" style="border:none" data-config_id="' . $config_id . '" data-host_id="' . $host_id . '"></div>';
            break;
        case "0":
            $icon = '<div class="v-pause ww-icon ww-icon--play" style="border:none" data-config_id="' . $config_id . '" data-host_id="' . $host_id . '"></div>';
            break;
    }
    return $icon;
}

function wtsec_options_page()
{
    $host = WTSEC_LIBRARY_WT::getOwnSite();
    $result = WTSEC_LIBRARY_WT::getOptions($host['id']);
    $options = [];
    if (isset($result['data']['userHost']['services'])) {
        foreach ($result['data']['userHost']['services'] as $service) {
            $configs = $service['configs'][0];
            $options[$service['name']] = ['config_id' => $configs['id'], 'is_active' => $configs['isActive']];
        }
    }
    $options['host_id'] = $host['id'];
    wtsec_layout("options", $options);
}

function wtsec_services_page()
{
    wtsec_layout("services");
}

function wtsec_antivirus_page()
{
    $host = WTSEC_LIBRARY_WT::getOwnSite();
    $services = [];
    if (!empty($host)) {
        $site = WTSEC_LIBRARY_WT::getAntivirus($host['id']);
        if (isset($site['data']['auth']['viewer']['sites']['one']['antivirus']['log'])) {
            $site = $site['data']['auth']['viewer']['sites']['one']['antivirus'];
            $service = "AV";
            $_service = strtolower($service);
            $domain = $host['hostname'];
            $uid = $host['id'];
            $status = wtsec_checkStatus($uid, $service);
            $services["vc"] = [
                "pause" => "",
                "site_address" => $domain,
                "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                "signatures" => (int)$site['stats']['infected'],
                "changes" => (int)$site['stats']['changed'],
                "scanned" => (int)$site['stats']['scaned'],
                "deleted" => (int)$site['stats']['deleted'],
                "list" => $site["log"]['edges'],
                "actions" => $buttons = wtsec_generateButtons($uid, $_service, $service, $status, WTSEC_SITE_URL),
                "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.antivirus')
            ];
        }
    }
    wtsec_layout("antivirus", $services);
}


function wtsec_firewall_page()
{
    $host = WTSEC_LIBRARY_WT::getOwnSite();
    $services = [];
    if (!empty($host)) {
        $site = WTSEC_LIBRARY_WT::getFirewall($host['id']);
        $chart = WTSEC_LIBRARY_WT::getFirewallChart($host['id']);
        if (isset($site['data']['auth']['viewer']['sites']['one']['firewall']['logs'])) {
            $site = $site['data']['auth']['viewer']['sites']['one']['firewall'];
            $chart = $chart['data']['auth']['viewer']['sites']['one']['firewall']['chart'];
            $chart = generateChart($chart);
            $edges = $site['logs']['edges'];
            $domain = $host['hostname'];

            $countryAttacks = getCountryAttacks($site['map'], $chart['count_attacks']);

            $services["waf"] = [
                "pause" => "",
                "site_address" => $domain,
                "status" => WTSEC_LIBRARY_WT::getStatusIcon($site['status']),
                "_status" => $site['status'],
                "installed_status" => in_array($site['status'], ["not_installed", "error", "down", "not_supported", "not_registered"]) ? false : true,
                "time_of_the_last_check" => convertTimeToReadable($site['lastTest']['time']),
                "attacks" => $chart['count_attacks'],
                "blocking" => $chart['count_blocks'],
                "non-blocking" => $chart['count_attacks'] - $chart['count_blocks'],
                "description" => WTSEC_LIBRARY_Localization::lmsg('descriptions.firewall'),
                "chart" => json_encode($chart['chart'], true),
                "edges" => $edges,
                "countryAttacks" => $countryAttacks,
            ];
        }
    }
    wtsec_layout("firewall", $services);
}

function wtsec_login_form()
{
    if (wtsec_request()->method === "POST") {
        $result = WTSEC_LIBRARY_WT::auth(wtsec_request()->key);
        if (isset($result['data']['guest']['apiKeys']['auth']['token']['value'])) {
            WTSEC_LIBRARY_Session::setNotification("success", WTSEC_LIBRARY_Localization::lmsg('successfully_activated'));
            $token = $result['data']['guest']['apiKeys']['auth']['token']['value'];
            WTSEC_LIBRARY_App::login($token);
            wtsec_app()->set("api_key", wtsec_request()->key);
            wp_safe_redirect(wtsec_getUrl('dashboard'));
            exit;
        } else {
            WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg("form.incorrect"));
        }
    }
    wp_safe_redirect(wtsec_getUrl('login'));
}

function wtsec_cmd_ajax()
{
    $service = strtoupper(wtsec_request()->service);
    $_service = strtolower(wtsec_request()->service);
    $uid = wtsec_request()->uid;
    $cmd = wtsec_request()->cmd;
    $status = wtsec_checkStatus($uid, $service);
    if (stripos($cmd, "install") === false) {
        wtsec_cmd($cmd, $service, $_service, $uid, $status, WTSEC_SITE_URL);
        wp_safe_redirect(wp_get_referer());
    } else {
        $redirect = wtsec_getUrl("dashboard");
        $form_url = wp_nonce_url(admin_url('admin-post.php?cmd=' . $cmd . '&action=ajax_cmd&service=' . $service . '&uid=' . $uid), "ajax_cmd");
        if (wtsec_filesystem_init($form_url, '', false, false)) {
            wtsec_cmd($cmd, $service, $_service, $uid, $status, WTSEC_SITE_URL);
            wp_safe_redirect($redirect);
        }
    }
}

function wtsec_login()
{
    require_once WTSEC_PLUGIN_PATH . "includes/login.php";
}

function wtsec_logout()
{
    WTSEC_LIBRARY_App::logout();
}


function wtsec_layout($template, $arguments = [], $faq = "faq")
{
    $body = WTSEC_PLUGIN_PATH . "includes/" . $template . ".php";
    $faq = WTSEC_PLUGIN_PATH . "includes/" . $faq . ".php";
    require_once WTSEC_PLUGIN_PATH . "includes/layout.php";
}


function wtsec_ajax_changeStatus()
{
    if (wtsec_request()->method === "POST") {
        $host_id = wtsec_request()->host_id;
        $config_id = wtsec_request()->config_id;
        $result = WTSEC_LIBRARY_WT::changeStatus($config_id, $host_id);
        echo json_encode($result);
    }
    wp_die();
}

function wtsec_changeStatus()
{
    if (wtsec_request()->method === "POST") {
        $host_id = wtsec_request()->host_id;
        $config_id = wtsec_request()->config_id;
        WTSEC_LIBRARY_WT::changeStatus($config_id, $host_id);
    }
    wp_safe_redirect(wp_get_referer());
}

function wtsec_page($page)
{
    return wtsec_pages()[$page];
}

function wtsec_getUrl($page)
{
    return admin_url('admin.php?page=' . WTSEC_PAGE_PREFIX . $page);
}

function wtsec_getRoute($page)
{
    return WTSEC_PAGE_PREFIX . $page;
}

function wtsec_pages()
{
    return [
//        "options" => [
//            "page_title" => WTSEC_LIBRARY_Localization::lmsg('options'),
//            "menu_title" => WTSEC_LIBRARY_Localization::lmsg('options'),
//            "function" => "wtsec_options_page",
//        ],
        "services" => [
            "page_title" => WTSEC_LIBRARY_Localization::lmsg('services'),
            "menu_title" => WTSEC_LIBRARY_Localization::lmsg('services'),
            "function" => "wtsec_services_page",
        ],
        "vc" => [
            "page_title" => WTSEC_LIBRARY_Localization::lmsg('remote_antivirus'),
            "menu_title" => WTSEC_LIBRARY_Localization::lmsg('remote_antivirus'),
            "function" => "wtsec_antivirus_page",
            "vc_action" => "vc-action",
            "vc_function" => "wtsec_vc_function"
        ],
        "waf" => [
            "page_title" => WTSEC_LIBRARY_Localization::lmsg('firewall'),
            "menu_title" => WTSEC_LIBRARY_Localization::lmsg('firewall'),
            "function" => "wtsec_firewall_page",
            "vc_action" => "firewall-action",
            "vc_function" => "wtsec_firewall_function"
        ],
    ];
}
```
