/** * Prepare to run */ function prepare($args) { parent::prepare($args); if (!common_logged_in()) { // TRANS: Client error displayed when trying to perform an action while not logged in. $this->clientError(_('You must be logged in to unsubscribe from a list.')); } // Only allow POST requests if ($_SERVER['REQUEST_METHOD'] != 'POST') { // TRANS: Client error displayed when trying to use another method than POST. $this->clientError(_('This action only accepts POST requests.')); } // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Client error displayed when the session token does not match or is not given. $this->clientError(_('There was a problem with your session token.' . ' Try again, please.')); } $tagger_arg = $this->trimmed('tagger'); $tag_arg = $this->trimmed('tag'); $id = intval($this->arg('id')); if ($id) { $this->peopletag = Profile_list::getKV('id', $id); } else { // TRANS: Client error displayed when trying to perform an action without providing an ID. $this->clientError(_('No ID given.'), 404); } if (!$this->peopletag || $this->peopletag->private) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.'), 404); } $this->tagger = Profile::getKV('id', $this->peopletag->tagger); return true; }
static function add($peopletag, $profile) { if ($peopletag->private) { return false; } if (Event::handle('StartSubscribePeopletag', array($peopletag, $profile))) { $args = array('profile_tag_id' => $peopletag->id, 'profile_id' => $profile->id); $existing = Profile_tag_subscription::pkeyGet($args); if (!empty($existing)) { return $existing; } $sub = new Profile_tag_subscription(); $sub->profile_tag_id = $peopletag->id; $sub->profile_id = $profile->id; $sub->created = common_sql_now(); $result = $sub->insert(); if (!$result) { common_log_db_error($sub, 'INSERT', __FILE__); // TRANS: Exception thrown when inserting a list subscription in the database fails. throw new Exception(_('Adding list subscription failed.')); } $ptag = Profile_list::getKV('id', $peopletag->id); $ptag->subscriberCount(true); Event::handle('EndSubscribePeopletag', array($peopletag, $profile)); return $ptag; } }
/** * Check pre-requisites and instantiate attributes * * @param Array $args array of arguments (URL, GET, POST) * * @return boolean success flag */ function prepare($args) { parent::prepare($args); // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Client error displayed when the session token does not match or is not given. $this->clientError(_('There was a problem with your session token.' . ' Try again, please.')); } // Only for logged-in users $this->user = common_current_user(); if (empty($this->user)) { // TRANS: Error message displayed when trying to perform an action that requires a logged in user. $this->clientError(_('Not logged in.')); } $id = $this->arg('peopletag_id'); $this->peopletag = Profile_list::getKV('id', $id); if (empty($this->peopletag)) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.')); } $field = $this->arg('field'); if (!in_array($field, array('fulltext', 'nickname', 'fullname', 'description', 'location', 'uri'))) { // TRANS: Client error displayed when trying to add an unindentified field to profile. // TRANS: %s is a field name. $this->clientError(sprintf(_('Unidentified field %s.'), htmlspecialchars($field)), 404); } $this->field = $field; return true; }
/** * Prepare to run */ function prepare($args) { parent::prepare($args); if (!common_logged_in()) { // TRANS: Error message displayed when trying to perform an action that requires a logged in user. $this->clientError(_('Not logged in.')); } $id = $this->arg('id'); if (common_config('singleuser', 'enabled')) { $tagger_arg = User::singleUserNickname(); } else { $tagger_arg = $this->arg('tagger'); } $tag_arg = $this->arg('tag'); $tagger = common_canonical_nickname($tagger_arg); $tag = common_canonical_tag($tag_arg); $current = common_current_user(); // Permanent redirect on non-canonical tag if ($tagger_arg != $tagger || $tag_arg != $tag) { $args = array('tagger' => $tagger, 'tag' => $tag); common_redirect(common_local_url('editpeopletag', $args), 301); } $user = null; if ($id) { $this->peopletag = Profile_list::getKV('id', $id); if (!empty($this->peopletag)) { $user = User::getKV('id', $this->peopletag->tagger); } } else { if (!$tagger) { // TRANS: Error message displayed when trying to perform an action that requires a tagging user or ID. $this->clientError(_('No tagger or ID.'), 404); } $user = User::getKV('nickname', $tagger); $this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag)); } if (!$this->peopletag) { // TRANS: Client error displayed when referring to a non-existing list. $this->clientError(_('No such list.'), 404); } if (!$user) { // This should not be happening // TRANS: Client error displayed when referring to non-local user. $this->clientError(_('Not a local user.'), 404); } if ($current->id != $user->id) { // TRANS: Client error displayed when reting to edit a tag that was not self-created. $this->clientError(_('You must be the creator of the tag to edit it.'), 404); } $this->tagger = $user->getProfile(); return true; }
protected function prepare(array $args = array()) { parent::prepare($args); $id = $this->trimmed('id'); if (!$id) { // TRANS: Client error displayed trying to perform an action without providing an ID. $this->clientError(_m('No ID.')); } $this->peopletag = Profile_list::getKV('id', $id); if (!$this->peopletag instanceof Profile_list) { // TRANS: Client error displayed when referring to a non-existing list. $this->clientError(_m('No such list.')); } $this->target = $this->peopletag; $remote_list = Ostatus_profile::getKV('peopletag_id', $id); if ($remote_list instanceof Ostatus_profile) { // TRANS: Client error displayed when trying to send a message to a remote list. $this->clientError(_m('Cannot accept remote posts for a remote list.')); } return true; }
function prepare($args) { parent::prepare($args); $id = $this->arg('id'); $tagger_id = $this->arg('tagger_id'); if (!$id) { // TRANS: Client error displayed trying to perform an action without providing an ID. $this->clientError(_('No ID.')); } common_debug("Peopletag id {$id} by user id {$tagger_id}"); $this->peopletag = Profile_list::getKV('id', $id); if (!$this->peopletag) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.'), 404); } $user = User::getKV('id', $tagger_id); if (!$user) { // remote peopletag, permanently redirect common_redirect($this->peopletag->permalink(), 301); } return true; }
/** * Create local ostatus_profile and profile/user_group entries for * the provided remote user or group. * This should never return null -- you will either get an object or * an exception will be thrown. * * @param ActivityObject $object * @param array $hints * * @return Ostatus_profile */ protected static function createActivityObjectProfile(ActivityObject $object, array $hints = array()) { $homeuri = $object->id; $discover = false; if (!$homeuri) { common_log(LOG_DEBUG, __METHOD__ . " empty actor profile URI: " . var_export($activity, true)); // TRANS: Exception. throw new Exception(_m('No profile URI.')); } $user = User::getKV('uri', $homeuri); if ($user instanceof User) { // TRANS: Exception. throw new Exception(_m('Local user cannot be referenced as remote.')); } if (OStatusPlugin::localGroupFromUrl($homeuri)) { // TRANS: Exception. throw new Exception(_m('Local group cannot be referenced as remote.')); } $ptag = Profile_list::getKV('uri', $homeuri); if ($ptag instanceof Profile_list) { $local_user = User::getKV('id', $ptag->tagger); if ($local_user instanceof User) { // TRANS: Exception. throw new Exception(_m('Local list cannot be referenced as remote.')); } } if (array_key_exists('feedurl', $hints)) { $feeduri = $hints['feedurl']; } else { $discover = new FeedDiscovery(); $feeduri = $discover->discoverFromURL($homeuri); } if (array_key_exists('salmon', $hints)) { $salmonuri = $hints['salmon']; } else { if (!$discover) { $discover = new FeedDiscovery(); $discover->discoverFromFeedURL($hints['feedurl']); } // XXX: NS_REPLIES is deprecated anyway, so let's remove it in the future. $salmonuri = $discover->getAtomLink(Salmon::REL_SALMON) ?: $discover->getAtomLink(Salmon::NS_REPLIES); } if (array_key_exists('hub', $hints)) { $huburi = $hints['hub']; } else { if (!$discover) { $discover = new FeedDiscovery(); $discover->discoverFromFeedURL($hints['feedurl']); } $huburi = $discover->getHubLink(); } if (!$huburi && !common_config('feedsub', 'fallback_hub') && !common_config('feedsub', 'nohub')) { // We can only deal with folks with a PuSH hub throw new FeedSubNoHubException(); } $oprofile = new Ostatus_profile(); $oprofile->uri = $homeuri; $oprofile->feeduri = $feeduri; $oprofile->salmonuri = $salmonuri; $oprofile->created = common_sql_now(); $oprofile->modified = common_sql_now(); if ($object->type == ActivityObject::PERSON) { $profile = new Profile(); $profile->created = common_sql_now(); self::updateProfile($profile, $object, $hints); $oprofile->profile_id = $profile->insert(); if ($oprofile->profile_id === false) { // TRANS: Server exception. throw new ServerException(_m('Cannot save local profile.')); } } else { if ($object->type == ActivityObject::GROUP) { $profile = new Profile(); $profile->query('BEGIN'); $group = new User_group(); $group->uri = $homeuri; $group->created = common_sql_now(); self::updateGroup($group, $object, $hints); // TODO: We should do this directly in User_group->insert()! // currently it's duplicated in User_group->update() // AND User_group->register()!!! $fields = array('nickname' => 'nickname', 'fullname' => 'fullname', 'mainpage' => 'profileurl', 'homepage' => 'homepage', 'description' => 'bio', 'location' => 'location', 'created' => 'created', 'modified' => 'modified'); foreach ($fields as $gf => $pf) { $profile->{$pf} = $group->{$gf}; } $profile_id = $profile->insert(); if ($profile_id === false) { $profile->query('ROLLBACK'); throw new ServerException(_('Profile insertion failed.')); } $group->profile_id = $profile_id; $oprofile->group_id = $group->insert(); if ($oprofile->group_id === false) { $profile->query('ROLLBACK'); // TRANS: Server exception. throw new ServerException(_m('Cannot save local profile.')); } $profile->query('COMMIT'); } else { if ($object->type == ActivityObject::_LIST) { $ptag = new Profile_list(); $ptag->uri = $homeuri; $ptag->created = common_sql_now(); self::updatePeopletag($ptag, $object, $hints); $oprofile->peopletag_id = $ptag->insert(); if ($oprofile->peopletag_id === false) { // TRANS: Server exception. throw new ServerException(_m('Cannot save local list.')); } } } } $ok = $oprofile->insert(); if ($ok === false) { // TRANS: Server exception. throw new ServerException(_m('Cannot save OStatus profile.')); } $avatar = self::getActivityObjectAvatar($object, $hints); if ($avatar) { try { $oprofile->updateAvatar($avatar); } catch (Exception $ex) { // Profile is saved, but Avatar is messed up. We're // just going to continue. common_log(LOG_WARNING, "Exception saving OStatus profile avatar: " . $ex->getMessage()); } } return $oprofile; }
/** * Check whether the given URL represents one of our canonical * user or group Atom feeds. * * @param string $feed URL * @return boolean true if it matches, false if not a recognized local feed * @throws exception if local entity does not exist */ protected function recognizedFeed($feed) { $matches = array(); // Simple mapping to local ID for user or group if (preg_match('!/(\\d+)\\.atom$!', $feed, $matches)) { $id = $matches[1]; $params = array('id' => $id, 'format' => 'atom'); // Double-check against locally generated URLs switch ($feed) { case common_local_url('ApiTimelineUser', $params): $user = User::getKV('id', $id); if (!$user instanceof User) { // TRANS: Client exception. %s is a feed URL. throw new ClientException(sprintf(_m('Invalid hub.topic "%s". User does not exist.'), $feed)); } return true; case common_local_url('ApiTimelineGroup', $params): $group = Local_group::getKV('group_id', $id); if (!$group instanceof Local_group) { // TRANS: Client exception. %s is a feed URL. throw new ClientException(sprintf(_m('Invalid hub.topic "%s". Local_group does not exist.'), $feed)); } return true; } common_debug("Feed was not recognized by any local User or Group Atom feed URLs: {$feed}"); return false; } // Profile lists are unique per user, so we need both IDs if (preg_match('!/(\\d+)/lists/(\\d+)/statuses\\.atom$!', $feed, $matches)) { $user = $matches[1]; $id = $matches[2]; $params = array('user' => $user, 'id' => $id, 'format' => 'atom'); // Double-check against locally generated URLs switch ($feed) { case common_local_url('ApiTimelineList', $params): $list = Profile_list::getKV('id', $id); $user = User::getKV('id', $user); if (!$list instanceof Profile_list || !$user instanceof User || $list->tagger != $user->id) { // TRANS: Client exception. %s is a feed URL. throw new ClientException(sprintf(_m('Invalid hub.topic %s; list does not exist.'), $feed)); } return true; } common_debug("Feed was not recognized by any local Profile_list Atom feed URL: {$feed}"); return false; } common_debug("Unknown feed URL structure, can't match against local user, group or profile_list: {$feed}"); return false; }
function getTargetList($user = null, $id = null) { $tagger = $this->getTargetUser($user); $list = null; if (empty($id)) { $id = $this->arg('id'); } if ($id) { if (is_numeric($id)) { $list = Profile_list::getKV('id', $id); // only if the list with the id belongs to the tagger if (empty($list) || $list->tagger != $tagger->id) { $list = null; } } if (empty($list)) { $tag = common_canonical_tag($id); $list = Profile_list::getByTaggerAndTag($tagger->id, $tag); } if (!empty($list) && $list->private) { if ($this->scoped->id == $list->tagger) { return $list; } } else { return $list; } } return null; }
function getLists($auth_user, $offset = 0, $limit = null, $since_id = 0, $max_id = 0) { $ids = array(); $keypart = sprintf('profile:lists:%d', $this->id); $idstr = self::cacheGet($keypart); if ($idstr !== false) { $ids = explode(',', $idstr); } else { $list = new Profile_list(); $list->selectAdd(); $list->selectAdd('id'); $list->tagger = $this->id; $list->selectAdd('id as "cursor"'); if ($since_id > 0) { $list->whereAdd('id > ' . $since_id); } if ($max_id > 0) { $list->whereAdd('id <= ' . $max_id); } if ($offset >= 0 && !is_null($limit)) { $list->limit($offset, $limit); } $list->orderBy('id DESC'); if ($list->find()) { while ($list->fetch()) { $ids[] = $list->id; } } self::cacheSet($keypart, implode(',', $ids)); } $showPrivate = ($auth_user instanceof User || $auth_user instanceof Profile) && $auth_user->id === $this->id; $lists = array(); foreach ($ids as $id) { $list = Profile_list::getKV('id', $id); if (!empty($list) && ($showPrivate || !$list->private)) { if (!isset($list->cursor)) { $list->cursor = $list->id; } $lists[] = $list; } } return new ArrayWrapper($lists); }
/** * Check pre-requisites and instantiate attributes * * @param Array $args array of arguments (URL, GET, POST) * * @return boolean success flag */ function prepare($args) { parent::prepare($args); // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Client error displayed when the session token does not match or is not given. $this->clientError(_('There was a problem with your session token.' . ' Try again, please.')); } // Only for logged-in users $this->user = common_current_user(); if (empty($this->user)) { // TRANS: Error message displayed when trying to perform an action that requires a logged in user. $this->clientError(_('Not logged in.')); } // Profile to subscribe to $tagged_id = $this->arg('tagged'); $this->tagged = Profile::getKV('id', $tagged_id); if (empty($this->tagged)) { // TRANS: Client error displayed trying to perform an action related to a non-existing profile. $this->clientError(_('No such profile.')); } $id = $this->arg('peopletag_id'); $this->peopletag = Profile_list::getKV('id', $id); if (empty($this->peopletag)) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.')); } return true; }