/** * Resolve an ambiguous profile nickname reference, checking in following order: * - profiles that $sender subscribes to * - profiles that subscribe to $sender * - local user profiles * * WARNING: does not validate or normalize $nickname -- MUST BE PRE-VALIDATED * OR THERE MAY BE A RISK OF SQL INJECTION ATTACKS. THIS FUNCTION DOES NOT * ESCAPE SQL. * * @fixme validate input * @fixme escape SQL * @fixme fix or remove mystery third parameter * @fixme is $sender a User or Profile? * * @param <type> $sender the user or profile in whose context we're looking * @param string $nickname validated nickname of * @param <type> $dt unused mystery parameter; in Notice reply-to handling a timestamp is passed. * * @return Profile or null */ function common_relative_profile($sender, $nickname, $dt = null) { // Will throw exception on invalid input. $nickname = Nickname::normalize($nickname); // Try to find profiles this profile is subscribed to that have this nickname $recipient = new Profile(); // XXX: use a join instead of a subquery $recipient->whereAdd('EXISTS (SELECT subscribed from subscription where subscriber = ' . intval($sender->id) . ' and subscribed = id)', 'AND'); $recipient->whereAdd("nickname = '" . $recipient->escape($nickname) . "'", 'AND'); if ($recipient->find(true)) { // XXX: should probably differentiate between profiles with // the same name by date of most recent update return $recipient; } // Try to find profiles that listen to this profile and that have this nickname $recipient = new Profile(); // XXX: use a join instead of a subquery $recipient->whereAdd('EXISTS (SELECT subscriber from subscription where subscribed = ' . intval($sender->id) . ' and subscriber = id)', 'AND'); $recipient->whereAdd("nickname = '" . $recipient->escape($nickname) . "'", 'AND'); if ($recipient->find(true)) { // XXX: should probably differentiate between profiles with // the same name by date of most recent update return $recipient; } // If this is a local user, try to find a local user with that nickname. $sender = User::staticGet($sender->id); if ($sender) { $recipient_user = User::staticGet('nickname', $nickname); if ($recipient_user) { return $recipient_user->getProfile(); } } // Otherwise, no links. @messages from local users to remote users, // or from remote users to other remote users, are just // outside our ability to make intelligent guesses about return null; }
protected function prepare(array $args = array()) { // If we die, show short error messages. GNUsocial::setApi(true); parent::prepare($args); $this->groups = array(); $this->profiles = array(); $term = $this->arg('term'); $limit = $this->arg('limit'); if ($limit > 200) { $limit = 200; } //prevent DOS attacks if (substr($term, 0, 1) == '@') { //profile search $term = substr($term, 1); $profile = new Profile(); $profile->limit($limit); $profile->whereAdd('nickname like \'' . trim($profile->escape($term), '\'') . '%\''); $profile->whereAdd(sprintf('id in (SELECT id FROM user) OR ' . 'id in (SELECT subscribed from subscription' . ' where subscriber = %d)', $this->scoped->id)); if ($profile->find()) { while ($profile->fetch()) { $this->profiles[] = clone $profile; } } } if (substr($term, 0, 1) == '!') { //group search $term = substr($term, 1); $group = new User_group(); $group->limit($limit); $group->whereAdd('nickname like \'' . trim($group->escape($term), '\'') . '%\''); //Can't post to groups we're not subscribed to...: $group->whereAdd(sprintf('id in (SELECT group_id FROM group_member' . ' WHERE profile_id = %d)', $this->scoped->id)); if ($group->find()) { while ($group->fetch()) { $this->groups[] = clone $group; } } } return true; }
static function getTagged($tagger, $tag) { $profile = new Profile(); $profile->query('SELECT profile.* ' . 'FROM profile JOIN profile_tag ' . 'ON profile.id = profile_tag.tagged ' . 'WHERE profile_tag.tagger = ' . $profile->escape($tagger) . ' ' . 'AND profile_tag.tag = "' . $profile->escape($tag) . '" '); $tagged = array(); while ($profile->fetch()) { $tagged[] = clone $profile; } return true; }
function getTaggedSubscriptions($tag, $offset = 0, $limit = null) { $qry = 'SELECT profile.* ' . 'FROM profile JOIN subscription ' . 'ON profile.id = subscription.subscribed ' . 'JOIN profile_tag on (profile_tag.tagged = subscription.subscribed ' . 'AND profile_tag.tagger = subscription.subscriber) ' . 'WHERE subscription.subscriber = %d ' . "AND profile_tag.tag = '%s' " . 'AND subscription.subscribed != subscription.subscriber ' . 'ORDER BY subscription.created DESC '; $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; $profile = new Profile(); $profile->query(sprintf($qry, $this->id, $profile->escape($tag))); return $profile; }
function getTaggedSubscribers($tag) { $qry = 'SELECT profile.* ' . 'FROM profile JOIN (subscription, profile_tag, profile_list) ' . 'ON profile.id = subscription.subscriber ' . 'AND profile.id = profile_tag.tagged ' . 'AND profile_tag.tagger = profile_list.tagger AND profile_tag.tag = profile_list.tag ' . 'WHERE subscription.subscribed = %d ' . 'AND subscription.subscribed != subscription.subscriber ' . 'AND profile_tag.tagger = %d AND profile_tag.tag = "%s" ' . 'AND profile_list.private = false ' . 'ORDER BY subscription.created DESC'; $profile = new Profile(); $tagged = array(); $cnt = $profile->query(sprintf($qry, $this->id, $this->id, $profile->escape($tag))); while ($profile->fetch()) { $tagged[] = clone $profile; } return $tagged; }