$this->showJsonObjects($nickname_ok);
$this->endDocument('json');
}
-
- function nicknameExists($nickname)
- {
- $user = User::staticGet('nickname', $nickname);
- return ($user instanceof User);
- }
}
{
parent::prepare($args);
- $this->nickname = Nickname::normalize($this->arg('nickname'));
+ $this->nickname = Nickname::normalize($this->arg('nickname'), true);
$this->fullname = $this->arg('full_name');
$this->homepage = $this->arg('homepage');
$this->description = $this->arg('description');
*/
function validateParams()
{
- if ($this->groupNicknameExists($this->nickname)) {
- // TRANS: Client error trying to create a group with a nickname this is already in use.
- $this->clientError(_('Nickname already in use. Try another one.'), 403);
-
- } elseif (!User_group::allowedNickname($this->nickname)) {
- // TRANS: Client error in form for group creation.
- $this->clientError(_('Not a valid nickname.'), 403);
-
- } elseif (!is_null($this->homepage)
+ if (!is_null($this->homepage)
&& strlen($this->homepage) > 0
&& !common_valid_http_url($this->homepage)) {
// TRANS: Client error in form for group creation.
$this->clientError(_('Homepage is not a valid URL.'), 403);
- } elseif (
- !is_null($this->fullname)
+ } elseif (!is_null($this->fullname)
&& mb_strlen($this->fullname) > 255) {
// TRANS: Client error in form for group creation.
$this->clientError(_('Full name is too long (maximum 255 characters).'), 403);
if (!empty($this->aliasstring)) {
$this->aliases = array_map(
- 'common_canonical_nickname',
+ array('Nickname', 'normalize'), // static call to Nickname::normalize
array_unique(preg_split('/[\s,]+/', $this->aliasstring))
);
} else {
403);
}
- foreach ($this->aliases as $alias) {
-
- if (!Nickname::isValid($alias)) {
- // TRANS: Client error shown when providing an invalid alias during group creation.
- // TRANS: %s is the invalid alias.
- $this->clientError(sprintf(_('Invalid alias: "%s".'), $alias), 403);
- }
- if ($this->groupNicknameExists($alias)) {
- // TRANS: Client error displayed when trying to use an alias during group creation that is already in use.
- // TRANS: %s is the alias that is already in use.
- $this->clientError(sprintf(_('Alias "%s" already in use. Try another one.'), $alias), 403);
- }
-
- // XXX assumes alphanum nicknames
-
- if (strcmp($alias, $this->nickname) == 0) {
- // TRANS: Client error displayed when trying to use an alias during group creation that is the same as the group's nickname.
- $this->clientError(_('Alias can\'t be the same as nickname.'), 403);
- }
- }
-
// Everything looks OK
return true;
}
-
- /**
- * Check to see whether a nickname is already in use by a group
- *
- * @param String $nickname The nickname in question
- *
- * @return boolean true or false
- */
- function groupNicknameExists($nickname)
- {
- $local = Local_group::getKV('nickname', $nickname);
-
- if (!empty($local)) {
- return true;
- }
-
- $alias = Group_alias::getKV('alias', $nickname);
-
- if (!empty($alias)) {
- return true;
- }
-
- return false;
- }
}
try {
if (!empty($this->nickname)) {
- if ($this->validateNickname()) {
- $this->group->nickname = $this->nickname;
- $this->group->mainpage = common_local_url(
- 'showgroup',
- array('nickname' => $this->nickname)
- );
+ try {
+ $this->group->nickname = Nickname::normalize($this->nickname, true);
+ } catch (NicknameTakenException $e) {
+ // Abort only if the nickname is occupied by _another_ local group
+ if ($e->profile->id != $this->group->id) {
+ throw new ApiValidationException($e->getMessage());
+ }
+ } catch (NicknameException $e) {
+ throw new ApiValidationException($e->getMessage());
}
+ $this->group->mainpage = common_local_url('showgroup',
+ array('nickname' => $this->group->nickname));
}
if (!empty($this->fullname)) {
if (!empty($this->homepage)) {
$this->validateHomepage();
- $this->group->homepage = $this->hompage;
+ $this->group->homepage = $this->homepage;
}
if (!empty($this->description)) {
}
} catch (ApiValidationException $ave) {
- $this->clientError($ave->getMessage(), 403);
+ $this->clientError($ave->getMessage(), 400);
}
$result = $this->group->update($orig);
if (!empty($this->aliasstring)) {
$aliases = $this->validateAliases();
}
-
} catch (ApiValidationException $ave) {
$this->clientError($ave->getMessage(), 403);
}
}
}
- function nicknameExists($nickname)
- {
- $group = Local_group::getKV('nickname', $nickname);
-
- if (!empty($group) &&
- $group->group_id != $this->group->id) {
- return true;
- }
-
- $alias = Group_alias::getKV('alias', $nickname);
-
- if (!empty($alias) &&
- $alias->group_id != $this->group->id) {
- return true;
- }
-
- return false;
- }
-
- function validateNickname()
- {
- if (!Validate::string(
- $this->nickname, array(
- 'min_length' => 1,
- 'max_length' => 64,
- 'format' => NICKNAME_FMT
- )
- )
- ) {
- throw new ApiValidationException(
- // TRANS: API validation exception thrown when nickname does not validate.
- _('Nickname must have only lowercase letters and numbers and no spaces.')
- );
- } else if ($this->nicknameExists($this->nickname)) {
- throw new ApiValidationException(
- // TRANS: API validation exception thrown when nickname is already used.
- _('Nickname already in use. Try another one.')
- );
- } else if (!User_group::allowedNickname($this->nickname)) {
- throw new ApiValidationException(
- // TRANS: API validation exception thrown when nickname does not validate.
- _('Not a valid nickname.')
- );
- }
-
- return true;
- }
-
function validateHomepage()
{
if (!is_null($this->homepage)
function validateAliases()
{
- $aliases = array_map(
- 'common_canonical_nickname',
- array_unique(
- preg_split('/[\s,]+/',
- $this->aliasstring
- )
- )
- );
+ try {
+ $aliases = array_map(array('Nickname', 'normalize'),
+ array_unique(preg_split('/[\s,]+/', $this->aliasstring)));
+ } catch (NicknameException $e) {
+ throw new ApiValidationException(sprintf('Error processing aliases: %s', $e->getMessage()));
+ }
if (count($aliases) > common_config('group', 'maxaliases')) {
// TRANS: API validation exception thrown when aliases do not validate.
common_config('group', 'maxaliases')));
}
- foreach ($aliases as $alias) {
- if (!Validate::string(
- $alias, array(
- 'min_length' => 1,
- 'max_length' => 64,
- 'format' => NICKNAME_FMT)
- )
- ) {
- throw new ApiValidationException(
- sprintf(
- // TRANS: API validation exception thrown when aliases does not validate.
- // TRANS: %s is the invalid alias.
- _('Invalid alias: "%s".'),
- $alias
- )
- );
- }
-
- if ($this->nicknameExists($alias)) {
- throw new ApiValidationException(
- sprintf(
- // TRANS: API validation exception thrown when aliases is already used.
- // TRANS: %s is the already used alias.
- _('Alias "%s" already in use. Try another one.'),
- $alias)
- );
- }
-
- // XXX assumes alphanum nicknames
- if (strcmp($alias, $this->nickname) == 0) {
- throw new ApiValidationException(
- // TRANS: API validation exception thrown when alias is the same as nickname.
- _('Alias cannot be the same as nickname.')
- );
- }
- }
-
return $aliases;
}
}
if (!$cur->isAdmin($this->group)) {
// TRANS: Client error displayed trying to edit a group while not being a group admin.
$this->clientError(_('You must be an admin to edit the group.'), 403);
- return;
}
if (Event::handle('StartGroupSaveForm', array($this))) {
- $nickname = Nickname::normalize($this->trimmed('newnickname'));
+ $nickname = $this->trimmed('newnickname');
+ try {
+ $nickname = Nickname::normalize($nickname, true);
+ } catch (NicknameTakenException $e) {
+ // Abort only if the nickname is occupied by _another_ group
+ if ($e->profile->id != $this->group->id) {
+ $this->showForm($e->getMessage());
+ return;
+ }
+ $nickname = Nickname::normalize($nickname); // without in-use check this time
+ } catch (NicknameException $e) {
+ $this->showForm($e->getMessage());
+ return;
+ }
+
$fullname = $this->trimmed('fullname');
$homepage = $this->trimmed('homepage');
$description = $this->trimmed('description');
$join_policy = User_group::JOIN_POLICY_OPEN;
}
- if ($this->nicknameExists($nickname)) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Nickname already in use. Try another one.'));
- return;
- } else if (!User_group::allowedNickname($nickname)) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Not a valid nickname.'));
- return;
- } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
+ if (!is_null($homepage) && (strlen($homepage) > 0) &&
!common_valid_http_url($homepage)) {
// TRANS: Group edit form validation error.
$this->showForm(_('Homepage is not a valid URL.'));
}
if (!empty($aliasstring)) {
- $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
+ $aliases = array_map(array('Nickname', 'normalize'),
+ array_unique(preg_split('/[\s,]+/', $aliasstring)));
} else {
$aliases = array();
}
return;
}
- foreach ($aliases as $alias) {
- if (!Nickname::isValid($alias)) {
- // TRANS: Group edit form validation error.
- $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
- return;
- }
- if ($this->nicknameExists($alias)) {
- // TRANS: Group edit form validation error.
- $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
- $alias));
- return;
- }
- // XXX assumes alphanum nicknames
- if (strcmp($alias, $nickname) == 0) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Alias can\'t be the same as nickname.'));
- return;
- }
- }
-
$this->group->query('BEGIN');
$orig = clone($this->group);
$result = $this->group->update($orig);
- if (!$result) {
+ if ($result === false) {
common_log_db_error($this->group, 'UPDATE', __FILE__);
// TRANS: Server error displayed when editing a group fails.
$this->serverError(_('Could not update group.'));
$this->showForm(_('Options saved.'));
}
}
-
- function nicknameExists($nickname)
- {
- $group = Local_group::getKV('nickname', $nickname);
-
- if (!empty($group) &&
- $group->group_id != $this->group->id) {
- return true;
- }
-
- $alias = Group_alias::getKV('alias', $nickname);
-
- if (!empty($alias) &&
- $alias->group_id != $this->group->id) {
- return true;
- }
-
- return false;
- }
}
parent::handlePost();
if (Event::handle('StartGroupSaveForm', array($this))) {
- $nickname = Nickname::normalize($this->trimmed('newnickname'));
+ $nickname = Nickname::normalize($this->trimmed('newnickname'), true);
$fullname = $this->trimmed('fullname');
$homepage = $this->trimmed('homepage');
$private = $this->boolean('private');
$aliasstring = $this->trimmed('aliases');
- if ($this->nicknameExists($nickname)) {
- // TRANS: Group create form validation error.
- throw new ClientException(_('Nickname already in use. Try another one.'));
- } else if (!User_group::allowedNickname($nickname)) {
- // TRANS: Group create form validation error.
- throw new ClientException(_('Not a valid nickname.'));
- } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
+ if (!is_null($homepage) && (strlen($homepage) > 0) &&
!common_valid_http_url($homepage)) {
// TRANS: Group create form validation error.
throw new ClientException(_('Homepage is not a valid URL.'));
}
if (!empty($aliasstring)) {
- $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
+ $aliases = array_map(array('Nickname', 'normalize'), array_unique(preg_split('/[\s,]+/', $aliasstring)));
} else {
$aliases = array();
}
return;
}
- foreach ($aliases as $alias) {
- if (!Nickname::isValid($alias)) {
- // TRANS: Group create form validation error.
- // TRANS: %s is the invalid alias.
- throw new ClientException(sprintf(_('Invalid alias: "%s"'), $alias));
- }
- if ($this->nicknameExists($alias)) {
- // TRANS: Group create form validation error. %s is the already used alias.
- throw new ClientException(sprintf(_('Alias "%s" already in use. Try another one.'),
- $alias));
- }
- // XXX assumes alphanum nicknames
- if (strcmp($alias, $nickname) == 0) {
- // TRANS: Group create form validation error.
- throw new ClientException(_('Alias cannot be the same as nickname.'));
- }
- }
-
if ($private) {
$force_scope = 1;
$join_policy = User_group::JOIN_POLICY_MODERATE;
common_redirect($group->homeUrl(), 303);
}
}
-
- function nicknameExists($nickname)
- {
- $local = Local_group::getKV('nickname', $nickname);
-
- if (!empty($local)) {
- return true;
- }
-
- $alias = Group_alias::getKV('alias', $nickname);
-
- if (!empty($alias)) {
- return true;
- }
-
- return false;
- }
}
try {
$nickname = Nickname::normalize($nickname, true);
} catch (NicknameTakenException $e) {
- // Abort only if the nickname is occupied by another user
- if ($e->byuser->id != $this->scoped->id) {
+ // Abort only if the nickname is occupied by another local profile
+ if ($e->profile->id != $this->scoped->id) {
$this->showForm($e->getMessage());
return;
}
),
);
}
+
+ public function getProfile()
+ {
+ $group = User_group::getKV('id', $this->group_id);
+ if (!($group instanceof User_group)) {
+ return null; // TODO: Throw exception when other code is ready
+ }
+ return $group->getProfile();
+ }
}
);
}
+ public function getProfile()
+ {
+ $group = User_group::getKV('id', $this->group_id);
+ if (!($group instanceof User_group)) {
+ return null; // TODO: Throw exception when other code is ready
+ }
+ return $group->getProfile();
+ }
+
function setNickname($nickname)
{
$this->decache();
function delete()
{
+ if (empty($this->id)) {
+ common_log(LOG_WARNING, "Ambiguous User->delete(); skipping related tables.");
+ return parent::delete();
+ }
+
try {
$profile = $this->getProfile();
$profile->delete();
);
}
+ protected $_profile = null;
+
+ /**
+ * @return Profile
+ *
+ * @throws UserNoProfileException if user has no profile
+ */
+ public function getProfile()
+ {
+ if (!($this->_profile instanceof Profile)) {
+ $this->_profile = Profile::getKV('id', $this->profile_id);
+ if (!($this->_profile instanceof Profile)) {
+ throw new GroupNoProfileException($this);
+ }
+ }
+
+ return $this->_profile;
+ }
+
public static function defaultLogo($size)
{
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
return $stream->getNotices($offset, $limit, $since_id, $max_id);
}
-
- function allowedNickname($nickname)
- {
- static $blacklist = array('new');
- return !in_array($nickname, $blacklist);
- }
-
function getMembers($offset=0, $limit=null) {
$ids = null;
if (is_null($limit) || $offset + $limit > User_group::CACHE_WINDOW) {
}
foreach ($to_insert as $insalias) {
- $alias->alias = $insalias;
+ if ($insalias === $this->nickname) {
+ continue;
+ }
+ $alias->alias = Nickname::normalize($insalias, true);
$result = $alias->insert();
if (!$result) {
common_log_db_error($alias, 'INSERT', __FILE__);
static function getForNickname($nickname, $profile=null)
{
- $nickname = common_canonical_nickname($nickname);
+ $nickname = Nickname::normalize($nickname);
// Are there any matching remote groups this profile's in?
if ($profile) {
}
}
+ $fields['nickname'] = Nickname::normalize($fields['nickname']);
+
// MAGICALLY put fields into current scope
// @fixme kill extract(); it makes debugging absurdly hard
$group = new User_group();
- $group->query('BEGIN');
-
if (empty($uri)) {
// fill in later...
$uri = null;
$mainpage = common_local_url('showgroup', array('nickname' => $nickname));
}
- $group->nickname = $nickname;
- $group->fullname = $fullname;
- $group->homepage = $homepage;
- $group->description = $description;
- $group->location = $location;
- $group->uri = $uri;
- $group->mainpage = $mainpage;
- $group->created = common_sql_now();
+ // We must create a new, incrementally assigned profile_id
+ $profile = new Profile();
+ $profile->nickname = $nickname;
+ $profile->fullname = $fullname;
+ $profile->profileurl = $mainpage;
+ $profile->homepage = $homepage;
+ $profile->bio = $description;
+ $profile->location = $location;
+ $profile->created = common_sql_now();
+
+ $group->nickname = $profile->nickname;
+ $group->fullname = $profile->fullname;
+ $group->homepage = $profile->homepage;
+ $group->description = $profile->bio;
+ $group->location = $profile->location;
+ $group->mainpage = $profile->profileurl;
+ $group->created = $profile->created;
+
+ $profile->query('BEGIN');
+ $id = $profile->insert();
+ if (empty($id)) {
+ $profile->query('ROLLBACK');
+ throw new ServerException(_('Profile insertion failed'));
+ }
+
+ $group->profile_id = $id;
+ $group->uri = $uri;
if (isset($fields['join_policy'])) {
$group->join_policy = intval($fields['join_policy']);
}
}
- $group->query('COMMIT');
-
Event::handle('EndGroupSave', array($group));
}
+ $profile->query('COMMIT');
+
return $group;
}
*/
function delete()
{
- if ($this->id) {
+ if (empty($this->id)) {
+ common_log(LOG_WARNING, "Ambiguous User_group->delete(); skipping related tables.");
+ return parent::delete();
+ }
- // Safe to delete in bulk for now
+ try {
+ $profile = $this->getProfile();
+ $profile->delete();
+ } catch (GroupNoProfileException $unp) {
+ common_log(LOG_INFO, "Group {$this->nickname} has no profile; continuing deletion.");
+ }
- $related = array('Group_inbox',
- 'Group_block',
- 'Group_member',
- 'Related_group');
+ // Safe to delete in bulk for now
- Event::handle('UserGroupDeleteRelated', array($this, &$related));
+ $related = array('Group_inbox',
+ 'Group_block',
+ 'Group_member',
+ 'Related_group');
- foreach ($related as $cls) {
+ Event::handle('UserGroupDeleteRelated', array($this, &$related));
- $inst = new $cls();
- $inst->group_id = $this->id;
+ foreach ($related as $cls) {
+ $inst = new $cls();
+ $inst->group_id = $this->id;
- if ($inst->find()) {
- while ($inst->fetch()) {
- $dup = clone($inst);
- $dup->delete();
- }
+ if ($inst->find()) {
+ while ($inst->fetch()) {
+ $dup = clone($inst);
+ $dup->delete();
}
}
+ }
- // And related groups in the other direction...
- $inst = new Related_group();
- $inst->related_group_id = $this->id;
- $inst->delete();
-
- // Aliases and the local_group entry need to be cleared explicitly
- // or we'll miss clearing some cache keys; that can make it hard
- // to create a new group with one of those names or aliases.
- $this->setAliases(array());
- $local = Local_group::getKV('group_id', $this->id);
- if ($local) {
- $local->delete();
- }
+ // And related groups in the other direction...
+ $inst = new Related_group();
+ $inst->related_group_id = $this->id;
+ $inst->delete();
+
+ // Aliases and the local_group entry need to be cleared explicitly
+ // or we'll miss clearing some cache keys; that can make it hard
+ // to create a new group with one of those names or aliases.
+ $this->setAliases(array());
+ $local = Local_group::getKV('group_id', $this->id);
+ if ($local instanceof Local_group) {
+ $local->delete();
+ }
- // blow the cached ids
- self::blow('user_group:notice_ids:%d', $this->id);
+ // blow the cached ids
+ self::blow('user_group:notice_ids:%d', $this->id);
- } else {
- common_log(LOG_WARNING, "Ambiguous user_group->delete(); skipping related tables.");
- }
- parent::delete();
+ return parent::delete();
}
function isPrivate()
class GroupNoProfileException extends NoProfileException
{
- public $group = null;
+ protected $group = null;
/**
* constructor
{
$this->group = $group;
- // TRANS: Exception text shown when no profile can be found for a user.
- // TRANS: %1$s is a user nickname, $2$d is a user ID (number).
+ // TRANS: Exception text shown when no profile can be found for a group.
+ // TRANS: %1$s is a group nickname, $2$d is a group profile_id (number).
$message = sprintf(_('User %1$s (%2$d) has no profile record.'),
$group->nickname, $group->id);
throw new NicknameBlacklistedException();
} elseif (self::isSystemPath($str)) {
throw new NicknamePathCollisionException();
- } elseif ($checkuse && $user = self::isTaken($str)) {
- if ($user instanceof User) {
- throw new NicknameTakenException($user);
+ } elseif ($checkuse) {
+ $profile = self::isTaken($str);
+ if ($profile instanceof Profile) {
+ throw new NicknameTakenException($profile);
}
}
* Is the nickname already in use locally? Checks the User table.
*
* @param string $str
- * @return User|null Returns null if no such user, otherwise a User object
+ * @return Profile|null Returns Profile if nickname found, otherwise null
*/
public static function isTaken($str)
{
- $user = User::getKV('nickname', $str);
- return $user; // null if no such User entry
+ $found = User::getKV('nickname', $str);
+ if ($found instanceof User) {
+ return $found->getProfile();
+ }
+
+ $found = Local_group::getKV('nickname', $str);
+ if ($found instanceof Local_group) {
+ return $found->getProfile();
+ }
+
+ $found = Group_alias::getKV('alias', $str);
+ if ($found instanceof Group_alias) {
+ return $found->getProfile();
+ }
+
+ return null;
}
}
class NicknameTakenException extends NicknameException
{
- public $user = null; // the User which occupies the nickname
+ public $profile = null; // the Profile which occupies the nickname
- public function __construct(User $user, $msg=null, $code=400)
+ public function __construct(Profile $profile, $msg=null, $code=400)
{
- $this->byuser = $user;
+ $this->profile = $profile;
if ($msg === null) {
$msg = $this->defaultMessage();
* @link http://status.net/
*/
-class NoProfileException extends NoProfileException
+class NoProfileException extends ServerException
{
public $profile_id = null;
public function __construct($profile_id, $msg=null)
{
- $this->id = (int)$profile_id;
+ $this->id = $profile_id;
if ($msg === null) {
// TRANS: Exception text shown when no profile can be found for a user.
// TRANS: %1$s is a user nickname, $2$d is a user ID (number).
- $msg = sprintf(_('User %1$s (%2$d) has no profile record.'),
- $group->nickname, $group->id);
+ $msg = sprintf(_('There is no profile with id==%u'), $this->id);
}
parent::__construct($msg, 404);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-if (!defined('STATUSNET') && !defined('LACONICA')) {
- exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Queue handler for letting plugins handle stuff.
{
try {
Event::handle('HandleQueuedNotice', array(&$notice));
- } catch (UserNoProfileException $unp) {
+ } catch (NoProfileException $unp) {
// We can't do anything about this, so just skip
return true;
}
try {
return Nickname::normalize($this->tw_fields['fullname'], true);
} catch (NicknameException $e) {
- return null
+ return null;
}
}
}