X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=de7540705a6f90a533540ca032fc6abeb1d4ade7;hb=488bf16bc8c3fdfbde228b52c80a034e889fb876;hp=35e03e342d81c6b8c1aae0a948c6a77882f5d3fd;hpb=edbc0c665cc65875b4d14b79939233b1c9c06bb6;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 35e03e342d..de7540705a 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -48,23 +48,27 @@ class Notice extends Memcached_DataObject public $source; // varchar(32) /* Static get */ - function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Notice',$k,$v); } + function staticGet($k,$v=null) + { return Memcached_DataObject::staticGet('Notice',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - function getProfile() { + function getProfile() + { return Profile::staticGet('id', $this->profile_id); } - function delete() { + function delete() + { $this->blowCaches(true); $this->blowFavesCache(true); $this->blowInboxes(); return parent::delete(); } - function saveTags() { + function saveTags() + { /* extract all #hastags */ $count = preg_match_all('/(?:^|\s)#([A-Za-z0-9_\-\.]{1,64})/', strtolower($this->content), $match); if (!$count) { @@ -91,7 +95,7 @@ class Notice extends Memcached_DataObject return true; } - static function saveNew($profile_id, $content, $source=NULL, $is_local=1, $reply_to=NULL, $uri=NULL) { + static function saveNew($profile_id, $content, $source=null, $is_local=1, $reply_to=null, $uri=null) { $profile = Profile::staticGet($profile_id); @@ -152,8 +156,9 @@ class Notice extends Memcached_DataObject # XXX: do we need to change this for remote users? - common_save_replies($notice); + $notice->saveReplies(); $notice->saveTags(); + $notice->saveGroups(); # Clear the cache for subscribed users, so they'll update at next request # XXX: someone clever could prepend instead of clearing the cache @@ -184,15 +189,47 @@ class Notice extends Memcached_DataObject return true; } - function blowCaches($blowLast=false) { + function blowCaches($blowLast=false) + { $this->blowSubsCache($blowLast); $this->blowNoticeCache($blowLast); $this->blowRepliesCache($blowLast); $this->blowPublicCache($blowLast); $this->blowTagCache($blowLast); + $this->blowGroupCache($blowLast); } - function blowTagCache($blowLast=false) { + function blowGroupCache($blowLast=false) + { + $cache = common_memcache(); + if ($cache) { + $group_inbox = new Group_inbox(); + $group_inbox->notice_id = $this->id; + if ($group_inbox->find()) { + while ($group_inbox->fetch()) { + $cache->delete(common_cache_key('group:notices:'.$group_inbox->group_id)); + if ($blowLast) { + $cache->delete(common_cache_key('group:notices:'.$group_inbox->group_id.';last')); + } + $member = new Group_member(); + $member->group_id = $group_inbox->group_id; + if ($member->find()) { + while ($member->fetch()) { + $cache->delete(common_cache_key('user:notices_with_friends:' . $member->profile_id)); + if ($blowLast) { + $cache->delete(common_cache_key('user:notices_with_friends:' . $member->profile_id . ';last')); + } + } + } + } + } + $group_inbox->free(); + unset($group_inbox); + } + } + + function blowTagCache($blowLast=false) + { $cache = common_memcache(); if ($cache) { $tag = new Notice_tag(); @@ -210,7 +247,8 @@ class Notice extends Memcached_DataObject } } - function blowSubsCache($blowLast=false) { + function blowSubsCache($blowLast=false) + { $cache = common_memcache(); if ($cache) { $user = new User(); @@ -230,7 +268,8 @@ class Notice extends Memcached_DataObject } } - function blowNoticeCache($blowLast=false) { + function blowNoticeCache($blowLast=false) + { if ($this->is_local) { $cache = common_memcache(); if ($cache) { @@ -242,7 +281,8 @@ class Notice extends Memcached_DataObject } } - function blowRepliesCache($blowLast=false) { + function blowRepliesCache($blowLast=false) + { $cache = common_memcache(); if ($cache) { $reply = new Reply(); @@ -260,7 +300,8 @@ class Notice extends Memcached_DataObject } } - function blowPublicCache($blowLast=false) { + function blowPublicCache($blowLast=false) + { if ($this->is_local == 1) { $cache = common_memcache(); if ($cache) { @@ -272,7 +313,8 @@ class Notice extends Memcached_DataObject } } - function blowFavesCache($blowLast=false) { + function blowFavesCache($blowLast=false) + { $cache = common_memcache(); if ($cache) { $fave = new Fave(); @@ -293,7 +335,7 @@ class Notice extends Memcached_DataObject # XXX: too many args; we need to move to named params or even a separate # class for notice streams - static function getStream($qry, $cachekey, $offset=0, $limit=20, $since_id=0, $before_id=0, $order=NULL, $since=NULL) { + static function getStream($qry, $cachekey, $offset=0, $limit=20, $since_id=0, $before_id=0, $order=null, $since=null) { if (common_config('memcached', 'enabled')) { @@ -310,19 +352,19 @@ class Notice extends Memcached_DataObject static function getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since) { - $needAnd = FALSE; - $needWhere = TRUE; + $needAnd = false; + $needWhere = true; if (preg_match('/\bWHERE\b/i', $qry)) { - $needWhere = FALSE; - $needAnd = TRUE; + $needWhere = false; + $needAnd = true; } if ($since_id > 0) { if ($needWhere) { $qry .= ' WHERE '; - $needWhere = FALSE; + $needWhere = false; } else { $qry .= ' AND '; } @@ -334,7 +376,7 @@ class Notice extends Memcached_DataObject if ($needWhere) { $qry .= ' WHERE '; - $needWhere = FALSE; + $needWhere = false; } else { $qry .= ' AND '; } @@ -346,7 +388,7 @@ class Notice extends Memcached_DataObject if ($needWhere) { $qry .= ' WHERE '; - $needWhere = FALSE; + $needWhere = false; } else { $qry .= ' AND '; } @@ -383,7 +425,7 @@ class Notice extends Memcached_DataObject # If outside our cache window, just go to the DB if ($offset + $limit > NOTICE_CACHE_WINDOW) { - return Notice::getStreamDirect($qry, $offset, $limit, NULL, NULL, $order, NULL); + return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null); } # Get the cache; if we can't, just go to the DB @@ -391,7 +433,7 @@ class Notice extends Memcached_DataObject $cache = common_memcache(); if (!$cache) { - return Notice::getStreamDirect($qry, $offset, $limit, NULL, NULL, $order, NULL); + return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null); } # Get the notices out of the cache @@ -400,8 +442,8 @@ class Notice extends Memcached_DataObject # On a cache hit, return a DB-object-like wrapper - if ($notices !== FALSE) { - $wrapper = new NoticeWrapper(array_slice($notices, $offset, $limit)); + if ($notices !== false) { + $wrapper = new ArrayWrapper(array_slice($notices, $offset, $limit)); return $wrapper; } @@ -423,7 +465,7 @@ class Notice extends Memcached_DataObject # bet with our DB. $new_notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW, - $last_id, NULL, $order, NULL); + $last_id, null, $order, null); if ($new_notice) { $new_notices = array(); @@ -441,13 +483,13 @@ class Notice extends Memcached_DataObject # return a wrapper of the array for use now - return new NoticeWrapper(array_slice($notices, $offset, $limit)); + return new ArrayWrapper(array_slice($notices, $offset, $limit)); } } # Otherwise, get the full cache window out of the DB - $notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW, NULL, NULL, $order, NULL); + $notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW, null, null, $order, null); # If there are no hits, just return the value @@ -472,12 +514,13 @@ class Notice extends Memcached_DataObject # return a wrapper of the array for use now - $wrapper = new NoticeWrapper(array_slice($notices, $offset, $limit)); + $wrapper = new ArrayWrapper(array_slice($notices, $offset, $limit)); return $wrapper; } - function publicStream($offset=0, $limit=20, $since_id=0, $before_id=0, $since=NULL) { + function publicStream($offset=0, $limit=20, $since_id=0, $before_id=0, $since=null) + { $parts = array(); @@ -496,10 +539,11 @@ class Notice extends Memcached_DataObject return Notice::getStream($qry, 'public', - $offset, $limit, $since_id, $before_id, NULL, $since); + $offset, $limit, $since_id, $before_id, null, $since); } - function addToInboxes() { + function addToInboxes() + { $enabled = common_config('inboxes', 'enabled'); if ($enabled === true || $enabled === 'transitional') { @@ -522,7 +566,8 @@ class Notice extends Memcached_DataObject # Delete from inboxes if we're deleted. - function blowInboxes() { + function blowInboxes() + { $enabled = common_config('inboxes', 'enabled'); @@ -535,5 +580,147 @@ class Notice extends Memcached_DataObject return; } -} + function saveGroups() + { + $enabled = common_config('inboxes', 'enabled'); + if ($enabled !== true && $enabled !== 'transitional') { + return; + } + + /* extract all !group */ + $count = preg_match_all('/(?:^|\s)!([A-Za-z0-9]{1,64})/', + strtolower($this->content), + $match); + if (!$count) { + return true; + } + + $profile = $this->getProfile(); + + /* Add them to the database */ + + foreach (array_unique($match[1]) as $nickname) { + /* XXX: remote groups. */ + $group = User_group::staticGet('nickname', $nickname); + + if (!$group) { + continue; + } + + if ($profile->isMember($group)) { + + $gi = new Group_inbox(); + + $gi->group_id = $group->id; + $gi->notice_id = $this->id; + $gi->created = common_sql_now(); + + $result = $gi->insert(); + + if (!$result) { + common_log_db_error($gi, 'INSERT', __FILE__); + } + + // FIXME: do this in an offline daemon + + $inbox = new Notice_inbox(); + $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created, source) ' . + 'SELECT user.id, ' . $this->id . ', "' . $this->created . '", 2 ' . + 'FROM user JOIN group_member ON user.id = group_member.profile_id ' . + 'WHERE group_member.group_id = ' . $group->id . ' ' . + 'AND NOT EXISTS (SELECT user_id, notice_id ' . + 'FROM notice_inbox ' . + 'WHERE user_id = user.id ' . + 'AND notice_id = ' . $this->id . ' )'; + if ($enabled === 'transitional') { + $qry .= ' AND user.inboxed = 1'; + } + $result = $inbox->query($qry); + } + } + } + + function saveReplies() + { + // Alternative reply format + $tname = false; + if (preg_match('/^T ([A-Z0-9]{1,64}) /', $this->content, $match)) { + $tname = $match[1]; + } + // extract all @messages + $cnt = preg_match_all('/(?:^|\s)@([a-z0-9]{1,64})/', $this->content, $match); + + $names = array(); + + if ($cnt || $tname) { + // XXX: is there another way to make an array copy? + $names = ($tname) ? array_unique(array_merge(array(strtolower($tname)), $match[1])) : array_unique($match[1]); + } + + $sender = Profile::staticGet($this->profile_id); + + $replied = array(); + + // store replied only for first @ (what user/notice what the reply directed, + // we assume first @ is it) + + for ($i=0; $icreated); + if (!$recipient) { + continue; + } + if ($i == 0 && ($recipient->id != $sender->id) && !$this->reply_to) { // Don't save reply to self + $reply_for = $recipient; + $recipient_notice = $reply_for->getCurrentNotice(); + if ($recipient_notice) { + $orig = clone($this); + $this->reply_to = $recipient_notice->id; + $this->update($orig); + } + } + // Don't save replies from blocked profile to local user + $recipient_user = User::staticGet('id', $recipient->id); + if ($recipient_user && $recipient_user->hasBlocked($sender)) { + continue; + } + $reply = new Reply(); + $reply->notice_id = $this->id; + $reply->profile_id = $recipient->id; + $id = $reply->insert(); + if (!$id) { + $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); + common_log(LOG_ERR, 'DB error inserting reply: ' . $last_error->message); + common_server_error(sprintf(_('DB error inserting reply: %s'), $last_error->message)); + return; + } else { + $replied[$recipient->id] = 1; + } + } + // Hash format replies, too + $cnt = preg_match_all('/(?:^|\s)@#([a-z0-9]{1,64})/', $this->content, $match); + if ($cnt) { + foreach ($match[1] as $tag) { + $tagged = Profile_tag::getTagged($sender->id, $tag); + foreach ($tagged as $t) { + if (!$replied[$t->id]) { + // Don't save replies from blocked profile to local user + $t_user = User::staticGet('id', $t->id); + if ($t_user && $t_user->hasBlocked($sender)) { + continue; + } + $reply = new Reply(); + $reply->notice_id = $this->id; + $reply->profile_id = $t->id; + $id = $reply->insert(); + if (!$id) { + common_log_db_error($reply, 'INSERT', __FILE__); + return; + } + } + } + } + } + } +}