PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / services / SettingsModePreference.php

SettingsModePreference.php in 404 Solution 4.3.0, at includes/services/SettingsModePreference.php

133 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Per-user UI preference: tracks whether the current WP user wants
9 * the plugin's settings/admin surface rendered in "simple" or
10 * "advanced" mode. Backed by `user_meta` (key `abj404_settings_mode`).
11 *
12 * Owns getSettingsMode / setSettingsMode previously hosted on
13 * PluginLogic. Composed through abj_service('settings_mode_preference').
14 *
15 * Unknown / missing / unauthenticated callers fall back to 'simple'
16 * (the safer default for a brand-new install).
17 */
18 class ABJ_404_Solution_SettingsModePreference {
19
20 const META_KEY = 'abj404_settings_mode';
21 const MODE_SIMPLE = 'simple';
22 const MODE_ADVANCED = 'advanced';
23
24 /** @var self|null */
25 private static $instance = null;
26
27 /** @var bool */
28 private static $loggedUserLookupFailure = false;
29
30 /** @return self */
31 public static function getInstance(): self {
32 if (self::$instance !== null) {
33 return self::$instance;
34 }
35 self::$instance = new self();
36 return self::$instance;
37 }
38
39 /** Test-seam reset. @return void */
40 public static function reset(): void {
41 self::$instance = null;
42 self::$loggedUserLookupFailure = false;
43 }
44
45 /**
46 * Get the current user's settings mode preference.
47 *
48 * @return string 'simple' or 'advanced'
49 */
50 public function getMode(): string {
51 if (!function_exists('get_current_user_id')) {
52 return self::MODE_SIMPLE;
53 }
54 try {
55 $userId = get_current_user_id();
56 } catch (\Throwable $e) {
57 // allow-silent-catch: delegated to logUserLookupFailure(), which preserves the error once per process to avoid parallel-test stderr floods.
58 $this->logUserLookupFailure($e);
59 return self::MODE_SIMPLE;
60 }
61 if (!$userId) {
62 return self::MODE_SIMPLE;
63 }
64 if (!function_exists('get_user_meta')) {
65 return self::MODE_SIMPLE;
66 }
67 try {
68 $mode = get_user_meta($userId, self::META_KEY, true);
69 } catch (\Throwable $e) {
70 $this->logWarning('settings mode read failed (code ' .
71 $e->getCode() . '): ' . $e->getMessage());
72 return self::MODE_SIMPLE;
73 }
74 return ($mode === self::MODE_ADVANCED) ? self::MODE_ADVANCED : self::MODE_SIMPLE;
75 }
76
77 /**
78 * Set the current user's settings mode preference. Unknown values
79 * are clamped to 'simple'.
80 *
81 * @param string $mode 'simple' or 'advanced'
82 * @return bool|int Meta ID on insert, true on update, false on failure / no user
83 */
84 public function setMode($mode) {
85 if (!function_exists('get_current_user_id')) {
86 return false;
87 }
88 try {
89 $userId = get_current_user_id();
90 } catch (\Throwable $e) {
91 // allow-silent-catch: delegated to logUserLookupFailure(), which preserves the error once per process to avoid parallel-test stderr floods.
92 $this->logUserLookupFailure($e);
93 return false;
94 }
95 if (!$userId) {
96 return false;
97 }
98 if (!function_exists('update_user_meta')) {
99 return false;
100 }
101 $validMode = ($mode === self::MODE_ADVANCED) ? self::MODE_ADVANCED : self::MODE_SIMPLE;
102 try {
103 return update_user_meta($userId, self::META_KEY, $validMode);
104 } catch (\Throwable $e) {
105 $this->logWarning('settings mode write failed (code ' .
106 $e->getCode() . '): ' . $e->getMessage());
107 return false;
108 }
109 }
110
111 private function logUserLookupFailure(\Throwable $e): void {
112 if (strpos($e->getMessage(), 'not defined nor mocked') !== false) {
113 return;
114 }
115 if (self::$loggedUserLookupFailure) {
116 return;
117 }
118 self::$loggedUserLookupFailure = true;
119 $this->logWarning('settings mode user lookup failed (code ' .
120 $e->getCode() . '): ' . $e->getMessage());
121 }
122
123 private function logWarning(string $message): void {
124 $logger = function_exists('abj_service_optional') ? abj_service_optional('logging') : null;
125 if (is_object($logger) && method_exists($logger, 'warn')) {
126 $logger->warn($message);
127 return;
128 }
129
130 abj404_logPhpFallback('service-resolution-fallback', $message);
131 }
132 }
133