Some checks failed
Security Monitoring & Compliance / Static Code Security Analysis (push) Has been cancelled
Security Monitoring & Compliance / Security Compliance Validation (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Has been cancelled
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Has been cancelled
Security Monitoring & Compliance / Secrets & Credential Scan (push) Has been cancelled
Security Monitoring & Compliance / WordPress Security Analysis (push) Has been cancelled
Security Monitoring & Compliance / Security Summary Report (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Notification (push) Has been cancelled
Security Monitoring & Compliance / Security Team Notification (push) Has been cancelled
Major modernization of HVAC plugin for PHP 8+ with full backward compatibility: CORE MODERNIZATION: - Implement strict type declarations throughout codebase - Modernize main plugin class with PHP 8+ features - Convert array syntax to modern PHP format - Add constructor property promotion where applicable - Enhance security helpers with modern PHP patterns COMPATIBILITY FIXES: - Fix PHP 8.1+ enum compatibility (convert to class constants) - Fix union type compatibility (true|WP_Error → bool|WP_Error) - Remove mixed type declarations for PHP 8.0 compatibility - Add default arms to match expressions preventing UnhandledMatchError - Fix method naming inconsistency (ensureRegistrationAccess callback) - Add null coalescing in TEC integration for strict type compliance DEPLOYMENT STATUS: ✅ Successfully deployed and tested on staging ✅ Site functional at https://upskill-staging.measurequick.com ✅ Expert code review completed with GPT-5 validation ✅ MCP Playwright testing confirms functionality Ready for production deployment when requested. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
198 lines
No EOL
5.8 KiB
PHP
198 lines
No EOL
5.8 KiB
PHP
<?php
|
|
/**
|
|
* HVAC Browser Detection Service
|
|
*
|
|
* Centralized browser detection and compatibility handling
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* HVAC Browser Detection Service
|
|
*/
|
|
class HVAC_Browser_Detection {
|
|
|
|
/**
|
|
* Instance
|
|
*
|
|
* @var HVAC_Browser_Detection
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* Cached user agent
|
|
*
|
|
* @var string
|
|
*/
|
|
private $user_agent = '';
|
|
|
|
/**
|
|
* Browser detection cache
|
|
*
|
|
* @var array
|
|
*/
|
|
private $browser_cache = [];
|
|
|
|
/**
|
|
* Get instance
|
|
*/
|
|
public static function instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor with secure user agent handling
|
|
*/
|
|
private function __construct() {
|
|
$raw_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
|
|
|
// Sanitize and validate user agent
|
|
$this->user_agent = sanitize_text_field($raw_user_agent);
|
|
|
|
// Additional validation for suspicious patterns
|
|
if (strlen($this->user_agent) > 500 ||
|
|
preg_match('/[<>\'"&]/', $this->user_agent) ||
|
|
preg_match('/javascript:/i', $this->user_agent) ||
|
|
preg_match('/data:/i', $this->user_agent)) {
|
|
$this->user_agent = ''; // Reset to empty for suspicious agents
|
|
error_log('HVAC: Suspicious user agent detected and sanitized');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Detect if user is using Safari browser
|
|
* Enhanced version with better detection accuracy
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function is_safari_browser() {
|
|
if (isset($this->browser_cache['is_safari'])) {
|
|
return $this->browser_cache['is_safari'];
|
|
}
|
|
|
|
if (empty($this->user_agent)) {
|
|
$this->browser_cache['is_safari'] = false;
|
|
return false;
|
|
}
|
|
|
|
// Check for Safari but not Chrome/Chromium (Chrome contains Safari in UA)
|
|
// Also exclude Edge and other WebKit-based browsers
|
|
$is_safari = (strpos($this->user_agent, 'Safari') !== false &&
|
|
strpos($this->user_agent, 'Chrome') === false &&
|
|
strpos($this->user_agent, 'Chromium') === false &&
|
|
strpos($this->user_agent, 'Edge') === false &&
|
|
strpos($this->user_agent, 'Edg') === false);
|
|
|
|
// Additional Safari-specific checks
|
|
if ($is_safari) {
|
|
// Verify it's actually Safari by checking for Version string (Safari-specific)
|
|
$is_safari = strpos($this->user_agent, 'Version/') !== false ||
|
|
strpos($this->user_agent, 'Safari/') !== false;
|
|
}
|
|
|
|
$this->browser_cache['is_safari'] = $is_safari;
|
|
|
|
// Debug logging
|
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
|
error_log('[HVAC Browser Detection] Safari check: ' . ($is_safari ? 'true' : 'false') . ' | UA: ' . substr($this->user_agent, 0, 100));
|
|
}
|
|
|
|
return $is_safari;
|
|
}
|
|
|
|
/**
|
|
* Detect if user is using Mobile Safari (iPhone/iPad)
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function is_mobile_safari() {
|
|
if (isset($this->browser_cache['is_mobile_safari'])) {
|
|
return $this->browser_cache['is_mobile_safari'];
|
|
}
|
|
|
|
$is_mobile_safari = $this->is_safari_browser() &&
|
|
(strpos($this->user_agent, 'iPhone') !== false ||
|
|
strpos($this->user_agent, 'iPad') !== false ||
|
|
strpos($this->user_agent, 'iPod') !== false);
|
|
|
|
$this->browser_cache['is_mobile_safari'] = $is_mobile_safari;
|
|
return $is_mobile_safari;
|
|
}
|
|
|
|
/**
|
|
* Get Safari version if available
|
|
*
|
|
* @return string|null Safari version or null if not Safari
|
|
*/
|
|
public function get_safari_version() {
|
|
if (!$this->is_safari_browser()) {
|
|
return null;
|
|
}
|
|
|
|
if (isset($this->browser_cache['safari_version'])) {
|
|
return $this->browser_cache['safari_version'];
|
|
}
|
|
|
|
$version = null;
|
|
|
|
// Extract version from user agent
|
|
if (preg_match('/Version\/([0-9]+(?:\.[0-9]+)*)/', $this->user_agent, $matches)) {
|
|
$version = $matches[1];
|
|
}
|
|
|
|
$this->browser_cache['safari_version'] = $version;
|
|
return $version;
|
|
}
|
|
|
|
/**
|
|
* Check if Safari version supports ES6+ features
|
|
* Safari 10+ has good ES6 support
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function safari_supports_es6() {
|
|
if (!$this->is_safari_browser()) {
|
|
return true; // Not Safari, assume other browsers support ES6
|
|
}
|
|
|
|
$version = $this->get_safari_version();
|
|
if (!$version) {
|
|
return false; // Unknown version, assume no ES6 support
|
|
}
|
|
|
|
// Safari 10+ has good ES6 support
|
|
return version_compare($version, '10.0', '>=');
|
|
}
|
|
|
|
/**
|
|
* Get browser info for debugging
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_browser_info() {
|
|
return [
|
|
'user_agent' => $this->user_agent,
|
|
'is_safari' => $this->is_safari_browser(),
|
|
'is_mobile_safari' => $this->is_mobile_safari(),
|
|
'safari_version' => $this->get_safari_version(),
|
|
'supports_es6' => $this->safari_supports_es6(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Clear browser detection cache
|
|
* Useful for testing or if user agent changes
|
|
*/
|
|
public function clear_cache() {
|
|
$this->browser_cache = [];
|
|
}
|
|
} |