]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'limitdist' into limitdist2
authorEvan Prodromou <evan@status.net>
Fri, 25 Mar 2011 15:46:49 +0000 (11:46 -0400)
committerEvan Prodromou <evan@status.net>
Fri, 25 Mar 2011 15:46:49 +0000 (11:46 -0400)
1  2 
classes/Notice.php
classes/Profile.php

diff --combined classes/Notice.php
index 114119bfc9f7027f23d56b9877a58b94a4e48f7b,938f32406d01150c88eb8c26ca3361d1f6a55477..83507f3bc0f63c1ed916d3ed08760999f567c5a4
@@@ -45,7 -45,7 +45,7 @@@ require_once INSTALLDIR.'/classes/Memca
  /* We keep 200 notices, the max number of notices available per API request,
   * in the memcached cache. */
  
 -define('NOTICE_CACHE_WINDOW', NoticeStream::CACHE_WINDOW);
 +define('NOTICE_CACHE_WINDOW', CachingNoticeStream::CACHE_WINDOW);
  
  define('MAX_BOXCARS', 128);
  
@@@ -73,6 -73,7 +73,7 @@@ class Notice extends Memcached_DataObje
      public $location_ns;                     // int(4)
      public $repeat_of;                       // int(4)
      public $object_type;                     // varchar(255)
+     public $scope;                           // int(4)
  
      /* Static get */
      function staticGet($k,$v=NULL)
      const LOCAL_NONPUBLIC = -1;
      const GATEWAY         = -2;
  
