<?php
\defined('ABSPATH') || die('ABSPATH is undefined? Please check your WordPress installation.');

global $wp_version;

/**
 * This method (unlike version_compare) matches any version number string against any version number string (does not require a strict version notation)
 *
 * @param $version1
 * @param $version2
 * @param $operator
 * @return mixed|null Returns NULL on failure
 */
function gdprc_version_check($version1, $version2, $operator)
{
    if (isset($version1) && \preg_match('~(\d+\.\d+(?:\.\d+)?)~', $version1, $versionMatch1) && isset($version2) && \preg_match('~(\d+\.\d+(?:\.\d+)?)~', $version2, $versionMatch2)) {
        return \version_compare(\array_shift($versionMatch1), \array_shift($versionMatch2), $operator);
    }
    return null;
}

global $gdprc_windowTopGdprConsents;
global $gdprc_mandatoryConsentIds;
global $gdprc_consentIds;
global $gdprc_disallowed_consent_plugins;

if (\gdprc_version_check($wp_version, '4.5.1', '<')) {
    echo '<div class="notice notice-error is-dismissible"> <p>Consent requires Wordpress version 4.5.1 or greater! Please upgrade Wordpress. <a href="https://www.wordpress.org/download/">https://www.wordpress.org/</a></p> </div>';
}

if (\gdprc_version_check(PHP_VERSION, '5.6.2', '<')) {
    echo '<div class="notice notice-error is-dismissible"> <p>GDPR Consent requires PHP version 5.6.2 or greater! Please upgrade your PHP version. <a href="http://www.php.net/">http://www.php.net/</a></p> </div>';
}

require_once __DIR__.'/../Library/utilities.php';

/**
 * This method filters all active plugins, and returns only the un-moderated plugins.
 *
 * @param $active_plugins
 * @return array
 */
