ElkArte Community

Extending Elk => Addons => Topic started by: ahrasis on March 13, 2017, 08:03:02 am

Title: EUCA: EU Cookie Alert
Post by: ahrasis on March 13, 2017, 08:03:02 am
EUCA: EU Cookie Alert

- For version 1.0x and 1.1x.
- Fully Hook.

1. Please do your own backup though every installation is usually backed up automatically.
2. This addon will display EU Cookie Notification only to forum guest from EU countries.
3. Once activated, the forum will use geoplugin cookielaw.js to screen guest.
4. Except for the above, internal javascript and css will be used.


Thank you for using/testing it.


Yours friendly,
Abu Fahim Ismail.

Free License. Feel free to modify accordingly but keep author's link if it is in there somewhere. ;)

(https://validator.w3.org/images/valid_icons/valid-xhtml10)  (https://jigsaw.w3.org/css-validator/images/vcss)

#Change Logs

@Version 1.0.2
- Use geoplugin cookielaw.js instead.
- Use internal javasscript and stylesheet.
Spoiler (click to show/hide)
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on August 27, 2017, 07:46:50 am
Updated to displays notification only to visitors / users from EU countries.

The code used for this addon is as follows:
Code: [Select]
function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
    $output = NULL;
    if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
        $ip = $_SERVER["REMOTE_ADDR"];
        if ($deep_detect) {
            if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                $ip = $_SERVER['HTTP_CLIENT_IP'];
        }
    }
    $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
    $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
    $continents = array(
        "AF" => "Africa",
        "AN" => "Antarctica",
        "AS" => "Asia",
        "EU" => "Europe",
        "OC" => "Australia (Oceania)",
        "NA" => "North America",
        "SA" => "South America"
    );
    if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
        $ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
        if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
            switch ($purpose) {
                case "location":
                    $output = array(
                        "city"           => @$ipdat->geoplugin_city,
                        "state"          => @$ipdat->geoplugin_regionName,
                        "country"        => @$ipdat->geoplugin_countryName,
                        "country_code"   => @$ipdat->geoplugin_countryCode,
                        "continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                        "continent_code" => @$ipdat->geoplugin_continentCode
                    );
                    break;
                case "address":
                    $address = array($ipdat->geoplugin_countryName);
                    if (@strlen($ipdat->geoplugin_regionName) >= 1)
                        $address[] = $ipdat->geoplugin_regionName;
                    if (@strlen($ipdat->geoplugin_city) >= 1)
                        $address[] = $ipdat->geoplugin_city;
                    $output = implode(", ", array_reverse($address));
                    break;
                case "city":
                    $output = @$ipdat->geoplugin_city;
                    break;
                case "state":
                    $output = @$ipdat->geoplugin_regionName;
                    break;
                case "region":
                    $output = @$ipdat->geoplugin_regionName;
                    break;
                case "country":
                    $output = @$ipdat->geoplugin_countryName;
                    break;
                case "countrycode":
                    $output = @$ipdat->geoplugin_countryCode;
                    break;
            }
        }
    }
    return $output;
}

function EU_Cookie(&$buttons)
{
global $context;

// Add it after login bar
$country_code = ip_info("Visitor", "Country Code");
$europe = array('AD', 'AL', 'AT', 'AX', 'BA', 'BE', 'BG', 'BY', 'CH', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FO', 'FR', 'GB', 'GG', 'GI', 'GR', 'HR', 'HU', 'IE', 'IM', 'IS', 'IT', 'JE', 'LI', 'LT', 'LU', 'LV', 'MC', 'MD', 'ME', 'MK', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'RS', 'RU', 'SE', 'SI', 'SJ', 'SK', 'SM', 'UA', 'VA');
    if(in_array($country_code, $europe)) {
$context['html_headers'] .= '
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.js"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
  "palette": {
"popup": {
  "background": "#000"
},
"button": {
  "background": "#f1d600"
}
  }
})});
</script>
';
}
}

As discussed in other topic, the above-called css and js file can be downloaded and use from your own forum instead. This however is not yet implemented in the current version. It will be considered in the future update.
Title: Re: EUCA: EU Cookie Alert
Post by: Frenzie on August 27, 2017, 01:46:29 pm
It looks like you included all of Europe in $europe? There are only 28 countries in the EU (list (https://europa.eu/european-union/about-eu/countries_en)). Switzerland (CH), Iceland (IS) and Russia (RU) jumped out at me. :)
Title: Re: EUCA: EU Cookie Alert
Post by: live627 on August 27, 2017, 06:49:37 pm
Might be a good idea to cache the result. I haven't checked that API, but it could eventually limit your calls. Also an extra lookup per page load could be slow (I assume it's per page based on that code snippet)
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on August 27, 2017, 10:51:50 pm
1. How do I cache the result?

2. Does ElkArte have the geoip location built-in, that can be directly used instead?
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on September 15, 2017, 12:46:45 am
I would suggest users to use version 1.0.0 instead of 1.0.1 since as stated by @live627, the later will cause loading issue since there is no cache being used.

I haven't figure out how to do the cache thing, but I hope to resolve it in the next release.

Edited: Try version 1.0.2 instead.
Title: Re: EUCA: EU Cookie Alert
Post by: Feline on September 15, 2017, 05:36:32 pm
why not simple set a "ecl_accepted" cookie (lifetime 30 days) if the visitor outside the EU ?
Then you can simple check this  cookie on each pageload ...
Same you can do if the visitor inside the EU and have accepted cookies ...

So you need the above code only if the ecl cookie not exists ...

Fel
Title: Re: EUCA: EU Cookie Alert
Post by: Feline on September 15, 2017, 07:07:24 pm
There is a small bug in the routine ...
Geoip don't handle IPv6 correct with your code.

You have to use this ..
Code: [Select]
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
 $link = '?ipv6='. $ip;
 else
 $link = '?ip='. $ip;

 $ipdat = json_decode(file_get_contents('http://www.geoplugin.net/json.gp'. $link));

So you get correct data if a IPV6 adress used ...

I just tested you code .. but you need only this ..
Code: [Select]
$ipdat = json_decode(file_get_contents('http://www.geoplugin.net/json.gp'. $link));
if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2)
 $country_code = $ipdat->geoplugin_countryCode;

