logUserLookupFailure($e); return self::MODE_SIMPLE; } if (!$userId) { return self::MODE_SIMPLE; } if (!function_exists('get_user_meta')) { return self::MODE_SIMPLE; } try { $mode = get_user_meta($userId, self::META_KEY, true); } catch (\Throwable $e) { $this->logWarning('settings mode read failed (code ' . $e->getCode() . '): ' . $e->getMessage()); return self::MODE_SIMPLE; } return ($mode === self::MODE_ADVANCED) ? self::MODE_ADVANCED : self::MODE_SIMPLE; } /** * Set the current user's settings mode preference. Unknown values * are clamped to 'simple'. * * @param string $mode 'simple' or 'advanced' * @return bool|int Meta ID on insert, true on update, false on failure / no user */ public function setMode($mode) { if (!function_exists('get_current_user_id')) { return false; } try { $userId = get_current_user_id(); } catch (\Throwable $e) { // Delegated to logUserLookupFailure(), which preserves the error // once per process to avoid parallel-test stderr floods. No // allow-silent-catch marker: the delegate call is what makes this // catch non-silent, and a marker here would keep the audit green // if that call were ever removed. $this->logUserLookupFailure($e); return false; } if (!$userId) { return false; } if (!function_exists('update_user_meta')) { return false; } $validMode = ($mode === self::MODE_ADVANCED) ? self::MODE_ADVANCED : self::MODE_SIMPLE; try { return update_user_meta($userId, self::META_KEY, $validMode); } catch (\Throwable $e) { $this->logWarning('settings mode write failed (code ' . $e->getCode() . '): ' . $e->getMessage()); return false; } } private function logUserLookupFailure(\Throwable $e): void { if (strpos($e->getMessage(), 'not defined nor mocked') !== false) { return; } if (self::$loggedUserLookupFailure) { return; } self::$loggedUserLookupFailure = true; $this->logWarning('settings mode user lookup failed (code ' . $e->getCode() . '): ' . $e->getMessage()); } private function logWarning(string $message): void { $logger = function_exists('abj_service_optional') ? abj_service_optional('logging') : null; if (is_object($logger) && method_exists($logger, 'warn')) { $logger->warn($message); return; } abj404_logPhpFallback('service-resolution-fallback', $message); } }