From 84984fdbfecdd79630801e2a6ca5b5e9e4b725a1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 25 Mar 2011 12:22:22 -0400 Subject: [PATCH] All notice streams check notice scope Added filtering code so that notice streams check notice scope. Added new class to implement filtering a stream, FilteringNoticeStream. Added a subclass that does the logic for checking Notice scope. And made all the streams use ScopingNoticeStream. --- lib/conversationnoticestream.php | 62 +++++++++++++++- lib/favenoticestream.php | 60 +++++++++++++++- lib/filenoticestream.php | 53 ++++++++++++-- lib/filteringnoticestream.php | 115 ++++++++++++++++++++++++++++++ lib/groupnoticestream.php | 62 ++++++++++++++-- lib/profilenoticestream.php | 6 +- lib/publicnoticestream.php | 61 +++++++++++++++- lib/repeatedbymenoticestream.php | 62 +++++++++++++++- lib/repeatsofmenoticestream.php | 61 +++++++++++++++- lib/replynoticestream.php | 62 +++++++++++++++- lib/scopingnoticestream.php | 78 ++++++++++++++++++++ lib/taggedprofilenoticestream.php | 64 +++++++++++++++-- lib/tagnoticestream.php | 62 +++++++++++++++- 13 files changed, 774 insertions(+), 34 deletions(-) create mode 100644 lib/filteringnoticestream.php create mode 100644 lib/scopingnoticestream.php diff --git a/lib/conversationnoticestream.php b/lib/conversationnoticestream.php index b26e898612..d7338d0245 100644 --- a/lib/conversationnoticestream.php +++ b/lib/conversationnoticestream.php @@ -1,14 +1,70 @@ . + * + * @category Cache + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class ConversationNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Notice stream for a conversation + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class ConversationNoticeStream extends ScopingNoticeStream { function __construct($id) { - parent::__construct(new RawConversationNoticeStream($id), - 'notice:conversation_ids:'.$id); + parent::__construct(new CachingNoticeStream(new RawConversationNoticeStream($id), + 'notice:conversation_ids:'.$id)); } } +/** + * Notice stream for a conversation + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawConversationNoticeStream extends NoticeStream { protected $id; diff --git a/lib/favenoticestream.php b/lib/favenoticestream.php index 5aaad5ce5b..987805cf9d 100644 --- a/lib/favenoticestream.php +++ b/lib/favenoticestream.php @@ -1,6 +1,51 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} -class FaveNoticeStream extends CachingNoticeStream +/** + * Notice stream for favorites + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class FaveNoticeStream extends ScopingNoticeStream { function __construct($user_id, $own) { @@ -10,10 +55,21 @@ class FaveNoticeStream extends CachingNoticeStream } else { $key = 'fave:ids_by_user:'.$user_id; } - parent::__construct($stream, $key); + parent::__construct(new CachingNoticeStream($stream, $key)); } } +/** + * Raw notice stream for favorites + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawFaveNoticeStream extends NoticeStream { protected $user_id; diff --git a/lib/filenoticestream.php b/lib/filenoticestream.php index fddc5d33ce..8c01893634 100644 --- a/lib/filenoticestream.php +++ b/lib/filenoticestream.php @@ -1,22 +1,67 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class FileNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +class FileNoticeStream extends ScopingNoticeStream { function __construct($file) { - parent::__construct(new RawFileNoticeStream($file), - 'file:notice-ids:'.$this->url); + parent::__construct(new CachingNoticeStream(new RawFileNoticeStream($file), + 'file:notice-ids:'.$this->url)); } } +/** + * Raw stream for a file + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawFileNoticeStream extends NoticeStream { protected $file = null; function __construct($file) { - $this->file = $file; parent::__construct(); + $this->file = $file; } /** diff --git a/lib/filteringnoticestream.php b/lib/filteringnoticestream.php new file mode 100644 index 0000000000..a3bdc08af6 --- /dev/null +++ b/lib/filteringnoticestream.php @@ -0,0 +1,115 @@ +. + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * A class for presenting a filtered notice stream based on an upstream stream + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +abstract class FilteringNoticeStream extends NoticeStream +{ + protected $upstream; + + function __construct($upstream) + { + $this->upstream = $upstream; + } + + abstract function filter($notice); + + function getNotices($offset, $limit, $sinceId, $maxId) + { + // "offset" is virtual; we have to get a lot + $total = $offset + $limit; + + $filtered = array(); + + $startAt = 0; + $askFor = $total; + + // Keep going till we have $total notices in $notices array, + // or we get nothing from upstream. + + $results = null; + + do { + + $raw = $this->upstream->getNotices($startAt, $askFor, $sinceId, $maxId); + + $results = $raw->N; + + if ($results == 0) { + break; + } + + while ($raw->fetch()) { + if ($this->filter($raw)) { + $filtered[] = clone($raw); + if (count($filtered >= $total)) { + break; + } + } + } + + // XXX: make these smarter; factor hit rate into $askFor + + $startAt += $askFor; + $askFor = max($total - count($filtered), NOTICES_PER_PAGE); + + } while (count($filtered) < $total && $results !== 0); + + return new ArrayWrapper(array_slice($filtered, $offset, $limit)); + } + + function getNoticeIds($offset, $limit, $sinceId, $maxId) + { + $notices = $this->getNotices($offset, $limit, $sinceId, $maxId); + + $ids = array(); + + while ($notices->fetch()) { + $ids[] = $notice->id; + } + + return $ids; + } +} diff --git a/lib/groupnoticestream.php b/lib/groupnoticestream.php index a6aa2c352c..22d94d0482 100644 --- a/lib/groupnoticestream.php +++ b/lib/groupnoticestream.php @@ -1,14 +1,68 @@ -. + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class GroupNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Stream of notices for a group + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ +class GroupNoticeStream extends ScopingNoticeStream { function __construct($group) { - parent::__construct(new RawGroupNoticeStream($group), - 'user_group:notice_ids:' . $group->id); + parent::__construct(new CachingNoticeStream(new RawGroupNoticeStream($group), + 'user_group:notice_ids:' . $group->id)); } } +/** + * Stream of notices for a group + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ class RawGroupNoticeStream extends NoticeStream { protected $group; diff --git a/lib/profilenoticestream.php b/lib/profilenoticestream.php index 9324bfb85d..ca54ad4892 100644 --- a/lib/profilenoticestream.php +++ b/lib/profilenoticestream.php @@ -45,12 +45,12 @@ if (!defined('STATUSNET')) { * @link http://status.net/ */ -class ProfileNoticeStream extends CachingNoticeStream +class ProfileNoticeStream extends ScopingNoticeStream { function __construct($profile) { - parent::__construct(new RawProfileNoticeStream($profile), - 'profile:notice_ids:' . $profile->id); + parent::__construct(new CachingNoticeStream(new RawProfileNoticeStream($profile), + 'profile:notice_ids:' . $profile->id)); } } diff --git a/lib/publicnoticestream.php b/lib/publicnoticestream.php index 0162375451..19d0ad96a0 100644 --- a/lib/publicnoticestream.php +++ b/lib/publicnoticestream.php @@ -1,13 +1,70 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class PublicNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Public stream + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class PublicNoticeStream extends ScopingNoticeStream { function __construct() { - parent::__construct(new RawPublicNoticeStream(), 'public'); + parent::__construct(new CachingNoticeStream(new RawPublicNoticeStream(), + 'public')); } } +/** + * Raw public stream + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawPublicNoticeStream extends NoticeStream { function getNoticeIds($offset=0, $limit=20, $since_id=0, $max_id=0) diff --git a/lib/repeatedbymenoticestream.php b/lib/repeatedbymenoticestream.php index 2c4c00ebf9..98c1583d6a 100644 --- a/lib/repeatedbymenoticestream.php +++ b/lib/repeatedbymenoticestream.php @@ -1,14 +1,70 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class RepeatedByMeNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Stream of notices repeated by me + * + * @category General + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class RepeatedByMeNoticeStream extends ScopingNoticeStream { function __construct($user) { - parent::__construct(new RawRepeatedByMeNoticeStream($user), - 'user:repeated_by_me:'.$user->id); + parent::__construct(new CachingNoticeStream(new RawRepeatedByMeNoticeStream($user), + 'user:repeated_by_me:'.$user->id)); } } +/** + * Raw stream of notices repeated by me + * + * @category General + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawRepeatedByMeNoticeStream extends NoticeStream { protected $user; diff --git a/lib/repeatsofmenoticestream.php b/lib/repeatsofmenoticestream.php index 1441908e5a..f51fc9e447 100644 --- a/lib/repeatsofmenoticestream.php +++ b/lib/repeatsofmenoticestream.php @@ -1,14 +1,69 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class RepeatsOfMeNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Stream of notices that are repeats of mine + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class RepeatsOfMeNoticeStream extends ScopingNoticeStream { function __construct($user) { - parent::__construct(new RawRepeatsOfMeNoticeStream($user), - 'user:repeats_of_me:'.$user->id); + parent::__construct(new CachingNoticeStream(new RawRepeatsOfMeNoticeStream($user), + 'user:repeats_of_me:'.$user->id)); } } +/** + * Raw stream of notices that are repeats of mine + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ class RawRepeatsOfMeNoticeStream extends NoticeStream { protected $user; diff --git a/lib/replynoticestream.php b/lib/replynoticestream.php index f358afcc54..d9214b7107 100644 --- a/lib/replynoticestream.php +++ b/lib/replynoticestream.php @@ -1,14 +1,70 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class ReplyNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Stream of mentions of me + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class ReplyNoticeStream extends ScopingNoticeStream { function __construct($userId) { - parent::__construct(new RawReplyNoticeStream($userId), - 'reply:stream:' . $userId); + parent::__construct(new CachingNoticeStream(new RawReplyNoticeStream($userId), + 'reply:stream:' . $userId)); } } +/** + * Raw stream of mentions of me + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawReplyNoticeStream extends NoticeStream { protected $userId; diff --git a/lib/scopingnoticestream.php b/lib/scopingnoticestream.php new file mode 100644 index 0000000000..a7ecbcd56b --- /dev/null +++ b/lib/scopingnoticestream.php @@ -0,0 +1,78 @@ +. + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Class comment + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class ScopingNoticeStream extends FilteringNoticeStream +{ + protected $profile; + + function __construct($upstream, $profile = null) + { + parent::__construct($upstream); + + if (empty($profile)) { + $user = common_current_user(); + if (!empty($user)) { + $profile = $user->getProfile(); + } + } + $this->profile = $profile; + } + + /** + * Only return notices where the profile is in scope + * + * @param Notice $notice The notice to check + * + * @return boolean whether to include the notice + */ + + function filter($notice) + { + return $notice->inScope($this->profile); + } + +} diff --git a/lib/taggedprofilenoticestream.php b/lib/taggedprofilenoticestream.php index d1711876eb..83c304ed8f 100644 --- a/lib/taggedprofilenoticestream.php +++ b/lib/taggedprofilenoticestream.php @@ -1,14 +1,70 @@ -. + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class TaggedProfileNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Stream of notices with a given profile and tag + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class TaggedProfileNoticeStream extends ScopingNoticeStream { function __construct($profile, $tag) { - parent::__construct(new RawTaggedProfileNoticeStream($profile, $tag), - 'profile:notice_ids_tagged:'.$profile->id.':'.Cache::keyize($tag)); + parent::__construct(new CachingNoticeStream(new RawTaggedProfileNoticeStream($profile, $tag), + 'profile:notice_ids_tagged:'.$profile->id.':'.Cache::keyize($tag))); } } +/** + * Raw stream of notices with a given profile and tag + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawTaggedProfileNoticeStream extends NoticeStream { protected $profile; diff --git a/lib/tagnoticestream.php b/lib/tagnoticestream.php index 0e287744dd..1dcf9f14bb 100644 --- a/lib/tagnoticestream.php +++ b/lib/tagnoticestream.php @@ -1,14 +1,70 @@ . + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ -class TagNoticeStream extends CachingNoticeStream +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Stream of notices with a given tag + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class TagNoticeStream extends ScopingNoticeStream { function __construct($tag) { - parent::__construct(new RawTagNoticeStream($tag), - 'notice_tag:notice_ids:' . Cache::keyize($tag)); + parent::__construct(new CachingNoticeStream(new RawTagNoticeStream($tag), + 'notice_tag:notice_ids:' . Cache::keyize($tag))); } } +/** + * Raw stream of notices with a given tag + * + * @category Stream + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class RawTagNoticeStream extends NoticeStream { protected $tag; -- 2.39.5