HEX
Server: LiteSpeed
System: Linux pbn-10.isgood.host 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User: pg88zccom (1239)
PHP: 8.1.32
Disabled: NONE
Upload Files
File: /usr/local/lsws/pg88zc.com/html/wp-content/plugins/mlink-plugin/includes/functions.php
<?php

use GwdMlinkPlugin\GwdMlinkDomainDatas;
use GwdMlinkPlugin\Helpers\Cache;
use GwdMlinkPlugin\Helpers\TokenProcess;

add_action('rest_api_init', function () {
    register_rest_route(
        'apimlink/v1',
        '/active-plugin',
        array(
            'methods' => 'GET',
            'callback' => 'active_gwd_apimlink_token',
            'args' => array(
                'app_token' => array(),
                'branch_code' => array(),
            )
        )
    );
    register_rest_route(
        'apimlink/v1',
        '/deactive-plugin',
        array(
            'methods' => 'GET',
            'callback' => 'deactive_gwd_apimlink_token',
            'args' => array(
                'app_token' => array()
            )
        )
    );
    register_rest_route(
        'apimlink/v1',
        '/refresh-data',
        array(
            'methods' => 'POST',
            'callback' => 'refresh_gwd_apimlink_data',
            'args' => array(
                'appToken' => array()
            )
        )
    );

    register_rest_route(
        'apimlink/v1',
        '/generate-mlink-url',
        array(
            'methods' => 'POST',
            'callback' => 'generate_gwd_mlink_url',
            'args' => array(
                'appToken' => array(),
                'md5Slugs' => array(),
            )
        )
    );

    register_rest_route(
        'apimlink/v1',
        '/get-gwd-list-url-cache',
        array(
            'methods' => 'GET',
            'callback' => 'get_gwd_list_url_cache',
            'args' => array()
        )
    );

    flush_rewrite_rules();
});

if (!function_exists('active_gwd_apimlink_token')) {
    function active_gwd_apimlink_token($request)
    {
        $tokenProcess = new TokenProcess();
        $response = $tokenProcess->activeToken();
        gwd_refresh_cache_data();
        return $response;
    }
}

if (!function_exists('deactive_gwd_apimlink_token')) {
    function deactive_gwd_apimlink_token($request)
    {
        $tokenProcess = new TokenProcess();
        return $tokenProcess->deactiveToken();
    }
}

if (!function_exists('refresh_gwd_apimlink_data')) {
    function refresh_gwd_apimlink_data($request)
    {
        $appToken = $request->get_param('appToken');
        $currentToken = get_option('gwd_mlink_token_value');
        // $currentTime = time();
        // $expireTime = get_option('gwd_mlink_expire_time_value', 0);

        // if ($appToken != $currentToken || $currentTime < $expireTime) {
        //     return [
        //         "status" => "fail",
        //         "message" => "Invalid request refresh!"
        //     ];
        // }
        // update_option('gwd_mlink_expire_time_value', $currentTime + 60);
        if ($appToken != $currentToken) {
            return [
                "status" => "fail",
                "message" => "Invalid request refresh!"
            ];
        }

        gwd_refresh_cache_data();

        generate_gwd_mlink_html();

        wp_cache_flush();
        mlink_remove_cache_folder();
        // Purge LiteSpeed cache
        if (has_action('litespeed_purge_all')) {
            do_action('litespeed_purge_all');
        }

        if (function_exists('rocket_clean_domain')) {
            rocket_clean_domain();
        }

        return [
            "status" => "success",
            "message" => "Refresh successfull!"
        ];
    }
}

if (!function_exists('gwd_refresh_cache_data')) {
    function gwd_refresh_cache_data()
    {
        $cache = new Cache;
        $cacheData['timestamp'] = 0;
        $cacheData['data'] = [];
        $cache->set('gwd_mlink_domainoption', $cacheData);
        $cache->set('gwd_mlink_domainoption', $cacheData);
        $cache->set('gwd_mlink_usermlink_option', $cacheData);

        wp_cache_flush();

        // Purge LiteSpeed cache
        if (has_action('litespeed_purge_all')) {
            do_action('litespeed_purge_all');
        }

        if (function_exists('rocket_clean_domain')) {
            rocket_clean_domain();
        }
    }
}

