$user, 'password' => $pass ); $result = $this->http_functions('validateMember', $params); if ($result === false) { // curl_exec failure: we'll return false anyway return $result; } return (json_decode($result)) ? $user : false; } /** */ public function canValidateByEmail() : bool { return true; } /** */ public function canValidateByUsername() : bool { return false; } protected function getUserFresh(string $username) : ?User { global $auth; $params = array('email' => $username); $result = $this->http_functions('getMemberByEmail', $params); // The username doesn't exist - return NULL if (($result === false) || ($result === '') || ($result === json_encode(null))) { return null; } $result = json_decode($result); $user = new User($username); // Set the email address $user->email = $result->member->loginEmail; // Set the display name $property = $auth['wix']['display_name_property'] ?? 'name'; if (isset($result->member->$property) && ($result->member->$property !== '')) { $user->display_name = $result->member->$property; } else { $user->display_name = $result->member->loginEmail; } // Set the level // First get the default level. Any admins defined in the config // file override settings in the external database. $user->level = $this->getDefaultLevel($username); // Then if they are not an admin get their admin status from Wix if (($user->level < 2) && isset($result->badges) && in_array($auth['wix']['admin_badge'], $result->badges)) { $user->level = 2; } return $user; } // Return an array of users, indexed by 'username' and 'display_name' public function getUsernames() : array { global $auth; $params = array(); if (isset($auth['wix']['display_name_property'])) { $params['display_name_property'] = $auth['wix']['display_name_property']; } $result = $this->http_functions('getMemberNames', $params); if ($result === false) { return array(); } $users = json_decode($result, true); self::sortUsers($users); return $users; } private function http_functions(string $function, array $params) { global $auth, $server; // Add a trailing '/' if necessary if (!str_ends_with($auth['wix']['site_url'], '/')) { $auth['wix']['site_url'] .= '/'; } // Get a user agent to keep the other end happy if (isset($server['HTTP_USER_AGENT']) && ($server['HTTP_USER_AGENT'] !== '')) { $user_agent = $server['HTTP_USER_AGENT']; } else { $user_agent = 'PHP'; } // Add in the API key $params['key'] = $auth['wix']['mrbs_api_key']; // And the API key secret name in Wix $params['secret_name'] = $auth['wix']['mrbs_api_key_secret_name']; // And the limit, for internal use by the Wix backend code if (isset($auth['wix']['limit'])) { $params['limit'] = $auth['wix']['limit']; } $url = $auth['wix']['site_url'] . "_functions/$function"; self::debug("URL=\"$url\""); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Necessary to prevent "HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)" error; curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // Necessary to prevent "OpenSSL SSL_read: Connection reset by peer, errno 104" error; curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params)); // Use compression if we can if (defined('CURLOPT_ENCODING')) { curl_setopt($ch, CURLOPT_ENCODING, ''); } // Get some debug info in case there's an error curl_setopt($ch, CURLOPT_VERBOSE, true); $stream = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $stream); $result = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($result === false) { rewind($stream); $message = curl_error($ch); $message .= "\n\nCurl verbose log:\n\n" . stream_get_contents($stream); trigger_error($message, E_USER_WARNING); } elseif ($http_code != 200) { trigger_error("Curl received HTTP response code $http_code: $result", E_USER_WARNING); $result = false; } fclose($stream); // curl_close() doesn't do anything from PHP 8.0 onwards (because the curl // handle is an object and not a resource) and is deprecated from PHP 8.5. assert(version_compare(MRBS_MIN_PHP_VERSION, '8.0.0', '<'), "The code below is now redundant."); if (version_compare(PHP_VERSION, '8.0.0') < 0) { curl_close($ch); } return $result; } private static function debug(string $message) : void { global $auth; if ($auth['wix']['debug']) { self::logDebugMessage($message); } } }