function gdprc_disable_plugins($active_plugins)
{
    global $wpdb;
    global $gdprc_mandatoryConsentIds;
    global $gdprcCookie;

    $options = \get_option('gdpr-consent-settings');
    if (!\gdprc_user_is_logged_in() && !empty($options['gdpr_consent_maintenance_mode'])) {
        return $active_plugins;
    }

    /**
     * Verify Mandatory cookies, and set them!
     */
    if (empty($gdprc_mandatoryConsentIds)) {
        /* If WPML is active, we do things differently */
        if (\in_array('sitepress-multilingual-cms/sitepress.php', $active_plugins)) {
            $get_mandatory_consents_query =
                "SELECT DISTINCT `{$wpdb->posts}`.`ID`
			    FROM `{$wpdb->posts}`, `{$wpdb->postmeta}`, `{$wpdb->prefix}icl_translations`
			    WHERE `{$wpdb->posts}`.`post_type` = 'gdprc_consent'
				    AND `{$wpdb->posts}`.`ID` = `{$wpdb->postmeta}`.`post_id`
		            AND `{$wpdb->posts}`.`ID` = `element_id`
		            AND `{$wpdb->prefix}icl_translations`.`source_language_code` IS NULL
					AND `{$wpdb->postmeta}`.`meta_key` = 'gdprc_consent_is_required' AND `{$wpdb->postmeta}`.`meta_value` = '1'
				    AND `{$wpdb->posts}`.`post_status` = 'publish'";
        }
        else {
            $get_mandatory_consents_query =
                "SELECT DISTINCT `{$wpdb->posts}`.`ID`
			    FROM `{$wpdb->posts}`, `{$wpdb->postmeta}`
			    WHERE `{$wpdb->posts}`.`post_type` = 'gdprc_consent'
				    AND `{$wpdb->posts}`.`ID` = `{$wpdb->postmeta}`.`post_id`
					AND `{$wpdb->postmeta}`.`meta_key` = 'gdprc_consent_is_required' AND `{$wpdb->postmeta}`.`meta_value` = '1'
				    AND `{$wpdb->posts}`.`post_status` = 'publish'";
        }

        $gdprc_mandatoryConsentIds = \array_column($wpdb->get_results($get_mandatory_consents_query, ARRAY_A), 'ID');
    }

    /**
     * Prepares the MySQL query and passes the COOKIE consents id's to the Query String
     */
    $gdprcCookie = \gdprc_consent_cookie_get();
    if (empty($gdprcCookie)) {
        $gdprcCookie = \implode(GDPRC_COOKIE_DELIMITER, $gdprc_mandatoryConsentIds);
    }
    else {
        $gdprcCookie = \implode(GDPRC_COOKIE_DELIMITER, \array_unique(\array_merge(\explode(GDPRC_COOKIE_DELIMITER, $gdprcCookie), $gdprc_mandatoryConsentIds)));
    }
//	\gdprc_consent_cookie_set($gdprcCookie); // Steve: Do not set in PHP, Wordpress blocks this? So we set it using wp_head action as SCRIPT picked up by plugin.js

    $blog_id = '';
    if (!empty(\get_current_blog_id())) {
        $blog_id = '_'.(string)\get_current_blog_id();
    }
    $_COOKIE['gdprc_consents'.$blog_id] = $gdprcCookie; // We still need to update $_COOKIE global if we do not run \gdprc_consent_cookie_set() so \gdprc_consent_cookie_get() will return a correct value

    /**
     * Get all consent IDs
     */
    global $gdprc_consentIds;
    if (empty($gdprc_consentIds)) {
        /* If WPML is active, we do things differently */
        if (\in_array('sitepress-multilingual-cms/sitepress.php', $active_plugins)) {
            $get_all_consent_ids_query =
                "SELECT `ID`
	            FROM `{$wpdb->posts}`, `{$wpdb->prefix}icl_translations`
	            WHERE `post_type` = 'gdprc_consent'
		            AND `{$wpdb->posts}`.`ID` = `element_id`
		            AND `source_language_code` IS NULL
		            AND `post_status` = 'publish'";
        }
        else {
            $get_all_consent_ids_query =
                "SELECT `ID`
	            FROM `{$wpdb->posts}`
	            WHERE `post_type` = 'gdprc_consent'
		            AND `post_status` = 'publish'";
        }

        $gdprc_consentIds = \array_column($wpdb->get_results($get_all_consent_ids_query, ARRAY_A), 'ID');
    }

    /**
     * Enqueue consent IDs and the Mandatory consent IDs in WP_HEAD
     */
    global $gdprc_windowTopGdprConsents;
    if (empty($gdprc_windowTopGdprConsents)) {
        \add_action('wp_head', function() use ($options, $gdprc_consentIds, $gdprc_mandatoryConsentIds) {
            global $gdprc_windowTopGdprConsents;

            if (isset($options['gdprc_consent_landing_page']) && !empty($options['gdprc_consent_landing_page'])) {
                $redirect = \get_permalink((int)$options['gdprc_consent_landing_page']);
                if (function_exists('wpml_permalink_filter')) {
                    $redirect = \apply_filters('wpml_permalink', $redirect, ICL_LANGUAGE_CODE, true);
                }
            }
            else {
                $redirect = null;
            }

            echo '<script>
window.top.gdprConsents = {
';
            echo '"cookieDelimiter": "'.GDPRC_COOKIE_DELIMITER.'",
"ids": "'.\implode(GDPRC_COOKIE_DELIMITER, $gdprc_consentIds).'",
"mandatoryIds": "'.\implode(GDPRC_COOKIE_DELIMITER, $gdprc_mandatoryConsentIds).'",
"multisite": "'.(string)\get_current_blog_id().'",
"acceptAllRedirect": "'.$redirect.'",
"refreshTime": '.(!empty($options['gdprc_refresh_timeout']) ? $options['gdprc_refresh_timeout'] : 800);
            if (!empty($options['gdprc_google_analytics'])) {
                echo ',
"directConsentId": "'.$options['gdprc_google_analytics_consent'].'",
"directContent": "'.\base64_encode($options['gdprc_google_analytics']).'"';
            }
            echo '};
</script>';
        }, 5);
        $gdprc_windowTopGdprConsents = true;
    }

    /**
     * Get DISALLOWED consent IDs (NOT IN ...)
     */
    global $gdprc_disallowed_consent_plugins;
    if (empty($gdprc_disallowed_consent_plugins)) {
        if (\in_array('sitepress-multilingual-cms/sitepress.php', $active_plugins)) {
            $disallowed_consent_plugins_query =
                "SELECT `meta_value`
	            FROM `{$wpdb->posts}`, `{$wpdb->postmeta}`, `{$wpdb->prefix}icl_translations`
	            WHERE `post_type` = 'gdprc_consent'
		            AND `ID` = `post_id`
		            AND `ID` = `element_id`
		            AND `source_language_code` IS NULL
		            AND `meta_key` = 'gdprc_disallowed_plugins'
		            AND `ID` NOT IN (%s)
		            AND `post_status` = 'publish'";
        }
        else {
            $disallowed_consent_plugins_query =
                "SELECT `meta_value`
	            FROM `{$wpdb->posts}`, `{$wpdb->postmeta}`
	            WHERE `post_type` = 'gdprc_consent'
		            AND `ID` = `post_id`
		            AND `meta_key` = 'gdprc_disallowed_plugins'
		            AND `ID` NOT IN (%s)
		            AND `post_status` = 'publish'";
        }

        $in_ids_list = \str_replace(GDPRC_COOKIE_DELIMITER, ',', $gdprcCookie);

        $gdprc_disallowed_consent_plugins = $wpdb->get_results(\sprintf($disallowed_consent_plugins_query, $in_ids_list ? $in_ids_list : '0'), ARRAY_A);

        /**
         * Since we now know what should be enabled and disabled we setup the filters ONCE!
         */
        // Set filters for Wordpress developers
        $filters = \explode(',', $gdprcCookie);
        foreach ($filters as $id) {
            \add_action('gdprc_consent_'.$id.'_given', function() { return true; });
        }
    }

    /**
     * Grabs all disallowed plugins from the consents
     */
    $disallowed_plugins = [];
    \array_walk_recursive($gdprc_disallowed_consent_plugins, function($consent_plugins) use (&$disallowed_plugins) {
        $consent_plugins = \unserialize($consent_plugins);
        foreach ($consent_plugins as $consent_plugin) {
            $disallowed_plugins[$consent_plugin] = $consent_plugin;
        }
    });

    $active_plugins = \array_diff($active_plugins, $disallowed_plugins);
    return $active_plugins;
}

function gdprc_disable_plugins_backup($active_plugins)
{
    global $gdprc_disallowed_consent_plugins;

    $options = \get_option('gdpr-consent-settings');
    if (!\gdprc_user_is_logged_in() && !empty($options['gdpr_consent_maintenance_mode'])) {
        return $active_plugins;
    }

    /**
     * Grabs all disallowed plugins from the consents
     */
    $disallowed_plugins = [];
    \array_walk_recursive($gdprc_disallowed_consent_plugins, function($consent_plugins) use (&$disallowed_plugins) {
        $consent_plugins = \unserialize($consent_plugins);
        foreach ($consent_plugins as $consent_plugin) {
            $disallowed_plugins[$consent_plugin] = $consent_plugin;
        }
    });

    $active_plugins = \array_diff($active_plugins, $disallowed_plugins);
    return $active_plugins;
}

if (!\is_admin()) {
    \add_filter('option_active_plugins', 'gdprc_disable_plugins', 0, 1);
    \add_filter('option_active_plugins', 'gdprc_disable_plugins_backup', 9999, 1);
}

/**
 * Check's if a Consent was given
 *
 * @param int $consent_id The ID of the consent to check
 * @return bool
 */
if (!function_exists('gdpr_consent')) {
    function gdpr_consent($consent_id)
    {
        return \do_action('gdprc_consent_'.\intval($consent_id).'_given', false) ? true : false;
    }
}
