3 * StatusNet - the distributed open-source microblogging tool
4 * Copyright (C) 2011, StatusNet, Inc.
6 * Stream of notices for a profile's "all" feed
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * @category NoticeStream
25 * @author Evan Prodromou <evan@status.net>
26 * @author Mikael Nordfeldth <mmn@hethane.se>
27 * @author Alexei Sorokin <sor.alexei@meowr.ru>
28 * @copyright 2011 StatusNet, Inc.
29 * @copyright 2014 Free Software Foundation, Inc.
30 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
31 * @link http://status.net/
34 if (!defined('GNUSOCIAL')) {
39 * Stream of notices for a profile's "all" feed
43 * @author Evan Prodromou <evan@status.net>
44 * @author Mikael Nordfeldth <mmn@hethane.se>
45 * @author Alexei Sorokin <sor.alexei@meowr.ru>
46 * @copyright 2011 StatusNet, Inc.
47 * @copyright 2014 Free Software Foundation, Inc.
48 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
49 * @link http://status.net/
51 class InboxNoticeStream extends ScopingNoticeStream
56 * @param Profile $target Profile to get a stream for
57 * @param Profile $scoped Currently scoped profile (if null, it is fetched)
59 public function __construct(Profile $target, Profile $scoped = null)
61 // FIXME: we don't use CachingNoticeStream - but maybe we should?
62 parent::__construct(new CachingNoticeStream(new RawInboxNoticeStream($target), 'profileall'), $scoped);
67 * Raw stream of notices for the target's inbox
71 * @author Evan Prodromou <evan@status.net>
72 * @author Mikael Nordfeldth <mmn@hethane.se>
73 * @author Alexei Sorokin <sor.alexei@meowr.ru>
74 * @copyright 2011 StatusNet, Inc.
75 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
76 * @link http://status.net/
78 class RawInboxNoticeStream extends FullNoticeStream
80 protected $target = null;
81 protected $inbox = null;
86 * @param Profile $target Profile to get a stream for
88 public function __construct(Profile $target)
90 parent::__construct();
91 $this->target = $target;
97 * @param int $offset Offset from start
98 * @param int $limit Limit of number to get
99 * @param int $since_id Since this notice
100 * @param int $max_id Before this notice
102 * @return array IDs found
104 public function getNoticeIds($offset, $limit, $since_id = null, $max_id = null)
108 // Grab all the profiles target is subscribed to (every user is subscribed to themselves)
109 $subscription = new Subscription();
110 $subscription->selectAdd();
111 $subscription->selectAdd('subscribed');
112 $subscription->whereAdd(sprintf('subscriber = %1$d', $this->target->id));
113 $subscription_profile_ids = $subscription->fetchAll('subscribed');
115 // Grab all the notices were target was mentioned
116 $reply = new Reply();
118 $reply->selectAdd('notice_id');
119 $reply->whereAdd(sprintf('profile_id = %1$d', $this->target->id));
120 $notice_ids += $reply->fetchAll('notice_id');
122 // Grab all the notices that require target's attention
123 $attention = new Attention();
124 $attention->selectAdd();
125 $attention->selectAdd('notice_id');
126 $attention->whereAdd(sprintf('profile_id = %1$d', $this->target->id));
127 $notice_ids += $attention->fetchAll('notice_id');
129 // Grab all the notices posted on groups target is a member of
130 $group_inbox = new Group_inbox();
131 $group_inbox->selectAdd();
132 $group_inbox->selectAdd('notice_id');
133 $group_inbox->whereAdd(
135 'group_id IN (SELECT group_id FROM group_member WHERE profile_id = %1$d)',
139 $notice_ids += $group_inbox->fetchAll('notice_id');
143 if (!empty($notice_ids)) { // Replies, Attentions and Groups
144 $query_ids .= 'notice.id IN (' . implode(', ', $notice_ids) . ') OR ';
146 // every user is at least subscribed to themselves
147 $query_ids .= 'notice.profile_id IN (' . implode(', ', $subscription_profile_ids) . ')';
149 $notice = new Notice();
150 $notice->selectAdd();
151 $notice->selectAdd('id');
152 $notice->whereAdd(sprintf('notice.created > "%s"', $notice->escape($this->target->created)));
153 $notice->whereAdd($query_ids);
155 if (!empty($since_id)) {
156 $notice->whereAdd(sprintf('notice.id > %d', $since_id));
158 if (!empty($max_id)) {
159 $notice->whereAdd(sprintf('notice.id <= %d', $max_id));
162 self::filterVerbs($notice, $this->selectVerbs);
164 $notice->limit($offset, $limit);
165 // notice.id will give us even really old posts, which were
166 // recently imported. For example if a remote instance had
167 // problems and just managed to post here. Another solution
168 // would be to have a 'notice.imported' field and order by it.
169 $notice->orderBy('notice.id DESC');
171 if (!$notice->find()) {
176 return $notice->fetchAll('id');