]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge commit 'origin/0.8.x' into 0.9.x
authorEric Helgeson <erichelgeson@gmail.com>
Mon, 3 Aug 2009 23:11:06 +0000 (18:11 -0500)
committerEric Helgeson <erichelgeson@gmail.com>
Mon, 3 Aug 2009 23:11:06 +0000 (18:11 -0500)
1  2 
classes/Notice.php

diff --combined classes/Notice.php
index 4e9aff4f5750b869d0d193c02d2746d713de7149,ebd5e1efd5c9c1b00b7641ec43b3e59822ce6617..9578d87b2b149925e8fefffc17c43abd3b3c75b3
@@@ -75,21 -75,7 +75,21 @@@ class Notice extends Memcached_DataObje
          $this->blowFavesCache(true);
          $this->blowSubsCache(true);
  
 +        // For auditing purposes, save a record that the notice
 +        // was deleted.
 +
 +        $deleted = new Deleted_notice();
 +
 +        $deleted->id         = $this->id;
 +        $deleted->profile_id = $this->profile_id;
 +        $deleted->uri        = $this->uri;
 +        $deleted->created    = $this->created;
 +        $deleted->deleted    = common_sql_now();
 +
          $this->query('BEGIN');
 +
 +        $deleted->insert();
 +
          //Null any notices that are replies to this notice
          $this->query(sprintf("UPDATE notice set reply_to = null WHERE reply_to = %d", $this->id));
          $related = array('Reply',
          if (!$count) {
              return true;
          }
-         
          //turn each into their canonical tag
          //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag
          $hashtags = array();
          for($i=0; $i<count($match[1]); $i++) {
-              $hashtags[] = common_canonical_tag($match[1][$i]);
+             $hashtags[] = common_canonical_tag($match[1][$i]);
          }
  
-  
          /* Add them to the database */
          foreach(array_unique($hashtags) as $hashtag) {
              /* elide characters we don't want in the tag */
              $notice->is_local = $is_local;
          }
  
-               $notice->query('BEGIN');
-               $notice->reply_to = $reply_to;
          if (!empty($created)) {
              $notice->created = $created;
          } else {
              $notice->created = common_sql_now();
          }
                $notice->content = $final;
                $notice->rendered = common_render_content($final, $notice);
                $notice->source = $source;
                $notice->uri = $uri;
  
-         if (!empty($reply_to)) {
-             $reply_notice = Notice::staticGet('id', $reply_to);
-             if (!empty($reply_notice)) {
-                 $notice->reply_to = $reply_to;
-                 $notice->conversation = $reply_notice->conversation;
-             }
+               $notice->reply_to = self::getReplyTo($reply_to, $profile_id, $source, $final);
+         if (!empty($notice->reply_to)) {
+             $reply = Notice::staticGet('id', $notice->reply_to);
+             $notice->conversation = $reply->conversation;
          }
  
          if (Event::handle('StartNoticeSave', array(&$notice))) {
  
+             // XXX: some of these functions write to the DB
+             $notice->query('BEGIN');
              $id = $notice->insert();
  
              if (!$id) {
                  return _('Problem saving notice.');
              }
  
-             # Update the URI after the notice is in the database
-             if (!$uri) {
-                 $orig = clone($notice);
+             // Update ID-dependent columns: URI, conversation
+             $orig = clone($notice);
+             $changed = false;
+             if (empty($uri)) {
                  $notice->uri = common_notice_uri($notice);
+                 $changed = true;
+             }
+             // If it's not part of a conversation, it's
+             // the beginning of a new conversation.
  
+             if (empty($notice->conversation)) {
+                 $notice->conversation = $notice->id;
+                 $changed = true;
+             }
+             if ($changed) {
                  if (!$notice->update($orig)) {
                      common_log_db_error($notice, 'UPDATE', __FILE__);
                      return _('Problem saving notice.');
                  }
              }
  
-             # XXX: do we need to change this for remote users?
+             // XXX: do we need to change this for remote users?
  
              $notice->saveReplies();
              $notice->saveTags();
              $notice->addToInboxes();
  
              $notice->saveUrls();
+             // FIXME: why do we have to re-render the content?
+             // Remove this if it's not necessary.
              $orig2 = clone($notice);
-               $notice->rendered = common_render_content($final, $notice);
+             $notice->rendered = common_render_content($final, $notice);
              if (!$notice->update($orig2)) {
                  common_log_db_error($notice, 'UPDATE', __FILE__);
                  return _('Problem saving notice.');
          $notice->profile_id = $profile_id;
          $notice->content = $content;
          if (common_config('db','type') == 'pgsql')
-             $notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit'));
+           $notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit'));
          else
-             $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit'));
+           $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit'));
  
          $cnt = $notice->count();
          return ($cnt == 0);
      {
          $user = new User();
  
-       if(common_config('db','quote_identifiers'))
-           $user_table = '"user"';
-       else $user_table = 'user';
+         if(common_config('db','quote_identifiers'))
+           $user_table = '"user"';
+         else $user_table = 'user';
  
          $qry =
            'SELECT id ' .
-         'FROM '. $user_table .' JOIN subscription '.
-         'ON '. $user_table .'.id = subscription.subscriber ' .
+           'FROM '. $user_table .' JOIN subscription '.
+           'ON '. $user_table .'.id = subscription.subscriber ' .
            'WHERE subscription.subscribed = %d ';
  
          $user->query(sprintf($qry, $this->profile_id));
              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->conversation = $recipient_notice->conversation;
-                     $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)) {
              }
          }
  
-         // If it's not a reply, make it the root of a new conversation
-         if (empty($this->conversation)) {
-             $orig = clone($this);
-             $this->conversation = $this->id;
-             $this->update($orig);
-         }
          foreach (array_keys($replied) as $recipient) {
              $user = User::staticGet('id', $recipient);
              if ($user) {
  
          return $ids;
      }
+     /**
+      * Determine which notice, if any, a new notice is in reply to.
+      *
+      * For conversation tracking, we try to see where this notice fits
+      * in the tree. Rough algorithm is:
+      *
+      * if (reply_to is set and valid) {
+      *     return reply_to;
+      * } else if ((source not API or Web) and (content starts with "T NAME" or "@name ")) {
+      *     return ID of last notice by initial @name in content;
+      * }
+      *
+      * Note that all @nickname instances will still be used to save "reply" records,
+      * so the notice shows up in the mentioned users' "replies" tab.
+      *
+      * @param integer $reply_to   ID passed in by Web or API
+      * @param integer $profile_id ID of author
+      * @param string  $source     Source tag, like 'web' or 'gwibber'
+      * @param string  $content    Final notice content
+      *
+      * @return integer ID of replied-to notice, or null for not a reply.
+      */
+     static function getReplyTo($reply_to, $profile_id, $source, $content)
+     {
+         static $lb = array('xmpp', 'mail', 'sms', 'omb');
+         // If $reply_to is specified, we check that it exists, and then
+         // return it if it does
+         if (!empty($reply_to)) {
+             $reply_notice = Notice::staticGet('id', $reply_to);
+             if (!empty($reply_notice)) {
+                 return $reply_to;
+             }
+         }
+         // If it's not a "low bandwidth" source (one where you can't set
+         // a reply_to argument), we return. This is mostly web and API
+         // clients.
+         if (!in_array($source, $lb)) {
+             return null;
+         }
+         // Is there an initial @ or T?
+         if (preg_match('/^T ([A-Z0-9]{1,64}) /', $content, $match) ||
+             preg_match('/^@([a-z0-9]{1,64})\s+/', $content, $match)) {
+             $nickname = common_canonical_nickname($match[1]);
+         } else {
+             return null;
+         }
+         // Figure out who that is.
+         $sender = Profile::staticGet('id', $profile_id);
+         $recipient = common_relative_profile($sender, $nickname, common_sql_now());
+         if (empty($recipient)) {
+             return null;
+         }
+         // Get their last notice
+         $last = $recipient->getCurrentNotice();
+         if (!empty($last)) {
+             return $last->id;
+         }
+     }
  }