288 lines
9.1 KiB
PHP
288 lines
9.1 KiB
PHP
|
<?php namespace JasonWilliams\Feed\Classes;
|
||
|
|
||
|
use JasonWilliams\Feed\Models\Settings;
|
||
|
use JasonWilliams\Feed\Models\FeedItem;
|
||
|
use October\Rain\Network\Http;
|
||
|
|
||
|
class SocialApis
|
||
|
{
|
||
|
// Update the database with the latest tweets
|
||
|
public static function updateTwitter()
|
||
|
{
|
||
|
$tweets = self::fetchTwitter();
|
||
|
|
||
|
if (sizeof($tweets) > 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;
|
||
|
}
|