Exemplo n.º 1
0
 public function onEndUserRegister(Profile $profile)
 {
     foreach ($this->join as $nickname) {
         $group = User_group::getForNickname($nickname);
         if ($group && !$profile->isMember($group)) {
             try {
                 $profile->joinGroup($group);
             } catch (Exception $e) {
                 // TRANS: Server exception.
                 // TRANS: %1$s is a user nickname, %2$s is a group nickname.
                 throw new ServerException(sprintf(_m('Could not join user %1$s to group %2$s.'), $profile->nickname, $group->nickname));
             }
         }
     }
 }
Exemplo n.º 2
0
 function onEndUserRegister($profile, $user)
 {
     $profile = $user->getProfile();
     foreach ($this->join as $nickname) {
         $group = User_group::getForNickname($nickname);
         if ($group && !$profile->isMember($group)) {
             try {
                 if (Event::handle('StartJoinGroup', array($group, $user))) {
                     Group_member::join($group->id, $user->id);
                     Event::handle('EndJoinGroup', array($group, $user));
                 }
             } catch (Exception $e) {
                 // TRANS: Server exception.
                 // TRANS: %1$s is a user nickname, %2$s is a group nickname.
                 throw new ServerException(sprintf(_m('Could not join user %1$s to group %2$s.'), $user->nickname, $group->nickname));
             }
         }
     }
 }
Exemplo n.º 3
0
 function getTargetGroup($id)
 {
     if (empty($id)) {
         if (self::is_decimal($this->arg('id'))) {
             return User_group::staticGet('id', $this->arg('id'));
         } else {
             if ($this->arg('id')) {
                 return User_group::getForNickname($this->arg('id'));
             } else {
                 if ($this->arg('group_id')) {
                     // This is to ensure that a non-numeric group_id still
                     // overrides group_name even if it doesn't get used
                     if (self::is_decimal($this->arg('group_id'))) {
                         return User_group::staticGet('id', $this->arg('group_id'));
                     }
                 } else {
                     if ($this->arg('group_name')) {
                         return User_group::getForNickname($this->arg('group_name'));
                     }
                 }
             }
         }
     } else {
         if (self::is_decimal($id)) {
             return User_group::staticGet('id', $id);
         } else {
             return User_group::getForNickname($id);
         }
     }
 }
Exemplo n.º 4
0
function common_group_link($sender_id, $nickname)
{
    $sender = Profile::staticGet($sender_id);
    $group = User_group::getForNickname($nickname, $sender);
    if ($sender && $group && $sender->isMember($group)) {
        $attrs = array('href' => $group->permalink(), 'class' => 'url');
        if (!empty($group->fullname)) {
            $attrs['title'] = $group->fullname . ' (' . $group->nickname . ')';
        }
        $xs = new XMLStringer();
        $xs->elementStart('span', 'vcard');
        $xs->elementStart('a', $attrs);
        $xs->element('span', 'fn nickname', $nickname);
        $xs->elementEnd('a');
        $xs->elementEnd('span');
        return $xs->getString();
    } else {
        return $nickname;
    }
}
Exemplo n.º 5
0
 /**
  * Get a local or remote group by name.
  * @return User_group
  * @throws CommandException
  */
 function getGroup($arg)
 {
     $group = null;
     if (Event::handle('StartCommandGetGroup', array($this, $arg, &$group))) {
         $group = User_group::getForNickname($arg, $this->user->getProfile());
     }
     Event::handle('EndCommandGetGroup', array($this, $arg, &$group));
     if (!$group) {
         throw new CommandException(_('No such group.'));
     }
     return $group;
 }
Exemplo n.º 6
0
/**
 * 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;
}
Exemplo n.º 7
0
 /**
  * Get a local or remote group by name.
  * @return User_group
  * @throws CommandException
  */
 function getGroup($arg)
 {
     $group = null;
     if (Event::handle('StartCommandGetGroup', array($this, $arg, &$group))) {
         $group = User_group::getForNickname($arg, $this->user->getProfile());
     }
     Event::handle('EndCommandGetGroup', array($this, $arg, &$group));
     if (!$group) {
         // TRANS: Command exception text shown when a group is requested that does not exist.
         throw new CommandException(_('No such group.'));
     }
     return $group;
 }
