You are here

function tweet_feed_save_tweet in Tweet Feed 7.2

Same name and namespace in other branches
  1. 7.3 tweet_feed.module \tweet_feed_save_tweet()

Save The Tweet (and profile)

Save our tweet data and (optionally) profile if site is configured to do so.

2 calls to tweet_feed_save_tweet()
tweet_feed_cron in ./tweet_feed.module
Implements hook_cron().
tweet_feed_process_tweets in ./tweet_feed.module
Process each tweet
1 string reference to 'tweet_feed_save_tweet'
tweet_feed_run_import in ./tweet_feed_admin.inc
Run the Import

File

./tweet_feed.module, line 638

Code

function tweet_feed_save_tweet($tweet, $feed, $update_node_id = 0, $hash = NULL, $cron = FALSE) {

  // Get the creation time of the tweet and store it.
  $creation_timestamp = strtotime($tweet->created_at);

  // Process the tweet. This linkes our twitter names, hash tags and converts any
  // URL's into HTML.
  $tweet_html = tweet_feed_format_output($tweet->text, $feed->new_window);

  // Add our hash tags to the hashtag taxonomy. If it already exists, then get the tid
  // for that term. Returns an array of tid's for hashtags used.
  $hashtags = tweet_feed_process_hashtags($tweet->entities->hashtags);

  // If hashtags comes back as false, then we have a problem and need to quit.
  // Using our custom bail function since this could be a drush command or a web
  // interface call and we need to be able to handle accordingly.
  if ($hashtags === FALSE) {
    tweet_feed_bail();
  }

  // Populate our node object with the data we will need to save
  $node = new stdClass();
  $node->created = $creation_timestamp;

  // If we are being passed a node id for updating, then set it here so we update that
  // node. (might be an edge case)
  if ($update_node_id > 0) {
    $node->nid = $update_node_id;
    node_load($node->nid);
  }

  // Because we modify the tweet to get source images, we need to get the hash before
  // we do any of our processing
  $tweet_hash = md5(serialize($tweet->text));

  // If we are being provided a hash, we compare against this hash and if they are equal
  // then there is nothing to do
  if ($tweet_hash == $hash) {
    return NULL;
  }

  // Get started with our node data structure
  $node->type = 'twitter_tweet_feed';
  $node->uid = 1;
  $node->status = 1;
  $node->comment = 0;
  $node->promote = 0;
  $node->moderate = 0;
  $node->sticky = 0;
  $node->language = LANGUAGE_NONE;

  // The tweet author goes into the title field
  // Filter it cleanly since it is going into the title field. If we cannot use iconv,
  // then use something more primitive, but effective
  // @see https://www.drupal.org/node/1910376
  // @see http://webcollab.sourceforge.net/unicode.html
  // Reject overly long 2 byte sequences, as well as characters above U+10000
  // and replace with --.
  $title_tweet_text = preg_replace('/[\\x00-\\x08\\x10\\x0B\\x0C\\x0E-\\x19\\x7F]' . '|[\\x00-\\x7F][\\x80-\\xBF]+' . '|([\\xC0\\xC1]|[\\xF0-\\xFF])[\\x80-\\xBF]*' . '|[\\xC2-\\xDF]((?![\\x80-\\xBF])|[\\x80-\\xBF]{2,})' . '|[\\xE0-\\xEF](([\\x80-\\xBF](?![\\x80-\\xBF]))|(?![\\x80-\\xBF]{2})|[\\x80-\\xBF]{3,})/S', '--', $tweet->text);

  // Reject overly long 3 byte sequences and UTF-16 surrogates and replace
  // with --.
  $title_tweet_text = preg_replace('/\\xE0[\\x80-\\x9F][\\x80-\\xBF]' . '|\\xED[\\xA0-\\xBF][\\x80-\\xBF]/S', '--', $title_tweet_text);
  $node->title = substr($tweet->user->screen_name . ': ' . $title_tweet_text, 0, 255);

  // The tweet itself goes into the tweet contents field
  $node->field_tweet_contents[$node->language][0] = array(
    'value' => utf8_encode(htmlspecialchars_decode($tweet_html)),
    'format' => 'full_html',
  );

  // Save the feed ID for this tweet
  $node->field_tweet_feed_id[$node->language][0]['value'] = $feed->fid;

  // Geographic Information if it exist

  //$node->field_geographic_coordinates[$node->language][0] = array(

  //  'value' => $tweet->place->full_name . ', ' . $tweet->place->country,
  //  'safe_value' => $tweet->place->full_name . ', ' . $tweet->place->country,

  //);

  // If we have a place, then assign it based on which components we have available
  // to us.
  if (!empty($tweet->place->full_name)) {
    $node->field_geographic_place[$node->language][0] = array(
      'value' => $tweet->place->full_name,
      'safe_value' => $tweet->place->full_name,
    );
    if (!empty($tweet->place->country)) {
      $node->field_geographic_place[$node->language][0]['value'] .= ', ' . $tweet->place->country;
      $node->field_geographic_place[$node->language][0]['safe_value'] .= ', ' . $tweet->place->country;
    }
  }

  // Handle the author name
  $node->field_tweet_author[$node->language][0] = array(
    'value' => $tweet->user->screen_name,
    'safe_value' => $tweet->user->screen_name,
  );

  // Handle the author id
  $node->field_tweet_author_id[$node->language][0] = array(
    'value' => $tweet->user->id,
    'safe_value' => $tweet->user->id,
  );

  // Handle the tweet creation date
  $node->field_tweet_creation_date[$node->language][0] = array(
    'value' => date('Y-m-d H:i:s', strtotime($tweet->created_at)),
    'timezone' => 'UTC/GMT',
    'timezone_db' => 'UTC/GMT',
    'datatype' => 'datetime',
  );

  // Handle the tweet id
  $node->field_tweet_id[$node->language][0] = array(
    'value' => $tweet->id,
    'safe_value' => (int) $tweet->id,
  );

  // Handle the favorite count for this tweet
  $node->field_twitter_favorite_count['unc'][0]['value'] = $tweet->favorite_count;

  // Handle the hashtags
  foreach ($hashtags as $hashtag) {
    $node->field_twitter_hashtags[$node->language][] = array(
      'target_id' => $hashtag,
    );
  }

  // Handle the re-tweet count
  $node->field_twitter_retweet_count[$node->language][0]['value'] = $tweet->retweet_count;

  // Handle the tweet source
  $node->field_tweet_source[$node->language][0] = array(
    'value' => $tweet->source,
    'safe_value' => strip_tags($tweet->source),
  );

  // Create a direct link to this tweet
  $node->field_link_to_tweet[$node->language][0]['value'] = 'https://twitter.com/' . $tweet->user->screen_name . '/status/' . (int) $tweet->id;

  // Handle user mentions (our custom field defined by the module)
  if (!empty($tweet->entities->user_mentions) && is_array($tweet->entities->user_mentions)) {
    foreach ($tweet->entities->user_mentions as $key => $mention) {
      $node->field_tweet_user_mentions[$node->language][$key] = array(
        'tweet_feed_mention_name' => $mention->name,
        'tweet_feed_mention_screen_name' => $mention->screen_name,
        'tweet_feed_mention_id' => $mention->id,
      );
    }
  }

  // Not sure about this method of getting the big twitter profile image, but we're
  // going to roll with it for now.
  $tweet->user->profile_image_url = str_replace('_normal', '', $tweet->user->profile_image_url);

  // Handle the profile image obtained from twitter.com
  $file = tweet_feed_process_twitter_image($tweet->user->profile_image_url, 'tweet-feed-profile-image', $tweet->id);
  if ($file !== NULL) {
    $node->field_profile_image[$node->language][0] = (array) $file;
  }

  /// Allow other modules to alter the node about to be saved
  drupal_alter('tweet_feed_tweet_save', $node, $tweet);

  // Save the node
  node_save($node);
  $nid = $node->nid;

  // Make sure the hash in our tweet_hashes table is right by deleting what is there
  // for this node and updating
  db_delete('tweet_hashes')
    ->condition('nid', $node->nid)
    ->execute();
  $hash_insert = array(
    'tid' => $tweet->id,
    'nid' => $node->nid,
    'hash' => $tweet_hash,
  );
  drupal_write_record('tweet_hashes', $hash_insert);

  // If we're not running as part of our cron, then report the saved tweet */

  //if ($cron == FALSE) {

  //  tweet_feed_set_message('Tweet Saved: ' . $node->title, 'ok', $web_interface);

  //}

  // Unset the node variable so we can re-use it
  unset($node);

  // If we are creating a user profile for the person who made this tweet, then we need
  // to either create it or update it here. To determine create/update we need to check
  // the hash of the profile id and see if it matches our data.
  if (variable_get('tweet_feed_get_tweeter_profiles', FALSE) == TRUE) {

    // See if we have a profile for the author if this tweet. If we do not then we do not
    // need to do the rest of the checks
    $query = new EntityFieldQuery();
    $result = $query
      ->entityCondition('entity_type', 'node')
      ->entityCondition('bundle', 'twitter_user_profile')
      ->fieldCondition('field_twitter_user_id', 'value', $tweet->user->id, '=')
      ->execute();

    // If we have a result, then we have a profile! Then we need to check to see if the hash
    // of the profile is the same as the hash of the user data. If so, then update. If not,
    // then skip and on to the next
    if (isset($result['node'])) {
      $user_hash = md5(serialize($tweet->user));
      $result = db_select('tweet_user_hashes', 'h')
        ->fields('h', array(
        'nid',
        'tuid',
        'hash',
      ))
        ->condition('h.tuid', $tweet->user->id)
        ->execute();
      if ($result
        ->rowCount() > 0) {
        $tdata = $result
          ->fetchObject();

        // If our hashes are equal, we have nothing to update and can move along
        if ($user_hash == $tdata->hash) {
          return;
        }
        else {
          $update_node_id = $tdata->nid;
        }
      }
    }

    // Populate our node object with the data we will need to save
    $node = new stdClass();

    // If we are being passed a node id for updating, then set it here so we update that
    // node. (might be an edge case)
    if ($update_node_id > 0) {
      $node->nid = $update_node_id;
    }

    // Initialize the standard parts of our tweeting node.
    $node->type = 'twitter_user_profile';
    $node->uid = 1;
    $node->created = $creation_timestamp;
    $node->status = 1;
    $node->comment = 0;
    $node->promote = 0;
    $node->moderate = 0;
    $node->sticky = 0;
    $node->language = LANGUAGE_NONE;
    $node->field_twitter_user_id[$node->language][0]['value'] = $tweet->user->id_str;
    $node->title = $tweet->user->name;
    $node->body[$node->language][0]['value'] = $tweet->user->description;
    $node->field_twitter_a_screen_name[$node->language][0]['value'] = $tweet->user->screen_name;
    $node->field_twitter_location[$node->language][0]['value'] = $tweet->user->location;
    $node->field_twitter_a_profile_url[$node->language][0]['value'] = $tweet->user->entities->url->urls[0]->url;
    $node->field_twitter_profile_url[$node->language][0]['value'] = $tweet->user->entities->url->urls[0]->display_url;
    $node->field_twitter_followers[$node->language][0]['value'] = $tweet->user->followers_count;
    $node->field_twitter_following[$node->language][0]['value'] = $tweet->user->friends_count;
    $node->field_twitter_favorites_count[$node->language][0]['value'] = $tweet->user->favourites_count;
    $node->field_twitter_tweet_count[$node->language][0]['value'] = $tweet->user->statuses_count;

    // Handle the profile background image obtained from twitter.com
    $file = tweet_feed_process_twitter_image($tweet->user->profile_background_image_url, 'tweet-feed-profile-background-image', $tweet->user->id_str);
    if ($file !== NULL) {
      $node->field_background_image[$node->language][0] = (array) $file;
    }

    // Handle the user profile image obtained from twitter.com
    $file = tweet_feed_process_twitter_image($tweet->user->profile_image_url, 'tweet-feed-profile-user-profile-image', $tweet->user->id_str);
    if ($file !== NULL) {
      $node->field_profile_image[$node->language][0] = (array) $file;
    }

    // Handle the user profile banner image obtained from twitter.com
    $file = tweet_feed_process_twitter_image($tweet->user->profile_banner_url, 'tweet-feed-profile-banner-image', $tweet->user->id_str);
    if ($file !== NULL) {
      $node->field_banner_image[$node->language][0] = (array) $file;
    }
    $node->field_background_color[$node->language][0]['value'] = $tweet->user->profile_background_color;
    $node->field_profile_text_color[$node->language][0]['value'] = $tweet->user->profile_text_color;
    $node->field_link_color[$node->language][0]['value'] = $tweet->user->profile_link_color;
    $node->field_sidebar_border_color[$node->language][0]['value'] = $tweet->user->profile_sidebar_border_color;
    $node->field_sidebar_fill_color[$node->language][0]['value'] = $tweet->user->profile_sidebar_fill_color;
    node_save($node);

    // Make sure the hash in our tweet_hashes table is right by deleting what is there
    // for this node and updating
    db_delete('tweet_user_hashes')
      ->condition('nid', $node->nid)
      ->execute();
    $hash_insert = array(
      'tuid' => $tweet->user->id_str,
      'nid' => $node->nid,
      'hash' => $user_hash,
    );
    drupal_write_record('tweet_user_hashes', $hash_insert);

    //tweet_feed_set_message('Tweet Profile Saved: ' . $tweet->user->name . '(' . $tweet->user->screen_name . ')', 'ok', $web_interface);
  }
}