PluginProbe
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress / 2.16
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress v2.16
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 All 171 releases
custom-facebook-feed / custom-facebook-feed.php
custom-facebook-feed.php
3,395 lines 175.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Smash Balloon Custom Facebook Feed
4 Plugin URI: https://smashballoon.com/custom-facebook-feed
5 Description: Add completely customizable Facebook feeds to your WordPress site
6 Version: 2.16
7 Author: Smash Balloon
8 Author URI: http://smashballoon.com/
9 License: GPLv2 or later
10 Text Domain: custom-facebook-feed
11 */
12 /*
13 Copyright 2020 Smash Balloon LLC (email : hey@smashballoon.com)
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 define('CFFVER', '2.16');
28
29 // Db version.
30 if ( ! defined( 'CFF_DBVERSION' ) ) {
31 define( 'CFF_DBVERSION', '1.1' );
32 }
33
34 // Plugin Folder Path.
35 if ( ! defined( 'CFF_PLUGIN_DIR' ) ) {
36 define( 'CFF_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
37 }
38 // Plugin Folder URL.
39 if ( ! defined( 'CFF_PLUGIN_URL' ) ) {
40 define( 'CFF_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
41 }
42
43 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
44 //Include admin
45 include dirname( __FILE__ ) .'/custom-facebook-feed-admin.php';
46
47 function cff_check_for_db_updates() {
48 $db_ver = get_option( 'cff_db_version', 0 );
49 if ( (float) $db_ver < 1.0 ) {
50 global $wp_roles;
51 $wp_roles->add_cap( 'administrator', 'manage_custom_facebook_feed_options' );
52 $cff_statuses_option = get_option( 'cff_statuses', array() );
53 if ( ! isset( $cff_statuses_option['first_install'] ) ) {
54 $options_set = get_option( 'cff_page_id', false );
55 if ( $options_set ) {
56 $cff_statuses_option['first_install'] = 'from_update';
57 } else {
58 $cff_statuses_option['first_install'] = time();
59 }
60 $cff_rating_notice_option = get_option( 'cff_rating_notice', false );
61 if ( $cff_rating_notice_option === 'dismissed' ) {
62 $cff_statuses_option['rating_notice_dismissed'] = time();
63 }
64 $cff_rating_notice_waiting = get_transient( 'custom_facebook_rating_notice_waiting' );
65 if ( $cff_rating_notice_waiting === false
66 && $cff_rating_notice_option === false ) {
67 $time = 2 * WEEK_IN_SECONDS;
68 set_transient( 'custom_facebook_rating_notice_waiting', 'waiting', $time );
69 update_option( 'cff_rating_notice', 'pending', false );
70 }
71 update_option( 'cff_statuses', $cff_statuses_option, false );
72 }
73 update_option( 'cff_db_version', CFF_DBVERSION );
74 }
75
76 if ( (float) $db_ver < 1.1 ) {
77 if ( ! wp_next_scheduled( 'cff_feed_issue_email' ) ) {
78 $timestamp = strtotime( 'next monday' );
79 $timestamp = $timestamp + (3600 * 24 * 7);
80 $six_am_local = $timestamp + cff_get_utc_offset() + (6*60*60);
81
82 wp_schedule_event( $six_am_local, 'cffweekly', 'cff_feed_issue_email' );
83 }
84
85
86 update_option( 'cff_db_version', CFF_DBVERSION );
87 }
88 }
89 add_action( 'wp_loaded', 'cff_check_for_db_updates' );
90
91 function cff_plugin_init() {
92 include_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/class-cff-tracking.php';
93 include_once trailingslashit( CFF_PLUGIN_DIR ) . 'inc/class-cff-parse.php';
94
95 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'class-cff-error-reporter.php';
96 global $cff_error_reporter;
97 $cff_error_reporter = new CFF_Error_Reporter();
98
99 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'blocks/class-cff-blocks.php';
100 $cff_blocks = new CFF_Blocks();
101 if ( $cff_blocks->allow_load() ) {
102 $cff_blocks->load();
103 }
104
105 if ( is_admin() ) {
106 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/class-cff-about.php';
107
108 if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0
109 && version_compare( get_bloginfo('version'), '4.6' , '>' ) ) {
110 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/addon-functions.php';
111 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/PluginSilentUpgrader.php';
112 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/PluginSilentUpgraderSkin.php';
113 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/class-install-skin.php';
114 }
115
116 require_once trailingslashit( CFF_PLUGIN_DIR ) . 'class-cff-sitehealth.php';
117 $cff_sitehealth = new CFF_SiteHealth();
118 if ( $cff_sitehealth->allow_load() ) {
119 $cff_sitehealth->load();
120 }
121 }
122 }
123
124 add_action( 'plugins_loaded', 'cff_plugin_init' );
125
126 function cff_get_utc_offset() {
127 return get_option( 'gmt_offset', 0 ) * HOUR_IN_SECONDS;
128 }
129
130 function cff_schedule_report_email() {
131 $options = get_option('cff_style_settings');
132
133 $input = isset( $options[ 'email_notification' ] ) ? $options[ 'email_notification' ] : 'monday';
134 $timestamp = strtotime( 'next ' . $input );
135 $timestamp = $timestamp + (3600 * 24 * 7);
136
137 $six_am_local = $timestamp + cff_get_utc_offset() + (6*60*60);
138
139 wp_schedule_event( $six_am_local, 'cffweekly', 'cff_feed_issue_email' );
140 }
141
142 function cff_text_domain() {
143 load_plugin_textdomain( 'custom-facebook-feed', false, basename( dirname(__FILE__) ) . '/languages' );
144 }
145 add_action( 'plugins_loaded', 'cff_text_domain' );
146
147 // Add shortcodes
148 add_shortcode('custom-facebook-feed', 'display_cff');
149 function display_cff($atts) {
150
151 //Style options
152 $options = get_option('cff_style_settings');
153 //Create the types string to set as shortcode default
154 $include_string = '';
155 if($options[ 'cff_show_author' ]) $include_string .= 'author,';
156 if($options[ 'cff_show_text' ]) $include_string .= 'text,';
157 if($options[ 'cff_show_desc' ]) $include_string .= 'desc,';
158 if($options[ 'cff_show_shared_links' ]) $include_string .= 'sharedlinks,';
159 if($options[ 'cff_show_date' ]) $include_string .= 'date,';
160 if($options[ 'cff_show_media' ]) $include_string .= 'media,';
161 if( isset($options[ 'cff_show_media_link' ]) ){ //If not set yet then show link by default
162 if($options[ 'cff_show_media_link' ]) $include_string .= 'medialink,';
163 } else {
164 $include_string .= 'medialink,';
165 }
166 if($options[ 'cff_show_event_title' ]) $include_string .= 'eventtitle,';
167 if($options[ 'cff_show_event_details' ]) $include_string .= 'eventdetails,';
168 if($options[ 'cff_show_meta' ]) $include_string .= 'social,';
169 if($options[ 'cff_show_link' ]) $include_string .= 'link,';
170 if($options[ 'cff_show_like_box' ]) $include_string .= 'likebox,';
171 //Pass in shortcode attrbutes
172 $atts = shortcode_atts(
173 array(
174 'accesstoken' => trim( get_option('cff_access_token') ),
175 'id' => get_option('cff_page_id'),
176 'pagetype' => get_option('cff_page_type'),
177 'num' => get_option('cff_num_show'),
178 'limit' => get_option('cff_post_limit'),
179 'others' => '',
180 'showpostsby' => get_option('cff_show_others'),
181 'cachetime' => get_option('cff_cache_time'),
182 'cacheunit' => get_option('cff_cache_time_unit'),
183 'locale' => get_option('cff_locale'),
184 'ajax' => get_option('cff_ajax'),
185 'offset' => '',
186 'account' => '',
187
188 //General
189 'width' => isset($options[ 'cff_feed_width' ]) ? $options[ 'cff_feed_width' ] : '',
190 'widthresp' => isset($options[ 'cff_feed_width_resp' ]) ? $options[ 'cff_feed_width_resp' ] : '',
191 'height' => isset($options[ 'cff_feed_height' ]) ? $options[ 'cff_feed_height' ] : '',
192 'padding' => isset($options[ 'cff_feed_padding' ]) ? $options[ 'cff_feed_padding' ] : '',
193 'bgcolor' => isset($options[ 'cff_bg_color' ]) ? $options[ 'cff_bg_color' ] : '',
194 'showauthor' => '',
195 'showauthornew' => isset($options[ 'cff_show_author' ]) ? $options[ 'cff_show_author' ] : '',
196 'class' => isset($options[ 'cff_class' ]) ? $options[ 'cff_class' ] : '',
197 'layout' => isset($options[ 'cff_preset_layout' ]) ? $options[ 'cff_preset_layout' ] : '',
198 'include' => $include_string,
199 'exclude' => '',
200
201 //Cols
202 'cols' => isset($options[ 'cff_cols' ]) ? $options[ 'cff_cols' ] : '',
203 'colsmobile' => isset($options[ 'cff_cols_mobile' ]) ? $options[ 'cff_cols_mobile' ] : '',
204 'colsjs' => true,
205
206 //Mobile settings
207 'nummobile' => isset($options[ 'cff_num_mobile' ]) ? max( 0, (int)$options[ 'cff_num_mobile' ] ) : '',
208
209 //Post Style
210 'poststyle' => isset($options[ 'cff_post_style' ]) ? $options[ 'cff_post_style' ] : '',
211 'postbgcolor' => isset($options[ 'cff_post_bg_color' ]) ? $options[ 'cff_post_bg_color' ] : '',
212 'postcorners' => isset($options[ 'cff_post_rounded' ]) ? $options[ 'cff_post_rounded' ] : '',
213 'boxshadow' => isset($options[ 'cff_box_shadow' ]) ? $options[ 'cff_box_shadow' ] : '',
214
215 //Typography
216 'textformat' => isset($options[ 'cff_title_format' ]) ? $options[ 'cff_title_format' ] : '',
217 'textsize' => isset($options[ 'cff_title_size' ]) ? $options[ 'cff_title_size' ] : '',
218 'textweight' => isset($options[ 'cff_title_weight' ]) ? $options[ 'cff_title_weight' ] : '',
219 'textcolor' => isset($options[ 'cff_title_color' ]) ? $options[ 'cff_title_color' ] : '',
220 'textlinkcolor' => isset($options[ 'cff_posttext_link_color' ]) ? $options[ 'cff_posttext_link_color' ] : '',
221 'textlink' => isset($options[ 'cff_title_link' ]) ? $options[ 'cff_title_link' ] : '',
222 'posttags' => isset($options[ 'cff_post_tags' ]) ? $options[ 'cff_post_tags' ] : '',
223 'linkhashtags' => isset($options[ 'cff_link_hashtags' ]) ? $options[ 'cff_link_hashtags' ] : '',
224
225 //Description
226 'descsize' => isset($options[ 'cff_body_size' ]) ? $options[ 'cff_body_size' ] : '',
227 'descweight' => isset($options[ 'cff_body_weight' ]) ? $options[ 'cff_body_weight' ] : '',
228 'desccolor' => isset($options[ 'cff_body_color' ]) ? $options[ 'cff_body_color' ] : '',
229 'linktitleformat' => isset($options[ 'cff_link_title_format' ]) ? $options[ 'cff_link_title_format' ] : '',
230 'linktitlesize' => isset($options[ 'cff_link_title_size' ]) ? $options[ 'cff_link_title_size' ] : '',
231 'linkdescsize' => isset($options[ 'cff_link_desc_size' ]) ? $options[ 'cff_link_desc_size' ] : '',
232 'linkurlsize' => isset($options[ 'cff_link_url_size' ]) ? $options[ 'cff_link_url_size' ] : '',
233 'linkdesccolor' => isset($options[ 'cff_link_desc_color' ]) ? $options[ 'cff_link_desc_color' ] : '',
234 'linktitlecolor' => isset($options[ 'cff_link_title_color' ]) ? $options[ 'cff_link_title_color' ] : '',
235 'linkurlcolor' => isset($options[ 'cff_link_url_color' ]) ? $options[ 'cff_link_url_color' ] : '',
236 'linkbgcolor' => isset($options[ 'cff_link_bg_color' ]) ? $options[ 'cff_link_bg_color' ] : '',
237 'linkbordercolor' => isset($options[ 'cff_link_border_color' ]) ? $options[ 'cff_link_border_color' ] : '',
238 'disablelinkbox' => isset($options[ 'cff_disable_link_box' ]) ? $options[ 'cff_disable_link_box' ] : '',
239
240 //Author
241 'authorsize' => isset($options[ 'cff_author_size' ]) ? $options[ 'cff_author_size' ] : '',
242 'authorcolor' => isset($options[ 'cff_author_color' ]) ? $options[ 'cff_author_color' ] : '',
243
244 //Event title
245 'eventtitleformat' => isset($options[ 'cff_event_title_format' ]) ? $options[ 'cff_event_title_format' ] : '',
246 'eventtitlesize' => isset($options[ 'cff_event_title_size' ]) ? $options[ 'cff_event_title_size' ] : '',
247 'eventtitleweight' => isset($options[ 'cff_event_title_weight' ]) ? $options[ 'cff_event_title_weight' ] : '',
248 'eventtitlecolor' => isset($options[ 'cff_event_title_color' ]) ? $options[ 'cff_event_title_color' ] : '',
249 'eventtitlelink' => isset($options[ 'cff_event_title_link' ]) ? $options[ 'cff_event_title_link' ] : '',
250 //Event date
251 'eventdatesize' => isset($options[ 'cff_event_date_size' ]) ? $options[ 'cff_event_date_size' ] : '',
252 'eventdateweight' => isset($options[ 'cff_event_date_weight' ]) ? $options[ 'cff_event_date_weight' ] : '',
253 'eventdatecolor' => isset($options[ 'cff_event_date_color' ]) ? $options[ 'cff_event_date_color' ] : '',
254 'eventdatepos' => isset($options[ 'cff_event_date_position' ]) ? $options[ 'cff_event_date_position' ] : '',
255 'eventdateformat' => isset($options[ 'cff_event_date_formatting' ]) ? $options[ 'cff_event_date_formatting' ] : '',
256 'eventdatecustom' => isset($options[ 'cff_event_date_custom' ]) ? $options[ 'cff_event_date_custom' ] : '',
257 //Event details
258 'eventdetailssize' => isset($options[ 'cff_event_details_size' ]) ? $options[ 'cff_event_details_size' ] : '',
259 'eventdetailsweight' => isset($options[ 'cff_event_details_weight' ]) ? $options[ 'cff_event_details_weight' ] : '',
260 'eventdetailscolor' => isset($options[ 'cff_event_details_color' ]) ? $options[ 'cff_event_details_color' ] : '',
261 'eventlinkcolor' => isset($options[ 'cff_event_link_color' ]) ? $options[ 'cff_event_link_color' ] : '',
262 //Date
263 'datepos' => isset($options[ 'cff_date_position' ]) ? $options[ 'cff_date_position' ] : '',
264 'datesize' => isset($options[ 'cff_date_size' ]) ? $options[ 'cff_date_size' ] : '',
265 'dateweight' => isset($options[ 'cff_date_weight' ]) ? $options[ 'cff_date_weight' ] : '',
266 'datecolor' => isset($options[ 'cff_date_color' ]) ? $options[ 'cff_date_color' ] : '',
267 'dateformat' => isset($options[ 'cff_date_formatting' ]) ? $options[ 'cff_date_formatting' ] : '',
268 'datecustom' => isset($options[ 'cff_date_custom' ]) ? $options[ 'cff_date_custom' ] : '',
269 'timezone' => isset($options[ 'cff_timezone' ]) ? $options[ 'cff_timezone' ] : 'America/Chicago',
270
271 //Link to Facebook
272 'linksize' => isset($options[ 'cff_link_size' ]) ? $options[ 'cff_link_size' ] : '',
273 'linkweight' => isset($options[ 'cff_link_weight' ]) ? $options[ 'cff_link_weight' ] : '',
274 'linkcolor' => isset($options[ 'cff_link_color' ]) ? $options[ 'cff_link_color' ] : '',
275 'viewlinktext' => isset($options[ 'cff_view_link_text' ]) ? $options[ 'cff_view_link_text' ] : '',
276 'linktotimeline' => isset($options[ 'cff_link_to_timeline' ]) ? $options[ 'cff_link_to_timeline' ] : '',
277 //Social
278 'iconstyle' => isset($options[ 'cff_icon_style' ]) ? $options[ 'cff_icon_style' ] : '',
279 'socialtextcolor' => isset($options[ 'cff_meta_text_color' ]) ? $options[ 'cff_meta_text_color' ] : '',
280 'socialbgcolor' => isset($options[ 'cff_meta_bg_color' ]) ? $options[ 'cff_meta_bg_color' ] : '',
281 //Misc
282 'textlength' => get_option('cff_title_length'),
283 'desclength' => get_option('cff_body_length'),
284 'likeboxpos' => isset($options[ 'cff_like_box_position' ]) ? $options[ 'cff_like_box_position' ] : '',
285 'likeboxoutside' => isset($options[ 'cff_like_box_outside' ]) ? $options[ 'cff_like_box_outside' ] : '',
286 'likeboxcolor' => isset($options[ 'cff_likebox_bg_color' ]) ? $options[ 'cff_likebox_bg_color' ] : '',
287 'likeboxtextcolor' => isset($options[ 'cff_like_box_text_color' ]) ? $options[ 'cff_like_box_text_color' ] : '',
288 'likeboxwidth' => isset($options[ 'cff_likebox_width' ]) ? $options[ 'cff_likebox_width' ] : '',
289 'likeboxheight' => isset($options[ 'cff_likebox_height' ]) ? $options[ 'cff_likebox_height' ] : '',
290 'likeboxfaces' => isset($options[ 'cff_like_box_faces' ]) ? $options[ 'cff_like_box_faces' ] : '',
291 'likeboxborder' => isset($options[ 'cff_like_box_border' ]) ? $options[ 'cff_like_box_border' ] : '',
292 'likeboxcover' => isset($options[ 'cff_like_box_cover' ]) ? $options[ 'cff_like_box_cover' ] : '',
293 'likeboxsmallheader' => isset($options[ 'cff_like_box_small_header' ]) ? $options[ 'cff_like_box_small_header' ] : '',
294 'likeboxhidebtn' => isset($options[ 'cff_like_box_hide_cta' ]) ? $options[ 'cff_like_box_hide_cta' ] : '',
295
296 'credit' => isset($options[ 'cff_show_credit' ]) ? $options[ 'cff_show_credit' ] : '',
297 'nofollow' => 'true',
298 'disablestyles' => isset($options[ 'cff_disable_styles' ]) ? $options[ 'cff_disable_styles' ] : '',
299 'textissue' => isset($options[ 'cff_format_issue' ]) ? $options[ 'cff_format_issue' ] : '',
300 'restrictedpage' => isset($options[ 'cff_restricted_page' ]) ? $options[ 'cff_restricted_page' ] : '',
301
302 //Page Header
303 'showheader' => isset($options[ 'cff_show_header' ]) ? $options[ 'cff_show_header' ] : '',
304 'headeroutside' => isset($options[ 'cff_header_outside' ]) ? $options[ 'cff_header_outside' ] : '',
305 'headertype' => isset($options[ 'cff_header_type' ]) ? $options[ 'cff_header_type' ] : '',
306 'headercover' => isset($options[ 'cff_header_cover' ]) ? $options[ 'cff_header_cover' ] : '',
307 'headeravatar' => isset($options[ 'cff_header_avatar' ]) ? $options[ 'cff_header_avatar' ] : '',
308 'headername' => isset($options[ 'cff_header_name' ]) ? $options[ 'cff_header_name' ] : '',
309 'headerbio' => isset($options[ 'cff_header_bio' ]) ? $options[ 'cff_header_bio' ] : '',
310 'headercoverheight' => isset($options[ 'cff_header_cover_height' ]) ? $options[ 'cff_header_cover_height' ] : '',
311 'headertext' => isset($options[ 'cff_header_text' ]) ? $options[ 'cff_header_text' ] : '',
312 'headerbg' => isset($options[ 'cff_header_bg_color' ]) ? $options[ 'cff_header_bg_color' ] : '',
313 'headerpadding' => isset($options[ 'cff_header_padding' ]) ? $options[ 'cff_header_padding' ] : '',
314 'headertextsize' => isset($options[ 'cff_header_text_size' ]) ? $options[ 'cff_header_text_size' ] : '',
315 'headertextweight' => isset($options[ 'cff_header_text_weight' ]) ? $options[ 'cff_header_text_weight' ] : '',
316 'headertextcolor' => isset($options[ 'cff_header_text_color' ]) ? $options[ 'cff_header_text_color' ] : '',
317 'headericon' => isset($options[ 'cff_header_icon' ]) ? $options[ 'cff_header_icon' ] : '',
318 'headericoncolor' => isset($options[ 'cff_header_icon_color' ]) ? $options[ 'cff_header_icon_color' ] : '',
319 'headericonsize' => isset($options[ 'cff_header_icon_size' ]) ? $options[ 'cff_header_icon_size' ] : '',
320 'headerinc' => '',
321 'headerexclude' => '',
322
323 'videoheight' => isset($options[ 'cff_video_height' ]) ? $options[ 'cff_video_height' ] : '',
324 'videoaction' => isset($options[ 'cff_video_action' ]) ? $options[ 'cff_video_action' ] : '',
325 'sepcolor' => isset($options[ 'cff_sep_color' ]) ? $options[ 'cff_sep_color' ] : '',
326 'sepsize' => isset($options[ 'cff_sep_size' ]) ? $options[ 'cff_sep_size' ] : '',
327
328 //Translate
329 'seemoretext' => isset( $options[ 'cff_see_more_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_see_more_text' ] ) ) : '',
330 'seelesstext' => isset( $options[ 'cff_see_less_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_see_less_text' ] ) ) : '',
331 'photostext' => isset( $options[ 'cff_translate_photos_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_photos_text' ] ) ) : '',
332 'phototext' => isset( $options[ 'cff_translate_photo_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_photo_text' ] ) ) : '',
333 'videotext' => isset( $options[ 'cff_translate_video_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_video_text' ] ) ) : '',
334
335 'learnmoretext' => isset( $options[ 'cff_translate_learn_more_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_learn_more_text' ] ) ) : '',
336 'shopnowtext' => isset( $options[ 'cff_translate_shop_now_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_shop_now_text' ] ) ) : '',
337 'messagepage' => isset( $options[ 'cff_translate_message_page_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_message_page_text' ] ) ) : '',
338
339 'facebooklinktext' => isset( $options[ 'cff_facebook_link_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_facebook_link_text' ] ) ) : '',
340 'sharelinktext' => isset( $options[ 'cff_facebook_share_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_facebook_share_text' ] ) ) : '',
341 'showfacebooklink' => isset($options[ 'cff_show_facebook_link' ]) ? $options[ 'cff_show_facebook_link' ] : '',
342 'showsharelink' => isset($options[ 'cff_show_facebook_share' ]) ? $options[ 'cff_show_facebook_share' ] : '',
343
344 'secondtext' => isset( $options[ 'cff_translate_second' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_second' ] ) ) : 'second',
345 'secondstext' => isset( $options[ 'cff_translate_seconds' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_seconds' ] ) ) : 'seconds',
346 'minutetext' => isset( $options[ 'cff_translate_minute' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_minute' ] ) ) : 'minute',
347 'minutestext' => isset( $options[ 'cff_translate_minutes' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_minutes' ] ) ) : 'minutes',
348 'hourtext' => isset( $options[ 'cff_translate_hour' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_hour' ] ) ) : 'hour',
349 'hourstext' => isset( $options[ 'cff_translate_hours' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_hours' ] ) ) : 'hours',
350 'daytext' => isset( $options[ 'cff_translate_day' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_day' ] ) ) : 'day',
351 'daystext' => isset( $options[ 'cff_translate_days' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_days' ] ) ) : 'days',
352 'weektext' => isset( $options[ 'cff_translate_week' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_week' ] ) ) : 'week',
353 'weekstext' => isset( $options[ 'cff_translate_weeks' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_weeks' ] ) ) : 'weeks',
354 'monthtext' => isset( $options[ 'cff_translate_month' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_month' ] ) ) : 'month',
355 'monthstext' => isset( $options[ 'cff_translate_months' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_months' ] ) ) : 'months',
356 'yeartext' => isset( $options[ 'cff_translate_year' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_year' ] ) ) : 'year',
357 'yearstext' => isset( $options[ 'cff_translate_years' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_years' ] ) ) : 'years',
358 'agotext' => isset( $options[ 'cff_translate_ago' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_ago' ] ) ) : 'ago'
359
360 ), $atts);
361
362 /********** GENERAL **********/
363 $cff_page_type = $atts[ 'pagetype' ];
364 ($cff_page_type == 'group') ? $cff_is_group = true : $cff_is_group = false;
365
366 $cff_feed_width = $atts[ 'width' ];
367 if ( is_numeric(substr($cff_feed_width, -1, 1)) ) $cff_feed_width = $cff_feed_width . 'px';
368
369 //Set to be 100% width on mobile?
370 $cff_feed_width_resp = $atts[ 'widthresp' ];
371 ( $cff_feed_width_resp == 'on' || $cff_feed_width_resp == 'true' || $cff_feed_width_resp == true ) ? $cff_feed_width_resp = true : $cff_feed_width_resp = false;
372 if( $atts[ 'widthresp' ] == 'false' ) $cff_feed_width_resp = false;
373
374 $cff_feed_height = $atts[ 'height' ];
375 if ( is_numeric(substr($cff_feed_height, -1, 1)) ) $cff_feed_height = $cff_feed_height . 'px';
376
377 $cff_feed_padding = $atts[ 'padding' ];
378 if ( is_numeric(substr($cff_feed_padding, -1, 1)) ) $cff_feed_padding = $cff_feed_padding . 'px';
379
380 $cff_bg_color = $atts[ 'bgcolor' ];
381 $cff_show_author = $atts[ 'showauthornew' ];
382 $cff_cache_time = $atts[ 'cachetime' ];
383 $cff_locale = $atts[ 'locale' ];
384 if ( empty($cff_locale) || !isset($cff_locale) || $cff_locale == '' ) $cff_locale = 'en_US';
385 if (!isset($cff_cache_time)) $cff_cache_time = '0';
386 $cff_cache_time_unit = $atts[ 'cacheunit' ];
387
388 if($cff_cache_time == 'nocaching') $cff_cache_time = 0;
389
390 $cff_class = $atts['class'];
391 //Compile feed styles
392 $cff_feed_styles = '';
393 if( !empty($cff_feed_width) || !empty($cff_feed_height) || !empty($cff_feed_padding) || (!empty($cff_bg_color) && $cff_bg_color !== '#') ) $cff_feed_styles = 'style="';
394 if ( !empty($cff_feed_width) ) $cff_feed_styles .= 'width:' . $cff_feed_width . '; ';
395 if ( !empty($cff_feed_height) ) $cff_feed_styles .= 'height:' . $cff_feed_height . '; ';
396 if ( !empty($cff_feed_padding) ) $cff_feed_styles .= 'padding:' . $cff_feed_padding . '; ';
397 if ( !empty($cff_bg_color) && $cff_bg_color !== '#' ) $cff_feed_styles .= 'background-color:#' . str_replace('#', '', $cff_bg_color) . '; ';
398 if( !empty($cff_feed_width) || !empty($cff_feed_height) || !empty($cff_feed_padding) || (!empty($cff_bg_color) && $cff_bg_color !== '#') ) $cff_feed_styles .= '"';
399 //Like box
400 $cff_like_box_position = $atts[ 'likeboxpos' ];
401 $cff_like_box_outside = $atts[ 'likeboxoutside' ];
402 //Open links in new window?
403 $target = 'target="_blank"';
404 /********** POST TYPES **********/
405 $cff_show_links_type = true;
406 $cff_show_event_type = true;
407 $cff_show_video_type = true;
408 $cff_show_photos_type = true;
409 $cff_show_status_type = true;
410 $cff_show_albums_type = true;
411 $cff_events_only = false;
412 //Are we showing ONLY events?
413 if ($cff_show_event_type && !$cff_show_links_type && !$cff_show_video_type && !$cff_show_photos_type && !$cff_show_status_type) $cff_events_only = true;
414 /********** LAYOUT **********/
415 $cff_includes = $atts[ 'include' ];
416 //Look for non-plural version of string in the types string in case user specifies singular in shortcode
417 $cff_show_author = false;
418 $cff_show_text = false;
419 $cff_show_desc = false;
420 $cff_show_shared_links = false;
421 $cff_show_date = false;
422 $cff_show_media = false;
423 $cff_show_media_link = false;
424 $cff_show_event_title = false;
425 $cff_show_event_details = false;
426 $cff_show_meta = false;
427 $cff_show_link = false;
428 $cff_show_like_box = false;
429 if ( stripos($cff_includes, 'author') !== false ) $cff_show_author = true;
430 if ( stripos($cff_includes, 'text') !== false ) $cff_show_text = true;
431 if ( stripos($cff_includes, 'desc') !== false ) $cff_show_desc = true;
432 if ( stripos($cff_includes, 'sharedlink') !== false ) $cff_show_shared_links = true;
433 if ( stripos($cff_includes, 'date') !== false ) $cff_show_date = true;
434 if ( stripos($cff_includes, 'media') !== false ) $cff_show_media = true;
435 if ( stripos($cff_includes, 'medialink') !== false ) $cff_show_media_link = true;
436 if ( stripos($cff_includes, 'eventtitle') !== false ) $cff_show_event_title = true;
437 if ( stripos($cff_includes, 'eventdetail') !== false ) $cff_show_event_details = true;
438 if ( stripos($cff_includes, 'social') !== false ) $cff_show_meta = true;
439 if ( stripos($cff_includes, ',link') !== false ) $cff_show_link = true; //comma used to separate it from 'sharedlinks' - which also contains 'link' string
440 if ( stripos($cff_includes, 'like') !== false ) $cff_show_like_box = true;
441
442
443 //Exclude string
444 $cff_excludes = $atts[ 'exclude' ];
445 //Look for non-plural version of string in the types string in case user specifies singular in shortcode
446 if ( stripos($cff_excludes, 'author') !== false ) $cff_show_author = false;
447 if ( stripos($cff_excludes, 'text') !== false ) $cff_show_text = false;
448 if ( stripos($cff_excludes, 'desc') !== false ) $cff_show_desc = false;
449 if ( stripos($cff_excludes, 'sharedlink') !== false ) $cff_show_shared_links = false;
450 if ( stripos($cff_excludes, 'date') !== false ) $cff_show_date = false;
451 if ( stripos($cff_excludes, 'media') !== false ) $cff_show_media = false;
452 if ( stripos($cff_excludes, 'medialink') !== false ) $cff_show_media_link = false;
453 if ( stripos($cff_excludes, 'eventtitle') !== false ) $cff_show_event_title = false;
454 if ( stripos($cff_excludes, 'eventdetail') !== false ) $cff_show_event_details = false;
455 if ( stripos($cff_excludes, 'social') !== false ) $cff_show_meta = false;
456 if ( stripos($cff_excludes, ',link') !== false ) $cff_show_link = false; //comma used to separate it from 'sharedlinks' - which also contains 'link' string
457 if ( stripos($cff_excludes, 'like') !== false ) $cff_show_like_box = false;
458
459
460 //Set free version to thumb layout by default as layout option not available on settings page
461 $cff_preset_layout = 'thumb';
462
463 //If the old shortcode option 'showauthor' is being used then apply it
464 $cff_show_author_old = $atts[ 'showauthor' ];
465 if( $cff_show_author_old == 'false' ) $cff_show_author = false;
466 if( $cff_show_author_old == 'true' ) $cff_show_author = true;
467
468
469 /********** META **********/
470 $cff_icon_style = $atts[ 'iconstyle' ];
471 $cff_meta_text_color = $atts[ 'socialtextcolor' ];
472 $cff_meta_bg_color = $atts[ 'socialbgcolor' ];
473 $cff_meta_styles = '';
474 if ( !empty($cff_meta_text_color) || ( !empty($cff_meta_bg_color) && $cff_meta_bg_color !== '#' ) ) $cff_meta_styles = 'style="';
475 if ( !empty($cff_meta_text_color) ) $cff_meta_styles .= 'color:#' . str_replace('#', '', $cff_meta_text_color) . ';';
476 if ( !empty($cff_meta_bg_color) && $cff_meta_bg_color !== '#' ) $cff_meta_styles .= 'background-color:#' . str_replace('#', '', $cff_meta_bg_color) . ';';
477 if ( !empty($cff_meta_text_color) || ( !empty($cff_meta_bg_color) && $cff_meta_bg_color !== '#' ) ) $cff_meta_styles .= '"';
478 $cff_nocomments_text = isset($options[ 'cff_nocomments_text' ]) ? $options[ 'cff_nocomments_text' ] : '';
479 $cff_hide_comments = isset($options[ 'cff_hide_comments' ]) ? $options[ 'cff_hide_comments' ] : '';
480 if (!isset($cff_nocomments_text) || empty($cff_nocomments_text)) $cff_hide_comments = true;
481 /********** TYPOGRAPHY **********/
482 //See More text
483 $cff_see_more_text = $atts[ 'seemoretext' ];
484 $cff_see_less_text = $atts[ 'seelesstext' ];
485 //See Less text
486 //Title
487 $cff_title_format = $atts[ 'textformat' ];
488 if (empty($cff_title_format)) $cff_title_format = 'p';
489 $cff_title_size = $atts[ 'textsize' ];
490 $cff_title_weight = $atts[ 'textweight' ];
491 $cff_title_color = $atts[ 'textcolor' ];
492
493 $cff_title_styles = '';
494 if( ( !empty($cff_title_size) && $cff_title_size != 'inherit' ) || ( !empty($cff_title_weight) && $cff_title_weight != 'inherit' ) || ( !empty($cff_title_color) && $cff_title_color !== '#' ) ) $cff_title_styles = 'style="';
495 if ( !empty($cff_title_size) && $cff_title_size != 'inherit' ) $cff_title_styles .= 'font-size:' . $cff_title_size . 'px; ';
496 if ( !empty($cff_title_weight) && $cff_title_weight != 'inherit' ) $cff_title_styles .= 'font-weight:' . $cff_title_weight . '; ';
497 if ( !empty($cff_title_color) && $cff_title_color !== '#' ) $cff_title_styles .= 'color:#' . str_replace('#', '', $cff_title_color) . ';';
498 if( ( !empty($cff_title_size) && $cff_title_size != 'inherit' ) || ( !empty($cff_title_weight) && $cff_title_weight != 'inherit' ) || ( !empty($cff_title_color) && $cff_title_color !== '#' ) ) $cff_title_styles .= '"';
499
500 $cff_title_link = $atts[ 'textlink' ];
501
502 $cff_posttext_link_color = str_replace('#', '', $atts['textlinkcolor']);
503
504 ( $cff_title_link == 'on' || $cff_title_link == 'true' || $cff_title_link == true ) ? $cff_title_link = true : $cff_title_link = false;
505 if( $atts[ 'textlink' ] == 'false' ) $cff_title_link = false;
506
507 //Author
508 $cff_author_size = $atts[ 'authorsize' ];
509 $cff_author_color = $atts[ 'authorcolor' ];
510
511 $cff_author_styles = '';
512 if( ( !empty($cff_author_size) && $cff_author_size != 'inherit' ) || ( !empty($cff_author_color) && $cff_author_color !== '#' ) ) $cff_author_styles = 'style="';
513 if ( !empty($cff_author_size) && $cff_author_size != 'inherit' ) $cff_author_styles .= 'font-size:' . $cff_author_size . 'px; ';
514 if ( !empty($cff_author_color) && $cff_author_color !== '#' ) $cff_author_styles .= 'color:#' . str_replace('#', '', $cff_author_color) . ';';
515 if( ( !empty($cff_author_size) && $cff_author_size != 'inherit' ) || ( !empty($cff_author_color) && $cff_author_color !== '#' ) ) $cff_author_styles .= '"';
516
517 //Description
518 $cff_body_size = $atts[ 'descsize' ];
519 $cff_body_weight = $atts[ 'descweight' ];
520 $cff_body_color = $atts[ 'desccolor' ];
521
522 $cff_body_styles = '';
523 if( ( !empty($cff_body_size) && $cff_body_size != 'inherit' ) || ( !empty($cff_body_weight) && $cff_body_weight != 'inherit' ) || ( !empty($cff_body_color) && $cff_body_color !== '#' ) ) $cff_body_styles = 'style="';
524 if ( !empty($cff_body_size) && $cff_body_size != 'inherit' ) $cff_body_styles .= 'font-size:' . $cff_body_size . 'px; ';
525 if ( !empty($cff_body_weight) && $cff_body_weight != 'inherit' ) $cff_body_styles .= 'font-weight:' . $cff_body_weight . '; ';
526 if ( !empty($cff_body_color) && $cff_body_color !== '#' ) $cff_body_styles .= 'color:#' . str_replace('#', '', $cff_body_color) . ';';
527 if( ( !empty($cff_body_size) && $cff_body_size != 'inherit' ) || ( !empty($cff_body_weight) && $cff_body_weight != 'inherit' ) || ( !empty($cff_body_color) && $cff_body_color !== '#' ) ) $cff_body_styles .= '"';
528
529 //Shared link title
530 $cff_link_title_format = $atts[ 'linktitleformat' ];
531 if (empty($cff_link_title_format)) $cff_link_title_format = 'p';
532 $cff_link_title_size = $atts[ 'linktitlesize' ];
533 $cff_link_title_color = str_replace('#', '', $atts[ 'linktitlecolor' ]);
534 $cff_link_url_color = $atts[ 'linkurlcolor' ];
535
536 $cff_link_title_styles = '';
537 if ( !empty($cff_link_title_size) && $cff_link_title_size != 'inherit' ) $cff_link_title_styles = 'style="font-size:' . $cff_link_title_size . 'px;"';
538
539 //Shared link description
540 $cff_link_desc_size = $atts[ 'linkdescsize' ];
541 $cff_link_desc_color = $atts[ 'linkdesccolor' ];
542
543 //Shared link URL
544 $cff_link_url_size = $atts[ 'linkurlsize' ];
545 $cff_link_url_color = $atts[ 'linkurlcolor' ];
546
547 //Shared link box
548 $cff_link_bg_color = $atts[ 'linkbgcolor' ];
549 $cff_link_border_color = $atts[ 'linkbordercolor' ];
550 $cff_disable_link_box = $atts['disablelinkbox'];
551 ($cff_disable_link_box == 'true' || $cff_disable_link_box == 'on') ? $cff_disable_link_box = true : $cff_disable_link_box = false;
552
553 $cff_link_box_styles = '';
554 if( !empty($cff_link_border_color) || (!empty($cff_link_bg_color) && $cff_link_bg_color !== '#') ) $cff_link_box_styles = 'style="';
555 if ( !empty($cff_link_border_color) ) $cff_link_box_styles .= 'border: 1px solid #' . str_replace('#', '', $cff_link_border_color) . '; ';
556 if ( !empty($cff_link_bg_color) && $cff_link_bg_color !== '#' ) $cff_link_box_styles .= 'background-color: #' . str_replace('#', '', $cff_link_bg_color) . ';';
557 if( !empty($cff_link_border_color) || (!empty($cff_link_bg_color) && $cff_link_bg_color !== '#') ) $cff_link_box_styles .= '"';
558
559 //Event Title
560 $cff_event_title_format = $atts[ 'eventtitleformat' ];
561 if (empty($cff_event_title_format)) $cff_event_title_format = 'p';
562 $cff_event_title_size = $atts[ 'eventtitlesize' ];
563 $cff_event_title_weight = $atts[ 'eventtitleweight' ];
564 $cff_event_title_color = $atts[ 'eventtitlecolor' ];
565
566 $cff_event_title_styles = '';
567 if( ( !empty($cff_event_title_size) && $cff_event_title_size != 'inherit' ) || ( !empty($cff_event_title_weight) && $cff_event_title_weight != 'inherit' ) || ( !empty($cff_event_title_color) && $cff_event_title_color !== '#' ) ) $cff_event_title_styles = 'style="';
568 if ( !empty($cff_event_title_size) && $cff_event_title_size != 'inherit' ) $cff_event_title_styles .= 'font-size:' . $cff_event_title_size . 'px; ';
569 if ( !empty($cff_event_title_weight) && $cff_event_title_weight != 'inherit' ) $cff_event_title_styles .= 'font-weight:' . $cff_event_title_weight . '; ';
570 if ( !empty($cff_event_title_color) && $cff_event_title_color !== '#' ) $cff_event_title_styles .= 'color:#' . str_replace('#', '', $cff_event_title_color) . ';';
571 if( ( !empty($cff_event_title_size) && $cff_event_title_size != 'inherit' ) || ( !empty($cff_event_title_weight) && $cff_event_title_weight != 'inherit' ) || ( !empty($cff_event_title_color) && $cff_event_title_color !== '#' ) ) $cff_event_title_styles .= '"';
572
573 $cff_event_title_link = $atts[ 'eventtitlelink' ];
574 ( $cff_event_title_link == 'on' || $cff_event_title_link == 'true' || $cff_event_title_link == true ) ? $cff_event_title_link = true : $cff_event_title_link = false;
575 if( $atts[ 'eventtitlelink' ] == 'false' ) $cff_event_title_link = false;
576
577 //Event Date
578 $cff_event_date_size = $atts[ 'eventdatesize' ];
579 $cff_event_date_weight = $atts[ 'eventdateweight' ];
580 $cff_event_date_color = $atts[ 'eventdatecolor' ];
581 $cff_event_date_position = $atts[ 'eventdatepos' ];
582 $cff_event_date_formatting = $atts[ 'eventdateformat' ];
583 $cff_event_date_custom = $atts[ 'eventdatecustom' ];
584
585 $cff_event_date_styles = '';
586 if( ( !empty($cff_event_date_size) && $cff_event_date_size != 'inherit' ) || ( !empty($cff_event_date_weight) && $cff_event_date_weight != 'inherit' ) || ( !empty($cff_event_date_color) && $cff_event_date_color !== '#' ) ) $cff_event_date_styles = 'style="';
587 if ( !empty($cff_event_date_size) && $cff_event_date_size != 'inherit' ) $cff_event_date_styles .= 'font-size:' . $cff_event_date_size . 'px; ';
588 if ( !empty($cff_event_date_weight) && $cff_event_date_weight != 'inherit' ) $cff_event_date_styles .= 'font-weight:' . $cff_event_date_weight . '; ';
589 if ( !empty($cff_event_date_color) && $cff_event_date_color !== '#' ) $cff_event_date_styles .= 'color:#' . str_replace('#', '', $cff_event_date_color) . ';';
590 if( ( !empty($cff_event_date_size) && $cff_event_date_size != 'inherit' ) || ( !empty($cff_event_date_weight) && $cff_event_date_weight != 'inherit' ) || ( !empty($cff_event_date_color) && $cff_event_date_color !== '#' ) ) $cff_event_date_styles .= '"';
591
592 //Event Details
593 $cff_event_details_size = $atts[ 'eventdetailssize' ];
594 $cff_event_details_weight = $atts[ 'eventdetailsweight' ];
595 $cff_event_details_color = $atts[ 'eventdetailscolor' ];
596 $cff_event_link_color = $atts[ 'eventlinkcolor' ];
597
598 $cff_event_details_styles = '';
599 if( ( !empty($cff_event_details_size) && $cff_event_details_size != 'inherit' ) || ( !empty($cff_event_details_weight) && $cff_event_details_weight != 'inherit' ) || ( !empty($cff_event_details_color) && $cff_event_details_color !== '#' ) ) $cff_event_details_styles = 'style="';
600 if ( !empty($cff_event_details_size) && $cff_event_details_size != 'inherit' ) $cff_event_details_styles .= 'font-size:' . $cff_event_details_size . 'px; ';
601 if ( !empty($cff_event_details_weight) && $cff_event_details_weight != 'inherit' ) $cff_event_details_styles .= 'font-weight:' . $cff_event_details_weight . '; ';
602 if ( !empty($cff_event_details_color) && $cff_event_details_color !== '#' ) $cff_event_details_styles .= 'color:#' . str_replace('#', '', $cff_event_details_color) . ';';
603 if( ( !empty($cff_event_details_size) && $cff_event_details_size != 'inherit' ) || ( !empty($cff_event_details_weight) && $cff_event_details_weight != 'inherit' ) || ( !empty($cff_event_details_color) && $cff_event_details_color !== '#' ) ) $cff_event_details_styles .= '"';
604
605 //Date
606 $cff_date_position = $atts[ 'datepos' ];
607 if (!isset($cff_date_position)) $cff_date_position = 'below';
608 $cff_date_size = $atts[ 'datesize' ];
609 $cff_date_weight = $atts[ 'dateweight' ];
610 $cff_date_color = $atts[ 'datecolor' ];
611
612 $cff_date_styles = '';
613 if( ( !empty($cff_date_size) && $cff_date_size != 'inherit' ) || ( !empty($cff_date_weight) && $cff_date_weight != 'inherit' ) || ( !empty($cff_date_color) && $cff_date_color !== '#' ) ) $cff_date_styles = 'style="';
614 if ( !empty($cff_date_size) && $cff_date_size != 'inherit' ) $cff_date_styles .= 'font-size:' . $cff_date_size . 'px; ';
615 if ( !empty($cff_date_weight) && $cff_date_weight != 'inherit' ) $cff_date_styles .= 'font-weight:' . $cff_date_weight . '; ';
616 if ( !empty($cff_date_color) && $cff_date_color !== '#' ) $cff_date_styles .= 'color:#' . str_replace('#', '', $cff_date_color) . ';';
617 if( ( !empty($cff_date_size) && $cff_date_size != 'inherit' ) || ( !empty($cff_date_weight) && $cff_date_weight != 'inherit' ) || ( !empty($cff_date_color) && $cff_date_color !== '#' ) ) $cff_date_styles .= '"';
618
619 $cff_date_before = isset($options[ 'cff_date_before' ]) ? $options[ 'cff_date_before' ] : '';
620 $cff_date_after = isset($options[ 'cff_date_after' ]) ? $options[ 'cff_date_after' ] : '';
621
622 //Timezone. The post date is adjusted by the timezone offset in the cff_getdate function.
623 $cff_timezone = $atts['timezone'];
624
625 //Posted ago strings
626 $cff_date_translate_strings = array(
627 'cff_translate_second' => $atts['secondtext'],
628 'cff_translate_seconds' => $atts['secondstext'],
629 'cff_translate_minute' => $atts['minutetext'],
630 'cff_translate_minutes' => $atts['minutestext'],
631 'cff_translate_hour' => $atts['hourtext'],
632 'cff_translate_hours' => $atts['hourstext'],
633 'cff_translate_day' => $atts['daytext'],
634 'cff_translate_days' => $atts['daystext'],
635 'cff_translate_week' => $atts['weektext'],
636 'cff_translate_weeks' => $atts['weekstext'],
637 'cff_translate_month' => $atts['monthtext'],
638 'cff_translate_months' => $atts['monthstext'],
639 'cff_translate_year' => $atts['yeartext'],
640 'cff_translate_years' => $atts['yearstext'],
641 'cff_translate_ago' => $atts['agotext']
642 );
643
644 //Link to Facebook
645 $cff_link_size = $atts[ 'linksize' ];
646 $cff_link_weight = $atts[ 'linkweight' ];
647 $cff_link_color = $atts[ 'linkcolor' ];
648
649 $cff_link_styles = '';
650 if( ( !empty($cff_link_size) && $cff_link_size != 'inherit' ) || ( !empty($cff_link_weight) && $cff_link_weight != 'inherit' ) || ( !empty($cff_link_color) && $cff_link_color !== '#' ) ) $cff_link_styles = 'style="';
651 if ( !empty($cff_link_size) && $cff_link_size != 'inherit' ) $cff_link_styles .= 'font-size:' . $cff_link_size . 'px; ';
652 if ( !empty($cff_link_weight) && $cff_link_weight != 'inherit' ) $cff_link_styles .= 'font-weight:' . $cff_link_weight . '; ';
653 if ( !empty($cff_link_color) && $cff_link_color !== '#' ) $cff_link_styles .= 'color:#' . str_replace('#', '', $cff_link_color) . ';';
654 if( ( !empty($cff_link_size) && $cff_link_size != 'inherit' ) || ( !empty($cff_link_weight) && $cff_link_weight != 'inherit' ) || ( !empty($cff_link_color) && $cff_link_color !== '#' ) ) $cff_link_styles .= '"';
655
656 //Link custom text
657 $cff_facebook_link_text = $atts[ 'facebooklinktext' ];
658 $cff_facebook_share_text = $atts[ 'sharelinktext' ];
659 if ($cff_facebook_share_text == '') $cff_facebook_share_text = 'Share';
660
661
662 //Show Facebook link
663 $cff_show_facebook_link = $atts[ 'showfacebooklink' ];
664 ( $cff_show_facebook_link == 'on' || $cff_show_facebook_link == 'true' || $cff_show_facebook_link == true ) ? $cff_show_facebook_link = true : $cff_show_facebook_link = false;
665 if( $atts[ 'showfacebooklink' ] === 'false' ) $cff_show_facebook_link = false;
666
667
668 //Show Share link
669 $cff_show_facebook_share = $atts[ 'showsharelink' ];
670 ( $cff_show_facebook_share == 'on' || $cff_show_facebook_share == 'true' || $cff_show_facebook_share == true ) ? $cff_show_facebook_share = true : $cff_show_facebook_share = false;
671 if( $atts[ 'showsharelink' ] === 'false' ) $cff_show_facebook_share = false;
672
673 $cff_view_link_text = $atts[ 'viewlinktext' ];
674 $cff_link_to_timeline = $atts[ 'linktotimeline' ];
675 /********** MISC **********/
676 //Like Box styles
677 $cff_likebox_bg_color = $atts[ 'likeboxcolor' ];
678
679 $cff_like_box_text_color = $atts[ 'likeboxtextcolor' ];
680 $cff_like_box_colorscheme = 'light';
681 if ($cff_like_box_text_color == 'white') $cff_like_box_colorscheme = 'dark';
682
683 $cff_likebox_width = $atts[ 'likeboxwidth' ];
684 if ( is_numeric(substr($cff_likebox_width, -1, 1)) ) $cff_likebox_width = $cff_likebox_width . 'px';
685
686 $cff_likebox_height = $atts[ 'likeboxheight' ];
687 $cff_likebox_height = preg_replace('/px$/', '', $cff_likebox_height);
688
689 if ( !isset($cff_likebox_width) || empty($cff_likebox_width) || $cff_likebox_width == '' ) $cff_likebox_width = '100%';
690 $cff_like_box_faces = $atts[ 'likeboxfaces' ];
691 if ( !isset($cff_like_box_faces) || empty($cff_like_box_faces) ){
692 $cff_like_box_faces = 'false';
693 } else {
694 $cff_like_box_faces = 'true';
695 }
696
697 $cff_like_box_border = $atts[ 'likeboxborder' ];
698 if ($cff_like_box_border) {
699 $cff_like_box_border = 'true';
700 } else {
701 $cff_like_box_border = 'false';
702 }
703
704 $cff_like_box_cover = $atts[ 'likeboxcover' ];
705 if ($cff_like_box_cover) {
706 $cff_like_box_cover = 'false';
707 } else {
708 $cff_like_box_cover = 'true';
709 }
710
711 $cff_like_box_small_header = $atts[ 'likeboxsmallheader' ];
712 if ($cff_like_box_small_header) {
713 $cff_like_box_small_header = 'true';
714 } else {
715 $cff_like_box_small_header = 'false';
716 }
717
718 $cff_like_box_hide_cta = $atts[ 'likeboxhidebtn' ];
719 if ($cff_like_box_hide_cta) {
720 $cff_like_box_hide_cta = 'true';
721 } else {
722 $cff_like_box_hide_cta = 'false';
723 }
724
725 //Compile Like box styles
726 $cff_likebox_styles = 'style="width: ' . $cff_likebox_width . ';';
727 if ( !empty($cff_likebox_bg_color) ) $cff_likebox_styles .= ' background-color: #' . str_replace('#', '', $cff_likebox_bg_color) . ';';
728
729 //Set the left margin on the like box based on how it's being displayed
730 if ( (!empty($cff_likebox_bg_color) && $cff_likebox_bg_color != '#') || ($cff_like_box_faces == 'true' || $cff_like_box_faces == 'on') ) $cff_likebox_styles .= ' margin-left: 0px;';
731
732 $cff_likebox_styles .= '"';
733
734 //Get feed header settings
735 $cff_header_bg_color = $atts['headerbg'];
736 $cff_header_padding = $atts['headerpadding'];
737 if ( is_numeric(substr($cff_header_padding, -1, 1)) ) $cff_header_padding = $cff_header_padding . 'px';
738
739 $cff_header_text_size = $atts['headertextsize'];
740 $cff_header_text_weight = $atts['headertextweight'];
741 $cff_header_text_color = $atts['headertextcolor'];
742
743 //Compile feed header styles
744 $cff_header_styles = '';
745 if( ( !empty($cff_header_bg_color) && $cff_header_bg_color !== '#' ) || !empty($cff_header_padding) || ( !empty($cff_header_text_size) && $cff_header_text_size != 'inherit' ) || ( !empty($cff_header_text_weight) && $cff_header_text_weight != 'inherit' ) || (!empty($cff_header_text_color) && $cff_header_text_color !== '#') ) $cff_header_styles = 'style="';
746 if ( !empty($cff_header_bg_color) && $cff_header_bg_color !== '#' ) $cff_header_styles .= 'background-color: #' . str_replace('#', '', $cff_header_bg_color) . '; ';
747 if ( !empty($cff_header_padding) ) $cff_header_styles .= 'padding: ' . $cff_header_padding . '; ';
748 if ( !empty($cff_header_text_size) && $cff_header_text_size != 'inherit' ) $cff_header_styles .= 'font-size: ' . $cff_header_text_size . 'px; ';
749 if ( !empty($cff_header_text_weight) && $cff_header_text_weight != 'inherit' ) $cff_header_styles .= 'font-weight: ' . $cff_header_text_weight . '; ';
750 if ( !empty($cff_header_text_color) && $cff_header_text_color !== '#' ) $cff_header_styles .= 'color: #' . str_replace('#', '', $cff_header_text_color) . '; ';
751 if( ( !empty($cff_header_bg_color) && $cff_header_bg_color !== '#' ) || !empty($cff_header_padding) || ( !empty($cff_header_text_size) && $cff_header_text_size != 'inherit' ) || ( !empty($cff_header_text_weight) && $cff_header_text_weight != 'inherit' ) || (!empty($cff_header_text_color) && $cff_header_text_color !== '#') ) $cff_header_styles .= '"';
752
753 //Video
754 //Dimensions
755 $cff_video_width = 640;
756 $cff_video_height = $atts[ 'videoheight' ];
757
758 //Action
759 $cff_video_action = $atts[ 'videoaction' ];
760
761 //Post Style settings
762 $cff_post_style = $atts['poststyle'];
763
764 $cff_post_bg_color = str_replace('#', '', $atts['postbgcolor']);
765 $cff_post_rounded = $atts['postcorners'];
766 ( ($cff_post_bg_color !== '#' && $cff_post_bg_color !== '') && $cff_post_style != 'regular' ) ? $cff_post_bg_color_check = true : $cff_post_bg_color_check = false;
767
768 $cff_box_shadow = $atts['boxshadow'];
769 ( ($cff_box_shadow == 'true' || $cff_box_shadow == 'on') && $cff_post_style == 'boxed' ) ? $cff_box_shadow = true : $cff_box_shadow = false;
770
771 //Separating Line
772 $cff_sep_color = $atts[ 'sepcolor' ];
773 if (empty($cff_sep_color)) $cff_sep_color = 'ddd';
774 $cff_sep_size = $atts[ 'sepsize' ];
775 $cff_sep_size_check = true;
776 //If empty then set a 0px border
777 if ( empty($cff_sep_size) || $cff_sep_size == '' ) {
778 $cff_sep_size = 0;
779 //Need to set a color otherwise the CSS is invalid
780 $cff_sep_color = 'fff';
781 $cff_sep_size_check = false;
782 }
783 ($cff_sep_color !== '#' && $cff_sep_color !== '') ? $cff_sep_color_check = true : $cff_sep_color_check = false;
784
785 //CFF item styles
786 $cff_item_styles = '';
787 if( $cff_post_style == 'boxed' || $cff_post_bg_color_check ){
788 $cff_item_styles = 'style="';
789 if($cff_post_bg_color_check) $cff_item_styles .= 'background-color: #' . $cff_post_bg_color . '; ';
790 if( isset($cff_post_rounded) && $cff_post_rounded !== '0' && !empty($cff_post_rounded) ) $cff_item_styles .= '-webkit-border-radius: ' . $cff_post_rounded . 'px; -moz-border-radius: ' . $cff_post_rounded . 'px; border-radius: ' . $cff_post_rounded . 'px; ';
791 $cff_item_styles .= '"';
792 }
793 if( $cff_post_style == 'regular' && ($cff_sep_color_check || $cff_sep_size_check) ){
794 $cff_item_styles .= 'style="border-bottom: ' . $cff_sep_size . 'px solid #' . str_replace('#', '', $cff_sep_color) . ';"';
795 }
796
797 //Text limits
798 $title_limit = $atts['textlength'];
799 if (!isset($title_limit)) $title_limit = 9999;
800 $body_limit = $atts['desclength'];
801
802 //Assign the Access Token and Page ID variables
803 $access_token = $atts['accesstoken'];
804 $page_id = trim( $atts['id'] );
805
806
807
808 //If an 'account' is specified then use that instead of the Page ID/token from the settings
809 $cff_account = trim($atts['account']);
810 if( !empty( $cff_account ) ){
811 $cff_connected_accounts = get_option('cff_connected_accounts');
812 if( !empty($cff_connected_accounts) ){
813
814 $cff_connected_accounts = json_decode( str_replace('\"','"', $cff_connected_accounts) );
815
816 //Grab the ID and token from the connected accounts setting
817 $page_id = $cff_connected_accounts->{ $cff_account }->{'id'};
818 $access_token = $cff_connected_accounts->{ $cff_account }->{'accesstoken'};
819
820 //Replace the encryption string in the Access Token
821 if (strpos($access_token, '02Sb981f26534g75h091287a46p5l63') !== false) {
822 $access_token = str_replace("02Sb981f26534g75h091287a46p5l63","",$access_token);
823 }
824 }
825 }
826
827 //If user pastes their full URL into the Page ID field then strip it out
828 $cff_facebook_string = 'facebook.com';
829 $cff_page_id_url_check = stripos($page_id, $cff_facebook_string);
830
831 if ( $cff_page_id_url_check ) {
832 //Remove trailing slash if exists
833 $page_id = preg_replace('{/$}', '', $page_id);
834 //Get last part of url
835 $page_id = substr( $page_id, strrpos( $page_id, '/' )+1 );
836 }
837
838 //Masonry
839 $masonry = false;
840 $cff_cols = $atts['cols'];
841 $cff_cols_mobile = $atts['colsmobile'];
842 $cff_cols_js = $atts['colsjs'];
843
844 if( intval($cff_cols) > 1 ) $masonry = true;
845 $js_only = isset( $cff_cols_js ) ? $cff_cols_js : false;
846 if( $js_only === 'false' ) $js_only = false;
847
848 if( $masonry || $masonry == 'true' ) $atts['headeroutside'] = true;
849
850 $masonry_classes = '';
851 if( isset($masonry) ) {
852 if( $masonry === 'on' || $masonry === true || $masonry === 'true' ) {
853
854 $masonry_classes .= 'cff-masonry';
855
856 if( $cff_cols != 3 ) {
857 $masonry_classes .= sprintf( ' masonry-%s-desktop', $cff_cols );
858 }
859 if( $cff_cols_mobile == 2 ) {
860 $masonry_classes .= ' masonry-2-mobile';
861 }
862 if( ! $js_only ) {
863 $masonry_classes .= ' cff-masonry-css';
864 } else {
865 $masonry_classes .= ' cff-masonry-js';
866 }
867 }
868 }
869
870 //If the Page ID contains a query string at the end then remove it
871 if ( stripos( $page_id, '?') !== false ) $page_id = substr($page_id, 0, strrpos($page_id, '?'));
872
873 //Always remove slash from end of Page ID
874 $page_id = preg_replace('{/$}', '', $page_id);
875
876 //Get show posts attribute. If not set then default to 25
877 $show_posts = $atts['num'];
878 if (empty($show_posts)) $show_posts = 25;
879 if ( $show_posts == 'undefined' ) $show_posts = 25;
880
881 //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
882 get_option('cff_show_access_token') ? $cff_show_access_token = true : $cff_show_access_token = false;
883
884 //Check whether a Page ID has been defined
885 if ($page_id == '') {
886 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 />";
887 return false;
888 }
889
890 //Is it a restricted page?
891 $cff_restricted_page = $atts['restrictedpage'];
892 ($cff_restricted_page == 'true' || $cff_restricted_page == 'on') ? $cff_restricted_page = true : $cff_restricted_page = false;
893
894 //Is it SSL?
895 $cff_ssl = '';
896 if (is_ssl()) $cff_ssl = '&return_ssl_resources=true';
897
898 //Use posts? or feed?
899 $old_others_option = get_option('cff_show_others'); //Use this to help depreciate the old option
900 $show_others = $atts['others'];
901 $show_posts_by = $atts['showpostsby'];
902 $graph_query = 'posts';
903 $cff_show_only_others = false;
904
905 //If 'others' shortcode option is used then it overrides any other option
906 if ($show_others || $old_others_option == 'on') {
907 //Show posts by everyone
908 if ( $old_others_option == 'on' || $show_others == 'on' || $show_others == 'true' || $show_others == true || $cff_is_group ) $graph_query = 'feed';
909
910 //Only show posts by me
911 if ( $show_others == 'false' ) $graph_query = 'posts';
912
913 } else {
914 //Else use the settings page option or the 'showpostsby' shortcode option
915
916 //Only show posts by me
917 if ( $show_posts_by == 'me' ) $graph_query = 'posts';
918
919 //Show posts by everyone
920 if ( $show_posts_by == 'others' || $cff_is_group ) $graph_query = 'feed';
921
922 //Show posts ONLY by others
923 if ( $show_posts_by == 'onlyothers' && !$cff_is_group ) {
924 $graph_query = 'visitor_posts';
925 $cff_show_only_others = true;
926 }
927 }
928
929 $cff_post_limit = $atts['limit'];
930
931 // If Mobile and Desktop post nums are not the same, use minnum for API requests.
932 $mobile_num = isset( $atts['nummobile'] ) && (int)$atts['nummobile'] > 0 ? (int)$atts['nummobile'] : 0;
933 $desk_num = $show_posts;
934 if ( $desk_num < $mobile_num ) {
935 $feed_options['minnum'] = $mobile_num;
936 }
937 $show_posts = isset( $atts['minnum'] ) ? $atts['minnum'] : $show_posts;
938
939 //If the limit isn't set then set it to be 7 more than the number of posts defined
940 if ( isset($cff_post_limit) && $cff_post_limit !== '' ) {
941 $cff_post_limit = $cff_post_limit;
942 } else {
943 if( intval($show_posts) >= 50 ) $cff_post_limit = intval(intval($show_posts) + 7);
944 if( intval($show_posts) < 50 ) $cff_post_limit = intval(intval($show_posts) + 5);
945 if( intval($show_posts) < 25 ) $cff_post_limit = intval(intval($show_posts) + 4);
946 if( intval($show_posts) < 10 ) $cff_post_limit = intval(intval($show_posts) + 3);
947 if( intval($show_posts) < 6 ) $cff_post_limit = intval(intval($show_posts) + 2);
948 if( intval($show_posts) < 2 ) $cff_post_limit = intval(intval($show_posts) + 1);
949 }
950 if( $cff_post_limit >= 100 ) $cff_post_limit = 100;
951
952 //If the number of posts is set to zero then don't show any and set limit to one
953 if ( ($show_posts == '0' || $show_posts == 0) && $show_posts !== ''){
954 $show_posts = 0;
955 $cff_post_limit = 1;
956 }
957
958
959 //Calculate the cache time in seconds
960 if($cff_cache_time_unit == 'minutes') $cff_cache_time_unit = 60;
961 if($cff_cache_time_unit == 'hours') $cff_cache_time_unit = 60*60;
962 if($cff_cache_time_unit == 'days') $cff_cache_time_unit = 60*60*24;
963 $cache_seconds = $cff_cache_time * $cff_cache_time_unit;
964
965 //Get like box vars
966 $cff_likebox_width = $atts[ 'likeboxwidth' ];
967 if ( !isset($cff_likebox_width) || empty($cff_likebox_width) || $cff_likebox_width == '' ) $cff_likebox_width = 300;
968
969 $like_box_page_id = explode(",", str_replace(' ', '', $page_id) );
970
971 //Like Box HTML
972 $like_box = '<';
973 //If the Like Box is at the top then change the element from a div so that it doesn't interfere with the "nth-of-type" used for grids in CSS
974 ($cff_like_box_position == 'top') ? $like_box .= 'section' : $like_box .= 'div';
975 $like_box .= ' class="cff-likebox';
976
977 if ($cff_like_box_outside) $like_box .= ' cff-outside';
978 $like_box .= ($cff_like_box_position == 'top') ? ' cff-top' : ' cff-bottom';
979 $like_box .= '" >';
980
981 //Calculate the like box height
982 $cff_likebox_height = 130;
983 if( $cff_like_box_small_header == 'true' ) $cff_likebox_height = 70;
984 if( $cff_like_box_faces == 'true' ) $cff_likebox_height = 214;
985 if( $cff_like_box_small_header == 'true' && $cff_like_box_faces == 'true' ) $cff_likebox_height = 154;
986
987 //Src is set in JS now so can be dynamic based on screen size as 'adapt_container_width' doesn't work in iframe
988 $like_box .= '<iframe src="" data-likebox-id="'.$like_box_page_id[0].'" data-likebox-width="'.$cff_likebox_width.'" data-likebox-header="'.$cff_like_box_small_header.'" data-hide-cover="'.$cff_like_box_cover.'" data-hide-cta="'.$cff_like_box_hide_cta.'" data-likebox-faces="'.$cff_like_box_faces.'" height="'.$cff_likebox_height.'" data-locale="'.$cff_locale.'" style="border:none;overflow:hidden" scrolling="no" allowTransparency="true" allow="encrypted-media" class="fb_iframe_widget"></iframe>';
989
990 $like_box .= '</';
991
992 ($cff_like_box_position == 'top') ? $like_box .= 'section' : $like_box .= 'div';
993 $like_box .= '>';
994
995 //Don't show like box if it's a group
996 if($cff_is_group) $like_box = '';
997
998
999 //Feed header
1000 $cff_show_header = $atts['showheader'];
1001 ($cff_show_header == 'true' || $cff_show_header == 'on') ? $cff_show_header = true : $cff_show_header = false;
1002
1003 $cff_header_outside = $atts['headeroutside'];
1004 ($cff_header_outside == 'true' || $cff_header_outside == 'on') ? $cff_header_outside = true : $cff_header_outside = false;
1005
1006 $cff_header_type = strtolower( $atts['headertype'] );
1007
1008 $cff_header = '';
1009
1010 if ($cff_header_type !== "visual") {
1011 $cff_header_text = stripslashes( $atts['headertext'] );
1012 $cff_header_icon = $atts['headericon'];
1013 $cff_header_icon_color = $atts['headericoncolor'];
1014 $cff_header_icon_size = $atts['headericonsize'];
1015
1016 $cff_header = '<h3 class="cff-header';
1017 if ($cff_header_outside) $cff_header .= ' cff-outside';
1018 $cff_header .= '" ' . $cff_header_styles . '>';
1019 $cff_header .= '<span class="fa fab fa-' . $cff_header_icon . '"';
1020 if(!empty($cff_header_icon_color) || !empty($cff_header_icon_size)) $cff_header .= ' style="';
1021 if(!empty($cff_header_icon_color)) $cff_header .= 'color: #' . str_replace('#', '', $cff_header_icon_color) . ';';
1022 if(!empty($cff_header_icon_size)) $cff_header .= ' font-size: ' . $cff_header_icon_size . 'px;';
1023 if(!empty($cff_header_icon_color) || !empty($cff_header_icon_size))$cff_header .= '"';
1024 $cff_header .= ' aria-hidden="true"></span>';
1025 $cff_header .= '<span class="header-text" style="height: '.$cff_header_icon_size.'px;">' . $cff_header_text . '</span>';
1026 $cff_header .= '</h3>';
1027 } else {
1028
1029 // Get Values for API call
1030 $access_token = $atts['accesstoken'];
1031 $page_id = $atts['id'];
1032 $cff_cache_time = $atts['cachetime'];
1033
1034 // Create Transient Name
1035 $transient_name = 'cff_header_' . $page_id;
1036 $transient_name = substr( $transient_name, 0, 45 );
1037
1038 //These fields only apply to pages
1039 ! $cff_is_group ? $page_only_fields = ',fan_count,about' : $page_only_fields = '';
1040
1041 $header_details_json_url = 'https://graph.facebook.com/v4.0/' . $page_id . '?fields=id,picture.height(150).width(150),cover,name,link' . $page_only_fields . '&access_token=' . $access_token;
1042
1043 //Get the data
1044 $header_details = cff_get_set_cache( $header_details_json_url, $transient_name, $cff_cache_time, WEEK_IN_SECONDS, '', false, $access_token );
1045 $header_details = json_decode( $header_details );
1046
1047 if ( ! empty( $atts['headerinc'] ) || ! empty( $atts['headerexclude'] ) ) {
1048 if ( ! empty( $atts['headerinc'] ) ) {
1049 $header_inc = explode( ',', str_replace( ' ', '', strtolower( $atts['headerinc'] ) ) );
1050 $cff_header_cover = in_array( 'cover', $header_inc, true );
1051 $cff_header_name = in_array( 'name', $header_inc, true );
1052 $cff_header_bio = in_array( 'about', $header_inc, true );
1053 } else {
1054 $header_exc = explode( ',', str_replace( ' ', '', strtolower( $atts['headerexclude'] ) ) );
1055 $cff_header_cover = ! in_array( 'cover', $header_exc, true );
1056 $cff_header_name = ! in_array( 'name', $header_exc, true );
1057 $cff_header_bio = ! in_array( 'about', $header_exc, true );
1058 }
1059
1060 } else {
1061 $cff_header_cover = $atts['headercover'];
1062 ( $cff_header_cover == 'true' || $cff_header_cover == 'on' ) ? $cff_header_cover = true : $cff_header_cover = false;
1063
1064 $cff_header_name = $atts['headername'];
1065 ( $cff_header_name == 'true' || $cff_header_name == 'on' ) ? $cff_header_name = true : $cff_header_name = false;
1066
1067 $cff_header_bio = $atts['headerbio'];
1068 ( $cff_header_bio == 'true' || $cff_header_bio == 'on' ) ? $cff_header_bio = true : $cff_header_bio = false;
1069 }
1070 $cff_header_cover_height = ! empty( $atts['headercoverheight'] ) ? (int)$atts['headercoverheight'] : 300;
1071
1072 // Facebook Header Output
1073 $header_style_attribute = '';
1074 $header_styles = array();
1075
1076 ( ! empty( $cff_header_text_size ) && $cff_header_text_size != 'inherit' ) ? $cff_header_text_size = $cff_header_text_size : $cff_header_text_size = '';
1077 if ( ! empty( $cff_header_text_weight ) && $cff_header_text_weight != 'inherit' ) {
1078 $header_styles['font-weight'] = $cff_header_text_weight;
1079 }
1080 if ( ! empty( $cff_header_text_color ) && $cff_header_text_color !== '#' ) {
1081 $header_styles['color'] = '#' . str_replace( '#', '', $cff_header_text_color );
1082 }
1083
1084 if ( ! empty( $header_styles ) ) {
1085 $header_style_attribute = ' style="';
1086 foreach ( $header_styles as $property => $value ) {
1087 $header_style_attribute .= $property . ': ' . esc_attr( $value ) . ';';
1088 }
1089 $header_style_attribute .= '"';
1090 }
1091
1092 $header_data = $header_details;
1093
1094 //If there's not API error then display the header
1095 if ( ! isset( $header_details->error ) ) {
1096 ob_start();
1097 include trailingslashit( CFF_PLUGIN_DIR ) . 'templates/header.php';
1098 $cff_header = ob_get_contents();
1099 ob_get_clean();
1100 }
1101 }
1102
1103 //Misc Settings
1104 $cff_nofollow = $atts['nofollow'];
1105 ( $cff_nofollow == 'on' || $cff_nofollow == 'true' || $cff_nofollow == true ) ? $cff_nofollow = true : $cff_nofollow = false;
1106 if( $atts[ 'nofollow' ] == 'false' ) $cff_nofollow = false;
1107 ( $cff_nofollow ) ? $cff_nofollow = ' rel="nofollow noopener"' : $cff_nofollow = '';
1108 $cff_nofollow_referrer = ' rel="nofollow noopener noreferrer"';
1109
1110 //If the number of posts is set to zero then don't show any and set limit to one
1111 if ( ($atts['num'] == '0' || $atts['num'] == 0) && $atts['num'] !== ''){
1112 $show_posts = 0;
1113 $cff_post_limit = 1;
1114 }
1115
1116 //***START FEED***
1117 $cff_content = '';
1118
1119 //Create CFF container HTML
1120 $cff_content .= '<div class="cff-wrapper">';
1121
1122 //Add the page header to the outside of the top of feed
1123 if ($cff_show_header && $cff_header_outside) $cff_content .= $cff_header;
1124
1125 //Add like box to the outside of the top of feed
1126 if ($cff_like_box_position == 'top' && $cff_show_like_box && $cff_like_box_outside) $cff_content .= $like_box;
1127
1128 $cff_content .= '<div id="cff" data-char="'.$title_limit.'"';
1129
1130 // mobile num attribute
1131 $mobile_num = isset( $atts['nummobile'] ) && (int)$atts['nummobile'] !== (int)$atts['num'] ? (int)$atts['nummobile'] : false;
1132 if ( $mobile_num ) {
1133 $cff_content .= ' data-nummobile="'.$mobile_num.'"';
1134 $cff_content .= ' data-pag-num="'.(int)$atts['num'].'"';
1135 }
1136
1137 //Disable default CSS styles?
1138 $cff_disable_styles = $atts['disablestyles'];
1139 ( $cff_disable_styles == 'on' || $cff_disable_styles == 'true' || $cff_disable_styles == true ) ? $cff_disable_styles = true : $cff_disable_styles = false;
1140 if( $atts[ 'disablestyles' ] === 'false' ) $cff_disable_styles = false;
1141
1142 //If there's a class then add it here
1143 if( !empty($cff_class) || !empty($cff_feed_height) || !$cff_disable_styles || $cff_feed_width_resp || !empty($masonry_classes) ) $cff_content .= ' class="';
1144 if( !empty($cff_class) ) $cff_content .= $cff_class . ' ';
1145 if( !empty($masonry_classes) ) $cff_content .= $masonry_classes;
1146 if ( !empty($cff_feed_height) ) $cff_content .= ' cff-fixed-height ';
1147 if ( $cff_feed_width_resp ) $cff_content .= ' cff-width-resp ';
1148 if ( !$cff_disable_styles ) $cff_content .= ' cff-default-styles';
1149 if( !empty($cff_class) || !empty($cff_feed_height) || !$cff_disable_styles || $cff_feed_width_resp ) $cff_content .= '"';
1150
1151 $cff_content .= ' ' . $cff_feed_styles . '>';
1152
1153 //Add the page header to the inside of the top of feed
1154 if ($cff_show_header && !$cff_header_outside) $cff_content .= $cff_header;
1155
1156 //Add like box to the inside of the top of feed
1157 if ($cff_like_box_position == 'top' && $cff_show_like_box && !$cff_like_box_outside) $cff_content .= $like_box;
1158 //Limit var
1159 $i_post = 0;
1160
1161 //Define array for post items
1162 $cff_posts_array = array();
1163
1164 //ALL POSTS
1165 if (!$cff_events_only){
1166
1167 $cff_posts_json_url = 'https://graph.facebook.com/v4.0/' . $page_id . '/' . $graph_query . '?fields=id,from{picture,id,name,link},message,message_tags,story,story_tags,status_type,created_time,backdated_time,call_to_action,attachments{title,description,media_type,unshimmed_url,target{id},media{source}}&access_token=' . $access_token . '&limit=' . $cff_post_limit . '&locale=' . $cff_locale . $cff_ssl;
1168
1169 if( $cff_show_access_token && strlen($access_token) > 130 ){
1170 //If using a Page Access Token then set caching time to be minimum of 5 minutes
1171 if( $cache_seconds < 300 || !isset($cache_seconds) ) $cache_seconds = 300;
1172 } else {
1173 //Temporarily set caching time to be minimum of 1 hour
1174 if( $cache_seconds < 3600 || !isset($cache_seconds) ) $cache_seconds = 3600;
1175
1176 //Temporarily increase default caching time to be 4 hours
1177 if( $cache_seconds == 3600 ) $cache_seconds = 14400;
1178 }
1179
1180 //Don't use caching if the cache time is set to zero
1181 if ($cff_cache_time != 0){
1182
1183 //Create the transient name
1184 //Split the Page ID in half and stick it together so we definitely have the beginning and end of it
1185 $trans_page_id = substr($page_id, 0, 16) . substr($page_id, -15);
1186 $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);
1187
1188 //Limit to 45 chars max
1189 $transient_name = substr($transient_name, 0, 45);
1190
1191 //Get any existing copy of our transient data
1192 if ( false === ( $posts_json = get_transient( $transient_name ) ) || $posts_json === null ) {
1193 //Get the contents of the Facebook page
1194 $posts_json = cff_fetchUrl($cff_posts_json_url);
1195
1196 //Check whether any data is returned from the API. If it isn't then don't cache the error response and instead keep checking the API on every page load until data is returned.
1197 $FBdata = json_decode($posts_json);
1198
1199 if( !empty($FBdata) ) {
1200
1201 //Error returned by API
1202 if( isset($FBdata->error) ){
1203
1204 //Cache the error JSON so doesn't keep making repeated requests
1205 //See if a backup cache exists
1206 if ( false !== get_transient( '!cff_' . $transient_name ) ) {
1207
1208 $posts_json = get_transient( '!cff_' . $transient_name );
1209
1210 //Add error message to backup cache so can be displayed at top of feed
1211 isset( $FBdata->error->message ) ? $error_message = $FBdata->error->message : $error_message = '';
1212 isset( $FBdata->error->type ) ? $error_type = $FBdata->error->type : $error_type = '';
1213 $prefix = '{';
1214 if (substr($posts_json, 0, strlen($prefix)) == $prefix) $posts_json = substr($posts_json, strlen($prefix));
1215 $posts_json = '{"cached_error": { "message": "'.$error_message.'", "type": "'.$error_type.'" }, ' . $posts_json;
1216 }
1217
1218 //Posts data returned by API
1219 } else {
1220 //If a backup should be created for this data then create one
1221 set_transient( '!cff_' . $transient_name, $posts_json, YEAR_IN_SECONDS );
1222 }
1223
1224 //Set regular cache
1225 set_transient( $transient_name, $posts_json, $cache_seconds );
1226
1227 }
1228 } else {
1229
1230 $posts_json = get_transient( $transient_name );
1231 //If we can't find the transient then fall back to just getting the json from the api
1232 if ($posts_json == false) $posts_json = cff_fetchUrl($cff_posts_json_url);
1233
1234 }
1235 } else {
1236 $posts_json = cff_fetchUrl($cff_posts_json_url);
1237 }
1238
1239
1240 //Interpret data with JSON
1241 $FBdata = json_decode($posts_json);
1242
1243 global $current_user;
1244 $user_id = $current_user->ID;
1245
1246 // Use this to show notice again
1247 // delete_user_meta($user_id, 'cff_ppca_check_notice_dismiss');
1248
1249 //Check to see whether this feed will have a PPCA error come Sep 4. If so, display a warning notice.
1250 $cff_ppca_check_error = false;
1251 if( ! get_user_meta($user_id, 'cff_ppca_check_notice_dismiss') ){
1252 $cff_posts_json_url = 'https://graph.facebook.com/v8.0/'.$page_id.'/posts?limit=1&access_token='.$access_token;
1253 $transient_name = 'cff_ppca_' . substr($page_id, 0, 5) . substr($page_id, strlen($page_id)-5, 5) . '_' . substr($access_token, 15, 10);
1254 $cff_cache_time = 1;
1255 $cache_seconds = YEAR_IN_SECONDS;
1256 $cff_ppca_check = cff_get_set_cache($cff_posts_json_url, $transient_name, $cff_cache_time, $cache_seconds, '', true, $access_token, $backup=false);
1257 $cff_ppca_check_json = json_decode($cff_ppca_check);
1258
1259 if( isset( $cff_ppca_check_json->error ) && strpos($cff_ppca_check_json->error->message, 'Public Content Access') !== false ){
1260 $cff_ppca_check_error = true;
1261 }
1262 }
1263
1264 //If there's no data then show a pretty error message
1265 if( empty($FBdata->data) || isset($FBdata->cached_error) || $cff_ppca_check_error ) {
1266
1267 //Check whether it's an error in the backup cache
1268 if( isset($FBdata->cached_error) ) $FBdata->error = $FBdata->cached_error;
1269
1270 //Show custom message for the PPCA error
1271 if( isset($FBdata->error->message) && strpos($FBdata->error->message, 'Page Public Content Access') !== false ) {
1272 $FBdata->error->message = '(#10) To use "Page Public Content Access", your use of this endpoint must be reviewed and approved by Facebook.';
1273 $FBdata->error->type = $FBdata->error->code = $FBdata->error->error_subcode = NULL;
1274 }
1275
1276 //Is it a PPCA error from the API?
1277 $cff_ppca_error = false;
1278 if ( isset($FBdata->error->message) && strpos($FBdata->error->message, 'Public Content Access') !== false ) $cff_ppca_error = true;
1279
1280 $cff_content .= '<div class="cff-error-msg">';
1281 $cff_content .= '<p><i class="fa fa-lock" aria-hidden="true" style="margin-right: 5px;"></i><b>This message is only visible to admins.</b><br />';
1282 if( !$cff_ppca_check_error ) $cff_content .= '<p>Problem displaying Facebook posts.';
1283 if( isset($FBdata->cached_error) ) $cff_content .= ' Backup cache in use.';
1284
1285
1286
1287 $cap = current_user_can( 'manage_custom_facebook_feed_options' ) ? 'manage_custom_facebook_feed_options' : 'manage_options';
1288 $cap = apply_filters( 'cff_settings_pages_capability', $cap );
1289
1290 if( $cff_ppca_check_error || $cff_ppca_error ){
1291
1292 $cff_content .= '</p>';
1293
1294 if( $cff_ppca_error ){
1295 $cff_content .= '<b>PPCA Error:</b> Due to Facebook API changes it is no longer possible to display a feed from a Facebook Page you are not an admin of. The Facebook feed below is not using a valid Access Token for this Facebook page and so has stopped updating.';
1296 } else {
1297 $cff_content .= "<a class='cff_notice_dismiss' href='" .esc_url( add_query_arg( 'cff_ppca_check_notice_dismiss', '0' ) ). "'><span class='fa fa-times-circle' aria-hidden='true'></span></a>";
1298 $cff_content .= '<b class="cff-warning-notice">PPCA Error:</b> Due to Facebook API changes on September 4, 2020, it will no longer be possible to display a feed from a Facebook Page you are not an admin of. The Facebook feed below is not using a valid Access Token for this Facebook page and so will stop updating after this date.';
1299 }
1300
1301 if ( current_user_can( $cap ) ) {
1302 $cff_content .= '<br /><b style="margin-top: 5px; display: inline-block;">Action Required:</b> Please <a href="https://smashballoon.com/facebook-ppca-error-notice/" target="_blank">see here</a> for information on how to fix this.';
1303 }
1304
1305 } else {
1306
1307 $cff_content .= '<br/><a href="javascript:void(0);" id="cff-show-error" onclick="cffShowError()">Click to show error</a>';
1308 $cff_content .= '<script type="text/javascript">function cffShowError() { document.getElementById("cff-error-reason").style.display = "block"; document.getElementById("cff-show-error").style.display = "none"; }</script>';
1309
1310 $cff_content .= '</p><div id="cff-error-reason">';
1311
1312 if( isset($FBdata->error->message) ) $cff_content .= '<b>Error:</b> ' . $FBdata->error->message;
1313 if( isset($FBdata->error->type) ) $cff_content .= '<br /><b>Type:</b> ' . $FBdata->error->type;
1314 if( isset($FBdata->error->error_subcode) ) $cff_content .= '<br />Subcode: ' . $FBdata->error->error_subcode;
1315
1316 if( isset($FBdata->error_msg) ) $cff_content .= '<b>Error:</b> ' . $FBdata->error_msg;
1317 if( isset($FBdata->error_code) ) $cff_content .= '<br />Code: ' . $FBdata->error_code;
1318
1319 if($FBdata == null) $cff_content .= '<b>Error:</b> Server configuration issue';
1320 if( empty($FBdata->error) && empty($FBdata->error_msg) && $FBdata !== null ) $cff_content .= '<b>Error:</b> No posts available for this Facebook ID';
1321
1322 if (current_user_can($cap)) {
1323 $cff_content .= '<br /><b>Solution:</b> <a href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank">See here</a> for how to solve this error';
1324 }
1325
1326 $cff_content .= '</div>'; //End #cff-error-reason
1327
1328 }
1329
1330 $cff_content .= '</div>'; //End .cff-error-msg
1331 //Only display errors to admins
1332 if( current_user_can( $cap ) ){
1333 $cff_content .= '<style>#cff .cff-error-msg{ display: block !important; }</style>';
1334 }
1335 }
1336
1337
1338 $numeric_page_id = '';
1339 if( !empty($FBdata->data) ){
1340 if ( ($cff_show_only_others || $show_posts_by == 'others') && count($FBdata->data) > 0 ) {
1341 //Get the numeric ID of the page so can compare it to the author of each post
1342 $first_post_id = explode("_", $FBdata->data[0]->id);
1343 $numeric_page_id = $first_post_id[0];
1344 }
1345 }
1346
1347 //***STARTS POSTS LOOP***
1348 if( isset($FBdata->data) ){
1349 foreach ($FBdata->data as $news )
1350 {
1351 //Explode News and Page ID's into 2 values
1352 $PostID = '';
1353 $cff_post_id = '';
1354 if( isset($news->id) ){
1355 $cff_post_id = $news->id;
1356 $PostID = explode("_", $cff_post_id);
1357 }
1358
1359 //Reassign variable changes from API v3.3 update
1360 $news->link = '';
1361 $news->description = '';
1362 $news->name = '';
1363 $news->caption = '';
1364 $news->source = '';
1365 $news->object_id = '';
1366 if( isset($news->attachments->data[0]->unshimmed_url) ) $news->link = $news->attachments->data[0]->unshimmed_url;
1367 if( isset($news->attachments->data[0]->description) ) $news->description = $news->attachments->data[0]->description;
1368 if( isset($news->attachments->data[0]->target->id) ) $news->object_id = $news->attachments->data[0]->target->id;
1369 if( isset($news->attachments->data[0]->media->source) ) $news->source = $news->attachments->data[0]->media->source;
1370 if( isset($news->attachments->data[0]->title) ){
1371 $news->name = $news->attachments->data[0]->title;
1372 $news->caption = $news->attachments->data[0]->title;
1373 }
1374
1375 //Check the post type
1376 $cff_post_type = 'status';
1377 if( isset($news->attachments->data[0]->media_type) ) $cff_post_type = $news->attachments->data[0]->media_type;
1378
1379 if ($cff_post_type == 'link') {
1380 isset($news->story) ? $story = $news->story : $story = '';
1381 //Check whether it's an event
1382 $event_link_check = "facebook.com/events/";
1383 if( isset($news->link) ){
1384 $event_link_check = stripos($news->link, $event_link_check);
1385 if ( $event_link_check ) $cff_post_type = 'event';
1386 }
1387 }
1388
1389 //Should we show this post or not?
1390 $cff_show_post = false;
1391 switch ($cff_post_type) {
1392 case 'link':
1393 if ( $cff_show_links_type ) $cff_show_post = true;
1394 break;
1395 case 'event':
1396 if ( $cff_show_event_type ) $cff_show_post = true;
1397 break;
1398 case 'video':
1399 if ( $cff_show_video_type ) $cff_show_post = true;
1400 break;
1401 case 'swf':
1402 if ( $cff_show_video_type ) $cff_show_post = true;
1403 break;
1404 case 'photo':
1405 if ( $cff_show_photos_type ) $cff_show_post = true;
1406 break;
1407 case 'offer':
1408 $cff_show_post = true;
1409 break;
1410 default:
1411 //Check whether it's a status (author comment or like)
1412 if ( $cff_show_status_type && !empty($news->message) ) $cff_show_post = true;
1413 break;
1414 }
1415
1416 //Is it a duplicate post?
1417 if (!isset($prev_post_message)) $prev_post_message = '';
1418 if (!isset($prev_post_link)) $prev_post_link = '';
1419 if (!isset($prev_post_description)) $prev_post_description = '';
1420 isset($news->message) ? $pm = $news->message : $pm = '';
1421 isset($news->link) ? $pl = $news->link : $pl = '';
1422 isset($news->description) ? $pd = $news->description : $pd = '';
1423
1424 if ( ($prev_post_message == $pm) && ($prev_post_link == $pl) && ($prev_post_description == $pd) ) $cff_show_post = false;
1425
1426 //Offset. If the post index ($i_post) is less than the offset then don't show the post
1427 if( intval($i_post) < intval($atts['offset']) ){
1428 $cff_show_post = false;
1429 $i_post++;
1430 }
1431
1432 //Check post type and display post if selected
1433 if ( $cff_show_post ) {
1434 //If it isn't then create the post
1435 //Only create posts for the amount of posts specified
1436 if( intval($atts['offset']) > 0 ){
1437 //If offset is being used then stop after showing the number of posts + the offset
1438 if ( $i_post == (intval($show_posts) + intval($atts['offset'])) ) break;
1439 } else {
1440 //Else just stop after the number of posts to be displayed is reached
1441 if ( $i_post == $show_posts ) break;
1442 }
1443 $i_post++;
1444 //********************************//
1445 //***COMPILE SECTION VARIABLES***//
1446 //********************************//
1447 //Set the post link
1448 isset($news->link) ? $link = htmlspecialchars($news->link) : $link = '';
1449 //Is it a shared album?
1450 $shared_album_string = 'shared an album:';
1451 isset($news->story) ? $story = $news->story : $story = '';
1452 $shared_album = stripos($story, $shared_album_string);
1453 if ( $shared_album ) {
1454 $link = str_replace('photo.php?','media/set/?',$link);
1455 }
1456
1457 //Check the post type
1458 isset($cff_post_type) ? $cff_post_type = $cff_post_type : $cff_post_type = '';
1459 if ($cff_post_type == 'link') {
1460 isset($news->story) ? $story = $news->story : $story = '';
1461 //Check whether it's an event
1462 $event_link_check = "facebook.com/events/";
1463 //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
1464 $event_link_check = stripos($news->link, $event_link_check);
1465 $event_link_check_2 = stripos($news->link, "permalink/");
1466 if ( $event_link_check && !$event_link_check_2 ) $cff_post_type = 'event';
1467 }
1468
1469 //If it's an event then check whether the URL contains facebook.com
1470 if(isset($news->link)){
1471 if( stripos($news->link, "events/") && $cff_post_type == 'event' ){
1472 //Facebook changed the event link from absolute to relative, and so if the link isn't absolute then add facebook.com to front
1473 ( stripos($link, 'facebook.com') ) ? $link = $link : $link = 'https://facebook.com' . $link;
1474 }
1475 }
1476
1477 //Is it an album?
1478 $cff_album = false;
1479 if( isset($news->status_type) ){
1480 if( $news->status_type == 'added_photos' ){
1481 if( isset($news->attachments) ){
1482 if( $news->attachments->data[0]->media_type == 'album' ) $cff_album = true;
1483 }
1484 }
1485 }
1486
1487 //If there's no link provided then link to either the Facebook page or the individual status
1488 if (empty($news->link)) {
1489 if ($cff_link_to_timeline == true){
1490 //Link to page
1491 $link = 'https://facebook.com/' . $page_id;
1492 } else {
1493 //Link to status
1494 $link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1];
1495 }
1496 }
1497
1498 //DATE
1499 $cff_date_formatting = $atts[ 'dateformat' ];
1500 $cff_date_custom = $atts[ 'datecustom' ];
1501
1502 isset($news->created_time) ? $post_time = $news->created_time : $post_time = '';
1503 if( isset($news->backdated_time) ) $post_time = $news->backdated_time; //If the post is backdated then use that as the date instead
1504
1505 $cff_date = '<p class="cff-date" '.$cff_date_styles.'>'. $cff_date_before . ' ' . cff_getdate(strtotime($post_time), $cff_date_formatting, $cff_date_custom, $cff_date_translate_strings, $cff_timezone) . ' ' . $cff_date_after;
1506 if($cff_date_position == 'below' || (!$cff_show_author && $cff_date_position == 'author') ) $cff_date .= '<span class="cff-date-dot">&nbsp;&middot;&nbsp;&nbsp;</span>';
1507 $cff_date .= '</p>';
1508
1509 //Page name
1510 if( isset($news->from->name) ){
1511 $cff_author_name = $news->from->name;
1512 $cff_author_name = str_replace('"', "", $cff_author_name);
1513 } else {
1514 $cff_author_name = '';
1515 }
1516
1517 //Story/post text vars
1518 $post_text = '';
1519 $cff_post_text_type = '';
1520 $cff_story_raw = '';
1521 $cff_message_raw = '';
1522 $cff_name_raw = '';
1523 $text_tags = '';
1524 $post_text_story = '';
1525 $post_text_message = '';
1526
1527 //STORY TAGS
1528 $cff_post_tags = $atts[ 'posttags' ];
1529
1530 //Use the story
1531 if (!empty($news->story)) {
1532 $cff_story_raw = $news->story;
1533 $post_text_story .= htmlspecialchars($cff_story_raw);
1534 $cff_post_text_type = 'story';
1535
1536
1537 //Add message and story tags if there are any and the post text is the message or the story
1538 if( $cff_post_tags && isset($news->story_tags) && !$cff_title_link){
1539
1540 $text_tags = $news->story_tags;
1541
1542 //Does the Post Text contain any html tags? - the & symbol is the best indicator of this
1543 $cff_html_check_array = array('&lt;', '', '', '&quot;', '&amp;', '&gt;&gt;');
1544
1545 //always use the text replace method
1546 if( cff_stripos_arr($post_text_story, $cff_html_check_array) !== false || ($cff_locale == 'el_GR' && count($news->story_tags) > 3) ) {
1547
1548 //Loop through the tags
1549 foreach($text_tags as $message_tag ) {
1550
1551 ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1552
1553 $tag_name = $message_tag->name;
1554 $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
1555
1556 $post_text_story = str_replace($tag_name, $tag_link, $post_text_story);
1557 }
1558
1559 } else {
1560
1561 //If it doesn't contain HTMl tags then use the offset to replace message tags
1562 $message_tags_arr = array();
1563
1564 $tag = 0;
1565 foreach($text_tags as $message_tag ) {
1566 $tag++;
1567 ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1568
1569 isset($message_tag->type) ? $tag_type = $message_tag->type : $tag_type = '';
1570
1571 $message_tags_arr = cff_array_push_assoc(
1572 $message_tags_arr,
1573 $tag,
1574 array(
1575 'id' => $message_tag->id,
1576 'name' => $message_tag->name,
1577 'type' => isset($message_tag->type) ? $message_tag->type : '',
1578 'offset' => $message_tag->offset,
1579 'length' => $message_tag->length
1580 )
1581 );
1582
1583 }
1584
1585 //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.
1586 $cff_story_tag_offsets = '';
1587 $cff_story_duplicate_offset = '';
1588
1589 //Check if there are any duplicate offsets. If so, assign to the cff_story_duplicate_offset var.
1590 for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1591 $c = (string)$message_tags_arr[$tag]['offset'];
1592 if( strpos( $cff_story_tag_offsets, $c ) !== false && $c !== '0' ){
1593 $cff_story_duplicate_offset = $c;
1594 } else {
1595 $cff_story_tag_offsets .= $c . ',';
1596 }
1597
1598 }
1599
1600 for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1601
1602 //If the name is blank (aka the story tag doesn't work properly) then don't use it
1603 if( $message_tags_arr[$tag]['name'] !== '' ) {
1604
1605 //If it's an event tag or it has the same offset as another tag then don't display it
1606 if( $message_tags_arr[$tag]['type'] == 'event' || $message_tags_arr[$tag]['offset'] == $cff_story_duplicate_offset || $message_tags_arr[$tag]['type'] == 'page' ){
1607 //Don't use the story tag in this case otherwise it changes '__ created an event' to '__ created an Name Of Event'
1608 //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.
1609 } else {
1610 $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '" target="_blank">' . $message_tags_arr[$tag]['name'] . '</a>';
1611 $c = $message_tags_arr[$tag]['offset'];
1612 $d = $message_tags_arr[$tag]['length'];
1613 $post_text_story = cff_mb_substr_replace( $post_text_story, $b, $c, $d);
1614 }
1615
1616 }
1617
1618 }
1619
1620 } // end if/else
1621
1622 } //END STORY TAGS
1623
1624 }
1625
1626 //POST AUTHOR
1627 $cff_author = '';
1628 if( isset($news->from->id) ){
1629
1630 $cff_author .= '<div class="cff-author">';
1631
1632 //Check if the author from ID exists, as sometimes it doesn't
1633 isset($news->from->id) ? $cff_from_id = $news->from->id : $cff_from_id = '';
1634
1635 $cff_author_link_atts = 'href="https://facebook.com/' . $cff_from_id . '" '.$target.$cff_nofollow.' '.$cff_author_styles;
1636
1637 //Link to the post if it's a visitor post as profile link no longer available
1638 $cff_author_link_el = 'a';
1639 $cff_author_link_atts = ' href="https://facebook.com/' . $cff_from_id . '" '.$target.$cff_nofollow.' '.$cff_author_styles;
1640
1641 //If no link is available then change to span
1642 if( !isset($news->from->link) ){
1643 $cff_author_link_el = 'span';
1644 $cff_author_link_atts = '';
1645 }
1646
1647 //Remove the first occurence of the author name from the story
1648 if( !empty($cff_author_name) ){
1649 $cff_author_name_pos = strpos($post_text_story, $cff_author_name);
1650 if ($cff_author_name_pos !== false) {
1651 $post_text_story = substr_replace($post_text_story, '', $cff_author_name_pos, strlen($cff_author_name));
1652 }
1653 }
1654
1655 //Author text
1656 $cff_author .= '<div class="cff-author-text">';
1657 if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'){
1658 $cff_author .= '<p class="cff-page-name cff-author-date" '.$cff_author_styles.'><'.$cff_author_link_el.$cff_author_link_atts.'>'.$cff_author_name.'</'.$cff_author_link_el.'><span class="cff-story"> '.$post_text_story.'</span></p>';
1659 $cff_author .= $cff_date;
1660 } else {
1661 $cff_author .= '<span class="cff-page-name"><'.$cff_author_link_el.$cff_author_link_atts.'>'.$cff_author_name.'</'.$cff_author_link_el.'><span class="cff-story"> '.$post_text_story.'</span></span>';
1662 }
1663
1664 $cff_author .= '</div>';
1665
1666 //Author image
1667 isset($news->from->picture->data->url) ? $cff_author_src = $news->from->picture->data->url : $cff_author_src = '';
1668
1669 $cff_author .= '<div class="cff-author-img"><'.$cff_author_link_el.$cff_author_link_atts.'><img src="'.$cff_author_src.'" title="'.$cff_author_name.'" alt="'.$cff_author_name.'" width=40 height=40 onerror="this.style.display=\'none\'"></'.$cff_author_link_el.'></div>';
1670
1671 $cff_author .= '</div>'; //End .cff-author
1672
1673 } else {
1674
1675 $cff_author .= '<div class="cff-author cff-no-author-info">';
1676
1677 //Author text
1678 $cff_author .= '<div class="cff-author-text">';
1679 if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'){
1680 if( !empty($post_text_story) ) $cff_author .= '<p class="cff-page-name cff-author-date"><span class="cff-story"> '.$post_text_story.'</span></p>';
1681 $cff_author .= $cff_date;
1682 } else {
1683 if( !empty($post_text_story) ) $cff_author .= '<span class="cff-page-name"><span class="cff-story"> '.$post_text_story.'</span></span>';
1684 }
1685 $cff_author .= '</div>';
1686
1687 //Author image
1688 $cff_author .= '<div class="cff-author-img"></div>';
1689 $cff_author .= '</div>'; //End .cff-author
1690
1691 }
1692
1693
1694 //POST TEXT
1695
1696 //Get the actual post text
1697 //Which content should we use?
1698 //Use the message
1699 if (!empty($news->message)) {
1700 $cff_message_raw = $news->message;
1701
1702 $post_text_message = htmlspecialchars($cff_message_raw);
1703 $cff_post_text_type = 'message';
1704
1705 //MESSAGE TAGS
1706 //Add message and story tags if there are any and the post text is the message or the story
1707 if( $cff_post_tags && isset($news->message_tags) && !$cff_title_link){
1708
1709 $text_tags = $news->message_tags;
1710
1711 //Does the Post Text contain any html tags? - the & symbol is the best indicator of this
1712 $cff_html_check_array = array('&lt;', '', '', '&quot;', '&amp;', '&gt;&gt;', '&gt;');
1713
1714 //always use the text replace method
1715 if( cff_stripos_arr($post_text_message, $cff_html_check_array) !== false ) {
1716 //Loop through the tags
1717 foreach($text_tags as $message_tag ) {
1718
1719 ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1720
1721 $tag_name = $message_tag->name;
1722 $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
1723
1724 $post_text_message = str_replace($tag_name, $tag_link, $post_text_message);
1725 }
1726
1727 } else {
1728 //If it doesn't contain HTMl tags then use the offset to replace message tags
1729 $message_tags_arr = array();
1730
1731 $tag = 0;
1732 foreach($text_tags as $message_tag ) {
1733 $tag++;
1734
1735 ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1736
1737 $message_tags_arr = cff_array_push_assoc(
1738 $message_tags_arr,
1739 $tag,
1740 array(
1741 'id' => $message_tag->id,
1742 'name' => $message_tag->name,
1743 'type' => isset($message_tag->type) ? $message_tag->type : '',
1744 'offset' => $message_tag->offset,
1745 'length' => $message_tag->length
1746 )
1747 );
1748 }
1749
1750 //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.
1751 $cff_msg_tag_offsets = '';
1752 $cff_msg_duplicate_offset = '';
1753
1754 //Check if there are any duplicate offsets. If so, assign to the cff_duplicate_offset var.
1755 for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1756 $c = (string)$message_tags_arr[$tag]['offset'];
1757 if( strpos( $cff_msg_tag_offsets, $c ) !== false && $c !== '0' ){
1758 $cff_msg_duplicate_offset = $c;
1759 } else {
1760 $cff_msg_tag_offsets .= $c . ',';
1761 }
1762 }
1763
1764 //Sort the array by the "offset" key as Facebook doesn't always return them in the correct order
1765 usort($message_tags_arr, "cffSortTags");
1766
1767 for($tag = count($message_tags_arr)-1; $tag >= 0; $tag--) {
1768
1769 //If the name is blank (aka the story tag doesn't work properly) then don't use it
1770 if( $message_tags_arr[$tag]['name'] !== '' ) {
1771
1772 if( $message_tags_arr[$tag]['offset'] == $cff_msg_duplicate_offset ){
1773 //If it has the same offset as another tag then don't display it
1774 } else {
1775 $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '">' . $message_tags_arr[$tag]['name'] . '</a>';
1776 $c = $message_tags_arr[$tag]['offset'];
1777 $d = $message_tags_arr[$tag]['length'];
1778 $post_text_message = cff_mb_substr_replace( $post_text_message, $b, $c, $d);
1779 }
1780
1781 }
1782
1783 }
1784
1785 } // end if/else
1786
1787 } //END MESSAGE TAGS
1788
1789 }
1790
1791
1792 //Check to see whether it's an embedded video so that we can show the name above the post text if necessary
1793 $cff_soundcloud = false;
1794 $cff_is_video_embed = false;
1795 if ($cff_post_type == 'video' || $cff_post_type == 'music'){
1796 if( isset($news->source) && !empty($news->source) ){
1797 $url = $news->source;
1798 } else if ( isset($news->link) ) {
1799 $url = $news->link;
1800 } else {
1801 $url = '';
1802 }
1803 //Embeddable video strings
1804 $youtube = 'youtube';
1805 $youtu = 'youtu';
1806 $vimeo = 'vimeo';
1807 $youtubeembed = 'youtube.com/embed';
1808 $soundcloud = 'soundcloud.com';
1809 $swf = '.swf';
1810 //Check whether it's a youtube video
1811 $youtube = stripos($url, $youtube);
1812 $youtu = stripos($url, $youtu);
1813 $youtubeembed = stripos($url, $youtubeembed);
1814 //Check whether it's a SoundCloud embed
1815
1816 $soundcloudembed = stripos($url, $soundcloud);
1817 //Check whether it's a youtube video
1818 if($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
1819 $cff_is_video_embed = true;
1820 }
1821 //If it's soundcloud then add it into the shared link box at the bottom of the post
1822 if( $soundcloudembed ) $cff_soundcloud = true;
1823
1824 $cff_video_name = '';
1825 //If the name exists and it's a non-embedded video then show the name at the top of the post text
1826 if( isset($news->name) && !$cff_is_video_embed ){
1827
1828 if (!$cff_title_link) $cff_video_name .= '<a href="'.$link.'" '.$target.$cff_nofollow.' style="color: #'.$cff_posttext_link_color.'">';
1829 $cff_video_name .= htmlspecialchars($news->name);
1830 if (!$cff_title_link) $cff_video_name .= '</a>';
1831 $cff_video_name .= '<br />';
1832
1833 //Only show the video name if there's no post text
1834 if( empty($post_text_message) || $post_text_message == '' || strlen($post_text_message) < 1 ){
1835
1836 //If there's no description then show the video name above the post text, otherwise we'll show it below
1837 if( empty($cff_description) || $cff_description == '' ) $post_text = $cff_video_name;
1838
1839 }
1840 }
1841 }
1842
1843 //Add the story and message together
1844 $post_text = '';
1845
1846 //DESCRIPTION
1847 $cff_description = '';
1848 if ( !empty($news->description) || !empty($news->caption) ) {
1849 $description_text = '';
1850
1851 if ( !empty($news->description) ) {
1852 $description_text = $news->description;
1853 }
1854
1855 //Replace ellipsis char in description text
1856 $raw_desc = $description_text;
1857 $description_text = str_replace( '','...', $description_text);
1858
1859 //If the description is the same as the post text then don't show it
1860 if( $raw_desc == $cff_story_raw || $raw_desc == $cff_message_raw || $raw_desc == $cff_name_raw ){
1861 $cff_description = '';
1862 } else {
1863 //Add links and create HTML
1864 $cff_description .= '<span class="cff-post-desc" '.$cff_body_styles.'>';
1865
1866 if ($cff_title_link) {
1867 $cff_description_tagged = cff_wrap_span( htmlspecialchars($description_text) );
1868 } else {
1869 $cff_description_text = cff_autolink( htmlspecialchars($description_text), $link_color=$cff_posttext_link_color );
1870 $cff_description_tagged = cff_desc_tags($cff_description_text);
1871 }
1872
1873 $cff_description .= $cff_description_tagged;
1874 $cff_description .= ' </span>';
1875 }
1876
1877 if( $cff_post_type == 'event' || $cff_is_video_embed || $cff_soundcloud ) $cff_description = '';
1878 }
1879
1880 //Add the message
1881 if($cff_show_text) $post_text .= $post_text_message;
1882
1883 $post_text = apply_filters( 'cff_post_text', $post_text );
1884
1885 //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
1886 if ($cff_post_type == 'video'){
1887 if( !empty($cff_description) && $cff_description != '' ){
1888 if( (!empty($post_text) && $post_text != '') && !empty($cff_video_name) ) $post_text .= '<br /><br />';
1889 $post_text .= $cff_video_name;
1890 }
1891 }
1892
1893
1894 //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
1895 if ( !empty($news->name) && empty($news->message) && $cff_post_type != 'link' ) {
1896 $cff_name_raw = $news->name;
1897 $post_text = htmlspecialchars($cff_name_raw);
1898 $cff_post_text_type = 'name';
1899 }
1900
1901 //OFFER TEXT
1902 if ($cff_post_type == 'offer'){
1903 isset($news->story) ? $post_text = htmlspecialchars($news->story) . '<br /><br />' : $post_text = '';
1904 $post_text .= htmlspecialchars($news->name);
1905 $cff_post_text_type = 'story';
1906 }
1907
1908 //Add the description
1909 if( $cff_show_desc && $cff_post_type != 'offer' && $cff_post_type != 'link' ) $post_text .= $cff_description;
1910
1911 //Change the linebreak element if the text issue setting is enabled
1912 $cff_format_issue = $atts['textissue'];
1913 ($cff_format_issue == 'true' || $cff_format_issue == 'on') ? $cff_format_issue = true : $cff_format_issue = false;
1914 $cff_linebreak_el = '<br />';
1915 if( $cff_format_issue ) $cff_linebreak_el = '<img class="cff-linebreak" />';
1916
1917 //EVENT
1918 $cff_event_has_cover_photo = false;
1919 $cff_event = '';
1920
1921
1922 //Create note
1923 if ($cff_post_type == 'note') {
1924
1925 // Get any existing copy of our transient data from previous versions
1926 $transient_name = 'cff_tle_' . $cff_post_id;
1927 $transient_name = substr($transient_name, 0, 45);
1928 if ( false !== ( $cff_note_json = get_transient( $transient_name ) ) ) {
1929 $cff_note_json = get_transient( $transient_name );
1930
1931 //Interpret data with JSON
1932 $cff_note_obj = json_decode($cff_note_json);
1933 $cff_note_object = $cff_note_obj->attachments->data[0];
1934 isset($cff_note_object->title) ? $cff_note_title = htmlentities($cff_note_object->title, ENT_QUOTES, 'UTF-8') : $cff_note_title = '';
1935 isset($cff_note_object->description) ? $cff_note_description = htmlentities($cff_note_object->description, ENT_QUOTES, 'UTF-8') : $cff_note_description = '';
1936 isset($cff_note_object->url) ? $cff_note_link = $cff_note_object->url : $cff_note_link = '';
1937 isset( $cff_note_object->media->image->src ) ? $cff_note_media_src = $cff_note_object->media->image->src : $cff_note_media_src = false;
1938 } else {
1939 $attachment_data = '';
1940 if(isset($news->attachments->data[0])){
1941 $attachment_data = $news->attachments->data[0];
1942 isset($attachment_data->title) ? $cff_note_title = htmlentities($attachment_data->title, ENT_QUOTES, 'UTF-8') : $cff_note_title = '';
1943 isset($attachment_data->description) ? $cff_note_description = htmlentities($attachment_data->description, ENT_QUOTES, 'UTF-8') : $cff_note_description = '';
1944 isset($attachment_data->unshimmed_url) ? $cff_note_link = $attachment_data->unshimmed_url : $cff_note_link = '';
1945 $cff_note_media_src = '';
1946 }
1947 }
1948
1949
1950 //Note details
1951 $cff_note = '<span class="cff-details">';
1952 $cff_note = '<span class="cff-note-title">'.$cff_note_title.'</span>';
1953 $cff_note .= $cff_note_description;
1954 $cff_note .= '</span>';
1955
1956 //Notes don't include any post text and so just replace the post text with the note content
1957 if($cff_show_text) $post_text = $cff_note;
1958 }
1959
1960
1961 //Create the HTML for the post text elemtent, if the post has text
1962 $cff_post_text = '';
1963
1964 if( !empty($post_text) ){
1965 $cff_post_text = '<' . $cff_title_format . ' class="cff-post-text" ' . $cff_title_styles . '>';
1966
1967 //Start HTML for post text
1968 $cff_post_text .= '<span class="cff-text" data-color="'.$cff_posttext_link_color.'">';
1969 if ($cff_title_link){
1970 //Link to the Facebook post if it's a link or a video;
1971 ($cff_post_type == 'link' || $cff_post_type == 'video') ? $text_link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1] : $text_link = $link;
1972
1973 $cff_post_text .= '<a class="cff-post-text-link" '.$cff_title_styles.' href="'.$text_link.'" '.$target.$cff_nofollow.'>';
1974 }
1975
1976 //Replace line breaks in text (needed for IE8 and to prevent lost line breaks in HTML minification)
1977 $post_text = preg_replace("/\r\n|\r|\n/",$cff_linebreak_el, $post_text);
1978
1979 //If the text is wrapped in a link then don't hyperlink any text within
1980 if ($cff_title_link) {
1981 //Remove links from text
1982 $result = preg_replace('/<a href=\"(.*?)\">(.*?)<\/a>/', "\\2", $post_text);
1983 //Wrap links in a span so we can break the text if it's too long
1984 $cff_post_text .= cff_wrap_span( $result ) . ' ';
1985 } else {
1986 //Don't use htmlspecialchars for post_text as it's added above so that it doesn't mess up the message_tag offsets
1987 $cff_post_text .= cff_autolink( $post_text ) . ' ';
1988 }
1989
1990 if ($cff_title_link) $cff_post_text .= '</a>';
1991 $cff_post_text .= '</span>';
1992 //'See More' link
1993 $cff_post_text .= '<span class="cff-expand">... <a href="#" style="color: #'.$cff_posttext_link_color.'"><span class="cff-more">' . $cff_see_more_text . '</span><span class="cff-less">' . $cff_see_less_text . '</span></a></span>';
1994 $cff_post_text .= '</' . $cff_title_format . '>';
1995
1996 //Facebook returns the text as "'s cover photo" for some reason, so ignore it
1997 if( $post_text == "'s cover photo" ) $cff_post_text = '';
1998 }
1999
2000 //Add a call to action button if included
2001 if( isset($news->call_to_action->value->link) ){
2002 $cff_cta_link = $news->call_to_action->value->link;
2003
2004 if( $cff_cta_link[0] == '/' ){
2005 $cff_cta_link = 'https://facebook.com' . $cff_cta_link;
2006 } else {
2007 //If it doesn't start with 'http' then add it otherwise the link doesn't work. Don't do this if it's a tel num.
2008 if (strpos($cff_cta_link, 'http') === false && strpos($cff_cta_link, 'tel:') === false) $cff_cta_link = 'http://' . $cff_cta_link;
2009 }
2010
2011 $cff_button_type = $news->call_to_action->type;
2012
2013 switch ($cff_button_type) {
2014 case 'SHOP_NOW':
2015 $cff_translate_shop_now_text = $atts['shopnowtext'];
2016 if (!isset($cff_translate_shop_now_text) || empty($cff_translate_shop_now_text)) $cff_translate_shop_now_text = 'Shop Now';
2017 $cff_cta_button_text = $cff_translate_shop_now_text;
2018 break;
2019 case 'MESSAGE_PAGE':
2020 $cff_translate_message_page_text = $atts['messagepage'];
2021 if (!isset($cff_translate_message_page_text) || empty($cff_translate_message_page_text)) $cff_translate_message_page_text = 'Message Page';
2022 $cff_cta_button_text = $cff_translate_message_page_text;
2023 break;
2024 case 'LEARN_MORE':
2025 $cff_translate_learn_more_text = $atts['learnmoretext'];
2026 if (!isset($cff_translate_learn_more_text) || empty($cff_translate_learn_more_text)) $cff_translate_learn_more_text = 'Learn More';
2027 $cff_cta_button_text = $cff_translate_learn_more_text;
2028 break;
2029 default:
2030 $cff_cta_button_text = ucwords(strtolower( str_replace('_',' ',$cff_button_type) ) );
2031 }
2032
2033 isset($news->call_to_action->value->app_link) ? $cff_app_link = $news->call_to_action->value->app_link : $cff_app_link = '';
2034 $cff_post_text .= '<p class="cff-cta-link" '.$cff_title_styles.'><a href="'.$cff_cta_link.'" target="_blank" data-app-link="'.$cff_app_link.'" style="color: #'.$cff_posttext_link_color.';" '.$cff_nofollow_referrer.' >'.$cff_cta_button_text.'</a></p>';
2035 }
2036
2037 //LINK
2038 $cff_shared_link = '';
2039 //Display shared link
2040 if ($cff_post_type == 'link' || $cff_soundcloud || $cff_is_video_embed) {
2041
2042 $cff_shared_link .= '<div class="cff-shared-link';
2043 if($cff_disable_link_box) $cff_shared_link .= ' cff-no-styles';
2044
2045 $cff_shared_link .= '" ';
2046
2047 if(!$cff_disable_link_box) $cff_shared_link .= $cff_link_box_styles;
2048 $cff_shared_link .= '>';
2049 $cff_link_image = '';
2050
2051 //Display link name and description
2052 $cff_shared_link .= '<div class="cff-text-link ';
2053 if (!$cff_link_image) $cff_shared_link .= 'cff-no-image';
2054 //The link title:
2055 if( isset($news->name) ) $cff_shared_link .= '"><'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow_referrer.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
2056 //The link source:
2057 if( !empty($news->link) ){
2058 $cff_link_caption = htmlentities($news->link, ENT_QUOTES, 'UTF-8');
2059 $cff_link_caption_parts = explode('/', $cff_link_caption);
2060 if( isset($cff_link_caption_parts[2]) ) $cff_link_caption = $cff_link_caption_parts[2];
2061 } else {
2062 $cff_link_caption = '';
2063 }
2064
2065 //Shared link styles
2066 $cff_link_url_color_html = '';
2067 $cff_link_url_size_html = '';
2068 if( isset($cff_link_url_color) && !empty($cff_link_url_color) && $cff_link_url_color != '#' ) $cff_link_url_color_html = 'color: #'.str_replace('#', '', $cff_link_url_color).';';
2069 if( $cff_link_url_size != 'inherit' && !empty($cff_link_url_size) ) $cff_link_url_size_html = 'font-size:'.$cff_link_url_size.'px;';
2070
2071 $cff_link_styles_html = '';
2072 if( strlen($cff_link_url_color_html) > 1 || strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html = 'style="';
2073 if( strlen($cff_link_url_color_html) > 1 ) $cff_link_styles_html .= $cff_link_url_color_html;
2074 if( strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html .= $cff_link_url_size_html;
2075 if( strlen($cff_link_url_color_html) > 1 || strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html .= '"';
2076
2077 if(!empty($cff_link_caption)) $cff_shared_link .= '<p class="cff-link-caption" '.$cff_link_styles_html.'>'.$cff_link_caption.'</p>';
2078 if ($cff_show_desc) {
2079 //Truncate desc
2080 if (!empty($body_limit)) {
2081 if (strlen($description_text) > $body_limit) $description_text = substr($description_text, 0, $body_limit) . '...';
2082 }
2083
2084 //Shared link desc styles
2085 $cff_link_desc_color_html = '';
2086 $cff_link_desc_size_html = '';
2087 if( isset($cff_link_desc_color) && !empty($cff_link_desc_color) && $cff_link_desc_color != '#' ) $cff_link_desc_color_html = 'color: #'.str_replace('#', '', $cff_link_desc_color).';';
2088 if( $cff_link_desc_size != 'inherit' && !empty($cff_link_desc_size) ) $cff_link_desc_size_html = 'font-size:'.$cff_link_desc_size.'px;';
2089
2090 $cff_link_desc_styles_html = '';
2091 if( strlen($cff_link_desc_color_html) > 1 || strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html = 'style="';
2092 if( strlen($cff_link_desc_color_html) > 1 ) $cff_link_desc_styles_html .= $cff_link_desc_color_html;
2093 if( strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html .= $cff_link_desc_size_html;
2094 if( strlen($cff_link_desc_color_html) > 1 || strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html .= '"';
2095
2096 //Add links and create HTML
2097 $cff_link_description = '<span class="cff-post-desc" '.$cff_link_desc_styles_html.'>';
2098 if ($cff_title_link) {
2099 $cff_link_description .= cff_wrap_span( htmlspecialchars($description_text) );
2100 } else {
2101 $description_text = cff_autolink( htmlspecialchars($description_text), $link_color=$cff_posttext_link_color );
2102 //Replace line breaks with <br> tags
2103 $cff_link_description .= nl2br($description_text);
2104 }
2105 $cff_link_description .= ' </span>';
2106
2107
2108 if( $description_text != $cff_link_caption ) $cff_shared_link .= $cff_link_description;
2109 }
2110
2111 $cff_shared_link .= '</div></div>';
2112 }
2113
2114 /* VIDEO */
2115
2116 //Check to see whether it's an embedded video so that we can show the name above the post text if necessary
2117 $cff_is_video_embed = false;
2118 if ( $cff_post_type == 'video' && isset($news->source) ){
2119 $url = $news->source;
2120 //Embeddable video strings
2121 $youtube = 'youtube';
2122 $youtu = 'youtu';
2123 $vimeo = 'vimeo';
2124 $youtubeembed = 'youtube.com/embed';
2125 //Check whether it's a youtube video
2126 $youtube = stripos($url, $youtube);
2127 $youtu = stripos($url, $youtu);
2128 $youtubeembed = stripos($url, $youtubeembed);
2129 //Check whether it's a youtube video
2130 if($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
2131 $cff_is_video_embed = true;
2132 }
2133 }
2134
2135
2136 $cff_media = '';
2137 if ($cff_post_type == 'video') {
2138 //Add the name to the description if it's a video embed
2139 if($cff_is_video_embed) {
2140 isset($news->name) ? $video_name = $news->name : $video_name = $link;
2141 isset($news->description) ? $description_text = $news->description : $description_text = '';
2142 //Add the 'cff-shared-link' class so that embedded videos display in a box
2143 $cff_description = '<div class="cff-desc-wrap cff-shared-link ';
2144 if (empty($picture)) $cff_description .= 'cff-no-image';
2145 if($cff_disable_link_box) $cff_description .= ' cff-no-styles"';
2146 if(!$cff_disable_link_box) $cff_description .= '" ' . $cff_link_box_styles;
2147 $cff_description .= '>';
2148
2149 if( isset($news->name) ) $cff_description .= '<'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
2150
2151 if (!empty($body_limit)) {
2152 if (strlen($description_text) > $body_limit) $description_text = substr($description_text, 0, $body_limit) . '...';
2153 }
2154
2155 $cff_description .= '<p class="cff-post-desc" '.$cff_body_styles.'><span>' . cff_autolink( htmlspecialchars($description_text) ) . '</span></p></div>';
2156 } else {
2157 isset($news->name) ? $video_name = $news->name : $video_name = $link;
2158 if( isset($news->name) ) $cff_description .= '<'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
2159 }
2160 }
2161
2162
2163 //Display the link to the Facebook post or external link
2164 $cff_link = '';
2165 //Default link
2166 $cff_viewpost_class = 'cff-viewpost-facebook';
2167 if ($cff_facebook_link_text == '') $cff_facebook_link_text = 'View on Facebook';
2168 $link_text = $cff_facebook_link_text;
2169
2170 //Link to the Facebook post if it's a link or a video
2171 if($cff_post_type == 'link' || $cff_post_type == 'video') $link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1];
2172
2173 //Remove "see more" text from post text so isn't included when shared
2174 $cff_post_text_to_share = '';
2175 if( strpos($cff_post_text, '<span class="cff-expand">') !== false ){
2176 $cff_post_text_to_share = explode('<span class="cff-expand">', $cff_post_text);
2177 if( is_array($cff_post_text_to_share) ) $cff_post_text_to_share = $cff_post_text_to_share[0];
2178 }
2179
2180 //Social media sharing URLs
2181 $cff_share_facebook = 'https://www.facebook.com/sharer/sharer.php?u=' . urlencode($link);
2182 $cff_share_twitter = 'https://twitter.com/intent/tweet?text=' . urlencode($link);
2183 $cff_share_google = 'https://plus.google.com/share?url=' . urlencode($link);
2184 $cff_share_linkedin = 'https://www.linkedin.com/shareArticle?mini=true&amp;url=' . urlencode($link) . '&amp;title=' . rawurlencode( strip_tags($cff_post_text_to_share) );
2185 $cff_share_email = 'mailto:?subject=Facebook&amp;body=' . urlencode($link) . '%20-%20' . rawurlencode( strip_tags($cff_post_text_to_share) );
2186
2187 //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
2188 if( isset($news->status_type) ){
2189 if( $news->status_type == 'shared_story' ) $link = "https://www.facebook.com/" . $cff_post_id;
2190 }
2191
2192 //If it's an offer post then change the text
2193 if ($cff_post_type == 'offer') $link_text = 'View Offer';
2194
2195 //Create post action links HTML
2196 $cff_link = '';
2197 if($cff_show_facebook_link || $cff_show_facebook_share){
2198 $cff_link .= '<div class="cff-post-links">';
2199
2200 //View on Facebook link
2201 if($cff_show_facebook_link) $cff_link .= '<a class="' . $cff_viewpost_class . '" href="' . $link . '" title="' . $link_text . '" ' . $target . $cff_nofollow . ' ' . $cff_link_styles . '>' . $link_text . '</a>';
2202
2203 //Share link
2204 if($cff_show_facebook_share){
2205 $cff_link .= '<div class="cff-share-container">';
2206 //Only show separating dot if both links are enabled
2207 if($cff_show_facebook_link) $cff_link .= '<span class="cff-dot" ' . $cff_link_styles . '>&middot;</span>';
2208 $cff_link .= '<a class="cff-share-link" href="'.$cff_share_facebook.'" title="' . $cff_facebook_share_text . '" ' . $cff_link_styles . '>' . $cff_facebook_share_text . '</a>';
2209 $cff_link .= "<p class='cff-share-tooltip'><a href='".$cff_share_facebook."' target='_blank' class='cff-facebook-icon'><span class='fa fab fa-facebook-square' aria-hidden='true'></span><span class='cff-screenreader'>Share on Facebook</span></a><a href='".$cff_share_twitter."' target='_blank' class='cff-twitter-icon'><span class='fa fab fa-twitter' aria-hidden='true'></span><span class='cff-screenreader'>Share on Twitter</span></a><a href='".$cff_share_linkedin."' target='_blank' class='cff-linkedin-icon'><span class='fa fab fa-linkedin' aria-hidden='true'></span><span class='cff-screenreader'>Share on Linked In</span></a><a href='".$cff_share_email."' target='_blank' class='cff-email-icon'><span class='fa fa-envelope' aria-hidden='true'></span><span class='cff-screenreader'>Share by Email</span></a><span class='fa fa-play fa-rotate-90' aria-hidden='true'></span></p></div>";
2210 }
2211
2212 $cff_link .= '</div>';
2213 }
2214
2215
2216 /* MEDIA LINK */
2217 $cff_translate_photo_text = $atts['phototext'];
2218 if (!isset($cff_translate_photo_text) || empty($cff_translate_photo_text)) $cff_translate_photo_text = 'Photo';
2219 $cff_translate_video_text = $atts['videotext'];
2220 if (!isset($cff_translate_video_text) || empty($cff_translate_video_text)) $cff_translate_video_text = 'Video';
2221
2222 $cff_media_link = '';
2223
2224 if( $cff_show_media_link && ($cff_post_type == 'photo' || $cff_post_type == 'video' || $cff_album) ){
2225 $cff_media_link .= '<p class="cff-media-link"><a href="'.$link.'" '.$target.' style="color: #'.$cff_posttext_link_color.';"><span style="padding-right: 5px;" class="fa fas fa-';
2226 if($cff_post_type == 'photo' || $cff_album) $cff_media_link .= 'picture-o fa-image" aria-hidden="true"></span>'. $cff_translate_photo_text;
2227 // if($cff_post_type == 'video') $cff_media_link .= 'file-video-o';
2228 if($cff_post_type == 'video') $cff_media_link .= 'video-camera fa-video" aria-hidden="true"></span>'. $cff_translate_video_text;
2229 $cff_media_link .= '</a></p>';
2230 }
2231
2232 //**************************//
2233 //***CREATE THE POST HTML***//
2234 //**************************//
2235 //Start the container
2236 $cff_post_item = '<div class="cff-item ';
2237 $cff_post_type_class = 'cff-status-post';
2238 if ($cff_post_type == 'link') $cff_post_type_class = 'cff-link-item';
2239 if ($cff_post_type == 'event') $cff_post_type_class = 'cff-timeline-event';
2240 if ($cff_post_type == 'photo') $cff_post_type_class = 'cff-photo-post';
2241 if ($cff_post_type == 'video') $cff_post_type_class = 'cff-video-post';
2242 if ($cff_post_type == 'swf') $cff_post_type_class = 'cff-swf-post';
2243 if ($cff_post_type == 'offer') $cff_post_type_class = 'cff-offer-post';
2244 $cff_post_item .= $cff_post_type_class;
2245 if ($cff_album) $cff_post_item .= ' cff-album';
2246
2247 if ($cff_post_bg_color_check || $cff_post_style == "boxed") $cff_post_item .= ' cff-box';
2248 if( $cff_box_shadow ) $cff_post_item .= ' cff-shadow';
2249 if(isset($news->from->name)) $cff_post_item .= ' author-'. cff_to_slug($news->from->name);
2250 $cff_post_item .= '" id="cff_'. $cff_post_id .'" ' . $cff_item_styles . '>';
2251
2252 //POST AUTHOR
2253 if($cff_show_author) $cff_post_item .= $cff_author;
2254 //DATE ABOVE
2255 if ($cff_show_date && $cff_date_position == 'above') $cff_post_item .= $cff_date;
2256 //POST TEXT
2257 if($cff_show_text || $cff_show_desc) $cff_post_item .= $cff_post_text;
2258 //LINK
2259 if($cff_show_shared_links) $cff_post_item .= $cff_shared_link;
2260 //DATE BELOW
2261 if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below') {
2262 if($cff_show_date && $cff_post_type !== 'event') $cff_post_item .= $cff_date;
2263 }
2264 //DATE BELOW (only for Event posts)
2265 if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below') {
2266 if($cff_show_date && $cff_post_type == 'event') $cff_post_item .= $cff_date;
2267 }
2268
2269 //MEDIA LINK
2270 if($cff_show_media_link) $cff_post_item .= $cff_media_link;
2271 //VIEW ON FACEBOOK LINK
2272 if($cff_show_link) $cff_post_item .= $cff_link;
2273
2274 //End the post item
2275 $cff_post_item .= '</div>';
2276
2277 //PUSH TO ARRAY
2278 $cff_posts_array = cff_array_push_assoc($cff_posts_array, $i_post, $cff_post_item);
2279
2280 } // End post type check
2281
2282 if (isset($news->message)) $prev_post_message = $news->message;
2283 if (isset($news->link)) $prev_post_link = $news->link;
2284 if (isset($news->description)) $prev_post_description = $news->description;
2285
2286 } // End the loop
2287 } //End isset($FBdata->data)
2288
2289 //Sort the array in reverse order (newest first)
2290 if(!$cff_is_group) ksort($cff_posts_array);
2291
2292 } // End ALL POSTS
2293
2294
2295 //Output the posts array
2296 $p = 0;
2297 foreach ($cff_posts_array as $post ) {
2298 if ( $p == $show_posts ) break;
2299 $cff_content .= $post;
2300 $p++;
2301 }
2302
2303 //Add the Like Box inside
2304 if ($cff_like_box_position == 'bottom' && $cff_show_like_box && !$cff_like_box_outside) $cff_content .= $like_box;
2305 /* Credit link */
2306 $cff_show_credit = $atts['credit'];
2307 ($cff_show_credit == 'true' || $cff_show_credit == 'on') ? $cff_show_credit = true : $cff_show_credit = false;
2308
2309 if($cff_show_credit) $cff_content .= '<p class="cff-credit"><a href="https://smashballoon.com/custom-facebook-feed/" target="_blank" style="color: #'.$link_color=$cff_posttext_link_color.'" title="Smash Balloon Custom Facebook Feed WordPress Plugin"><img src="'.plugins_url( '/img/smashballoon-tiny.png' , __FILE__ ).'" alt="Smash Balloon Custom Facebook Feed WordPress Plugin" />The Custom Facebook Feed plugin</a></p>';
2310 //End the feed
2311 $cff_content .= '</div><div class="cff-clear"></div>';
2312 //Add the Like Box outside
2313 if ($cff_like_box_position == 'bottom' && $cff_show_like_box && $cff_like_box_outside) $cff_content .= $like_box;
2314
2315 //If the feed is loaded via Ajax then put the scripts into the shortcode itself
2316 $ajax_theme = $atts['ajax'];
2317 ( $ajax_theme == 'on' || $ajax_theme == 'true' || $ajax_theme == true ) ? $ajax_theme = true : $ajax_theme = false;
2318 if( $atts[ 'ajax' ] == 'false' ) $ajax_theme = false;
2319 if ($ajax_theme) {
2320 //Minify files?
2321 $options = get_option('cff_style_settings');
2322 isset($options[ 'cff_minify' ]) ? $cff_minify = $options[ 'cff_minify' ] : $cff_minify = '';
2323 $cff_minify ? $cff_min = '.min' : $cff_min = '';
2324
2325 $cff_link_hashtags = $atts['linkhashtags'];
2326 ($cff_link_hashtags == 'true' || $cff_link_hashtags == 'on') ? $cff_link_hashtags = 'true' : $cff_link_hashtags = 'false';
2327 if($cff_title_link == 'true' || $cff_title_link == 'on') $cff_link_hashtags = 'false';
2328 $cff_content .= '<script type="text/javascript">var cfflinkhashtags = "' . $cff_link_hashtags . '";</script>';
2329 $cff_content .= '<script type="text/javascript" src="' . plugins_url( '/js/cff-scripts'.$cff_min.'.js?ver='.CFFVER , __FILE__ ) . '"></script>';
2330 }
2331
2332 $cff_content .= '</div>';
2333
2334 if( isset( $cff_posttext_link_color ) && !empty( $cff_posttext_link_color ) ) $cff_content .= '<style>#cff .cff-post-text a{ color: #'.$cff_posttext_link_color.'; }</style>';
2335
2336 //Return our feed HTML to display
2337 return $cff_content;
2338 }
2339
2340 //***FUNCTIONS***
2341
2342 //Link @[] or \u0040[Page ID:274:Page Name] post tagging format
2343 function cff_desc_tags($description){
2344 preg_match_all( "/@\[(.*?)\]/", $description, $cff_tag_matches );
2345 $replace_strings_arr = array();
2346 foreach ( $cff_tag_matches[1] as $cff_tag_match ) {
2347 $cff_tag_parts = explode( ':', $cff_tag_match );
2348 $replace_strings_arr[] = '<a href="https://facebook.com/'.$cff_tag_parts[0].'">'.$cff_tag_parts[2].'</a>';
2349 }
2350 $cff_tag_iterator = 0;
2351 $cff_description_tagged = '';
2352 $cff_text_split = preg_split( "/@\[(.*?)\]/" , $description );
2353 foreach ( $cff_text_split as $cff_desc_split ) {
2354 if ( $cff_tag_iterator < count( $replace_strings_arr ) ) {
2355 $cff_description_tagged .= $cff_desc_split . $replace_strings_arr[ $cff_tag_iterator ];
2356 } else {
2357 $cff_description_tagged .= $cff_desc_split;
2358 }
2359 $cff_tag_iterator++;
2360 }
2361
2362 return $cff_description_tagged;
2363 }
2364 //Sort message tags by offset value
2365 function cffSortTags($a, $b) {
2366 return $a['offset'] - $b['offset'];
2367 }
2368
2369 function cff_is_wp_error( $response ) {
2370 return is_wp_error( $response );
2371 }
2372 function cff_log_wp_error( $response, $url ) {
2373 if ( is_wp_error( $response ) ) {
2374 global $cff_error_reporter;
2375 delete_option( 'cff_dismiss_critical_notice' );
2376
2377 $admin_message_error = '';
2378 if ( isset( $response ) && isset( $response->errors ) ) {
2379 foreach ( $response->errors as $key => $item ) {
2380 $admin_message_error .= ' '.$key . ' - ' . $item[0];
2381 }
2382 }
2383
2384 $admin_message = __( 'Error connecting to the Facebook API:', 'custom-facebook-feed' ) . ' ' . $admin_message_error;
2385 $public_message =__( 'Unable to make remote requests to the Facebook API. Log in as an admin to view more details.', 'custom-facebook-feed' );
2386 $frontend_directions = '<p class="cff-error-directions"><a href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a></p>';
2387 $backend_directions = '<a class="button button-primary" href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a>';
2388 $error = array(
2389 'accesstoken' => 'none',
2390 'public_message' => $public_message,
2391 'admin_message' => $admin_message,
2392 'frontend_directions' => $frontend_directions,
2393 'backend_directions' => $backend_directions,
2394 'post_id' => get_the_ID(),
2395 'errorno' => 'wp_remote_get'
2396 );
2397
2398
2399 $cff_error_reporter->add_error( 'wp_remote_get', $error );
2400 }
2401 }
2402 function cff_is_fb_error( $response ) {
2403 return (strpos( $response, '{"error":' ) === 0);
2404 }
2405 function cff_log_fb_error( $response, $url ) {
2406 if ( is_admin() ) {
2407 return;
2408 }
2409 global $cff_error_reporter;
2410 delete_option( 'cff_dismiss_critical_notice' );
2411
2412 $access_token_refresh_errors = array( 10, 4, 200 );
2413
2414 $response = json_decode( $response, true );
2415 $api_error_code = $response['error']['code'];
2416
2417 //Page Public Content Access error
2418 $ppca_error = false;
2419 if( strpos($response['error']['message'], 'Public Content Access') !== false ) $ppca_error = true;
2420
2421 if ( in_array( (int)$api_error_code, $access_token_refresh_errors, true ) && !$ppca_error ) {
2422 $pieces = explode( 'access_token=', $url );
2423 $accesstoken_parts = isset( $pieces[1] ) ? explode( '&', $pieces[1] ) : 'none';
2424 $accesstoken = $accesstoken_parts[0];
2425
2426 $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $api_error_code );
2427 $admin_message = '<strong>' . $api_error_number_message . '</strong><br>' . $response['error']['message'];
2428 $public_message = __( 'There is a problem with your access token.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
2429 $link = admin_url( 'admin.php?page=cff-top' );
2430 $frontend_directions = '<p class="cff-error-directions cff-reconnect"><a href="'. esc_url( $link ).'" target="_blank" rel="noopener">' . __( 'Reconnect Your Account in the Admin Area', 'custom-facebook-feed') . '</a></p>';
2431 $backend_directions = '<button class="cff-reconnect button button-primary" >' . __( 'Reconnect Your Account', 'custom-facebook-feed') . '</button>';
2432 $error = array(
2433 'accesstoken' => $accesstoken,
2434 'post_id' => get_the_ID(),
2435 'errorno' => $api_error_code
2436 );
2437
2438 $cff_error_reporter->add_error( 'accesstoken', $error );
2439 } else {
2440 $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $api_error_code );
2441 $admin_message = '<strong>' . $api_error_number_message . '</strong><br>' . $response['error']['message'];
2442 $public_message = __( 'Error connecting to the Facebook API.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
2443 $frontend_directions = '<p class="cff-error-directions"><a href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a></p>';
2444 $backend_directions = '<a class="button button-primary" href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a>';
2445
2446 //Page Public Content Access admin error
2447 if( $ppca_error ){
2448 $api_error_number_message = false;
2449 $admin_message = '<B>PPCA Error:</b> Due to Facebook API changes it is no longer possible to display a feed from a Facebook Page you are not an admin of. Please use the button below for more information on how to fix this.';
2450 $public_message = __( 'Error connecting to the Facebook API.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
2451 $frontend_directions = '<p class="cff-error-directions"><a href="https://smashballoon.com/facebook-api-changes-september-4-2020/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a></p>';
2452 $backend_directions = '<a class="button button-primary" href="https://smashballoon.com/facebook-api-changes-september-4-2020/" target="_blank" rel="noopener">' . __( 'Directions on How to Resolve This Issue', 'custom-facebook-feed' ) . '</a>';
2453 }
2454
2455 $error = array(
2456 'accesstoken' => 'none',
2457 'public_message' => $public_message,
2458 'admin_message' => $admin_message,
2459 'frontend_directions' => $frontend_directions,
2460 'backend_directions' => $backend_directions,
2461 'post_id' => get_the_ID(),
2462 'errorno' => $api_error_code
2463 );
2464
2465 $cff_error_reporter->add_error( 'api', $error );
2466 }
2467
2468 }
2469 //Get JSON object of feed data
2470 function cff_fetchUrl($url){
2471 $response = wp_remote_get( $url );
2472
2473 if ( !cff_is_wp_error( $response ) ) {
2474 $feedData = wp_remote_retrieve_body( $response );
2475
2476 if ( ! cff_is_fb_error( $feedData ) ) {
2477 global $cff_error_reporter;
2478
2479 $cff_error_reporter->remove_error( 'api' );
2480 $cff_error_reporter->remove_error( 'wp_remote_get' );
2481
2482 $feedData = apply_filters( 'cff_filter_api_data', $feedData );
2483
2484 return $feedData;
2485 } else {
2486 if ( strpos( $url, '&limit=' ) !== false ) {
2487 cff_log_fb_error( $feedData, $url );
2488 }
2489
2490 return $feedData;
2491 }
2492
2493 } else {
2494 if ( strpos( $url, '&limit=' ) !== false ) {
2495 cff_log_wp_error( $response, $url );
2496 }
2497
2498 return '{}';
2499 }
2500
2501 }
2502
2503 //Make links into span instead when the post text is made clickable
2504 function cff_wrap_span($text) {
2505 $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
2506 return preg_replace_callback($pattern, 'cff_wrap_span_callback', $text);
2507 }
2508 function cff_wrap_span_callback($matches) {
2509 $max_url_length = 100;
2510 $max_depth_if_over_length = 2;
2511 $ellipsis = '&hellip;';
2512 $target = 'target="_blank"';
2513 $url_full = $matches[0];
2514 $url_short = '';
2515 if (strlen($url_full) > $max_url_length) {
2516 $parts = parse_url($url_full);
2517 $url_short = $parts['scheme'] . '://' . preg_replace('/^www\./', '', $parts['host']) . '/';
2518 $path_components = explode('/', trim($parts['path'], '/'));
2519 foreach ($path_components as $dir) {
2520 $url_string_components[] = $dir . '/';
2521 }
2522 if (!empty($parts['query'])) {
2523 $url_string_components[] = '?' . $parts['query'];
2524 }
2525 if (!empty($parts['fragment'])) {
2526 $url_string_components[] = '#' . $parts['fragment'];
2527 }
2528 for ($k = 0; $k < count($url_string_components); $k++) {
2529 $curr_component = $url_string_components[$k];
2530 if ($k >= $max_depth_if_over_length || strlen($url_short) + strlen($curr_component) > $max_url_length) {
2531 if ($k == 0 && strlen($url_short) < $max_url_length) {
2532 // Always show a portion of first directory
2533 $url_short .= substr($curr_component, 0, $max_url_length - strlen($url_short));
2534 }
2535 $url_short .= $ellipsis;
2536 break;
2537 }
2538 $url_short .= $curr_component;
2539 }
2540 } else {
2541 $url_short = $url_full;
2542 }
2543 return "<span class='cff-break-word'>$url_short</span>";
2544 }
2545
2546 //Use the timezone to offset the date as all post dates are in UTC +0000
2547 function cff_set_timezone($original, $cff_timezone){
2548 $cff_date_time = new DateTime(date('m/d g:i a'), new DateTimeZone('UTC'));
2549 $cff_date_time->setTimeZone(new DateTimeZone($cff_timezone));
2550 $cff_date_time_offset = $cff_date_time->getOffset();
2551
2552 $original = $original + $cff_date_time_offset;
2553
2554 return $original;
2555 }
2556 //Time stamp function - used for posts
2557 function cff_getdate($original, $date_format, $custom_date, $cff_date_translate_strings, $cff_timezone) {
2558
2559 //Offset the date by the timezone
2560 $new_time = cff_set_timezone($original, $cff_timezone);
2561
2562 switch ($date_format) {
2563
2564 case '2':
2565 $print = date_i18n('F jS, g:i a', $new_time);
2566 break;
2567 case '3':
2568 $print = date_i18n('F jS', $new_time);
2569 break;
2570 case '4':
2571 $print = date_i18n('D F jS', $new_time);
2572 break;
2573 case '5':
2574 $print = date_i18n('l F jS', $new_time);
2575 break;
2576 case '6':
2577 $print = date_i18n('D M jS, Y', $new_time);
2578 break;
2579 case '7':
2580 $print = date_i18n('l F jS, Y', $new_time);
2581 break;
2582 case '8':
2583 $print = date_i18n('l F jS, Y - g:i a', $new_time);
2584 break;
2585 case '9':
2586 $print = date_i18n("l M jS, 'y", $new_time);
2587 break;
2588 case '10':
2589 $print = date_i18n('m.d.y', $new_time);
2590 break;
2591 case '11':
2592 $print = date_i18n('m/d/y', $new_time);
2593 break;
2594 case '12':
2595 $print = date_i18n('d.m.y', $new_time);
2596 break;
2597 case '13':
2598 $print = date_i18n('d/m/y', $new_time);
2599 break;
2600 default:
2601
2602 $cff_second = $cff_date_translate_strings['cff_translate_second'];
2603 $cff_seconds = $cff_date_translate_strings['cff_translate_seconds'];
2604 $cff_minute = $cff_date_translate_strings['cff_translate_minute'];
2605 $cff_minutes = $cff_date_translate_strings['cff_translate_minutes'];
2606 $cff_hour = $cff_date_translate_strings['cff_translate_hour'];
2607 $cff_hours = $cff_date_translate_strings['cff_translate_hours'];
2608 $cff_day = $cff_date_translate_strings['cff_translate_day'];
2609 $cff_days = $cff_date_translate_strings['cff_translate_days'];
2610 $cff_week = $cff_date_translate_strings['cff_translate_week'];
2611 $cff_weeks = $cff_date_translate_strings['cff_translate_weeks'];
2612 $cff_month = $cff_date_translate_strings['cff_translate_month'];
2613 $cff_months = $cff_date_translate_strings['cff_translate_months'];
2614 $cff_year = $cff_date_translate_strings['cff_translate_years'];
2615 $cff_years = $cff_date_translate_strings['cff_translate_years'];
2616 $cff_ago = $cff_date_translate_strings['cff_translate_ago'];
2617
2618
2619 $periods = array($cff_second, $cff_minute, $cff_hour, $cff_day, $cff_week, $cff_month, $cff_year, "decade");
2620 $periods_plural = array($cff_seconds, $cff_minutes, $cff_hours, $cff_days, $cff_weeks, $cff_months, $cff_years, "decade");
2621
2622 $lengths = array("60","60","24","7","4.35","12","10");
2623 $now = time();
2624
2625 // is it future date or past date
2626 if($now > $original) {
2627 $difference = $now - $original;
2628 $tense = $cff_ago;
2629 } else {
2630 $difference = $original - $now;
2631 $tense = $cff_ago;
2632 }
2633 for($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
2634 $difference /= $lengths[$j];
2635 }
2636
2637 $difference = round($difference);
2638
2639 if($difference != 1) {
2640 $periods[$j] = $periods_plural[$j];
2641 }
2642 $print = "$difference $periods[$j] {$tense}";
2643
2644 break;
2645
2646 }
2647 if ( !empty($custom_date) ){
2648 $print = date_i18n($custom_date, $new_time);
2649 }
2650
2651 return $print;
2652 }
2653 function cff_eventdate($original, $date_format, $custom_date) {
2654 switch ($date_format) {
2655
2656 case '2':
2657 $print = date_i18n('F jS, g:ia', $original);
2658 break;
2659 case '3':
2660 $print = date_i18n('g:ia - F jS', $original);
2661 break;
2662 case '4':
2663 $print = date_i18n('g:ia, F jS', $original);
2664 break;
2665 case '5':
2666 $print = date_i18n('l F jS - g:ia', $original);
2667 break;
2668 case '6':
2669 $print = date_i18n('D M jS, Y, g:iA', $original);
2670 break;
2671 case '7':
2672 $print = date_i18n('l F jS, Y, g:iA', $original);
2673 break;
2674 case '8':
2675 $print = date_i18n('l F jS, Y - g:ia', $original);
2676 break;
2677 case '9':
2678 $print = date_i18n("l M jS, 'y", $original);
2679 break;
2680 case '10':
2681 $print = date_i18n('m.d.y - g:iA', $original);
2682 break;
2683 case '11':
2684 $print = date_i18n('m/d/y, g:ia', $original);
2685 break;
2686 case '12':
2687 $print = date_i18n('d.m.y - g:iA', $original);
2688 break;
2689 case '13':
2690 $print = date_i18n('d/m/y, g:ia', $original);
2691 break;
2692 default:
2693 $print = date_i18n('F j, Y, g:ia', $original);
2694 break;
2695 }
2696 if ( !empty($custom_date) ){
2697 $print = date_i18n($custom_date, $original);
2698 }
2699 return $print;
2700 }
2701 //Use custom stripos function if it's not available (only available in PHP 5+)
2702 if(!is_callable('stripos')){
2703 function stripos($haystack, $needle){
2704 return strpos($haystack, stristr( $haystack, $needle ));
2705 }
2706 }
2707 function cff_stripos_arr($haystack, $needle) {
2708 if(!is_array($needle)) $needle = array($needle);
2709 foreach($needle as $what) {
2710 if(($pos = stripos($haystack, ltrim($what) ))!==false) return $pos;
2711 }
2712 return false;
2713 }
2714 function cff_mb_substr_replace($string, $replacement, $start, $length=NULL) {
2715 if (is_array($string)) {
2716 $num = count($string);
2717 // $replacement
2718 $replacement = is_array($replacement) ? array_slice($replacement, 0, $num) : array_pad(array($replacement), $num, $replacement);
2719 // $start
2720 if (is_array($start)) {
2721 $start = array_slice($start, 0, $num);
2722 foreach ($start as $key => $value)
2723 $start[$key] = is_int($value) ? $value : 0;
2724 }
2725 else {
2726 $start = array_pad(array($start), $num, $start);
2727 }
2728 // $length
2729 if (!isset($length)) {
2730 $length = array_fill(0, $num, 0);
2731 }
2732 elseif (is_array($length)) {
2733 $length = array_slice($length, 0, $num);
2734 foreach ($length as $key => $value)
2735 $length[$key] = isset($value) ? (is_int($value) ? $value : $num) : 0;
2736 }
2737 else {
2738 $length = array_pad(array($length), $num, $length);
2739 }
2740 // Recursive call
2741 return array_map(__FUNCTION__, $string, $replacement, $start, $length);
2742 }
2743 preg_match_all('/./us', (string)$string, $smatches);
2744 preg_match_all('/./us', (string)$replacement, $rmatches);
2745 if ($length === NULL) $length = mb_strlen($string);
2746 array_splice($smatches[0], $start, $length, $rmatches[0]);
2747 return join($smatches[0]);
2748 }
2749
2750 //Push to assoc array
2751 function cff_array_push_assoc($array, $key, $value){
2752 $array[$key] = $value;
2753 return $array;
2754 }
2755 //Convert string to slug
2756 function cff_to_slug($string){
2757 return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $string)));
2758 }
2759
2760
2761 //Allows shortcodes in theme
2762 add_filter('widget_text', 'do_shortcode');
2763
2764 //Enqueue stylesheet
2765 add_action( 'wp_enqueue_scripts', 'cff_add_my_stylesheet' );
2766 function cff_add_my_stylesheet() {
2767
2768 //Minify files?
2769 $options = get_option('cff_style_settings');
2770 isset($options[ 'cff_minify' ]) ? $cff_minify = $options[ 'cff_minify' ] : $cff_minify = '';
2771 $cff_minify ? $cff_min = '.min' : $cff_min = '';
2772
2773 // Respects SSL, Style.css is relative to the current file
2774 wp_register_style( 'cff', plugins_url('css/cff-style'.$cff_min.'.css', __FILE__), array(), CFFVER );
2775 wp_enqueue_style( 'cff' );
2776
2777 $options = get_option('cff_style_settings');
2778
2779 if( !isset( $options[ 'cff_font_source' ] ) ){
2780 wp_enqueue_style( 'sb-font-awesome', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' );
2781 } else {
2782
2783 if( $options[ 'cff_font_source' ] == 'none' ){
2784 //Do nothing
2785 } else if( $options[ 'cff_font_source' ] == 'local' ){
2786 wp_enqueue_style( 'sb-font-awesome', plugins_url('css/font-awesome.min.css', __FILE__), array(), '4.7.0' );
2787 } else {
2788 wp_enqueue_style( 'sb-font-awesome', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' );
2789 }
2790
2791 }
2792
2793
2794 }
2795 //Enqueue scripts
2796 add_action( 'wp_enqueue_scripts', 'cff_scripts_method' );
2797 function cff_scripts_method() {
2798
2799 //Minify files?
2800 $options = get_option('cff_style_settings');
2801 isset($options[ 'cff_minify' ]) ? $cff_minify = $options[ 'cff_minify' ] : $cff_minify = '';
2802 $cff_minify ? $cff_min = '.min' : $cff_min = '';
2803
2804 //Register the script to make it available
2805 wp_register_script( 'cffscripts', plugins_url( '/js/cff-scripts'.$cff_min.'.js' , __FILE__ ), array('jquery'), CFFVER, true );
2806 //Enqueue it to load it onto the page
2807 wp_enqueue_script('cffscripts');
2808 }
2809
2810 function cff_activate() {
2811 $options = get_option('cff_style_settings');
2812
2813 //Show all post types
2814 $options[ 'cff_show_links_type' ] = true;
2815 $options[ 'cff_show_event_type' ] = true;
2816 $options[ 'cff_show_video_type' ] = true;
2817 $options[ 'cff_show_photos_type' ] = true;
2818 $options[ 'cff_show_status_type' ] = true;
2819 $options[ 'cff_show_albums_type' ] = true;
2820 $options[ 'cff_show_author' ] = true;
2821 $options[ 'cff_show_text' ] = true;
2822 $options[ 'cff_show_desc' ] = true;
2823 $options[ 'cff_show_shared_links' ] = true;
2824 $options[ 'cff_show_date' ] = true;
2825 $options[ 'cff_show_media' ] = true;
2826 $options[ 'cff_show_media_link' ] = true;
2827 $options[ 'cff_show_event_title' ] = true;
2828 $options[ 'cff_show_event_details' ] = true;
2829 $options[ 'cff_show_meta' ] = true;
2830 $options[ 'cff_show_link' ] = true;
2831 $options[ 'cff_show_like_box' ] = true;
2832 $options[ 'cff_show_facebook_link' ] = true;
2833 $options[ 'cff_show_facebook_share' ] = true;
2834 $options[ 'cff_event_title_link' ] = true;
2835
2836 update_option( 'cff_style_settings', $options );
2837
2838 get_option('cff_show_access_token');
2839 update_option( 'cff_show_access_token', true );
2840
2841 //Run cron twice daily when plugin is first activated for new users
2842 if ( ! wp_next_scheduled( 'cff_cron_job' ) ) {
2843 wp_schedule_event( time(), 'twicedaily', 'cff_cron_job' );
2844 }
2845 if ( ! wp_next_scheduled( 'cff_feed_issue_email' ) ) {
2846 cff_schedule_report_email();
2847 }
2848 // set usage tracking to false if fresh install.
2849 $usage_tracking = get_option( 'cff_usage_tracking', false );
2850
2851 if ( ! is_array( $usage_tracking ) ) {
2852 $usage_tracking = array(
2853 'enabled' => false,
2854 'last_send' => 0
2855 );
2856
2857 update_option( 'cff_usage_tracking', $usage_tracking, false );
2858 }
2859 }
2860 register_activation_hook( __FILE__, 'cff_activate' );
2861
2862 function cff_cron_custom_interval( $schedules ) {
2863 $schedules['cffweekly'] = array(
2864 'interval' => 3600 * 24 * 7,
2865 'display' => __( 'Weekly' )
2866 );
2867
2868 return $schedules;
2869 }
2870 add_filter( 'cron_schedules', 'cff_cron_custom_interval' );
2871
2872 function cff_deactivate() {
2873 wp_clear_scheduled_hook('cff_cron_job');
2874 }
2875 register_deactivation_hook(__FILE__, 'cff_deactivate');
2876
2877 //Uninstall
2878 function cff_uninstall()
2879 {
2880 if ( ! current_user_can( 'activate_plugins' ) )
2881 return;
2882
2883 //If the user is preserving the settings then don't delete them
2884 $cff_preserve_settings = get_option('cff_preserve_settings');
2885 if($cff_preserve_settings) return;
2886
2887 //Settings
2888 delete_option( 'cff_show_access_token' );
2889 delete_option( 'cff_access_token' );
2890 delete_option( 'cff_page_id' );
2891 delete_option( 'cff_num_show' );
2892 delete_option( 'cff_post_limit' );
2893 delete_option( 'cff_show_others' );
2894 delete_option( 'cff_cache_time' );
2895 delete_option( 'cff_cache_time_unit' );
2896 delete_option( 'cff_locale' );
2897 delete_option( 'cff_ajax' );
2898 delete_option( 'cff_preserve_settings' );
2899 //Style & Layout
2900 delete_option( 'cff_title_length' );
2901 delete_option( 'cff_body_length' );
2902 delete_option('cff_style_settings');
2903
2904 wp_clear_scheduled_hook( 'cff_feed_issue_email' );
2905
2906 delete_option( 'cff_usage_tracking_config' );
2907 delete_option( 'cff_usage_tracking' );
2908
2909 delete_option( 'cff_statuses' );
2910 delete_option( 'cff_rating_notice' );
2911 delete_option( 'cff_db_version' );
2912
2913 global $wp_roles;
2914 $wp_roles->remove_cap( 'administrator', 'manage_custom_facebook_feed_options' );
2915 wp_clear_scheduled_hook( 'cff_usage_tracking_cron' );
2916 }
2917 register_uninstall_hook( __FILE__, 'cff_uninstall' );
2918 add_action( 'wp_head', 'cff_custom_css' );
2919 function cff_custom_css() {
2920 $options = get_option('cff_style_settings');
2921 isset($options[ 'cff_custom_css' ]) ? $cff_custom_css = $options[ 'cff_custom_css' ] : $cff_custom_css = '';
2922
2923 if( !empty($cff_custom_css) ) echo "\r\n";
2924 if( !empty($cff_custom_css) ) echo '<!-- Custom Facebook Feed Custom CSS -->';
2925 if( !empty($cff_custom_css) ) echo "\r\n";
2926 if( !empty($cff_custom_css) ) echo '<style type="text/css">';
2927 if( !empty($cff_custom_css) ) echo "\r\n";
2928 if( !empty($cff_custom_css) ) echo stripslashes($cff_custom_css);
2929 if( !empty($cff_custom_css) ) echo "\r\n";
2930 if( !empty($cff_custom_css) ) echo '</style>';
2931 if( !empty($cff_custom_css) ) echo "\r\n";
2932 }
2933 add_action( 'wp_footer', 'cff_js' );
2934 function cff_js() {
2935 $options = get_option('cff_style_settings');
2936 $cff_custom_js = isset($options[ 'cff_custom_js' ]) ? $options[ 'cff_custom_js' ] : '';
2937
2938 //Link hashtags?
2939 isset($options[ 'cff_link_hashtags' ]) ? $cff_link_hashtags = $options[ 'cff_link_hashtags' ] : $cff_link_hashtags = 'true';
2940 ($cff_link_hashtags == 'true' || $cff_link_hashtags == 'on') ? $cff_link_hashtags = 'true' : $cff_link_hashtags = 'false';
2941
2942 //If linking the post text then don't link the hashtags
2943 isset($options[ 'cff_title_link' ]) ? $cff_title_link = $options[ 'cff_title_link' ] : $cff_title_link = false;
2944 ($cff_title_link == 'true' || $cff_title_link == 'on') ? $cff_title_link = true : $cff_title_link = false;
2945 if ($cff_title_link) $cff_link_hashtags = 'false';
2946
2947
2948 echo '<!-- Custom Facebook Feed JS -->';
2949 echo "\r\n";
2950 echo '<script type="text/javascript">';
2951 echo "\r\n";
2952 echo 'var cfflinkhashtags = "' . $cff_link_hashtags . '";';
2953 echo "\r\n";
2954 if( !empty($cff_custom_js) ) echo "jQuery( document ).ready(function($) {";
2955 if( !empty($cff_custom_js) ) echo "\r\n";
2956 if( !empty($cff_custom_js) ) echo stripslashes($cff_custom_js);
2957 if( !empty($cff_custom_js) ) echo "\r\n";
2958 if( !empty($cff_custom_js) ) echo "});";
2959 if( !empty($cff_custom_js) ) echo "\r\n";
2960 echo '</script>';
2961 echo "\r\n";
2962 }
2963
2964 add_action('init', 'cff_ppca_check_notice_dismiss');
2965 function cff_ppca_check_notice_dismiss() {
2966 global $current_user;
2967 $user_id = $current_user->ID;
2968 if ( isset($_GET['cff_ppca_check_notice_dismiss']) && '0' == $_GET['cff_ppca_check_notice_dismiss'] ) {
2969 add_user_meta($user_id, 'cff_ppca_check_notice_dismiss', 'true', true);
2970 }
2971 }
2972
2973 function cff_is_pro_version() {
2974 return defined( 'CFFWELCOME_VER' );
2975 }
2976
2977 function cff_get_set_cache($cff_posts_json_url, $transient_name, $cff_cache_time, $cache_seconds, $data_att_html, $cff_show_access_token, $access_token, $backup=false) {
2978
2979 if( $cff_show_access_token && strlen($access_token) > 130 ){
2980 //If using a Page Access Token then set caching time to be minimum of 1 minutes
2981 if( $cache_seconds < 60 || !isset($cache_seconds) ) $cache_seconds = 60;
2982 } else {
2983 //Set caching time to be minimum of 30 minutes
2984 if( $cache_seconds < 1800 || !isset($cache_seconds) ) $cache_seconds = 1800;
2985
2986 //Temporarily increase default caching time to be 3 hours
2987 if( $cache_seconds == 3600 ) $cache_seconds = 10800;
2988 }
2989
2990 //Don't use caching if the cache time is set to zero
2991 if ($cff_cache_time != 0){
2992
2993 // Get any existing copy of our transient data
2994 if ( false === ( $posts_json = get_transient( $transient_name ) ) || $posts_json === null ) {
2995
2996 //Get the contents of the Facebook page
2997 $posts_json = cff_fetchUrl($cff_posts_json_url);
2998
2999 //Check whether any data is returned from the API. If it isn't then don't cache the error response and instead keep checking the API on every page load until data is returned.
3000 $FBdata = json_decode($posts_json);
3001
3002 //Check whether the JSON is wrapped in a "data" property as if it doesn't then it's a featured post
3003 $prefix_data = '{"data":';
3004 (substr($posts_json, 0, strlen($prefix_data)) == $prefix_data) ? $cff_featured_post = false : $cff_featured_post = true;
3005
3006 //Add API URL to beginning of JSON array
3007 $prefix = '{';
3008 if (substr($posts_json, 0, strlen($prefix)) == $prefix) $posts_json = substr($posts_json, strlen($prefix));
3009
3010 //Encode and replace quotes so can be stored as a string
3011 $data_att_html = str_replace( '"', '&quot;', json_encode($data_att_html) );
3012 $posts_json = '{"api_url":"'.$cff_posts_json_url.'", "shortcode_options":"'.$data_att_html.'", ' . $posts_json;
3013
3014 //If it's a featured post then it doesn't contain 'data'
3015 ( $cff_featured_post ) ? $FBdata = $FBdata : $FBdata = $FBdata->data;
3016
3017 //Check the API response
3018 if( !empty($FBdata) ) {
3019
3020 //Error returned by API
3021 if( isset($FBdata->error) ){
3022
3023 //Cache the error JSON so doesn't keep making repeated requests
3024 //See if a backup cache exists
3025 if ( false !== get_transient( '!cff_backup_' . $transient_name ) ) {
3026
3027 $posts_json = get_transient( '!cff_backup_' . $transient_name );
3028
3029 //Add error message to backup cache so can be displayed at top of feed
3030 isset( $FBdata->error->message ) ? $error_message = $FBdata->error->message : $error_message = '';
3031 isset( $FBdata->error->type ) ? $error_type = $FBdata->error->type : $error_type = '';
3032 $prefix = '{';
3033 if (substr($posts_json, 0, strlen($prefix)) == $prefix) $posts_json = substr($posts_json, strlen($prefix));
3034 $posts_json = '{"cached_error": { "message": "'.$error_message.'", "type": "'.$error_type.'" }, ' . $posts_json;
3035 }
3036
3037 //Posts data returned by API
3038 } else {
3039
3040 //If a backup should be created for this data then create one
3041 if( $backup ){
3042 set_transient( '!cff_backup_' . $transient_name, $posts_json, YEAR_IN_SECONDS );
3043 }
3044 }
3045
3046 //Set regular cache
3047 set_transient( $transient_name, $posts_json, $cache_seconds );
3048
3049 }
3050
3051 } else {
3052
3053 $posts_json = get_transient( $transient_name );
3054
3055 if( strpos($posts_json, '"error":{"message":') !== false && false !== get_transient( '!cff_backup_' . $transient_name ) ){
3056 //Use backup cache if exists
3057 $posts_json = get_transient( '!cff_backup_' . $transient_name );
3058 }
3059
3060 //If we can't find the transient then fall back to just getting the json from the api
3061 if ($posts_json == false){
3062 $posts_json = cff_fetchUrl($cff_posts_json_url);
3063 }
3064 }
3065
3066 } else {
3067 $posts_json = cff_fetchUrl($cff_posts_json_url);
3068
3069 }
3070
3071 return $posts_json;
3072
3073 } //End cff_get_set_cache
3074
3075
3076
3077 //AUTOLINK
3078 $GLOBALS['autolink_options'] = array(
3079
3080 # Should http:// be visibly stripped from the front
3081 # of URLs?
3082 'strip_protocols' => true,
3083
3084 );
3085
3086 ####################################################################
3087
3088 function cff_autolink($text, $link_color='', $span_tag = false, $limit=100, $tagfill='class="cff-break-word"', $auto_title = true){
3089
3090 $text = cff_autolink_do($text, $link_color, '![a-z][a-z-]+://!i', $limit, $tagfill, $auto_title, $span_tag);
3091 $text = cff_autolink_do($text, $link_color, '!(mailto|skype):!i', $limit, $tagfill, $auto_title, $span_tag);
3092 $text = cff_autolink_do($text, $link_color, '!www\\.!i', $limit, $tagfill, $auto_title, 'http://', $span_tag);
3093 return $text;
3094 }
3095
3096 ####################################################################
3097
3098 function cff_autolink_do($text, $link_color, $sub, $limit, $tagfill, $auto_title, $span_tag, $force_prefix=null){
3099
3100 $text_l = StrToLower($text);
3101 $cursor = 0;
3102 $loop = 1;
3103 $buffer = '';
3104
3105 while (($cursor < strlen($text)) && $loop){
3106
3107 $ok = 1;
3108 $matched = preg_match($sub, $text_l, $m, PREG_OFFSET_CAPTURE, $cursor);
3109
3110 if (!$matched){
3111
3112 $loop = 0;
3113 $ok = 0;
3114
3115 }else{
3116
3117 $pos = $m[0][1];
3118 $sub_len = strlen($m[0][0]);
3119
3120 $pre_hit = substr($text, $cursor, $pos-$cursor);
3121 $hit = substr($text, $pos, $sub_len);
3122 $pre = substr($text, 0, $pos);
3123 $post = substr($text, $pos + $sub_len);
3124
3125 $fail_text = $pre_hit.$hit;
3126 $fail_len = strlen($fail_text);
3127
3128 #
3129 # substring found - first check to see if we're inside a link tag already...
3130 #
3131
3132 $bits = preg_split("!</a>!i", $pre);
3133 $last_bit = array_pop($bits);
3134 if (preg_match("!<a\s!i", $last_bit)){
3135
3136 #echo "fail 1 at $cursor<br />\n";
3137
3138 $ok = 0;
3139 $cursor += $fail_len;
3140 $buffer .= $fail_text;
3141 }
3142 }
3143
3144 #
3145 # looks like a nice spot to autolink from - check the pre
3146 # to see if there was whitespace before this match
3147 #
3148
3149 if ($ok){
3150
3151 if ($pre){
3152 if (!preg_match('![\s\(\[\{>]$!s', $pre)){
3153
3154 #echo "fail 2 at $cursor ($pre)<br />\n";
3155
3156 $ok = 0;
3157 $cursor += $fail_len;
3158 $buffer .= $fail_text;
3159 }
3160 }
3161 }
3162
3163 #
3164 # we want to autolink here - find the extent of the url
3165 #
3166
3167 if ($ok){
3168 if (preg_match('/^([a-z0-9\-\.\/\-_%~!?=,:;&+*#@\(\)\$]+)/i', $post, $matches)){
3169
3170 $url = $hit.$matches[1];
3171
3172 $cursor += strlen($url) + strlen($pre_hit);
3173 $buffer .= $pre_hit;
3174
3175 $url = html_entity_decode($url);
3176
3177
3178 #
3179 # remove trailing punctuation from url
3180 #
3181
3182 while (preg_match('|[.,!;:?]$|', $url)){
3183 $url = substr($url, 0, strlen($url)-1);
3184 $cursor--;
3185 }
3186 foreach (array('()', '[]', '{}') as $pair){
3187 $o = substr($pair, 0, 1);
3188 $c = substr($pair, 1, 1);
3189 if (preg_match("!^(\\$c|^)[^\\$o]+\\$c$!", $url)){
3190 $url = substr($url, 0, strlen($url)-1);
3191 $cursor--;
3192 }
3193 }
3194
3195
3196 #
3197 # nice-i-fy url here
3198 #
3199
3200 $link_url = $url;
3201 $display_url = $url;
3202
3203 if ($force_prefix) $link_url = $force_prefix.$link_url;
3204
3205 if ($GLOBALS['autolink_options']['strip_protocols']){
3206 if (preg_match('!^(http|https)://!i', $display_url, $m)){
3207
3208 $display_url = substr($display_url, strlen($m[1])+3);
3209 }
3210 }
3211
3212 $display_url = cff_autolink_label($display_url, $limit);
3213
3214
3215 #
3216 # add the url
3217 #
3218
3219 if ($display_url != $link_url && !preg_match('@title=@msi',$tagfill) && $auto_title) {
3220
3221 $display_quoted = preg_quote($display_url, '!');
3222
3223 if (!preg_match("!^(http|https)://{$display_quoted}$!i", $link_url)){
3224
3225 $tagfill .= ' title="'.$link_url.'"';
3226 }
3227 }
3228
3229 $link_url_enc = HtmlSpecialChars($link_url);
3230 $display_url_enc = HtmlSpecialChars($display_url);
3231
3232
3233 if( substr( $link_url_enc, 0, 4 ) !== "http" ) $link_url_enc = 'http://' . $link_url_enc;
3234 $buffer .= "<a href=\"{$link_url_enc}\" rel='nofollow noopener noreferrer'>{$display_url_enc}</a>";
3235
3236
3237 }else{
3238 #echo "fail 3 at $cursor<br />\n";
3239
3240 $ok = 0;
3241 $cursor += $fail_len;
3242 $buffer .= $fail_text;
3243 }
3244 }
3245
3246 }
3247
3248 #
3249 # add everything from the cursor to the end onto the buffer.
3250 #
3251
3252 $buffer .= substr($text, $cursor);
3253
3254 return $buffer;
3255 }
3256
3257 ####################################################################
3258
3259 function cff_autolink_label($text, $limit){
3260
3261 if (!$limit){ return $text; }
3262
3263 if (strlen($text) > $limit){
3264 return substr($text, 0, $limit-3).'...';
3265 }
3266
3267 return $text;
3268 }
3269
3270 ####################################################################
3271
3272 function cff_autolink_email($text, $tagfill=''){
3273
3274 $atom = '[^()<>@,;:\\\\".\\[\\]\\x00-\\x20\\x7f]+'; # from RFC822
3275
3276 #die($atom);
3277
3278 $text_l = StrToLower($text);
3279 $cursor = 0;
3280 $loop = 1;
3281 $buffer = '';
3282
3283 while(($cursor < strlen($text)) && $loop){
3284
3285 #
3286 # find an '@' symbol
3287 #
3288
3289 $ok = 1;
3290 $pos = strpos($text_l, '@', $cursor);
3291
3292 if ($pos === false){
3293
3294 $loop = 0;
3295 $ok = 0;
3296
3297 }else{
3298
3299 $pre = substr($text, $cursor, $pos-$cursor);
3300 $hit = substr($text, $pos, 1);
3301 $post = substr($text, $pos + 1);
3302
3303 $fail_text = $pre.$hit;
3304 $fail_len = strlen($fail_text);
3305
3306 #die("$pre::$hit::$post::$fail_text");
3307
3308 #
3309 # substring found - first check to see if we're inside a link tag already...
3310 #
3311
3312 $bits = preg_split("!</a>!i", $pre);
3313 $last_bit = array_pop($bits);
3314 if (preg_match("!<a\s!i", $last_bit)){
3315
3316 #echo "fail 1 at $cursor<br />\n";
3317
3318 $ok = 0;
3319 $cursor += $fail_len;
3320 $buffer .= $fail_text;
3321 }
3322 }
3323
3324 #
3325 # check backwards
3326 #
3327
3328 if ($ok){
3329 if (preg_match("!($atom(\.$atom)*)\$!", $pre, $matches)){
3330
3331 # move matched part of address into $hit
3332
3333 $len = strlen($matches[1]);
3334 $plen = strlen($pre);
3335
3336 $hit = substr($pre, $plen-$len).$hit;
3337 $pre = substr($pre, 0, $plen-$len);
3338
3339 }else{
3340
3341 #echo "fail 2 at $cursor ($pre)<br />\n";
3342
3343 $ok = 0;
3344 $cursor += $fail_len;
3345 $buffer .= $fail_text;
3346 }
3347 }
3348
3349 #
3350 # check forwards
3351 #
3352
3353 if ($ok){
3354 if (preg_match("!^($atom(\.$atom)*)!", $post, $matches)){
3355
3356 # move matched part of address into $hit
3357
3358 $len = strlen($matches[1]);
3359
3360 $hit .= substr($post, 0, $len);
3361 $post = substr($post, $len);
3362
3363 }else{
3364 #echo "fail 3 at $cursor ($post)<br />\n";
3365
3366 $ok = 0;
3367 $cursor += $fail_len;
3368 $buffer .= $fail_text;
3369 }
3370 }
3371
3372 #
3373 # commit
3374 #
3375
3376 if ($ok) {
3377
3378 $cursor += strlen($pre) + strlen($hit);
3379 $buffer .= $pre;
3380 $buffer .= "<a href=\"mailto:$hit\"$tagfill>$hit</a>";
3381
3382 }
3383
3384 }
3385
3386 #
3387 # add everything from the cursor to the end onto the buffer.
3388 #
3389
3390 $buffer .= substr($text, $cursor);
3391
3392 return $buffer;
3393 }
3394
3395 ###################################################################