/home/bonphmya/wendykred.online/wp-content/plugins/conveythis-translate/app/class/ConveyThisSEO.php
<?php

require_once 'Variables.php';

class ConveyThisSEO
{
    private $variables;

    function __construct()
    {
        $this->variables = new Variables();
    }

    public function sp_serve_custom_sitemaps()
    {
        /*SEOPress*/
        foreach ($this->variables->target_languages as $language) {
            if (get_query_var("post-{$language}-sitemap")) {
                header('Content-Type: application/xml; charset=utf-8');
                echo '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="' . esc_url(home_url("sitemaps_xsl.xsl")) . '"?>';
                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is properly escaped within the function.
                echo $this->generate_custom_sitemap_content('post', $language);
                exit;
            }
            if (get_query_var("page-{$language}-sitemap")) {
                header('Content-Type: application/xml; charset=utf-8');
                echo '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="' . esc_url(home_url("sitemaps_xsl.xsl")) . '"?>';
                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is properly escaped within the function.
                echo $this->generate_custom_sitemap_content('page', $language);
                exit;
            }
        }
    }

    public function sp_add_query_vars_filter($vars)
    {
        /*SEOPress*/
        foreach ($this->variables->target_languages as $language) {
            $vars[] = "post-{$language}-sitemap";
            $vars[] = "page-{$language}-sitemap";
        }

        return $vars;
    }

    public function sp_custom_sitemaps_rewrite_rule()
    {
        /* Adding rules for custom sitemaps SEOPress */
        foreach ($this->variables->target_languages as $language) {
            add_rewrite_rule("^post-{$language}-sitemap(\d+)\.xml$", "index.php?post-{$language}-sitemap=\$matches[1]", 'top');
            add_rewrite_rule("^page-{$language}-sitemap(\d+)\.xml$", "index.php?page-{$language}-sitemap=\$matches[1]", 'top');
        }
        flush_rewrite_rules();
    }

    public function sp_sitemaps_xml_index($xml)
    {
        /* Adding custom sitemaps by post and page type SEOPress */
        $xml = str_replace('</sitemapindex>', '', $xml);

        $pattern = '/<loc>(.*?(?:post-|page-).*?)<\/loc>/s';
        preg_match_all($pattern, $xml, $matches);
        $urls = $matches[1];

        $sitemap_custom_items = '';

        foreach ($this->variables->target_languages as $language) {
            foreach ($urls as $url) {
                $modifiedUrl = preg_replace('/(post|page)-sitemap(\d*)\.xml$/', '$1-' . $language . '-sitemap$2.xml', $url);

                $sitemap_custom_items .= "<sitemap>\n<loc>{$modifiedUrl}</loc>\n</sitemap>\n";
            }
        }

        $sitemap_custom_items .= '</sitemapindex>';

        return $xml . $sitemap_custom_items;
    }

    public function rm_enable_custom_sitemap()
    {
        /*RankMath*/
        $languages = $this->variables->target_languages;
        foreach ($languages as $language) {
            add_filter('rank_math/sitemap/index', function ($sitemap) use ($language) {
                return $this->rm_add_custom_sitemaps($sitemap, $language);
            }, 10, 2);

            add_filter("rank_math/sitemap/post-{$language}/content", function () use ($language) {
                return $this->generate_custom_sitemap_content('post', $language);
            });

            add_filter("rank_math/sitemap/page-{$language}/content", function () use ($language) {
                return $this->generate_custom_sitemap_content('page', $language);
            });
        }
    }

    public function rm_add_custom_sitemaps($sitemap, $language)
    {
        /* Adding custom sitemaps by post and page type RankMath*/
        if (class_exists('RankMath')) {
            $rank = new RankMath\Settings();
            $settings = $rank->all();
            $is_post_included = $settings["sitemap"]["pt_post_sitemap"];
            $is_page_included = $settings["sitemap"]["pt_page_sitemap"];

            if ($is_post_included) {
                $sitemap .= "
    <sitemap>
        <loc>" . home_url() . "/post-{$language}-sitemap.xml" . "</loc>
        <lastmod>" . gmdate('c') . "</lastmod>
    </sitemap>";
            }

            if ($is_page_included) {
                $sitemap .= "
    <sitemap>
        <loc>" . home_url() . "/page-{$language}-sitemap.xml" . "</loc>
        <lastmod>" . gmdate('c') . "</lastmod>
    </sitemap>";
            }
        }

        return $sitemap;
    }


