ja.son-williams.ca/www/plugins/jasonwilliams/feed/classes/SocialApis.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;
}