]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Group discovery from text functions polished
authorMikael Nordfeldth <mmn@hethane.se>
Tue, 29 Oct 2013 10:27:26 +0000 (11:27 +0100)
committerMikael Nordfeldth <mmn@hethane.se>
Tue, 29 Oct 2013 12:40:14 +0000 (13:40 +0100)
Also removed the entirely unused saveGroups function.

Now avoiding multiGet and using listFind in Profile->getGroups()
so we don't have to deal with ArrayWrapper.

12 files changed:
actions/usergroups.php
classes/Notice.php
classes/Profile.php
classes/User_group.php
lib/apiaction.php
lib/command.php
lib/groupsnav.php
lib/profileaction.php
lib/toselector.php
lib/util.php
plugins/OStatus/OStatusPlugin.php
scripts/createsim.php

index 9ffc8e0ab34eb6182fc6f0ce8cd04a11b2c29687..b705afe06886993cc40e5908257c5cbe99e25f68 100644 (file)
@@ -137,12 +137,11 @@ class UsergroupsAction extends ProfileAction
 
             $groups = $this->user->getGroups($offset, $limit);
 
-            if ($groups) {
+            if ($groups instanceof User_group) {
                 $gl = new GroupList($groups, $this->user, $this);
                 $cnt = $gl->show();
-                if (0 == $cnt) {
-                    $this->showEmptyListMessage();
-                }
+            } else {
+                $this->showEmptyListMessage();
             }
 
             $this->pagination($this->page > 1, $cnt > GROUPS_PER_PAGE,
index 4e5a83a85970ab4fae894d29100b761be97ca363..c5cde618ca126f44d8118fa0f5d1f8a35081e65a 100644 (file)
@@ -410,9 +410,8 @@ class Notice extends Managed_DataObject
         $notice->url = $url;
 
         // Get the groups here so we can figure out replies and such
-
         if (!isset($groups)) {
-            $groups = self::groupsFromText($notice->content, $profile);
+            $groups = User_group::idsFromText($notice->content, $profile);
         }
 
         $reply = null;
@@ -1154,7 +1153,7 @@ class Notice extends Managed_DataObject
         $groups = array();
         foreach (array_unique($group_ids) as $id) {
             $group = User_group::getKV('id', $id);
-            if ($group) {
+            if ($group instanceof User_group) {
                 common_log(LOG_ERR, "Local delivery to group id $id, $group->nickname");
                 $result = $this->addToGroupInbox($group);
                 if (!$result) {
@@ -1181,48 +1180,7 @@ class Notice extends Managed_DataObject
         return $groups;
     }
 
-    /**
-     * 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();
-        }
-
-        $profile = $this->getProfile();
-
-        $groups = self::groupsFromText($this->content, $profile);
-
-        /* Add them to the database */
-
-        foreach ($groups as $group) {
-            /* XXX: remote groups. */
-
-            if (empty($group)) {
-                continue;
-            }
-
-
-            if ($profile->isMember($group)) {
-
-                $result = $this->addToGroupInbox($group);
-
-                if (!$result) {
-                    common_log_db_error($gi, 'INSERT', __FILE__);
-                }
-
-                $groups[] = clone($group);
-            }
-        }
-
-        return $groups;
-    }
-
-    function addToGroupInbox($group)
+    function addToGroupInbox(User_group $group)
     {
         $gi = Group_inbox::pkeyGet(array('group_id' => $group->id,
                                          'notice_id' => $this->id));
@@ -1445,7 +1403,7 @@ class Notice extends Managed_DataObject
 
     /**
      * Pull list of groups this notice needs to be delivered to,
-     * as previously recorded by saveGroups() or saveKnownGroups().
+     * as previously recorded by saveKnownGroups().
      *
      * @return array of Group objects
      */
@@ -2500,29 +2458,6 @@ class Notice extends Managed_DataObject
         return false;
     }
 
-    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 ($group instanceof User_group && $profile->isMember($group)) {
-                $groups[] = $group->id;
-            }
-        }
-
-        return $groups;
-    }
-
     public function getParent()
     {
         $parent = Notice::getKV('id', $this->reply_to);
index 50cbeb3ac4fdc16b422aa1b8df93fff9910577c0..4e0632ba0ac998db4520050942dbcd418514d0b3 100644 (file)
@@ -221,9 +221,8 @@ class Profile extends Managed_DataObject
     function isMember($group)
     {
        $groups = $this->getGroups(0, null);
-       $gs = $groups->fetchAll();
-       foreach ($gs as $g) {
-           if ($group->id == $g->id) {
+        while ($groups instanceof User_group && $groups->fetch()) {
+           if ($groups->id == $group->id) {
                return true;
            }
        }
@@ -272,7 +271,18 @@ class Profile extends Managed_DataObject
             $ids = array_slice($ids, $offset, $limit);
         }
 
-        return User_group::multiGet('id', $ids);
+        try {
+            return User_group::listFind('id', $ids);
+        } catch (NoResultException $e) {
+            return null;    // throw exception when we handle it everywhere
+        }
+    }
+
+    function getGroupCount() {
+        $groups = $this->getGroups(0, null);
+        return $groups instanceof User_group
+                ? $groups->N
+                : 0;
     }
 
     function isTagged($peopletag)
index 6f3c7038a74d25b80c7cc8d8ca80631677cfb771..22b8d0bc04c7ab3004c93f9450ad8eaa9d00e3b2 100644 (file)
@@ -418,14 +418,14 @@ class User_group extends Managed_DataObject
         return true;
     }
 
-    static function getForNickname($nickname, $profile=null)
+    static function getForNickname($nickname, Profile $profile=null)
     {
         $nickname = Nickname::normalize($nickname);
 
         // Are there any matching remote groups this profile's in?
-        if ($profile) {
+        if ($profile instanceof Profile) {
             $group = $profile->getGroups(0, null);
-            while ($group->fetch()) {
+            while ($group instanceof User_group && $group->fetch()) {
                 if ($group->nickname == $nickname) {
                     // @fixme is this the best way?
                     return clone($group);
@@ -434,13 +434,12 @@ class User_group extends Managed_DataObject
         }
 
         // If not, check local groups.
-
         $group = Local_group::getKV('nickname', $nickname);
-        if (!empty($group)) {
+        if ($group instanceof Local_group) {
             return User_group::getKV('id', $group->group_id);
         }
         $alias = Group_alias::getKV('alias', $nickname);
-        if (!empty($alias)) {
+        if ($alias instanceof Group_alias) {
             return User_group::getKV('id', $alias->group_id);
         }
         return null;
@@ -822,4 +821,37 @@ class User_group extends Managed_DataObject
         return ($this->join_policy == self::JOIN_POLICY_MODERATE &&
                 $this->force_scope == 1);
     }
+
+    static function groupsFromText($text, Profile $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 = self::getForNickname($nickname, $profile);
+            if ($group instanceof User_group && $profile->isMember($group)) {
+                $groups[] = clone($group);
+            }
+        }
+
+        return $groups;
+    }
+
+    static function idsFromText($text, Profile $profile)
+    {
+        $ids = array();
+        $groups = self::groupsFromText($text, $profile);
+        foreach ($groups as $group) {
+            $ids[$group->id] = true;
+        }
+        return array_keys($ids);
+    }
 }
index 481dcf1b9529a23e7fb6ca04dc1e70eb10f0d8ed..d151f4c51fd7f461f639235d9db39d87d4d11211 100644 (file)
@@ -225,7 +225,7 @@ class ApiAction extends Action
         }
         $twitter_user['profile_image_url_original'] = $origurl;
 
-        $twitter_user['groups_count'] = $profile->getGroups(0, null)->N;
+        $twitter_user['groups_count'] = $profile->getGroupCount();
         foreach (array('linkcolor', 'backgroundcolor') as $key) {
             $twitter_user[$key] = Profile_prefs::getConfigData($profile, 'theme', $key);
         }
index 04c2e57ec8689b3372b3adf79ad39844e162c22d..d15fe43ce17f2356ce18027024112202dab0a3ad 100644 (file)
@@ -980,7 +980,7 @@ class GroupsCommand extends Command
     {
         $group = $this->user->getGroups();
         $groups=array();
-        while ($group->fetch()) {
+        while ($group instanceof User_group && $group->fetch()) {
             $groups[]=$group->nickname;
         }
         if(count($groups)==0){
index 8439ab63992616d466de2c3ff8fca8be59efd1bb..8e5d1a39fb60584f29b001103c74f5fb8ce0ca24 100644 (file)
@@ -58,7 +58,7 @@ class GroupsNav extends MoreMenu
 
     function haveGroups()
     {
-        return (!empty($this->groups) && ($this->groups->N > 0));
+        return ($this->groups instanceof User_group && $this->groups->N > 0);
     }
 
     function tag()
@@ -70,7 +70,7 @@ class GroupsNav extends MoreMenu
     {
         $items = array();
 
-        while ($this->groups->fetch()) {
+        while ($this->groups instanceof User_group && $this->groups->fetch()) {
             $items[] = array('placeholder',
                              array('nickname' => $this->groups->nickname,
                                    'mainpage' => $this->groups->homeUrl()),
index ea33af326adf2ed9a427da3f1c2e1cc0323fc262..b2990bd249625780d369578813f66857ee357a96 100644 (file)
@@ -270,13 +270,12 @@ class ProfileAction extends Action
             $this->text($this->profile->getGroups(0, null)->N);
             $this->elementEnd('h2');
 
-            if ($groups) {
+            if ($groups instanceof User_group) {
                 $gml = new GroupMiniList($groups, $this->profile, $this);
                 $cnt = $gml->show();
-                if ($cnt == 0) {
-                    // TRANS: Text for user user group membership statistics if user is not a member of any group.
-                    $this->element('p', null, _('(None)'));
-                }
+            } else {
+                // TRANS: Text for user user group membership statistics if user is not a member of any group.
+                $this->element('p', null, _('(None)'));
             }
 
             Event::handle('EndShowGroupsMiniList', array($this));
index b01948ed621fc90a4c709c4ba1a5e73cd3624402..6d424dc259ccc8433c2e5996cd392bc16fe51dbe 100644 (file)
@@ -94,7 +94,7 @@ class ToSelector extends Widget
 
         $groups = $this->user->getGroups();
 
-        while ($groups->fetch()) {
+        while ($groups instanceof User_group && $groups->fetch()) {
             $value = 'group:'.$groups->id;
             if (($this->to instanceof User_group) && $this->to->id == $groups->id) {
                 $default = $value;
index d12404572491c4c8c2b6cbe29af239acd117477a..bf3250e0c1901ee772fd912699793ad4236073d8 100644 (file)
@@ -320,7 +320,7 @@ function common_set_user($user)
     } else if (is_string($user)) {
         $nickname = $user;
         $user = User::getKV('nickname', $nickname);
-    } else if (!($user instanceof User)) {
+    } else if (!$user instanceof User) {
         return false;
     }
 
@@ -433,7 +433,7 @@ function common_remembered_user()
 
     $user = User::getKV('id', $rm->user_id);
 
-    if (!$user) {
+    if (!$user instanceof User) {
         common_log(LOG_WARNING, 'No such user for rememberme: ' . $rm->user_id);
         common_forgetme();
         return null;
@@ -488,8 +488,8 @@ function common_current_user()
             common_ensure_session();
             $id = isset($_SESSION['userid']) ? $_SESSION['userid'] : false;
             if ($id) {
-                $user = User::getKV($id);
-                if ($user) {
+                $user = User::getKV('id', $id);
+                if ($user instanceof User) {
                        $_cur = $user;
                        return $_cur;
                 }
@@ -584,13 +584,10 @@ function common_canonical_email($email)
  * @param Notice $notice in whose context we're working
  * @return string partially rendered HTML
  */
-function common_render_content($text, $notice)
+function common_render_content($text, Notice $notice)
 {
     $r = common_render_text($text);
-    $id = $notice->profile_id;
     $r = common_linkify_mentions($r, $notice);
-    $r = preg_replace_callback('/(^|[\s\.\,\:\;]+)!(' . Nickname::DISPLAY_FMT . ')/',
-                      function ($m) { return "{$m[1]}!".common_group_link($id, $m[2]); }, $r);
     return $r;
 }
 
@@ -677,35 +674,39 @@ function common_linkify_mention($mention)
  */
 function common_find_mentions($text, $notice)
 {
-    $mentions = array();
-
-    $sender = Profile::getKV('id', $notice->profile_id);
-
-    if (empty($sender)) {
-        return $mentions;
+    try {
+        $sender = Profile::getKV('id', $notice->profile_id);
+    } catch (NoProfileException $e) {
+        return array();
     }
 
+    $mentions = array();
+
     if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) {
         // Get the context of the original notice, if any
-        $originalAuthor   = null;
-        $originalNotice   = null;
-        $originalMentions = array();
+        $origAuthor   = null;
+        $origNotice   = null;
+        $origMentions = array();
 
         // Is it a reply?
 
-        if (!empty($notice) && !empty($notice->reply_to)) {
-            $originalNotice = Notice::getKV('id', $notice->reply_to);
-            if (!empty($originalNotice)) {
-                $originalAuthor = Profile::getKV('id', $originalNotice->profile_id);
+        if ($notice instanceof Notice) {
+            try {
+                $origNotice = $notice->getParent();
+                $origAuthor = $origNotice->getProfile();
 
-                $ids = $originalNotice->getReplies();
+                $ids = $origNotice->getReplies();
 
                 foreach ($ids as $id) {
                     $repliedTo = Profile::getKV('id', $id);
-                    if (!empty($repliedTo)) {
-                        $originalMentions[$repliedTo->nickname] = $repliedTo;
+                    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 (ServerException $e) {
+                common_log(LOG_WARNING, __METHOD__ . ' got exception: ' . $e->getMessage());
             }
         }
 
@@ -723,19 +724,19 @@ function common_find_mentions($text, $notice)
             // 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];
+            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 (!empty($mentioned)) {
+            if ($mentioned instanceof Profile) {
                 $user = User::getKV('id', $mentioned->id);
 
-                if ($user) {
+                if ($user instanceof User) {
                     $url = common_local_url('userbyid', array('id' => $user->id));
                 } else {
                     $url = $mentioned->profileurl;
@@ -757,26 +758,42 @@ function common_find_mentions($text, $notice)
         // @#tag => mention of all subscriptions tagged 'tag'
 
         preg_match_all('/(?:^|[\s\.\,\:\;]+)@#([\pL\pN_\-\.]{1,64})/',
-                       $text,
-                       $hmatches,
-                       PREG_OFFSET_CAPTURE);
-
+                       $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);
+            if (!$plist instanceof Profile_list || $plist->private) {
+                continue;
+            }
+            $tagged = $sender->getTaggedSubscribers($tag);
 
-                $url = common_local_url('showprofiletag',
-                                        array('tagger' => $sender->nickname,
-                                              'tag' => $tag));
+            $url = common_local_url('showprofiletag',
+                                    array('tagger' => $sender->nickname,
+                                          'tag' => $tag));
+
+            $mentions[] = array('mentioned' => $tagged,
+                                'text' => $hmatch[0],
+                                'position' => $hmatch[1],
+                                'url' => $url);
+        }
 
-                $mentions[] = array('mentioned' => $tagged,
-                                    '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' => $profile,
+                                'text'      => $hmatch[0],
+                                'position'  => $hmatch[1],
+                                'url'       => $group->permalink,
+                                'title'     => $group->getFancyName());
         }
 
         Event::handle('EndFindMentions', array($sender, $text, &$mentions));
@@ -1146,35 +1163,6 @@ function common_valid_profile_tag($str)
     return preg_match('/^[A-Za-z0-9_\-\.]{1,64}$/', $str);
 }
 
-/**
- *
- * @param <type> $sender_id
- * @param <type> $nickname
- * @return <type>
- * @access private
- */
-function common_group_link($sender_id, $nickname)
-{
-    $sender = Profile::getKV($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->getFancyName();
-        }
-        $xs = new XMLStringer();
-        $xs->elementStart('span', 'vcard');
-        $xs->elementStart('a', $attrs);
-        $xs->element('span', 'fn nickname group', $nickname);
-        $xs->elementEnd('a');
-        $xs->elementEnd('span');
-        return $xs->getString();
-    } else {
-        return $nickname;
-    }
-}
-
 /**
  * Resolve an ambiguous profile nickname reference, checking in following order:
  * - profiles that $sender subscribes to
@@ -1222,7 +1210,7 @@ function common_relative_profile($sender, $nickname, $dt=null)
         return $recipient;
     }
     // If this is a local user, try to find a local user with that nickname.
-    $sender = User::getKV($sender->id);
+    $sender = User::getKV('id', $sender->id);
     if ($sender instanceof User) {
         $recipient_user = User::getKV('nickname', $nickname);
         if ($recipient_user instanceof User) {
@@ -2020,8 +2008,8 @@ function common_profile_uri($profile)
 
     if (!empty($profile)) {
         if (Event::handle('StartCommonProfileURI', array($profile, &$uri))) {
-            $user = User::getKV($profile->id);
-            if (!empty($user)) {
+            $user = User::getKV('id', $profile->id);
+            if ($user instanceof User) {
                 $uri = $user->uri;
             }
             Event::handle('EndCommonProfileURI', array($profile, &$uri));
index 84f2a5e9cafc4457015d0ee35ad7d471b8f8ff36..29dde3119e4a5eb165714ce2ef4d82cf6d551d89 100644 (file)
@@ -337,7 +337,7 @@ class OStatusPlugin extends Plugin
      * @param array &$mention in/out param: set of found mentions
      * @return boolean hook return value
      */
-    function onEndFindMentions($sender, $text, &$mentions)
+    function onEndFindMentions(Profile $sender, $text, &$mentions)
     {
         $matches = array();
 
index e0ad74c49e6128ad3a12143775926cf07d9fcea5..7fc2ed1d90f1ce86762361aa5d06807f838a4ca6 100644 (file)
@@ -163,7 +163,7 @@ function newNotice($i, $tagmax)
 
     if ($in_group == 0) {
         $groups = $user->getGroups();
-        if ($groups->N > 0) {
+        if ($groups instanceof User_group) {
             $gval = rand(0, $groups->N - 1);
             $groups->fetch(); // go to 0th
             for ($i = 0; $i < $gval; $i++) {