PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 3.1.0
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v3.1.0
5.12.0 5.13.0 5.13.1 5.11.0 5.10.0 5.9.0 5.8.0 5.8.1 5.7.0 5.6.2 5.6.3 5.6.1 5.6.0 5.5.0 5.4.0 5.3.2 5.3.1 5.1.6 5.1.5 trunk 2.1.5 2.11 2.12 2.13 2.15 All 47 releases
double-opt-in / logger / logger.php

logger.php in Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification 3.1.0, at logger/logger.php

159 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Forge12\Shared;
3
4 // Sicherstellen, dass Interface existiert
5 if (! interface_exists('Forge12\Shared\LoggerInterface')) {
6 require_once __DIR__ . '/logger.interface.php';
7 }
8
9 if ( ! class_exists( 'Forge12\Shared\Logger' ) ) {
10 class Logger implements LoggerInterface {
11 private static $instance;
12 private $log_file;
13 private $log_level;
14 private $log_dir;
15
16 const DEBUG = 100;
17 const INFO = 200;
18 const NOTICE = 250;
19 const WARNING = 300;
20 const ERROR = 400;
21 const CRITICAL = 500;
22
23 private function __construct() {
24 $upload_dir = wp_upload_dir();
25 $this->log_dir = $upload_dir['basedir'] . '/f12-logs';
26
27 if ( ! file_exists( $this->log_dir ) ) {
28 wp_mkdir_p( $this->log_dir );
29 }
30
31 // Tagesbasiert loggen
32 $this->log_file = $this->log_dir . '/plugins-' . date('Y-m-d') . '.log';
33
34 // Setze Level je nach WP_DEBUG
35 $this->log_level = defined( 'WP_DEBUG' ) && WP_DEBUG ? self::DEBUG : self::INFO;
36 }
37
38 public static function getInstance() {
39 if ( ! self::$instance ) {
40 self::$instance = new self();
41 }
42 return self::$instance;
43 }
44
45 private function sanitizeContext(array $context): array {
46 foreach ($context as $key => $value) {
47 if (in_array(strtolower($key), ['ip', 'user_ip'])) {
48 $context[$key] = $this->mask_ip($value);
49 }
50 if (in_array(strtolower($key), ['email', 'user_email'])) {
51 $context[$key] = $this->mask_email($value);
52 }
53 if (in_array(strtolower($key), ['password', 'pwd'])) {
54 $context[$key] = $this->mask_password($value);
55 }
56 }
57 return $context;
58 }
59
60 private function mask_password(string $password): string {
61 return '********';
62 }
63
64 private function mask_email(string $email): string {
65 if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
66 return 'invalid';
67 }
68 [$user, $domain] = explode('@', $email, 2);
69 $len = strlen($user);
70 if ($len <= 2) {
71 $maskedUser = substr($user, 0, 1) . '*';
72 } else {
73 $maskedUser = substr($user, 0, 1) . str_repeat('*', $len - 2) . substr($user, -1);
74 }
75 return $maskedUser . '@' . $domain;
76 }
77
78 private function mask_ip(string $ip): string {
79 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
80 $parts = explode('.', $ip);
81 $parts[3] = '0';
82 return implode('.', $parts);
83 }
84 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
85 return substr($ip, 0, 20) . '::';
86 }
87 return 'unknown';
88 }
89
90 private function rotateLogs(int $maxSize = 52428800, int $maxFiles = 5): void {
91 if (file_exists($this->log_file) && filesize($this->log_file) > $maxSize) {
92 for ($i = $maxFiles - 1; $i >= 1; $i--) {
93 $old = $this->log_file . '.' . $i;
94 $new = $this->log_file . '.' . ($i + 1);
95 if (file_exists($old)) {
96 rename($old, $new);
97 }
98 }
99 rename($this->log_file, $this->log_file . '.1');
100 }
101 }
102
103 private function cleanupOldLogs(int $days = 7): void {
104 foreach (glob($this->log_dir . '/plugins-*.log*') as $file) {
105 if (filemtime($file) < strtotime("-{$days} days")) {
106 @unlink($file);
107 }
108 }
109 }
110
111 private function writeLog( $level, $levelName, $message, array $context = [] ) {
112 if ( $level < $this->log_level ) {
113 return;
114 }
115
116 // Cleanup & Rotation bei jedem Schreiben
117 $this->cleanupOldLogs();
118 $this->rotateLogs();
119
120 $context = $this->sanitizeContext($context);
121
122 $time = date( 'Y-m-d H:i:s' );
123 $plugin = $context['plugin'] ?? 'unknown';
124 $msg = sprintf( "[%s] [%s] [%s] %s %s\n",
125 $time,
126 strtoupper( $levelName ),
127 $plugin,
128 $message,
129 $context ? json_encode( $context ) : ''
130 );
131 error_log( $msg, 3, $this->log_file );
132 }
133
134 public function debug( $message, array $context = [] ) :void {
135 $this->writeLog( self::DEBUG, 'DEBUG', $message, $context );
136 }
137
138 public function info( $message, array $context = [] ) : void {
139 $this->writeLog( self::INFO, 'INFO', $message, $context );
140 }
141
142 public function error( $message, array $context = [] ) : void {
143 $this->writeLog( self::ERROR, 'ERROR', $message, $context );
144 }
145
146 public function warning( $message, array $context = [] ) : void {
147 $this->writeLog( self::WARNING, 'WARNING', $message, $context );
148 }
149
150 public function notice( $message, array $context = [] ) : void {
151 $this->writeLog( self::NOTICE, 'NOTICE', $message, $context );
152 }
153
154 public function critical( $message, array $context = [] ) : void {
155 $this->writeLog( self::CRITICAL, 'CRITICAL', $message, $context );
156 }
157 }
158 }
159