PluginProbe ʕ •ᴥ•ʔ
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress / 4.12.0
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress v4.12.0
4.12.0 4.10.0 4.9.0 4.8.1 trunk 1.0 1.1 1.12.1 1.2.3 1.2.4 1.2.5 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.5 1.5.1 1.5.2 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.5.1 1.6.6 1.6.6.1 1.6.6.2 1.6.6.3 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.9.0 1.9.1 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.8.1 1.9.9 1.9.9.1 1.9.9.2 1.9.9.3 2.0 2.0.1 2.1 2.1.1 2.1.2 2.1.3 2.10 2.11 2.11.1 2.12 2.12.1 2.12.2 2.12.3 2.12.4 2.13 2.14 2.14.1 2.15 2.15.1 2.16 2.16.1 2.17 2.17.1 2.18 2.18.1 2.18.2 2.18.3 2.19 2.19.1 2.19.2 2.19.3 2.2 2.2.1 2.3 2.3.1 2.3.10 2.3.2 2.3.3 2.3.4 2.3.6 2.3.7 2.3.8 2.3.9 2.4 2.4.1 2.4.1.1 2.4.1.2 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5 2.5.1 2.5.2 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.7 2.7.1 2.7.2 2.8 2.9 2.9.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.7.5 4.7.6 4.7.7
custom-facebook-feed / inc / CFF_Shortcode.php
custom-facebook-feed / inc Last commit date
Admin 2 weeks ago Builder 2 weeks ago Helpers 2 weeks ago Integrations 2 weeks ago UsageTracking 2 weeks ago CFF_Autolink.php 2 weeks ago CFF_Blocks.php 2 weeks ago CFF_Cache.php 2 weeks ago CFF_Education.php 2 weeks ago CFF_Elementor_Base.php 2 weeks ago CFF_Elementor_Widget.php 2 weeks ago CFF_Error_Reporter.php 2 weeks ago CFF_FB_Settings.php 2 weeks ago CFF_Feed_Elementor_Control.php 2 weeks ago CFF_Feed_Locator.php 2 weeks ago CFF_Feed_Pro.php 2 weeks ago CFF_GDPR_Integrations.php 2 weeks ago CFF_Group_Posts.php 2 weeks ago CFF_HTTP_Request.php 2 weeks ago CFF_Oembed.php 2 weeks ago CFF_Parse.php 2 weeks ago CFF_Resizer.php 2 weeks ago CFF_Response.php 2 weeks ago CFF_Shortcode.php 2 weeks ago CFF_Shortcode_Display.php 2 weeks ago CFF_SiteHealth.php 2 weeks ago CFF_Utils.php 2 weeks ago CFF_View.php 2 weeks ago Custom_Facebook_Feed.php 2 weeks ago Email_Notification.php 2 weeks ago Platform_Data.php 2 weeks ago SB_Facebook_Data_Encryption.php 2 weeks ago SB_Facebook_Data_Manager.php 2 weeks ago index.php 2 weeks ago
CFF_Shortcode.php
2053 lines
1 <?php
2
3 /**
4 * Custom Facebook Feed Main Shortcode Class
5 *
6 * @since 2.19
7 */
8
9 namespace CustomFacebookFeed;
10
11 use CustomFacebookFeed\Builder\CFF_Source;
12 use CustomFacebookFeed\Integrations\CFF_Graph_Data;
13 use CustomFacebookFeed\SB_Facebook_Data_Encryption;
14
15 if (! defined('ABSPATH')) {
16 die('-1');
17 }
18
19 class CFF_Shortcode extends CFF_Shortcode_Display
20 {
21 /**
22 * @var Class
23 */
24 protected $fb_feed_settings;
25
26 /**
27 * @var array
28 */
29 protected $atts;
30
31 /**
32 * @var array
33 */
34 protected $options;
35
36 /**
37 * @var id
38 */
39 protected $page_id;
40
41 /**
42 * @var string
43 */
44 protected $access_token;
45
46 /**
47 * @var string
48 */
49 protected $feed_id;
50
51
52 /**
53 * Shortcode constructor
54 *
55 * @since 2.19
56 */
57 public function __construct()
58 {
59 $this->init();
60 }
61
62
63
64 /**
65 * Init.
66 *
67 * @since 2.19
68 */
69 public function init()
70 {
71 add_shortcode('custom-facebook-feed', array($this, 'display_cff'));
72 }
73
74
75 /**
76 * Get JSON data
77 *
78 * Returns a list of posts JSON form the FaceBook API API
79 *
80 * @since 2.19
81 * @return JSON OBJECT
82 */
83 public function get_feed_json($graph_query, $cff_post_limit, $cff_locale, $cff_show_access_token, $cache_seconds, $cff_cache_time, $show_posts_by, $data_att_html)
84 {
85 // Is it SSL?
86 $cff_ssl = is_ssl() ? '&return_ssl_resources=true' : '';
87 $attachments_desc = ( $this->atts['salesposts'] == 'true' ) ? '' : ',description';
88 $story_tags = ( $this->atts['storytags'] == 'true' ) ? '' : ',story_tags';
89
90 $cff_posts_json_url = 'https://graph.facebook.com/v23.0/' . $this->page_id . '/' . $graph_query . '?fields=id,updated_time,from{picture,id,name,link},message,message_tags,story' . $story_tags . ',status_type,created_time,backdated_time,call_to_action,attachments{title' . $attachments_desc . ',media_type,unshimmed_url,target{id},media{source}}&access_token=' . $this->access_token . '&limit=' . $cff_post_limit . '&locale=' . $cff_locale . $cff_ssl;
91 // Create the transient name
92 // Split the Page ID in half and stick it together so we definitely have the beginning and end of it
93 $trans_page_id = substr($this->page_id, 0, 16) . substr($this->page_id, -15);
94 $transient_name = 'cff_' . substr($graph_query, 0, 1) . '_' . $trans_page_id . substr($cff_post_limit, 0, 3) . substr($show_posts_by, 0, 2) . substr($cff_locale, 0, 2);
95 // Limit to 45 chars max
96 $transient_name = substr($transient_name, 0, 45);
97
98 $posts_json = CFF_Utils::cff_get_set_cache($cff_posts_json_url, $transient_name, $cff_cache_time, $cache_seconds, $data_att_html, false, $this->access_token, true);
99
100 return json_decode($posts_json);
101 }
102
103
104 /**
105 * Get Graph Query & (Show only by others)
106 *
107 * Getting the FaceBook Graph Query depending on the settings
108 *
109 * @since 2.19
110 * @return array
111 */
112 public function get_graph_query($show_posts_by, $cff_is_group)
113 {
114 // Use posts? or feed?
115 $old_others_option = get_option('cff_show_others'); // Use this to help depreciate the old option
116 $show_others = $this->atts['others'];
117 $graph_query = 'posts';
118 $cff_show_only_others = false;
119 // If 'others' shortcode option is used then it overrides any other option
120 if ($show_others || $old_others_option == 'on') {
121 // Show posts by everyone
122 if ($old_others_option == 'on' || $show_others == 'on' || $show_others == 'true' || $show_others == true || $cff_is_group) {
123 $graph_query = 'feed';
124 }
125 // Only show posts by me
126 if ($show_others == 'false') {
127 $graph_query = 'posts';
128 }
129 } else {
130 // Else use the settings page option or the 'showpostsby' shortcode option
131 // Only show posts by me
132 if ($show_posts_by == 'me') {
133 $graph_query = 'posts';
134 }
135 // Show posts by everyone
136 if ($show_posts_by == 'others' || $cff_is_group) {
137 $graph_query = 'feed';
138 }
139 // Show posts ONLY by others
140 if ($show_posts_by == 'onlyothers' && !$cff_is_group) {
141 $graph_query = 'visitor_posts';
142 $cff_show_only_others = true;
143 }
144 }
145
146 return [
147 'graph_query' => $graph_query,
148 'cff_show_only_others' => $cff_show_only_others
149 ];
150 }
151
152
153 /**
154 * Get Posts Limit
155 *
156 * Getting the FaceBook Graph Query depending on the settings
157 *
158 * @since 2.19
159 * @return int
160 */
161 public function get_post_limit($show_posts)
162 {
163 $cff_post_limit = $this->atts['limit'];
164 if (!isset($cff_post_limit) || empty($cff_post_limit)) {
165 if (intval($show_posts) >= 50) {
166 $cff_post_limit = intval(intval($show_posts) + 7);
167 }
168 if (intval($show_posts) < 50) {
169 $cff_post_limit = intval(intval($show_posts) + 5);
170 }
171 if (intval($show_posts) < 25) {
172 $cff_post_limit = intval(intval($show_posts) + 4);
173 }
174 if (intval($show_posts) < 10) {
175 $cff_post_limit = intval(intval($show_posts) + 3);
176 }
177 if (intval($show_posts) < 6) {
178 $cff_post_limit = intval(intval($show_posts) + 2);
179 }
180 if (intval($show_posts) < 2) {
181 $cff_post_limit = intval(intval($show_posts) + 1);
182 }
183 }
184 if ($cff_post_limit >= 100) {
185 $cff_post_limit = 100;
186 }
187 return $cff_post_limit;
188 }
189
190
191 public function cff_get_shortcode_data_attribute_html($feed_options)
192 {
193
194 // If an access token is set in the shortcode then set "use own access token" to be enabled
195 if (isset($feed_options['accesstoken'])) {
196 $feed_options['ownaccesstoken'] = 'on';
197 }
198
199 if (!empty($feed_options)) {
200 $json_data = '{';
201 $i = 0;
202 $len = count($feed_options);
203 foreach ($feed_options as $key => $value) {
204 if ($i == $len - 1) {
205 $json_data .= '&quot;' . esc_attr($key) . '&quot;: &quot;' . esc_attr($value) . '&quot;';
206 } else {
207 $json_data .= '&quot;' . esc_attr($key) . '&quot;: &quot;' . esc_attr($value) . '&quot;, ';
208 }
209 $i++;
210 }
211 $json_data .= '}';
212
213 return $json_data;
214 }
215 }
216
217 public function cff_get_processed_options($feed_options)
218 {
219 $feed_id = empty($feed_options['feed']) ? 'default' : intval($feed_options['feed']);
220 $feed_options = $this->get_settings_for_feed($feed_options);
221
222 if (empty($feed_options)) {
223 $options = get_option('cff_style_settings');
224 $fdo = new CFF_FB_Settings($feed_options, $options);
225 $feed_options = $fdo->get_settings();
226 $feed_options['feederror'] = $feed_id;
227 return $feed_options;
228 }
229
230 $page_id = is_array($feed_options['id']) ? implode('', $feed_options['id']) : $feed_options['id'];
231 if (empty($page_id) || is_null($page_id)) {
232 return;
233 }
234
235 $cff_facebook_string = 'facebook.com';
236 ( stripos($page_id, $cff_facebook_string) !== false) ? $cff_page_id_url_check = true : $cff_page_id_url_check = false;
237 if ($cff_page_id_url_check === true && !empty($page_id)) {
238 // Remove trailing slash if exists
239 $page_id = preg_replace('{/$}', '', $page_id);
240 // Get last part of url
241 $page_id = substr($page_id, strrpos($page_id, '/') + 1);
242 }
243 // If the Page ID contains a query string at the end then remove it
244 if (stripos($page_id, '?') !== false) {
245 $page_id = substr($page_id, 0, strrpos($page_id, '?'));
246 }
247 // If the Page ID contains a query string at the end then remove it
248 if (!empty($page_id) && stripos($page_id, '?') !== false) {
249 $page_id = substr($page_id, 0, strrpos($page_id, '?'));
250 }
251
252 // Always remove slash from end of Page ID
253 $page_id = preg_replace('{/$}', '', $page_id);
254
255 // Update the page ID in the feed options array for use everywhere
256 $feed_options['id'] = $page_id;
257
258
259 // If an 'account' is specified then use that instead of the Page ID/token from the settings
260 $cff_account = trim($feed_options['account']);
261
262 if (!empty($cff_account)) {
263 $cff_connected_accounts = get_option('cff_connected_accounts');
264 if (!empty($cff_connected_accounts)) {
265 // Replace both single and double quotes before decoding
266 $cff_connected_accounts = str_replace('\"', '"', $cff_connected_accounts);
267 $cff_connected_accounts = str_replace("\'", "'", $cff_connected_accounts);
268
269 $cff_connected_accounts = json_decode($cff_connected_accounts);
270
271 if (isset($cff_account) && is_object($cff_connected_accounts)) {
272 // Grab the ID and token from the connected accounts setting
273 if (isset($cff_connected_accounts->{ $cff_account })) {
274 $feed_options['id'] = $cff_connected_accounts->{ $cff_account }->{'id'};
275 $feed_options['accesstoken'] = $cff_connected_accounts->{ $cff_account }->{'accesstoken'};
276 }
277 }
278 }
279 }
280
281
282 $cff_connected_accounts = get_option('cff_connected_accounts');
283 if (!empty($cff_connected_accounts)) {
284 $connected_accounts = (array)json_decode(stripcslashes($cff_connected_accounts));
285 if (array_key_exists($feed_options['id'], $connected_accounts)) {
286 $feed_options['pagetype'] = $connected_accounts[$feed_options['id']]->pagetype;
287 }
288 }
289
290 if (! empty($feed_options['feedlayout'])) {
291 if ($feed_options['feedlayout'] === 'list') {
292 $feed_options['cols'] = 1;
293 $feed_options['colsmobile'] = 1;
294 $feed_options['colstablet'] = 1;
295 $feed_options['masonrycols'] = 1;
296 $feed_options['masonrycolsmobile'] = 1;
297 } elseif ($feed_options['feedlayout'] === 'masonry') {
298 $feed_options['masonrycols'] = $feed_options['cols'] ;
299 $feed_options['masonrycolsmobile'] = $feed_options['colsmobile'];
300 }
301 }
302
303 return $feed_options;
304 }
305
306 /**
307 * Display.
308 * The main Shortcode display
309 *
310 * @since 2.19
311 */
312 public function display_cff($atts)
313 {
314 do_action('cff_before_display_facebook');
315 $this->options = get_option('cff_style_settings');
316 $data_att_html = $this->cff_get_shortcode_data_attribute_html($atts);
317 $feed_id = empty($atts['feed']) ? 'default' : intval($atts['feed']);
318 $feed_options = $this->get_settings_for_feed($atts);
319
320 if (empty($feed_options)) {
321 $this->fb_feed_settings = new CFF_FB_Settings($atts, $this->options);
322 $this->atts = $this->fb_feed_settings->get_settings();
323 $id_and_token = $this->fb_feed_settings->get_id_and_token();
324 $this->page_id = $id_and_token['id'];
325
326 $encryption = new SB_Facebook_Data_Encryption();
327 $this->access_token = $encryption->decrypt($id_and_token['token']) ? $encryption->decrypt($id_and_token['token']) : $id_and_token['token'];
328
329 $this->atts = $this->cff_get_processed_options($this->atts);
330 } else {
331 if (! empty($feed_options['feedlayout'])) {
332 if ($feed_options['feedlayout'] === 'list') {
333 $feed_options['cols'] = 1;
334 $feed_options['colsmobile'] = 1;
335 $feed_options['colstablet'] = 1;
336 $feed_options['masonrycols'] = 1;
337 $feed_options['masonrycolsmobile'] = 1;
338 } elseif ($feed_options['feedlayout'] === 'masonry') {
339 $feed_options['masonrycols'] = $feed_options['cols'] ;
340 $feed_options['masonrycolsmobile'] = $feed_options['colsmobile'];
341 }
342 }
343
344
345 $this->atts = $feed_options;
346 }
347
348 if (empty($this->atts['sources']) || $this->atts['sources'] === null) {
349 return;
350 }
351
352 $this->cff_add_translations();
353
354
355 // Vars for the templates
356 $atts = $this->atts;
357 $options = $this->options;
358 $access_token = $this->access_token;
359 $page_id = $this->page_id;
360
361 if ($atts['cff_enqueue_with_shortcode'] === 'on' || $atts['cff_enqueue_with_shortcode'] === 'true') {
362 wp_enqueue_style('cff');
363 wp_enqueue_script('cffscripts');
364 }
365
366 $palette = '';
367 $custom_palette_class = '';
368 $doing_custom_styles = false;
369
370 if (! empty($this->atts['colorpalette'])) {
371 switch ($this->atts['colorpalette']) {
372 case 'dark':
373 $palette = 'cff-dark ';
374 break;
375 case 'light':
376 $palette = 'cff-light ';
377 break;
378 case 'custom':
379 $doing_custom_styles = true;
380 $custom_palette_class = 'cff-palette-' . $feed_id . ' ';
381 break;
382 default:
383 $palette = '';
384 }
385 }
386
387 $this->atts['paletteclass'] = $palette . $custom_palette_class;
388
389 /********** GENERAL */
390 $cff_page_type = $this->atts[ 'pagetype' ];
391 ($cff_page_type == 'group') ? $cff_is_group = true : $cff_is_group = false;
392
393
394 $cff_show_author = $this->atts[ 'showauthornew' ];
395 $cff_cache_time = $this->atts[ 'cachetime' ];
396 $cff_locale = $this->atts[ 'locale' ];
397 if (empty($cff_locale) || !isset($cff_locale) || $cff_locale == '') {
398 $cff_locale = 'en_US';
399 }
400 if (!isset($cff_cache_time) || $cff_cache_time == '') {
401 $cff_cache_time = 0;
402 }
403 $cff_cache_time_unit = $this->atts[ 'cacheunit' ];
404
405 $like_box = CFF_Utils::print_template_part('likebox', get_defined_vars());
406
407
408 if ($cff_cache_time == 'nocaching') {
409 $cff_cache_time = 0;
410 }
411
412 // Like box
413 $cff_like_box_position = $this->atts[ 'likeboxpos' ];
414 $cff_like_box_outside = CFF_Utils::check_if_on($this->atts[ 'likeboxoutside' ]);
415 // Open links in new window?
416 $target = 'target="_blank"';
417 /********** LAYOUT */
418 $cff_show_author = $this->check_show_section('author');
419 $cff_show_text = $this->check_show_section('text');
420 $cff_show_desc = $this->check_show_section('desc');
421 $cff_show_shared_links = $this->check_show_section('sharedlink');
422 $cff_show_date = $this->check_show_section('date');
423 $cff_show_media = $this->check_show_section('media');
424 $cff_show_media_link = $this->check_show_section('medialink');
425 $cff_show_event_title = $this->check_show_section('eventtitle');
426 $cff_show_event_details = $this->check_show_section('eventdetail');
427 $cff_show_meta = $this->check_show_section('social');
428 $cff_show_link = $this->check_show_section(',link');
429 $cff_show_like_box = isset($this->atts['showlikebox']) ? CFF_Utils::check_if_on($this->atts['showlikebox']) : false;
430
431 // Set free version to thumb layout by default as layout option not available on settings page
432 $cff_preset_layout = 'thumb';
433
434 // If the old shortcode option 'showauthor' is being used then apply it
435 $cff_show_author_old = $this->atts[ 'showauthor' ];
436 if ($cff_show_author_old == 'false') {
437 $cff_show_author = false;
438 }
439 if ($cff_show_author_old == 'true') {
440 $cff_show_author = true;
441 }
442
443 // See Less text
444 // Constrain to a hex colour at the source — this value feeds multiple
445 // style="..." attributes below.
446 $cff_posttext_link_color_raw = ltrim( (string) $this->atts['textlinkcolor'], '#' );
447 $cff_posttext_link_color = preg_match( '/^[0-9a-fA-F]{3,8}$/', $cff_posttext_link_color_raw ) ? $cff_posttext_link_color_raw : '';
448 $cff_title_link = CFF_Utils::check_if_on($this->atts['textlink']);
449
450 // Description Style
451 $cff_body_styles = $this->get_style_attribute('body_description');
452
453 // Shared link box
454 $cff_disable_link_box = CFF_Utils::check_if_on($this->atts['disablelinkbox']);
455
456 $cff_link_box_styles = $cff_disable_link_box ? '' : $this->get_style_attribute('link_box');
457
458 // Date
459 $cff_date_position = ( !isset($this->atts[ 'datepos' ]) ) ? 'below' : $this->atts[ 'datepos' ];
460
461
462 // Show Facebook link
463 $cff_link_to_timeline = $this->atts[ 'linktotimeline' ];
464
465 // Post Style settings
466 $cff_post_style = $this->atts['poststyle'];
467 $cff_post_bg_color_check = ($this->atts['postbgcolor'] !== '' && $this->atts['postbgcolor'] !== '#' && $cff_post_style != 'regular' ) ? true : false;
468 $cff_box_shadow = CFF_Utils::check_if_on($this->atts['boxshadow']) && $cff_post_style == 'boxed';
469
470 // Text limits
471 $body_limit = $this->atts['desclength'];
472
473 // Get show posts attribute. If not set then default to 25
474 $show_posts = ( empty($this->atts['num']) || $this->atts['num'] == 'undefined' ) ? 25 : $this->atts['num'];
475 $show_posts_number = isset($this->atts['minnum']) ? $this->atts['minnum'] : $this->atts['num'];
476
477 // If the 'Enter my own Access Token' box is unchecked then don't use the user's access token, even if there's one in the field
478 get_option('cff_show_access_token') ? $cff_show_access_token = true : $cff_show_access_token = false;
479
480 // Check whether a Page ID has been defined
481 if ($this->page_id == '') {
482 if ($this->using_legacy_feed($feed_options)) {
483 echo "Please enter the Page ID of the Facebook feed you'd like to display. You can do this in either the Custom Facebook Feed plugin settings or in the shortcode itself. For example, [custom-facebook-feed id=YOUR_PAGE_ID_HERE].<br /><br />";
484 }
485 return false;
486 }
487
488 // Is it a restricted page?
489 $cff_restricted_page = CFF_Utils::check_if_on($this->atts['restrictedpage']);
490
491 $show_posts_by = $this->atts['showpostsby'];
492 $graph_info = $this->get_graph_query($show_posts_by, $cff_is_group);
493 $graph_query = $graph_info['graph_query'];
494 $cff_show_only_others = $graph_info['cff_show_only_others'];
495
496
497
498
499 // If Mobile and Desktop post nums are not the same, use minnum for API requests.
500 $mobile_num = isset($this->atts['nummobile']) && (int)$this->atts['nummobile'] > 0 ? (int)$this->atts['nummobile'] : 0;
501 $desk_num = $show_posts;
502 if ($desk_num < $mobile_num) {
503 $this->atts['minnum'] = $mobile_num;
504 }
505
506 $show_posts = isset($this->atts['minnum']) ? $this->atts['minnum'] : $show_posts;
507 $cff_post_limit = $this->get_post_limit($show_posts);
508
509 // If the number of posts is set to zero then don't show any and set limit to one
510 if (($show_posts == '0' || $show_posts == 0) && $show_posts !== '') {
511 $show_posts = 0;
512 $cff_post_limit = 1;
513 }
514
515
516 // Calculate the cache time in seconds
517 if ($cff_cache_time_unit == 'minutes') {
518 $cff_cache_time_unit = 60;
519 }
520 if ($cff_cache_time_unit == 'hours') {
521 $cff_cache_time_unit = 60 * 60;
522 }
523 if ($cff_cache_time_unit == 'days') {
524 $cff_cache_time_unit = 60 * 60 * 24;
525 }
526 $cache_seconds = $cff_cache_time * $cff_cache_time_unit;
527
528
529
530
531 // Misc Settings
532 $cff_nofollow = CFF_Utils::check_if_on($this->atts['nofollow']);
533 ( $cff_nofollow ) ? $cff_nofollow = ' rel="nofollow noopener"' : $cff_nofollow = '';
534 $cff_nofollow_referrer = ' rel="nofollow noopener noreferrer"';
535
536 // If the number of posts is set to zero then don't show any and set limit to one
537 if (($this->atts['num'] == '0' || $this->atts['num'] == 0) && $this->atts['num'] !== '') {
538 $show_posts = 0;
539 $cff_post_limit = 1;
540 }
541
542 // ***START FEED***
543 // $defined_vars = get_defined_vars();
544 $cff_content = '';
545
546 // Create CFF container HTML
547 $cff_content .= '<div class="cff-wrapper">';
548 $cff_style_class = $this->feed_style_class_compiler();
549 $cff_insider_style = $this->get_style_attribute('feed_wrapper_insider');
550 $cff_feed_height = CFF_Utils::get_css_distance($this->atts[ 'height' ]) ;
551 // Feed header
552 $cff_show_header = CFF_Utils::check_if_on($this->atts['showheader']);
553 $cff_header_outside = CFF_Utils::check_if_on($this->atts['headeroutside']);
554 $cff_header_type = strtolower($this->atts['headertype']);
555 $cff_header = CFF_Utils::print_template_part('header', get_defined_vars(), $this);
556
557
558
559 // Add the page header to the outside of the top of feed
560 if ($cff_show_header && $cff_header_outside) {
561 $cff_content .= $cff_header;
562 }
563
564 // Add like box to the outside of the top of feed
565 if ($cff_like_box_position == 'top' && $cff_show_like_box && $cff_like_box_outside) {
566 $cff_content .= $like_box;
567 }
568
569
570 // Get Custom Class and Compiled CSS
571
572 $custom_wrp_class = !empty($cff_feed_height) ? ' cff-wrapper-fixed-height' : '';
573
574 $cff_content .= '<div class="cff-wrapper-ctn ' . $custom_wrp_class . '" ' . $cff_insider_style . '>';
575 $cff_content .= '<div id="cff" role="region" aria-label="' . esc_attr__('Facebook feed', 'custom-facebook-feed') . '" ' . $cff_style_class['cff_custom_class'] . ' ' . $cff_style_class['cff_feed_styles'] . ' ' . $cff_style_class['cff_feed_attributes'] . '>';
576
577 // Add the page header to the inside of the top of feed
578 if ($cff_show_header && !$cff_header_outside) {
579 $cff_content .= $cff_header;
580 }
581
582 // Add like box to the inside of the top of feed
583 if ($cff_like_box_position == 'top' && $cff_show_like_box && !$cff_like_box_outside) {
584 $cff_content .= $like_box;
585 }
586 // Limit var
587 $i_post = 0;
588
589 // Define array for post items
590 $cff_posts_array = array();
591 // ALL POSTS
592
593 // $FBdata = $this->get_feed_json( $graph_query, $cff_post_limit, $cff_locale, $cff_show_access_token, $cache_seconds, $cff_cache_time, $show_posts_by, $data_att_html );
594 $data_json = CFF_Shortcode::cff_get_json_data($this->atts, null, $data_att_html);
595 $FBdata = isset($data_json[$this->page_id]) ? $data_json[$this->page_id] : [];
596
597 global $current_user;
598 $user_id = $current_user->ID;
599
600 // Print Pretty Message Error
601 $cff_content .= CFF_Utils::print_template_part('error-message', get_defined_vars());
602
603 $numeric_page_id = '';
604 if (!empty($FBdata->data)) {
605 if (($cff_show_only_others || $show_posts_by == 'others') && count($FBdata->data) > 0) {
606 // Get the numeric ID of the page so can compare it to the author of each post
607 $first_post_id = explode("_", $FBdata->data[0]->id);
608 $numeric_page_id = $first_post_id[0];
609 }
610 }
611
612
613 $posts_wrap_box_shadow_class = $cff_box_shadow && $this->atts['feedlayout'] === 'list' ? ' cff-posts-wrap-box-shadow' : '';
614 $cff_content .= '<div class="cff-posts-wrap' . $posts_wrap_box_shadow_class . '" role="list">';
615
616 // ***STARTS POSTS LOOP***
617 if (isset($FBdata->data)) {
618 if (
619 ! \cff_main()->cff_error_reporter->are_critical_errors()
620 && isset($this->atts['sources'])
621 && is_array($this->atts['sources'])
622 ) {
623 foreach ($this->atts['sources'] as $source) {
624 if (! empty($source['error'])) {
625 \CustomFacebookFeed\Builder\CFF_Source::clear_error($source['account_id']);
626 }
627 }
628 }
629 foreach ($FBdata->data as $news) {
630 // Explode News and Page ID's into 2 values
631 $PostID = '';
632 $cff_post_id = '';
633
634 if (isset($news->id)) {
635 $cff_post_id = $news->id;
636 $PostID = explode("_", $cff_post_id);
637 }
638
639 // Reassign variable changes from API v3.3 update
640 $news->link = isset($news->attachments->data[0]->unshimmed_url) ? $news->attachments->data[0]->unshimmed_url : '';
641 $news->description = isset($news->attachments->data[0]->description) ? $news->attachments->data[0]->description : '';
642 $news->object_id = isset($news->attachments->data[0]->target->id) ? $news->attachments->data[0]->target->id : '';
643 $news->source = isset($news->attachments->data[0]->media->source) ? $news->attachments->data[0]->media->source : '';
644 $news->name = isset($news->attachments->data[0]->title) ? $news->attachments->data[0]->title : '';
645 $news->caption = isset($news->attachments->data[0]->title) ? $news->attachments->data[0]->title : '';
646
647 // Check the post type
648 $cff_post_type = isset($news->attachments->data[0]->media_type) ? $news->attachments->data[0]->media_type : 'status';
649
650 if ($cff_post_type == 'link') {
651 isset($news->story) ? $story = $news->story : $story = '';
652 // Check whether it's an event
653 $event_link_check = "facebook.com/events/";
654 if (isset($news->link)) {
655 $event_link_check = CFF_Utils::stripos($news->link, $event_link_check);
656 if ($event_link_check) {
657 $cff_post_type = 'event';
658 }
659 }
660 }
661 $cff_show_links_type = true;
662 $cff_show_event_type = true;
663 $cff_show_video_type = true;
664 $cff_show_photos_type = true;
665 $cff_show_status_type = true;
666 $cff_show_albums_type = true;
667 $cff_events_only = false;
668 // Are we showing ONLY events?
669 if ($cff_show_event_type && !$cff_show_links_type && !$cff_show_video_type && !$cff_show_photos_type && !$cff_show_status_type) {
670 $cff_events_only = true;
671 }
672 // Should we show this post or not?
673 $cff_show_post = true;
674
675 // Is it a duplicate post?
676 if (!isset($prev_post_message)) {
677 $prev_post_message = '';
678 }
679 if (!isset($prev_post_link)) {
680 $prev_post_link = '';
681 }
682 if (!isset($prev_post_description)) {
683 $prev_post_description = '';
684 }
685 isset($news->message) ? $pm = $news->message : $pm = '';
686 isset($news->link) ? $pl = $news->link : $pl = '';
687 isset($news->description) ? $pd = $news->description : $pd = '';
688
689 // Check post type and display post if selected
690 if ($cff_show_post) {
691 // If it isn't then create the post
692 // Only create posts for the amount of posts specified
693 if (intval($this->atts['offset']) > 0) {
694 // If offset is being used then stop after showing the number of posts + the offset
695 if ($i_post == (intval($show_posts) + intval($this->atts['offset']))) {
696 break;
697 }
698 } else {
699 // Else just stop after the number of posts to be displayed is reached
700 if ($i_post == $show_posts) {
701 break;
702 }
703 }
704 $i_post++;
705 // ********************************//
706 // ***COMPILE SECTION VARIABLES***//
707 // ********************************//
708 // Set the post link
709 isset($news->link) ? $link = htmlspecialchars($news->link) : $link = '';
710 // Is it a shared album?
711 $shared_album_string = 'shared an album:';
712 isset($news->story) ? $story = $news->story : $story = '';
713 $shared_album = CFF_Utils::stripos($story, $shared_album_string);
714 if ($shared_album) {
715 $link = str_replace('photo.php?', 'media/set/?', $link);
716 }
717
718
719 if ($cff_post_type == 'link') {
720 isset($news->story) ? $story = $news->story : $story = '';
721 // Check whether it's an event
722 $event_link_check = "facebook.com/events/";
723 // Make sure URL doesn't include 'permalink' as that indicates someone else sharing a post from within an event (eg: https://www.facebook.com/events/617323338414282/permalink/617324268414189/) and the event ID is then not retrieved properly from the event URL as it's formatted like so: facebook.com/events/EVENT_ID/permalink/POST_ID
724 $event_link_check = CFF_Utils::stripos($news->link, $event_link_check);
725 $event_link_check_2 = CFF_Utils::stripos($news->link, "permalink/");
726 if ($event_link_check && !$event_link_check_2) {
727 $cff_post_type = 'event';
728 }
729 }
730
731 // If it's an event then check whether the URL contains facebook.com
732 if (isset($news->link)) {
733 if (CFF_Utils::stripos($news->link, "events/") && $cff_post_type == 'event') {
734 // Facebook changed the event link from absolute to relative, and so if the link isn't absolute then add facebook.com to front
735 if (!CFF_Utils::stripos($link, 'facebook.com')) {
736 $link = 'https://facebook.com' . $link;
737 }
738 }
739 }
740
741 // Is it an album?
742 $cff_album = false;
743 if (isset($news->status_type)) {
744 if ($news->status_type == 'added_photos') {
745 if (isset($news->attachments)) {
746 if ($news->attachments->data[0]->media_type == 'album') {
747 $cff_album = true;
748 }
749 }
750 }
751 }
752
753 // If there's no link provided then link to either the Facebook page or the individual status
754 if (empty($news->link)) {
755 if ($cff_link_to_timeline == true) {
756 // Link to page
757 $link = 'https://facebook.com/' . $this->page_id;
758 } else {
759 // Link to status
760 $link = "https://www.facebook.com/" . $this->page_id . "/posts/" . $PostID[1];
761 }
762 }
763
764 $cff_date = CFF_Utils::print_template_part('item/date', get_defined_vars(), $this);
765
766
767
768
769 // Story/post text vars
770 $post_text = '';
771 $cff_story_raw = '';
772 $cff_message_raw = '';
773 $cff_name_raw = '';
774 $text_tags = '';
775 $post_text_story = '';
776 $post_text_message = '';
777
778 // STORY TAGS
779 $cff_post_tags = $this->atts[ 'posttags' ];
780
781 // Use the story
782 if (!empty($news->story)) {
783 $cff_story_raw = $news->story;
784 $post_text_story .= htmlspecialchars($cff_story_raw);
785
786
787 // Add message and story tags if there are any and the post text is the message or the story
788 if ($cff_post_tags && isset($news->story_tags) && !$cff_title_link) {
789 $text_tags = $news->story_tags;
790
791 // Does the Post Text contain any html tags? - the & symbol is the best indicator of this
792 $cff_html_check_array = array('&lt;', '', '', '&quot;', '&amp;', '&gt;&gt;');
793
794 // always use the text replace method
795 if (CFF_Utils::cff_stripos_arr($post_text_story, $cff_html_check_array) !== false || ($cff_locale == 'el_GR' && count($news->story_tags) > 3)) {
796 // Loop through the tags
797 foreach ($text_tags as $message_tag) {
798 if (!isset($message_tag->id)) {
799 $message_tag = $message_tag[0];
800 }
801
802 $tag_name = $message_tag->name;
803 $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
804
805 $post_text_story = str_replace($tag_name, $tag_link, $post_text_story);
806 }
807 } else {
808 // If it doesn't contain HTMl tags then use the offset to replace message tags
809 $message_tags_arr = array();
810
811 $tag = 0;
812 foreach ($text_tags as $message_tag) {
813 $tag++;
814 if (!isset($message_tag->id)) {
815 $message_tag = $message_tag[0];
816 }
817
818 isset($message_tag->type) ? $tag_type = $message_tag->type : $tag_type = '';
819
820 $message_tags_arr = CFF_Utils::cff_array_push_assoc(
821 $message_tags_arr,
822 $tag,
823 array(
824 'id' => $message_tag->id,
825 'name' => $message_tag->name,
826 'type' => isset($message_tag->type) ? $message_tag->type : '',
827 'offset' => $message_tag->offset,
828 'length' => $message_tag->length
829 )
830 );
831 }
832
833 // Keep track of the offsets so that if two tags have the same offset then only one is used. Need this as API 2.5 update changed the story_tag JSON format. A duplicate offset usually means '__ was with __ and 3 others'. We don't want to link the '3 others' part.
834 $cff_story_tag_offsets = '';
835 $cff_story_duplicate_offset = '';
836
837 // Check if there are any duplicate offsets. If so, assign to the cff_story_duplicate_offset var.
838 for ($tag = count($message_tags_arr); $tag >= 1; $tag--) {
839 $c = (string)$message_tags_arr[$tag]['offset'];
840 if (strpos($cff_story_tag_offsets, $c) !== false && $c !== '0') {
841 $cff_story_duplicate_offset = $c;
842 } else {
843 $cff_story_tag_offsets .= $c . ',';
844 }
845 }
846
847 for ($tag = count($message_tags_arr); $tag >= 1; $tag--) {
848 // If the name is blank (aka the story tag doesn't work properly) then don't use it
849 if ($message_tags_arr[$tag]['name'] !== '') {
850 // If it's an event tag or it has the same offset as another tag then don't display it
851 if ($message_tags_arr[$tag]['type'] == 'event' || $message_tags_arr[$tag]['offset'] == $cff_story_duplicate_offset || $message_tags_arr[$tag]['type'] == 'page') {
852 // Don't use the story tag in this case otherwise it changes '__ created an event' to '__ created an Name Of Event'
853 // Don't use the story tag if it's a page as it causes an issue when sharing a page: Smash Balloon Dev shared a Smash Balloon.
854 } else {
855 $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '" target="_blank">' . $message_tags_arr[$tag]['name'] . '</a>';
856 $c = $message_tags_arr[$tag]['offset'];
857 $d = $message_tags_arr[$tag]['length'];
858 $post_text_story = CFF_Utils::cff_mb_substr_replace($post_text_story, $b, $c, $d);
859 }
860 }
861 }
862 } // end if/else
863 } //END STORY TAGS
864 }
865
866 // POST AUTHOR
867 $cff_author = CFF_Utils::print_template_part('item/author', get_defined_vars(), $this);
868 // Get the actual post text
869 // Which content should we use?
870 // Use the message
871 if (!empty($news->message)) {
872 $cff_message_raw = $news->message;
873
874 $post_text_message = htmlspecialchars($cff_message_raw);
875
876 // MESSAGE TAGS
877 // Add message and story tags if there are any and the post text is the message or the story
878 if ($cff_post_tags && isset($news->message_tags) && !$cff_title_link) {
879 $text_tags = $news->message_tags;
880
881 // Does the Post Text contain any html tags? - the & symbol is the best indicator of this
882 $cff_html_check_array = array('&lt;', '', '', '&quot;', '&amp;', '&gt;&gt;', '&gt;');
883
884 // always use the text replace method
885 if (CFF_Utils::cff_stripos_arr($post_text_message, $cff_html_check_array) !== false) {
886 // Loop through the tags
887 foreach ($text_tags as $message_tag) {
888 if (! isset($message_tag->id)) {
889 $message_tag = $message_tag[0];
890 }
891
892 $tag_name = $message_tag->name;
893 $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
894
895 $post_text_message = str_replace($tag_name, $tag_link, $post_text_message);
896 }
897 } else {
898 // If it doesn't contain HTMl tags then use the offset to replace message tags
899 $message_tags_arr = array();
900
901 $tag = 0;
902 foreach ($text_tags as $message_tag) {
903 $tag++;
904
905 if (! isset($message_tag->id)) {
906 $message_tag = $message_tag[0];
907 }
908
909 $message_tags_arr = CFF_Utils::cff_array_push_assoc(
910 $message_tags_arr,
911 $tag,
912 array(
913 'id' => $message_tag->id,
914 'name' => $message_tag->name,
915 'type' => isset($message_tag->type) ? $message_tag->type : '',
916 'offset' => $message_tag->offset,
917 'length' => $message_tag->length
918 )
919 );
920 }
921
922 // Keep track of the offsets so that if two tags have the same offset then only one is used. Need this as API 2.5 update changed the story_tag JSON format.
923 $cff_msg_tag_offsets = '';
924 $cff_msg_duplicate_offset = '';
925
926 // Check if there are any duplicate offsets. If so, assign to the cff_duplicate_offset var.
927 for ($tag = count($message_tags_arr); $tag >= 1; $tag--) {
928 $c = (string)$message_tags_arr[$tag]['offset'];
929 if (strpos($cff_msg_tag_offsets, $c) !== false && $c !== '0') {
930 $cff_msg_duplicate_offset = $c;
931 } else {
932 $cff_msg_tag_offsets .= $c . ',';
933 }
934 }
935
936 // Sort the array by the "offset" key as Facebook doesn't always return them in the correct order
937 usort($message_tags_arr, "CustomFacebookFeed\CFF_Utils::cffSortTags");
938
939 for ($tag = count($message_tags_arr) - 1; $tag >= 0; $tag--) {
940 // If the name is blank (aka the story tag doesn't work properly) then don't use it
941 if ($message_tags_arr[$tag]['name'] !== '') {
942 if ($message_tags_arr[$tag]['offset'] == $cff_msg_duplicate_offset) {
943 // If it has the same offset as another tag then don't display it
944 } else {
945 $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '">' . $message_tags_arr[$tag]['name'] . '</a>';
946 $c = $message_tags_arr[$tag]['offset'];
947 $d = $message_tags_arr[$tag]['length'];
948 $post_text_message = CFF_Utils::cff_mb_substr_replace($post_text_message, $b, $c, $d);
949 }
950 }
951 }
952 } // end if/else
953 } //END MESSAGE TAGS
954 }
955
956
957 // Check to see whether it's an embedded video so that we can show the name above the post text if necessary
958 $cff_soundcloud = false;
959 $cff_is_video_embed = false;
960 if ($cff_post_type == 'video' || $cff_post_type == 'music') {
961 if (isset($news->source) && !empty($news->source)) {
962 $url = $news->source;
963 } elseif (isset($news->link)) {
964 $url = $news->link;
965 } else {
966 $url = '';
967 }
968 // Embeddable video strings
969 $vimeo = 'vimeo';
970 $youtube = CFF_Utils::stripos($url, 'youtube');
971 $youtu = CFF_Utils::stripos($url, 'youtu');
972 $youtubeembed = CFF_Utils::stripos($url, 'youtube.com/embed');
973 $soundcloudembed = CFF_Utils::stripos($url, 'soundcloud.com');
974
975 // Check whether it's a youtube video
976 if ($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
977 $cff_is_video_embed = true;
978 }
979 // If it's soundcloud then add it into the shared link box at the bottom of the post
980 if ($soundcloudembed) {
981 $cff_soundcloud = true;
982 }
983 }
984
985 // Add the story and message together
986 $post_text = '';
987
988 // DESCRIPTION
989 $cff_description = '';
990 if (!empty($news->description) || !empty($news->caption)) {
991 $description_text = '';
992
993 if (!empty($news->description)) {
994 $description_text = $news->description;
995 }
996
997 // Replace ellipsis char in description text
998 $raw_desc = $description_text;
999 $description_text = str_replace('', '...', $description_text);
1000
1001 // If the description is the same as the post text then don't show it
1002 if ($raw_desc == $cff_story_raw || $raw_desc == $cff_message_raw || $raw_desc == $cff_name_raw) {
1003 $cff_description = '';
1004 } else {
1005 // Add links and create HTML
1006 $cff_description .= '<span class="cff-post-desc" ' . $cff_body_styles . '>';
1007
1008 if ($cff_title_link) {
1009 $cff_description_tagged = CFF_Utils::cff_wrap_span(htmlspecialchars($description_text));
1010 } else {
1011 $cff_description_text = CFF_Autolink::cff_autolink(htmlspecialchars($description_text), $link_color = $cff_posttext_link_color);
1012 $cff_description_tagged = CFF_Utils::cff_desc_tags($cff_description_text);
1013 }
1014
1015 $cff_description .= $cff_description_tagged;
1016 $cff_description .= ' </span>';
1017 }
1018
1019 if ($cff_post_type == 'event' || $cff_is_video_embed || $cff_soundcloud) {
1020 $cff_description = '';
1021 }
1022 }
1023
1024 // Add the message
1025 if ($cff_show_text) {
1026 $post_text .= $post_text_message;
1027 }
1028
1029 $post_text = apply_filters('cff_post_text', $post_text);
1030
1031 // If it's a shared video post then add the video name after the post text above the video description so it's all one chunk
1032 if ($cff_post_type == 'video') {
1033 if (!empty($cff_description) && $cff_description != '') {
1034 $cff_video_name = ''; // the video name is never set. Is this still available in the API?
1035 if ((!empty($post_text) && $post_text != '') && !empty($cff_video_name)) {
1036 $post_text .= '<br /><br />';
1037 }
1038 $post_text .= $cff_video_name;
1039 }
1040 }
1041
1042
1043 // Use the name if there's no other text, unless it's a shared link post as then it's already used as the shared link box title
1044 if (!empty($news->name) && empty($news->message) && $cff_post_type != 'link') {
1045 $cff_name_raw = $news->name;
1046 $post_text = htmlspecialchars($cff_name_raw);
1047 }
1048
1049 // OFFER TEXT
1050 if ($cff_post_type == 'offer') {
1051 isset($news->story) ? $post_text = htmlspecialchars($news->story) . '<br /><br />' : $post_text = '';
1052 $post_text .= htmlspecialchars($news->name);
1053 }
1054
1055 // Add the description
1056 if ($cff_show_desc && $cff_post_type != 'offer' && $cff_post_type != 'link') {
1057 $post_text .= $cff_description;
1058 }
1059
1060 // Change the linebreak element if the text issue setting is enabled
1061 $cff_format_issue = CFF_Utils::check_if_on($this->atts['textissue']);
1062 $cff_linebreak_el = ( $cff_format_issue ) ? '<br />' : '<img class="cff-linebreak" alt="" aria-hidden="true" />';
1063
1064 // EVENT
1065 $cff_event_has_cover_photo = false;
1066 $cff_event = '';
1067
1068
1069 // Create note
1070 if ($cff_post_type == 'note') {
1071 // Notes don't include any post text and so just replace the post text with the note content
1072 if ($cff_show_text) {
1073 $post_text = CFF_Utils::print_template_part('item/type/note', get_defined_vars(), $this);
1074 }
1075 }
1076
1077 $cff_post_text = CFF_Utils::print_template_part('item/post-text', get_defined_vars(), $this);
1078
1079 // LINK
1080 // Display shared link
1081 $cff_shared_link = CFF_Utils::print_template_part('item/shared-link', get_defined_vars(), $this);
1082
1083 // Link to the Facebook post if it's a link or a video
1084 if ($cff_post_type == 'link' || $cff_post_type == 'video') {
1085 $link = "https://www.facebook.com/" . $this->page_id . "/posts/" . $PostID[1];
1086 }
1087
1088
1089 // If it's a shared post then change the link to use the Post ID so that it links to the shared post and not the original post that's being shared
1090 if (isset($news->status_type)) {
1091 if ($news->status_type == 'shared_story') {
1092 $link = "https://www.facebook.com/" . $cff_post_id;
1093 }
1094 }
1095
1096 // Create post action links HTML
1097 $cff_link = CFF_Utils::print_template_part('item/post-link', get_defined_vars(), $this);
1098 /* MEDIA LINK */
1099 $cff_media_link = CFF_Utils::print_template_part('item/media-link', get_defined_vars(), $this);
1100 // **************************//
1101 // ***CREATE THE POST HTML***//
1102 // **************************//
1103 // Start the container
1104 $cff_post_item = CFF_Utils::print_template_part('item/container', get_defined_vars(), $this);
1105
1106 // PUSH TO ARRAY
1107 $cff_posts_array = CFF_Utils::cff_array_push_assoc($cff_posts_array, $i_post, $cff_post_item);
1108 } // End post type check
1109
1110 if (isset($news->message)) {
1111 $prev_post_message = $news->message;
1112 }
1113 if (isset($news->link)) {
1114 $prev_post_link = $news->link;
1115 }
1116 if (isset($news->description)) {
1117 $prev_post_description = $news->description;
1118 }
1119 } // End the loop
1120 } //End isset($FBdata->data)
1121
1122 // Sort the array in reverse order (newest first)
1123 if (!$cff_is_group) {
1124 ksort($cff_posts_array);
1125 }
1126
1127 // End ALL POSTS
1128
1129
1130 // Output the posts array
1131 $p = 0;
1132 foreach ($cff_posts_array as $post) {
1133 if ($p == $show_posts) {
1134 break;
1135 }
1136 $cff_content .= $post;
1137 $p++;
1138 }
1139
1140
1141 // Add the Like Box inside
1142 if ($cff_like_box_position == 'bottom' && $cff_show_like_box && !$cff_like_box_outside) {
1143 $cff_content .= $like_box;
1144 }
1145 /* Credit link */
1146
1147 $cff_content .= '</div>'; // End cff-posts-wrap
1148
1149 $cff_content .= CFF_Utils::print_template_part('credit', get_defined_vars());
1150
1151 // End the feed
1152 $cff_content .= '<input class="cff-pag-url" type="hidden" data-locatornonce="' . esc_attr( wp_create_nonce( 'cff-locator-nonce-' . get_the_ID() ) ) . '" data-cff-shortcode="' . $data_att_html . '" data-post-id="' . get_the_ID() . '" data-feed-id="' . esc_attr( $atts['id'] ) . '">';
1153 $cff_content .= '</div></div><div class="cff-clear"></div>';
1154
1155 // Add the Like Box outside
1156 if ($cff_like_box_position == 'bottom' && $cff_show_like_box && $cff_like_box_outside) {
1157 $cff_content .= $like_box;
1158 }
1159
1160 // If the feed is loaded via Ajax then put the scripts into the shortcode itself
1161 $cff_content .= $this->ajax_loaded();
1162 $cff_content .= '</div>';
1163
1164 if ($doing_custom_styles) {
1165 $cff_content .= '<style type="text/css">' . "\n";
1166
1167 if (
1168 ! empty($this->atts['colorpalette'])
1169 && $this->atts['colorpalette'] === 'custom'
1170 ) {
1171 $wrap_selector = '#cff.' . $custom_palette_class;
1172
1173 if (! empty($this->atts['custombgcolor1'])) {
1174 $cff_content .= $wrap_selector . ' ' . '.cff-item,' . "\n";
1175 $cff_content .= $wrap_selector . ' ' . '.cff-item.cff-box,' . "\n";
1176 $cff_content .= $wrap_selector . ' ' . '.cff-item.cff-box:first-child,' . "\n";
1177 $cff_content .= $wrap_selector . ' ' . '.cff-album-item {' . "\n";
1178 $cff_content .= ' ' . 'background-color: ' . esc_attr($this->atts['custombgcolor1']) . ';' . "\n";
1179 $cff_content .= '}' . "\n";
1180 }
1181
1182 if (! $cff_disable_link_box && ! empty($this->atts['custombgcolor2'])) {
1183 $cff_content .= $wrap_selector . ' ' . '.cff-view-comments,' . "\n";
1184 $cff_content .= $wrap_selector . ' ' . '.cff-load-more,' . "\n";
1185 $cff_content .= $wrap_selector . ' ' . '.cff-shared-link {' . "\n";
1186 $cff_content .= ' ' . 'background-color: ' . esc_attr($this->atts['custombgcolor2']) . ';' . "\n";
1187 $cff_content .= '}' . "\n";
1188 }
1189
1190 if (! empty($this->atts['textcolor1'])) {
1191 $cff_content .= $wrap_selector . ' ' . '.cff-comment .cff-comment-text p,' . "\n";
1192 $cff_content .= $wrap_selector . ' ' . '.cff-album-info p,' . "\n";
1193 $cff_content .= $wrap_selector . ' ' . '.cff-story,' . "\n";
1194 $cff_content .= $wrap_selector . ' ' . '.cff-text {' . "\n";
1195 $cff_content .= ' ' . 'color: ' . esc_attr($this->atts['textcolor1']) . ';' . "\n";
1196 $cff_content .= '}' . "\n";
1197 }
1198
1199 if (! empty($this->atts['textcolor2'])) {
1200 $cff_content .= $wrap_selector . ' ' . '.cff-comment-date,' . "\n";
1201 $cff_content .= $wrap_selector . ' ' . '.cff-text-link .cff-post-desc,' . "\n";
1202 $cff_content .= $wrap_selector . ' ' . '.cff-link-caption,' . "\n";
1203 $cff_content .= $wrap_selector . ' ' . '.cff-date {' . "\n";
1204 $cff_content .= ' ' . 'color: ' . esc_attr($this->atts['textcolor2']) . ';' . "\n";
1205 $cff_content .= '}' . "\n";
1206 }
1207
1208 if (! empty($this->atts['customlinkcolor'])) {
1209 $cff_content .= $wrap_selector . ' ' . 'a,' . "\n";
1210 $cff_content .= $wrap_selector . ' ' . '.cff-post-links a,' . "\n";
1211 $cff_content .= $wrap_selector . ' ' . 'a {' . "\n";
1212 $cff_content .= ' ' . 'color: ' . esc_attr($this->atts['customlinkcolor']) . ';' . "\n";
1213 $cff_content .= '}' . "\n";
1214 }
1215 }
1216 $lightbox_selector = '#cff-lightbox-wrapper';
1217
1218 if (! empty($this->atts['lightboxbgcolor'])) {
1219 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-dataContainer,' . "\n";
1220 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-sidebar {' . "\n";
1221 $cff_content .= ' ' . 'background-color: ' . esc_attr($this->atts['lightboxbgcolor']) . ';' . "\n";
1222 $cff_content .= '}' . "\n";
1223 }
1224
1225 if (! empty($this->atts['lightboxtextcolor'])) {
1226 $cff_content .= $lightbox_selector . ' ' . '.cff-author .cff-date,' . "\n";
1227 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-closeContainer svg,' . "\n";
1228 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-caption-text {' . "\n";
1229 $cff_content .= ' ' . 'color: ' . esc_attr($this->atts['lightboxtextcolor']) . ';' . "\n";
1230 $cff_content .= '}' . "\n";
1231 }
1232
1233 if (! empty($this->atts['lightboxlinkcolor'])) {
1234 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-caption-text a:link,' . "\n";
1235 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-caption-text a:hover,' . "\n";
1236 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-caption-text a:active,' . "\n";
1237 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-caption-text a:visited,' . "\n";
1238 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-facebook:link,' . "\n";
1239 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-facebook:hover,' . "\n";
1240 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-facebook:active,' . "\n";
1241 $cff_content .= $lightbox_selector . ' ' . '.cff-lightbox-facebook:visited,' . "\n";
1242 $cff_content .= $lightbox_selector . ' ' . 'a {' . "\n";
1243 $cff_content .= ' ' . 'color: ' . esc_attr($this->atts['lightboxlinkcolor']) . ';' . "\n";
1244 $cff_content .= '}' . "\n";
1245 }
1246
1247 $cff_content .= '</style>';
1248 }
1249
1250
1251 if (isset($cff_posttext_link_color) && !empty($cff_posttext_link_color)) {
1252 $cff_content .= '<style>#cff .cff-post-text a{ color: #' . $cff_posttext_link_color . '; }</style>';
1253 }
1254
1255 if (isset($_GET['sb_debug'])) {
1256 $cff_content .= $this->sb_get_debug_report($feed_options);
1257 }
1258
1259 // Return our feed HTML to display
1260 return $cff_content;
1261 }
1262
1263 /**
1264 * Get Debug Report for Feed
1265 *
1266 * @since 4.0
1267 *
1268 * @param array $feed_opitons
1269 *
1270 * @return string $output
1271 */
1272 public function sb_get_debug_report($feed_options)
1273 {
1274 if (!isset($_GET['sb_debug'])) {
1275 return;
1276 }
1277 $cff_options = get_option('cff_style_settings');
1278
1279 $output = '';
1280 $output .= '<p>Settings</p>';
1281 $output .= '<ul style="word-break: break-all;">';
1282
1283 $output .= '<li>Optimize Images: ';
1284 $output .= isset($cff_options[ 'cff_disable_resize' ]) && $cff_options[ 'cff_disable_resize' ] == 'on' ? 'Enabled' : 'Disabled';
1285 $output .= "</li>";
1286 $output .= "</li>";
1287 $output .= '<li>AJAX theme loading fix: ';
1288 $output .= isset($cff_options[ 'cff_disable_ajax_cache' ]) && $cff_options[ 'cff_disable_ajax_cache' ] == true ? 'Enabled' : 'Disabled';
1289 $output .= "</li>";
1290 $output .= '<li>Show Credit Link: ';
1291 $output .= isset($cff_options['cff_format_issue']) && $cff_options['cff_format_issue'] == true ? 'Enabled' : 'Disabled';
1292 $output .= "</li>";
1293 $output .= '<li>Fix Text Shortening Issue: ';
1294 $output .= isset($cff_options['cff_show_credit']) && $cff_options['cff_show_credit'] == true ? 'Enabled' : 'Disabled';
1295 $output .= "</li>";
1296 $output .= '<li>Admin Error Notice: ';
1297 $output .= isset($cff_options['disable_admin_notice']) && $cff_options['disable_admin_notice'] == true ? 'Enabled' : 'Disabled';
1298 $output .= "</li>";
1299 $output .= '</ul>';
1300
1301 $output .= '<p>Feed Options</p>';
1302 $public_settings_keys = CFF_Shortcode::get_public_db_settings_keys();
1303
1304 $output .= '<ul style="word-break: break-all;">';
1305 foreach ($feed_options as $key => $option) {
1306 if (is_array($option)) {
1307 continue;
1308 }
1309 if (in_array($key, $public_settings_keys, true)) {
1310 $output .= sprintf('<li>%s: %s</li>', esc_html($key), esc_html($option));
1311 }
1312 }
1313 $output .= '</ul>';
1314
1315 return $output;
1316 }
1317
1318 /**
1319 * The plugin will output settings on the frontend for debugging purposes.
1320 * Safe settings to display are added here.
1321 * *
1322 *
1323 * @return array
1324 *
1325 * @since 4.0
1326 */
1327 public static function get_public_db_settings_keys()
1328 {
1329 $public = array(
1330 'ownaccesstoken',
1331 'id',
1332 'pagetype',
1333 'num',
1334 'limit',
1335 'others',
1336 'showpostsby',
1337 'cachetype',
1338 'cachetime',
1339 'cacheunit',
1340 'locale',
1341 'storytags',
1342 'ajax',
1343 'offset',
1344 'account',
1345 'width',
1346 'widthresp',
1347 'height',
1348 'padding',
1349 'bgcolor',
1350 'showauthor',
1351 'showauthornew',
1352 'class',
1353 'type',
1354 'gdpr',
1355 'loadiframes',
1356 'eventsource',
1357 'eventoffset',
1358 'eventimage',
1359 'pastevents',
1360 'albumsource',
1361 'showalbumtitle',
1362 'showalbumnum',
1363 'albumcols',
1364 'photosource',
1365 'photocols',
1366 'videosource',
1367 'showvideoname',
1368 'showvideodesc',
1369 'videocols',
1370 'playlist',
1371 'disablelightbox',
1372 'filter',
1373 'exfilter',
1374 'layout',
1375 'enablenarrow',
1376 'oneimage',
1377 'mediaposition' => 'above',
1378 'include',
1379 'exclude',
1380 'masonry',
1381 'masonrycols',
1382 'masonrycolsmobile',
1383 'masonryjs',
1384 'cols',
1385 'colsmobile',
1386 'colsjs',
1387 'nummobile',
1388 'poststyle',
1389 'postbgcolor',
1390 'postcorners',
1391 'boxshadow',
1392 'textformat',
1393 'textsize',
1394 'textweight',
1395 'textcolor',
1396 'textlinkcolor',
1397 'textlink',
1398 'posttags',
1399 'linkhashtags',
1400 'lightboxcomments',
1401 'authorsize',
1402 'authorcolor',
1403 'descsize',
1404 'descweight',
1405 'desccolor',
1406 'linktitleformat',
1407 'linktitlesize',
1408 'linkdescsize',
1409 'linkurlsize',
1410 'linkdesccolor',
1411 'linktitlecolor',
1412 'linkurlcolor',
1413 'linkbgcolor',
1414 'linkbordercolor',
1415 'disablelinkbox',
1416 'eventtitleformat',
1417 'eventtitlesize',
1418 'eventtitleweight',
1419 'eventtitlecolor',
1420 'eventtitlelink',
1421 'eventdatesize',
1422 'eventdateweight',
1423 'eventdatecolor',
1424 'eventdatepos',
1425 'eventdateformat',
1426 'eventdatecustom',
1427 'timezoneoffset',
1428 'cff_enqueue_with_shortcode',
1429 'eventdetailssize',
1430 'eventdetailsweight',
1431 'eventdetailscolor',
1432 'eventlinkcolor',
1433 'datepos',
1434 'datesize',
1435 'dateweight',
1436 'datecolor',
1437 'dateformat',
1438 'datecustom',
1439 'timezone',
1440 'beforedate',
1441 'afterdate',
1442 'linksize',
1443 'linkweight',
1444 'linkcolor',
1445 'viewlinktext',
1446 'linktotimeline',
1447 'buttoncolor',
1448 'buttonhovercolor',
1449 'buttontextcolor',
1450 'buttontext',
1451 'nomoretext',
1452 'iconstyle',
1453 'socialtextcolor',
1454 'socialbgcolor',
1455 'sociallinkcolor',
1456 'expandcomments',
1457 'commentsnum',
1458 'hidecommentimages',
1459 'loadcommentsjs',
1460 'salesposts',
1461 'textlength',
1462 'desclength',
1463 'showlikebox',
1464 'likeboxpos',
1465 'likeboxoutside',
1466 'likeboxcolor',
1467 'likeboxtextcolor',
1468 'likeboxwidth',
1469 'likeboxfaces',
1470 'likeboxborder',
1471 'likeboxcover',
1472 'likeboxsmallheader',
1473 'likeboxhidebtn',
1474 'credit',
1475 'textissue',
1476 'disablesvgs',
1477 'restrictedpage',
1478 'hidesupporterposts',
1479 'privategroup',
1480 'nofollow',
1481 'timelinepag',
1482 'gridpag',
1483 'disableresize',
1484 'showheader',
1485 'headertype',
1486 'headercover',
1487 'headeravatar',
1488 'headername',
1489 'headerbio',
1490 'headercoverheight',
1491 'headerlikes',
1492 'headeroutside',
1493 'headertext',
1494 'headerbg',
1495 'headerpadding',
1496 'headertextsize',
1497 'headertextweight',
1498 'headertextcolor',
1499 'headericon',
1500 'headericoncolor',
1501 'headericonsize',
1502 'headerinc',
1503 'headerexclude',
1504 'loadmore',
1505 'fulllinkimages',
1506 'linkimagesize',
1507 'postimagesize',
1508 'videoheight',
1509 'videoaction',
1510 'videoplayer',
1511 'sepcolor',
1512 'sepsize',
1513 'seemoretext',
1514 'seelesstext',
1515 'photostext',
1516 'facebooklinktext',
1517 'sharelinktext',
1518 'showfacebooklink',
1519 'showsharelink',
1520 'buyticketstext',
1521 'maptext',
1522 'interestedtext',
1523 'goingtext',
1524 'previouscommentstext',
1525 'commentonfacebooktext',
1526 'likesthistext',
1527 'likethistext',
1528 'reactedtothistext',
1529 'andtext',
1530 'othertext',
1531 'otherstext',
1532 'noeventstext',
1533 'replytext',
1534 'repliestext',
1535 'learnmoretext',
1536 'shopnowtext',
1537 'messagepage',
1538 'getdirections',
1539 'secondtext',
1540 'secondstext',
1541 'minutetext',
1542 'minutestext',
1543 'hourtext',
1544 'hourstext',
1545 'daytext',
1546 'daystext',
1547 'weektext',
1548 'weekstext',
1549 'monthtext',
1550 'monthstext',
1551 'yeartext',
1552 'yearstext',
1553 'agotext',
1554 'multifeedactive',
1555 'daterangeactive',
1556 'featuredpostactive',
1557 'albumactive',
1558 'masonryactive',
1559 'carouselactive',
1560 'reviewsactive',
1561 'from',
1562 'until',
1563 'featuredpost',
1564 'album',
1565 'daterange',
1566 'lightbox',
1567 'reviewsrated',
1568 'starsize',
1569 'hidenegative',
1570 'reviewslinktext',
1571 'reviewshidenotext',
1572 'reviewsmethod',
1573 'feedtype',
1574 'likeboxcustomwidth',
1575 'colstablet',
1576 'feedlayout',
1577 'colorpalette',
1578 'custombgcolor1',
1579 'custombgcolor2',
1580 'textcolor1',
1581 'textcolor2',
1582 'posttextcolor',
1583 'misctextcolor',
1584 'misclinkcolor',
1585 'headericonenabled',
1586 'lightboxbgcolor',
1587 'lightboxtextcolor',
1588 'lightboxlinkcolor',
1589 'beforedateenabled',
1590 'afterdateenabled',
1591 'showpoststypes',
1592 'headerbiosize',
1593 'headerbiocolor',
1594 'apipostlimit',
1595 'carouselheight',
1596 'carouseldesktop_cols',
1597 'carouselmobile_cols',
1598 'carouselnavigation',
1599 'carouselpagination',
1600 'carouselautoplay',
1601 'carouselinterval',
1602 );
1603
1604 return $public;
1605 }
1606
1607 /* NEW 3.0 Methods */
1608 /**
1609 * Whether or not this feed is meant to use the new settings
1610 * or legacy settings
1611 *
1612 * @param array $feed_options
1613 *
1614 * @return bool
1615 *
1616 * @since 4.0
1617 */
1618 public function using_legacy_feed($feed_options)
1619 {
1620 $cff_statuses = get_option('cff_statuses', array());
1621
1622 if (
1623 isset($cff_statuses['support_legacy_shortcode'])
1624 && is_array($cff_statuses['support_legacy_shortcode'])
1625 ) {
1626 return empty($feed_options['feed']);
1627 }
1628
1629 if (empty($cff_statuses['support_legacy_shortcode'])) {
1630 return false;
1631 }
1632
1633 return empty($feed_options['feed']);
1634 }
1635
1636 /**
1637 * If a single unique feed was detected when updating from version 3.x
1638 * to version 4.0, a shortcode without a feed specified will be defaulted
1639 * to feed=1
1640 *
1641 * @param $feed_options
1642 *
1643 * @return bool
1644 */
1645 public function is_legacy_feed_one($feed_options)
1646 {
1647 $cff_statuses = get_option('cff_statuses', array());
1648
1649 if (
1650 isset($cff_statuses['support_legacy_shortcode'])
1651 && is_array($cff_statuses['support_legacy_shortcode'])
1652 ) {
1653 return empty($feed_options['feed']);
1654 }
1655
1656 return false;
1657 }
1658
1659 /**
1660 * For non-legacy feeds. Queries the new db tables to see if the feed
1661 * exists and then converts the settings to what is usable by the plugin.
1662 *
1663 * @param array $feed_options
1664 *
1665 * @return array|bool
1666 *
1667 * @since 4.0
1668 */
1669 public function get_settings_for_feed($feed_options)
1670 {
1671 if (! is_array($feed_options)) {
1672 $feed_options = array();
1673 }
1674
1675 if ($this->is_legacy_feed_one($feed_options)) {
1676 $feed_options['feed'] = 1;
1677 }
1678
1679 if (! $this->using_legacy_feed($feed_options)) {
1680 $feed_id = isset($feed_options['feed']) ? $feed_options['feed'] : false;
1681
1682 if (empty($feed_id)) {
1683 $feed_list = \CustomFacebookFeed\Builder\CFF_Feed_Builder::get_feed_list();
1684
1685 if (count($feed_list) === 1) {
1686 $feed_saver = new \CustomFacebookFeed\Builder\CFF_Feed_Saver($feed_list[0]['id']);
1687 $settings = $feed_saver->get_feed_settings();
1688 } else {
1689 if (( current_user_can('editor') || current_user_can('administrator') )) {
1690 echo "<span id='cff-no-id'>" . sprintf(__("It looks like you have more than one feed. Go to %sthis page%s and enter the intended feed ID in your shortcode like this: [custom-facebook-feed feed=YOUR_FEED_ID_HERE].", 'custom-facebook-feed'), '<a href="' . esc_url(admin_url('admin.php?page=cff-feed-builder')) . '">', '</a>') . "</span><br /><br />";
1691 }
1692 return false;
1693 }
1694 } else {
1695 $feed_saver = new \CustomFacebookFeed\Builder\CFF_Feed_Saver($feed_id);
1696 $settings = $feed_saver->get_feed_settings();
1697 }
1698
1699 if (empty($settings)) {
1700 if (( current_user_can('editor') || current_user_can('administrator') )) {
1701 $feed_list = \CustomFacebookFeed\Builder\CFF_Feed_Builder::get_feed_list();
1702 if (empty($feed_list)) {
1703 echo "<span id='cff-no-id'>" . sprintf(__("It looks like you haven't set up a feed yet. Try going to %sthis page%s to create one and then enter the feed id in the shortcode like this [custom-facebook-feed feed=YOUR_FEED_ID_HERE].", 'custom-facebook-feed'), '<a href="' . esc_url(admin_url('admin.php?page=cff-feed-builder')) . '">', '</a>') . "</span><br /><br />";
1704 }
1705 }
1706 return false;
1707 } elseif (empty($settings['sources'])) {
1708 if (( current_user_can('editor') || current_user_can('administrator') )) {
1709 echo "<span id='cff-no-id'>" . sprintf(__("No source found for this feed. It looks like you may have removed the account this feed was using to display posts. Go to %sthis page%s, switch to the settings tab and click the sources menu item to manage sources for this feed.", 'custom-facebook-feed'), '<a href="' . esc_url(admin_url('admin.php?page=cff-feed-builder&feed_id=' . (int) $feed_id)) . '">', '</a>') . "</span><br /><br />";
1710 }
1711 return $settings;
1712 }
1713
1714
1715 if (
1716 empty($settings['showpoststypes'])
1717 || $settings['showpoststypes'] === 'all'
1718 ) {
1719 $settings['type'] = 'links,events,videos,photos,albums,statuses';
1720 }
1721
1722 if (! empty($settings['feedtype']) && $settings['feedtype'] !== 'timeline') {
1723 $settings['type'] = $settings['feedtype'];
1724 }
1725 } else {
1726 $settings = CFF_FB_Settings::get_legacy_settings($feed_options);
1727
1728 if (! empty($feed_options['type'])) {
1729 $settings['feedtype'] = $feed_options['type'];
1730 $settings['type'] = $feed_options['type'];
1731 } else {
1732 if (
1733 empty($settings['showpoststypes'])
1734 || $settings['showpoststypes'] === 'all'
1735 ) {
1736 $settings['type'] = 'links,events,videos,photos,albums,statuses';
1737 }
1738
1739 if (! empty($settings['feedtype']) && $settings['feedtype'] !== 'timeline') {
1740 $settings['type'] = $settings['feedtype'];
1741 }
1742 }
1743
1744 $default_grid = [
1745 'albums',
1746 'videos',
1747 'photos',
1748 'singlealbum'
1749 ];
1750
1751 $type_setting_array = is_array($settings['type']) ? array_filter($settings['type']) : array_filter(explode(',', $settings['type']));
1752
1753 $single_type = count($type_setting_array) === 1 ? $type_setting_array[0] : false;
1754
1755 if (! empty($feed_options['album'])) {
1756 $single_type = 'singlealbum';
1757 }
1758
1759 if ($single_type) {
1760 if (in_array($single_type, $default_grid)) {
1761 if (empty($feed_options['feedlayout'])) {
1762 $settings['feedlayout'] = 'grid';
1763 }
1764 if (empty($feed_options['cols'])) {
1765 $colskey = substr($single_type, 0, -1) . 'cols';
1766 $options_val = isset($settings[ $colskey ]) ? $settings[ $colskey ] : 4;
1767 $settings['cols'] = isset($settings[ $colskey ]) ? $settings[ $colskey ] : $options_val;
1768 }
1769 }
1770 $settings['feedtype'] = $single_type;
1771 }
1772 }
1773
1774 $cff_includes = $settings['include'];
1775 $cff_excludes = $settings['exclude'];
1776
1777 $cff_show_like_box = false;
1778 if (is_string($cff_includes)) {
1779 if (CFF_Utils::stripos($cff_includes, 'likebox') !== false) {
1780 $cff_show_like_box = true;
1781 }
1782 } elseif (in_array('likebox', $cff_includes)) {
1783 $cff_show_like_box = true;
1784 }
1785 if (is_string($cff_excludes)) {
1786 if (CFF_Utils::stripos($cff_excludes, 'likebox') !== false) {
1787 $cff_show_like_box = false;
1788 }
1789 } elseif (in_array('likebox', $cff_excludes)) {
1790 $cff_show_like_box = false;
1791 }
1792
1793 if (! isset($feed_options['include']) && ! isset($feed_options['exclude'])) {
1794 if (! empty($settings['showlikebox'])) {
1795 $settings['showlikebox'] = $settings['showlikebox'] === false || $settings['showlikebox'] === 'off' ? false : true;
1796 } else {
1797 $settings['showlikebox'] = $cff_show_like_box;
1798 }
1799 } else {
1800 $settings['showlikebox'] = $cff_show_like_box;
1801 }
1802
1803 if (! $settings['showlikebox']) {
1804 $settings['include'] = str_replace('likebox,', ',', $settings['include']);
1805 }
1806
1807 if (! empty($settings['headericonenabled']) && $settings['headericonenabled'] === 'off') {
1808 $settings['headericon'] = '';
1809 }
1810
1811 if (
1812 ! empty($settings['apipostlimit'])
1813 && $settings['apipostlimit'] === 'auto'
1814 ) {
1815 $settings['limit'] = '';
1816 }
1817
1818 if ($settings['poststyle'] === 'regular') {
1819 $settings['boxshadow'] = false;
1820 }
1821
1822 if (isset($feed_options['ajax'])) {
1823 $settings['ajax'] = $feed_options['ajax'];
1824 } else {
1825 $settings['ajax'] = get_option('cff_ajax', '');
1826 }
1827 $settings['locale'] = ( isset($feed_options['locale']) ) ? $feed_options['locale'] : get_option('cff_locale', 'en_US');
1828
1829 // Default Timezone
1830 $defaults = array(
1831 'cff_timezone' => 'America/Chicago',
1832 'gdpr' => 'auto',
1833 'cff_show_credit' => false,
1834 'cff_format_issue' => '',
1835 'disable_admin_notice' => false
1836 );
1837 $style_options = get_option('cff_style_settings', $defaults);
1838 $settings['timezone'] = (isset($style_options[ 'cff_timezone' ])) ? $style_options[ 'cff_timezone' ] : $defaults[ 'cff_timezone' ];
1839 $settings['gdpr'] = (isset($style_options[ 'gdpr' ])) ? $style_options[ 'gdpr' ] : $defaults[ 'gdpr' ];
1840 $settings['credit'] = (isset($style_options[ 'cff_show_credit' ])) ? $style_options[ 'cff_show_credit' ] : $defaults[ 'cff_show_credit' ];
1841 $settings['textissue'] = (isset($style_options[ 'cff_format_issue' ])) ? $style_options[ 'cff_format_issue' ] : $defaults[ 'cff_format_issue' ];
1842 $settings['likeboxheight'] = '';
1843 $settings['disablestyles'] = isset($style_options[ 'cff_disable_styles' ]) ? $style_options[ 'cff_disable_styles' ] : '';
1844
1845 $settings['cachetime'] = isset($feed_options[ 'cachetime' ]) ? $feed_options[ 'cachetime' ] : get_option('cff_cache_time', '1');
1846 $settings['cacheunit'] = isset($feed_options[ 'cacheunit' ]) ? $feed_options[ 'cacheunit' ] : get_option('cff_cache_time_unit', 'hours');
1847
1848 $maybe_legacy_shortcode = $feed_options;
1849 if (isset($maybe_legacy_shortcode['feed'])) {
1850 unset($maybe_legacy_shortcode['feed']);
1851 }
1852
1853 // Merge in legacy settings (shortcode only settings)
1854 if (! empty($maybe_legacy_shortcode)) {
1855 $legacy_shortcode_settings = [
1856 'width',
1857 'widthresp',
1858 'mediaposition',
1859 'masonryjs',
1860 'colsjs',
1861 'textformat',
1862 // all text weight settings
1863 'textweight',
1864 'descweight',
1865 'eventtitleweight',
1866 'eventdateweight',
1867 'eventdetailsweight',
1868 'dateweight',
1869 'linkweight',
1870 'headertextweight',
1871 'posttags',
1872 'linkhashtags',
1873 'offset',
1874 'cff_enqueue_with_shortcode',
1875 'commentsnum',
1876 'restrictedpage',
1877 'hidesupporterposts',
1878 'privategroup',
1879 'fulllinkimages',
1880 'linkimagesize',
1881 'postimagesize',
1882 'videoheight',
1883 'videoaction',
1884 'videoplayer',
1885 'class',
1886 'padding'
1887 ];
1888
1889 foreach ($maybe_legacy_shortcode as $maybe_legacy => $value) {
1890 if (in_array($maybe_legacy, $legacy_shortcode_settings, true)) {
1891 $settings[ $maybe_legacy ] = $value;
1892 }
1893 }
1894
1895 if ($settings['posttags'] === 'false') {
1896 $settings['posttags'] = false;
1897 }
1898
1899 if ($settings['linkhashtags'] === 'false') {
1900 $settings['linkhashtags'] = false;
1901 }
1902 }
1903
1904 if (! CFF_Utils::cff_is_pro_version()) {
1905 $this->page_id = $settings['id'];
1906 $encryption = new SB_Facebook_Data_Encryption();
1907 $this->access_token = $encryption->decrypt($settings['accesstoken']) ? $encryption->decrypt($settings['accesstoken']) : $settings['accesstoken'];
1908 $this->feed_id = ! empty($feed_id) ? $feed_id : 'default';
1909 }
1910
1911 return \CustomFacebookFeed\Builder\CFF_Post_Set::builder_to_general_settings_convert($settings);
1912 }
1913
1914 public static function cff_get_json_data($feed_options, $next_urls_arr_safe, $data_att_html, $is_customizer = false)
1915 {
1916 $page_access_token = $feed_options['pagetoken'];
1917 $page_id = trim($feed_options['id']);
1918 $page_ids = [$page_id];
1919 $feed_id = isset($feed_options['the_feed_id']) && $feed_options['the_feed_id'] !== false ? $feed_options['the_feed_id'] : false;
1920 $FBdata_arr = [];
1921 // Loop through page IDs
1922 foreach ($page_ids as $page_id) {
1923 // Are there more posts to get for this ID?
1924 $graph_data = new CFF_Graph_Data($page_id, $page_ids, $feed_id, $feed_options, $data_att_html, $next_urls_arr_safe, $is_customizer, $FBdata_arr);
1925 $feed_data = $graph_data->get_feed_data();
1926 $FBdata = $feed_data !== 'no_more_posts' ? json_decode($feed_data) : $feed_data;
1927 $FBdata_arr[$page_id] = $FBdata;
1928 } //End page_id loop
1929 return $FBdata_arr;
1930 }
1931
1932
1933 /**
1934 * this function breaks up the "next" url from the json data into an array of parts to load into
1935 * the html to be retrieved on click and pieced back together
1936 *
1937 * @since 3.18
1938 */
1939 public static function cff_get_next_url_parts($json_data_arr)
1940 {
1941 $next_urls_arr_safe = '{';
1942 $next_urls_arr_safe .= '}';
1943 // If the array ends in a comma then remove the comma
1944 return $next_urls_arr_safe;
1945 }
1946
1947 public static function get_single_event_data($eventID, $access_token)
1948 {
1949 $encryption = new SB_Facebook_Data_Encryption();
1950
1951 // Is it SSL?
1952 $cff_ssl = '';
1953 if (is_ssl()) {
1954 $cff_ssl = '&return_ssl_resources=true';
1955 }
1956
1957 // Get the contents of the event
1958 $event_json_url = 'https://graph.facebook.com/v23.0/' . $eventID . '?fields=cover,place,name,owner,start_time,timezone,id,comments.summary(true){message,created_time},description&access_token=' . $access_token . $cff_ssl;
1959
1960 // Get any existing copy of our transient data
1961 $transient_name = 'cff_tle_' . $eventID;
1962 $transient_name = substr($transient_name, 0, 45);
1963
1964 if (false === ( $event_json = $encryption->maybe_decrypt(get_transient($transient_name)) ) || $event_json === null) {
1965 // Get the contents of the Facebook page
1966 $event_json = CFF_Utils::cff_fetchUrl($event_json_url);
1967 // Cache the JSON for 180 days as the timeline event info probably isn't going to change
1968 set_transient($transient_name, $encryption->maybe_encrypt($event_json), 60 * 60 * 24 * 180);
1969 } else {
1970 $event_json = $encryption->maybe_decrypt(get_transient($transient_name));
1971 // If we can't find the transient then fall back to just getting the json from the api
1972 if ($event_json == false) {
1973 $event_json = CFF_Utils::cff_fetchUrl($event_json_url);
1974 }
1975 }
1976
1977 // Interpret data with JSON
1978 $event_object = json_decode($event_json);
1979
1980 $description_text = '';
1981 if (isset($event_object->name)) {
1982 $description_text .= $event_object->name . ' ';
1983 }
1984 if (isset($event_object->place->location->city)) {
1985 $description_text .= $event_object->place->location->city . ' ';
1986 }
1987 if (isset($event_object->place->location->country)) {
1988 $description_text .= $event_object->place->location->country . ' ';
1989 }
1990 if (isset($event_object->place->location->street)) {
1991 $description_text .= $event_object->place->location->street . ' ';
1992 }
1993 if (isset($event_object->place->name)) {
1994 $description_text .= $event_object->place->name . ' ';
1995 }
1996 if (isset($event_object->description)) {
1997 $description_text .= $event_object->description;
1998 }
1999 $event_object->description_text = $description_text;
2000
2001 return $event_object;
2002 }
2003
2004 public static function add_translations($atts)
2005 {
2006 $translations = get_option('cff_style_settings', false);
2007
2008 $final_translations = [
2009 'seemoretext' => isset($translations[ 'cff_see_more_text' ]) ? stripslashes(esc_attr($translations[ 'cff_see_more_text' ])) : __('See More', 'custom-facebook-feed'),
2010 'seelesstext' => isset($translations[ 'cff_see_less_text' ]) ? stripslashes(esc_attr($translations[ 'cff_see_less_text' ])) : __('See Less', 'custom-facebook-feed'),
2011 'facebooklinktext' => isset($translations[ 'cff_facebook_link_text' ]) ? stripslashes(esc_attr($translations[ 'cff_facebook_link_text' ])) : __('View on Facebook', 'custom-facebook-feed'),
2012 'sharelinktext' => isset($translations[ 'cff_facebook_share_text' ]) ? stripslashes(esc_attr($translations[ 'cff_facebook_share_text' ])) : __('Share', 'custom-facebook-feed'),
2013
2014 'learnmoretext' => isset($translations[ 'cff_translate_learn_more_text' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_learn_more_text' ])) : __('Learn More', 'custom-facebook-feed'),
2015 'shopnowtext' => isset($translations[ 'cff_translate_shop_now_text' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_shop_now_text' ])) : __('Shop Now', 'custom-facebook-feed'),
2016 'messagepage' => isset($translations[ 'cff_translate_message_page_text' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_message_page_text' ])) : __('Message Page', 'custom-facebook-feed'),
2017 'getdirections' => isset($translations[ 'cff_translate_get_directions_text' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_get_directions_text' ])) : __('Get Directions', 'custom-facebook-feed'),
2018
2019 'secondtext' => isset($translations[ 'cff_translate_second' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_second' ])) : 'second',
2020 'secondstext' => isset($translations[ 'cff_translate_seconds' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_seconds' ])) : 'seconds',
2021 'minutetext' => isset($translations[ 'cff_translate_minute' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_minute' ])) : 'minute',
2022 'minutestext' => isset($translations[ 'cff_translate_minutes' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_minutes' ])) : 'minutes',
2023 'hourtext' => isset($translations[ 'cff_translate_hour' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_hour' ])) : 'hour',
2024 'hourstext' => isset($translations[ 'cff_translate_hours' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_hours' ])) : 'hours',
2025 'daytext' => isset($translations[ 'cff_translate_day' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_day' ])) : 'day',
2026 'daystext' => isset($translations[ 'cff_translate_days' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_days' ])) : 'days',
2027 'weektext' => isset($translations[ 'cff_translate_week' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_week' ])) : 'week',
2028 'weekstext' => isset($translations[ 'cff_translate_weeks' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_weeks' ])) : 'weeks',
2029 'monthtext' => isset($translations[ 'cff_translate_month' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_month' ])) : 'month',
2030 'monthstext' => isset($translations[ 'cff_translate_months' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_months' ])) : 'months',
2031 'yeartext' => isset($translations[ 'cff_translate_year' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_year' ])) : 'year',
2032 'yearstext' => isset($translations[ 'cff_translate_years' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_years' ])) : 'years',
2033 'agotext' => isset($translations[ 'cff_translate_ago' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_ago' ])) : 'ago',
2034
2035 'phototext' => isset($translations[ 'cff_translate_photo_text' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_photo_text' ])) : '',
2036 'videotext' => isset($translations[ 'cff_translate_video_text' ]) ? stripslashes(esc_attr($translations[ 'cff_translate_video_text' ])) : '',
2037 ];
2038
2039
2040 $final_translations['facebooklinktext'] = ! empty($atts['facebooklinktext']) ? $atts['facebooklinktext'] : $final_translations['facebooklinktext'];
2041 $final_translations['sharelinktext'] = ! empty($atts['sharelinktext']) ? $atts['sharelinktext'] : $final_translations['sharelinktext'];
2042
2043 $atts = array_merge($atts, $final_translations);
2044
2045 return $atts;
2046 }
2047
2048 public function cff_add_translations()
2049 {
2050 $this->atts = CFF_Shortcode::add_translations($this->atts);
2051 }
2052 }
2053