    function yo_add_custom_sitemaps($sitemaps)
    {
        $custom_sitemaps = '';

        foreach ($this->variables->target_languages as $language) {
            foreach ($sitemaps as $idx => $sitemap) {
                $modifiedUrl = preg_replace('/(post|page)-sitemap(\d*)\.xml$/', '$1-' . $language . '-sitemap$2.xml', $sitemap['loc']);
                $lastmod = gmdate('c', strtotime($sitemap['lastmod']));

                $custom_sitemaps .= "
    <sitemap>
        <loc>" . $modifiedUrl . "</loc>
        <lastmod>" . $lastmod . "</lastmod>
    </sitemap>";
            }
        }

        return $custom_sitemaps;
    }

    public function generate_custom_sitemap_content($type, $language = '')
    {
        /* Build xml content of custom sitemap (RankMath/SEOPress) */
        $args = [
            'post_type' => $type,
            'posts_per_page' => -1,
        ];
        $query = new WP_Query($args);

        $sitemap_content = '';

        while ($query->have_posts()) {
            $query->the_post();
            $url = array(
                "loc" => get_permalink(),
                "mod" => $query->post->post_modified_gmt,
            );
            $sitemap_items = "
    <url>
        <loc>" . get_permalink() . "</loc>
        <lastmod>" . $query->post->post_modified_gmt . "</lastmod>
    </url>";

            $sitemap_content .= $this->sitemap_add_translated_urls($sitemap_items, $url, $language);
        }
        wp_reset_postdata();

        $sitemap_xml = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">' . $sitemap_content . '</urlset>';
        return $sitemap_xml;
    }

    public function yo_enable_custom_sitemap()
    {
        /* Yoast */
        global $wpseo_sitemaps;

        if (isset($wpseo_sitemaps) && !empty($wpseo_sitemaps) && is_object($wpseo_sitemaps)) {
            foreach ($wpseo_sitemaps->providers as $provider) {
                if ($provider->handles_type('post')) {
                    $sitemaps = $provider->get_index_links(400);
                }
            }

            $filtered_sitemaps = array_filter($sitemaps, function ($sitemap) {
                return strpos($sitemap['loc'], 'post-sitemap') !== false || strpos($sitemap['loc'], 'page-sitemap') !== false;
            });

            add_filter("wpseo_sitemap_index", function () use ($filtered_sitemaps) {
                return $this->yo_add_custom_sitemaps($filtered_sitemaps);
            }, 10, 2);

            foreach ($this->variables->target_languages as $lang) {

                $wpseo_sitemaps->register_sitemap("post-{$lang}", function () use ($lang) {
                    $this->yo_create_custom_sitemap('post');
                });

                $wpseo_sitemaps->register_sitemap("page-{$lang}", function () use ($lang) {
                    $this->yo_create_custom_sitemap('page');
                });
            }
        }
    }

    public function yo_create_custom_sitemap($type)
    {
        /* Build xml content of custom sitemap Yoast*/
        global $wpseo_sitemaps;

        if (isset($wpseo_sitemaps) && !empty($wpseo_sitemaps) && is_object($wpseo_sitemaps)) {
            $args = [
                    'post_type' => $type,
                    'posts_per_page' => -1,
                ];
            $query = new WP_Query($args);
            $urls = array();
            while ($query->have_posts()) {
                $query->the_post();

                $urls[] = $wpseo_sitemaps->renderer->sitemap_url(array(
                    "loc" => get_permalink(),
                    "mod" => get_the_modified_date('c'),
                ));
            }
            wp_reset_postdata();

            $sitemap_body = '
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
' . implode("", $urls) . '
</urlset>';

            $wpseo_sitemaps->set_sitemap($sitemap_body);
        }
    }