Exemplo n.º 8
0
/**
 * 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;
}
Exemplo n.º 9
0
 function getTargetGroup($id)
 {
     if (empty($id)) {
         if (self::is_decimal($this->arg('id'))) {
             return User_group::getKV('id', $this->arg('id'));
         } else {
             if ($this->arg('id')) {
                 return User_group::getForNickname($this->arg('id'));
             } else {
                 if ($this->arg('group_id')) {
                     // This is to ensure that a non-numeric group_id still
                     // overrides group_name even if it doesn't get used
                     if (self::is_decimal($this->arg('group_id'))) {
                         return User_group::getKV('id', $this->arg('group_id'));
                     }
                 } else {
                     if ($this->arg('group_name')) {
                         return User_group::getForNickname($this->arg('group_name'));
                     }
                 }
             }
         }
     } else {
         if (self::is_decimal($id)) {
             return User_group::getKV('id', $id);
         } else {
             if ($this->arg('uri')) {
                 // FIXME: move this into empty($id) check?
                 return User_group::getKV('uri', urldecode($this->arg('uri')));
             } else {
                 return User_group::getForNickname($id);
             }
         }
     }
 }
Exemplo n.º 10
0
 /**
  * Parse !group delivery and record targets into group_inbox.
  * @return array of Group objects
  */
 function saveGroups()
 {
     // Don't save groups for repeats
     if (!empty($this->repeat_of)) {
         return array();
     }
     $groups = array();
     /* extract all !group */
     $count = preg_match_all('/(?:^|\\s)!([A-Za-z0-9]{1,64})/', strtolower($this->content), $match);
     if (!$count) {
         return $groups;
     }
     $profile = $this->getProfile();
     /* Add them to the database */
     foreach (array_unique($match[1]) as $nickname) {
         /* XXX: remote groups. */
         $group = User_group::getForNickname($nickname, $profile);
         if (empty($group)) {
             continue;
         }
         // we automatically add a tag for every group name, too
         $tag = Notice_tag::pkeyGet(array('tag' => common_canonical_tag($nickname), 'notice_id' => $this->id));
         if (is_null($tag)) {
             $this->saveTag($nickname);
         }
         if ($profile->isMember($group)) {
             $result = $this->addToGroupInbox($group);
             if (!$result) {
                 common_log_db_error($gi, 'INSERT', __FILE__);
             }
             $groups[] = clone $group;
         }
     }
     return $groups;
 }
Exemplo n.º 11
0
 static function groupsFromText($text, $profile)
 {
     $groups = array();
     /* extract all !group */
     $count = preg_match_all('/(?:^|\\s)!(' . Nickname::DISPLAY_FMT . ')/', strtolower($text), $match);
     if (!$count) {
         return $groups;
     }
     foreach (array_unique($match[1]) as $nickname) {
         $group = User_group::getForNickname($nickname, $profile);
         if (!empty($group) && $profile->isMember($group)) {
             $groups[] = $group->id;
         }
     }
     return $groups;
 }
 /**
  * When saving a notice, check its groups. If any of them has
  * privacy == always, force a group private message to all mentioned groups.
  * If any of the groups disallows private messages, skip it.
  *
  * @param 
  *
  */
 function onStartNoticeSave(&$notice)
 {
     // Look for group tags
     // FIXME: won't work for remote groups
     // @fixme if Notice::saveNew is refactored so we can just pull its list
     // of groups between processing and saving, make use of it
     $count = preg_match_all('/(?:^|\\s)!(' . Nickname::DISPLAY_FMT . ')/', strtolower($notice->content), $match);
     $groups = array();
     $ignored = array();
     $forcePrivate = false;
     if ($count > 0) {
         /* Add them to the database */
         foreach (array_unique($match[1]) as $nickname) {
             $group = User_group::getForNickname($nickname, $profile);
             if (empty($group)) {
                 continue;
             }
             $gps = Group_privacy_settings::forGroup($group);
             switch ($gps->allow_privacy) {
                 case Group_privacy_settings::ALWAYS:
                     $forcePrivate = true;
                     // fall through
                 // fall through
                 case Group_privacy_settings::SOMETIMES:
                     $groups[] = $group;
                     break;
                 case Group_privacy_settings::NEVER:
                     $ignored[] = $group;
                     break;
             }
         }
         if ($forcePrivate) {
             foreach ($ignored as $group) {
                 common_log(LOG_NOTICE, "Notice forced to group direct message " . "but group " . $group->nickname . " does not allow them.");
             }
             $user = User::staticGet('id', $notice->profile_id);
             if (empty($user)) {
                 common_log(LOG_WARNING, "Notice forced to group direct message " . "but profile " . $notice->profile_id . " is not a local user.");
             } else {
                 foreach ($groups as $group) {
                     Group_message::send($user, $group, $notice->content);
                 }
             }
             // Don't save the notice!
             // FIXME: this is probably cheating.
             throw new ClientException(sprintf(_('Forced notice to private group message.')), 200);
         }
     }
     return true;
 }