return in_array($country_code, $europe);

Fel
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on September 15, 2017, 10:28:05 pm
Thank you for the code and I agree that the code can be simpler.

That's said, for the time being, I am more on the cache thing as suggested by @live627 as it will take the forum longer time to load if this is not cache in the first place. There is no use of implementing a simple check just to have your forum load much more slower than it is before.
Title: Re: EUCA: EU Cookie Alert
Post by: Frenzie on September 16, 2017, 06:07:18 am
I'm not sure if this would be the best way to do it, but in your current ip_info function you could try something like

Code: [Select]
if $_SESSION['ip_info']
$output = $_SESSION['ip_info']
else {
if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
//etc
$_SESSION['ip_info'] = $output;
}
return $output

That should reduce the number of requests to one per visitor.
Title: Re: EUCA: EU Cookie Alert
Post by: Feline on September 16, 2017, 03:32:55 pm
We not set a cookie that the ecl-check is solved?
Then you can first simple check this cookie and if not exists, show the ecl overlay ..

If the visitor inside the eu, wait until he accept cookies, then set the ecl-cookie.
if the visitor outside the eu, simple set the ecl cookie.
Now this routine is nevermore called ...

Fel
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on September 18, 2017, 07:34:29 am

I have decided to use geoplugin cookielaw.js instead.

#Change Logs

@Version 1.0.2
- Use geoplugin cookielaw.js instead.
- Use internal javasscript and stylesheet.
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on February 17, 2018, 10:53:49 am
I just realized that there is a bug in this addon which causes some buttons in display page not working properly. Please do not use version 1.0.2. I will try to fix it later.
Title: Re: EUCA: EU Cookie Alert
Post by: Feline on February 18, 2018, 10:58:05 am
Hi ahrasis,

there is one problem with GeoIp ..
You are blacklisted if you make more the 100 requests/min and also you not checked if the visitor a Spider.
If a spider on work, this can quickly get the limit for GeoIp ...
So the first point is, to filter out all spider and secondary save the GeoIp data for all scanned IP's in the cache (I hope Elkarte have one). So you can look at the cache if a IP checked.

Also GeoIp have updatet the ContinedCode for v6 IP's on my complaint.
So you need only check the geoplugin_continentCode if this hold the code EU.

On our System, we create also a "Landing Page" .. that means, the incomming visitors see the Page in the language as normaly speeked in his Country .. so Germany Guest see the page in German  ;)  also if the admin have set te default language to english.
If the visitor logged in, he see the page in the language as he set and after logout the page shown continue in the set language.

I can get you a full list of all known spiders word wide ... and I udate this list anytime i detect a new spider, because I logged all incomming Requests ...
I dont known, if Elkarte have the same Spider handling as SMF 2.1 have, but with my code any new Spider are automatically added to the Spiderlist. So you not need to fill in this manually.

If you need help for the enhanced spider detection, call me.

Greeting from Germany
Feline

Title: Re: EUCA: EU Cookie Alert
Post by: radu81 on February 18, 2018, 03:48:11 pm
Feline, It looks like you invested a lot of work and time into this on PortaMX  ;)
Title: Re: EUCA: EU Cookie Alert
Post by: Feline on February 18, 2018, 03:52:31 pm
Quote from: radu81 – Feline, It looks like you invested a lot of work and time into this on PortaMX  ;)
True  ;) .. I love it, to get the best for our visitors ... Design, Comfort, Speed and mutch more .. for Desctop and Mobile
Title: Re: EUCA: EU Cookie Alert
Post by: ahrasis on February 18, 2018, 06:43:30 pm
Thanks @Feline. I will try to exclude spiders in the future, but I am afraid it is more to the code itself, not the spiders. My test result was even the code is not loaded, the buttons are still affected by this addon. I haven't properly checked on this but I hope to resolve it soon.
Title: Re: EUCA: EU Cookie Alert
Post by: Feline on February 18, 2018, 11:06:33 pm
Well .. I don't use the javascript from GEOIP ..
I make a normal http request (with the curl php routines) so I can use a Timeout and can detect if we have received code or not.

The flow is as follow:
after userdata is loaded ..
1. check if a guest or spider
    if is a spider, check if we known it
    a) no .. add to the spiderlist -> done
    b) in spiderlist -> done

2. is a normal guest
    check if we known the IP (all guest IP's and the geoip data cached)
    a) in cache ... done
    b) get data from GeoIp

3. Check the data if he inside the EU
    YES: he have ECL cookie set? => Yes done, No = Show the ECL overlay
    NO: request geoip, if in EU cache the IP and Geoip code, show ECL overlay

On this flow, it's also very simple to make a Landing page .. means, the site is shown in the user country language.
(We have currently only english and german, but I hope we get more)

That is, what we have done and use on our Site.

Feline