Plugin Directory

Changeset 3357679


Ignore:
Timestamp:
09/08/2025 08:26:38 AM (7 months ago)
Author:
creativform
Message:

8.9.3

  • Added PHP support for the older PHP versions (7.0 and bove)
Location:
cf-geoplugin
Files:
505 added
6 edited

Legend:

Unmodified
Added
Removed
  • cf-geoplugin/trunk/CHANGELOG.txt

    r3355639 r3357679  
    11== Changelog ==
     2
     3= 8.9.3 =
     4* Added PHP support for the older PHP versions (7.0 and bove)
    25
    36= 8.9.2 =
  • cf-geoplugin/trunk/cf-geoplugin.php

    r3355639 r3357679  
    99 * Plugin URI:        https://wpgeocontroller.com/
    1010 * Description:       Unlock the power of location-based functionality of WordPress – The ultimate all-in-one geolocation plugin for WordPress.
    11  * Version:           8.9.2
     11 * Version:           8.9.3
    1212 * Requires at least: 6.0
    1313 * Requires PHP:      7.0
  • cf-geoplugin/trunk/inc/classes/Bots.php

    r3354427 r3357679  
    11<?php
    22
     3// If someone try to called this file directly via URL, abort.
    34if (!defined('WPINC')) {
    45    die("Don't mess with us.");
     6}
     7
     8if (!defined('ABSPATH')) {
     9    exit;
    510}
    611
  • cf-geoplugin/trunk/inc/classes/Browser.php

    r3354427 r3357679  
    877877            // Get information (if available)
    878878            $ch = CFGP_ClientHints::detect();
    879             if (!empty($ch['osName']) && $ch['osName'] !== 'Unknown') {
     879            if (!empty($ch['osName']??null) && $ch['osName'] !== 'Unknown') {
    880880                $this->_platform = $ch['osName'];
    881881            }
  • cf-geoplugin/trunk/inc/classes/OS_Helper.php

    r3355639 r3357679  
    11<?php
     2// If someone try to called this file directly via URL, abort.
     3if (!defined('WPINC')) { die("Don't mess with us."); }
     4if (!defined('ABSPATH')) { exit; }
     5
    26/**
    37 * Client Hints helper (Windows 10/11 detection, architecture, bitness, brands)
     
    3337final class CFGP_ClientHints
    3438{
    35     // Header names normalized to $_SERVER keys
    36     private const H_SEC_CH_UA                   = 'HTTP_SEC_CH_UA';
    37     private const H_SEC_CH_UA_MOBILE            = 'HTTP_SEC_CH_UA_MOBILE';
    38     private const H_SEC_CH_UA_PLATFORM          = 'HTTP_SEC_CH_UA_PLATFORM';
    39     private const H_SEC_CH_UA_PLATFORM_VERSION  = 'HTTP_SEC_CH_UA_PLATFORM_VERSION';
    40     private const H_SEC_CH_UA_ARCH              = 'HTTP_SEC_CH_UA_ARCH';
    41     private const H_SEC_CH_UA_BITNESS           = 'HTTP_SEC_CH_UA_BITNESS';
    42     private const H_SEC_CH_UA_FULL_VERSION_LIST = 'HTTP_SEC_CH_UA_FULL_VERSION_LIST';
     39    // Header names normalized to $_SERVER keys (no visibility for PHP<7.1)
     40    const H_SEC_CH_UA                   = 'HTTP_SEC_CH_UA';
     41    const H_SEC_CH_UA_MOBILE            = 'HTTP_SEC_CH_UA_MOBILE';
     42    const H_SEC_CH_UA_PLATFORM          = 'HTTP_SEC_CH_UA_PLATFORM';
     43    const H_SEC_CH_UA_PLATFORM_VERSION  = 'HTTP_SEC_CH_UA_PLATFORM_VERSION';
     44    const H_SEC_CH_UA_ARCH              = 'HTTP_SEC_CH_UA_ARCH';
     45    const H_SEC_CH_UA_BITNESS           = 'HTTP_SEC_CH_UA_BITNESS';
     46    const H_SEC_CH_UA_FULL_VERSION_LIST = 'HTTP_SEC_CH_UA_FULL_VERSION_LIST';
    4347
    4448    /**
     
    4650     * Call as early as possible (before any output).
    4751     */
    48     public static function emitHeaders(): void
     52    public static function emitHeaders()
    4953    {
    5054        if (headers_sent()) {
     
    5256        }
    5357
    54         // Ask for high-entropy hints we plan to read.
    5558        header('Accept-CH: Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version-List');
    5659
    57         // Permissions-Policy opt-in (syntax requires quoted tokens).
    5860        header('Permissions-Policy: ' .
    5961            'ch-ua=("*"), ' .
     
    7072     * Detect platform/OS using Client Hints; fall back to UA when missing.
    7173     *
    72      * @return array<string, mixed>
     74     * @return array
    7375     */
    74     public static function detect(): array
    75     {
    76         $ua                 = self::server('HTTP_USER_AGENT');
     76    public static function detect()
     77    {
     78        // Always cast UA to string to avoid TypeError in stripos()
     79        $ua                 = (string) self::server('HTTP_USER_AGENT');
    7780        $platformRaw        = self::stripQuotes(self::server(self::H_SEC_CH_UA_PLATFORM));
    7881        $platformVersionRaw = self::stripQuotes(self::server(self::H_SEC_CH_UA_PLATFORM_VERSION));
     
    8487        $platform = self::normalizePlatform($platformRaw, $ua);
    8588
    86         // Normalize version (e.g., "15.0.0") to [major,minor,patch]
     89        // Normalize version (e.g., "15.0.0")
    8790        $platformVersion = self::normalizeVersion($platformVersionRaw);
    8891
    89         // Decide Windows edition from platformVersion (Chromium mapping)
    90         // Observed: Win 10 => "10.0.0"; Win 11 => "13.0.0+" (varies by release).
    91         $isWindows   = (strcasecmp($platform, 'Windows') === 0);
    92         $major       = self::versionMajor($platformVersion);
    93         $isWin11     = $isWindows && $major !== null && $major >= 13; // threshold configurable
    94         $isWin10     = $isWindows && $major !== null && $major < 13;
    95 
    96         // Fallbacks from UA if hints missing or non-Chromium.
     92        // Windows flags by Client Hints
     93        $isWindows = (strcasecmp((string)$platform, 'Windows') === 0);
     94        $major     = self::versionMajor($platformVersion);
     95
     96        $isWin11   = $isWindows && self::isWindows11ByMajor($major);
     97        $isWin10   = $isWindows && ($major !== null) && ($major < 13);
     98
     99        // Fallback from UA if hints missing or non-Chromium
    97100        if (!$isWindows && stripos($ua, 'Windows NT') !== false) {
    98101            $isWindows = true;
    99             // Distinguish 11 vs 10 is not reliable via UA; default to 10.
    100102            if (!$platform) {
    101103                $platform = 'Windows';
    102104            }
     105            // UA ne razlikuje pouzdano 10 vs 11
    103106        }
    104107
    105108        $osName = self::composeOsName($platform, $isWin11, $isWin10, $ua);
    106109
    107         return [
     110        return array(
    108111            'platform'         => $platform ?: 'Unknown',
    109112            'platformVersion'  => $platformVersion,
     
    116119            'is_windows_11'    => $isWin11,
    117120            'is_windows_10'    => $isWin10,
    118         ];
     121        );
    119122    }
    120123
    121124    /**
    122125     * Allow overriding the Windows 11 threshold (default >= 13).
    123      * Example: CFGP_ClientHints::isWindows11ByMajor(15) // true
     126     * @param mixed $major
     127     * @return bool
    124128     */
    125     public static function isWindows11ByMajor(int $major): bool
    126     {
    127         // If your telemetry shows different mapping, adjust this constant or wrap with your filter.
    128         return $major >= 13;
     129    public static function isWindows11ByMajor($major)
     130    {
     131        $m = is_numeric($major) ? (int)$major : null;
     132        if ($m === null) return false;
     133        return $m >= 13;
    129134    }
    130135
    131136    // ----------------- Internals -----------------
    132137
    133     private static function server(string $key): ?string
    134     {
     138    private static function server($key)
     139    {
     140        if (!$key) return null;
    135141        return isset($_SERVER[$key]) && is_string($_SERVER[$key]) ? $_SERVER[$key] : null;
    136142    }
    137143
    138     private static function stripQuotes(?string $val): ?string
     144    private static function stripQuotes($val)
    139145    {
    140146        if ($val === null) return null;
    141147        $val = trim($val);
    142148        if ($val === '') return null;
    143         // Many CH values are quoted; remove surrounding quotes if present.
    144149        if ($val[0] === '"' && substr($val, -1) === '"') {
    145150            return substr($val, 1, -1);
     
    148153    }
    149154
    150     private static function normalizePlatform(?string $platform, ?string $ua): ?string
     155    private static function normalizePlatform($platform, $ua)
    151156    {
    152157        $p = $platform ? trim($platform) : '';
    153158        if ($p !== '') {
    154             // Standardize common names
    155159            if (strcasecmp($p, 'macOS') === 0 || strcasecmp($p, 'Mac OS') === 0 || stripos($p, 'Mac') !== false) {
    156160                return 'Mac OS';
    157161            }
    158             if (strcasecmp($p, 'Windows') === 0) {
    159                 return 'Windows';
    160             }
    161             if (strcasecmp($p, 'Linux') === 0) {
    162                 return 'Linux';
    163             }
    164             if (strcasecmp($p, 'Android') === 0) {
    165                 return 'Android';
    166             }
    167             if (strcasecmp($p, 'iOS') === 0) {
    168                 return 'iOS';
    169             }
    170             return $p; // keep as provided
    171         }
    172 
    173         // Fallback: infer from UA
     162            if (strcasecmp($p, 'Windows') === 0) return 'Windows';
     163            if (strcasecmp($p, 'Linux') === 0)   return 'Linux';
     164            if (strcasecmp($p, 'Android') === 0) return 'Android';
     165            if (strcasecmp($p, 'iOS') === 0)     return 'iOS';
     166            return $p;
     167        }
     168
    174169        $ua = (string)$ua;
    175170        if ($ua) {
    176             if (stripos($ua, 'Windows') !== false) return 'Windows';
    177             if (stripos($ua, 'Android') !== false) return 'Android';
    178             if (stripos($ua, 'iPhone') !== false || stripos($ua, 'iPad') !== false || stripos($ua, 'iOS') !== false) return 'iOS';
    179             if (stripos($ua, 'Mac OS') !== false || stripos($ua, 'Macintosh') !== false) return 'Mac OS';
    180             if (stripos($ua, 'Linux') !== false) return 'Linux';
     171            if (stripos($ua, 'Windows') !== false)    return 'Windows';
     172            if (stripos($ua, 'Android') !== false)    return 'Android';
     173            if (stripos($ua, 'iPhone') !== false
     174                || stripos($ua, 'iPad') !== false
     175                || stripos($ua, 'iOS') !== false)     return 'iOS';
     176            if (stripos($ua, 'Mac OS') !== false
     177                || stripos($ua, 'Macintosh') !== false) return 'Mac OS';
     178            if (stripos($ua, 'Linux') !== false)      return 'Linux';
    181179        }
    182180
     
    184182    }
    185183
    186     private static function normalizeVersion(?string $v): ?string
     184    private static function normalizeVersion($v)
    187185    {
    188186        if (!$v) return null;
    189         // Accept forms like 15, "15.0", "15.0.0"; normalize to "15.0.0"
    190         $parts = preg_split('/\s*[\.;,_-]\s*/', trim($v));
    191         if (!$parts || !ctype_digit($parts[0])) {
    192             // Some browsers already provide "15.0.0"; keep it
    193             if (preg_match('/^\d+(\.\d+){0,2}$/', $v)) {
    194                 // Pad to 3 components
    195                 $count = substr_count($v, '.');
    196                 return $v . str_repeat('.0', max(0, 2 - $count));
    197             }
    198             return null;
    199         }
    200         $major = (int)$parts[0];
    201         $minor = isset($parts[1]) && ctype_digit($parts[1]) ? (int)$parts[1] : 0;
    202         $patch = isset($parts[2]) && ctype_digit($parts[2]) ? (int)$parts[2] : 0;
    203         return $major . '.' . $minor . '.' . $patch;
    204     }
    205 
    206     private static function versionMajor(?string $v): ?int
     187        $v = trim($v);
     188
     189        // Accept "15", "15.0", "15.0.0" and normalize to 3 parts
     190        if (preg_match('/^\d+(\.\d+){0,2}$/', $v)) {
     191            $count = substr_count($v, '.');
     192            return $v . str_repeat('.0', max(0, 2 - $count));
     193        }
     194
     195        // Some browsers separate with semicolons/underscores, try to parse first token as major
     196        $parts = preg_split('/\s*[\.;,_-]\s*/', $v);
     197        if ($parts && isset($parts[0]) && ctype_digit($parts[0])) {
     198            $major = (int)$parts[0];
     199            $minor = (isset($parts[1]) && ctype_digit($parts[1])) ? (int)$parts[1] : 0;
     200            $patch = (isset($parts[2]) && ctype_digit($parts[2])) ? (int)$parts[2] : 0;
     201            return $major . '.' . $minor . '.' . $patch;
     202        }
     203
     204        return null;
     205    }
     206
     207    private static function versionMajor($v)
    207208    {
    208209        if (!$v) return null;
    209         $m = null;
    210210        if (preg_match('/^(\d+)/', $v, $mm)) {
    211             $m = (int)$mm[1];
    212         }
    213         return $m;
    214     }
    215 
    216     private static function composeOsName(?string $platform, bool $isWin11, bool $isWin10, string $ua): string
    217     {
    218         if(!$platform) {
    219             return 'Unknown';
    220         }
    221    
     211            return (int)$mm[1];
     212        }
     213        return null;
     214    }
     215
     216    private static function composeOsName($platform, $isWin11, $isWin10, $ua)
     217    {
     218        if (!$platform) {
     219            return 'Unknown';
     220        }
     221
     222        $ua = (string)$ua;
     223
     224        // Normalize to booleans
     225        $isWin10 = (bool) $isWin10;
     226        $isWin11 = (bool) $isWin11;
     227
    222228        if ($platform === 'Windows') {
    223229            if ($isWin11) return 'Windows 11';
    224230            if ($isWin10) return 'Windows 10';
    225             // Unknown Windows variant from UA
    226231            if (stripos($ua, 'Windows NT 6.1') !== false) return 'Windows 7';
    227232            if (stripos($ua, 'Windows NT 6.2') !== false) return 'Windows 8';
     
    233238        if ($platform === 'Android') return 'Android';
    234239        if ($platform === 'iOS')     return 'iOS';
    235        
     240
    236241        return 'Unknown';
    237242    }
  • cf-geoplugin/trunk/readme.txt

    r3355639 r3357679  
    66Tested up to: 6.8
    77Requires PHP: 7.0
    8 Stable tag: 8.9.2
     8Stable tag: 8.9.3
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    415415== Changelog ==
    416416
     417= 8.9.3 =
     418* Added PHP support for the older PHP versions (7.0 and bove)
     419
    417420= 8.9.2 =
    418421* Fixed unexpected PHP errors
     
    528531== Upgrade Notice ==
    529532
     533= 8.9.3 =
     534* Added PHP support for the older PHP versions (7.0 and bove)
     535
    530536= 8.9.2 =
    531537* Fixed unexpected PHP errors
    532 
    533 = 8.9.1 =
    534 * Added Client Hints (UA-CH) support for accurate detection
    535 * Improved UA fallback parsing, safer regex, and bot-first detection
    536 * Cleaner platform mapping
    537 * Backward compatible API
    538 * Fixed GUI and documentation
    539 * Code optimization
    540 
    541 = 8.9.0 =
    542 * Complete rewrite of plugin documentation with clearer structure and new usage examples.
    543 * Added Disclaimer / Legal Notice and Accessibility Statement.
    544 * Updated Privacy Policy and Terms & Conditions references.
    545 * Improved explanations for shortcodes, CSS, and Google Maps integration.
    546 * Enhanced CSV import/export instructions for SEO redirection.
    547 * Fixed minor typos and grammar issues across admin settings.
    548 * Small UI text refinements for better user experience.
    549538
    550539== Other Notes ==
Note: See TracChangeset for help on using the changeset viewer.