    public function rank_math_sitemap_init()
    {
        global $wp_query;
        if (!empty($wp_query)) {
            $type = get_query_var('sitemap', '');
            add_filter('rank_math/sitemap/enable_caching', '__return_false');
            add_filter("rank_math/sitemap/{$type}_urlset", array($this, 'sitemap_add_xhtml_to_urlset'));
        }
    }

    public function wpseo_init_sitemap()
    {
        global $wp_query;
        if (!empty($wp_query)) {
            $type = get_query_var('sitemap', '');
            add_filter("wpseo_sitemap_{$type}_urlset", array($this, 'sitemap_add_xhtml_to_urlset'));
        }
    }

    public function sitemap_add_xhtml_to_urlset($urlset)
    {
        $urlset = str_replace('<urlset', '<urlset xmlns:xhtml="http://www.w3.org/1999/xhtml" ', $urlset);
        return $urlset;
    }

    public function sitemap_add_translated_urls($output, $url, $language = '')
    {
        $actual_link = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        if (in_array($url['loc'], $this->variables->blockpages)) // no need to add translated url for blocked pages
            return $output;

        $alternate = "";
        $translatedOutputUrls = array();

        // add source language to alternate
	    $alternate .= "\t<xhtml:link hreflang='x-default' href='" . $url['loc'] . "' rel='alternate'/>\n\t";
	    $alternate .= "\t<xhtml:link hreflang='" . $this->variables->source_language . "' href='" . $url['loc'] . "' rel='alternate'/>\n\t";

        foreach ($this->variables->target_languages as $language) {
            $modifiedResult = $this->modify_url($url, $language);

            if (str_contains($actual_link, '-' . $language . '-') === false) {
                $alternate .= $modifiedResult['alternate'];
                continue;
            } else {
                $translatedUrl = $modifiedResult['translatedUrl'];
                $translatedOutputUrls = $modifiedResult['translatedOutputUrls'];
                $alternate .= $modifiedResult['alternate'];
            }
        }

        //add alternate to translated url
        foreach ($translatedOutputUrls as &$value) {
            $value = str_replace("</url>", $alternate . "</url>", $value);
        }

        //add alternate to source url
        $newOutput = str_replace("</url>", $alternate . "</url>", $output);

        $translatedOutput = implode("", $translatedOutputUrls);

        return $translatedOutput ?: $newOutput . $translatedOutput;
    }

    function modify_url($url, $language)
    {

        $site_url = home_url();
        $translatedOutputUrls = array();

        $site_url = str_replace("https://", "", $site_url);
        $site_url = str_replace("http://", "", $site_url);

        if (!empty($this->variables->url_structure) && $this->variables->url_structure == "subdomain")
            $translatedUrl = str_replace($site_url, $language . "." . $site_url, $url['loc']);
        else
            $translatedUrl = str_replace($site_url, $site_url . "/" . $language, $url['loc']);


        $loc = "\t\t<loc>" . $translatedUrl . "</loc>\n";
        $lasmod = !empty($url['mod']) ? "\t\t<lastmod>" . gmdate('c', strtotime($url['mod'])) . "</lastmod>\n" : "";
        $images = "";
        if (isset($url['images']) && is_array($url['images'])) {
            foreach ($url['images'] as $image) {
                $images .= "\t\t<image:image><image:loc>" . $image['src'] . "</image:loc></image:image>\n";
            }
        }
        $translatedOutputUrls[] = "\t<url>\n" . $loc . $lasmod . $images . "\t</url>\n";
        $alternate = "\t<xhtml:link hreflang='" . $language . "' href='" . $translatedUrl . "' rel='alternate'/>\n\t";

        return array('translatedUrl' => $translatedUrl, 'translatedOutputUrls' => $translatedOutputUrls, 'alternate' => $alternate);
    }
}