Recent Facebook Posts - Version 1.5.4

Version Description

Download this release

Release Info

Developer DvanKooten
Plugin Icon wp plugin Recent Facebook Posts
Version 1.5.4
Comparing to
See all releases

Code changes from version 1.2.2 to 1.5.4

assets/css/admin.css ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .rfbp-column{ float:left; }
2
+ .rfbp-sidebar{ width:30%; float:right; margin-left:1%; }
3
+ .rfbp-error{ color:red; }
4
+
5
+ .rfbp-box{ margin:0 0 24px;}
6
+ .rfbp-well { background:#222; color:#eee; padding:10px 20px; margin-top:10px; }
7
+
8
+ .error{ color:red; }
9
+ p.status{ font-weight:bold;}
10
+ span.connected, span.disconnected{ font-weight:bold; display:inline-block; color:white; padding:3px; }
11
+ span.connected{ background:green; }
12
+ span.disconnected{ background:lightGrey; }
13
+
14
+ .clearfix:after {
15
+ visibility: hidden;
16
+ display: block;
17
+ font-size: 0;
18
+ content: " ";
19
+ clear: both;
20
+ height: 0;
21
+ }
22
+
23
+ * html .clearfix { zoom: 1; } /* IE6 */
24
+ *:first-child+html .clearfix { zoom: 1; } /* IE7 */
css/rfb.css → assets/css/default.css RENAMED
@@ -1,9 +1,9 @@
1
  .rfb_posts a.rfb_link{ display:block; clear:both; float:none; font-weight:normal; background:none; border:0; padding:1px 0; margin:0; cursor:pointer; text-decoration:none; font-size:11px; line-height:15px; height:15px; }
2
  .rfb_posts a.rfb_link:hover{ text-decoration:none; }
3
  .rfb_posts .rfb_text a{ word-break:break-all; }
4
- .rfb_posts .rfb_image a{ border:1px solid #ccc; display:inline-block; margin:0; padding:3px; line-height:0; }
5
- .rfb_posts .rfb_image a:hover{ border-color:#3b5998; }
6
- .rfb_posts .rfb_image img{ max-width:100%; margin:0; padding:0; }
7
 
8
  .rfb_posts span.like_count, .rfb_posts span.comment_count{ margin-right:3px; background:url("../img/fb-sprite.png") no-repeat 0 0; padding-left:18px; color: #3B5998 !important; display:inline-block; }
9
  .rfb_posts span.like_count_and_comment_count:hover{ background-color: #ECEFF5; }
1
  .rfb_posts a.rfb_link{ display:block; clear:both; float:none; font-weight:normal; background:none; border:0; padding:1px 0; margin:0; cursor:pointer; text-decoration:none; font-size:11px; line-height:15px; height:15px; }
2
  .rfb_posts a.rfb_link:hover{ text-decoration:none; }
3
  .rfb_posts .rfb_text a{ word-break:break-all; }
4
+ div.widget .rfb_posts .rfb_image a, .rfb_posts .rfb_image a{ border:1px solid #ccc; display:inline-block; margin:0; padding:3px; line-height:0; max-width:100%; }
5
+ div.widget .rfb_posts .rfb_image a:hover, .rfb_posts .rfb_image a:hover{ border-color:#3b5998; }
6
+ div.widget .rfb_posts .rfb_image img, .rfb_posts .rfb_image img{ max-width:100%; margin:0; padding:0; }
7
 
8
  .rfb_posts span.like_count, .rfb_posts span.comment_count{ margin-right:3px; background:url("../img/fb-sprite.png") no-repeat 0 0; padding-left:18px; color: #3B5998 !important; display:inline-block; }
9
  .rfb_posts span.like_count_and_comment_count:hover{ background-color: #ECEFF5; }
{img → assets/img}/fb-sprite.png RENAMED
File without changes
assets/img/icon.png ADDED
Binary file
assets/js/admin.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ (function($) {
4
+
5
+ $("#rfb_img_size").change(function() {
6
+
7
+ if($(this).val() == 'dont_show') {
8
+ $("#rfb_img_options").hide();
9
+ } else {
10
+ $("#rfb_img_options").show();
11
+ }
12
+
13
+ });
14
+
15
+ })(jQuery);
classes/class-rfb-admin.php DELETED
@@ -1,116 +0,0 @@
1
- <?php
2
-
3
- class RFB_Admin {
4
-
5
- public function __construct($RFB) {
6
- global $pagenow;
7
-
8
- add_action('admin_init', array(&$this, 'register_settings'));
9
- add_action('admin_menu', array(&$this, 'build_menu'));
10
-
11
- add_filter("plugin_action_links_recent-facebook-posts/recent-facebook-posts.php", array(&$this, 'add_settings_link'));
12
-
13
- $this->RFB = $RFB;
14
-
15
- if(isset($_GET['rfb_renew_access_token'])) {
16
- $this->renew_access_token();
17
- }
18
-
19
- if(isset($_GET['page']) && $_GET['page'] == 'rfb-settings') {
20
- $this->handle_requests();
21
- }
22
- }
23
-
24
- private function renew_access_token() {
25
- $fb = $this->RFB->get_fb_instance();
26
-
27
- // Get Facebook User ID
28
- $user = $fb->getUser();
29
-
30
- if($user) {
31
- $access_token = $fb->getAccessToken();
32
- // store access token for later usage
33
- update_option('rfb_access_token', $access_token);
34
- }
35
- }
36
-
37
- public function register_settings() {
38
- register_setting('rfb_settings_group', 'rfb_settings');
39
- }
40
-
41
- public function build_menu() {
42
- $page = add_options_page('Recent Facebook Posts - Settings','Recent Facebook Posts','manage_options','rfb-settings',array($this, 'settings_page'));
43
- add_action( 'admin_print_styles-' . $page, array(&$this, 'load_css') );
44
- }
45
-
46
- public function load_css() {
47
- wp_enqueue_style( 'rfb_admin_css', plugins_url('recent-facebook-posts/css/admin.css') );
48
- }
49
-
50
- public function settings_page () {
51
-
52
- $opts = $this->RFB->get_options();
53
- $curl = extension_loaded('curl');
54
-
55
- //update_option('rfb_access_token', '');
56
- $access_token = get_option('rfb_access_token');
57
- $connected = false;
58
-
59
- if($curl) {
60
-
61
- $fb = $this->RFB->get_fb_instance();
62
-
63
- if($access_token) {
64
-
65
- $fb->setAccessToken($access_token);
66
- $connected = $fb->getUser();
67
-
68
- if($connected) {
69
- // try to fetch a test pos
70
- try {
71
- $try = $fb->api('/' . $opts['fb_id'] . '/posts?limit=1');
72
- } catch(Exception $e) {
73
- $connected = false;
74
- $error = $e;
75
- }
76
- }
77
- }
78
-
79
- }
80
-
81
-
82
- // check if cache directory is writable
83
- $cache_dir = dirname(__FILE__) . '/../cache/';
84
- $cache_file = dirname(__FILE__) . '/../cache/posts.cache';
85
-
86
- if(!file_exists($cache_dir)) {
87
- $cache_error = 'The cache directory (<i>'. ABSPATH . 'wp-content/plugins/recent-facebook-posts/cache/</i>) does not exist.';
88
- } elseif(!is_writable($cache_dir)) {
89
- $cache_error = 'The cache directory (<i>'. ABSPATH . 'wp-content/plugins/recent-facebook-posts/cache/</i>) is not writable.';
90
- } elseif(file_exists($cache_file) && !is_writable($cache_file)) {
91
- $cache_error = 'The cache file (<i>'. ABSPATH . 'wp-content/plugins/recent-facebook-posts/cache/posts.cache</i>) exists but is not writable.';
92
- }
93
-
94
-
95
- require dirname(__FILE__) . '/../views/settings_page.html.php';
96
- }
97
-
98
- public function handle_requests() {
99
- if(isset($_POST['renew_cache'])) {
100
- add_action('init', array($this->RFB, 'renew_cache_file'));
101
- }
102
- }
103
-
104
-
105
- /**
106
- * Adds the settings link on the plugin's overview page
107
- * @param array $links Array containing all the settings links for the various plugins.
108
- * @return array The new array containing all the settings links
109
- */
110
- function add_settings_link($links) {
111
- $settings_link = '<a href="options-general.php?page=rfb-settings">Settings</a>';
112
- array_unshift($links, $settings_link);
113
-
114
- return $links;
115
- }
116
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/class-rfb.php DELETED
@@ -1,329 +0,0 @@
1
- <?php
2
-
3
- class RFB {
4
-
5
- private static $instance;
6
- private static $fb_instance;
7
- private $defaults = array(
8
- 'app_id' => '',
9
- 'app_secret' => '',
10
- 'fb_id' => 'DannyvanKootenCOM',
11
- 'cache_time' => 1800,
12
- 'load_css' => 0,
13
- 'link_text' => 'Find us on Facebook',
14
- 'link_new_window' => 0,
15
- 'img_size' => 'thumbnail',
16
- 'img_width' => 100,
17
- 'img_height' => 100
18
- );
19
- private $options;
20
-
21
- public static function get_instance() {
22
- if(!self::$instance) self::$instance = new RFB();
23
- return self::$instance;
24
- }
25
-
26
- public function __construct() {
27
-
28
- add_action('wp_login', array($this, 'renew_access_token'));
29
- add_action('init', array($this, 'on_init'));
30
-
31
- add_shortcode('recent-facebook-posts', array($this, 'shortcode_output'));
32
-
33
- // only on frontend
34
- if(!is_admin()) {
35
- $opts = $this->get_options();
36
- if($opts['load_css']) {
37
- add_action( 'wp_enqueue_scripts', array(&$this, 'load_css'));
38
- }
39
- }
40
- }
41
-
42
- public function on_init() {
43
- if(!session_id() && !headers_sent()) {
44
- session_start();
45
- }
46
- }
47
-
48
- public function load_css() {
49
- wp_register_style('rfb_css', plugins_url('recent-facebook-posts/css/rfb.css') );
50
- wp_enqueue_style('rfb_css' );
51
- }
52
-
53
- public function get_options() {
54
- if(!$this->options) {
55
- $this->options = array_merge($this->defaults, (array) get_option('rfb_settings'));
56
- }
57
-
58
- return $this->options;
59
- }
60
-
61
- public function renew_access_token($redirect_uri = null) {
62
-
63
- // only renew when the visitor is an administrator
64
- $user = wp_get_current_user();
65
- if(!user_can($user, 'manage_options')) return false;
66
-
67
- if(!$redirect_uri) {
68
- $redirect_uri = get_admin_url() . '?rfb_renew_access_token';
69
- }
70
-
71
- $fb = $this->get_fb_instance();
72
-
73
- // Get Facebook User ID
74
- $fb_user = $fb->getUser();
75
-
76
- $location = $fb->getLoginUrl(array('redirect_uri' => $redirect_uri));
77
-
78
- if(!headers_sent()) {
79
- header("Location: $location");
80
- exit;
81
- } else {
82
- echo '<script type="text/javascript">window.location = \''. $location .'\';</script>';
83
- exit;
84
- }
85
-
86
- return ;
87
- }
88
-
89
- public function get_fb_instance() {
90
- if(!self::$fb_instance) {
91
-
92
- require dirname(__FILE__) . '/facebook-php-sdk/facebook.php';
93
-
94
- $opts = $this->get_options();
95
-
96
- self::$fb_instance = new Facebook(array(
97
- 'appId' => trim($opts['app_id']),
98
- 'secret' => trim($opts['app_secret']),
99
- ));
100
- }
101
- return self::$fb_instance;
102
- }
103
-
104
- public function get_posts() {
105
- $cache_file = dirname(__FILE__) . '/../cache/posts.cache';
106
- $opts = $this->get_options();
107
-
108
- // check if cache file exists
109
- // check if cache file exists for longer then the given expiration time
110
- if(!file_exists($cache_file) || ($this->get_time_of_last_file_change($cache_file) < (time() - $opts['cache_time']))) {
111
- $this->renew_cache_file();
112
-
113
- if(!file_exists($cache_file)) return array();
114
- }
115
-
116
- $posts = json_decode(file_get_contents($cache_file), true);
117
- return $posts;
118
- }
119
-
120
- public function renew_cache_file() {
121
- $opts = $this->get_options();
122
- if(empty($opts['app_id']) || empty($opts['fb_id'])) return false;
123
-
124
- $access_token = get_option('rfb_access_token');
125
-
126
- if(!$access_token) {
127
- $access_token = $this->renew_access_token();
128
- if(!$access_token) return false;
129
- }
130
-
131
- $fb = $this->get_fb_instance();
132
- $fb->setAccessToken($access_token);
133
-
134
- if(!$fb->getUser()) return false;
135
-
136
- $apiResult = $fb->api(trim($opts['fb_id']) . '/posts?with=message&limit=250');
137
-
138
- if(!$apiResult or !is_array($apiResult) or !isset($apiResult['data']) or !is_array($apiResult['data'])) { return false; }
139
-
140
- $data = array();
141
- foreach($apiResult['data'] as $p) {
142
-
143
- // skip this "post" if it is not of one of the following types
144
- if(!in_array($p['type'], array('status', 'photo', 'video', 'link'))) {
145
- continue;
146
- }
147
-
148
- // skip empty status updates
149
- if($p['type'] == 'status' && empty($p['message'])) { continue; }
150
-
151
- //split user and post ID (userID_postID)
152
- $idArray = explode("_", $p['id']);
153
-
154
- $post = array();
155
- $post['type'] = $p['type'];
156
- $post['author'] = $p['from'];
157
- $post['content'] = isset($p['message']) ? $p['message'] : '';
158
-
159
-
160
- // set post content and image
161
- if($p['type'] == 'photo') {
162
- $post['image'] = "http://graph.facebook.com/".$p['object_id']."/picture";
163
- } elseif($p['type'] == 'video') {
164
- //$post['image'] = $p['picture'];
165
- $post['image'] = "http://graph.facebook.com/".$p['object_id']."/picture";
166
- $post['content'] .= "\n\n {$p['link']}";
167
- } else {
168
- $post['image'] = null;
169
- }
170
-
171
-
172
- // calculate post like and comment counts
173
- if(isset($p['likes'])) {
174
- if(isset($p['likes']['count'])) {
175
- $like_count = $p['likes']['count'];
176
- } elseif(isset($p['likes']['data']) && is_array($p['likes']['data'])) {
177
- $like_count = count($p['likes']['data']);
178
- }
179
- } else {
180
- $like_count = 0;
181
- }
182
-
183
- if(isset($p['comments'])) {
184
- if(isset($p['comments']['count'])) {
185
- $comment_count = $p['comments']['count'];
186
- } elseif(isset($p['comments']['data']) && is_array($p['comments']['data'])) {
187
- $comment_count = count($p['comments']['data']);
188
- }
189
- } else {
190
- $comment_count = 0;
191
- }
192
-
193
- $post['timestamp'] = strtotime($p['created_time']);
194
- $post['like_count'] = $like_count;
195
- $post['comment_count'] = $comment_count;
196
- $post['link'] = "http://www.facebook.com/".$opts['fb_id']."/posts/".$idArray[1];
197
- $data[] = $post;
198
-
199
- }
200
-
201
- $data = json_encode($data);
202
- $cache_dir = dirname(__FILE__) . '/../cache/';
203
- $cache_file = dirname(__FILE__) . '/../cache/posts.cache';
204
-
205
- // create cache directory if not exists
206
- if(!file_exists($cache_dir)) {
207
- @mkdir($cache_dir, 0777);
208
- }
209
-
210
- // abandon if cache folder is not writable
211
- if(!is_writable(dirname(__FILE__) . '/../cache/')) {
212
- return false;
213
- }
214
-
215
- file_put_contents($cache_file, $data);
216
-
217
- return true;
218
- }
219
-
220
- public function shortcode_output($atts)
221
- {
222
- extract(shortcode_atts(array(
223
- 'number' => '5',
224
- 'likes' => 1,
225
- 'comments' => 1,
226
- 'excerpt_length' => 140
227
- ), $atts));
228
-
229
- $opts = $this->get_options();
230
- $posts = $this->get_posts();
231
- $posts = array_slice($posts, 0, $number);
232
-
233
- $output = '<div class="recent-facebook-posts rfb_posts shortcode">';
234
-
235
- foreach($posts as $post) {
236
- $content = $post['content'];
237
- $shortened = false;
238
-
239
- if(strlen($content) > $excerpt_length) {
240
- $limit = strpos($post['content'], ' ',$excerpt_length);
241
- if($limit) {
242
- $content = substr($post['content'], 0, $limit);
243
- $shortened = true;
244
- }
245
- }
246
-
247
-
248
- $output .= '<div class="rfb-post">';
249
- $output .= '<p class="rfb_text">'. nl2br(make_clickable($content));
250
- if ($shortened) $output .= '..';
251
- $output .= '</p>';
252
-
253
- if($opts['img_size'] != 'dont_show' && isset($post['image']) && $post['image']) {
254
- if(isset($post['type']) && $post['type'] == 'photo') {
255
- $img_atts = 'src="'. $post['image'] .'?type='. $opts['img_size'] .'" style="max-width: '. $opts['img_width'] .'px; max-height: '. $opts['img_width'] .'px;"';
256
- } else {
257
- $img_atts = 'src="'. $post['image'] .'" style="max-width: '. $opts['img_width'] .'px; max-height: '. $opts['img_width'] .'px;"';
258
- }
259
-
260
- $output .= '<p class="rfb_image"><a target="_blank" href="'. $post['link'] . '" rel="nofollow"><img '. $img_atts .' alt="" /></a></p>';
261
- }
262
-
263
- $output .= '<p><a target="_blank" class="rfb_link" href="'. $post['link'] .'" rel="nofollow">';
264
- if($likes || $comments) { $output .= '<span class="like_count_and_comment_count">'; }
265
- if($likes) { $output .= '<span class="like_count">'. $post['like_count'] . ' <span>likes</span></span> '; }
266
- if($comments) { $output .= '<span class="comment_count">' . $post['comment_count'] . ' <span>comments</span></span> '; }
267
- if($likes || $comments) { $output .= '</span>'; }
268
- $output .= '<span class="timestamp" title="'. date('l, F j, Y', $post['timestamp']) . ' at ' . date('G:i', $post['timestamp']) . '" >';
269
- if($likes || $comments) { $output .= ' · '; }
270
- $output .= '<span>' . $this->time_ago($post['timestamp']) . '</span></span>';
271
- $output .= '</a></p></div>' ;
272
-
273
- }
274
-
275
- if(empty($posts)) {
276
- $output .= '<p>No recent Facebook status updates to show.</p>';
277
- if(current_user_can('manage_options')) {
278
- $output .= '<p><strong>Admins only notice:</strong> Did you <a href="' . get_admin_url(null,'options-general.php?page=rfb-settings') . '">configure the plugin</a> properly?</p>';
279
- }
280
- }
281
-
282
- $output .= "</div>";
283
- return $output;
284
- }
285
-
286
- public function time_ago($timestamp) {
287
- $diff = time() - (int) $timestamp;
288
-
289
- if ($diff == 0)
290
- return 'just now';
291
-
292
- $intervals = array
293
- (
294
- 1 => array('year', 31556926),
295
- $diff < 31556926 => array('month', 2628000),
296
- $diff < 2629744 => array('week', 604800),
297
- $diff < 604800 => array('day', 86400),
298
- $diff < 86400 => array('hour', 3600),
299
- $diff < 3600 => array('minute', 60),
300
- $diff < 60 => array('second', 1)
301
- );
302
-
303
- $value = floor($diff/$intervals[1][1]);
304
- return $value.' '.$intervals[1][0].($value > 1 ? 's' : '').' ago';
305
- }
306
-
307
- private function get_time_of_last_file_change($filePath)
308
- {
309
- clearstatcache();
310
- $time = filemtime($filePath);
311
-
312
- $isDST = (date('I', $time) == 1);
313
- $systemDST = (date('I') == 1);
314
-
315
- $adjustment = 0;
316
-
317
- if($isDST == false && $systemDST == true)
318
- $adjustment = 3600;
319
-
320
- else if($isDST == true && $systemDST == false)
321
- $adjustment = -3600;
322
-
323
- else
324
- $adjustment = 0;
325
-
326
- return ($time + $adjustment);
327
- }
328
-
329
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/facebook-php-sdk/fb_ca_chain_bundle.crt DELETED
@@ -1,121 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIFgjCCBGqgAwIBAgIQDKKbZcnESGaLDuEaVk6fQjANBgkqhkiG9w0BAQUFADBm
3
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
4
- d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
5
- ZSBDQS0zMB4XDTEwMDExMzAwMDAwMFoXDTEzMDQxMTIzNTk1OVowaDELMAkGA1UE
6
- BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEX
7
- MBUGA1UEChMORmFjZWJvb2ssIEluYy4xFzAVBgNVBAMUDiouZmFjZWJvb2suY29t
8
- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9rzj7QIuLM3sdHu1HcI1VcR3g
9
- b5FExKNV646agxSle1aQ/sJev1mh/u91ynwqd2BQmM0brZ1Hc3QrfYyAaiGGgEkp
10
- xbhezyfeYhAyO0TKAYxPnm2cTjB5HICzk6xEIwFbA7SBJ2fSyW1CFhYZyo3tIBjj
11
- 19VjKyBfpRaPkzLmRwIDAQABo4ICrDCCAqgwHwYDVR0jBBgwFoAUUOpzidsp+xCP
12
- nuUBINTeeZlIg/cwHQYDVR0OBBYEFPp+tsFBozkjrHlEnZ9J4cFj2eM0MA4GA1Ud
13
- DwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMF8GA1UdHwRYMFYwKaAnoCWGI2h0dHA6
14
- Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9jYTMtZmIuY3JsMCmgJ6AlhiNodHRwOi8vY3Js
15
- NC5kaWdpY2VydC5jb20vY2EzLWZiLmNybDCCAcYGA1UdIASCAb0wggG5MIIBtQYL
16
- YIZIAYb9bAEDAAEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0
17
- LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIB
18
- UgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkA
19
- YwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEA
20
- bgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMA
21
- UABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkA
22
- IABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwA
23
- aQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8A
24
- cgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMA
25
- ZQAuMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQUF
26
- AAOCAQEACOkTIdxMy11+CKrbGNLBSg5xHaTvu/v1wbyn3dO/mf68pPfJnX6ShPYy
27
- 4XM4Vk0x4uaFaU4wAGke+nCKGi5dyg0Esg7nemLNKEJaFAJZ9enxZm334lSCeARy
28
- wlDtxULGOFRyGIZZPmbV2eNq5xdU/g3IuBEhL722mTpAye9FU/J8Wsnw54/gANyO
29
- Gzkewigua8ip8Lbs9Cht399yAfbfhUP1DrAm/xEcnHrzPr3cdCtOyJaM6SRPpRqH
30
- ITK5Nc06tat9lXVosSinT3KqydzxBYua9gCFFiR3x3DgZfvXkC6KDdUlDrNcJUub
31
- a1BHnLLP4mxTHL6faAXYd05IxNn/IA==
32
- -----END CERTIFICATE-----
33
- -----BEGIN CERTIFICATE-----
34
- MIIGVTCCBT2gAwIBAgIQCFH5WYFBRcq94CTiEsnCDjANBgkqhkiG9w0BAQUFADBs
35
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
36
- d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
37
- ZSBFViBSb290IENBMB4XDTA3MDQwMzAwMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL
38
- MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
39
- LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
40
- Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR
41
- CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv
42
- KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5
43
- BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf
44
- 1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs
45
- zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d
46
- 32duXvsCAwEAAaOCAvcwggLzMA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w
47
- ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
48
- LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
49
- AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
50
- AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
51
- AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
52
- AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
53
- AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
54
- AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
55
- AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
56
- AHIAZQBuAGMAZQAuMA8GA1UdEwEB/wQFMAMBAf8wNAYIKwYBBQUHAQEEKDAmMCQG
57
- CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSBhzCB
58
- hDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGlnaEFz
59
- c3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQu
60
- Y29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSMEGDAW
61
- gBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUBINTe
62
- eZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAF1PhPGoiNOjsrycbeUpSXfh59bcqdg1
63
- rslx3OXb3J0kIZCmz7cBHJvUV5eR13UWpRLXuT0uiT05aYrWNTf58SHEW0CtWakv
64
- XzoAKUMncQPkvTAyVab+hA4LmzgZLEN8rEO/dTHlIxxFVbdpCJG1z9fVsV7un5Tk
65
- 1nq5GMO41lJjHBC6iy9tXcwFOPRWBW3vnuzoYTYMFEuFFFoMg08iXFnLjIpx2vrF
66
- EIRYzwfu45DC9fkpx1ojcflZtGQriLCnNseaIGHr+k61rmsb5OPs4tk8QUmoIKRU
67
- 9ZKNu8BVIASm2LAXFszj0Mi0PeXZhMbT9m5teMl5Q+h6N/9cNUm/ocU=
68
- -----END CERTIFICATE-----
69
- -----BEGIN CERTIFICATE-----
70
- MIIEQjCCA6ugAwIBAgIEQoclDjANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
71
- VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
72
- ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
73
- KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
74
- ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEy
75
- MjIxNTI3MjdaFw0xNDA3MjIxNTU3MjdaMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
76
- EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV
77
- BAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwggEiMA0GCSqG
78
- SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGzOVz5vvUu+UtLTKm3+WBP8nNJUm2cSrD
79
- 1ZQ0Z6IKHLBfaaZAscS3so/QmKSpQVk609yU1jzbdDikSsxNJYL3SqVTEjju80lt
80
- cZF+Y7arpl/DpIT4T2JRvvjF7Ns4kuMG5QiRDMQoQVX7y1qJFX5x6DW/TXIJPb46
81
- OFBbdzEbjbPHJEWap6xtABRaBLe6E+tRCphBQSJOZWGHgUFQpnlcid4ZSlfVLuZd
82
- HFMsfpjNGgYWpGhz0DQEE1yhcdNafFXbXmThN4cwVgTlEbQpgBLxeTmIogIRfCdm
83
- t4i3ePLKCqg4qwpkwr9mXZWEwaElHoddGlALIBLMQbtuC1E4uEvLAgMBAAGjggET
84
- MIIBDzASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggr
85
- BgEFBQcDAgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdo
86
- dHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8v
87
- Y3JsLmVudHJ1c3QubmV0L3NlcnZlcjEuY3JsMB0GA1UdDgQWBBSxPsNpA/i/RwHU
88
- mCYaCALvY2QrwzALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7
89
- UISX8+1i0BowGQYJKoZIhvZ9B0EABAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEF
90
- BQADgYEAUuVY7HCc/9EvhaYzC1rAIo348LtGIiMduEl5Xa24G8tmJnDioD2GU06r
91
- 1kjLX/ktCdpdBgXadbjtdrZXTP59uN0AXlsdaTiFufsqVLPvkp5yMnqnuI3E2o6p
92
- NpAkoQSbB6kUCNnXcW26valgOjDLZFOnr241QiwdBAJAAE/rRa8=
93
- -----END CERTIFICATE-----
94
- -----BEGIN CERTIFICATE-----
95
- MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
96
- VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
97
- ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
98
- KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
99
- ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
100
- MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
101
- ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
102
- b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
103
- bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
104
- U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
105
- A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
106
- I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
107
- wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
108
- AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
109
- oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
110
- BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
111
- dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
112
- MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
113
- b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
114
- dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
115
- MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
116
- E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
117
- MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
118
- hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
119
- 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
120
- 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
121
- -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/admin.css DELETED
@@ -1,27 +0,0 @@
1
-
2
- #rfb{ clear:both; }
3
- #rfb div.column{ float:left; }
4
- #rfb label.error{ color:red; }
5
-
6
- #rfb div.box{ padding:5px; }
7
- #rfb div.box ul{ list-style:square; margin-left:25px; }
8
- #rfb div.box li{ margin:0; }
9
-
10
- #rfb-donatebox{ border:2px solid green; background:#CFC; }
11
- #rfb-donatebox h3{ color:green; margin:0; }
12
- #rfb-donatebox li{ line-height:22px; }
13
- #rfb p.status{ font-weight:bold;}
14
- #rfb span.connected, #rfb span.disconnected{ font-weight:bold; display:inline-block; color:white; padding:3px; }
15
- #rfb span.connected{ background:green; }
16
- #rfb span.disconnected{ background:lightGrey; }
17
-
18
- #rfb .clearfix:after {
19
- visibility: hidden;
20
- display: block;
21
- font-size: 0;
22
- content: " ";
23
- clear: both;
24
- height: 0;
25
- }
26
- * html #rfb .clearfix { zoom: 1; } /* IE6 */
27
- *:first-child+html #rfb .clearfix { zoom: 1; } /* IE7 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/RFBP.php ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class RFBP {
4
+
5
+ private static $instance = null;
6
+ private static $api = null;
7
+ private $options;
8
+ public $cache_renewed = false;
9
+
10
+ public static function instance() {
11
+ return self::$instance;
12
+ }
13
+
14
+ public function __construct() {
15
+
16
+ self::$instance = $this;
17
+
18
+ // both frontend and backend
19
+ include_once RFBP_PLUGIN_DIR . 'includes/RFBP_Widget.php';
20
+ add_action( 'widgets_init', array($this, 'register_widget') );
21
+
22
+ // finish if this is an AJAX request
23
+ if(defined("DOING_AJAX") && DOING_AJAX) { return; }
24
+
25
+ // starts sessions, fixes app token problem
26
+ if(!session_id() && !headers_sent()) {
27
+ session_start();
28
+ }
29
+
30
+ $opts = $this->get_settings();
31
+
32
+ // only on frontend
33
+ if(!is_admin()) {
34
+
35
+ include_once RFBP_PLUGIN_DIR . 'includes/helper-functions.php';
36
+ include_once RFBP_PLUGIN_DIR . 'includes/template-functions.php';
37
+
38
+ add_shortcode('recent-facebook-posts', array($this, 'shortcode_output'));
39
+
40
+ if($opts['load_css']) {
41
+ add_action( 'wp_enqueue_scripts', array($this, 'load_css'));
42
+ }
43
+
44
+ } else {
45
+ // only in admin panel
46
+ include_once RFBP_PLUGIN_DIR . 'includes/RFBP_Admin.php';
47
+ new RFBP_Admin();
48
+ }
49
+ }
50
+
51
+ public function register_widget()
52
+ {
53
+ register_widget( "RFBP_Widget" );
54
+ }
55
+
56
+ public function load_css() {
57
+ wp_register_style('recent-facebook-posts-css', plugins_url('recent-facebook-posts/assets/css/default.css') );
58
+ wp_enqueue_style('recent-facebook-posts-css' );
59
+ }
60
+
61
+ public function get_settings() {
62
+ if(!$this->options) {
63
+
64
+ $defaults = array(
65
+ 'app_id' => '',
66
+ 'app_secret' => '',
67
+ 'fb_id' => 'DannyvanKootenCOM',
68
+ 'cache_time' => 1800,
69
+ 'load_css' => 0,
70
+ 'link_text' => 'Find us on Facebook',
71
+ 'link_new_window' => 0,
72
+ 'img_size' => 'thumbnail',
73
+ 'img_width' => 100,
74
+ 'img_height' => 100
75
+ );
76
+
77
+ // get user options
78
+ $options = get_option('rfb_settings');
79
+
80
+ // options did not exist yet, add option to database
81
+ if(!$options) { add_option('rfb_settings', $defaults); }
82
+
83
+ $this->options = array_merge($defaults, (array) $options);
84
+ }
85
+
86
+ return $this->options;
87
+ }
88
+
89
+ static public function api()
90
+ {
91
+ if(!self::$api) {
92
+
93
+ if(!class_exists("Facebook")) {
94
+ require_once RFBP_PLUGIN_DIR . 'includes/facebook-php-sdk/facebook.php';
95
+ }
96
+
97
+ $opts = RFBP::instance()->get_settings();
98
+ self::$api = new Facebook(array(
99
+ 'appId' => trim($opts['app_id']),
100
+ 'secret' => trim($opts['app_secret']),
101
+ ));
102
+ }
103
+
104
+ return self::$api;
105
+ }
106
+
107
+ public function get_posts() {
108
+
109
+ $opts = $this->get_settings();
110
+
111
+ // try to get posts from cache
112
+ if(($posts = $this->get_cached_posts())) {
113
+ return $posts;
114
+ }
115
+
116
+ if(empty($opts['app_id']) || empty($opts['fb_id'])) { return array(); }
117
+
118
+ $accessToken = get_option('rfb_access_token');
119
+
120
+ // if no access token has been stored, we can't make the API call.
121
+ if(!$accessToken) { return array(); }
122
+
123
+ $fb = self::api();
124
+ $fb->setAccessToken($accessToken);
125
+
126
+ // check if Facebook API has an identified user
127
+ // if not, API is not connected
128
+ if(!$fb->getUser()) { return array(); }
129
+
130
+ $apiResult = $fb->api(trim($opts['fb_id']) . '/posts?fields=id,picture,type,from,message,status_type,object_id,link,created_time,comments.limit(1).summary(true),likes.limit(1).summary(true)');
131
+
132
+ if(!$apiResult or !is_array($apiResult) or !isset($apiResult['data']) or !is_array($apiResult['data'])) { return array(); }
133
+
134
+ $posts = array();
135
+ foreach($apiResult['data'] as $p) {
136
+
137
+ // skip this "post" if it is not of one of the following types
138
+ if(!in_array($p['type'], array('status', 'photo', 'video', 'link'))) {
139
+ continue;
140
+ }
141
+
142
+ // skip empty status updates
143
+ if($p['type'] == 'status' && (!isset($p['message']) || empty($p['message']))) { continue; }
144
+ if($p['type'] == 'status' && $p['status_type'] == 'approved_friend') { continue; }
145
+
146
+ //var_dump($p); echo '<br /><br />';
147
+
148
+ //split user and post ID (userID_postID)
149
+ $idArray = explode("_", $p['id']);
150
+
151
+ $post = array();
152
+ $post['type'] = $p['type'];
153
+ $post['author'] = $p['from'];
154
+ $post['content'] = isset($p['message']) ? $p['message'] : '';
155
+ $post['image'] = null;
156
+
157
+ // set post content and image
158
+ if($p['type'] == 'photo') {
159
+
160
+ $image = "//graph.facebook.com/". $p['object_id'] . '/picture?type=' . $opts['img_size'];
161
+ $post['image'] = $image;
162
+
163
+ } elseif($p['type'] == 'video') {
164
+
165
+ $image = $p['picture'];
166
+
167
+ if($opts['img_size'] == 'normal') {
168
+ $image = str_replace(array("_s.jpg", "_s.png"), array("_n.jpg", "_n.png"), $image);
169
+ }
170
+
171
+ $post['image'] = $image;
172
+
173
+ } elseif($p['type'] == 'link') {
174
+ $post['content'] .= "\n\n" . $p['link'];
175
+ }
176
+
177
+ // calculate post like and comment counts
178
+ if(isset($p['likes']['summary']['total_count'])) {
179
+ $like_count = $p['likes']['summary']['total_count'];
180
+ } else {
181
+ $like_count = 0;
182
+ }
183
+
184
+ if(isset($p['comments']['summary']['total_count'])) {
185
+ $comment_count = $p['comments']['summary']['total_count'];
186
+ } else {
187
+ $comment_count = 0;
188
+ }
189
+
190
+ $post['timestamp'] = strtotime($p['created_time']);
191
+ $post['like_count'] = $like_count;
192
+ $post['comment_count'] = $comment_count;
193
+ $post['link'] = "http://www.facebook.com/".$opts['fb_id']."/posts/".$idArray[1];
194
+ $posts[] = $post;
195
+
196
+ }
197
+
198
+ // store results in cache for later use
199
+ $this->set_cached_posts($posts);
200
+
201
+ return $posts;
202
+ }
203
+
204
+ public function invalidate_cache()
205
+ {
206
+ $opts = $this->get_settings();
207
+ $cache_file = WP_CONTENT_DIR . '/recent-facebook-posts.cache';
208
+ $time = time() - ($opts['cache_time'] * 2);
209
+ return touch($cache_file, $time);
210
+ }
211
+
212
+ private function get_cached_posts()
213
+ {
214
+ $opts = $this->get_settings();
215
+ $cache_file = WP_CONTENT_DIR . '/recent-facebook-posts.cache';
216
+ if(!file_exists($cache_file) || ($this->get_time_of_last_file_change($cache_file) < (time() - $opts['cache_time']))) {
217
+ return false;
218
+ }
219
+
220
+ // by now, cache file exists.
221
+ $posts = json_decode(file_get_contents($cache_file), true);
222
+ return $posts;
223
+
224
+ }
225
+
226
+ private function set_cached_posts($posts)
227
+ {
228
+ $data = json_encode($posts);
229
+ $cache_dir = WP_CONTENT_DIR . '/';
230
+ $cache_file = WP_CONTENT_DIR . '/recent-facebook-posts.cache';
231
+
232
+ // abandon if cache folder is not writable
233
+ if(!is_writable(WP_CONTENT_DIR)) {
234
+ return false;
235
+ }
236
+
237
+ file_put_contents($cache_file, $data);
238
+ $this->cache_renewed = true;
239
+ return true;
240
+ }
241
+
242
+ public function shortcode_output($atts)
243
+ {
244
+ extract(shortcode_atts(array(
245
+ 'number' => '5',
246
+ 'likes' => 1,
247
+ 'comments' => 1,
248
+ 'excerpt_length' => 140
249
+ ), $atts));
250
+
251
+ $opts = $this->get_settings();
252
+ $posts = $this->get_posts();
253
+ $posts = array_slice($posts, 0, $number);
254
+
255
+ // set link target
256
+ $link_target = ($opts['link_new_window']) ? "_blank" : '';
257
+
258
+ $output = "\n<!-- Recent Facebook Posts v".RFBP_VERSION." - http://wordpress.org/plugins/recent-facebook-posts/ -->\n";
259
+
260
+ $output .= '<div class="recent-facebook-posts rfb_posts shortcode">';
261
+
262
+ foreach($posts as $post) {
263
+ $content = $post['content'];
264
+ $shortened = false;
265
+
266
+ if(strlen($content) > $excerpt_length) {
267
+ $limit = strpos($post['content'], ' ',$excerpt_length);
268
+ if($limit) {
269
+ $content = substr($post['content'], 0, $limit);
270
+ $shortened = true;
271
+ }
272
+ }
273
+
274
+
275
+ $output .= '<div class="rfb-post">';
276
+ $output .= '<p class="rfb_text">'. nl2br(rfbp_make_clickable($content, $link_target));
277
+ if ($shortened) $output .= '..';
278
+ $output .= '</p>';
279
+
280
+ if($opts['img_size'] != 'dont_show' && isset($post['image']) && $post['image']) {
281
+
282
+ $img_atts = 'src="'. $post['image'] .'" style="max-width: '. $opts['img_width'] .'px; max-height: '. $opts['img_width'] .'px;"';
283
+
284
+ $output .= '<p class="rfb_image"><a target="'.$link_target.'" href="'. $post['link'] . '" rel="nofollow"><img '. $img_atts .' alt="" /></a></p>';
285
+ }
286
+
287
+ $output .= '<p><a target="'.$link_target.'"" class="rfb_link" href="'. $post['link'] .'" rel="nofollow">';
288
+ if($likes || $comments) { $output .= '<span class="like_count_and_comment_count">'; }
289
+ if($likes) { $output .= '<span class="like_count">'. $post['like_count'] . ' <span>likes</span></span> '; }
290
+ if($comments) { $output .= '<span class="comment_count">' . $post['comment_count'] . ' <span>comments</span></span> '; }
291
+ if($likes || $comments) { $output .= '</span>'; }
292
+ $output .= '<span class="timestamp" title="'. date('l, F j, Y', $post['timestamp']) . ' at ' . date('G:i', $post['timestamp']) . '" >';
293
+ if($likes || $comments) { $output .= ' · '; }
294
+ $output .= '<span>' . rfbp_time_ago($post['timestamp']) . '</span></span>';
295
+ $output .= '</a></p></div>' ;
296
+
297
+ }
298
+
299
+ if(empty($posts)) {
300
+ $output .= '<p>No recent Facebook status updates to show.</p>';
301
+ if(current_user_can('manage_options')) {
302
+ $output .= '<p><strong>Admins only notice:</strong> Did you <a href="' . get_admin_url(null,'options-general.php?page=rfb-settings') . '">configure the plugin</a> properly?</p>';
303
+ }
304
+ }
305
+
306
+ $output .= "</div>";
307
+ $output .= "\n <!-- / Recent Facebook Posts -->\n";
308
+ return $output;
309
+ }
310
+
311
+ private function get_time_of_last_file_change($filePath)
312
+ {
313
+ clearstatcache();
314
+ $time = filemtime($filePath);
315
+
316
+ $isDST = (date('I', $time) == 1);
317
+ $systemDST = (date('I') == 1);
318
+
319
+ $adjustment = 0;
320
+
321
+ if($isDST == false && $systemDST == true)
322
+ $adjustment = 3600;
323
+
324
+ else if($isDST == true && $systemDST == false)
325
+ $adjustment = -3600;
326
+
327
+ else
328
+ $adjustment = 0;
329
+
330
+ return ($time + $adjustment);
331
+ }
332
+
333
+ }
includes/RFBP_Admin.php ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class RFBP_Admin {
4
+
5
+ public function __construct() {
6
+
7
+ global $pagenow;
8
+
9
+ add_action('admin_init', array($this, 'register_settings'));
10
+ add_action('admin_menu', array($this, 'build_menu'));
11
+
12
+ add_filter("plugin_action_links_recent-facebook-posts/recent-facebook-posts.php", array($this, 'add_settings_link'));
13
+
14
+ // check expiry date of access token
15
+ $expiryDate = get_option('rfb_access_token_expiry_date');
16
+ if($expiryDate && (date('Ymd', strtotime("+14 days")) >= $expiryDate)) {
17
+ // access token expires in less than 14 days, show admin notice
18
+ add_action( 'admin_notices', array($this, 'show_admin_notice') );
19
+ }
20
+
21
+ // handle requests early, but only on rfb settings page
22
+ if(isset($_GET['page']) && $_GET['page'] == 'rfb-settings' ) {
23
+
24
+ // load css
25
+ add_action('admin_enqueue_scripts', array($this, 'load_css') );
26
+
27
+ // maybe renew cache file
28
+ if(isset($_POST['renew_cache'])) {
29
+ add_action('init', array(RFBP::instance(), 'invalidate_cache'));
30
+ add_action('init', array(RFBP::instance(), 'get_posts'));
31
+ }
32
+
33
+ // maybe to facebook
34
+ if(isset($_GET['login_to_fb'])) {
35
+ $this->redirect_to_facebook();
36
+ }
37
+ }
38
+ }
39
+
40
+ private function redirect_to_facebook()
41
+ {
42
+ $fb = RFBP::api();
43
+ $loginUrl = $fb->getLoginUrl(array('scope' => array('read_stream'), 'redirect_uri' => get_admin_url(null, 'options-general.php?page=rfb-settings&logged_in=1')));
44
+
45
+ // check if headers have beent sent, otherwise redirect via JS
46
+ if(!headers_sent()) {
47
+ header("Location: {$loginUrl}");
48
+ exit;
49
+ } else {
50
+ ?>
51
+ <script type="text/javascript">
52
+ window.location.href = "<?php echo $loginUrl; ?>";
53
+ </script>
54
+ <noscript>
55
+ <meta http-equiv="refresh" content="0;url=<?php echo $loginUrl; ?>" />
56
+ </noscript>
57
+ <?php
58
+ }
59
+ }
60
+
61
+ public function get_settings()
62
+ {
63
+ return RFBP::instance()->get_settings();
64
+ }
65
+
66
+ public function register_settings() {
67
+ register_setting('rfb_settings_group', 'rfb_settings', array($this, 'sanitize_settings'));
68
+ }
69
+
70
+ public function sanitize_settings($opts)
71
+ {
72
+ $oldOptions = $this->get_settings();
73
+
74
+ // check to see if page ID has changed
75
+ // if so, invalidate cache
76
+ if($oldOptions['fb_id'] != $opts['fb_id'] || $opts['img_size'] != $oldOptions['img_size'] || $opts['app_id'] != $oldOptions['app_id'] || $opts['app_secret'] != $oldOptions['app_secret']) {
77
+ RFBP::instance()->invalidate_cache();
78
+ add_settings_error('rfb_settings', 'cache_invalidated', "Some settings have been changed which invalidated Recent Facebook Posts' cache file. The cache will automatically be updated or you can do it manually." . '<form action="'.admin_url('options-general.php?page=rfb-settings') . '" method="post"><input type="hidden" name="renew_cache" value="1" /><input type="submit" class="button-primary" value="Renew cache file" /></form>', 'updated');
79
+ }
80
+
81
+ $opts['cache_time'] = (int) $opts['cache_time'];
82
+ $opts['img_height'] = (int) $opts['img_height'];
83
+ $opts['img_width'] = (int) $opts['img_width'];
84
+ return $opts;
85
+ }
86
+
87
+ public function build_menu() {
88
+ $page = add_options_page('Recent Facebook Posts - Settings','Recent Facebook Posts','manage_options','rfb-settings', array($this, 'settings_page'));
89
+ }
90
+
91
+ public function load_css() {
92
+ wp_enqueue_style( 'rfb_admin_css', plugins_url('recent-facebook-posts/assets/css/admin.css') );
93
+ wp_enqueue_script( 'rfb_admin_js', plugins_url('recent-facebook-posts/assets/js/admin.js'), array('jquery'), null, true);
94
+ }
95
+
96
+ public function settings_page () {
97
+
98
+ $opts = $this->get_settings();
99
+ $curl = extension_loaded('curl');
100
+ $connected = false;
101
+
102
+ // only try to connect when curl is installed and app_id is given
103
+ if($curl && !empty($opts['app_id'])) {
104
+
105
+ $fb = RFBP::api();
106
+ $connected = $fb->getUser();
107
+
108
+ if($connected) {
109
+ try {
110
+ $try = $fb->api('/me');
111
+ } catch(Exception $e) {
112
+ $connected = false;
113
+ $apiError = $e;
114
+ }
115
+ }
116
+
117
+ }
118
+
119
+ // show user-friendly error message
120
+ if(!$curl) { $errorMessage = "This plugin needs the PHP cURL extension installed on your server. Please ask your webhost to enable the php_curl extension."; }
121
+ elseif(empty($opts['app_id'])) { $errorMessage = "This plugin needs a valid Application ID to work. Please fill it in below."; }
122
+ elseif(empty($opts['app_secret'])) { $errorMessage = "This plugin needs a valid Application Secret to work. Please fill it in below."; }
123
+ elseif(!$connected) {
124
+ $errorMessage = "The plugin is not connected to Facebook. Please <a class=\"button-primary\" href=\"". admin_url('options-general.php?page=rfb-settings&login_to_fb') ."\">connect</a>.";
125
+ } else {
126
+ // everything is fine!
127
+ $accessToken = $fb->getAccessToken();
128
+ update_option('rfb_access_token', $accessToken);
129
+
130
+ if(isset($_GET['logged_in'])) {
131
+ update_option('rfb_access_token_expiry_date', date("Ymd", strtotime("+60 days")));
132
+ $notice = "<strong>Login success!</strong> You succesfully connected the plugin with Facebook.";
133
+ } elseif(RFBP::instance()->cache_renewed) { $notice = "<strong>Cache renewed!</strong> You succesfully renewed the cache."; }
134
+ }
135
+
136
+
137
+ // check if cache directory is writable
138
+ $cacheDir = WP_CONTENT_DIR;
139
+ $cacheFile = WP_CONTENT_DIR . '/recent-facebook-posts.cache';
140
+
141
+ if(!is_writable($cacheDir)) {
142
+ $cacheError = 'The wp-content folder (<i>'. WP_CONTENT_DIR .'</i>) is not writable. Please set the folder permissions to 755.';
143
+ } elseif(file_exists($cacheFile) && !is_writable($cacheFile)) {
144
+ $cacheError = 'The cache file (<i>'. $cacheFile .'</i>) exists but is not writable. Please set the file permissions to 755.';
145
+ }
146
+
147
+ include_once RFBP_PLUGIN_DIR . 'includes/views/settings_page.html.php';
148
+ }
149
+
150
+ public function show_admin_notice()
151
+ {
152
+ ?>
153
+ <div class="updated">
154
+ <p>Your Facebook access token for <a href="<?php echo admin_url('options-general.php?page-rfb-settings'); ?>">Recent Facebook Posts</a> expires in less than 14 days. Please renew it. <a class="primary-button" href="<?php echo admin_url('options-general.php?page=rfb-settings&login_to_fb'); ?>">Renew token</a></p>
155
+ </div>
156
+ <?php
157
+ }
158
+
159
+ /**
160
+ * Adds the settings link on the plugin's overview page
161
+ * @param array $links Array containing all the settings links for the various plugins.
162
+ * @return array The new array containing all the settings links
163
+ */
164
+ function add_settings_link($links) {
165
+ $settings_link = '<a href="options-general.php?page=rfb-settings">Settings</a>';
166
+ array_unshift($links, $settings_link);
167
+
168
+ return $links;
169
+ }
170
+ }
classes/class-rfb-widget.php → includes/RFBP_Widget.php RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- class RFB_Widget extends WP_Widget {
4
 
5
  private $defaults = array(
6
  'title' => 'Recent Facebook posts',
@@ -24,11 +24,10 @@ class RFB_Widget extends WP_Widget {
24
  $instance = array_merge($this->defaults, $instance);
25
  extract($instance);
26
 
27
- global $RFB;
28
- $rfb_options = $RFB->get_options();
29
 
30
  if(empty($rfb_options['app_id'])) { ?>
31
- <p style="color:red;">You'll need to <a href="<?php echo get_admin_url(null, 'options-general.php?page=rfb-settings'); ?>">configure Recent Facebook Posts</a> in order for it to work.</p>
32
  <?php } ?>
33
  <p>
34
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
@@ -76,22 +75,30 @@ class RFB_Widget extends WP_Widget {
76
  return $instance;
77
  }
78
 
79
- public function widget( $args, $instance ) {
80
- global $RFB;
81
 
82
- $opts = $RFB->get_options();
83
- $posts = $RFB->get_posts();
 
 
84
  $posts = array_slice($posts, 0, $instance['number_of_posts']);
85
 
86
- extract( $args );
 
 
87
  $instance = array_merge($this->defaults, $instance);
 
88
  extract($instance);
 
89
 
90
  $title = apply_filters( 'widget_title', $instance['title'] );
91
 
92
  echo $before_widget;
93
  if ( ! empty( $title ) )
94
  echo $before_title . $title . $after_title; ?>
 
 
 
95
  <ul class="rfb_posts">
96
  <?php foreach($posts as $post) { ?>
97
  <?php
@@ -108,18 +115,18 @@ class RFB_Widget extends WP_Widget {
108
 
109
  ?>
110
  <li>
111
- <p class="rfb_text"><?php echo nl2br(make_clickable($content)); if($shortened) echo '..'; ?></p>
112
  <?php
113
  if($opts['img_size'] != 'dont_show' && isset($post['image']) && $post['image']) {
114
 
115
  if(isset($post['type']) && $post['type'] == 'photo') {
116
- $img_atts = "src=\"{$post['image']}?type={$opts['img_size']}\" style=\"max-height: {$opts['img_height']}px;\"";
117
  } else {
118
  $img_atts = "src=\"{$post['image']}\" style=\"\"";
119
  }
120
  ?>
121
  <p class="rfb_image">
122
- <a target="_blank" href="<?php echo $post['link']; ?>" rel="nofollow">
123
 
124
  <img <?php echo $img_atts; ?> alt="" />
125
  </a>
@@ -127,12 +134,12 @@ class RFB_Widget extends WP_Widget {
127
  <?php } ?>
128
 
129
 
130
- <p><a target="_blank" class="rfb_link" href="<?php echo $post['link']; ?>" rel="nofollow">
131
  <?php if($show_like_count || $show_comment_count) { ?><span class="like_count_and_comment_count"><?php } ?>
132
  <?php if($show_like_count) { ?><span class="like_count"><?php echo $post['like_count']; ?> <span>likes</span></span> <?php } ?>
133
  <?php if($show_comment_count) { ?><span class="comment_count"><?php echo $post['comment_count']; ?> <span>comments</span></span> <?php } ?>
134
  <?php if($show_like_count || $show_comment_count) { ?></span><?php } ?>
135
- <span class="timestamp" title="<?php echo date('l, F j, Y', $post['timestamp']) . ' at ' . date('G:i', $post['timestamp']); ?>" ><?php if($show_like_count || $show_comment_count) { ?> · <?php } ?><span><?php echo $RFB->time_ago($post['timestamp']); ?></span></span>
136
  </a></p>
137
  </li>
138
  <?php }
@@ -140,16 +147,18 @@ class RFB_Widget extends WP_Widget {
140
  if(empty($posts)) { ?>
141
  <li>
142
  <p>No recent Facebook status updates to show.</p>
143
- <?php if(current_user_can('manage_options')) { ?><p><strong>Admins only notice:</strong> Did you <a href="<?php echo get_admin_url(null,'options-general.php?page=rfb-settings'); ?>">configure the plugin</a> properly?<?php } ?></p>
144
  </li>
145
 
146
  <?php } ?>
147
  </ul>
148
 
149
  <?php if($show_link) { ?>
150
- <p><a href="http://www.facebook.com/<?php echo $opts['fb_id']; ?>/" rel="external nofollow" <?php if($opts['link_new_window']) { ?>target="_blank"<?php } ?>><?php echo strip_tags($opts['link_text']); ?></a>.</p>
151
  <?php } ?>
152
 
 
 
153
  <?php
154
 
155
  echo $after_widget;
1
  <?php
2
 
3
+ class RFBP_Widget extends WP_Widget {
4
 
5
  private $defaults = array(
6
  'title' => 'Recent Facebook posts',
24
  $instance = array_merge($this->defaults, $instance);
25
  extract($instance);
26
 
27
+ $rfb_options = RFBP::instance()->get_settings();
 
28
 
29
  if(empty($rfb_options['app_id'])) { ?>
30
+ <p style="color:red;">You'll need to <a href="<?php echo get_admin_url(null, 'options-general.php?page=rfb-settings'); ?>">configure Recent Facebook Posts</a> first before this will work.</p>
31
  <?php } ?>
32
  <p>
33
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
75
  return $instance;
76
  }
77
 
78
+ public function widget( $args, $instance = array()) {
 
79
 
80
+ $opts = RFBP::instance()->get_settings();
81
+ $posts = RFBP::instance()->get_posts();
82
+
83
+ // slice posts to number set by user
84
  $posts = array_slice($posts, 0, $instance['number_of_posts']);
85
 
86
+ // set link target
87
+ $link_target = ($opts['link_new_window']) ? "_blank" : '';
88
+
89
  $instance = array_merge($this->defaults, $instance);
90
+
91
  extract($instance);
92
+ extract( $args );
93
 
94
  $title = apply_filters( 'widget_title', $instance['title'] );
95
 
96
  echo $before_widget;
97
  if ( ! empty( $title ) )
98
  echo $before_title . $title . $after_title; ?>
99
+
100
+ <!-- Recent Facebook Posts v<?php echo RFBP_VERSION; ?> - http://wordpress.org/plugins/recent-facebook-posts/ -->
101
+
102
  <ul class="rfb_posts">
103
  <?php foreach($posts as $post) { ?>
104
  <?php
115
 
116
  ?>
117
  <li>
118
+ <p class="rfb_text"><?php echo nl2br(rfbp_make_clickable($content, $link_target)); if($shortened) echo '..'; ?></p>
119
  <?php
120
  if($opts['img_size'] != 'dont_show' && isset($post['image']) && $post['image']) {
121
 
122
  if(isset($post['type']) && $post['type'] == 'photo') {
123
+ $img_atts = "src=\"{$post['image']}\" style=\"width:auto; max-height: {$opts['img_height']}px;\"";
124
  } else {
125
  $img_atts = "src=\"{$post['image']}\" style=\"\"";
126
  }
127
  ?>
128
  <p class="rfb_image">
129
+ <a target="<?php echo $link_target; ?>" href="<?php echo $post['link']; ?>" rel="nofollow">
130
 
131
  <img <?php echo $img_atts; ?> alt="" />
132
  </a>
134
  <?php } ?>
135
 
136
 
137
+ <p><a target="<?php echo $link_target; ?>" class="rfb_link" href="<?php echo $post['link']; ?>" rel="nofollow">
138
  <?php if($show_like_count || $show_comment_count) { ?><span class="like_count_and_comment_count"><?php } ?>
139
  <?php if($show_like_count) { ?><span class="like_count"><?php echo $post['like_count']; ?> <span>likes</span></span> <?php } ?>
140
  <?php if($show_comment_count) { ?><span class="comment_count"><?php echo $post['comment_count']; ?> <span>comments</span></span> <?php } ?>
141
  <?php if($show_like_count || $show_comment_count) { ?></span><?php } ?>
142
+ <span class="timestamp" title="<?php echo date('l, F j, Y', $post['timestamp']) . ' at ' . date('G:i', $post['timestamp']); ?>" ><?php if($show_like_count || $show_comment_count) { ?> · <?php } ?><span><?php echo rfbp_time_ago($post['timestamp']); ?></span></span>
143
  </a></p>
144
  </li>
145
  <?php }
147
  if(empty($posts)) { ?>
148
  <li>
149
  <p>No recent Facebook status updates to show.</p>
150
+ <?php if(current_user_can('manage_options')) { ?><p><strong>Admins only notice:</strong> Did you <a href="<?php echo admin_url('options-general.php?page=rfb-settings'); ?>">configure the plugin</a> properly?<?php } ?></p>
151
  </li>
152
 
153
  <?php } ?>
154
  </ul>
155
 
156
  <?php if($show_link) { ?>
157
+ <p><a href="http://www.facebook.com/<?php echo $opts['fb_id']; ?>/" rel="external nofollow" target="<?php echo $link_target; ?>"><?php echo strip_tags($opts['link_text']); ?></a>.</p>
158
  <?php } ?>
159
 
160
+ <!-- / Recent Facebook Posts -->
161
+
162
  <?php
163
 
164
  echo $after_widget;
{classes → includes}/facebook-php-sdk/base_facebook.php RENAMED
@@ -120,7 +120,7 @@ abstract class BaseFacebook
120
  /**
121
  * Version.
122
  */
123
- const VERSION = '3.2.0';
124
 
125
  /**
126
  * Signed Request Algorithm.
@@ -367,20 +367,20 @@ abstract class BaseFacebook
367
  // In any event, we don't have an access token, so say so.
368
  return false;
369
  }
370
-
371
  if (empty($access_token_response)) {
372
  return false;
373
  }
374
-
375
  $response_params = array();
376
  parse_str($access_token_response, $response_params);
377
-
378
  if (!isset($response_params['access_token'])) {
379
  return false;
380
  }
381
-
382
  $this->destroySession();
383
-
384
  $this->setPersistentData(
385
  'access_token', $response_params['access_token']
386
  );
@@ -439,6 +439,11 @@ abstract class BaseFacebook
439
  // the JS SDK puts a code in with the redirect_uri of ''
440
  if (array_key_exists('code', $signed_request)) {
441
  $code = $signed_request['code'];
 
 
 
 
 
442
  $access_token = $this->getAccessTokenFromCode($code, '');
443
  if ($access_token) {
444
  $this->setPersistentData('code', $code);
@@ -483,10 +488,10 @@ abstract class BaseFacebook
483
  */
484
  public function getSignedRequest() {
485
  if (!$this->signedRequest) {
486
- if (isset($_REQUEST['signed_request'])) {
487
  $this->signedRequest = $this->parseSignedRequest(
488
  $_REQUEST['signed_request']);
489
- } else if (isset($_COOKIE[$this->getSignedRequestCookieName()])) {
490
  $this->signedRequest = $this->parseSignedRequest(
491
  $_COOKIE[$this->getSignedRequestCookieName()]);
492
  }
@@ -524,6 +529,11 @@ abstract class BaseFacebook
524
  if ($signed_request) {
525
  if (array_key_exists('user_id', $signed_request)) {
526
  $user = $signed_request['user_id'];
 
 
 
 
 
527
  $this->setPersistentData('user_id', $signed_request['user_id']);
528
  return $user;
529
  }
@@ -889,6 +899,10 @@ abstract class BaseFacebook
889
  $params['access_token'] = $this->getAccessToken();
890
  }
891
 
 
 
 
 
892
  // json_encode all params values that are not strings
893
  foreach ($params as $key => $value) {
894
  if (!is_string($value)) {
@@ -899,6 +913,19 @@ abstract class BaseFacebook
899
  return $this->makeRequest($url, $params);
900
  }
901
 
 
 
 
 
 
 
 
 
 
 
 
 
 
902
  /**
903
  * Makes an HTTP request. This method can be overridden by subclasses if
904
  * developers want to do fancier things or use something other than curl to
@@ -1143,10 +1170,16 @@ abstract class BaseFacebook
1143
  }
1144
  return 'http';
1145
  }
 
1146
  if (isset($_SERVER['HTTPS']) &&
1147
  ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {
1148
  return 'https';
1149
  }
 
 
 
 
 
1150
  return 'http';
1151
  }
1152
 
120
  /**
121
  * Version.
122
  */
123
+ const VERSION = '3.2.2';
124
 
125
  /**
126
  * Signed Request Algorithm.
367
  // In any event, we don't have an access token, so say so.
368
  return false;
369
  }
370
+
371
  if (empty($access_token_response)) {
372
  return false;
373
  }
374
+
375
  $response_params = array();
376
  parse_str($access_token_response, $response_params);
377
+
378
  if (!isset($response_params['access_token'])) {
379
  return false;
380
  }
381
+
382
  $this->destroySession();
383
+
384
  $this->setPersistentData(
385
  'access_token', $response_params['access_token']
386
  );
439
  // the JS SDK puts a code in with the redirect_uri of ''
440
  if (array_key_exists('code', $signed_request)) {
441
  $code = $signed_request['code'];
442
+ if ($code && $code == $this->getPersistentData('code')) {
443
+ // short-circuit if the code we have is the same as the one presented
444
+ return $this->getPersistentData('access_token');
445
+ }
446
+
447
  $access_token = $this->getAccessTokenFromCode($code, '');
448
  if ($access_token) {
449
  $this->setPersistentData('code', $code);
488
  */
489
  public function getSignedRequest() {
490
  if (!$this->signedRequest) {
491
+ if (!empty($_REQUEST['signed_request'])) {
492
  $this->signedRequest = $this->parseSignedRequest(
493
  $_REQUEST['signed_request']);
494
+ } else if (!empty($_COOKIE[$this->getSignedRequestCookieName()])) {
495
  $this->signedRequest = $this->parseSignedRequest(
496
  $_COOKIE[$this->getSignedRequestCookieName()]);
497
  }
529
  if ($signed_request) {
530
  if (array_key_exists('user_id', $signed_request)) {
531
  $user = $signed_request['user_id'];
532
+
533
+ if($user != $this->getPersistentData('user_id')){
534
+ $this->clearAllPersistentData();
535
+ }
536
+
537
  $this->setPersistentData('user_id', $signed_request['user_id']);
538
  return $user;
539
  }
899
  $params['access_token'] = $this->getAccessToken();
900
  }
901
 
902
+ if (isset($params['access_token'])) {
903
+ $params['appsecret_proof'] = $this->getAppSecretProof($params['access_token']);
904
+ }
905
+
906
  // json_encode all params values that are not strings
907
  foreach ($params as $key => $value) {
908
  if (!is_string($value)) {
913
  return $this->makeRequest($url, $params);
914
  }
915
 
916
+ /**
917
+ * Generate a proof of App Secret
918
+ * This is required for all API calls originating from a server
919
+ * It is a sha256 hash of the access_token made using the app secret
920
+ *
921
+ * @param string $access_token The access_token to be hashed (required)
922
+ *
923
+ * @return string The sha256 hash of the access_token
924
+ */
925
+ protected function getAppSecretProof($access_token) {
926
+ return hash_hmac('sha256', $access_token, $this->getAppSecret());
927
+ }
928
+
929
  /**
930
  * Makes an HTTP request. This method can be overridden by subclasses if
931
  * developers want to do fancier things or use something other than curl to
1170
  }
1171
  return 'http';
1172
  }
1173
+ /*apache + variants specific way of checking for https*/
1174
  if (isset($_SERVER['HTTPS']) &&
1175
  ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {
1176
  return 'https';
1177
  }
1178
+ /*nginx way of checking for https*/
1179
+ if (isset($_SERVER['SERVER_PORT']) &&
1180
+ ($_SERVER['SERVER_PORT'] === '443')) {
1181
+ return 'https';
1182
+ }
1183
  return 'http';
1184
  }
1185
 
{classes → includes}/facebook-php-sdk/facebook.php RENAMED
File without changes
includes/facebook-php-sdk/fb_ca_chain_bundle.crt ADDED
@@ -0,0 +1,3920 @@