0) { foreach ($tweets as $tweet) { // Skip tweets created by IFTTT if they have an image attached (because they came from Instagram) if (!isset($tweet['retweet_status']) && strpos($tweet['source'], "IFTTT") && isset($tweet['entities']['media'])) continue; // Skip any tweets created by Foursquare if (!isset($tweet['retweet_status']) && strpos($tweet['source'], "Foursquare")) continue; $extradata = array(); // Get the timestamp before we go down a layer to retweets $timestamp = strtotime($tweet['created_at']); // Set extra data if this is a retweet if (isset($tweet['retweeted_status'])) { $tweet = $tweet['retweeted_status']; $extradata['opuser'] = $tweet['user']['screen_name']; $extradata['opname'] = $tweet['user']['name']; $extradata['opimg'] = $tweet['user']['profile_image_url_https']; } // Set extra data if there's an attached image if (isset($tweet['entities']['media'])) $extradata['img'] = $tweet['entities']['media'][0]['media_url_https']; // Convert any extra data into a JSON object $extradata = (sizeof($extradata) > 0) ? json_encode($extradata) : ""; // Create a new FeedItem $feeditem = new FeedItem; $feeditem->timestamp = $timestamp; $feeditem->channel_id = 2; $feeditem->title = $tweet['full_text']; $feeditem->link = "https://twitter.com/i/web/status/".$tweet['id_str']; $feeditem->extra = $extradata; $feeditem->save(); // Are there links to include? if (sizeof($tweet['entities']['urls']) > 0) { foreach ($tweet['entities']['urls'] as $url) { $feeditem->links()->create([ 'addr' => $url['url'], 'display' =>$url['display_url'] ]); } } // Are there tags to include? if (sizeof($tweet['entities']['hashtags'])) { foreach ($tweet['entities']['hashtags'] as $tag) { $feeditem->tags()->create([ 'tag' => $tag['text'] ]); } } } // Set the latest item ID Settings::set('twitter_latest_tweet', $tweets[sizeof($tweets) - 1]['id_str']); } } // Update the database with the latest instagram posts public static function updateInstagram() { $posts = self::fetchInstagram(); if (sizeof($posts) > 0) { foreach ($posts as $post) { // Skip videos and albums if ($post['media_type'] != "IMAGE") continue; // Create a new FeedItem $feeditem = new FeedItem; $feeditem->timestamp = strtotime($post['timestamp']); $feeditem->channel_id = 3; $feeditem->title = (isset($post['caption'])) ? $post['caption'] : ""; $feeditem->link = $post['permalink']; $feeditem->extra = json_encode(['img' => $post['media_url']]); $feeditem->save(); // Are there tags to include? if (isset($post['caption']) && strpos($post['caption'], '#')) { preg_match_all('%\B#\w*[a-zA-Z]+\w*%', $post['caption'], $hashtags); foreach ($hashtags[0] as $tag) { $feeditem->tags()->create([ 'tag' => substr($tag, 1) ]); } } } // Set the latest item ID Settings::set('instagram_latest_post', strtotime(end($posts)['timestamp'])); } } // Update the database with the latest foursquare posts public static function updateFoursquare() { $posts = self::fetchFoursquare(); if (sizeof($posts) > 0) { foreach ($posts as $post) { $extradata = [ 'lat' => $post['venue']['location']['lat'], 'lng' => $post['venue']['location']['lng'], 'address' => [] ]; // Build the address if (isset($post['venue']['location']['address'])) $extradata['address'][] = $post['venue']['location']['address']; if (isset($post['venue']['location']['city'])) $extradata['address'][] = $post['venue']['location']['city']; if (isset($post['venue']['location']['country'])) $extradata['address'][] = $post['venue']['location']['country']; $extradata['address'] = implode(', ', $extradata['address']); // Create a new FeedItem $feeditem = new FeedItem; $feeditem->timestamp = $post['createdAt']; $feeditem->channel_id = 6; $feeditem->title = $post['venue']['name']; $feeditem->body = (isset($post['shout'])) ? $post['shout'] : ""; $feeditem->extra = json_encode($extradata); $feeditem->save(); // Are there tags to include? if (isset($post['shout']) && strpos($post['shout'], '#')) { preg_match_all('%\B#\w*[a-zA-Z]+\w*%', $post['shout'], $hashtags); foreach ($hashtags[0] as $tag) { $feeditem->tags()->create([ 'tag' => substr($tag, 1) ]); } } } // Set the latest item ID Settings::set('foursquare_latest_post', end($posts)['createdAt']); } } // Fetch and return the latest tweets private static function fetchTwitter() { // Set the API endpoint $endpoint = "https://api.twitter.com/1.1/statuses/user_timeline.json"; // Set request parameteres $req_params = array( 'screen_name' => Settings::get('twitter_username'), 'count' => 200, 'since_id' => Settings::get('twitter_latest_tweet'), 'tweet_mode' => 'extended', 'exclude_replies' => true, 'include_rts' => true ); // Set oauth parameters self::$authobject = array( 'oauth_token' => Settings::get('twitter_access_token'), 'oauth_consumer_key' => Settings::get('twitter_consumer_key'), 'oauth_nonce' => time(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => time(), 'oauth_version' => '1.0' ); // Add parameters to oauth array self::$authobject = array_merge(self::$authobject, $req_params); // Generate the oauth signautre $base_string = self::buildBaseString($endpoint, "GET", self::$authobject); $composite_key = rawurlencode(Settings::get('twitter_consumer_secret'))."&".rawurlencode(Settings::get('twitter_access_token_secret')); self::$authobject['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $composite_key, true)); // Create the URL by adding the parameters to the endpoint $endpoint = $endpoint."?".http_build_query($req_params); $tweets = array_reverse(json_decode(Http::get($endpoint, function($http) { $http->header(self::buildAuthorizationHeader(self::$authobject)); }), true)); return $tweets; } // Fetch and return the latest instagram posts private static function fetchInstagram() { $endpoint = "https://graph.instagram.com/me/media"; // Set the fields we want back $fields = [ 'id', 'ig-id', 'caption', 'media_type', 'media_url', 'permalink', 'timestamp' ]; // Create the URL by adding the parameters to the endpoint $endpoint = $endpoint."?".http_build_query([ 'access_token' => Settings::get('instagram_access_token'), 'fields' => implode(',', $fields), 'limit' => 100 ]); $posts = json_decode(Http::get($endpoint), true); $posts = array_reverse($posts['data']); foreach($posts as $postkey => $post) { if (strtotime($post['timestamp']) <= Settings::get('instagram_latest_post')) unset($posts[$postkey]); } return $posts; } // Fetch and return the latest foursquare checkins private static function fetchFoursquare() { $endpoint = "https://api.foursquare.com/v2/users/self/checkins"; // Create the URL by adding the parameters to the endpoint $endpoint = $endpoint."?".http_build_query([ 'oauth_token' => Settings::get('foursquare_access_token'), 'v' => date('Ymd'), 'limit' => 250, 'sort' => 'oldestfirst', 'afterTimestamp' => Settings::get('foursquare_latest_post') + 1 ]); $posts = json_decode(Http::get($endpoint), true); return $posts['response']['checkins']['items']; } // Function to build a base string for the twitter API private static function buildBaseString($baseURI, $method, $params) { $r = array(); ksort($params); foreach ($params as $key => $value) { $r[] = $key.'='.rawurlencode($value); } return $method.'&'.rawurlencode($baseURI).'&'.rawurlencode(implode('&', $r)); } // Function to build the OAuth authorization header for twitter private static function buildAuthorizationHeader($oauth) { $r = 'Authorization: OAuth '; $values = array(); foreach($oauth as $key=>$value) $values[] = $key.'="'.rawurlencode($value).'"'; $r .= implode(', ', $values); return $r; } private static $authobject; }