summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
Diffstat (limited to 'classes')
-rw-r--r--classes/Inbox.php39
-rw-r--r--classes/Profile.php97
-rw-r--r--classes/User.php12
3 files changed, 119 insertions, 29 deletions
diff --git a/classes/Inbox.php b/classes/Inbox.php
index 014ba3d82..2533210b7 100644
--- a/classes/Inbox.php
+++ b/classes/Inbox.php
@@ -96,12 +96,23 @@ class Inbox extends Memcached_DataObject
$inbox = new Inbox();
$inbox->user_id = $user_id;
- $inbox->notice_ids = call_user_func_array('pack', array_merge(array('N*'), $ids));
+ $inbox->pack($ids);
$inbox->fake = true;
return $inbox;
}
+ /**
+ * Append the given notice to the given user's inbox.
+ * Caching updates are managed for the inbox itself.
+ *
+ * If the notice is already in this inbox, the second
+ * add will be silently dropped.
+ *
+ * @param int @user_id
+ * @param int $notice_id
+ * @return boolean success
+ */
static function insertNotice($user_id, $notice_id)
{
$inbox = DB_DataObject::staticGet('inbox', 'user_id', $user_id);
@@ -114,6 +125,13 @@ class Inbox extends Memcached_DataObject
return false;
}
+ $ids = $inbox->unpack();
+ if (in_array(intval($notice_id), $ids)) {
+ // Already in there, we probably re-ran some inbox adds
+ // due to an error. Skip the dupe silently.
+ return true;
+ }
+
$result = $inbox->query(sprintf('UPDATE inbox '.
'set notice_ids = concat(cast(0x%08x as binary(4)), '.
'substr(notice_ids, 1, %d)) '.
@@ -150,7 +168,7 @@ class Inbox extends Memcached_DataObject
}
}
- $ids = unpack('N*', $inbox->notice_ids);
+ $ids = $inbox->unpack();
if (!empty($since_id)) {
$newids = array();
@@ -229,4 +247,21 @@ class Inbox extends Memcached_DataObject
}
return new ArrayWrapper($items);
}
+
+ /**
+ * Saves a list of integer notice_ids into a packed blob in this object.
+ * @param array $ids list of integer notice_ids
+ */
+ protected function pack(array $ids)
+ {
+ $this->notice_ids = call_user_func_array('pack', array_merge(array('N*'), $ids));
+ }
+
+ /**
+ * @return array of integer notice_ids
+ */
+ protected function unpack()
+ {
+ return unpack('N*', $this->notice_ids);
+ }
}
diff --git a/classes/Profile.php b/classes/Profile.php
index eded1ff71..54f557ea7 100644
--- a/classes/Profile.php
+++ b/classes/Profile.php
@@ -225,31 +225,62 @@ class Profile extends Memcached_DataObject
{
$notice = new Notice();
- $notice->profile_id = $this->id;
+ // Temporary hack until notice_profile_id_idx is updated
+ // to (profile_id, id) instead of (profile_id, created, id).
+ // It's been falling back to PRIMARY instead, which is really
+ // very inefficient for a profile that hasn't posted in a few
+ // months. Even though forcing the index will cause a filesort,
+ // it's usually going to be better.
+ if (common_config('db', 'type') == 'mysql') {
+ $index = '';
+ $query =
+ "select id from notice force index (notice_profile_id_idx) ".
+ "where profile_id=" . $notice->escape($this->id);
+
+ if ($since_id != 0) {
+ $query .= " and id > $since_id";
+ }
- $notice->selectAdd();
- $notice->selectAdd('id');
+ if ($max_id != 0) {
+ $query .= " and id < $max_id";
+ }
- if ($since_id != 0) {
- $notice->whereAdd('id > ' . $since_id);
- }
+ $query .= ' order by id DESC';
- if ($max_id != 0) {
- $notice->whereAdd('id <= ' . $max_id);
- }
+ if (!is_null($offset)) {
+ $query .= " LIMIT $limit OFFSET $offset";
+ }
+
+ $notice->query($query);
+ } else {
+ $index = '';
- $notice->orderBy('id DESC');
+ $notice->profile_id = $this->id;
- if (!is_null($offset)) {
- $notice->limit($offset, $limit);
+ $notice->selectAdd();
+ $notice->selectAdd('id');
+
+ if ($since_id != 0) {
+ $notice->whereAdd('id > ' . $since_id);
+ }
+
+ if ($max_id != 0) {
+ $notice->whereAdd('id <= ' . $max_id);
+ }
+
+ $notice->orderBy('id DESC');
+
+ if (!is_null($offset)) {
+ $notice->limit($offset, $limit);
+ }
+
+ $notice->find();
}
$ids = array();
- if ($notice->find()) {
- while ($notice->fetch()) {
- $ids[] = $notice->id;
- }
+ while ($notice->fetch()) {
+ $ids[] = $notice->id;
}
return $ids;
@@ -577,11 +608,41 @@ class Profile extends Memcached_DataObject
{
$sub = new Subscription();
$sub->subscriber = $this->id;
- $sub->delete();
+
+ $sub->find();
+
+ while ($sub->fetch()) {
+ $other = Profile::staticGet('id', $sub->subscribed);
+ if (empty($other)) {
+ continue;
+ }
+ if ($other->id == $this->id) {
+ continue;
+ }
+ Subscription::cancel($this, $other);
+ }
$subd = new Subscription();
$subd->subscribed = $this->id;
- $subd->delete();
+ $subd->find();
+
+ while ($subd->fetch()) {
+ $other = Profile::staticGet('id', $subd->subscriber);
+ if (empty($other)) {
+ continue;
+ }
+ if ($other->id == $this->id) {
+ continue;
+ }
+ Subscription::cancel($other, $this);
+ }
+
+ $self = new Subscription();
+
+ $self->subscriber = $this->id;
+ $self->subscribed = $this->id;
+
+ $self->delete();
}
function _deleteMessages()
diff --git a/classes/User.php b/classes/User.php
index f1ebe07b9..bec05f8cf 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -520,8 +520,8 @@ class User extends Memcached_DataObject
common_log(LOG_WARNING,
sprintf(
"Profile ID %d (%s) tried to block his or herself.",
- $profile->id,
- $profile->nickname
+ $this->id,
+ $this->nickname
)
);
return false;
@@ -543,13 +543,7 @@ class User extends Memcached_DataObject
return false;
}
- // Cancel their subscription, if it exists
-
- $otherUser = User::staticGet('id', $other->id);
-
- if (!empty($otherUser)) {
- subs_unsubscribe_to($otherUser, $this->getProfile());
- }
+ Subscription::cancel($other, $this->getProfile());
$block->query('COMMIT');