return $def;
}
-
- function multiGet($kc, $kvs, $skipNulls=true)
- {
- return Memcached_DataObject::multiGet('Notice', $kc, $kvs, $skipNulls);
- }
/* Notice types */
const LOCAL_PUBLIC = 1;
return $result;
}
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
/**
* Extract #hashtags from this notice's content and save them to the database.
*/
* @return Notice
* @throws ClientException
*/
- static function saveNew($profile_id, $content, $source, $options=null) {
+ static function saveNew($profile_id, $content, $source, array $options=null) {
$defaults = array('uri' => null,
'url' => null,
'reply_to' => null,
$repeat = Notice::getKV('id', $repeat_of);
- if (empty($repeat)) {
+ if (!($repeat instanceof Notice)) {
// TRANS: Client exception thrown in notice when trying to repeat a missing or deleted notice.
throw new ClientException(_('Cannot repeat; original notice is missing or deleted.'));
}
throw new ClientException(_('Cannot repeat a notice you cannot read.'), 403);
}
- if ($profile->hasRepeated($repeat->id)) {
+ if ($profile->hasRepeated($repeat)) {
// TRANS: Client error displayed when trying to repeat an already repeated notice.
throw new ClientException(_('You already repeated that notice.'));
}
// If the original is private to a group, and notice has no group specified,
// make it to the same group(s)
- if (empty($groups) && ($reply->scope | Notice::GROUP_SCOPE)) {
+ if (empty($groups) && ($reply->scope & Notice::GROUP_SCOPE)) {
$groups = array();
$replyGroups = $reply->getGroups();
foreach ($replyGroups as $group) {
// For private streams
- $user = $profile->getUser();
+ try {
+ $user = $profile->getUser();
- if (!empty($user)) {
if ($user->private_stream &&
($notice->scope == Notice::PUBLIC_SCOPE ||
$notice->scope == Notice::SITE_SCOPE)) {
$notice->scope |= Notice::FOLLOWER_SCOPE;
}
+ } catch (NoSuchUserException $e) {
+ // Cannot handle private streams for remote profiles
}
// Force the scope for private groups
$ids[] = $f2p->file_id;
}
- $files = Memcached_DataObject::multiGet('File', 'id', $ids);
+ $files = File::multiGet('id', $ids);
$this->_attachments = $files->fetchAll();
if ($root !== false && $root->inScope($profile)) {
return $root;
- } else {
- $last = $this;
+ }
- do {
- $parent = $last->getOriginal();
- if (!empty($parent) && $parent->inScope($profile)) {
+ $last = $this;
+ while (true) {
+ try {
+ $parent = $last->getParent();
+ if ($parent->inScope($profile)) {
$last = $parent;
continue;
- } else {
- $root = $last;
- break;
}
- } while (!empty($parent));
-
- self::cacheSet($keypart, $root);
+ } catch (Exception $e) {
+ // Latest notice has no parent
+ }
+ // No parent, or parent out of scope
+ $root = $last;
+ break;
}
+ self::cacheSet($keypart, $root);
+
return $root;
}
* if left empty, will be loaded from reply records
* @return array associating recipient user IDs with an inbox source constant
*/
- function whoGets($groups=null, $recipients=null)
+ function whoGets(array $groups=null, array $recipients=null)
{
$c = self::memcache();
* @param array $recipient optional list of reply profile ids
* if left empty, will be loaded from reply records
*/
- function addToInboxes($groups=null, $recipients=null)
+ function addToInboxes(array $groups=null, array $recipients=null)
{
$ni = $this->whoGets($groups, $recipients);
*
* Mail notifications etc will be handled later.
*
- * @param array of unique identifier URIs for recipients
+ * @param array $uris Array of unique identifier URIs for recipients
*/
- function saveKnownReplies($uris)
+ function saveKnownReplies(array $uris)
{
if (empty($uris)) {
return;
$replied = array();
// If it's a reply, save for the replied-to author
-
- if (!empty($this->reply_to)) {
- $original = $this->getOriginal();
- if (!empty($original)) { // that'd be weird
- $author = $original->getProfile();
- if (!empty($author)) {
- $this->saveReply($author->id);
- $replied[$author->id] = 1;
- self::blow('reply:stream:%d', $author->id);
- }
+ try {
+ $author = $this->getParent()->getProfile();
+ if ($author instanceof Profile) {
+ $this->saveReply($author->id);
+ $replied[$author->id] = 1;
+ self::blow('reply:stream:%d', $author->id);
}
+ } catch (Exception $e) {
+ // Not a reply, since it has no parent!
}
// @todo ideally this parser information would only
// favorite and repeated
if (!empty($cur)) {
- $noticeInfoAttr['favorite'] = ($cur->hasFave($this)) ? "true" : "false";
$cp = $cur->getProfile();
- $noticeInfoAttr['repeated'] = ($cp->hasRepeated($this->id)) ? "true" : "false";
+ $noticeInfoAttr['favorite'] = ($cp->hasFave($this)) ? "true" : "false";
+ $noticeInfoAttr['repeated'] = ($cp->hasRepeated($this)) ? "true" : "false";
}
if (!empty($this->repeat_of)) {
// Only for users on this site
- if ($scope & Notice::SITE_SCOPE) {
- $user = $profile->getUser();
- if (empty($user)) {
- return false;
- }
+ if (($scope & Notice::SITE_SCOPE) && !$profile->isLocal()) {
+ return false;
}
// Only for users mentioned in the notice
return $groups;
}
- protected $_original = -1;
+ protected $_parent = -1;
- function getOriginal()
+ public function getParent()
{
- if (is_int($this->_original) && $this->_original == -1) {
- if (empty($this->reply_to)) {
- $this->_original = null;
- } else {
- $this->_original = Notice::getKV('id', $this->reply_to);
- }
+ if (empty($this->reply_to)) {
+ // Should this also be NoResultException? I don't think so.
+ throw new Exception('Notice has no parent');
+ } elseif ($this->_parent === -1) { // local object cache
+ $this->_parent = Notice::getKV('id', $this->reply_to);
+ }
+
+ if (!($this->_parent instanceof Notice)) {
+ throw new NoResultException($this->_parent);
}
- return $this->_original;
+ return $this->_parent;
}
/**
function __sleep()
{
$vars = parent::__sleep();
- $skip = array('_original', '_profile', '_groups', '_attachments', '_faves', '_replies', '_repeats');
+ $skip = array('_parent', '_profile', '_groups', '_attachments', '_faves', '_replies', '_repeats');
return array_diff($vars, $skip);
}
$ids = array_unique($ids);
- return Memcached_DataObject::pivotGet('Profile', 'id', $ids);
+ return Profile::pivotGet('id', $ids);
}
static function fillGroups(&$notices)
$gids = array_unique($gids);
- $group = Memcached_DataObject::pivotGet('User_group', 'id', $gids);
+ $group = User_group::pivotGet('id', $gids);
foreach ($notices as $notice)
{
$fileIds = array_unique($fileIds);
- $fileMap = Memcached_DataObject::pivotGet('File', 'id', $fileIds);
+ $fileMap = File::pivotGet('id', $fileIds);
foreach ($notices as $notice)
{