X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FUser.php;h=d6dfa3525361800e5174fdd40a44c139b2b35e22;hb=8b26d488add6859be8d3b865122dfb6a6401d24d;hp=916844251e5c69710faa69890c52f826d0ef56f4;hpb=5c332af844eeace5d0fb61314dd29c22e6e465fd;p=friendica.git diff --git a/src/Model/User.php b/src/Model/User.php index 916844251e..d6dfa35253 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1,6 +1,6 @@ get(); + $system['homepage'] = (string)DI::baseUrl(); $system['dob'] = '0000-00-00'; // Ensure that the user contains data - $user = DBA::selectFirst('user', ['prvkey', 'guid'], ['uid' => 0]); + $user = DBA::selectFirst('user', ['prvkey', 'guid', 'language'], ['uid' => 0]); if (empty($user['prvkey']) || empty($user['guid'])) { $fields = [ 'username' => $system['name'], @@ -190,7 +203,8 @@ class User $system['guid'] = $fields['guid']; } else { - $system['guid'] = $user['guid']; + $system['guid'] = $user['guid']; + $system['language'] = $user['language']; } return $system; @@ -219,7 +233,7 @@ class User 'self' => true, 'network' => Protocol::ACTIVITYPUB, 'name' => 'System Account', - 'addr' => $system_actor_name . '@' . DI::baseUrl()->getHostname(), + 'addr' => $system_actor_name . '@' . DI::baseUrl()->getHost(), 'nick' => $system_actor_name, 'url' => DI::baseUrl() . '/friendica', 'pubkey' => $keys['pubkey'], @@ -482,23 +496,63 @@ class User } /** - * Returns the default group for a given user and network + * Returns the default circle for a given user * * @param int $uid User id * - * @return int group id + * @return int circle id * @throws Exception */ - public static function getDefaultGroup(int $uid): int + public static function getDefaultCircle(int $uid): int { $user = DBA::selectFirst('user', ['def_gid'], ['uid' => $uid]); if (DBA::isResult($user)) { - $default_group = $user["def_gid"]; + $default_circle = $user['def_gid']; } else { - $default_group = 0; + $default_circle = 0; + } + + return $default_circle; + } + + /** + * Returns the default circle for groups for a given user + * + * @param int $uid User id + * + * @return int circle id + * @throws Exception + */ + public static function getDefaultGroupCircle(int $uid): int + { + $default_circle = DI::pConfig()->get($uid, 'system', 'default-group-gid'); + if (empty($default_circle)) { + $default_circle = self::getDefaultCircle($uid); } - return $default_group; + return $default_circle; + } + +/** + * Fetch the language code from the given user. If the code is invalid, return the system language + * + * @param integer $uid User-Id + * @param boolean $short If true, return the short form g.g. "en", otherwise the long form e.g. "en-gb" + * @return string + */ + public static function getLanguageCode(int $uid, bool $short): string + { + $owner = self::getOwnerDataById($uid); + $languages = DI::l10n()->getAvailableLanguages(); + if (in_array($owner['language'], array_keys($languages))) { + $language = $owner['language']; + } else { + $language = DI::config()->get('system', 'language'); + } + if ($short) { + return substr($language, 0, 2); + } + return $language; } /** @@ -528,7 +582,7 @@ class User // Addons can create users, and since this 'catch' branch should only // execute if getAuthenticationInfo can't find an existing user, that's // exactly what will happen here. Creating a numeric username would create - // abiguity with user IDs, possibly opening up an attack vector. + // ambiguity with user IDs, possibly opening up an attack vector. // So let's be very careful about that. if (empty($username) || is_numeric($username)) { throw $e; @@ -674,6 +728,10 @@ class User */ public static function updateLastActivity(int $uid) { + if (!$uid) { + return; + } + $user = User::getById($uid, ['last-activity']); if (empty($user)) { return; @@ -683,7 +741,7 @@ class User if ($user['last-activity'] != $current_day) { User::update(['last-activity' => $current_day], $uid); - // Set the last actitivy for all identities of the user + // Set the last activity for all identities of the user DBA::update('user', ['last-activity' => $current_day], ['parent-uid' => $uid, 'account_removed' => false]); } } @@ -757,7 +815,7 @@ class User } /** - * Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:). + * Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters. * * Password length is limited to 72 characters if the current default password hashing algorithm is Blowfish. * From the manual: "Using the PASSWORD_BCRYPT as the algorithm, will result in the password parameter being @@ -770,13 +828,13 @@ class User */ public static function getPasswordRegExp(string $delimiter = null): string { - $allowed_characters = '!"#$%&\'()*+,-./;<=>?@[\]^_`{|}~'; + $allowed_characters = ':!"#$%&\'()*+,-./;<=>?@[\]^_`{|}~'; if ($delimiter) { $allowed_characters = preg_quote($allowed_characters, $delimiter); } - return '^[a-zA-Z0-9' . $allowed_characters . ']' . (PASSWORD_DEFAULT !== PASSWORD_BCRYPT ? '{1,72}' : '+') . '$'; + return '^[a-zA-Z0-9' . $allowed_characters . ']' . (PASSWORD_DEFAULT === PASSWORD_BCRYPT ? '{1,72}' : '+') . '$'; } /** @@ -804,7 +862,7 @@ class User } if (!preg_match('/' . self::getPasswordRegExp('/') . '/', $password)) { - throw new Exception(DI::l10n()->t('The password can\'t contain accentuated letters, white spaces or colons (:)')); + throw new Exception(DI::l10n()->t("The password can't contain white spaces nor accentuated letters")); } return self::updatePasswordHashed($uid, self::hashPassword($password)); @@ -815,14 +873,14 @@ class User * Empties the password reset token field just in case. * * @param int $uid - * @param string $pasword_hashed + * @param string $password_hashed * @return bool * @throws Exception */ - private static function updatePasswordHashed(int $uid, string $pasword_hashed): bool + private static function updatePasswordHashed(int $uid, string $password_hashed): bool { $fields = [ - 'password' => $pasword_hashed, + 'password' => $password_hashed, 'pwdreset' => null, 'pwdreset_time' => null, 'legacy_password' => false @@ -846,11 +904,25 @@ class User ]); } + /** + * Returns if the given uid is valid and a moderator + * + * @param int $uid + * + * @return bool + * @throws Exception + */ + public static function isModerator(int $uid): bool + { + // @todo Replace with a moderator check in the future + return self::isSiteAdmin($uid); + } + /** * Checks if a nickname is in the list of the forbidden nicknames * * Check if a nickname is forbidden from registration on the node by the - * admin. Forbidden nicknames (e.g. role namess) can be configured in the + * admin. Forbidden nicknames (e.g. role names) can be configured in the * admin panel. * * @param string $nickname The nickname that should be checked @@ -1023,7 +1095,7 @@ class User $_SESSION['register'] = 1; $_SESSION['openid'] = $openid_url; - $openid = new LightOpenID(DI::baseUrl()->getHostname()); + $openid = new LightOpenID(DI::baseUrl()->getHost()); $openid->identity = $openid_url; $openid->returnUrl = DI::baseUrl() . '/openid'; $openid->required = ['namePerson/friendly', 'contact/email', 'namePerson']; @@ -1187,13 +1259,13 @@ class User throw new Exception(DI::l10n()->t('An error occurred creating your self contact. Please try again.')); } - // Create a group with no members. This allows somebody to use it - // right away as a default group for new contacts. - $def_gid = Group::create($uid, DI::l10n()->t('Friends')); + // Create a circle with no members. This allows somebody to use it + // right away as a default circle for new contacts. + $def_gid = Circle::create($uid, DI::l10n()->t('Friends')); if (!$def_gid) { DBA::delete('user', ['uid' => $uid]); - throw new Exception(DI::l10n()->t('An error occurred creating your default contact group. Please try again.')); + throw new Exception(DI::l10n()->t('An error occurred creating your default contact circle. Please try again.')); } $fields = ['def_gid' => $def_gid]; @@ -1203,6 +1275,11 @@ class User DBA::update('user', $fields, ['uid' => $uid]); + $def_gid_groups = Circle::create($uid, DI::l10n()->t('Groups')); + if ($def_gid_groups) { + DI::pConfig()->set($uid, 'system', 'default-group-gid', $def_gid_groups); + } + // if we have no OpenID photo try to look up an avatar if (!strlen($photo)) { $photo = Network::lookupAvatarByEmail($email); @@ -1231,7 +1308,7 @@ class User $resource_id = Photo::newResource(); - // Not using Photo::PROFILE_PHOTOS here, so that it is discovered as translateble string + // Not using Photo::PROFILE_PHOTOS here, so that it is discovered as translatable string $profile_album = DI::l10n()->t('Profile Photos'); $r = Photo::store($image, $uid, 0, $resource_id, $filename, $profile_album, 4); @@ -1266,6 +1343,8 @@ class User Hook::callAll('register_account', $uid); + self::setRegisterMethodByUserCount(); + $return['user'] = $user; return $return; } @@ -1273,33 +1352,18 @@ class User /** * Update a user entry and distribute the changes if needed * - * @param array $fields + * @param array $fields * @param integer $uid * @return boolean + * @throws Exception */ public static function update(array $fields, int $uid): bool { - $old_owner = self::getOwnerDataById($uid); - if (empty($old_owner)) { - return false; - } - if (!DBA::update('user', $fields, ['uid' => $uid])) { return false; } - $update = Contact::updateSelfFromUserID($uid); - - $owner = self::getOwnerDataById($uid); - if (empty($owner)) { - return false; - } - - if ($old_owner['name'] != $owner['name']) { - Profile::update(['name' => $owner['name']], $uid); - } - - if ($update) { + if (Contact::updateSelfFromUserID($uid)) { Profile::publishUpdate($uid); } @@ -1360,7 +1424,7 @@ class User $l10n, $user, DI::config()->get('config', 'sitename'), - DI::baseUrl()->get(), + DI::baseUrl(), ($register['password'] ?? '') ?: 'Sent in a previous email' ); } @@ -1374,7 +1438,7 @@ class User * permanently against re-registration, as the person was not yet * allowed to have friends on this system * - * @return bool True, if the deny was successfull + * @return bool True, if the deny was successful * @throws Exception */ public static function deny(string $hash): bool @@ -1457,7 +1521,7 @@ class User Thank you and welcome to %4$s.')); $preamble = sprintf($preamble, $user['username'], DI::config()->get('config', 'sitename')); - $body = sprintf($body, DI::baseUrl()->get(), $user['nickname'], $result['password'], DI::config()->get('config', 'sitename')); + $body = sprintf($body, DI::baseUrl(), $user['nickname'], $result['password'], DI::config()->get('config', 'sitename')); $email = DI::emailer() ->newSystemMail() @@ -1610,6 +1674,7 @@ class User // Remove the user relevant data Worker::add(Worker::PRIORITY_NEGLIGIBLE, 'RemoveUser', $uid); + self::setRegisterMethodByUserCount(); return true; } @@ -1636,7 +1701,7 @@ class User */ public static function identities(int $uid): array { - if (empty($uid)) { + if (!$uid) { return []; } @@ -1647,7 +1712,7 @@ class User return $identities; } - if ($user['parent-uid'] == 0) { + if (!$user['parent-uid']) { // First add our own entry $identities = [[ 'uid' => $user['uid'], @@ -1708,7 +1773,7 @@ class User */ public static function hasIdentities(int $uid): bool { - if (empty($uid)) { + if (!$uid) { return false; } @@ -1717,7 +1782,7 @@ class User return false; } - if ($user['parent-uid'] != 0) { + if ($user['parent-uid']) { return true; } @@ -1788,7 +1853,7 @@ class User * * @param int $start Start count (Default is 0) * @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE) - * @param string $type The type of users, which should get (all, bocked, removed) + * @param string $type The type of users, which should get (all, blocked, removed) * @param string $order Order of the user list (Default is 'contact.name') * @param bool $descending Order direction (Default is ascending) * @return array|bool The list of the users @@ -1844,8 +1909,8 @@ class User { $condition = [ 'email' => self::getAdminEmailList(), - 'parent-uid' => 0, - 'blocked' => 0, + 'parent-uid' => null, + 'blocked' => false, 'verified' => true, 'account_removed' => false, 'account_expired' => false, @@ -1877,4 +1942,29 @@ class User return true; }); } + + public static function setRegisterMethodByUserCount() + { + $max_registered_users = DI::config()->get('config', 'max_registered_users'); + if ($max_registered_users <= 0) { + return; + } + + $register_policy = DI::config()->get('config', 'register_policy'); + if (!in_array($register_policy, [Module\Register::OPEN, Module\Register::CLOSED])) { + Logger::debug('Unsupported register policy.', ['policy' => $register_policy]); + return; + } + + $users = DBA::count('user', ['blocked' => false, 'account_removed' => false, 'account_expired' => false]); + if (($users >= $max_registered_users) && ($register_policy == Module\Register::OPEN)) { + DI::config()->set('config', 'register_policy', Module\Register::CLOSED); + Logger::notice('Max users reached, registration is closed.', ['users' => $users, 'max' => $max_registered_users]); + } elseif (($users < $max_registered_users) && ($register_policy == Module\Register::CLOSED)) { + DI::config()->set('config', 'register_policy', Module\Register::OPEN); + Logger::notice('Below maximum users, registration is opened.', ['users' => $users, 'max' => $max_registered_users]); + } else { + Logger::debug('Unchanged register policy', ['policy' => $register_policy, 'users' => $users, 'max' => $max_registered_users]); + } + } }