use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
+use Friendica\Module;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
+use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Network\HTTPException;
use Friendica\Object\Image;
* ACCOUNT_TYPE_NEWS - the account is a news reflector
* Associated page type: PAGE_FLAGS_SOAPBOX
*
- * ACCOUNT_TYPE_COMMUNITY - the account is community forum
+ * ACCOUNT_TYPE_COMMUNITY - the account is community group
* Associated page types: PAGE_COMMUNITY, PAGE_FLAGS_PRVGROUP
*
* ACCOUNT_TYPE_RELAY - the account is a relay
return null;
}
+ /**
+ * Get the Uri-Id of the system account
+ *
+ * @return integer
+ */
+ public static function getSystemUriId(): int
+ {
+ $system = self::getSystemAccount();
+ return $system['uri-id'] ?? 0;
+ }
+
/**
* Fetch the system account
*
$system['region'] = '';
$system['postal-code'] = '';
$system['country-name'] = '';
- $system['homepage'] = DI::baseUrl();
+ $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'],
$system['guid'] = $fields['guid'];
} else {
- $system['guid'] = $user['guid'];
+ $system['guid'] = $user['guid'];
+ $system['language'] = $user['language'];
}
return $system;
}
/**
- * 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;
}
/**
// 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;
*/
public static function updateLastActivity(int $uid)
{
+ if (!$uid) {
+ return;
+ }
+
$user = User::getById($uid, ['last-activity']);
if (empty($user)) {
return;
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]);
}
}
* 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
]);
}
+ /**
+ * 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
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];
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);
$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);
Hook::callAll('register_account', $uid);
+ self::setRegisterMethodByUserCount();
+
$return['user'] = $user;
return $return;
}
/**
* 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);
}
* 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
// Remove the user relevant data
Worker::add(Worker::PRIORITY_NEGLIGIBLE, 'RemoveUser', $uid);
+ self::setRegisterMethodByUserCount();
return true;
}
*/
public static function identities(int $uid): array
{
- if (empty($uid)) {
+ if (!$uid) {
return [];
}
return $identities;
}
- if ($user['parent-uid'] == 0) {
+ if (!$user['parent-uid']) {
// First add our own entry
$identities = [[
'uid' => $user['uid'],
*/
public static function hasIdentities(int $uid): bool
{
- if (empty($uid)) {
+ if (!$uid) {
return false;
}
return false;
}
- if ($user['parent-uid'] != 0) {
+ if ($user['parent-uid']) {
return true;
}
*
* @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
{
$condition = [
'email' => self::getAdminEmailList(),
- 'parent-uid' => 0,
- 'blocked' => 0,
+ 'parent-uid' => null,
+ 'blocked' => false,
'verified' => true,
'account_removed' => false,
'account_expired' => false,
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]);
+ }
+ }
}