add_action('wp_enqueue_scripts', function () {
    wp_enqueue_style('gwd-auth-css', GWD_MLINK_URL . 'assets/css/auth.css');
});

// Hook into the admin_notices action to display the notice
add_action('admin_notices', 'gwd_check_token_option');

/**
 * Check for the "gwd_mlink_token_value" option and display a notice if it's missing.
 */
function gwd_check_token_option()
{
    // Check if the option exists
    $token_value = get_option('gwd_mlink_token_value');
    if (empty($token_value)) {
        // Display admin notice
        echo '<div class="notice notice-warning is-dismissible">';
        echo '<p><strong>GWD Token Missing:</strong> Mlink chưa được gắn token. Hãy vào <a href="/wp-admin/options-general.php?page=gwd-mlink-plugin-settings">mlink setting</a> để nhập token để có thể sử dụng.</p>';
        echo '</div>';
    }
}

if (!function_exists('generate_gwd_mlink_url')) {
    function generate_gwd_mlink_url($request)
    {
        // $appToken = $request->get_param('appToken');
        // $currentToken = get_option('gwd_mlink_token_value');
        // if ($appToken != $currentToken) {
        //     return [
        //         "status" => "fail",
        //         "message" => "Invalid token!"
        //     ];
        // }
        gwd_refresh_cache_data();

        generate_gwd_mlink_html();
        wp_cache_flush();
        mlink_remove_cache_folder();

        // Purge LiteSpeed cache
        if (has_action('litespeed_purge_all')) {
            do_action('litespeed_purge_all');
        }

        if (function_exists('rocket_clean_domain')) {
            rocket_clean_domain();
        }
        return [
            'status' => 'success',
            'message' => 'HTML files generated successfully and .htaccess updated',
        ];
    }
}

