diff --git a/classes/Notice.php b/classes/Notice.php index 3eb6530669..16fbf0c17f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -158,6 +158,7 @@ class Notice extends Memcached_DataObject common_save_replies($notice); $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 @@ -195,6 +196,26 @@ class Notice extends Memcached_DataObject $this->blowRepliesCache($blowLast); $this->blowPublicCache($blowLast); $this->blowTagCache($blowLast); + $this->blowGroupCache($blowLast); + } + + 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')); + } + } + } + $group_inbox->free(); + unset($group_inbox); + } } function blowTagCache($blowLast=false) @@ -549,5 +570,59 @@ 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 ($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) ' . + 'SELECT user.id, ' . $this->id . ', "' . $this->created . '" ' . + 'FROM user JOIN user_group ON user.id = user_group.profile_id ' . + 'WHERE user_group.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'; + } + $inbox->query($qry); + } + } + } } diff --git a/lib/util.php b/lib/util.php index 4d4a3b20f2..03a99e54c1 100644 --- a/lib/util.php +++ b/lib/util.php @@ -424,6 +424,7 @@ function common_render_content($text, $notice) $r = preg_replace('/(^|\s+)@([A-Za-z0-9]{1,64})/e', "'\\1@'.common_at_link($id, '\\2')", $r); $r = preg_replace('/^T ([A-Z0-9]{1,64}) /e', "'T '.common_at_link($id, '\\1').' '", $r); $r = preg_replace('/(^|\s+)@#([A-Za-z0-9]{1,64})/e', "'\\1@#'.common_at_hash_link($id, '\\2')", $r); + $r = preg_replace('/(^|\s)!([A-Za-z0-9]{1,64})/e', "\\1'!'.common_group_link($id, '\\2')", $r); return $r; } @@ -595,6 +596,17 @@ function common_at_link($sender_id, $nickname) } } +function common_group_link($sender_id, $nickname) +{ + $sender = Profile::staticGet($sender_id); + $group = User_group::staticGet(common_canonical_nickname($nickname)); + if ($group && $sender->isMember($group)) { + return ''.$nickname.''; + } else { + return $nickname; + } +} + function common_at_hash_link($sender_id, $tag) { $user = User::staticGet($sender_id); @@ -1052,7 +1064,7 @@ function common_redirect($url, $code=307) $xo->startXML('a', '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); - $xo->output('a', array('href' => $url), $url); + $xo->element('a', array('href' => $url), $url); $xo->endXML(); exit; }