+     const SITE_SCOPE      = 1;
+     const ADDRESSEE_SCOPE = 2;
+     const GROUP_SCOPE     = 4;
+     const FOLLOWER_SCOPE  = 8;
      function getProfile()
      {
          $profile = Profile::staticGet('id', $this->profile_id);
          if (empty($profile)) {
              return false;
          }
 -        $notice = $profile->getNotices(0, NoticeStream::CACHE_WINDOW);
 +        $notice = $profile->getNotices(0, CachingNoticeStream::CACHE_WINDOW);
          if (!empty($notice)) {
              $last = 0;
              while ($notice->fetch()) {
  
      function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0)
      {
 -        $stream = new NoticeStream(array('Notice', '_publicStreamDirect'),
 -                                   array(),
 -                                   'public');
 -
 +        $stream = new PublicNoticeStream();
          return $stream->getNotices($offset, $limit, $since_id, $max_id);
      }
  
 -    function _publicStreamDirect($offset=0, $limit=20, $since_id=0, $max_id=0)
 -    {
 -        $notice = new Notice();
 -
 -        $notice->selectAdd(); // clears it
 -        $notice->selectAdd('id');
 -
 -        $notice->orderBy('created DESC, id DESC');
 -
 -        if (!is_null($offset)) {
 -            $notice->limit($offset, $limit);
 -        }
 -
 -        if (common_config('public', 'localonly')) {
 -            $notice->whereAdd('is_local = ' . Notice::LOCAL_PUBLIC);
 -        } else {
 -            // -1 == blacklisted, -2 == gateway (i.e. Twitter)
 -            $notice->whereAdd('is_local !='. Notice::LOCAL_NONPUBLIC);
 -            $notice->whereAdd('is_local !='. Notice::GATEWAY);
 -        }
 -
 -        Notice::addWhereSinceId($notice, $since_id);
 -        Notice::addWhereMaxId($notice, $max_id);
 -
 -        $ids = array();
 -
 -        if ($notice->find()) {
 -            while ($notice->fetch()) {
 -                $ids[] = $notice->id;
 -            }
 -        }
 -
 -        $notice->free();
 -        $notice = NULL;
 -
 -        return $ids;
 -    }
  
      function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0)
      {
 -        $stream = new NoticeStream(array('Notice', '_conversationStreamDirect'),
 -                                   array($id),
 -                                   'notice:conversation_ids:'.$id);
 +        $stream = new ConversationNoticeStream($id);
  
          return $stream->getNotices($offset, $limit, $since_id, $max_id);
      }
 -
 -    function _conversationStreamDirect($id, $offset=0, $limit=20, $since_id=0, $max_id=0)
 -    {
 -        $notice = new Notice();
 -
 -        $notice->selectAdd(); // clears it
 -        $notice->selectAdd('id');
 -
 -        $notice->conversation = $id;
 -
 -        $notice->orderBy('created DESC, id DESC');
 -
 -        if (!is_null($offset)) {
 -            $notice->limit($offset, $limit);
 -        }
 -
 -        Notice::addWhereSinceId($notice, $since_id);
 -        Notice::addWhereMaxId($notice, $max_id);
 -
 -        $ids = array();
 -
 -        if ($notice->find()) {
 -            while ($notice->fetch()) {
 -                $ids[] = $notice->id;
 -            }
 -        }
 -
 -        $notice->free();
 -        $notice = NULL;
 -
 -        return $ids;
 -    }
  
      /**
       * Is this notice part of an active conversation?
                      ($this->is_local != Notice::GATEWAY));
          }
      }
+     /**
+      * Check that the given profile is allowed to read, respond to, or otherwise
+      * act on this notice.
+      * 
+      * The $scope member is a bitmask of scopes, representing a logical AND of the
+      * scope requirement. So, 0x03 (Notice::ADDRESSEE_SCOPE | Notice::SITE_SCOPE) means
+      * "only visible to people who are mentioned in the notice AND are users on this site."
+      * Users on the site who are not mentioned in the notice will not be able to see the
+      * notice.
+      *
+      * @param Profile $profile The profile to check
+      *
+      * @return boolean whether the profile is in the notice's scope
+      */
+     function inScope($profile)
+     {
+         // If there's any scope, and there's no logged-in user,
+         // not allowed.
+         if ($this->scope > 0 && empty($profile)) {
+             return false;
+         }
+         // Only for users on this site
+         if ($this->scope & Notice::SITE_SCOPE) {
+             $user = $profile->getUser();
+             if (empty($user)) {
+                 return false;
+             }
+         }
+         // Only for users mentioned in the notice
+         if ($this->scope & Notice::ADDRESSEE_SCOPE) {
+             // XXX: just query for the single reply
+             $replies = $this->getReplies();
+             if (!in_array($profile->id, $replies)) {
+                 return false;
+             }
+         }
+         // Only for members of the given group
+         if ($this->scope & Notice::GROUP_SCOPE) {
+             // XXX: just query for the single membership
+             $groups = $this->getGroups();
+             $foundOne = false;
+             foreach ($groups as $group) {
+                 if ($profile->isMember($group)) {
+                     $foundOne = true;
+                     break;
+                 }
+             }
+             if (!$foundOne) {
+                 return false;
+             }
+         }
+         // Only for followers of the author
+         if ($this->scope & Notice::FOLLOWER_SCOPE) {
+             $author = $this->getProfile();
+             if (!Subscription::exists($profile, $author)) {
+                 return false;
+             }
+         }
+         return true;
+     }
  }