if (!function_exists('generate_gwd_mlink_html')) {
    function generate_gwd_mlink_html()
    {
        $domainTool = GwdMlinkDomainDatas::getInstance();
        $domains = (array) $domainTool->getUserMlinkData();
        $rootFolder = ABSPATH . '/mlink'; // Root folder for mlink files

        if (!is_dir($rootFolder)) {
            mkdir($rootFolder, 0755, true); // Create mlink folder if it doesn't exist
        }

        foreach ($domains as $md5Slug => $rdrUrl) {
            $redirectUrl = "https://" . $rdrUrl;

            // Create a folder for the md5Slug
            $slugFolder = $rootFolder . '/' . $md5Slug;
            if (!is_dir($slugFolder)) {
                mkdir($slugFolder, 0755, true);
            }

            // Generate index.html file content
            $htmlContent = '
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                    <title>Redirecting...</title>
                    <!-- Redirect after 1 second -->
                    <meta http-equiv="refresh" content="0;url=' . $redirectUrl . '">
                    <meta name="robots" content="noindex, nofollow">
                    <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, proxy-revalidate" />
                    <meta http-equiv="Pragma" content="no-cache" />
                    <meta http-equiv="Expires" content="0" />
                </head>
                <body>
                    <p>Redirecting to <a href="' . $redirectUrl . '">Next Url</a> in 1 second...</p>
                </body>
                </html>';

            // Write index.html file
            $filePath = $slugFolder . '/index.html';
            file_put_contents($filePath, $htmlContent);
        }

        // Prepare .htaccess content
        $htaccessFile = ABSPATH . '.htaccess';

        $existingContent = file_get_contents($htaccessFile);

        // Remove any existing rewrite rules related to mlink redirection
        $existingContent = preg_replace('/^RewriteRule \^mlink\/[a-z0-9-]+\/?\$ \/mlink\/[a-z0-9-]+\/index\.html \[L\]$/m', '', $existingContent);

        // Add the specific rule for /mlink/?branchseo=abc
        $branchseoRewriteRule = <<<EOD
                                    <IfModule mod_rewrite.c>
                                    RewriteCond %{QUERY_STRING} branchseo=([^&]+) [NC]
                                    RewriteCond %{DOCUMENT_ROOT}/mlink/%1/index.html -f
                                    RewriteRule ^mlink/?$ /mlink/%1/index.html [L]
                                    </IfModule>

                                    # Custom Mlink Rewrite Rules
                                    EOD;

        // Add the specific rule for if does not have /mlink/?branchseo=abc
        $branchseoNotExistRewriteRule = <<<EOD
                                            <IfModule mod_rewrite.c>
                                            RewriteCond %{QUERY_STRING} branchseo=([^&]+) [NC]
                                            RewriteCond %{DOCUMENT_ROOT}/mlink/%1/index.html !-f
                                            RewriteRule ^mlink/?$ / [L]
                                            </IfModule>

                                            # Custom Mlink Rewrite Rules
                                            EOD;
        $oldRule = <<<EOD
                                            <IfModule mod_rewrite.c>
                                            RewriteCond %{QUERY_STRING} branchseo=([^&]+) [NC]
                                            RewriteRule ^mlink/?$ /mlink/%1/index.html [L]
                                            </IfModule>
        
                                            # Custom Mlink Rewrite Rules
                                            EOD;

        // Remove existing branchseo rules if they exist in the content
        $existingContent = str_replace($oldRule, '', $existingContent);
        $existingContent = str_replace($branchseoNotExistRewriteRule, '', $existingContent);
        $existingContent = str_replace($branchseoRewriteRule, '', $existingContent);

        // Clean up extra newlines after removing rules
        $existingContent = preg_replace("/\n{2,}/", "\n", $existingContent);

        // Append the new rules to the content
        $existingContent = $branchseoRewriteRule . "\n" . $branchseoNotExistRewriteRule . "\n" . $existingContent;

        // Final cleanup to ensure formatting
        $existingContent = trim($existingContent) . "\n";

        // Write the updated content back to .htaccess
        file_put_contents($htaccessFile, $existingContent);
    }
}

if (!function_exists('get_gwd_list_url_cache')) {
    function get_gwd_list_url_cache($request)
    {
        // $cache = new Cache;
        // $md5Slugs = $cache->get("domain_md5_slug_data");
        $url = home_url();
        // $url = "https://www.suttaworld.org";
        $mlinks = get_all_mlink_branchseo_links($url);
        $links = [];
        if ($mlinks['success']) {
            $links = array_merge($links, $mlinks['links']);
        }

        $sitemap_url = $url . '/sitemap_index.xml'; // Replace this with the correct sitemap index URL
        $all_sitemap_urls = get_all_sitemap_urls($sitemap_url);
        $links = array_merge($links, $all_sitemap_urls);
        $filePath = ABSPATH . '/gwd_url.json';
        file_put_contents($filePath, json_encode($links));
        return [
            'status' => 'success',
            'message' => 'All Link generated!',
            'data' => $links
        ];
    }
}

function fetch_sitemap_content($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Optional: Ignore SSL certificate errors
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
    $content = curl_exec($ch);
    curl_close($ch);
    return $content;
}

