/** * Build the canonical profile URI+URL of the requested user or group */ function targetProfile() { if ($this->nickname) { $user = User::staticGet('nickname', $this->nickname); if ($user) { return common_local_url('userbyid', array('id' => $user->id)); } else { // TRANS: Client error. $this->clientError(_m('No such user.')); } } else { if ($this->group) { $group = Local_group::staticGet('nickname', $this->group); if ($group) { return common_local_url('groupbyid', array('id' => $group->group_id)); } else { // TRANS: Client error. $this->clientError(_m('No such group.')); } } else { if ($this->peopletag && $this->tagger) { $user = User::staticGet('nickname', $this->tagger); if (empty($user)) { // TRANS: Client error. $this->clientError(_m('No such user.')); } $peopletag = Profile_list::getByTaggerAndTag($user->id, $this->peopletag); if ($peopletag) { return common_local_url('profiletagbyid', array('tagger_id' => $user->id, 'id' => $peopletag->id)); } // TRANS: Client error. $this->clientError(_m('No such list.')); } else { // TRANS: Client error. $this->clientError(_m('No local user or group nickname provided.')); } } } }
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::staticGet('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->auth_user->id == $list->tagger) { return $list; } } else { return $list; } } return null; }
/** * Find @-mentions in the given text, using the given notice object as context. * References will be resolved with common_relative_profile() against the user * who posted the notice. * * Note the return data format is internal, to be used for building links and * such. Should not be used directly; rather, call common_linkify_mentions(). * * @param string $text * @param Notice $notice notice in whose context we're building links * * @return array * * @access private */ function common_find_mentions($text, $notice) { $mentions = array(); $sender = Profile::staticGet('id', $notice->profile_id); if (empty($sender)) { return $mentions; } if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) { // Get the context of the original notice, if any $originalAuthor = null; $originalNotice = null; $originalMentions = array(); // Is it a reply? if (!empty($notice) && !empty($notice->reply_to)) { $originalNotice = Notice::staticGet('id', $notice->reply_to); if (!empty($originalNotice)) { $originalAuthor = Profile::staticGet('id', $originalNotice->profile_id); $ids = $originalNotice->getReplies(); foreach ($ids as $id) { $repliedTo = Profile::staticGet('id', $id); if (!empty($repliedTo)) { $originalMentions[$repliedTo->nickname] = $repliedTo; } } } } $matches = common_find_mentions_raw($text); foreach ($matches as $match) { try { $nickname = Nickname::normalize($match[0]); } catch (NicknameException $e) { // Bogus match? Drop it. continue; } // Try to get a profile for this nickname. // Start with conversation context, then go to // sender context. if (!empty($originalAuthor) && $originalAuthor->nickname == $nickname) { $mentioned = $originalAuthor; } else { if (!empty($originalMentions) && array_key_exists($nickname, $originalMentions)) { $mentioned = $originalMentions[$nickname]; } else { $mentioned = common_relative_profile($sender, $nickname); } } if (!empty($mentioned)) { $user = User::staticGet('id', $mentioned->id); if ($user) { $url = common_local_url('userbyid', array('id' => $user->id)); } else { $url = $mentioned->profileurl; } $mention = array('mentioned' => array($mentioned), 'text' => $match[0], 'position' => $match[1], 'url' => $url); if (!empty($mentioned->fullname)) { $mention['title'] = $mentioned->fullname; } $mentions[] = $mention; } } // @#tag => mention of all subscriptions tagged 'tag' preg_match_all('/(?:^|[\\s\\.\\,\\:\\;]+)@#([\\pL\\pN_\\-\\.]{1,64})/', $text, $hmatches, PREG_OFFSET_CAPTURE); foreach ($hmatches[1] as $hmatch) { $tag = common_canonical_tag($hmatch[0]); $plist = Profile_list::getByTaggerAndTag($sender->id, $tag); if (!empty($plist) && !$plist->private) { $tagged = $sender->getTaggedSubscribers($tag); $url = common_local_url('showprofiletag', array('tagger' => $sender->nickname, 'tag' => $tag)); $mentions[] = array('mentioned' => $tagged, 'text' => $hmatch[0], 'position' => $hmatch[1], 'url' => $url); } } Event::handle('EndFindMentions', array($sender, $text, &$mentions)); } return $mentions; }
/** * Find @-mentions in the given text, using the given notice object as context. * References will be resolved with common_relative_profile() against the user * who posted the notice. * * Note the return data format is internal, to be used for building links and * such. Should not be used directly; rather, call common_linkify_mentions(). * * @param string $text * @param Profile $sender the Profile that is sending the current text * @param Notice $parent the Notice this text is in reply to, if any * * @return array * * @access private */ function common_find_mentions($text, Profile $sender, Notice $parent = null) { $mentions = array(); if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) { // Get the context of the original notice, if any $origMentions = array(); // Does it have a parent notice for context? if ($parent instanceof Notice) { $ids = $parent->getReplies(); // replied-to _profile ids_ foreach ($ids as $id) { try { $repliedTo = Profile::getByID($id); $origMentions[$repliedTo->getNickname()] = $repliedTo; } catch (NoResultException $e) { // continue foreach } } } $matches = common_find_mentions_raw($text); foreach ($matches as $match) { try { $nickname = Nickname::normalize($match[0]); } catch (NicknameException $e) { // Bogus match? Drop it. continue; } // Try to get a profile for this nickname. // Start with conversation context, then go to // sender context. if ($parent instanceof Notice && $parent->getProfile()->getNickname() === $nickname) { $mentioned = $parent->getProfile(); } else { if (!empty($origMentions) && array_key_exists($nickname, $origMentions)) { $mentioned = $origMentions[$nickname]; } else { // sets to null if no match $mentioned = common_relative_profile($sender, $nickname); } } if ($mentioned instanceof Profile) { $user = User::getKV('id', $mentioned->id); try { $url = $mentioned->getUrl(); } catch (InvalidUrlException $e) { $url = common_local_url('userbyid', array('id' => $mentioned->getID())); } $mention = array('mentioned' => array($mentioned), 'type' => 'mention', 'text' => $match[0], 'position' => $match[1], 'length' => mb_strlen($match[0]), 'title' => $mentioned->getFullname(), 'url' => $url); $mentions[] = $mention; } } // @#tag => mention of all subscriptions tagged 'tag' preg_match_all('/(?:^|[\\s\\.\\,\\:\\;]+)@#([\\pL\\pN_\\-\\.]{1,64})/', $text, $hmatches, PREG_OFFSET_CAPTURE); foreach ($hmatches[1] as $hmatch) { $tag = common_canonical_tag($hmatch[0]); $plist = Profile_list::getByTaggerAndTag($sender->getID(), $tag); if (!$plist instanceof Profile_list || $plist->private) { continue; } $tagged = $sender->getTaggedSubscribers($tag); $url = common_local_url('showprofiletag', array('nickname' => $sender->getNickname(), 'tag' => $tag)); $mentions[] = array('mentioned' => $tagged, 'type' => 'list', 'text' => $hmatch[0], 'position' => $hmatch[1], 'length' => mb_strlen($hmatch[0]), 'url' => $url); } preg_match_all('/(?:^|[\\s\\.\\,\\:\\;]+)!(' . Nickname::DISPLAY_FMT . ')/', $text, $hmatches, PREG_OFFSET_CAPTURE); foreach ($hmatches[1] as $hmatch) { $nickname = Nickname::normalize($hmatch[0]); $group = User_group::getForNickname($nickname, $sender); if (!$group instanceof User_group || !$sender->isMember($group)) { continue; } $profile = $group->getProfile(); $mentions[] = array('mentioned' => array($profile), 'type' => 'group', 'text' => $hmatch[0], 'position' => $hmatch[1], 'length' => mb_strlen($hmatch[0]), 'url' => $group->permalink(), 'title' => $group->getFancyName()); } Event::handle('EndFindMentions', array($sender, $text, &$mentions)); } return $mentions; }
/** * get Profile_list objects from the database * given their (tag, tagger) key pairs. * * @param array $keys array of array(tagger, tag) * * @return Profile_list results */ static function getByKeys(array $keys) { $cache = Cache::instance(); if (!empty($cache)) { $tags = array(); foreach ($keys as $key) { $t = Profile_list::getByTaggerAndTag($key[0], $key[1]); if (!empty($t)) { $tags[] = $t; } } return new ArrayWrapper($tags); } else { $tag = new Profile_list(); if (empty($keys)) { //if no IDs requested, just return the tag object return $tag; } $pairs = array(); foreach ($keys as $key) { $pairs[] = '(' . $key[0] . ', "' . $key[1] . '")'; } $tag->whereAdd('(tagger, tag) in (' . implode(', ', $pairs) . ')'); $tag->find(); $temp = array(); while ($tag->fetch()) { $temp[$tag->tagger . '-' . $tag->tag] = clone $tag; } $wrapped = array(); foreach ($keys as $key) { $id = $key[0] . '-' . $key[1]; if (array_key_exists($id, $temp)) { $wrapped[] = $temp[$id]; } } return new ArrayWrapper($wrapped); } }
/** * Find @-mentions in the given text, using the given notice object as context. * References will be resolved with common_relative_profile() against the user * who posted the notice. * * Note the return data format is internal, to be used for building links and * such. Should not be used directly; rather, call common_linkify_mentions(). * * @param string $text * @param Notice $notice notice in whose context we're building links * * @return array * * @access private */ function common_find_mentions($text, Notice $notice) { // The getProfile call throws NoProfileException on failure $sender = $notice->getProfile(); $mentions = array(); if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) { // Get the context of the original notice, if any $origAuthor = null; $origNotice = null; $origMentions = array(); // Is it a reply? if ($notice instanceof Notice) { try { $origNotice = $notice->getParent(); $origAuthor = $origNotice->getProfile(); $ids = $origNotice->getReplies(); foreach ($ids as $id) { $repliedTo = Profile::getKV('id', $id); if ($repliedTo instanceof Profile) { $origMentions[$repliedTo->nickname] = $repliedTo; } } } catch (NoProfileException $e) { common_log(LOG_WARNING, sprintf('Notice %d author profile id %d does not exist', $origNotice->id, $origNotice->profile_id)); } catch (NoParentNoticeException $e) { // This notice is not in reply to anything } catch (Exception $e) { common_log(LOG_WARNING, __METHOD__ . ' got exception ' . get_class($e) . ' : ' . $e->getMessage()); } } $matches = common_find_mentions_raw($text); foreach ($matches as $match) { try { $nickname = Nickname::normalize($match[0]); } catch (NicknameException $e) { // Bogus match? Drop it. continue; } // Try to get a profile for this nickname. // Start with conversation context, then go to // sender context. if ($origAuthor instanceof Profile && $origAuthor->nickname == $nickname) { $mentioned = $origAuthor; } else { if (!empty($origMentions) && array_key_exists($nickname, $origMentions)) { $mentioned = $origMentions[$nickname]; } else { $mentioned = common_relative_profile($sender, $nickname); } } if ($mentioned instanceof Profile) { $user = User::getKV('id', $mentioned->id); if ($user instanceof User) { $url = common_local_url('userbyid', array('id' => $user->id)); } else { $url = $mentioned->profileurl; } $mention = array('mentioned' => array($mentioned), 'type' => 'mention', 'text' => $match[0], 'position' => $match[1], 'url' => $url); if (!empty($mentioned->fullname)) { $mention['title'] = $mentioned->fullname; } $mentions[] = $mention; } } // @#tag => mention of all subscriptions tagged 'tag' preg_match_all('/(?:^|[\\s\\.\\,\\:\\;]+)@#([\\pL\\pN_\\-\\.]{1,64})/', $text, $hmatches, PREG_OFFSET_CAPTURE); foreach ($hmatches[1] as $hmatch) { $tag = common_canonical_tag($hmatch[0]); $plist = Profile_list::getByTaggerAndTag($sender->id, $tag); if (!$plist instanceof Profile_list || $plist->private) { continue; } $tagged = $sender->getTaggedSubscribers($tag); $url = common_local_url('showprofiletag', array('tagger' => $sender->nickname, 'tag' => $tag)); $mentions[] = array('mentioned' => $tagged, 'type' => 'list', 'text' => $hmatch[0], 'position' => $hmatch[1], 'url' => $url); } preg_match_all('/(?:^|[\\s\\.\\,\\:\\;]+)!(' . Nickname::DISPLAY_FMT . ')/', $text, $hmatches, PREG_OFFSET_CAPTURE); foreach ($hmatches[1] as $hmatch) { $nickname = Nickname::normalize($hmatch[0]); $group = User_group::getForNickname($nickname, $sender); if (!$group instanceof User_group || !$sender->isMember($group)) { continue; } $profile = $group->getProfile(); $mentions[] = array('mentioned' => array($profile), 'type' => 'group', 'text' => $hmatch[0], 'position' => $hmatch[1], 'url' => $group->permalink(), 'title' => $group->getFancyName()); } Event::handle('EndFindMentions', array($sender, $text, &$mentions)); } return $mentions; }