diff --combined classes/Profile.php
index b582451350f94551e74b30a8df31ffa21dcfe941,a58a1f07c6136646e44afd680bb44612fb0cbe9d..b6b05f6a4fb89ff0d19f6910325b6a03c842d8ea
@@@ -198,18 -198,90 +198,18 @@@ class Profile extends Memcached_DataObj
  
      function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
      {
 -        $stream = new NoticeStream(array($this, '_streamTaggedDirect'),
 -                                   array($tag),
 -                                   'profile:notice_ids_tagged:'.$this->id.':'.$tag);
 +        $stream = new TaggedProfileNoticeStream($this, $tag);
  
          return $stream->getNotices($offset, $limit, $since_id, $max_id);
      }
  
      function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
      {
 -        $stream = new NoticeStream(array($this, '_streamDirect'),
 -                                   array(),
 -                                   'profile:notice_ids:' . $this->id);
 +        $stream = new ProfileNoticeStream($this);
  
          return $stream->getNotices($offset, $limit, $since_id, $max_id);
      }
  
 -    function _streamTaggedDirect($tag, $offset, $limit, $since_id, $max_id)
 -    {
 -        // XXX It would be nice to do this without a join
 -        // (necessary to do it efficiently on accounts with long history)
 -
 -        $notice = new Notice();
 -
 -        $query =
 -          "select id from notice join notice_tag on id=notice_id where tag='".
 -          $notice->escape($tag) .
 -          "' and profile_id=" . intval($this->id);
 -
 -        $since = Notice::whereSinceId($since_id, 'id', 'notice.created');
 -        if ($since) {
 -            $query .= " and ($since)";
 -        }
 -
 -        $max = Notice::whereMaxId($max_id, 'id', 'notice.created');
 -        if ($max) {
 -            $query .= " and ($max)";
 -        }
 -
 -        $query .= ' order by notice.created DESC, id DESC';
 -
 -        if (!is_null($offset)) {
 -            $query .= " LIMIT " . intval($limit) . " OFFSET " . intval($offset);
 -        }
 -
 -        $notice->query($query);
 -
 -        $ids = array();
 -
 -        while ($notice->fetch()) {
 -            $ids[] = $notice->id;
 -        }
 -
 -        return $ids;
 -    }
 -
 -    function _streamDirect($offset, $limit, $since_id, $max_id)
 -    {
 -        $notice = new Notice();
 -
 -        $notice->profile_id = $this->id;
 -
 -        $notice->selectAdd();
 -        $notice->selectAdd('id');
 -
 -        Notice::addWhereSinceId($notice, $since_id);
 -        Notice::addWhereMaxId($notice, $max_id);
 -
 -        $notice->orderBy('created DESC, id DESC');
 -
 -        if (!is_null($offset)) {
 -            $notice->limit($offset, $limit);
 -        }
 -
 -        $notice->find();
 -
 -        $ids = array();
 -
 -        while ($notice->fetch()) {
 -            $ids[] = $notice->id;
 -        }
 -
 -        return $ids;
 -    }
 -
      function isMember($group)
      {
          $mem = new Group_member();
                  Event::handle('EndJoinGroup', array($group, $this));
              }
          } else {
 -            throw new Exception(_m('Invalid group join approval: not pending.'));
 +            // TRANS: Exception thrown trying to approve a non-existing group join request.
 +            throw new Exception(_('Invalid group join approval: not pending.'));
          }
          if ($join) {
              $join->notify();
      /**
       * Leave a group that this profile is a member of.
       *
 -     * @param User_group $group 
 +     * @param User_group $group
       */
      function leaveGroup(User_group $group)
      {
              // This is the stream of favorite notices, in rev chron
              // order. This forces it into cache.
  
 -            $ids = Fave::idStream($this->id, 0, NoticeStream::CACHE_WINDOW);
 +            $ids = Fave::idStream($this->id, 0, CachingNoticeStream::CACHE_WINDOW);
  
              // If it's in the list, then it's a fave
  
              // then the cache has all available faves, so this one
              // is not a fave.
  
 -            if (count($ids) < NoticeStream::CACHE_WINDOW) {
 +            if (count($ids) < CachingNoticeStream::CACHE_WINDOW) {
                  return false;
              }
  
  
          return $profile;
      }
+     function canRead(Notice $notice)
+     {
+         if ($notice->scope & Notice::SITE_SCOPE) {
+             $user = $this->getUser();
+             if (empty($user)) {
+                 return false;
+             }
+         }
+         if ($notice->scope & Notice::ADDRESSEE_SCOPE) {
+             $replies = $notice->getReplies();
+             if (!in_array($this->id, $replies)) {
+                 $groups = $notice->getGroups();
+                 $foundOne = false;
+                 foreach ($groups as $group) {
+                     if ($this->isMember($group)) {
+                         $foundOne = true;
+                         break;
+                     }
+                 }
+                 if (!$foundOne) {
+                     return false;
+                 }
+             }
+         }
+         if ($notice->scope & Notice::FOLLOWER_SCOPE) {
+             $author = $notice->getProfile();
+             if (!Subscription::exists($this, $author)) {
+                 return false;
+             }
+         }
+         return true;
+     }
  }