function get_all_sitemap_urls($sitemap_url)
{
    // Fetch the main sitemap XML (sitemap_index.xml)
    $sitemap_xml = fetch_sitemap_content($sitemap_url);
    if ($sitemap_xml === false) {
        return 'Could not fetch sitemap.';
    }

    // Parse the XML
    $sitemap = simplexml_load_string($sitemap_xml);
    if ($sitemap === false) {
        return 'Error parsing XML.';
    }

    $all_urls = [];

    // Loop through each entry in the sitemap index (each points to a sub-sitemap)
    foreach ($sitemap->sitemap as $sitemap_entry) {
        $sub_sitemap_url = (string) $sitemap_entry->loc;

        // Fetch each sub-sitemap XML (e.g., post-sitemap.xml)
        $sub_sitemap_xml = fetch_sitemap_content($sub_sitemap_url);
        if ($sub_sitemap_xml === false) {
            continue;
        }

        $sub_sitemap = simplexml_load_string($sub_sitemap_xml);
        if ($sub_sitemap === false) {
            continue;
        }

        // Loop through each URL in the sub-sitemap (e.g., individual posts/pages URLs)
        foreach ($sub_sitemap->url as $url_entry) {
            $url = (string) $url_entry->loc; // Extract the URL
            $all_urls[] = $url; // Add the URL to the list
        }
    }

    return $all_urls;
}

function get_all_mlink_branchseo_links($homepageUrl)
{
    // Initialize cURL to fetch the homepage content
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $homepageUrl,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);

    $htmlContent = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) {
        return [
            'success' => false,
            'error' => "cURL error: $err",
        ];
    }

    if ($httpCode !== 200) {
        return [
            'success' => false,
            'error' => "Unexpected HTTP status code: $httpCode",
        ];
    }

    // Load the HTML content into DOMDocument
    $dom = new DOMDocument();
    libxml_use_internal_errors(true); // Suppress parsing errors for invalid HTML
    @$dom->loadHTML($htmlContent);
    libxml_clear_errors();

    // Use DOMXPath to find all links matching the pattern
    $xpath = new DOMXPath($dom);
    $links = $xpath->query("//a[contains(@href, '?branchseo=')]");

    $matchingLinks = [];
    foreach ($links as $link) {
        $href = $link->getAttribute('href');
        $matchingLinks[] = $homepageUrl . $href;
    }

    return [
        'success' => true,
        'links' => $matchingLinks,
    ];
}

function get_all_branchseo_codes($homepageUrl)
{
    // Initialize cURL to fetch the homepage content
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $homepageUrl,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);

    $htmlContent = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) {
        return [
            'success' => false,
            'error' => "cURL error: $err",
        ];
    }

    if ($httpCode !== 200) {
        return [
            'success' => false,
            'error' => "Unexpected HTTP status code: $httpCode",
        ];
    }

    // Load the HTML content into DOMDocument
    $dom = new DOMDocument();
    libxml_use_internal_errors(true); // Suppress parsing errors for invalid HTML
    @$dom->loadHTML($htmlContent);
    libxml_clear_errors();

    // Use DOMXPath to find all links matching the pattern
    $xpath = new DOMXPath($dom);
    $links = $xpath->query("//a[contains(@href, '/mlink/?branchseo=')]");

    $branchseoCodes = [];
    foreach ($links as $link) {
        $href = $link->getAttribute('href');

        // Extract the branchseo code from the query parameter
        $urlParts = parse_url($href);
        if (isset($urlParts['query'])) {
            parse_str($urlParts['query'], $queryParams);
            if (isset($queryParams['branchseo'])) {
                $branchseoCodes[] = $queryParams['branchseo'];
            }
        }
    }

    // Remove duplicates and return the codes
    $branchseoCodes = array_unique($branchseoCodes);

    return [
        'success' => true,
        'codes' => $branchseoCodes,
    ];
}

function mlink_remove_cache_folder()
{
    $domain = $_SERVER['HTTP_HOST'];
    $litespeedBasePath = '/usr/local/lsws';
    $wpContentBasePath = $_SERVER['DOCUMENT_ROOT'] . '/wp-content/cache';

    $litespeedCachePath = $litespeedBasePath . '/' . $domain . '/cache';

    // Helper function to remove a folder with a shell command
    $removeFolder = function ($path) {
        if (is_dir($path)) {
            rmdir($path);
        } else {
        }
    };

    // Remove LiteSpeed cache folder
    $removeFolder($litespeedCachePath);

    // Remove WordPress cache folder
    $removeFolder($wpContentBasePath);

    // return $litespeedRemoved && $wpCacheRemoved;
}