diff -r c7c0fbc09788 -r 5e8dcbe22c24 web/wp-content/plugins/social/social-twitter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/wp-content/plugins/social/social-twitter.php Tue Dec 04 18:43:10 2012 -0800 @@ -0,0 +1,387 @@ + $comment) { + if (is_object($comment)) { + $_comments['id_'.$comment->comment_ID] = $comment; + if (in_array($comment->comment_type, Social_Service_Twitter::comment_types())) { + $comment_ids[] = $comment->comment_ID; + $tweet_comments['id_'.$comment->comment_ID] = $comment; + } + } + else { // social items + $_comments[$key] = $comment; + } + } + + // if no tweet comments, get out now + if (!count($tweet_comments)) { + return $comments; + } + + // use our keyed array + $comments = $_comments; + unset($_comments); + + $social_map = array(); // key = social id, value = comment_ID + $hash_map = array(); // key = hash, value = comment_ID + $broadcasted_social_ids = array(); + $broadcast_retweets = array(); // array of comments + + if (isset($broadcasted_ids['twitter'])) { + foreach ($broadcasted_ids['twitter'] as $account_id => $broadcasted) { + foreach ($broadcasted as $id => $data) { + $broadcasted_social_ids[] = $id; + // if we don't have a message saved for a tweet, try to get it so that we can use it next time + if (empty($data['message'])) { + $url = wp_nonce_url(home_url('index.php?social_controller=aggregation&social_action=retrieve_twitter_content&broadcasted_id='.$id.'&post_id='.$post_id), 'retrieve_twitter_content'); + wp_remote_get(str_replace('&', '&', $url), array( + 'timeout' => 0.01, + 'blocking' => false, + )); + } + else { + // create a hash from the broadcast so we can match retweets to it + $hash = self::build_hash($data['message']); + + // This is stored as broadcasted and not the ID so we can easily store broadcasted retweets + // instead of attaching retweets to non-existent comments. + $hash_map[$hash] = 'broadcasted'; + } + } + } + } + + // Load the comment meta + $results = $wpdb->get_results(" + SELECT meta_key, meta_value, comment_id + FROM $wpdb->commentmeta + WHERE comment_id IN (".implode(',', $comment_ids).") + AND ( + meta_key = 'social_in_reply_to_status_id' + OR meta_key = 'social_status_id' + OR meta_key = 'social_raw_data' + OR meta_key = 'social_profile_image_url' + OR meta_key = 'social_comment_type' + ) + "); + + // Set up social data for twitter comments + foreach ($tweet_comments as $key => &$comment) { + $comment->social_items = array(); + + // Attach meta + foreach ($results as $result) { + if ($comment->comment_ID == $result->comment_id) { + switch ($result->meta_key) { + case 'social_raw_data': + $comment->social_raw_data = json_decode(base64_decode($result->meta_value)); + break; + case 'social_status_id': + $social_map[$result->meta_value] = $result->comment_id; + default: + $comment->{$result->meta_key} = $result->meta_value; + } + } + } + + // Attach hash + if (isset($comment->social_raw_data) and isset($comment->social_raw_data->text)) { + $text = trim($comment->social_raw_data->text); + } + else { + $text = trim($comment->comment_content); + } + $comment->social_hash = self::build_hash($text); + + if (!isset($hash_map[$comment->social_hash])) { + $hash_map[$comment->social_hash] = $comment->comment_ID; + } + } + + // merge data so that $comments has the data we've set up + $comments = array_merge($comments, $tweet_comments); + + // set-up replies and retweets + foreach ($tweet_comments as $key => &$comment) { + if (is_object($comment)) { + // set reply/comment parent + if (!empty($comment->social_in_reply_to_status_id) and isset($social_map[$comment->social_in_reply_to_status_id])) { + $comments[$key]->comment_parent = $social_map[$comment->social_in_reply_to_status_id]; + } + + // set retweets + $rt_matched = false; + if (isset($comment->social_raw_data) and isset($comment->social_raw_data->retweeted_status)) { + // explicit match via API data + $rt_id = $comment->social_raw_data->retweeted_status->id_str; + if (in_array($rt_id, $broadcasted_social_ids)) { + $broadcast_retweets[] = $comment; + unset($comments[$key]); + $rt_matched = true; + } + else if (isset($social_map[$rt_id]) and isset($comments['id_'.$social_map[$rt_id]])) { + $comments['id_'.$social_map[$rt_id]]->social_items[$key] = $comment; + unset($comments[$key]); + $rt_matched = true; + } + } + + if (!$rt_matched) { + // best guess via hashes + $hash_match = $hash_map[$comment->social_hash]; + if ($hash_match != $comment->comment_ID) { // hash match to own tweet is expected, at minimum - set above + if ($hash_match == 'broadcasted') { + $broadcast_retweets[] = $comment; + } + else if (isset($comments['id_'.$hash_match])) { + $comments['id_'.$hash_match]->social_items[$key] = $comment; + } + else { + // Loop through the broadcasted retweets and see if this is a retweet of one of those. + foreach ($broadcast_retweets as $retweet) { + if ($retweet->comment_ID == $hash_match) { + $broadcast_retweets[] = $comment; + break; + } + } + } + unset($comments[$key]); + } + } + } + } + + if (!isset($comments['social_items'])) { + $comments['social_items'] = array(); + } + + if (count($broadcast_retweets)) { + $comments['social_items']['twitter'] = $broadcast_retweets; + } + + return $comments; + } + + + /** + * Sets the raw data for the broadcasted post. + * + * @wp-filter social_broadcast_response + * @static + * @param array $data + * @param Social_Service_Account $account + * @param string $service_key + * @param int $post_id + * @param Social_Response $response + * @return array + */ + public static function social_save_broadcasted_ids_data(array $data, Social_Service_Account $account, $service_key, $post_id, Social_Response $response = null) { + if ($service_key == 'twitter') { + if (!empty($response)) { + $data['message'] = base64_encode(json_encode($response->body()->response)); + } + $data['account'] = (object) array( + 'user' => $account->as_object()->user + ); + } + + return $data; + } + + /** + * Strips extra retweet data before comparing. + * + * @static + * @param string $text + * @return string + */ + private static function build_hash($text) { + $text = explode(' ', $text); + $content = ''; + foreach ($text as $_content) { + if (!empty($_content) and strpos($_content, 'http://') === false) { + if ($_content == 'RT' or preg_match('/@([\w_]+):/i', $_content)) { + continue; + } + + $content .= $_content.' '; + } + } + + return md5(trim($content)); + } + + /** + * Checks for a retweet via twitter API data and user perception. + * + * @static + * @param stdClass $comment + * @return bool + */ + public static function is_retweet($comment = null, $tweet = null) { + $is_retweet = false; + if (!is_null($comment)) { + if (isset($comment->social_raw_data) and !empty($comment->social_raw_data->retweeted_status)) { + $is_retweet = true; + } + if (substr($comment->comment_content, 0, 4) == 'RT @') { + $is_retweet = true; + } + } + else if (!is_null($tweet)) { + if (!empty($tweet->retweeted_status)) { + $is_retweet = true; + } + if (substr($tweet->text, 0, 4) == 'RT @') { + $is_retweet = true; + } + } + return $is_retweet; + } + + /** + * Adds a retweet to the original broadcasted post social items stack. + * + * @static + * @param int $comment_id + * @param array $comments + * @param array $social_items + */ + private static function add_to_social_items($comment_id, &$comments, &$social_items) { + $object = null; + $_comments = array(); + foreach ($comments as $id => $comment) { + if (is_int($id)) { + if ($comment->comment_ID == $comment_id) { + $object = $comment; + } + else { + $_comments[] = $comment; + } + } + else { + if (isset($_comments[$id])) { + $_comments[$id] = array_merge($_comments[$id], $comment); + } + else { + $_comments[$id] = $comment; + } + } + } + $comments = $_comments; + + if ($object !== null) { + if (!isset($social_items['twitter'])) { + $social_items['twitter'] = array(); + } + + $social_items['twitter'][$comment_id] = $object; + } + } + + /** + * Adds messaging to the title. + * + * @static + * @param string $title + * @param string $key + * @return string + */ + public static function social_item_output_title($title, $key) { + if ($key == 'twitter') { + $title .= __(' retweeted this', 'social'); + } + + return $title; + } + + /** + * Add a "reply to" field to broadcast form. + * + * @static + * @param obj $post + * @param obj $service + * @param obj $account + * @return void + */ + public static function social_broadcast_form_item_edit($post, $service, $account) { + if ($service->key() != 'twitter') { + return; + } + $field_name = str_replace('_content', '_in_reply_to', $account['field_name_content']); +?> + +
+ + +
+