diff --git a/_build/build.transport.php b/_build/build.transport.php index e9b2d68..f922341 100644 --- a/_build/build.transport.php +++ b/_build/build.transport.php @@ -35,7 +35,7 @@ $modx->loadClass('transport.modPackageBuilder','',false, true); $builder = new modPackageBuilder($modx); -$builder->createPackage('facebook_feed','0.1.3','alpha'); +$builder->createPackage('facebook_feed','0.2.0','beta'); $builder->registerNamespace('facebook_feed',false,true,'{core_path}components/facebook_feed/'); /* load action/menu */ diff --git a/_build/data/transport.settings.php b/_build/data/transport.settings.php index 8b9799b..d6b9a26 100644 --- a/_build/data/transport.settings.php +++ b/_build/data/transport.settings.php @@ -24,22 +24,13 @@ 'area' => 'App_Key' ),'',true,true); -$settings['facebook_feed.page_id']= $modx->newObject('modSystemSetting'); -$settings['facebook_feed.page_id']->fromArray(array( - 'key' => 'facebook_feed.page_id', +$settings['facebook_feed.access_token']= $modx->newObject('modSystemSetting'); +$settings['facebook_feed.access_token']->fromArray(array( + 'key' => 'facebook_feed.access_token', 'value' => '', 'xtype' => 'textfield', 'namespace' => 'facebook_feed', - 'area' => 'Page' -),'',true,true); - -$settings['facebook_feed.page_token']= $modx->newObject('modSystemSetting'); -$settings['facebook_feed.page_token']->fromArray(array( - 'key' => 'facebook_feed.page_token', - 'value' => '', - 'xtype' => 'textfield', - 'namespace' => 'facebook_feed', - 'area' => 'Page' + 'area' => 'App_Key' ),'',true,true); return $settings; diff --git a/core/components/facebook_feed/chunks/facebook_feed_tpl.chunk.tpl b/core/components/facebook_feed/chunks/facebook_feed_tpl.chunk.tpl index 3aa5381..7e3be8f 100644 --- a/core/components/facebook_feed/chunks/facebook_feed_tpl.chunk.tpl +++ b/core/components/facebook_feed/chunks/facebook_feed_tpl.chunk.tpl @@ -2,4 +2,5 @@

by [[+name]] [[+time_ago]]

[[+message]]

+

Liked [[+likes]] times and shared [[+shares]] times. View on Facebook

diff --git a/core/components/facebook_feed/controllers/home.class.php b/core/components/facebook_feed/controllers/home.class.php index f69e6aa..14e14a7 100644 --- a/core/components/facebook_feed/controllers/home.class.php +++ b/core/components/facebook_feed/controllers/home.class.php @@ -6,8 +6,10 @@ class Facebook_feedHomeManagerController extends Facebook_feedManagerController * @param array $scriptProperties */ public function process(array $scriptProperties = array()) { - $data = $this->feed->getPages(); - return '

Login with Facebook

'.print_r($data, true); + $output = ''; + if($this->feed->generateAccessToken()) + $output .= '

Successfully updated Access Token.

'; + return $output; } /** * The pagetitle to put in the attribute. @@ -22,7 +24,7 @@ public function getPageTitle() { */ public function loadCustomCssJs() { /*$this->addCss('url/to/some/css_file.css'); - $this->addJavascript('url/to/some/javascript.js');*/ + $this->addJavascript('url/to/some/javascript.js'); $this->addJavascript($this->feed->config['jsUrl'].'feed.js'); $this->addHtml('<script type="text/javascript"> window.fbAsyncInit = function() { @@ -48,6 +50,6 @@ public function loadCustomCssJs() { fjs.parentNode.insertBefore(js, fjs); }(document, \'script\', \'facebook-jssdk\')); }); - </script>'); + </script>');*/ } } diff --git a/core/components/facebook_feed/lexicon/en/default.inc.php b/core/components/facebook_feed/lexicon/en/default.inc.php new file mode 100644 index 0000000..8ca9ca0 --- /dev/null +++ b/core/components/facebook_feed/lexicon/en/default.inc.php @@ -0,0 +1,21 @@ +<?php + +/** + * Default English language strings for Login + * @package login + * @subpackage lexicon + */ +$_lang['facebook_feed'] = 'Facebook Feed'; +$_lang['facebook_feed_desc'] = 'Update Access Token'; +$_lang['facebook_feed.ago'] = ' ago'; +$_lang['facebook_feed.ago_days'] = '[[+days]] days'; +$_lang['facebook_feed.ago_hours'] = '[[+hours]] hrs'; +$_lang['facebook_feed.ago_minutes'] = '[[+minutes]] min'; +$_lang['facebook_feed.ago_seconds'] = '[[+seconds]] sec'; + +$_lang['setting_facebook_feed.app_id'] = 'Facebook Application ID'; +$_lang['setting_facebook_feed.app_id_desc'] = 'Enter the ID of the Application given to you by Facebook.'; +$_lang['setting_facebook_feed.app_secret'] = 'Facebook Application Secret'; +$_lang['setting_facebook_feed.app_secret_desc'] = 'Enter the Secret of the Application given to you by Facebook.'; +$_lang['setting_facebook_feed.access_token'] = 'Facebook Access Token(don\'t change)'; +$_lang['setting_facebook_feed.access_token_desc'] = 'This holds the generated Access Token for this application, do not change unless you know what you are doing.'; diff --git a/core/components/facebook_feed/model/fb_feed/feed.class.php b/core/components/facebook_feed/model/fb_feed/feed.class.php index aef4774..217a435 100644 --- a/core/components/facebook_feed/model/fb_feed/feed.class.php +++ b/core/components/facebook_feed/model/fb_feed/feed.class.php @@ -12,7 +12,7 @@ class Feed { * The Facebook Application Secret */ protected $app_secret; - protected $page_token; + protected $access_token; public $config; @@ -40,63 +40,127 @@ function __construct(modX &$modx,array $config = array()) { 'jsUrl' => $assetsUrl.'js/', 'connectorUrl' => $assetsUrl.'connector.php', - 'app_id' => $this->modx->getOption('facebook_feed.app_id', null, ''), - 'page_id' => $this->modx->getOption('facebook_feed.page_id', null, '') + 'app_id' => $this->modx->getOption('facebook_feed.app_id', null, '') ),$config); $this->app_secret = $this->modx->getOption('facebook_feed.app_secret', null, ''); - $this->page_token = $this->modx->getOption('facebook_feed.page_token', null, ''); + $this->access_token = $this->modx->getOption('facebook_feed.access_token', null, ''); } - function initFB() { + protected function initFB() { return new Facebook\Facebook([ 'app_id' => $this->config['app_id'], 'app_secret' => $this->app_secret, 'default_graph_version' => 'v2.8', - 'default_access_token' => '300618826991721|sPBUAkM_V0ok3SbpYHy0iwWtSCY' + 'default_access_token' => $this->access_token ]); } - function getExtendedToken($fb) { - $helper = $fb->getJavaScriptHelper(); - try { - $accessToken = $helper->getAccessToken(); - } catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - return ''; - } catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - return ''; + public function generateAccessToken() { + $curl = curl_init(); + $url = 'https://graph.facebook.com/oauth/access_token?client_id='.$this->config['app_id'].'&client_secret='.$this->app_secret.'&grant_type=client_credentials'; + //echo '<pre>'.$url.'</pre>'; + curl_setopt_array($curl, array( + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_URL => $url, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_SSL_VERIFYPEER => 0 + )); + $result = curl_exec($curl); + if(!$result){ + $xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl)); + return false; } - - if($accessToken){ - $oAuth2Client = $fb->getOAuth2Client(); - if (! $accessToken->isLongLived()) { - // Exchanges a short-lived access token for a long-lived one - try { - $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken); - } catch (Facebook\Exceptions\FacebookSDKException $e) { - echo "<p>Error getting long-lived access token: " . $helper->getMessage() . "</p>\n\n"; - return ''; - } - } - $_SESSION['FBF_Token'] = $accessToken; - return $accessToken; + curl_close($curl); + $token = substr($result, strpos($result, '=') + 1); + + $setting = $this->modx->getObject('modSystemSetting',array('key' => 'facebook_feed.access_token')); + if ($setting != null) { + $setting->set('value',$options['app_id']); + $setting->save(); + return true; } + return false; } - function getPages() { - $fb = $this->initFB(); + function calcTimeAgo($time) { + return $this->getTimeAgo($time); + } - $accessToken = $_SESSION['FBF_Token']; + /** + * Gets a properly formatted "time ago" from a specified timestamp. Copied + * from MODx core output filters. + * + * @param string $time + * @return string + */ + public function getTimeAgo($time = '') { + if (empty($time)) return false; + $this->modx->lexicon->load('filters'); + $agoTS = array(); + $uts = array(); + $uts['start'] = strtotime($time); + $uts['end'] = time(); + if( $uts['start']!==-1 && $uts['end']!==-1 ) { + if( $uts['end'] >= $uts['start'] ) { + $diff = $uts['end'] - $uts['start']; + $years = intval((floor($diff/31536000))); + if ($years) $diff = $diff % 31536000; + $months = intval((floor($diff/2628000))); + if ($months) $diff = $diff % 2628000; + $weeks = intval((floor($diff/604800))); + if ($weeks) $diff = $diff % 604800; + $days = intval((floor($diff/86400))); + if ($days) $diff = $diff % 86400; + $hours = intval((floor($diff/3600))); + if ($hours) $diff = $diff % 3600; + $minutes = intval((floor($diff/60))); + if ($minutes) $diff = $diff % 60; + $diff = intval($diff); + $agoTS = array( + 'years' => $years, + 'months' => $months, + 'weeks' => $weeks, + 'days' => $days, + 'hours' => $hours, + 'minutes' => $minutes, + 'seconds' => $diff, + ); + } + } + $ago = array(); + if (!empty($agoTS['years'])) { + $ago[] = $this->modx->lexicon(($agoTS['years'] > 1 ? 'ago_years' : 'ago_year'),array('time' => $agoTS['years'])); + } + if (!empty($agoTS['months'])) { + $ago[] = $this->modx->lexicon(($agoTS['months'] > 1 ? 'ago_months' : 'ago_month'),array('time' => $agoTS['months'])); + } + if (!empty($agoTS['weeks']) && empty($agoTS['years'])) { + $ago[] = $this->modx->lexicon(($agoTS['weeks'] > 1 ? 'ago_weeks' : 'ago_week'),array('time' => $agoTS['weeks'])); + } + if (!empty($agoTS['days']) && empty($agoTS['months']) && empty($agoTS['years'])) { + $ago[] = $this->modx->lexicon(($agoTS['days'] > 1 ? 'ago_days' : 'ago_day'),array('time' => $agoTS['days'])); + } + if (!empty($agoTS['hours']) && empty($agoTS['weeks']) && empty($agoTS['months']) && empty($agoTS['years'])) { + $ago[] = $this->modx->lexicon(($agoTS['hours'] > 1 ? 'ago_hours' : 'ago_hour'),array('time' => $agoTS['hours'])); + } + if (!empty($agoTS['minutes']) && empty($agoTS['days']) && empty($agoTS['weeks']) && empty($agoTS['months']) && empty($agoTS['years'])) { + $ago[] = $this->modx->lexicon('ago_minutes',array('time' => $agoTS['minutes'])); + } + if (empty($ago)) { /* handle <1 min */ + $ago[] = $this->modx->lexicon('ago_seconds',array('time' => $agoTS['seconds'])); + } + $output = implode(', ',$ago); + $output = $this->modx->lexicon('ago',array('time' => $output)); + return $output; + } - if(!$accessToken) - $accessToken = $this->getExtendedToken($fb); - if(!$accessToken) - return ''; - $response = $fb->get('/me/accounts?fields=access_token,name&access_token='.$accessToken->getValue()); - return $response->getGraphEdge(); + function humanNumber($number) { + if($number > 999999){ + return number_format((float)$number / 1000000., 1, '.', ''). 'm'; + } elseif ($number > 999) { + return floor($number/1000) . 'k'; + } + return (int)$number; } function runFeed($scriptProperties) { @@ -108,13 +172,16 @@ function runFeed($scriptProperties) { ), $scriptProperties); $fb = $this->initFB(); - $response = $fb->get('/' . $config['page'] . '/feed?fields=full_picture,created_time,id,message,description,story,likes.limit(2).summary(true),shares,comments_mirroring_domain,comments,link&summary=true&limit=' . $config['limit']); + $response = $fb->get('/' . $config['page'] . '/feed?fields=full_picture,created_time,id,message,name,description,story,likes.limit(2).summary(true),shares,comments_mirroring_domain,comments,link&summary=true&limit=' . $config['limit']); $data = $response->getDecodedBody()['data']; foreach ($data as $post) { $pinfo = array(); $pinfo['img'] = $post['full_picture']; $pinfo['name'] = $post['name']; - //$pinfo['time_ago'] = $this->calcTimeAgo($post['created_time']); + $pinfo['link'] = $post['link']; + $pinfo['time_ago'] = $this->calcTimeAgo($post['created_time']); + $pinfo['likes'] = $this->humanNumber($post['likes']['summary']['total_count']); + $pinfo['shares'] = $this->humanNumber($post['shares']['count']); if(isset($post['message'])){ $pinfo['message'] = nl2br($post['message']); } else if(isset($post['description'])) { @@ -123,9 +190,9 @@ function runFeed($scriptProperties) { //ignore other types of posts continue; } - $output .= $modx->getChunk($config['tpl'], $pinfo); + $output .= $this->modx->getChunk($config['tpl'], $pinfo); } - $output .= print_r($data,true); + //$output .= print_r($data,true); return $output; } }