X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FTwitterBridge%2Ftwitterimport.php;h=1c362d6fe8fe96e85b1ff8f05dccc9c8101f9d1d;hb=f34a196e83257e41c79190b1be6cad264a9b7e3e;hp=9e53849d8477eb923c39fcf26a8541617ec4eaa1;hpb=e0e7cb7c5376a7adfdcf8e0724aedfae3de471ef;p=quix0rs-gnu-social.git diff --git a/plugins/TwitterBridge/twitterimport.php b/plugins/TwitterBridge/twitterimport.php index 9e53849d84..1c362d6fe8 100644 --- a/plugins/TwitterBridge/twitterimport.php +++ b/plugins/TwitterBridge/twitterimport.php @@ -56,7 +56,7 @@ class TwitterImport if (preg_match("/$source/", mb_strtolower($status->source))) { common_debug($this->name() . ' - Skipping import of status ' . - $status->id . ' with source ' . $source); + twitter_id($status) . ' with source ' . $source); return null; } @@ -86,23 +86,24 @@ class TwitterImport return null; } - $statusUri = $this->makeStatusURI($status->user->screen_name, $status->id); + $statusId = twitter_id($status); + $statusUri = $this->makeStatusURI($status->user->screen_name, $statusId); // check to see if we've already imported the status - $n2s = Notice_to_status::staticGet('status_id', $status->id); + $n2s = Notice_to_status::staticGet('status_id', $statusId); if (!empty($n2s)) { common_log( LOG_INFO, $this->name() . - " - Ignoring duplicate import: {$status->id}" + " - Ignoring duplicate import: {$statusId}" ); return Notice::staticGet('id', $n2s->notice_id); } // If it's a retweet, save it as a repeat! if (!empty($status->retweeted_status)) { - common_log(LOG_INFO, "Status {$status->id} is a retweet of {$status->retweeted_status->id}."); + common_log(LOG_INFO, "Status {$statusId} is a retweet of " . twitter_id($status->retweeted_status) . "."); $original = $this->saveStatus($status->retweeted_status); if (empty($original)) { return null; @@ -126,7 +127,7 @@ class TwitterImport 'uri' => $statusUri, 'is_local' => Notice::GATEWAY)); common_log(LOG_INFO, "Saved {$repeat->id} as a repeat of {$original->id}"); - Notice_to_status::saveNew($repeat->id, $status->id); + Notice_to_status::saveNew($repeat->id, $statusId); return $repeat; } } @@ -145,17 +146,18 @@ class TwitterImport $notice->reply_to = null; - if (!empty($status->in_reply_to_status_id)) { - common_log(LOG_INFO, "Status {$status->id} is a reply to status {$status->in_reply_to_status_id}"); - $n2s = Notice_to_status::staticGet('status_id', $status->in_reply_to_status_id); + $replyTo = twitter_id($status, 'in_reply_to_status_id'); + if (!empty($replyTo)) { + common_log(LOG_INFO, "Status {$statusId} is a reply to status {$replyTo}"); + $n2s = Notice_to_status::staticGet('status_id', $replyTo); if (empty($n2s)) { - common_log(LOG_INFO, "Couldn't find local notice for status {$status->in_reply_to_status_id}"); + common_log(LOG_INFO, "Couldn't find local notice for status {$replyTo}"); } else { $reply = Notice::staticGet('id', $n2s->notice_id); if (empty($reply)) { - common_log(LOG_INFO, "Couldn't find local notice for status {$status->in_reply_to_status_id}"); + common_log(LOG_INFO, "Couldn't find local notice for status {$replyTo}"); } else { - common_log(LOG_INFO, "Found local notice {$reply->id} for status {$status->in_reply_to_status_id}"); + common_log(LOG_INFO, "Found local notice {$reply->id} for status {$replyTo}"); $notice->reply_to = $reply->id; $notice->conversation = $reply->conversation; } @@ -165,7 +167,7 @@ class TwitterImport if (empty($notice->conversation)) { $conv = Conversation::create(); $notice->conversation = $conv->id; - common_log(LOG_INFO, "No known conversation for status {$status->id} so making a new one {$conv->id}."); + common_log(LOG_INFO, "No known conversation for status {$statusId} so making a new one {$conv->id}."); } $notice->is_local = Notice::GATEWAY; @@ -186,7 +188,7 @@ class TwitterImport Event::handle('EndNoticeSave', array($notice)); } - Notice_to_status::saveNew($notice->id, $status->id); + Notice_to_status::saveNew($notice->id, $statusId); $this->saveStatusMentions($notice, $status); $this->saveStatusAttachments($notice, $status); @@ -205,7 +207,7 @@ class TwitterImport */ function makeStatusURI($username, $id) { - return 'http://twitter.com/' + return 'http://twitter.com/#!/' . $username . '/status/' . $id; @@ -543,7 +545,8 @@ class TwitterImport $text = $status->text; if (empty($status->entities)) { - common_log(LOG_WARNING, "No entities data for {$status->id}; trying to fake up links ourselves."); + $statusId = twitter_id($status); + common_log(LOG_WARNING, "No entities data for {$statusId}; trying to fake up links ourselves."); $text = common_replace_urls_callback($text, 'common_linkify'); $text = preg_replace('/(^|\"\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/e', "'\\1#'.TwitterStatusFetcher::tagLink('\\2')", $text); $text = preg_replace('/(^|\s+)@([a-z0-9A-Z_]{1,64})/e', "'\\1@'.TwitterStatusFetcher::atLink('\\2')", $text); @@ -551,8 +554,8 @@ class TwitterImport } // Move all the entities into order so we can - // replace them in reverse order and thus - // not mess up their indices + // replace them and escape surrounding plaintext + // in order $toReplace = array(); @@ -574,56 +577,85 @@ class TwitterImport } } - // sort in reverse order by key + // sort in forward order by key - krsort($toReplace); + ksort($toReplace); + + $result = ''; + $cursor = 0; foreach ($toReplace as $part) { list($type, $object) = $part; + $start = $object->indices[0]; + $end = $object->indices[1]; + if ($cursor < $start) { + // Copy in the preceding plaintext + $result .= $this->twitEscape(mb_substr($text, $cursor, $start - $cursor)); + $cursor = $start; + } + $orig = $this->twitEscape(mb_substr($text, $start, $end - $start)); switch($type) { case self::URL: - $linkText = $this->makeUrlLink($object); + $linkText = $this->makeUrlLink($object, $orig); break; case self::HASHTAG: - $linkText = $this->makeHashtagLink($object); + $linkText = $this->makeHashtagLink($object, $orig); break; case self::MENTION: - $linkText = $this->makeMentionLink($object); + $linkText = $this->makeMentionLink($object, $orig); break; default: + $linkText = $orig; continue; } - $text = mb_substr($text, 0, $object->indices[0]) . $linkText . mb_substr($text, $object->indices[1]); + $result .= $linkText; + $cursor = $end; } - return $text; + $last = $this->twitEscape(mb_substr($text, $cursor)); + $result .= $last; + + return $result; } - function makeUrlLink($object) + function twitEscape($str) { - return "{$object->url}"; + // Twitter seems to preemptive turn < and > into < and > + // but doesn't for &, so while you may have some magic protection + // against XSS by not bothing to escape manually, you still get + // invalid XHTML. Thanks! + // + // Looks like their web interface pretty much sends anything + // through intact, so.... to do equivalent, decode all entities + // and then re-encode the special ones. + return htmlspecialchars(html_entity_decode($str, ENT_COMPAT, 'UTF-8')); } - function makeHashtagLink($object) + function makeUrlLink($object, $orig) { - return "#" . self::tagLink($object->text); + return "{$orig}"; } - function makeMentionLink($object) + function makeHashtagLink($object, $orig) { - return "@".self::atLink($object->screen_name, $object->name); + return "#" . self::tagLink($object->text, substr($orig, 1)); } - static function tagLink($tag) + function makeMentionLink($object, $orig) { - return "{$tag}"; + return "@".self::atLink($object->screen_name, $object->name, substr($orig, 1)); } - static function atLink($screenName, $fullName=null) + static function tagLink($tag, $orig) + { + return "{$orig}"; + } + + static function atLink($screenName, $fullName, $orig) { if (!empty($fullName)) { - return "{$screenName}"; + return "{$orig}"; } else { - return "{$screenName}"; + return "{$orig}"; } } @@ -643,6 +675,7 @@ class TwitterImport $reply = new Reply(); $reply->notice_id = $notice->id; $reply->profile_id = $user->id; + $reply->modified = $notice->created; common_log(LOG_INFO, __METHOD__ . ": saving reply: notice {$notice->id} to profile {$user->id}"); $id = $reply->insert(); } @@ -667,4 +700,4 @@ class TwitterImport } } } -} \ No newline at end of file +}