Custom Facebook Feed - Version 2.19

Version Description

  • New: Improved the error reporting system to make resolving issues easier.
  • New: The locations of the Facebook feeds on your site will now be logged and listed on a single page for easier management. After this feature has been active for awhile, a "Feed Finder" link will appear under your connected accounts on the plugin Settings page which allows you to see a list of all feeds on your site along with their locations.
  • Tweak: When clearing the plugin cache, the cache in the Litespeed plugin will now also be cleared if being used on the site.
  • Fix: Fixed an issue with anonymous avatars not displaying correctly in group feeds.
  • Fix: Added a fix for apostrophes in connected accounts.
Download this release

Release Info

Developer smashballoon
Plugin Icon 128x128 Custom Facebook Feed
Version 2.19
Comparing to
See all releases

Code changes from version 2.18.3 to 2.19

README.txt CHANGED
@@ -4,7 +4,7 @@ Tags: Facebook, Facebook feed, Facebook posts, Facebook group, Facebook page
4
  Requires at least: 3.0
5
  Requires PHP: 5.6
6
  Tested up to: 5.6
7
- Stable tag: 2.18.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -262,6 +262,13 @@ The most common reason for this is that an add-on or extension you have installe
262
  9. It's super easy to display your Facebook feed in any page or post
263
 
264
  == Changelog ==
 
 
 
 
 
 
 
265
  = 2.18.3 =
266
  * Tweak: Updated deprecated jQuery functions to prevent potential issues with newer versions.
267
  * Tweak: Due to an API bug which Facebook hasn't resolved yet that affects buy/sell posts in groups, we have added a 'salesposts' shortcode option which will work around the issue until they fix it. If you are displaying posts from a group and receiving an "API Error 100" notice then adding `salesposts=true` to your shortcode and clearing the plugin cache should resolve the issue.
4
  Requires at least: 3.0
5
  Requires PHP: 5.6
6
  Tested up to: 5.6
7
+ Stable tag: 2.19
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
262
  9. It's super easy to display your Facebook feed in any page or post
263
 
264
  == Changelog ==
265
+ = 2.19 =
266
+ * New: Improved the error reporting system to make resolving issues easier.
267
+ * New: The locations of the Facebook feeds on your site will now be logged and listed on a single page for easier management. After this feature has been active for awhile, a "Feed Finder" link will appear under your connected accounts on the plugin Settings page which allows you to see a list of all feeds on your site along with their locations.
268
+ * Tweak: When clearing the plugin cache, the cache in the Litespeed plugin will now also be cleared if being used on the site.
269
+ * Fix: Fixed an issue with anonymous avatars not displaying correctly in group feeds.
270
+ * Fix: Added a fix for apostrophes in connected accounts.
271
+
272
  = 2.18.3 =
273
  * Tweak: Updated deprecated jQuery functions to prevent potential issues with newer versions.
274
  * Tweak: Due to an API bug which Facebook hasn't resolved yet that affects buy/sell posts in groups, we have added a 'salesposts' shortcode option which will work around the issue until they fix it. If you are displaying posts from a group and receiving an "API Error 100" notice then adding `salesposts=true` to your shortcode and clearing the plugin cache should resolve the issue.
admin/admin-functions.php CHANGED
@@ -2,6 +2,7 @@
2
  use CustomFacebookFeed\CFF_Utils;
3
  use CustomFacebookFeed\CFF_Oembed;
4
  use CustomFacebookFeed\CFF_GDPR_Integrations;
 
5
 
6
  //Create Style page
7
  function cff_style_page() {
@@ -331,7 +332,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
331
  $cff_hide_comments = $options[ 'cff_hide_comments' ];
332
  //Misc
333
  $cff_feed_width = $options[ 'cff_feed_width' ];
334
- $cff_feed_width_resp = $options[ 'cff_feed_width_resp' ];
335
  $cff_feed_height = $options[ 'cff_feed_height' ];
336
  $cff_feed_padding = $options[ 'cff_feed_padding' ];
337
  $cff_like_box_position = $options[ 'cff_like_box_position' ];
@@ -393,7 +394,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
393
  $cff_author_size = $options[ 'cff_author_size' ];
394
  $cff_author_color = $options[ 'cff_author_color' ];
395
 
396
- $gdpr = $options[ 'gdpr' ];
397
  //New
398
  $cff_custom_css = $options[ 'cff_custom_css' ];
399
  $cff_custom_js = $options[ 'cff_custom_js' ];
@@ -404,7 +405,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
404
  $cff_video_action = $options[ 'cff_video_action' ];
405
  $cff_sep_color = $options[ 'cff_sep_color' ];
406
  $cff_sep_size = $options[ 'cff_sep_size' ];
407
-
408
  // Texts lengths
409
  $cff_title_length = 'cff_title_length';
410
  $cff_body_length = 'cff_body_length';
@@ -771,7 +772,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
771
  //Custom CSS
772
  if (isset($_POST[ 'cff_custom_css' ])) $cff_custom_css = $_POST[ 'cff_custom_css' ];
773
  if (isset($_POST[ 'cff_custom_js' ])) $cff_custom_js = $_POST[ 'cff_custom_js' ];
774
-
775
  if (isset($_POST[ 'cff_video_height' ])) $cff_video_height = sanitize_text_field( $_POST[ 'cff_video_height' ] );
776
  if (isset($_POST[ 'cff_video_action' ])) $cff_video_action = sanitize_text_field( $_POST[ 'cff_video_action' ] );
777
  if (isset($_POST[ 'cff_open_links' ])) $cff_open_links = sanitize_text_field( $_POST[ 'cff_open_links' ] );
@@ -903,7 +904,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
903
  $options[ 'cff_translate_learn_more_text' ] = $cff_translate_learn_more_text;
904
  $options[ 'cff_translate_shop_now_text' ] = $cff_translate_shop_now_text;
905
  $options[ 'cff_translate_message_page_text' ] = $cff_translate_message_page_text;
906
-
907
  //Date translate
908
  $options[ 'cff_translate_second' ] = $cff_translate_second;
909
  $options[ 'cff_translate_seconds' ] = $cff_translate_seconds;
@@ -924,10 +925,10 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
924
  }
925
  //Update the array
926
  update_option( 'cff_style_settings', $options );
927
- // Put an settings updated message on the screen
928
  ?>
929
  <div class="updated"><p><strong><?php _e('Settings saved.', 'custom-facebook-feed' ); ?></strong></p></div>
930
- <?php } ?>
931
 
932
  <?php } //End nonce check ?>
933
 
@@ -942,7 +943,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
942
  </button>
943
  </div>
944
  <?php endif; ?>
945
-
946
  <div id="cff-admin" class="wrap">
947
  <div id="header">
948
  <h1><?php _e('Custom Facebook Feed', 'custom-facebook-feed'); ?></h1>
@@ -1050,7 +1051,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1050
  <option value="5" <?php if( $cff_cols == 5 ) { echo 'selected'; } ?>>5</option>
1051
  <option value="6" <?php if( $cff_cols == 6 ) { echo 'selected'; } ?>>6</option>
1052
  </select>
1053
-
1054
  <br />
1055
  <div class="cff-mobile-col-settings" <?php if( intval($cff_cols) > 1 ) echo 'style="display:block;"' ?>>
1056
  <div class="cff-row">
@@ -1070,7 +1071,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1070
  </table>
1071
 
1072
  <?php submit_button(); ?>
1073
-
1074
  <hr id="types" />
1075
  <table class="form-table">
1076
  <tbody>
@@ -1353,7 +1354,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1353
  <p class="cff-tooltip cff-more-info"><?php _e("This positions the Like Box widget outside of the feed container. It is useful if your feed has a vertical scrollbar as it places it outside of the scrollable area and fixes it at the top or bottom."); ?></p>
1354
  </td>
1355
  </tr>
1356
-
1357
  <tr valign="top">
1358
  <th class="bump-left" scope="row"><label><?php _e('Show faces of fans', 'custom-facebook-feed'); ?></label><code class="cff_shortcode"> likeboxfaces
1359
  Eg: likeboxfaces=true</code></th>
@@ -1532,7 +1533,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1532
  <p>Find out how to display <a href="https://smashballoon.com/using-shortcode-options-customize-facebook-feeds/" target="_blank"><b>multiple feeds</b></a>.</p>
1533
  </div>
1534
 
1535
-
1536
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png?2019' ?>" /></a>
1537
 
1538
  <?php } //End General tab ?>
@@ -1558,17 +1559,17 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1558
  <div class="cff-layout cff-thumb <?php if($cff_preset_layout == "thumb") echo "cff-layout-selected"; ?>">
1559
  <h3><input type="radio" name="cff_preset_layout" id="cff_preset_layout" value="thumb" disabled />&nbsp;<?php _e('Thumbnail'); ?></h3>
1560
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/layout-thumb.png' ?>" alt="Thumbnail Layout" />
1561
-
1562
  </div>
1563
  <div class="cff-layout cff-half <?php if($cff_preset_layout == "half") echo "cff-layout-selected"; ?>">
1564
  <h3><input type="radio" name="cff_preset_layout" id="cff_preset_layout" value="half" disabled />&nbsp;<?php _e('Half-width'); ?></h3>
1565
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/layout-half.png' ?>" alt="Half Width Layout" />
1566
-
1567
  </div>
1568
  <div class="cff-layout cff-full <?php if($cff_preset_layout == "full") echo "cff-layout-selected"; ?>">
1569
  <h3><input type="radio" name="cff_preset_layout" id="cff_preset_layout" value="full" disabled />&nbsp;<?php _e('Full-width'); ?></h3>
1570
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/layout-full.png' ?>" alt="Full Width Layout" />
1571
-
1572
  </div>
1573
  </div>
1574
 
@@ -1711,7 +1712,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1711
  <tr id="poststyle"><!-- Quick link --></tr>
1712
  </tbody>
1713
  </table>
1714
-
1715
  <?php submit_button(); ?>
1716
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png' ?>" /></a>
1717
  <?php } //End Post Layout tab ?>
@@ -1734,7 +1735,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1734
 
1735
  <input type="hidden" name="<?php echo $style_typography_hidden_field_name; ?>" value="Y">
1736
  <br />
1737
-
1738
  <h3><?php _e('Post Item'); ?></h3>
1739
  <table class="form-table">
1740
  <tbody>
@@ -1764,7 +1765,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1764
  </div>
1765
 
1766
  <div class="cff-post-style-settings cff-regular">
1767
-
1768
  <div class="cff-row">
1769
  <label><?php _e('Separating Line Color'); ?></label><code class="cff_shortcode"> sepcolor
1770
  Eg: sepcolor=CFCFCF</code>
@@ -1998,7 +1999,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
1998
  <tr>
1999
  <th class="bump-left"><label for="cff_body_color" class="bump-left"><?php _e('Text Color'); ?></label><code class="cff_shortcode"> desccolor
2000
  Eg: desccolor=9F9F9F</code></th>
2001
-
2002
  <td>
2003
  <input name="cff_body_color" value="#<?php esc_attr_e( str_replace('#', '', $cff_body_color) ); ?>" class="cff-colorpicker" />
2004
  </td>
@@ -2069,7 +2070,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2069
  <input name="cff_date_color" value="#<?php esc_attr_e( str_replace('#', '', $cff_date_color) ); ?>" class="cff-colorpicker" />
2070
  </td>
2071
  </tr>
2072
-
2073
  <tr>
2074
  <th class="bump-left"><label for="cff_date_formatting" class="bump-left"><?php _e('Date Formatting'); ?></label><code class="cff_shortcode"> dateformat
2075
  Eg: dateformat=3</code></th>
@@ -2411,7 +2412,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2411
  </select>
2412
  </td>
2413
  </tr>
2414
-
2415
  <tr>
2416
  <th class="bump-left"><label for="cff_event_title_size" class="bump-left"><?php _e('Text Size'); ?></label><code class="cff_shortcode"> eventtitlesize
2417
  Eg: eventtitlesize=12</code></th>
@@ -2464,7 +2465,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2464
  </tbody>
2465
  </table>
2466
  <hr />
2467
-
2468
  <h3><?php _e('Event Date'); ?></h3>
2469
  <table class="form-table">
2470
  <tbody>
@@ -2623,7 +2624,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2623
  </table>
2624
 
2625
  <?php submit_button(); ?>
2626
-
2627
  <hr />
2628
 
2629
  <h3><?php _e('Post Action Links'); ?></span> <a class="cff-tooltip-link" href="JavaScript:void(0);"><?php _e('What is this?'); ?></a>
@@ -2792,7 +2793,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2792
  </div>
2793
 
2794
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png' ?>" /></a>
2795
-
2796
  <?php } //End Typography tab ?>
2797
  <?php if( $cff_active_tab == 'misc' ) { //Start Misc tab ?>
2798
 
@@ -2826,7 +2827,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2826
  <tr valign="top">
2827
  <td style="padding-top: 0;">
2828
  <p style="padding-bottom: 10px;"><?php _e('Enter your own custom JavaScript/jQuery in the box below', 'custom-facebook-feed'); ?> <i style="margin-left: 5px; font-size: 11px;"><a href="https://smashballoon.com/snippets/" target="_blank"><?php _e('See some examples', 'custom-facebook-feed'); ?></a></i></p>
2829
- <textarea name="cff_custom_js" id="cff_custom_js" style="width: 70%;" rows="7"><?php echo esc_textarea( stripslashes($cff_custom_js), 'custom-facebook-feed' ); ?></textarea>
2830
  </td>
2831
  </tr>
2832
  </tbody>
@@ -2948,7 +2949,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
2948
  </tr>
2949
 
2950
  </tbody>
2951
- </table>
2952
 
2953
  <hr />
2954
  <h3><?php _e('Media'); ?></h3>
@@ -3205,7 +3206,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
3205
  <p class="cff-tooltip"><?php _e("Understanding how you are using the plugin allows us to further improve it. The plugin will send a report in the background once per week which includes information about your plugin settings and statistics about your site, which we can use to help improve the features which matter most to you and improve your experience using the plugin. The plugin will never collect any sensitive information like access tokens, email addresses, or user information, and sending this data won't slow down your site at all. For more information,", 'custom-facebook-feed'); ?> <a href="https://smashballoon.com/custom-facebook-feed/docs/usage-tracking/" target="_blank"><?php _e("see here", 'custom-facebook-feed'); ?></a>.</p>
3206
  </td>
3207
  </tr>
3208
-
3209
  </tbody>
3210
  </table>
3211
 
@@ -3298,7 +3299,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
3298
  <td><input name="cff_translate_message_page_text" type="text" value="<?php echo stripslashes( esc_attr( $cff_translate_message_page_text ) ); ?>" /></td>
3299
  <td class="cff-context"><?php _e("Used for the 'Message Page' button", 'custom-facebook-feed'); ?></td>
3300
  </tr>
3301
-
3302
  <tr class="cff-table-header"><th colspan="3"><?php _e('Date', 'custom-facebook-feed'); ?></th></tr>
3303
  <tr>
3304
  <td><label for="cff_photos_text" class="bump-left"><?php _e('"Posted _ hours ago" text', 'custom-facebook-feed'); ?></label></td>
@@ -3354,7 +3355,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
3354
 
3355
  </tbody>
3356
  </table>
3357
-
3358
  <?php submit_button(); ?>
3359
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png' ?>" /></a>
3360
  <?php } //End Custom Text tab ?>
@@ -3367,7 +3368,7 @@ use CustomFacebookFeed\CFF_GDPR_Integrations;
3367
  <button id="cff-admin-show-share-links" class="button secondary" style="margin-bottom: 1px;"><i class="fa fa-share-alt" aria-hidden="true"></i>&nbsp;&nbsp;Share the plugin</button> <div id="cff-admin-share-links"></div>
3368
  </div>
3369
 
3370
- <?php
3371
  } //End Style_Page
3372
 
3373
 
@@ -3449,16 +3450,17 @@ function cff_settings_page() {
3449
  $options[ 'cff_timezone' ] = $cff_timezone;
3450
  $options[ 'cff_num_mobile' ] = $cff_num_mobile;
3451
  update_option( 'cff_style_settings', $options );
3452
-
3453
  //Delete ALL transients
3454
  cff_delete_cache();
3455
- // Put an settings updated message on the screen
 
3456
  ?>
3457
  <div class="updated"><p><strong><?php _e('Settings saved.', 'custom-facebook-feed' ); ?></strong></p></div>
3458
- <?php } ?>
 
 
3459
 
3460
- <?php } //End nonce check ?>
3461
-
3462
  <div id="cff-admin" class="wrap">
3463
 
3464
  <?php
@@ -3539,15 +3541,16 @@ function cff_settings_page() {
3539
  </div>
3540
 
3541
  <a href="JavaScript:void(0);" class="cff_admin_btn" id="cff_fb_login"><i class="fa fa-facebook-square"></i> <?php _e( 'Connect a Facebook account', 'custom-facebook-feed' ); ?></a>
3542
-
3543
 
3544
  <?php
3545
  if( isset($_GET['access_token']) && isset($_GET['final_response']) ){
3546
 
3547
  if( $_GET['final_response'] == 'true' ){
3548
-
3549
 
3550
- \cff_main()->cff_error_reporter->remove_error( 'accesstoken' );
 
 
3551
 
3552
  $access_token = $_GET['access_token'];
3553
  $cff_is_groups = false;
@@ -3629,9 +3632,9 @@ function cff_settings_page() {
3629
  echo "<p>Facebook has not returned any groups for your user. It is only possible to display a feed from a group which you are either an admin or a member. Please note, if you are not an admin of the group then it is required that an admin add our app in the group settings in order to display a feed.</p><p>Please either create or join a Facebook group and then follow the directions when connecting your account on this page.</p>";
3630
  echo '<a href="JavaScript:void(0);" class="button button-primary" id="cff-close-modal-primary-button">Close</a>';
3631
  } else {
3632
-
3633
 
3634
- \cff_main()->cff_error_reporter->remove_error( 'accesstoken' );
 
3635
  echo '<div class="cff-groups-list">';
3636
  echo '<p style="margin-top: 0;"><i class="fa fa-check-circle" aria-hidden="true" style="font-size: 15px; margin: 0 8px 0 2px;"></i>Select a Facebook group below to get an Access Token.</p>';
3637
 
@@ -3690,10 +3693,10 @@ function cff_settings_page() {
3690
 
3691
  } else {
3692
  //PAGES
3693
-
3694
 
3695
- \cff_main()->cff_error_reporter->remove_error( 'accesstoken' );
3696
-
 
3697
  echo '<p class="cff-tokens-note"><i class="fa fa-check-circle" aria-hidden="true" style="font-size: 15px; margin: 0 8px 0 2px;"></i> Select a Facebook page below to connect it.</p>';
3698
 
3699
  echo '<div class="cff-pages-wrap">';
@@ -3853,7 +3856,12 @@ function cff_settings_page() {
3853
  <h3 class="cff_connected_actions">Connected Accounts:</h3>
3854
  <div id="cff_connected_accounts_wrap"><?php //Add connected accounts here ?></div>
3855
 
3856
- <div class="cff_connected_actions">
 
 
 
 
 
3857
  <a href="JavaScript:void(0);" id="cff_export_accounts">Show raw account data</a>
3858
  <div id="cff_export_accounts_wrap">
3859
  <textarea name="cff_connected_accounts" id="cff_connected_accounts" style="width: 100%;" rows="5" /><?php echo stripslashes( esc_attr( $cff_connected_accounts_val ) ); ?></textarea>
@@ -4139,10 +4147,10 @@ function cff_settings_page() {
4139
  </select>
4140
  </td>
4141
  </tr>
4142
-
4143
  </tbody>
4144
  </table>
4145
-
4146
  <div class="cff-save-settings-btn">
4147
  <?php submit_button('Save Settings & Clear Cache'); ?>
4148
 
@@ -4171,6 +4179,10 @@ function cff_settings_page() {
4171
 
4172
  <?php } //End config tab ?>
4173
 
 
 
 
 
4174
 
4175
  <?php if( $cff_active_tab == 'support' ) { //Start Support tab ?>
4176
 
@@ -4460,7 +4472,7 @@ echo '-----------------------------'."\n";
4460
  } ?>
4461
 
4462
  ## FACEBOOK API RESPONSE: ##
4463
- <?php
4464
  $api_response_json = json_decode($posts_json);
4465
  if( isset( $api_response_json->error ) ) echo $posts_json;
4466
  if( isset( $api_response_json->data ) ){
@@ -4490,20 +4502,66 @@ foreach ( $cron as $key => $data ) {
4490
  }
4491
  ?>
4492
 
4493
- ## Error Log: ##
4494
  <?php
4495
 
4496
  $errors = \cff_main()->cff_error_reporter->get_errors();
4497
- if ( ! empty( $errors ) ) :
4498
- foreach ( $errors as $error ) :
4499
- echo $error['admin_message']."\n";
4500
- echo 'Feed with error: ' . esc_url( get_the_permalink( $error['post_id'] ) )."\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
4501
 
4502
- endforeach;
 
 
 
 
 
 
4503
  endif;
 
 
 
 
 
4504
 
 
 
 
 
 
4505
  ?>
4506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4507
  ## oEmbed: ##
4508
  <?php
4509
  $oembed_token_settings = get_option( 'cff_oembed_token', array() );
@@ -4783,9 +4841,9 @@ if( $cff_active_tab == 'more' ) { //Start More Social Feeds tab
4783
  } //End More tab
4784
 
4785
 
4786
-
4787
 
4788
- } //End Settings_Page
 
4789
 
4790
 
4791
 
@@ -4869,11 +4927,11 @@ function cff_oembeds_page() {
4869
  <?php if ( ! $saved_access_token_data && ! $valid_new_access_token && ! CFF_Oembed::can_do_oembed() ) {
4870
  if ( $access_token_error ) { ?>
4871
  <p><?php _e("There was a problem with the access token that was retrieved.", "custom-facebook-feed"); ?></p>
4872
- <?php }
4873
  $token_href = 'https://api.smashballoon.com/facebook-login.php?state=' . $admin_url_state;
4874
  if ( class_exists( 'SB_Instagram_Oembed' ) ) {
4875
  $sbi_oembed_token = SB_Instagram_Oembed::last_access_token();
4876
-
4877
  if ( ! empty( $sbi_oembed_token ) ) {
4878
  $token_href = add_query_arg( 'transfer', '1', $admin_url_state );
4879
  }
@@ -5060,11 +5118,8 @@ function cff_lite_dismiss() {
5060
  add_action( 'wp_ajax_cff_lite_dismiss', 'cff_lite_dismiss' );
5061
 
5062
  function cff_reset_log() {
5063
-
5064
-
5065
- \cff_main()->cff_error_reporter->remove_all_errors();
5066
  cff_delete_cache();
5067
-
5068
  die();
5069
  }
5070
  add_action( 'wp_ajax_cff_reset_log', 'cff_reset_log' );
@@ -5119,7 +5174,7 @@ function cff_ppca_notice() {
5119
  <b>Action required: PPCA Error.</b> <span style='margin-right: 10px;'>Due to Facebook API changes it is no longer possible to display feeds from Facebook Pages you are not an admin of. Please <a href='https://smashballoon.com/facebook-ppca-error-notice/' target='_blank'>see here</a> for more information.</span><a href='admin.php?page=cff-top' class='cff-admin-notice-button'>Go to Facebook Feed Settings</a></p>
5120
  </div>
5121
  ");
5122
- }
5123
  }
5124
 
5125
  }
@@ -5137,12 +5192,12 @@ function cff_nag_ppca_ignore() {
5137
  // Add a Settings link to the plugin on the Plugins page
5138
  $cff_plugin_file = 'custom-facebook-feed/custom-facebook-feed.php';
5139
  add_filter( "plugin_action_links_{$cff_plugin_file}", 'cff_add_settings_link', 10, 2 );
5140
-
5141
  //modify the link by unshifting the array
5142
  function cff_add_settings_link( $links, $file ) {
5143
  $cff_settings_link = '<a href="' . admin_url( 'admin.php?page=cff-top' ) . '">' . __( 'Settings', 'cff-top', 'custom-facebook-feed' ) . '</a>';
5144
  array_unshift( $links, $cff_settings_link );
5145
-
5146
  return $links;
5147
  }
5148
 
@@ -5179,6 +5234,14 @@ function cff_delete_cache(){
5179
  if (function_exists('w3tc_flush_all')) {
5180
  w3tc_flush_all();
5181
  }
 
 
 
 
 
 
 
 
5182
 
5183
  }
5184
 
2
  use CustomFacebookFeed\CFF_Utils;
3
  use CustomFacebookFeed\CFF_Oembed;
4
  use CustomFacebookFeed\CFF_GDPR_Integrations;
5
+ use CustomFacebookFeed\CFF_Feed_Locator;
6
 
7
  //Create Style page
8
  function cff_style_page() {
332
  $cff_hide_comments = $options[ 'cff_hide_comments' ];
333
  //Misc
334
  $cff_feed_width = $options[ 'cff_feed_width' ];
335
+ $cff_feed_width_resp = $options[ 'cff_feed_width_resp' ];
336
  $cff_feed_height = $options[ 'cff_feed_height' ];
337
  $cff_feed_padding = $options[ 'cff_feed_padding' ];
338
  $cff_like_box_position = $options[ 'cff_like_box_position' ];
394
  $cff_author_size = $options[ 'cff_author_size' ];
395
  $cff_author_color = $options[ 'cff_author_color' ];
396
 
397
+ $gdpr = $options[ 'gdpr' ];
398
  //New
399
  $cff_custom_css = $options[ 'cff_custom_css' ];
400
  $cff_custom_js = $options[ 'cff_custom_js' ];
405
  $cff_video_action = $options[ 'cff_video_action' ];
406
  $cff_sep_color = $options[ 'cff_sep_color' ];
407
  $cff_sep_size = $options[ 'cff_sep_size' ];
408
+
409
  // Texts lengths
410
  $cff_title_length = 'cff_title_length';
411
  $cff_body_length = 'cff_body_length';
772
  //Custom CSS
773
  if (isset($_POST[ 'cff_custom_css' ])) $cff_custom_css = $_POST[ 'cff_custom_css' ];
774
  if (isset($_POST[ 'cff_custom_js' ])) $cff_custom_js = $_POST[ 'cff_custom_js' ];
775
+
776
  if (isset($_POST[ 'cff_video_height' ])) $cff_video_height = sanitize_text_field( $_POST[ 'cff_video_height' ] );
777
  if (isset($_POST[ 'cff_video_action' ])) $cff_video_action = sanitize_text_field( $_POST[ 'cff_video_action' ] );
778
  if (isset($_POST[ 'cff_open_links' ])) $cff_open_links = sanitize_text_field( $_POST[ 'cff_open_links' ] );
904
  $options[ 'cff_translate_learn_more_text' ] = $cff_translate_learn_more_text;
905
  $options[ 'cff_translate_shop_now_text' ] = $cff_translate_shop_now_text;
906
  $options[ 'cff_translate_message_page_text' ] = $cff_translate_message_page_text;
907
+
908
  //Date translate
909
  $options[ 'cff_translate_second' ] = $cff_translate_second;
910
  $options[ 'cff_translate_seconds' ] = $cff_translate_seconds;
925
  }
926
  //Update the array
927
  update_option( 'cff_style_settings', $options );
928
+ // Put an settings updated message on the screen
929
  ?>
930
  <div class="updated"><p><strong><?php _e('Settings saved.', 'custom-facebook-feed' ); ?></strong></p></div>
931
+ <?php } ?>
932
 
933
  <?php } //End nonce check ?>
934
 
943
  </button>
944
  </div>
945
  <?php endif; ?>
946
+
947
  <div id="cff-admin" class="wrap">
948
  <div id="header">
949
  <h1><?php _e('Custom Facebook Feed', 'custom-facebook-feed'); ?></h1>
1051
  <option value="5" <?php if( $cff_cols == 5 ) { echo 'selected'; } ?>>5</option>
1052
  <option value="6" <?php if( $cff_cols == 6 ) { echo 'selected'; } ?>>6</option>
1053
  </select>
1054
+
1055
  <br />
1056
  <div class="cff-mobile-col-settings" <?php if( intval($cff_cols) > 1 ) echo 'style="display:block;"' ?>>
1057
  <div class="cff-row">
1071
  </table>
1072
 
1073
  <?php submit_button(); ?>
1074
+
1075
  <hr id="types" />
1076
  <table class="form-table">
1077
  <tbody>
1354
  <p class="cff-tooltip cff-more-info"><?php _e("This positions the Like Box widget outside of the feed container. It is useful if your feed has a vertical scrollbar as it places it outside of the scrollable area and fixes it at the top or bottom."); ?></p>
1355
  </td>
1356
  </tr>
1357
+
1358
  <tr valign="top">
1359
  <th class="bump-left" scope="row"><label><?php _e('Show faces of fans', 'custom-facebook-feed'); ?></label><code class="cff_shortcode"> likeboxfaces
1360
  Eg: likeboxfaces=true</code></th>
1533
  <p>Find out how to display <a href="https://smashballoon.com/using-shortcode-options-customize-facebook-feeds/" target="_blank"><b>multiple feeds</b></a>.</p>
1534
  </div>
1535
 
1536
+
1537
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png?2019' ?>" /></a>
1538
 
1539
  <?php } //End General tab ?>
1559
  <div class="cff-layout cff-thumb <?php if($cff_preset_layout == "thumb") echo "cff-layout-selected"; ?>">
1560
  <h3><input type="radio" name="cff_preset_layout" id="cff_preset_layout" value="thumb" disabled />&nbsp;<?php _e('Thumbnail'); ?></h3>
1561
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/layout-thumb.png' ?>" alt="Thumbnail Layout" />
1562
+
1563
  </div>
1564
  <div class="cff-layout cff-half <?php if($cff_preset_layout == "half") echo "cff-layout-selected"; ?>">
1565
  <h3><input type="radio" name="cff_preset_layout" id="cff_preset_layout" value="half" disabled />&nbsp;<?php _e('Half-width'); ?></h3>
1566
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/layout-half.png' ?>" alt="Half Width Layout" />
1567
+
1568
  </div>
1569
  <div class="cff-layout cff-full <?php if($cff_preset_layout == "full") echo "cff-layout-selected"; ?>">
1570
  <h3><input type="radio" name="cff_preset_layout" id="cff_preset_layout" value="full" disabled />&nbsp;<?php _e('Full-width'); ?></h3>
1571
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/layout-full.png' ?>" alt="Full Width Layout" />
1572
+
1573
  </div>
1574
  </div>
1575
 
1712
  <tr id="poststyle"><!-- Quick link --></tr>
1713
  </tbody>
1714
  </table>
1715
+
1716
  <?php submit_button(); ?>
1717
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png' ?>" /></a>
1718
  <?php } //End Post Layout tab ?>
1735
 
1736
  <input type="hidden" name="<?php echo $style_typography_hidden_field_name; ?>" value="Y">
1737
  <br />
1738
+
1739
  <h3><?php _e('Post Item'); ?></h3>
1740
  <table class="form-table">
1741
  <tbody>
1765
  </div>
1766
 
1767
  <div class="cff-post-style-settings cff-regular">
1768
+
1769
  <div class="cff-row">
1770
  <label><?php _e('Separating Line Color'); ?></label><code class="cff_shortcode"> sepcolor
1771
  Eg: sepcolor=CFCFCF</code>
1999
  <tr>
2000
  <th class="bump-left"><label for="cff_body_color" class="bump-left"><?php _e('Text Color'); ?></label><code class="cff_shortcode"> desccolor
2001
  Eg: desccolor=9F9F9F</code></th>
2002
+
2003
  <td>
2004
  <input name="cff_body_color" value="#<?php esc_attr_e( str_replace('#', '', $cff_body_color) ); ?>" class="cff-colorpicker" />
2005
  </td>
2070
  <input name="cff_date_color" value="#<?php esc_attr_e( str_replace('#', '', $cff_date_color) ); ?>" class="cff-colorpicker" />
2071
  </td>
2072
  </tr>
2073
+
2074
  <tr>
2075
  <th class="bump-left"><label for="cff_date_formatting" class="bump-left"><?php _e('Date Formatting'); ?></label><code class="cff_shortcode"> dateformat
2076
  Eg: dateformat=3</code></th>
2412
  </select>
2413
  </td>
2414
  </tr>
2415
+
2416
  <tr>
2417
  <th class="bump-left"><label for="cff_event_title_size" class="bump-left"><?php _e('Text Size'); ?></label><code class="cff_shortcode"> eventtitlesize
2418
  Eg: eventtitlesize=12</code></th>
2465
  </tbody>
2466
  </table>
2467
  <hr />
2468
+
2469
  <h3><?php _e('Event Date'); ?></h3>
2470
  <table class="form-table">
2471
  <tbody>
2624
  </table>
2625
 
2626
  <?php submit_button(); ?>
2627
+
2628
  <hr />
2629
 
2630
  <h3><?php _e('Post Action Links'); ?></span> <a class="cff-tooltip-link" href="JavaScript:void(0);"><?php _e('What is this?'); ?></a>
2793
  </div>
2794
 
2795
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png' ?>" /></a>
2796
+
2797
  <?php } //End Typography tab ?>
2798
  <?php if( $cff_active_tab == 'misc' ) { //Start Misc tab ?>
2799
 
2827
  <tr valign="top">
2828
  <td style="padding-top: 0;">
2829
  <p style="padding-bottom: 10px;"><?php _e('Enter your own custom JavaScript/jQuery in the box below', 'custom-facebook-feed'); ?> <i style="margin-left: 5px; font-size: 11px;"><a href="https://smashballoon.com/snippets/" target="_blank"><?php _e('See some examples', 'custom-facebook-feed'); ?></a></i></p>
2830
+ <textarea name="cff_custom_js" id="cff_custom_js" style="width: 70%;" rows="7"><?php echo esc_textarea( stripslashes($cff_custom_js), 'custom-facebook-feed' ); ?></textarea>
2831
  </td>
2832
  </tr>
2833
  </tbody>
2949
  </tr>
2950
 
2951
  </tbody>
2952
+ </table>
2953
 
2954
  <hr />
2955
  <h3><?php _e('Media'); ?></h3>
3206
  <p class="cff-tooltip"><?php _e("Understanding how you are using the plugin allows us to further improve it. The plugin will send a report in the background once per week which includes information about your plugin settings and statistics about your site, which we can use to help improve the features which matter most to you and improve your experience using the plugin. The plugin will never collect any sensitive information like access tokens, email addresses, or user information, and sending this data won't slow down your site at all. For more information,", 'custom-facebook-feed'); ?> <a href="https://smashballoon.com/custom-facebook-feed/docs/usage-tracking/" target="_blank"><?php _e("see here", 'custom-facebook-feed'); ?></a>.</p>
3207
  </td>
3208
  </tr>
3209
+
3210
  </tbody>
3211
  </table>
3212
 
3299
  <td><input name="cff_translate_message_page_text" type="text" value="<?php echo stripslashes( esc_attr( $cff_translate_message_page_text ) ); ?>" /></td>
3300
  <td class="cff-context"><?php _e("Used for the 'Message Page' button", 'custom-facebook-feed'); ?></td>
3301
  </tr>
3302
+
3303
  <tr class="cff-table-header"><th colspan="3"><?php _e('Date', 'custom-facebook-feed'); ?></th></tr>
3304
  <tr>
3305
  <td><label for="cff_photos_text" class="bump-left"><?php _e('"Posted _ hours ago" text', 'custom-facebook-feed'); ?></label></td>
3355
 
3356
  </tbody>
3357
  </table>
3358
+
3359
  <?php submit_button(); ?>
3360
  <a href="https://smashballoon.com/custom-facebook-feed/demo/?utm_campaign=facebook-free&utm_source=footer&utm_medium=ad" target="_blank" class="cff-pro-notice"><img src="<?php echo CFF_PLUGIN_URL. 'admin/assets/img/pro.png' ?>" /></a>
3361
  <?php } //End Custom Text tab ?>
3368
  <button id="cff-admin-show-share-links" class="button secondary" style="margin-bottom: 1px;"><i class="fa fa-share-alt" aria-hidden="true"></i>&nbsp;&nbsp;Share the plugin</button> <div id="cff-admin-share-links"></div>
3369
  </div>
3370
 
3371
+ <?php
3372
  } //End Style_Page
3373
 
3374
 
3450
  $options[ 'cff_timezone' ] = $cff_timezone;
3451
  $options[ 'cff_num_mobile' ] = $cff_num_mobile;
3452
  update_option( 'cff_style_settings', $options );
3453
+
3454
  //Delete ALL transients
3455
  cff_delete_cache();
3456
+ // Put an settings updated message on the screen
3457
+ \cff_main()->cff_error_reporter->add_action_log( 'Saved settings on the configure tab.' );
3458
  ?>
3459
  <div class="updated"><p><strong><?php _e('Settings saved.', 'custom-facebook-feed' ); ?></strong></p></div>
3460
+ <?php } ?>
3461
+
3462
+ <?php } //End nonce check ?>
3463
 
 
 
3464
  <div id="cff-admin" class="wrap">
3465
 
3466
  <?php
3541
  </div>
3542
 
3543
  <a href="JavaScript:void(0);" class="cff_admin_btn" id="cff_fb_login"><i class="fa fa-facebook-square"></i> <?php _e( 'Connect a Facebook account', 'custom-facebook-feed' ); ?></a>
3544
+
3545
 
3546
  <?php
3547
  if( isset($_GET['access_token']) && isset($_GET['final_response']) ){
3548
 
3549
  if( $_GET['final_response'] == 'true' ){
 
3550
 
3551
+
3552
+ \cff_main()->cff_error_reporter->remove_error( 'connection' );
3553
+ \cff_main()->cff_error_reporter->add_action_log( 'Connection or updating account');
3554
 
3555
  $access_token = $_GET['access_token'];
3556
  $cff_is_groups = false;
3632
  echo "<p>Facebook has not returned any groups for your user. It is only possible to display a feed from a group which you are either an admin or a member. Please note, if you are not an admin of the group then it is required that an admin add our app in the group settings in order to display a feed.</p><p>Please either create or join a Facebook group and then follow the directions when connecting your account on this page.</p>";
3633
  echo '<a href="JavaScript:void(0);" class="button button-primary" id="cff-close-modal-primary-button">Close</a>';
3634
  } else {
 
3635
 
3636
+
3637
+ \cff_main()->cff_error_reporter->remove_error( 'connection' );
3638
  echo '<div class="cff-groups-list">';
3639
  echo '<p style="margin-top: 0;"><i class="fa fa-check-circle" aria-hidden="true" style="font-size: 15px; margin: 0 8px 0 2px;"></i>Select a Facebook group below to get an Access Token.</p>';
3640
 
3693
 
3694
  } else {
3695
  //PAGES
 
3696
 
3697
+
3698
+ \cff_main()->cff_error_reporter->remove_error( 'connection' );
3699
+
3700
  echo '<p class="cff-tokens-note"><i class="fa fa-check-circle" aria-hidden="true" style="font-size: 15px; margin: 0 8px 0 2px;"></i> Select a Facebook page below to connect it.</p>';
3701
 
3702
  echo '<div class="cff-pages-wrap">';
3856
  <h3 class="cff_connected_actions">Connected Accounts:</h3>
3857
  <div id="cff_connected_accounts_wrap"><?php //Add connected accounts here ?></div>
3858
 
3859
+ <div class="cff_connected_actions cff_feeds_account_ctn">
3860
+ <?php if ( CFF_Feed_Locator::count_unique() >= 1 ) : ?>
3861
+ <div class="cff_locations_link">
3862
+ <a href="?page=cff-top&amp;tab=allfeeds"><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-search fa-w-16 fa-2x"><path fill="currentColor" d="M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z" class=""></path></svg> <?php _e('Feed Finder', 'custom-facebook-feed'); ?></a>
3863
+ </div>
3864
+ <?php endif; ?>
3865
  <a href="JavaScript:void(0);" id="cff_export_accounts">Show raw account data</a>
3866
  <div id="cff_export_accounts_wrap">
3867
  <textarea name="cff_connected_accounts" id="cff_connected_accounts" style="width: 100%;" rows="5" /><?php echo stripslashes( esc_attr( $cff_connected_accounts_val ) ); ?></textarea>
4147
  </select>
4148
  </td>
4149
  </tr>
4150
+
4151
  </tbody>
4152
  </table>
4153
+
4154
  <div class="cff-save-settings-btn">
4155
  <?php submit_button('Save Settings & Clear Cache'); ?>
4156
 
4179
 
4180
  <?php } //End config tab ?>
4181
 
4182
+ <?php if ( $cff_active_tab == 'allfeeds' ) {
4183
+ $locator_summary = CFF_Feed_Locator::summary();
4184
+ include_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/templates/locator-summary.php';
4185
+ } ?>
4186
 
4187
  <?php if( $cff_active_tab == 'support' ) { //Start Support tab ?>
4188
 
4472
  } ?>
4473
 
4474
  ## FACEBOOK API RESPONSE: ##
4475
+ <?php
4476
  $api_response_json = json_decode($posts_json);
4477
  if( isset( $api_response_json->error ) ) echo $posts_json;
4478
  if( isset( $api_response_json->data ) ){
4502
  }
4503
  ?>
4504
 
4505
+ ## Errors: ##
4506
  <?php
4507
 
4508
  $errors = \cff_main()->cff_error_reporter->get_errors();
4509
+ if ( ! empty( $errors['resizing'] ) ) :
4510
+ echo '* Resizing *' . "\n";
4511
+ echo $errors['resizing'] . "\n";
4512
+ endif;
4513
+ if ( ! empty( $errors['database_create'] ) ) :
4514
+ echo '* Database Create *' . "\n";
4515
+ echo $errors['database_create'] . "\n";
4516
+ endif;
4517
+ if ( ! empty( $errors['upload_dir'] ) ) :
4518
+ echo '* Uploads Directory *' . "\n";
4519
+ echo $errors['upload_dir'] . "\n";
4520
+ endif;
4521
+ if ( ! empty( $errors['connection'] ) ) :
4522
+ echo '* API/WP_HTTP Request *' . "\n";
4523
+ var_export( $errors['connection'] );
4524
+ endif;
4525
+ ?>
4526
 
4527
+ ## Error Log: ##
4528
+ <?php
4529
+ $error_log = \cff_main()->cff_error_reporter->get_error_log();
4530
+ if ( ! empty( $error_log ) ) :
4531
+ foreach ( $error_log as $error ) :
4532
+ echo strip_tags($error) . "\n";
4533
+ endforeach;
4534
  endif;
4535
+ ?>
4536
+
4537
+ ## Action Log: ##
4538
+ <?php
4539
+ $actions = \cff_main()->cff_error_reporter->get_action_log();
4540
 
4541
+ if ( ! empty( $actions ) ) :
4542
+ foreach ( $actions as $action ) :
4543
+ echo strip_tags($action) . "\n";
4544
+ endforeach;
4545
+ endif;
4546
  ?>
4547
 
4548
+ ## Location Summary: ##
4549
+ <?php
4550
+ $locator_summary = CFF_Feed_Locator::summary();
4551
+
4552
+ if ( ! empty( $locator_summary) ) {
4553
+
4554
+ foreach ( $locator_summary as $locator_section ) {
4555
+ if ( ! empty( $locator_section['results'] ) ) {
4556
+ $first_five = array_slice( $locator_section['results'], 0, 5 );
4557
+ foreach ( $first_five as $result ) {
4558
+ echo esc_url( get_the_permalink( $result['post_id'] ) ) . "\n";
4559
+ }
4560
+
4561
+ }
4562
+ }
4563
+ }?>
4564
+
4565
  ## oEmbed: ##
4566
  <?php
4567
  $oembed_token_settings = get_option( 'cff_oembed_token', array() );
4841
  } //End More tab
4842
 
4843
 
 
4844
 
4845
+
4846
+ } //End Settings_Page
4847
 
4848
 
4849
 
4927
  <?php if ( ! $saved_access_token_data && ! $valid_new_access_token && ! CFF_Oembed::can_do_oembed() ) {
4928
  if ( $access_token_error ) { ?>
4929
  <p><?php _e("There was a problem with the access token that was retrieved.", "custom-facebook-feed"); ?></p>
4930
+ <?php }
4931
  $token_href = 'https://api.smashballoon.com/facebook-login.php?state=' . $admin_url_state;
4932
  if ( class_exists( 'SB_Instagram_Oembed' ) ) {
4933
  $sbi_oembed_token = SB_Instagram_Oembed::last_access_token();
4934
+
4935
  if ( ! empty( $sbi_oembed_token ) ) {
4936
  $token_href = add_query_arg( 'transfer', '1', $admin_url_state );
4937
  }
5118
  add_action( 'wp_ajax_cff_lite_dismiss', 'cff_lite_dismiss' );
5119
 
5120
  function cff_reset_log() {
5121
+ \cff_main()->cff_error_reporter->add_action_log( 'View feed and retry button clicked.' );
 
 
5122
  cff_delete_cache();
 
5123
  die();
5124
  }
5125
  add_action( 'wp_ajax_cff_reset_log', 'cff_reset_log' );
5174
  <b>Action required: PPCA Error.</b> <span style='margin-right: 10px;'>Due to Facebook API changes it is no longer possible to display feeds from Facebook Pages you are not an admin of. Please <a href='https://smashballoon.com/facebook-ppca-error-notice/' target='_blank'>see here</a> for more information.</span><a href='admin.php?page=cff-top' class='cff-admin-notice-button'>Go to Facebook Feed Settings</a></p>
5175
  </div>
5176
  ");
5177
+ }
5178
  }
5179
 
5180
  }
5192
  // Add a Settings link to the plugin on the Plugins page
5193
  $cff_plugin_file = 'custom-facebook-feed/custom-facebook-feed.php';
5194
  add_filter( "plugin_action_links_{$cff_plugin_file}", 'cff_add_settings_link', 10, 2 );
5195
+
5196
  //modify the link by unshifting the array
5197
  function cff_add_settings_link( $links, $file ) {
5198
  $cff_settings_link = '<a href="' . admin_url( 'admin.php?page=cff-top' ) . '">' . __( 'Settings', 'cff-top', 'custom-facebook-feed' ) . '</a>';
5199
  array_unshift( $links, $cff_settings_link );
5200
+
5201
  return $links;
5202
  }
5203
 
5234
  if (function_exists('w3tc_flush_all')) {
5235
  w3tc_flush_all();
5236
  }
5237
+ if (function_exists('sg_cachepress_purge_cache')) {
5238
+ sg_cachepress_purge_cache();
5239
+ }
5240
+
5241
+ // Litespeed Cache
5242
+ if ( method_exists( 'LiteSpeed_Cache_API', 'purge' ) ) {
5243
+ LiteSpeed_Cache_API::purge( 'esi.custom-facebook-feed' );
5244
+ }
5245
 
5246
  }
5247
 
admin/assets/css/cff-admin-style.css CHANGED
@@ -11,7 +11,7 @@
11
  font-weight: normal;
12
  }
13
  #cff-admin .cff-tooltip ul{
14
- margin-top: 0;
15
  margin-bottom: 0;
16
  }
17
  #cff-admin .cff-tooltip li{
@@ -33,7 +33,7 @@
33
  font-size: 13px;
34
  background: #f9f9f9;
35
  background: rgba(255,255,255,0.8);
36
-
37
  -moz-border-radius: 8px;
38
  -webkit-border-radius: 8px;
39
  border-radius: 8px;
@@ -268,7 +268,7 @@
268
  width: 222px;
269
  padding: 15px 15px 10px 15px;
270
  margin-right: 15px;
271
-
272
  background: #f6f6f6;
273
  border: 1px solid #ddd;
274
 
@@ -3032,4 +3032,38 @@
3032
  background: #F7E6E6;
3033
  border: 1px solid #BA7B7B;
3034
  color: #592626;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3035
  }
11
  font-weight: normal;
12
  }
13
  #cff-admin .cff-tooltip ul{
14
+ margin-top: 0;
15
  margin-bottom: 0;
16
  }
17
  #cff-admin .cff-tooltip li{
33
  font-size: 13px;
34
  background: #f9f9f9;
35
  background: rgba(255,255,255,0.8);
36
+
37
  -moz-border-radius: 8px;
38
  -webkit-border-radius: 8px;
39
  border-radius: 8px;
268
  width: 222px;
269
  padding: 15px 15px 10px 15px;
270
  margin-right: 15px;
271
+
272
  background: #f6f6f6;
273
  border: 1px solid #ddd;
274
 
3032
  background: #F7E6E6;
3033
  border: 1px solid #BA7B7B;
3034
  color: #592626;
3035
+ }
3036
+ .cff_feeds_account_ctn{width: 100%; float: left;}
3037
+ .cff_feeds_account_ctn #cff_export_accounts{float: right;}
3038
+ /* Locator Summary */
3039
+ .cff-feed-locator-summary-wrap {
3040
+ max-width: 1100px;
3041
+ margin-bottom: 40px;
3042
+ }
3043
+ .cff-full-wrap {
3044
+ display: none;
3045
+ }
3046
+ .cff-locator-more {
3047
+ display: inline-block;
3048
+ margin: 0 0 0 1px;
3049
+ padding: 0 5px;
3050
+ border: 1px solid rgba(0,0,0,0.1);
3051
+ border-radius: 3px;
3052
+ line-height: 1.6;
3053
+ }
3054
+
3055
+ .cff_shortcode_visible .cff_locations_link {
3056
+ display: none;
3057
+ }
3058
+ .cff_locations_link{
3059
+ float: left;
3060
+ }
3061
+ .cff_locations_link a {
3062
+ font-weight: normal;
3063
+ text-decoration: none;
3064
+ }
3065
+ .cff_locations_link svg {
3066
+ width: 11px;
3067
+ position: relative;
3068
+ top: 1px;
3069
  }
admin/assets/js/cff-admin-scripts.js CHANGED
@@ -976,6 +976,13 @@ jQuery(document).ready(function($) {
976
  jQuery('.sb_cross_install_modal').remove();
977
  });
978
 
 
 
 
 
 
 
 
979
  });
980
 
981
 
976
  jQuery('.sb_cross_install_modal').remove();
977
  });
978
 
979
+ // Locator
980
+ jQuery('.cff-locator-more').click(function(e) {
981
+ e.preventDefault();
982
+ jQuery(this).closest('td').find('.cff-full-wrap').show();
983
+ jQuery(this).closest('td').find('.cff-condensed-wrap').hide();
984
+ jQuery(this).remove();
985
+ });
986
  });
987
 
988
 
admin/templates/locator-summary.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Custom Feeds for Facebook Feed Locator Summary Template
4
+ * Creates the HTML for the feed locator summary
5
+ *
6
+ * @version 2.19 Custom Feeds for Facebook Pro by Smash Balloon
7
+ *
8
+ */
9
+
10
+ use CustomFacebookFeed\CFF_FB_Settings;
11
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
+ $database_settings = get_option('cff_style_settings');
13
+ $connected_accounts = (array)json_decode(stripcslashes(get_option( 'cff_connected_accounts' )));
14
+
15
+ ?>
16
+ <div class="cff-feed-locator-summary-wrap">
17
+ <h3><?php esc_html_e( 'Feed Finder Summary', 'custom-facebook-feed' ); ?></h3>
18
+ <p><?php esc_html_e( 'The table below shows a record of all feeds found on your site. A feed may not show up here immediately after being created.', 'custom-facebook-feed' ); ?></p>
19
+ <?php
20
+ if ( ! empty( $locator_summary ) ) : ?>
21
+
22
+ <?php foreach ( $locator_summary as $locator_section ) :
23
+ if ( ! empty( $locator_section['results'] ) ) : ?>
24
+ <div class="cff-single-location">
25
+ <h4><?php echo esc_html( $locator_section['label'] ); ?></h4>
26
+ <table class="widefat striped">
27
+ <thead>
28
+ <tr>
29
+ <th><?php esc_html_e( 'Type', 'custom-facebook-feed' ); ?></th>
30
+ <th><?php esc_html_e( 'Sources', 'custom-facebook-feed' ); ?></th>
31
+ <th><?php esc_html_e( 'Shortcode', 'custom-facebook-feed' ); ?></th>
32
+ <th><?php esc_html_e( 'Location', 'custom-facebook-feed' ); ?></th>
33
+ </tr>
34
+ </thead>
35
+ <tbody>
36
+
37
+ <?php foreach ( $locator_section['results'] as $result ) :
38
+ $shortcode_atts = $result['shortcode_atts'] != '[""]' ? json_decode( $result['shortcode_atts'], true ) : [];
39
+ $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array();
40
+ $display_terms = CFF_FB_Settings::feed_type_and_terms_display( $connected_accounts, $result, $database_settings );
41
+ $comma_separated = implode(',',$display_terms['name']);
42
+
43
+ $display = $comma_separated;
44
+ if ( strlen( $comma_separated ) > 31 ) {
45
+ $display = '<span class="cff-condensed-wrap">' . substr( $comma_separated, 0, 30 ) . '<a class="cff-locator-more" href="JavaScript:void(0);">...</a></span>';
46
+ $comma_separated = '<span class="cff-full-wrap">' . esc_html( $comma_separated ) . '</span>';
47
+ } else {
48
+ $comma_separated = '';
49
+ }
50
+ $type = implode(',',$display_terms['type']);
51
+
52
+ $full_shortcode_string = '[custom-facebook-feed';
53
+ foreach ( $shortcode_atts as $key => $value ) {
54
+ $full_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"';
55
+ }
56
+ $full_shortcode_string .= ']';
57
+ ?>
58
+ <tr>
59
+ <td><?php echo esc_html( $type ); ?></td>
60
+ <td><?php echo $display . $comma_separated; ?></td>
61
+ <td>
62
+ <span class="cff-condensed-wrap"><a class="cff-locator-more" href="JavaScript:void(0);"><?php esc_html_e( 'Show', 'custom-facebook-feed' ); ?></a></span>
63
+ <span class="cff-full-wrap"><?php echo $full_shortcode_string; ?></span>
64
+ </td>
65
+ <td><a href="<?php echo esc_url( get_the_permalink( $result['post_id'] ) ); ?>" target="_blank" rel="noopener"><?php echo esc_html( get_the_title( $result['post_id'] ) ); ?></a></td>
66
+ </tr>
67
+ <?php endforeach; ?>
68
+
69
+
70
+ </tbody>
71
+ </table>
72
+ </div>
73
+
74
+ <?php endif;
75
+ endforeach;
76
+ else: ?>
77
+ <p><?php esc_html_e( 'Locations of your feeds are currently being detected. You\'ll see more information posted here soon!', 'custom-facebook-feed' ); ?></p>
78
+ <?php endif; ?>
79
+ </div>
assets/css/cff-style.css CHANGED
@@ -17,7 +17,7 @@
17
  -moz-box-sizing: border-box;
18
  box-sizing: border-box;
19
  }
20
- .cff-wrapper-ctn{overflow: hidden;}
21
  .cff-wrapper-ctn.cff-wrapper-fixed-height{overflow: auto; overflow-x: hidden;}
22
  .cff-wrapper-ctn,
23
  #cff .cff-posts-wrap,
@@ -345,6 +345,7 @@
345
  width: 40px;
346
  height: 40px;
347
  background: url('../img/cff-avatar.png') no-repeat;
 
348
  }
349
 
350
  /* Author Date */
17
  -moz-box-sizing: border-box;
18
  box-sizing: border-box;
19
  }
20
+ .cff-wrapper-ctn{overflow: hidden; box-sizing: border-box;}
21
  .cff-wrapper-ctn.cff-wrapper-fixed-height{overflow: auto; overflow-x: hidden;}
22
  .cff-wrapper-ctn,
23
  #cff .cff-posts-wrap,
345
  width: 40px;
346
  height: 40px;
347
  background: url('../img/cff-avatar.png') no-repeat;
348
+ margin: 0px !important;
349
  }
350
 
351
  /* Author Date */
assets/css/cff-style.min.css CHANGED
@@ -1 +1 @@
1
- .cff-wrapper:after{content:"";display:table;clear:both}#cff{float:left;width:100%;margin:0 auto;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.cff-wrapper-ctn{overflow:hidden}.cff-wrapper-ctn.cff-wrapper-fixed-height{overflow:auto;overflow-x:hidden}#cff .cff-masonry-posts,#cff .cff-posts-wrap,.cff-wrapper-ctn{position:relative;clear:both;height:100%;top:0;bottom:0;width:100%}#cff .cff-item{float:left;width:100%;clear:both;padding:20px 0 15px 0;margin:0;border-bottom:1px solid #ddd}#cff .cff-item:first-child{padding-top:0}#cff .cff-item.cff-box,#cff .cff-item.cff-box:first-child{padding:15px;margin:8px 0;background:rgba(255,255,255,.5);border:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-item.cff-box:first-child{margin-top:0}#cff .cff-item.cff-box:last-child{margin-bottom:0}#cff .cff-item.cff-shadow{box-shadow:0 0 10px 0 rgba(0,0,0,.15);-moz-box-shadow:0 0 10px 0 rgba(0,0,0,.15);-webkit-box-shadow:0 0 10px 0 rgba(0,0,0,.15)}.cff-header{width:100%;margin:0 0 15px 0;padding:0;line-height:1;-webkit-box-sizing:border-box;box-sizing:border-box;display:flex;align-items:center}.cff-header .fa,.cff-header svg{margin:0 10px 0 0;padding:0}.cff-visual-header{margin-bottom:24px!important}.cff-visual-header .cff-header-hero{width:100%;height:300px;position:relative;overflow:hidden}.cff-visual-header .cff-header-hero img{width:100%;display:none}.cff-visual-header .cff-likes-box{position:absolute;bottom:10px;right:10px;padding:5px;background:#eee;line-height:1;border-radius:2px;color:#445790}.cff-visual-header .cff-likes-box .cff-square-logo{float:left;display:inline-block;line-height:0}.cff-visual-header .cff-likes-box .cff-square-logo svg{width:18px;vertical-align:top}.cff-visual-header .cff-likes-box .cff-likes-count{float:left;display:inline-block;margin-left:8px;vertical-align:top;font-size:15px;line-height:20px}.cff-visual-header .cff-header-inner-wrap{position:relative;display:block;text-decoration:none!important}.cff-visual-header .cff-header-inner-wrap a{color:inherit!important;border:0}.cff-visual-header .cff-header-img img{display:block;width:100px;border-radius:3px;padding:0;margin:0}.cff-visual-header.cff-has-cover .cff-header-img img{border:2px solid #fff}.cff-visual-header .cff-header-img{position:absolute;display:inline-block;line-height:1}.cff-visual-header.cff-has-cover .cff-header-img{top:-25px;left:10px}.cff-visual-header .cff-header-text{display:inline-block;float:left;margin:20px 0 0 120px}#cff .cff-visual-header .cff-header-text h3,.cff-visual-header .cff-header-text h3{display:inline-block;width:auto;margin:0 8px 0 0;padding:0;font-size:1.2em;line-height:1.2em}.cff-visual-header .cff-header-text{padding-top:10px;margin:0}.cff-visual-header.cff-has-name{min-height:100px}.cff-visual-header.cff-has-cover.cff-has-name .cff-header-text{min-height:75px}.cff-visual-header.cff-has-name .cff-header-text{margin-left:120px}.cff-visual-header.cff-has-cover.cff-has-name .cff-header-text{margin-left:125px}.cff-visual-header.cff-has-name .cff-header-text{padding-top:30px}.cff-visual-header.cff-has-name.cff-has-about .cff-header-text,.cff-visual-header.cff-has-name.cff-has-cover .cff-header-text{padding-top:10px}#cff .cff-visual-header .cff-header-inner-wrap .cff-bio,.cff-visual-header .cff-header-inner-wrap .cff-bio{display:block;width:100%;clear:both;margin:3px 0 0 0;padding:0;line-height:1.2em}.cff-visual-header .cff-header-name{float:left;padding:0 5px 2px 0}.cff-visual-header .cff-bio-info{font-size:.9em;line-height:1.7}.cff-visual-header .cff-bio-info svg{display:inline-block;width:1em;vertical-align:middle;position:relative;top:-2px}.cff-posts-count svg{padding-right:3px}.cff-header-inner-wrap:after,.cff-header-text:after{display:table;clear:both;content:" "}#cff .cff-less{display:none}#cff.cff-default-styles a{text-decoration:none}#cff.cff-default-styles a:focus,#cff.cff-default-styles a:hover{text-decoration:underline}#cff .cff-post-text-link{display:block}.cff-post-text{width:100%;float:left}#cff .cff-post-desc,#cff h3,#cff h4,#cff h5,#cff h6,#cff p{float:left;width:100%;clear:both;padding:0;margin:5px 0;word-wrap:break-word}#cff.cff-default-styles .cff-post-desc,#cff.cff-default-styles h3,#cff.cff-default-styles h4,#cff.cff-default-styles h5,#cff.cff-default-styles h6,#cff.cff-default-styles p{line-height:1.4}#cff .cff-date{float:left;min-width:50px;width:auto}#cff.cff-default-styles .cff-date{font-size:11px}#cff .cff-author{float:left;clear:both;margin:0 0 15px 0;padding:0;line-height:1.2;width:100%}#cff .cff-author a{text-decoration:none;border:none}#cff .cff-author-img{float:left;width:40px;height:40px;margin:0 0 0 -100%!important;font-size:0;background:#eee;background:url(../img/cff-avatar.png) no-repeat;background-size:100%;border-radius:50%}#cff .cff-author img{float:left;margin:0!important;padding:0!important;border:none!important;font-size:0;border-radius:50%}#cff .cff-author-img.cff-no-consent img{display:none}.cff-no-consent .cff-header-text{margin-left:0!important}.cff-no-consent .cff-header-hero,.cff-no-consent .cff-header-img{display:none!important}#cff .cff-author .cff-author-text span.cff-page-name{display:table-cell;vertical-align:middle;height:40px;margin:0;font-weight:700;padding-left:50px;float:none}#cff .cff-author .cff-story{font-weight:400}#cff.cff-default-styles .cff-author a{text-decoration:none}#cff .cff-author.cff-no-author-info .cff-date{margin-top:12px!important}#cff .cff-author.cff-no-author-info .cff-author-img{width:40px;height:40px;background:url(../img/cff-avatar.png) no-repeat}#cff .cff-author .cff-author-text{float:left;width:100%}#cff .cff-author .cff-date,#cff .cff-author .cff-page-name{float:left;clear:both;width:auto;margin:0 0 0 50px!important}#cff.cff-default-styles .cff-author .cff-author-text *{font-weight:700;line-height:1.2}#cff .cff-author .cff-date{color:#9197a3;font-size:11px;margin-top:2px!important;margin-bottom:0!important}#cff.cff-default-styles .cff-author .cff-date{font-weight:400}#cff .cff-author .cff-page-name.cff-author-date{float:left;padding:3px 0 0 0;font-size:14px}#cff .cff-cta-link a,.cff-media-link .fa{display:inline-block;width:auto;padding:5px 7px 5px 6px;margin-right:6px;border:1px solid #eee;border:1px solid rgba(0,0,0,.1);border-radius:3px;background:rgba(0,0,0,.02)}#cff .cff-cta-link a:hover,.cff-media-link .fa:hover{background:#f9f9f9;background:rgba(0,0,0,.03);text-decoration:none}#cff .cff-cta-link a{padding:5px 15px}#cff .cff-break-word{word-break:break-all}#cff .cff-expand{display:none}#cff.cff-default-styles .cff-expand a{font-size:11px;font-weight:400}#cff .cff-shared-link{float:left;clear:both;width:100%;padding:5px 10px;margin:10px 0 5px 0;background:#f9f9f9;border:1px solid #d9d9d9;background:rgba(0,0,0,.02);border:1px solid rgba(0,0,0,.07);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-no-styles{background:0 0;border:none;padding:0}#cff .cff-link{float:left;clear:both;max-width:20%;margin:10px 0 0 0}#cff .cff-link img{max-width:100%}#cff .cff-link-title{float:left;clear:both;width:100%;display:block}#cff.cff-default-styles .cff-link-title{font-weight:700}#cff p.cff-link-title{margin:5px 0 0 0}#cff .cff-text-link{float:left;clear:none;width:72%;margin-left:3%;padding:0 0 5px 0}#cff .cff-link-caption{margin:0}#cff.cff-default-styles .cff-link-caption{font-size:12px}#cff .cff-text-link.cff-no-image{width:100%;margin-left:0}#cff .cff-post-desc{margin:5px 0 0 0}#cff .cff-details{float:left;clear:none;width:100%;margin:0;padding:0}#cff .cff-details h5{margin:0 0 5px 0}#cff.cff-default-styles .cff-details h5{padding:0;font-size:16px}#cff.cff-default-styles .cff-details p{font-size:14px}#cff .cff-timeline-event .cff-date,#cff .cff-timeline-event .cff-info,#cff .cff-timeline-event .cff-timeline-event-title,#cff .cff-timeline-event .cff-where{display:block;width:100%;clear:both}#cff .cff-details .cff-info{padding:10px 0 0 0}#cff.cff-default-styles .cff-details .cff-info{line-height:1.2}#cff .cff-desc-wrap{float:left;width:100%}#cff .cff-note-title{display:block;font-weight:700;padding-bottom:5px}#cff .cff-post-links{float:left;clear:none;padding:5px 0 0 0;margin:0}#cff.cff-default-styles .cff-post-links{font-size:11px}#cff .cff-post-links.cff-left{float:left;margin:8px 0}#cff.cff-default-styles .cff-post-links a{font-size:11px}#cff .cff-post-links a:first-child{padding-left:0;margin:0}#cff .cff-dot{padding:0 5px}#cff .cff-share-container{position:relative;display:inline}#cff .cff-share-tooltip{display:none;position:absolute;z-index:1000;bottom:22px;right:-40px;width:110px;padding:3px 5px 4px 5px;margin:0;background:#333;color:#eee;font-size:12px;line-height:1.3;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-share-tooltip .fa-play{position:absolute;font-size:8px;bottom:-6px;left:50%;margin-left:-3px;color:#333}#cff .cff-share-tooltip a .fa,#cff .cff-share-tooltip a svg{font-size:16px;margin:0;padding:5px}#cff .cff-share-tooltip a{display:block;float:left;margin:0!important;padding:0!important;color:#eee!important;opacity:0;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}#cff .cff-share-tooltip a:hover{color:#fff!important}#cff .cff-share-tooltip .cff-facebook-icon:hover{background:#3b5998}#cff .cff-share-tooltip .cff-twitter-icon:hover{background:#00aced}#cff .cff-share-tooltip .cff-google-icon:hover{background:#dd4b39}#cff .cff-share-tooltip .cff-linkedin-icon:hover{background:#007bb6}#cff .cff-share-tooltip .cff-pinterest-icon:hover{background:#cb2027}#cff .cff-share-tooltip .cff-email-icon:hover{background:#dd4b39}#cff .cff-share-tooltip a.cff-show{opacity:1;transition:opacity .2s ease}.cff-likebox{float:left;width:100%;position:relative;margin:20px 0 0 0}.fb_iframe_widget{border:none;overflow:hidden}.cff-likebox .fb_iframe_widget{width:100%}.cff-likebox .fb_iframe_widget span{width:100%!important}.cff-likebox .fb_iframe_widget iframe{margin:0;position:relative;top:0;left:0;width:100%!important;height:100%}.cff-likebox.cff-top.cff-outside{margin-bottom:10px}.cff-likebox.cff-bottom.cff-outside{margin-top:10px}#cff.cff-fixed-height{padding:5px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-error-msg{display:none;position:relative;font-size:12px;font-family:sans-serif;padding:8px 12px;border:1px solid #ddd;margin-bottom:10px;clear:both;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}#cff .cff-error-msg p{float:none}#cff .cff-error-msg .cff_notice_dismiss{position:absolute;top:4px;right:8px}#cff #cff-error-reason{display:none;padding:5px 0 0 0;clear:both}#cff.cff-default-styles .cff-credit{font-size:11px}#cff.cff-default-styles .cff-credit a{text-decoration:none}#cff .cff-credit img{float:left;margin:-2px 5px 0 0}#cff .cff-credit .fa{padding-right:5px;font-size:13px}.cff-credit a{display:flex;align-items:center}.cff-screenreader{text-indent:-9999px!important;display:block!important;width:0!important;height:0!important;line-height:0!important}@media all and (max-width:640px){#cff.cff-width-resp{width:100%!important}.cff-wrapper .cff-visual-header .cff-header-img img{width:80px}.cff-wrapper .cff-visual-header.cff-has-name .cff-header-text{margin-left:95px}.cff-wrapper .cff-visual-header.cff-has-cover.cff-has-name .cff-header-text{margin-left:105px}}#cff .cff-comment .cff-comment-text img,#cff img.emoji,#cff-lightbox-wrapper .cff-comment .cff-comment-text img,#cff-lightbox-wrapper img.emoji{float:none;max-width:100%}#cff .cff-linebreak{display:block;height:5px}#cff.cff-masonry .cff-item.cff-box{margin-left:1.5%;margin-right:1.5%}#cff.cff-masonry{box-sizing:border-box}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-item:first-child{padding-top:20px;margin-top:0}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox{float:none;display:inline-block;width:30.3%;margin:0 1.5%;margin-bottom:20px}#cff.cff-masonry.cff-opaque-comments .cff-item{z-index:1}#cff.cff-masonry.masonry-2-desktop .cff-item{width:47%;margin:0 1.5%}#cff.cff-masonry.masonry-4-desktop .cff-item{width:22%;margin:0 1.5%}#cff.cff-masonry.masonry-5-desktop .cff-item{width:17%;margin:0 1.5%}#cff.cff-masonry.masonry-6-desktop .cff-item{width:13.516%;margin:0 1.5%}#cff.cff-masonry .cff-comments-box{position:relative;z-index:999}#cff.cff-masonry .cff-comment-attachment,#cff.cff-masonry .cff-comment-replies-box{max-width:100%}#cff.cff-masonry .cff-load-more{display:block;float:left;clear:both}@media (max-width:780px){#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox,#cff.cff-masonry.masonry-2-desktop .cff-item,#cff.cff-masonry.masonry-4-desktop .cff-item,#cff.cff-masonry.masonry-5-desktop .cff-item,#cff.cff-masonry.masonry-6-desktop .cff-item{width:100%;margin:0}#cff.cff-masonry.masonry-2-mobile .cff-item{width:47%;margin-left:1.5%;margin-right:1.5%}}#cff.cff-masonry.cff-masonry-css{width:100%;overflow:hidden;margin-bottom:20px}#cff.cff-masonry.cff-masonry-css{-webkit-column-gap:20px;-moz-column-gap:20px;column-gap:20px;-webkit-column-fill:auto;column-fill:unset;-webkit-column-count:3;-moz-column-count:3;column-count:3;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-desktop{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-4-desktop{-webkit-column-count:4;-moz-column-count:4;column-count:4;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-5-desktop{-webkit-column-count:5;-moz-column-count:5;column-count:5;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:6;-moz-column-count:6;column-count:6;margin:0}#cff.cff-masonry.cff-masonry-css .cff-item,#cff.cff-masonry.cff-masonry-css .cff-likebox,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop .cff-item{float:none;display:inline-block;width:100%;margin:0 0 12px 0}#cff.cff-masonry.cff-masonry-css .cff-likebox{width:99.5%}#cff.cff-masonry.cff-masonry-css .cff-load-more{margin:0 0 10px 0;position:relative;bottom:0}@media only screen and (max-width:780px){#cff.cff-masonry.cff-masonry-css,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:1;-moz-column-count:1;column-count:1}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile,#cff.cff-masonry.cff-masonry-css.masonry-2-mobile .cff-item{width:100%}}#cff.cff-disable-masonry{height:auto!important}#cff.cff-disable-masonry .cff-item,#cff.cff-disable-masonry .cff-likebox{position:relative!important;top:auto!important}.cff-num-diff-hide{display:none!important}.cff-gdpr-notice{max-width:100%;box-sizing:border-box;padding:8px 15px;margin:0;font-size:12px;background:#fdf7f7;display:inline-block;border-radius:5px;border:1px solid #e4b1b1;line-height:1.3;display:none}
1
+ .cff-wrapper:after{content:"";display:table;clear:both}#cff{float:left;width:100%;margin:0 auto;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.cff-wrapper-ctn{overflow:hidden; box-sizing: border-box;}.cff-wrapper-ctn.cff-wrapper-fixed-height{overflow:auto;overflow-x:hidden}#cff .cff-masonry-posts,#cff .cff-posts-wrap,.cff-wrapper-ctn{position:relative;clear:both;height:100%;top:0;bottom:0;width:100%}#cff .cff-item{float:left;width:100%;clear:both;padding:20px 0 15px 0;margin:0;border-bottom:1px solid #ddd}#cff .cff-item:first-child{padding-top:0}#cff .cff-item.cff-box,#cff .cff-item.cff-box:first-child{padding:15px;margin:8px 0;background:rgba(255,255,255,.5);border:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-item.cff-box:first-child{margin-top:0}#cff .cff-item.cff-box:last-child{margin-bottom:0}#cff .cff-item.cff-shadow{box-shadow:0 0 10px 0 rgba(0,0,0,.15);-moz-box-shadow:0 0 10px 0 rgba(0,0,0,.15);-webkit-box-shadow:0 0 10px 0 rgba(0,0,0,.15)}.cff-header{width:100%;margin:0 0 15px 0;padding:0;line-height:1;-webkit-box-sizing:border-box;box-sizing:border-box;display:flex;align-items:center}.cff-header .fa,.cff-header svg{margin:0 10px 0 0;padding:0}.cff-visual-header{margin-bottom:24px!important}.cff-visual-header .cff-header-hero{width:100%;height:300px;position:relative;overflow:hidden}.cff-visual-header .cff-header-hero img{width:100%;display:none}.cff-visual-header .cff-likes-box{position:absolute;bottom:10px;right:10px;padding:5px;background:#eee;line-height:1;border-radius:2px;color:#445790}.cff-visual-header .cff-likes-box .cff-square-logo{float:left;display:inline-block;line-height:0}.cff-visual-header .cff-likes-box .cff-square-logo svg{width:18px;vertical-align:top}.cff-visual-header .cff-likes-box .cff-likes-count{float:left;display:inline-block;margin-left:8px;vertical-align:top;font-size:15px;line-height:20px}.cff-visual-header .cff-header-inner-wrap{position:relative;display:block;text-decoration:none!important}.cff-visual-header .cff-header-inner-wrap a{color:inherit!important;border:0}.cff-visual-header .cff-header-img img{display:block;width:100px;border-radius:3px;padding:0;margin:0}.cff-visual-header.cff-has-cover .cff-header-img img{border:2px solid #fff}.cff-visual-header .cff-header-img{position:absolute;display:inline-block;line-height:1}.cff-visual-header.cff-has-cover .cff-header-img{top:-25px;left:10px}.cff-visual-header .cff-header-text{display:inline-block;float:left;margin:20px 0 0 120px}#cff .cff-visual-header .cff-header-text h3,.cff-visual-header .cff-header-text h3{display:inline-block;width:auto;margin:0 8px 0 0;padding:0;font-size:1.2em;line-height:1.2em}.cff-visual-header .cff-header-text{padding-top:10px;margin:0}.cff-visual-header.cff-has-name{min-height:100px}.cff-visual-header.cff-has-cover.cff-has-name .cff-header-text{min-height:75px}.cff-visual-header.cff-has-name .cff-header-text{margin-left:120px}.cff-visual-header.cff-has-cover.cff-has-name .cff-header-text{margin-left:125px}.cff-visual-header.cff-has-name .cff-header-text{padding-top:30px}.cff-visual-header.cff-has-name.cff-has-about .cff-header-text,.cff-visual-header.cff-has-name.cff-has-cover .cff-header-text{padding-top:10px}#cff .cff-visual-header .cff-header-inner-wrap .cff-bio,.cff-visual-header .cff-header-inner-wrap .cff-bio{display:block;width:100%;clear:both;margin:3px 0 0 0;padding:0;line-height:1.2em}.cff-visual-header .cff-header-name{float:left;padding:0 5px 2px 0}.cff-visual-header .cff-bio-info{font-size:.9em;line-height:1.7}.cff-visual-header .cff-bio-info svg{display:inline-block;width:1em;vertical-align:middle;position:relative;top:-2px}.cff-posts-count svg{padding-right:3px}.cff-header-inner-wrap:after,.cff-header-text:after{display:table;clear:both;content:" "}#cff .cff-less{display:none}#cff.cff-default-styles a{text-decoration:none}#cff.cff-default-styles a:focus,#cff.cff-default-styles a:hover{text-decoration:underline}#cff .cff-post-text-link{display:block}.cff-post-text{width:100%;float:left}#cff .cff-post-desc,#cff h3,#cff h4,#cff h5,#cff h6,#cff p{float:left;width:100%;clear:both;padding:0;margin:5px 0;word-wrap:break-word}#cff.cff-default-styles .cff-post-desc,#cff.cff-default-styles h3,#cff.cff-default-styles h4,#cff.cff-default-styles h5,#cff.cff-default-styles h6,#cff.cff-default-styles p{line-height:1.4}#cff .cff-date{float:left;min-width:50px;width:auto}#cff.cff-default-styles .cff-date{font-size:11px}#cff .cff-author{float:left;clear:both;margin:0 0 15px 0;padding:0;line-height:1.2;width:100%}#cff .cff-author a{text-decoration:none;border:none}#cff .cff-author-img{float:left;width:40px;height:40px;margin:0 0 0 -100%!important;font-size:0;background:#eee;background:url(../img/cff-avatar.png) no-repeat;background-size:100%;border-radius:50%}#cff .cff-author img{float:left;margin:0!important;padding:0!important;border:none!important;font-size:0;border-radius:50%}#cff .cff-author-img.cff-no-consent img{display:none}.cff-no-consent .cff-header-text{margin-left:0!important}.cff-no-consent .cff-header-hero,.cff-no-consent .cff-header-img{display:none!important}#cff .cff-author .cff-author-text span.cff-page-name{display:table-cell;vertical-align:middle;height:40px;margin:0;font-weight:700;padding-left:50px;float:none}#cff .cff-author .cff-story{font-weight:400}#cff.cff-default-styles .cff-author a{text-decoration:none}#cff .cff-author.cff-no-author-info .cff-date{margin-top:12px!important}#cff .cff-author.cff-no-author-info .cff-author-img{width:40px;height:40px;background:url(../img/cff-avatar.png) no-repeat;margin:0!important}#cff .cff-author .cff-author-text{float:left;width:100%}#cff .cff-author .cff-date,#cff .cff-author .cff-page-name{float:left;clear:both;width:auto;margin:0 0 0 50px!important}#cff.cff-default-styles .cff-author .cff-author-text *{font-weight:700;line-height:1.2}#cff .cff-author .cff-date{color:#9197a3;font-size:11px;margin-top:2px!important;margin-bottom:0!important}#cff.cff-default-styles .cff-author .cff-date{font-weight:400}#cff .cff-author .cff-page-name.cff-author-date{float:left;padding:3px 0 0 0;font-size:14px}#cff .cff-cta-link a,.cff-media-link .fa{display:inline-block;width:auto;padding:5px 7px 5px 6px;margin-right:6px;border:1px solid #eee;border:1px solid rgba(0,0,0,.1);border-radius:3px;background:rgba(0,0,0,.02)}#cff .cff-cta-link a:hover,.cff-media-link .fa:hover{background:#f9f9f9;background:rgba(0,0,0,.03);text-decoration:none}#cff .cff-cta-link a{padding:5px 15px}#cff .cff-break-word{word-break:break-all}#cff .cff-expand{display:none}#cff.cff-default-styles .cff-expand a{font-size:11px;font-weight:400}#cff .cff-shared-link{float:left;clear:both;width:100%;padding:5px 10px;margin:10px 0 5px 0;background:#f9f9f9;border:1px solid #d9d9d9;background:rgba(0,0,0,.02);border:1px solid rgba(0,0,0,.07);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-no-styles{background:0 0;border:none;padding:0}#cff .cff-link{float:left;clear:both;max-width:20%;margin:10px 0 0 0}#cff .cff-link img{max-width:100%}#cff .cff-link-title{float:left;clear:both;width:100%;display:block}#cff.cff-default-styles .cff-link-title{font-weight:700}#cff p.cff-link-title{margin:5px 0 0 0}#cff .cff-text-link{float:left;clear:none;width:72%;margin-left:3%;padding:0 0 5px 0}#cff .cff-link-caption{margin:0}#cff.cff-default-styles .cff-link-caption{font-size:12px}#cff .cff-text-link.cff-no-image{width:100%;margin-left:0}#cff .cff-post-desc{margin:5px 0 0 0}#cff .cff-details{float:left;clear:none;width:100%;margin:0;padding:0}#cff .cff-details h5{margin:0 0 5px 0}#cff.cff-default-styles .cff-details h5{padding:0;font-size:16px}#cff.cff-default-styles .cff-details p{font-size:14px}#cff .cff-timeline-event .cff-date,#cff .cff-timeline-event .cff-info,#cff .cff-timeline-event .cff-timeline-event-title,#cff .cff-timeline-event .cff-where{display:block;width:100%;clear:both}#cff .cff-details .cff-info{padding:10px 0 0 0}#cff.cff-default-styles .cff-details .cff-info{line-height:1.2}#cff .cff-desc-wrap{float:left;width:100%}#cff .cff-note-title{display:block;font-weight:700;padding-bottom:5px}#cff .cff-post-links{float:left;clear:none;padding:5px 0 0 0;margin:0}#cff.cff-default-styles .cff-post-links{font-size:11px}#cff .cff-post-links.cff-left{float:left;margin:8px 0}#cff.cff-default-styles .cff-post-links a{font-size:11px}#cff .cff-post-links a:first-child{padding-left:0;margin:0}#cff .cff-dot{padding:0 5px}#cff .cff-share-container{position:relative;display:inline}#cff .cff-share-tooltip{display:none;position:absolute;z-index:1000;bottom:22px;right:-40px;width:110px;padding:3px 5px 4px 5px;margin:0;background:#333;color:#eee;font-size:12px;line-height:1.3;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-share-tooltip .fa-play{position:absolute;font-size:8px;bottom:-6px;left:50%;margin-left:-3px;color:#333}#cff .cff-share-tooltip a .fa,#cff .cff-share-tooltip a svg{font-size:16px;margin:0;padding:5px}#cff .cff-share-tooltip a{display:block;float:left;margin:0!important;padding:0!important;color:#eee!important;opacity:0;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}#cff .cff-share-tooltip a:hover{color:#fff!important}#cff .cff-share-tooltip .cff-facebook-icon:hover{background:#3b5998}#cff .cff-share-tooltip .cff-twitter-icon:hover{background:#00aced}#cff .cff-share-tooltip .cff-google-icon:hover{background:#dd4b39}#cff .cff-share-tooltip .cff-linkedin-icon:hover{background:#007bb6}#cff .cff-share-tooltip .cff-pinterest-icon:hover{background:#cb2027}#cff .cff-share-tooltip .cff-email-icon:hover{background:#dd4b39}#cff .cff-share-tooltip a.cff-show{opacity:1;transition:opacity .2s ease}.cff-likebox{float:left;width:100%;position:relative;margin:20px 0 0 0}.fb_iframe_widget{border:none;overflow:hidden}.cff-likebox .fb_iframe_widget{width:100%}.cff-likebox .fb_iframe_widget span{width:100%!important}.cff-likebox .fb_iframe_widget iframe{margin:0;position:relative;top:0;left:0;width:100%!important;height:100%}.cff-likebox.cff-top.cff-outside{margin-bottom:10px}.cff-likebox.cff-bottom.cff-outside{margin-top:10px}#cff.cff-fixed-height{padding:5px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-error-msg{display:none;position:relative;font-size:12px;font-family:sans-serif;padding:8px 12px;border:1px solid #ddd;margin-bottom:10px;clear:both;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}#cff .cff-error-msg p{float:none}#cff .cff-error-msg .cff_notice_dismiss{position:absolute;top:4px;right:8px}#cff #cff-error-reason{display:none;padding:5px 0 0 0;clear:both}#cff.cff-default-styles .cff-credit{font-size:11px}#cff.cff-default-styles .cff-credit a{text-decoration:none}#cff .cff-credit img{float:left;margin:-2px 5px 0 0}#cff .cff-credit .fa{padding-right:5px;font-size:13px}.cff-credit a{display:flex;align-items:center}.cff-screenreader{text-indent:-9999px!important;display:block!important;width:0!important;height:0!important;line-height:0!important}@media all and (max-width:640px){#cff.cff-width-resp{width:100%!important}.cff-wrapper .cff-visual-header .cff-header-img img{width:80px}.cff-wrapper .cff-visual-header.cff-has-name .cff-header-text{margin-left:95px}.cff-wrapper .cff-visual-header.cff-has-cover.cff-has-name .cff-header-text{margin-left:105px}}#cff .cff-comment .cff-comment-text img,#cff img.emoji,#cff-lightbox-wrapper .cff-comment .cff-comment-text img,#cff-lightbox-wrapper img.emoji{float:none;max-width:100%}#cff .cff-linebreak{display:block;height:5px}#cff.cff-masonry .cff-item.cff-box{margin-left:1.5%;margin-right:1.5%}#cff.cff-masonry{box-sizing:border-box}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-item:first-child{padding-top:20px;margin-top:0}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox{float:none;display:inline-block;width:30.3%;margin:0 1.5%;margin-bottom:20px}#cff.cff-masonry.cff-opaque-comments .cff-item{z-index:1}#cff.cff-masonry.masonry-2-desktop .cff-item{width:47%;margin:0 1.5%}#cff.cff-masonry.masonry-4-desktop .cff-item{width:22%;margin:0 1.5%}#cff.cff-masonry.masonry-5-desktop .cff-item{width:17%;margin:0 1.5%}#cff.cff-masonry.masonry-6-desktop .cff-item{width:13.516%;margin:0 1.5%}#cff.cff-masonry .cff-comments-box{position:relative;z-index:999}#cff.cff-masonry .cff-comment-attachment,#cff.cff-masonry .cff-comment-replies-box{max-width:100%}#cff.cff-masonry .cff-load-more{display:block;float:left;clear:both}@media (max-width:780px){#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox,#cff.cff-masonry.masonry-2-desktop .cff-item,#cff.cff-masonry.masonry-4-desktop .cff-item,#cff.cff-masonry.masonry-5-desktop .cff-item,#cff.cff-masonry.masonry-6-desktop .cff-item{width:100%;margin:0}#cff.cff-masonry.masonry-2-mobile .cff-item{width:47%;margin-left:1.5%;margin-right:1.5%}}#cff.cff-masonry.cff-masonry-css{width:100%;overflow:hidden;margin-bottom:20px}#cff.cff-masonry.cff-masonry-css{-webkit-column-gap:20px;-moz-column-gap:20px;column-gap:20px;-webkit-column-fill:auto;column-fill:unset;-webkit-column-count:3;-moz-column-count:3;column-count:3;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-desktop{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-4-desktop{-webkit-column-count:4;-moz-column-count:4;column-count:4;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-5-desktop{-webkit-column-count:5;-moz-column-count:5;column-count:5;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:6;-moz-column-count:6;column-count:6;margin:0}#cff.cff-masonry.cff-masonry-css .cff-item,#cff.cff-masonry.cff-masonry-css .cff-likebox,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop .cff-item{float:none;display:inline-block;width:100%;margin:0 0 12px 0}#cff.cff-masonry.cff-masonry-css .cff-likebox{width:99.5%}#cff.cff-masonry.cff-masonry-css .cff-load-more{margin:0 0 10px 0;position:relative;bottom:0}@media only screen and (max-width:780px){#cff.cff-masonry.cff-masonry-css,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:1;-moz-column-count:1;column-count:1}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile,#cff.cff-masonry.cff-masonry-css.masonry-2-mobile .cff-item{width:100%}}#cff.cff-disable-masonry{height:auto!important}#cff.cff-disable-masonry .cff-item,#cff.cff-disable-masonry .cff-likebox{position:relative!important;top:auto!important}.cff-num-diff-hide{display:none!important}.cff-gdpr-notice{max-width:100%;box-sizing:border-box;padding:8px 15px;margin:0;font-size:12px;background:#fdf7f7;display:inline-block;border-radius:5px;border:1px solid #e4b1b1;line-height:1.3;display:none}
assets/js/cff-scripts.js CHANGED
@@ -441,6 +441,41 @@ if(!cff_js_exists){
441
  }
442
  }
443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  jQuery(document).ready(function(){
445
  var $ = jQuery;
446
  $('#cookie-notice a').on('click', function() {
@@ -496,6 +531,17 @@ if(!cff_js_exists){
496
  afterConsentToggled( true, jQuery(this) );
497
  });
498
  });
 
 
 
 
 
 
 
 
 
 
 
499
  })
500
 
501
  } //End cff_js_exists check
441
  }
442
  }
443
 
444
+ //Feed Locator Script
445
+ function cffGetFeedLocatorDataArray(){
446
+ var feedLocatorData = [];
447
+ jQuery('.cff-list-container').each(function(){
448
+ $cffPagUrl = jQuery(this).find('.cff-pag-url');
449
+ var singleFeedLocatorData = {
450
+ feedID : $cffPagUrl.attr('data-feed-id'),
451
+ postID : $cffPagUrl.attr('data-post-id'),
452
+ shortCodeAtts : jQuery.trim($cffPagUrl.attr('data-cff-shortcode')) == '' ? null : JSON.parse($cffPagUrl.attr('data-cff-shortcode')),
453
+ location : locationGuess(jQuery(this))
454
+ };
455
+ feedLocatorData.push(singleFeedLocatorData);
456
+ });
457
+ return feedLocatorData;
458
+ }
459
+
460
+ function locationGuess($cff = false) {
461
+ var $feed = ($cff == false) ? jQuery(this.el) : $cff,
462
+ location = 'content';
463
+
464
+ if ($feed.closest('footer').length) {
465
+ location = 'footer';
466
+ } else if ($feed.closest('.header').length
467
+ || $feed.closest('header').length) {
468
+ location = 'header';
469
+ } else if ($feed.closest('.sidebar').length
470
+ || $feed.closest('aside').length) {
471
+ location = 'sidebar';
472
+ }
473
+
474
+ return location;
475
+ }
476
+
477
+
478
+
479
  jQuery(document).ready(function(){
480
  var $ = jQuery;
481
  $('#cookie-notice a').on('click', function() {
531
  afterConsentToggled( true, jQuery(this) );
532
  });
533
  });
534
+ if( $('.cff-list-container').length ){
535
+ var feedLocatorData = cffGetFeedLocatorDataArray();
536
+ $.ajax({
537
+ url: cffajaxurl,
538
+ type: 'POST',
539
+ data:{
540
+ action: 'feed_locator',
541
+ feedLocatorData : feedLocatorData
542
+ }
543
+ });
544
+ }
545
  })
546
 
547
  } //End cff_js_exists check
assets/js/cff-scripts.min.js CHANGED
@@ -1 +1 @@
1
- var cff_js_exists=void 0!==cff_js_exists;function cffAddMasonry(t){780<jQuery(window).width()||t.hasClass("masonry-2-mobile")?(t.addClass("cff-masonry cff-masonry-js").removeClass("cff-disable-masonry"),t.find(".cff-item").length?(t.masonry({itemSelector:".cff-new, .cff-item, .cff-likebox"}),t.find(".cff-item").each(function(){jQuery(this).css("margin-bottom","15px")})):t.find(".cff-album-item").length&&t.masonry({itemSelector:".cff-album-item"})):t.addClass("cff-disable-masonry")}function cff_init(){function t(){jQuery(".cff-visual-header.cff-has-cover").each(function(){var t=jQuery(this).find(".cff-header-hero").innerHeight(),e=jQuery(this).find(".cff-header-hero img").innerHeight(),i=jQuery(this).find(".cff-header-hero").innerWidth(),n=jQuery(this).find(".cff-header-hero img").innerWidth()/e,o=i/t<n?t*n+"px":"100%",e=e-t,e=Math.max(0,Math.round(e/2)),i="100%"!=o?Math.max(0,Math.round((t*n-i)/2)):0;jQuery(this).find(".cff-header-hero img").css({opacity:1,display:"block",visibility:"visible","max-width":"none","max-height":"none","margin-top":-e+"px","margin-left":-i+"px",width:o})})}jQuery("#cff .cff-item").each(function(){var u=jQuery(this);u.find(".cff-viewpost-facebook").parent("p").length&&u.find(".cff-viewpost-facebook").unwrap("p"),u.find(".cff-author").parent("p").length&&(u.find(".cff-author").eq(1).unwrap("p"),u.find(".cff-author").eq(1).remove()),u.find("#cff .cff-link").parent("p").length&&u.find("#cff .cff-link").unwrap("p");var i=!1,n=u.find(".cff-post-text .cff-text"),t=u.closest("#cff").attr("data-char");void 0!==t&&""!=t||(t=99999),n.find("a.cff-post-text-link").length&&(n=u.find(".cff-post-text .cff-text a"));var o=n.html();null==o&&(o="");var e=new RegExp(/(<[^>]*>)/g),r=0;full_text_arr=o.split(e);for(var s,a=0,f=full_text_arr.length;a<f;a++)e.test(full_text_arr[a])||(r!=t?t<(r+=full_text_arr[a].length)&&(s=r-t,full_text_arr[a]=full_text_arr[a].slice(0,-s),r=t,o.length>t&&u.find(".cff-expand").show()):full_text_arr.splice(a,1));var h=full_text_arr.join("");function c(){var t,e=u.find(".cff-text").html(),i=u.find(".cff-post-desc").html(),n=/(^|\s)#(\w*[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]+\w*)/gi,o=u.find(".cff-text").attr("data-color");function r(t){t=jQuery.trim(t);return/^#[0-9A-F]{6}$/i.test(t)?t:' <a href="https://www.facebook.com/hashtag/'+t.substring(1)+'" target="_blank" rel="nofollow" style="color:#'+o+'">'+t+"</a>"}"undefined"==typeof cfflinkhashtags&&(cfflinkhashtags="true"),"true"!=cfflinkhashtags||0<(t=u.find(".cff-text")).length&&(e=e.replace(/<br>/g,"<br> "),t.html(e.replace(n,r))),0<u.find(".cff-post-desc").length&&u.find(".cff-post-desc").html(i.replace(n,r))}"<"==(h=h.replace(/(<(?!\/)[^>]+>)+(<\/[^>]+>)/g,"")).substr(h.length-1)&&(h=h.substring(0,h.length-1)),h=(h=h.replace(/(<br>\s*)+$/,"")).replace(/(<img class="cff-linebreak">\s*)+$/,""),n.html(h),u.find(".cff-expand a").on("click",function(t){t.preventDefault();var e=jQuery(this),t=e.find(".cff-more"),e=e.find(".cff-less");0==i?(n.html(o),i=!0,t.hide(),e.show()):(n.html(h),i=!1,t.show(),e.hide()),c(),n.find("a").attr("target","_blank"),u.closest(".cff").hasClass("cff-masonry-js")&&!u.closest(".cff").hasClass("cff-masonry-css")&&cffAddMasonry(u.closest(".cff"))}),n.find("a").add(u.find(".cff-post-desc a")).attr({target:"_blank",rel:"nofollow"}),$sharedLink=u.find(".cff-shared-link"),""==$sharedLink.text()&&$sharedLink.remove(),c(),u.find(".cff-text a").add(u.find(".cff-post-desc a")).attr({target:"_blank",rel:"nofollow noopener noreferrer"}),u.find(".cff-share-link").on("click",function(t){t.preventDefault();var e,t=u.find(".cff-share-tooltip");t.is(":visible")?t.hide().find("a").removeClass("cff-show"):(t.show(),e=0,t.find("a").each(function(){var t=jQuery(this);setTimeout(function(){t.addClass("cff-show")},e),e+=20}))})}),jQuery(".cff-wrapper").each(function(){var t,e,i,n=jQuery(this).find("#cff"),o=jQuery(this);setTimeout(function(){checkConsent(o)?addFullFeatures(o):(jQuery(".cff-gdpr-notice").css({display:"inline-block"}),o.find(".cff-visual-header").length&&o.find(".cff-header-text").closest(".cff-visual-header").addClass("cff-no-consent"))},250),void 0!==n.attr("data-nummobile")&&(t=void 0!==n.attr("data-pag-num")&&""!==n.attr("data-pag-num")?parseInt(n.attr("data-pag-num")):1,e=void 0!==n.attr("data-nummobile")&&""!==n.attr("data-nummobile")?parseInt(n.attr("data-nummobile")):t,i=n.find(".cff-item").length?".cff-item":".cff-album-item",jQuery(window).width()<480?e<n.find(i).length&&n.find(i).slice(e-n.find(i).length).addClass("cff-num-diff-hide"):t<n.find(i).length&&n.find(i).slice(t-n.find(i).length).addClass("cff-num-diff-hide"),n.removeAttr("data-nummobile")),n.hasClass("cff-masonry-js")&&(cffAddMasonry(n),setTimeout(function(){cffAddMasonry(n)},500),jQuery(window).on("resize",function(){setTimeout(function(){cffAddMasonry(n)},500)}),n.find(".cff-credit").length&&n.css("padding-bottom",30))}),setTimeout(t,200),jQuery(window).on("resize",function(){setTimeout(function(){t()},500)})}function checkConsent(t){var e=void 0!==(t=t.find(".cff-list-container")).attr("data-cff-flags")?t.attr("data-cff-flags").split(","):[],t=-1<e.indexOf("gdpr"),e=(e.indexOf("overrideBlockCDN"),!1);return!(!e&&t)||("undefined"!=typeof CLI_Cookie?null!==CLI_Cookie.read(CLI_ACCEPT_COOKIE_NAME)&&(e="yes"===CLI_Cookie.read("cookielawinfo-checkbox-non-necessary")):void 0!==window.cnArgs?2===(t=("; "+document.cookie).split("; cookie_notice_accepted=")).length&&(e="true"===t.pop().split(";").shift()):void 0!==window.cookieconsent?e="allow"===cffCmplzGetCookie("complianz_consent_status"):void 0!==window.Cookiebot?e=Cookiebot.consented:void 0!==window.BorlabsCookie&&(e=window.BorlabsCookie.checkCookieConsent("facebook")),e)}function cffCmplzGetCookie(t){for(var e=t+"=",i=window.document.cookie.split(";"),n=0;n<i.length;n++){var o=i[n].trim();if(0==o.indexOf(e))return o.substring(e.length,o.length)}return""}function addFullFeatures(t){t=jQuery(t),jQuery(".cff-gdpr-notice").remove(),t.find(".cff-author-img").each(function(){jQuery(this).find("img").attr("src",jQuery(this).attr("data-avatar")),jQuery(this).removeClass("cff-no-consent")}),t.find(".cff-likebox iframe").each(function(){var t=jQuery(this),e=t.attr("data-likebox-width"),i=t.parent().width();""==e&&(e=340),i<e&&(e=i),t.attr("src","https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2F"+t.attr("data-likebox-id")+"%2F&tabs&width="+Math.floor(e)+"&small_header="+t.attr("data-likebox-header")+"&adapt_container_width=true&hide_cover="+t.attr("data-hide-cover")+"&hide_cta="+t.attr("data-hide-cta")+"&show_facepile="+t.attr("data-likebox-faces")+"&locale="+t.attr("data-locale"))}),jQuery(".cff-visual-header").length&&jQuery(".cff-visual-header").each(function(){jQuery(this).removeClass("cff-no-consent"),jQuery(this).find(".cff-header-hero").length&&jQuery(this).find(".cff-header-hero").find("img").attr("src",jQuery(this).find(".cff-header-hero").find("img").attr("data-cover-url")),jQuery(this).find(".cff-header-img").length&&jQuery(this).find(".cff-header-img").find("img").attr("src",jQuery(this).find(".cff-header-img").find("img").attr("data-avatar"))})}function afterConsentToggled(t,e){t&&addFullFeatures(e)}cff_js_exists||(jQuery("#cff.cff-masonry-js").length&&(function(t){function e(){}function i(s){if(s){var a="undefined"==typeof console?e:function(t){console.error(t)};return s.bridget=function(t,e){var r,u,i;(i=e).prototype.option||(i.prototype.option=function(t){s.isPlainObject(t)&&(this.options=s.extend(!0,this.options,t))}),r=t,u=e,s.fn[r]=function(e){if("string"!=typeof e)return this.each(function(){var t=s.data(this,r);t?(t.option(e),t._init()):(t=new u(this,e),s.data(this,r,t))});for(var t=f.call(arguments,1),i=0,n=this.length;i<n;i++){var o=this[i],o=s.data(o,r);if(o)if(s.isFunction(o[e])&&"_"!==e.charAt(0)){o=o[e].apply(o,t);if(void 0!==o)return o}else a("no such method '"+e+"' for "+r+" instance");else a("cannot call methods on "+r+" prior to initialization; attempted to call '"+e+"'")}return this}},s.bridget}}var f=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):i("object"==typeof exports?require("jquery"):t.jQuery)}(window),function(i){function n(t){var e=i.event;return e.target=e.target||e.srcElement||t,e}var t=document.documentElement,e=function(){};t.addEventListener?e=function(t,e,i){t.addEventListener(e,i,!1)}:t.attachEvent&&(e=function(e,t,i){e[t+i]=i.handleEvent?function(){var t=n(e);i.handleEvent.call(i,t)}:function(){var t=n(e);i.call(e,t)},e.attachEvent("on"+t,e[t+i])});var o=function(){};t.removeEventListener?o=function(t,e,i){t.removeEventListener(e,i,!1)}:t.detachEvent&&(o=function(e,i,n){e.detachEvent("on"+i,e[i+n]);try{delete e[i+n]}catch(t){e[i+n]=void 0}}),o={bind:e,unbind:o},"function"==typeof define&&define.amd?define("eventie/eventie",o):"object"==typeof exports?module.exports=o:i.eventie=o}(window),function(){function t(){}function r(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function e(t){return function(){return this[t].apply(this,arguments)}}var i=t.prototype,n=this,o=n.EventEmitter;i.getListeners=function(t){var e,i,n=this._getEvents();if(t instanceof RegExp)for(i in e={},n)n.hasOwnProperty(i)&&t.test(i)&&(e[i]=n[i]);else e=n[t]||(n[t]=[]);return e},i.flattenListeners=function(t){for(var e=[],i=0;i<t.length;i+=1)e.push(t[i].listener);return e},i.getListenersAsObject=function(t){var e,i=this.getListeners(t);return i instanceof Array&&((e={})[t]=i),e||i},i.addListener=function(t,e){var i,n=this.getListenersAsObject(t),o="object"==typeof e;for(i in n)n.hasOwnProperty(i)&&-1===r(n[i],e)&&n[i].push(o?e:{listener:e,once:!1});return this},i.on=e("addListener"),i.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},i.once=e("addOnceListener"),i.defineEvent=function(t){return this.getListeners(t),this},i.defineEvents=function(t){for(var e=0;e<t.length;e+=1)this.defineEvent(t[e]);return this},i.removeListener=function(t,e){var i,n,o=this.getListenersAsObject(t);for(n in o)o.hasOwnProperty(n)&&(i=r(o[n],e),-1!==i&&o[n].splice(i,1));return this},i.off=e("removeListener"),i.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},i.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},i.manipulateListeners=function(t,e,i){var n,o,r=t?this.removeListener:this.addListener,u=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(n=i.length;n--;)r.call(this,e,i[n]);else for(n in e)e.hasOwnProperty(n)&&(o=e[n])&&("function"==typeof o?r:u).call(this,n,o);return this},i.removeEvent=function(t){var e,i=typeof t,n=this._getEvents();if("string"==i)delete n[t];else if(t instanceof RegExp)for(e in n)n.hasOwnProperty(e)&&t.test(e)&&delete n[e];else delete this._events;return this},i.removeAllListeners=e("removeEvent"),i.emitEvent=function(t,e){var i,n,o,r,u=this.getListenersAsObject(t);for(o in u)if(u.hasOwnProperty(o))for(n=u[o].length;n--;)i=u[o][n],!0===i.once&&this.removeListener(t,i.listener),r=i.listener.apply(this,e||[]),r===this._getOnceReturnValue()&&this.removeListener(t,i.listener);return this},i.trigger=e("emitEvent"),i.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},i.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},i._getOnceReturnValue=function(){return!this.hasOwnProperty("_onceReturnValue")||this._onceReturnValue},i._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return n.EventEmitter=o,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof r[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,i=0,n=o.length;i<n;i++)if(e=o[i]+t,"string"==typeof r[e])return e}}var o="Webkit Moz ms Ms O".split(" "),r=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(E){function B(t){var e=parseFloat(t);return-1===t.indexOf("%")&&!isNaN(e)&&e}function t(g){var v,A,C,F=!1;return function(t){if(F||(F=!0,m=E.getComputedStyle,y=m?function(t){return m(t,null)}:function(t){return t.currentStyle},v=function(t){t=y(t);return t||D("Style returned "+t+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),t},(A=g("boxSizing"))&&((p=document.createElement("div")).style.width="200px",p.style.padding="1px 2px 3px 4px",p.style.borderStyle="solid",p.style.borderWidth="1px 2px 3px 4px",p.style[A]="border-box",(l=document.body||document.documentElement).appendChild(p),d=v(p),C=200===B(d.width),l.removeChild(p))),"string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var e=v(t);if("none"===e.display)return function(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=b.length;e<i;e++)t[b[e]]=0;return t}();var i={};i.width=t.offsetWidth,i.height=t.offsetHeight;for(var n=i.isBorderBox=!(!A||!e[A]||"border-box"!==e[A]),o=0,r=b.length;o<r;o++){var u=b[o],s=function(t,e){if(E.getComputedStyle||-1===e.indexOf("%"))return e;var i=t.style,n=i.left,o=t.runtimeStyle,r=o&&o.left;return r&&(o.left=t.currentStyle.left),i.left=e,e=i.pixelLeft,i.left=n,r&&(o.left=r),e}(t,s=e[u]),s=parseFloat(s);i[u]=isNaN(s)?0:s}var a=i.paddingLeft+i.paddingRight,f=i.paddingTop+i.paddingBottom,h=i.marginLeft+i.marginRight,c=i.marginTop+i.marginBottom,d=i.borderLeftWidth+i.borderRightWidth,l=i.borderTopWidth+i.borderBottomWidth,p=n&&C,n=B(e.width);!1!==n&&(i.width=n+(p?0:a+d));n=B(e.height);return!1!==n&&(i.height=n+(p?0:f+l)),i.innerWidth=i.width-(a+d),i.innerHeight=i.height-(f+l),i.outerWidth=i.width+h,i.outerHeight=i.height+c,i}var m,p,l,d,y}}var D="undefined"==typeof console?function(){}:function(t){console.error(t)},b=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],t):"object"==typeof exports?module.exports=t(require("desandro-get-style-property")):E.getSize=t(E.getStyleProperty)}(window),function(e){function i(t){"function"==typeof t&&(i.isReady?t():u.push(t))}function n(t){t="readystatechange"===t.type&&"complete"!==r.readyState;i.isReady||t||o()}function o(){i.isReady=!0;for(var t=0,e=u.length;t<e;t++)(0,u[t])()}function t(t){return"complete"===r.readyState?o():(t.bind(r,"DOMContentLoaded",n),t.bind(r,"readystatechange",n),t.bind(e,"load",n)),i}var r=e.document,u=[];i.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],t):"object"==typeof exports?module.exports=t(require("eventie")):e.docReady=t(e.eventie)}(window),function(o){function i(t,e){return t[n](e)}function r(t){t.parentNode||document.createDocumentFragment().appendChild(t)}var t,n=function(){if(o.matches)return"matches";if(o.matchesSelector)return"matchesSelector";for(var t=["webkit","moz","ms","o"],e=0,i=t.length;e<i;e++){var n=t[e]+"MatchesSelector";if(o[n])return n}}();t=n?i(document.createElement("div"),"div")?i:function(t,e){return r(t),i(t,e)}:function(t,e){r(t);for(var i=t.parentNode.querySelectorAll(e),n=0,o=i.length;n<o;n++)if(i[n]===t)return!0;return!1},"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return t}):"object"==typeof exports?module.exports=t:window.matchesSelector=t}(Element.prototype),function(i,n){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["doc-ready/doc-ready","matches-selector/matches-selector"],function(t,e){return n(i,t,e)}):"object"==typeof exports?module.exports=n(i,require("doc-ready"),require("desandro-matches-selector")):i.fizzyUIUtils=n(i,i.docReady,i.matchesSelector)}(window,function(d,t,f){var i,l={extend:function(t,e){for(var i in e)t[i]=e[i];return t},modulo:function(t,e){return(t%e+e)%e}},e=Object.prototype.toString;l.isArray=function(t){return"[object Array]"==e.call(t)},l.makeArray=function(t){var e=[];if(l.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0,n=t.length;i<n;i++)e.push(t[i]);else e.push(t);return e},l.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,n=t.length;i<n;i++)if(t[i]===e)return i;return-1},l.removeFrom=function(t,e){e=l.indexOf(t,e);-1!=e&&t.splice(e,1)},l.isElement="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(t){return t instanceof HTMLElement}:function(t){return t&&"object"==typeof t&&1==t.nodeType&&"string"==typeof t.nodeName},l.setText=function(t,e){t[i=i||(void 0!==document.documentElement.textContent?"textContent":"innerText")]=e},l.getParent=function(t,e){for(;t!=document.body;)if(t=t.parentNode,f(t,e))return t},l.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},l.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},l.filterFindElements=function(t,e){for(var i=[],n=0,o=(t=l.makeArray(t)).length;n<o;n++){var r=t[n];if(l.isElement(r))if(e){f(r,e)&&i.push(r);for(var u=r.querySelectorAll(e),s=0,a=u.length;s<a;s++)i.push(u[s])}else i.push(r)}return i},l.debounceMethod=function(t,e,n){var o=t.prototype[e],r=e+"Timeout";t.prototype[e]=function(){var t=this[r];t&&clearTimeout(t);var e=arguments,i=this;this[r]=setTimeout(function(){o.apply(i,e),delete i[r]},n||100)}},l.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var p=d.console;return l.htmlInit=function(h,c){t(function(){for(var t=l.toDashed(c),e=document.querySelectorAll(".js-"+t),i="data-"+t+"-options",n=0,o=e.length;n<o;n++){var r,u=e[n],s=u.getAttribute(i);try{r=s&&JSON.parse(s)}catch(t){p&&p.error("Error parsing "+i+" on "+u.nodeName.toLowerCase()+(u.id?"#"+u.id:"")+": "+t);continue}var a=new h(u,r),f=d.jQuery;f&&f.data(u,c,a)}})},l}),function(o,r){"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property","fizzy-ui-utils/utils"],function(t,e,i,n){return r(o,t,e,i,n)}):"object"==typeof exports?module.exports=r(o,require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property"),require("fizzy-ui-utils")):(o.Outlayer={},o.Outlayer.Item=r(o,o.EventEmitter,o.getSize,o.getStyleProperty,o.fizzyUIUtils))}(window,function(t,e,i,r,n){function o(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}var u=t.getComputedStyle,s=u?function(t){return u(t,null)}:function(t){return t.currentStyle},a=r("transition"),f=r("transform"),h=a&&f,t=!!r("perspective"),c={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[a],d=["transform","transition","transitionDuration","transitionProperty"],l=function(){for(var t={},e=0,i=d.length;e<i;e++){var n=d[e],o=r(n);o&&o!==n&&(t[n]=o)}return t}();n.extend(o.prototype,e.prototype),o.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},o.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},o.prototype.getSize=function(){this.size=i(this.element)},o.prototype.css=function(t){var e,i=this.element.style;for(e in t)i[l[e]||e]=t[e]},o.prototype.getPosition=function(){var t=s(this.element),e=this.layout.options,i=e.isOriginLeft,n=e.isOriginTop,o=parseInt(t[i?"left":"right"],10),e=parseInt(t[n?"top":"bottom"],10),o=isNaN(o)?0:o,e=isNaN(e)?0:e,t=this.layout.size;o-=i?t.paddingLeft:t.paddingRight,e-=n?t.paddingTop:t.paddingBottom,this.position.x=o,this.position.y=e},o.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={},n=e.isOriginLeft?"paddingLeft":"paddingRight",o=e.isOriginLeft?"left":"right",r=e.isOriginLeft?"right":"left",n=this.position.x+t[n],n=e.percentPosition&&!e.isHorizontal?n/t.width*100+"%":n+"px";i[o]=n,i[r]="";o=e.isOriginTop?"paddingTop":"paddingBottom",n=e.isOriginTop?"top":"bottom",r=e.isOriginTop?"bottom":"top",o=this.position.y+t[o],o=e.percentPosition&&e.isHorizontal?o/t.height*100+"%":o+"px";i[n]=o,i[r]="",this.css(i),this.emitEvent("layout",[this])};var p=t?function(t,e){return"translate3d("+t+"px, "+e+"px, 0)"}:function(t,e){return"translate("+t+"px, "+e+"px)"};o.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),r=parseInt(e,10),r=o===this.position.x&&r===this.position.y;this.setPosition(t,e),!r||this.isTransitioning?(t-=i,i=e-n,e={},t=(n=this.layout.options).isOriginLeft?t:-t,i=n.isOriginTop?i:-i,e.transform=p(t,i),this.transition({to:e,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})):this.layoutPosition()},o.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},o.prototype.moveTo=h?o.prototype._transitionTo:o.prototype.goTo,o.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},o.prototype._nonTransition=function(t){for(var e in this.css(t.to),t.isCleaning&&this._removeStyles(t.to),t.onTransitionEnd)t.onTransitionEnd[e].call(this)},o.prototype._transition=function(t){if(parseFloat(this.layout.options.transitionDuration)){var e,i=this._transn;for(e in t.onTransitionEnd)i.onEnd[e]=t.onTransitionEnd[e];for(e in t.to)i.ingProperties[e]=!0,t.isCleaning&&(i.clean[e]=!0);t.from&&(this.css(t.from),this.element.offsetHeight,0),this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0}else this._nonTransition(t)};var m=f&&n.toDashed(f)+",opacity";o.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:m,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(c,this,!1))},o.prototype.transition=o.prototype[a?"_transition":"_nonTransition"],o.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},o.prototype.onotransitionend=function(t){this.ontransitionend(t)};var y={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};o.prototype.ontransitionend=function(t){var e,i;t.target===this.element&&(e=this._transn,i=y[t.propertyName]||t.propertyName,delete e.ingProperties[i],function(t){for(var e in t)return;return 1}(e.ingProperties)&&this.disableTransition(),i in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[i]),i in e.onEnd&&(e.onEnd[i].call(this),delete e.onEnd[i]),this.emitEvent("transitionEnd",[this]))},o.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(c,this,!1),this.isTransitioning=!1},o.prototype._removeStyles=function(t){var e,i={};for(e in t)i[e]="";this.css(i)};var g={transitionProperty:"",transitionDuration:""};return o.prototype.removeTransitionStyles=function(){this.css(g)},o.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},o.prototype.remove=function(){var t;a&&parseFloat(this.layout.options.transitionDuration)?((t=this).once("transitionEnd",function(){t.removeElem()}),this.hide()):this.removeElem()},o.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={};e[this.getHideRevealTransitionEndProperty("visibleStyle")]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},o.prototype.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},o.prototype.getHideRevealTransitionEndProperty=function(t){var e,t=this.layout.options[t];if(t.opacity)return"opacity";for(e in t)return e},o.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={};e[this.getHideRevealTransitionEndProperty("hiddenStyle")]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},o.prototype.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},o.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},o}),function(r,u){"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","eventEmitter/EventEmitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(t,e,i,n,o){return u(r,t,e,i,n,o)}):"object"==typeof exports?module.exports=u(r,require("eventie"),require("wolfy87-eventemitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):r.Outlayer=u(r,r.eventie,r.EventEmitter,r.getSize,r.fizzyUIUtils,r.Outlayer.Item)}(window,function(t,e,i,o,r,n){function u(t,e){var i=r.getQueryElement(t);i?(this.element=i,f&&(this.$element=f(this.element)),this.options=r.extend({},this.constructor.defaults),this.option(e),e=++h,this.element.outlayerGUID=e,(c[e]=this)._create(),this.options.isInitLayout&&this.layout()):a&&a.error("Bad element for "+this.constructor.namespace+": "+(i||t))}function s(){}var a=t.console,f=t.jQuery,h=0,c={};return u.namespace="outlayer",u.Item=n,u.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},r.extend(u.prototype,i.prototype),u.prototype.option=function(t){r.extend(this.options,t)},u.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),r.extend(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},u.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},u.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0,r=e.length;o<r;o++){var u=new i(e[o],this);n.push(u)}return n},u.prototype._filterFindItemElements=function(t){return r.filterFindElements(t,this.options.itemSelector)},u.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;e<i;e++)t.push(this.items[e].element);return t},u.prototype._init=u.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},u.prototype._resetLayout=function(){this.getSize()},u.prototype.getSize=function(){this.size=o(this.element)},u.prototype._getMeasurement=function(t,e){var i,n=this.options[t];n?("string"==typeof n?i=this.element.querySelector(n):r.isElement(n)&&(i=n),this[t]=i?o(i)[e]:n):this[t]=0},u.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},u.prototype._getItemsForLayout=function(t){for(var e=[],i=0,n=t.length;i<n;i++){var o=t[i];o.isIgnored||e.push(o)}return e},u.prototype._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){for(var i=[],n=0,o=t.length;n<o;n++){var r=t[n],u=this._getItemLayoutPosition(r);u.item=r,u.isInstant=e||r.isLayoutInstant,i.push(u)}this._processLayoutQueue(i)}},u.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},u.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;e<i;e++){var n=t[e];this._positionItem(n.item,n.x,n.y,n.isInstant)}},u.prototype._positionItem=function(t,e,i,n){n?t.goTo(e,i):t.moveTo(e,i)},u.prototype._postLayout=function(){this.resizeContainer()},u.prototype.resizeContainer=function(){var t;!this.options.isResizingContainer||(t=this._getContainerSize())&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))},u.prototype._getContainerSize=s,u.prototype._setContainerMeasure=function(t,e){var i;void 0!==t&&((i=this.size).isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px")},u.prototype._emitCompleteOnItems=function(t,e){function i(){o.emitEvent(t+"Complete",[e])}function n(){++u===r&&i()}var o=this,r=e.length;if(e&&r)for(var u=0,s=0,a=e.length;s<a;s++)e[s].once(t,n);else i()},u.prototype.ignore=function(t){t=this.getItem(t);t&&(t.isIgnored=!0)},u.prototype.unignore=function(t){t=this.getItem(t);t&&delete t.isIgnored},u.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;e<i;e++){var n=t[e];this.ignore(n)}}},u.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;e<i;e++){var n=t[e];r.removeFrom(this.stamps,n),this.unignore(n)}},u.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=r.makeArray(t)):void 0},u.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var t=0,e=this.stamps.length;t<e;t++){var i=this.stamps[t];this._manageStamp(i)}}},u.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},u.prototype._manageStamp=s,u.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,t=o(t);return{left:e.left-i.left-t.marginLeft,top:e.top-i.top-t.marginTop,right:i.right-e.right-t.marginRight,bottom:i.bottom-e.bottom-t.marginBottom}},u.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},u.prototype.bindResize=function(){this.isResizeBound||(e.bind(t,"resize",this),this.isResizeBound=!0)},u.prototype.unbindResize=function(){this.isResizeBound&&e.unbind(t,"resize",this),this.isResizeBound=!1},u.prototype.onresize=function(){this.resizeTimeout&&clearTimeout(this.resizeTimeout);var t=this;this.resizeTimeout=setTimeout(function(){t.resize(),delete t.resizeTimeout},100)},u.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},u.prototype.needsResizeLayout=function(){var t=o(this.element);return this.size&&t&&t.innerWidth!==this.size.innerWidth},u.prototype.addItems=function(t){t=this._itemize(t);return t.length&&(this.items=this.items.concat(t)),t},u.prototype.appended=function(t){t=this.addItems(t);t.length&&(this.layoutItems(t,!0),this.reveal(t))},u.prototype.prepended=function(t){var e=this._itemize(t);e.length&&(t=this.items.slice(0),this.items=e.concat(t),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(t))},u.prototype.reveal=function(t){this._emitCompleteOnItems("reveal",t);for(var e=t&&t.length,i=0;e&&i<e;i++)t[i].reveal()},u.prototype.hide=function(t){this._emitCompleteOnItems("hide",t);for(var e=t&&t.length,i=0;e&&i<e;i++)t[i].hide()},u.prototype.revealItemElements=function(t){t=this.getItems(t);this.reveal(t)},u.prototype.hideItemElements=function(t){t=this.getItems(t);this.hide(t)},u.prototype.getItem=function(t){for(var e=0,i=this.items.length;e<i;e++){var n=this.items[e];if(n.element===t)return n}},u.prototype.getItems=function(t){for(var e=[],i=0,n=(t=r.makeArray(t)).length;i<n;i++){var o=t[i],o=this.getItem(o);o&&e.push(o)}return e},u.prototype.remove=function(t){var e=this.getItems(t);if(this._emitCompleteOnItems("remove",e),e&&e.length)for(var i=0,n=e.length;i<n;i++){var o=e[i];o.remove(),r.removeFrom(this.items,o)}},u.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;e<i;e++)this.items[e].destroy();this.unbindResize();t=this.element.outlayerGUID;delete c[t],delete this.element.outlayerGUID,f&&f.removeData(this.element,this.constructor.namespace)},u.data=function(t){t=(t=r.getQueryElement(t))&&t.outlayerGUID;return t&&c[t]},u.create=function(t,e){function i(){u.apply(this,arguments)}return Object.create?i.prototype=Object.create(u.prototype):r.extend(i.prototype,u.prototype),(i.prototype.constructor=i).defaults=r.extend({},u.defaults),r.extend(i.defaults,e),i.prototype.settings={},i.namespace=t,i.data=u.data,(i.Item=function(){n.apply(this,arguments)}).prototype=new n,r.htmlInit(i,t),f&&f.bridget&&f.bridget(t,i),i},u.Item=n,u}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","fizzy-ui-utils/utils"],e):"object"==typeof exports?module.exports=e(require("outlayer"),require("get-size"),require("fizzy-ui-utils")):t.Masonry=e(t.Outlayer,t.getSize,t.fizzyUIUtils)}(window,function(t,s,a){t=t.create("masonry");return t.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},t.prototype.measureColumns=function(){this.getContainerWidth(),this.columnWidth||(i=(e=this.items[0])&&e.element,this.columnWidth=i&&s(i).outerWidth||this.containerWidth);var t=this.columnWidth+=this.gutter,e=this.containerWidth+this.gutter,i=e/t,t=t-e%t,i=Math[t&&t<1?"round":"floor"](i);this.cols=Math.max(i,1)},t.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,t=s(t);this.containerWidth=t&&t.innerWidth},t.prototype._getItemLayoutPosition=function(t){t.getSize();for(var e=t.size.outerWidth%this.columnWidth,i=Math[e&&e<1?"round":"ceil"](t.size.outerWidth/this.columnWidth),i=Math.min(i,this.cols),n=this._getColGroup(i),e=Math.min.apply(Math,n),o=a.indexOf(n,e),i={x:this.columnWidth*o,y:e},r=e+t.size.outerHeight,u=this.cols+1-n.length,s=0;s<u;s++)this.colYs[o+s]=r;return i},t.prototype._getColGroup=function(t){if(t<2)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;n<i;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},t.prototype._manageStamp=function(t){var e=s(t),i=this._getElementOffset(t),n=this.options.isOriginLeft?i.left:i.right,t=n+e.outerWidth,n=Math.floor(n/this.columnWidth),n=Math.max(0,n),o=Math.floor(t/this.columnWidth);o-=t%this.columnWidth?0:1,o=Math.min(this.cols-1,o);for(var r=(this.options.isOriginTop?i.top:i.bottom)+e.outerHeight,u=n;u<=o;u++)this.colYs[u]=Math.max(r,this.colYs[u])},t.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},t.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},t.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},t})),cff_init(),jQuery(document).ready(function(){var t=jQuery;t("#cookie-notice a").on("click",function(){setTimeout(function(){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(checkConsent(jQuery(this)),jQuery(this))})},1e3)}),t("#cookie-law-info-bar a").on("click",function(){setTimeout(function(){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(checkConsent(jQuery(this)),jQuery(this))})},1e3)}),t(".cli-user-preference-checkbox").on("click",function(){setTimeout(function(){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!1,jQuery(this))})},1e3)}),t(window).on("CookiebotOnAccept",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!0,jQuery(this))})}),t(document).on("cmplzAcceptAll",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!0,jQuery(this))})}),t(document).on("cmplzRevoke",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!1,jQuery(this))})}),t(document).on("borlabs-cookie-consent-saved",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!0,jQuery(this))})})}));
1
+ var cff_js_exists=void 0!==cff_js_exists;function cffAddMasonry(t){780<jQuery(window).width()||t.hasClass("masonry-2-mobile")?(t.addClass("cff-masonry cff-masonry-js").removeClass("cff-disable-masonry"),t.find(".cff-item").length?(t.masonry({itemSelector:".cff-new, .cff-item, .cff-likebox"}),t.find(".cff-item").each(function(){jQuery(this).css("margin-bottom","15px")})):t.find(".cff-album-item").length&&t.masonry({itemSelector:".cff-album-item"})):t.addClass("cff-disable-masonry")}function cff_init(){function t(){jQuery(".cff-visual-header.cff-has-cover").each(function(){var t=jQuery(this).find(".cff-header-hero").innerHeight(),e=jQuery(this).find(".cff-header-hero img").innerHeight(),i=jQuery(this).find(".cff-header-hero").innerWidth(),n=jQuery(this).find(".cff-header-hero img").innerWidth()/e,o=i/t<n?t*n+"px":"100%",e=e-t,e=Math.max(0,Math.round(e/2)),i="100%"!=o?Math.max(0,Math.round((t*n-i)/2)):0;jQuery(this).find(".cff-header-hero img").css({opacity:1,display:"block",visibility:"visible","max-width":"none","max-height":"none","margin-top":-e+"px","margin-left":-i+"px",width:o})})}jQuery("#cff .cff-item").each(function(){var u=jQuery(this);u.find(".cff-viewpost-facebook").parent("p").length&&u.find(".cff-viewpost-facebook").unwrap("p"),u.find(".cff-author").parent("p").length&&(u.find(".cff-author").eq(1).unwrap("p"),u.find(".cff-author").eq(1).remove()),u.find("#cff .cff-link").parent("p").length&&u.find("#cff .cff-link").unwrap("p");var i=!1,n=u.find(".cff-post-text .cff-text"),t=u.closest("#cff").attr("data-char");void 0!==t&&""!=t||(t=99999),n.find("a.cff-post-text-link").length&&(n=u.find(".cff-post-text .cff-text a"));var o=n.html();null==o&&(o="");var e=new RegExp(/(<[^>]*>)/g),r=0;full_text_arr=o.split(e);for(var s,a=0,f=full_text_arr.length;a<f;a++)e.test(full_text_arr[a])||(r!=t?t<(r+=full_text_arr[a].length)&&(s=r-t,full_text_arr[a]=full_text_arr[a].slice(0,-s),r=t,o.length>t&&u.find(".cff-expand").show()):full_text_arr.splice(a,1));var c=full_text_arr.join("");function h(){var t,e=u.find(".cff-text").html(),i=u.find(".cff-post-desc").html(),n=/(^|\s)#(\w*[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]+\w*)/gi,o=u.find(".cff-text").attr("data-color");function r(t){t=jQuery.trim(t);return/^#[0-9A-F]{6}$/i.test(t)?t:' <a href="https://www.facebook.com/hashtag/'+t.substring(1)+'" target="_blank" rel="nofollow" style="color:#'+o+'">'+t+"</a>"}"undefined"==typeof cfflinkhashtags&&(cfflinkhashtags="true"),"true"!=cfflinkhashtags||0<(t=u.find(".cff-text")).length&&(e=e.replace(/<br>/g,"<br> "),t.html(e.replace(n,r))),0<u.find(".cff-post-desc").length&&u.find(".cff-post-desc").html(i.replace(n,r))}"<"==(c=c.replace(/(<(?!\/)[^>]+>)+(<\/[^>]+>)/g,"")).substr(c.length-1)&&(c=c.substring(0,c.length-1)),c=(c=c.replace(/(<br>\s*)+$/,"")).replace(/(<img class="cff-linebreak">\s*)+$/,""),n.html(c),u.find(".cff-expand a").on("click",function(t){t.preventDefault();var e=jQuery(this),t=e.find(".cff-more"),e=e.find(".cff-less");0==i?(n.html(o),i=!0,t.hide(),e.show()):(n.html(c),i=!1,t.show(),e.hide()),h(),n.find("a").attr("target","_blank"),u.closest(".cff").hasClass("cff-masonry-js")&&!u.closest(".cff").hasClass("cff-masonry-css")&&cffAddMasonry(u.closest(".cff"))}),n.find("a").add(u.find(".cff-post-desc a")).attr({target:"_blank",rel:"nofollow"}),$sharedLink=u.find(".cff-shared-link"),""==$sharedLink.text()&&$sharedLink.remove(),h(),u.find(".cff-text a").add(u.find(".cff-post-desc a")).attr({target:"_blank",rel:"nofollow noopener noreferrer"}),u.find(".cff-share-link").on("click",function(t){t.preventDefault();var e,t=u.find(".cff-share-tooltip");t.is(":visible")?t.hide().find("a").removeClass("cff-show"):(t.show(),e=0,t.find("a").each(function(){var t=jQuery(this);setTimeout(function(){t.addClass("cff-show")},e),e+=20}))})}),jQuery(".cff-wrapper").each(function(){var t,e,i,n=jQuery(this).find("#cff"),o=jQuery(this);setTimeout(function(){checkConsent(o)?addFullFeatures(o):(jQuery(".cff-gdpr-notice").css({display:"inline-block"}),o.find(".cff-visual-header").length&&o.find(".cff-header-text").closest(".cff-visual-header").addClass("cff-no-consent"))},250),void 0!==n.attr("data-nummobile")&&(t=void 0!==n.attr("data-pag-num")&&""!==n.attr("data-pag-num")?parseInt(n.attr("data-pag-num")):1,e=void 0!==n.attr("data-nummobile")&&""!==n.attr("data-nummobile")?parseInt(n.attr("data-nummobile")):t,i=n.find(".cff-item").length?".cff-item":".cff-album-item",jQuery(window).width()<480?e<n.find(i).length&&n.find(i).slice(e-n.find(i).length).addClass("cff-num-diff-hide"):t<n.find(i).length&&n.find(i).slice(t-n.find(i).length).addClass("cff-num-diff-hide"),n.removeAttr("data-nummobile")),n.hasClass("cff-masonry-js")&&(cffAddMasonry(n),setTimeout(function(){cffAddMasonry(n)},500),jQuery(window).on("resize",function(){setTimeout(function(){cffAddMasonry(n)},500)}),n.find(".cff-credit").length&&n.css("padding-bottom",30))}),setTimeout(t,200),jQuery(window).on("resize",function(){setTimeout(function(){t()},500)})}function checkConsent(t){var e=void 0!==(t=t.find(".cff-list-container")).attr("data-cff-flags")?t.attr("data-cff-flags").split(","):[],t=-1<e.indexOf("gdpr"),e=(e.indexOf("overrideBlockCDN"),!1);return!(!e&&t)||("undefined"!=typeof CLI_Cookie?null!==CLI_Cookie.read(CLI_ACCEPT_COOKIE_NAME)&&(e="yes"===CLI_Cookie.read("cookielawinfo-checkbox-non-necessary")):void 0!==window.cnArgs?2===(t=("; "+document.cookie).split("; cookie_notice_accepted=")).length&&(e="true"===t.pop().split(";").shift()):void 0!==window.cookieconsent?e="allow"===cffCmplzGetCookie("complianz_consent_status"):void 0!==window.Cookiebot?e=Cookiebot.consented:void 0!==window.BorlabsCookie&&(e=window.BorlabsCookie.checkCookieConsent("facebook")),e)}function cffCmplzGetCookie(t){for(var e=t+"=",i=window.document.cookie.split(";"),n=0;n<i.length;n++){var o=i[n].trim();if(0==o.indexOf(e))return o.substring(e.length,o.length)}return""}function addFullFeatures(t){t=jQuery(t),jQuery(".cff-gdpr-notice").remove(),t.find(".cff-author-img").each(function(){jQuery(this).find("img").attr("src",jQuery(this).attr("data-avatar")),jQuery(this).removeClass("cff-no-consent")}),t.find(".cff-likebox iframe").each(function(){var t=jQuery(this),e=t.attr("data-likebox-width"),i=t.parent().width();""==e&&(e=340),i<e&&(e=i),t.attr("src","https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2F"+t.attr("data-likebox-id")+"%2F&tabs&width="+Math.floor(e)+"&small_header="+t.attr("data-likebox-header")+"&adapt_container_width=true&hide_cover="+t.attr("data-hide-cover")+"&hide_cta="+t.attr("data-hide-cta")+"&show_facepile="+t.attr("data-likebox-faces")+"&locale="+t.attr("data-locale"))}),jQuery(".cff-visual-header").length&&jQuery(".cff-visual-header").each(function(){jQuery(this).removeClass("cff-no-consent"),jQuery(this).find(".cff-header-hero").length&&jQuery(this).find(".cff-header-hero").find("img").attr("src",jQuery(this).find(".cff-header-hero").find("img").attr("data-cover-url")),jQuery(this).find(".cff-header-img").length&&jQuery(this).find(".cff-header-img").find("img").attr("src",jQuery(this).find(".cff-header-img").find("img").attr("data-avatar"))})}function afterConsentToggled(t,e){t&&addFullFeatures(e)}function cffGetFeedLocatorDataArray(){var e=[];return jQuery(".cff-list-container").each(function(){$cffPagUrl=jQuery(this).find(".cff-pag-url");var t={feedID:$cffPagUrl.attr("data-feed-id"),postID:$cffPagUrl.attr("data-post-id"),shortCodeAtts:""==jQuery.trim($cffPagUrl.attr("data-cff-shortcode"))?null:JSON.parse($cffPagUrl.attr("data-cff-shortcode")),location:locationGuess(jQuery(this))};e.push(t)}),e}function locationGuess(t=!1){var e=0==t?jQuery(this.el):t,t="content";return e.closest("footer").length?t="footer":e.closest(".header").length||e.closest("header").length?t="header":(e.closest(".sidebar").length||e.closest("aside").length)&&(t="sidebar"),t}cff_js_exists||(jQuery("#cff.cff-masonry-js").length&&(function(t){function e(){}function i(s){if(s){var a="undefined"==typeof console?e:function(t){console.error(t)};return s.bridget=function(t,e){var r,u,i;(i=e).prototype.option||(i.prototype.option=function(t){s.isPlainObject(t)&&(this.options=s.extend(!0,this.options,t))}),r=t,u=e,s.fn[r]=function(e){if("string"!=typeof e)return this.each(function(){var t=s.data(this,r);t?(t.option(e),t._init()):(t=new u(this,e),s.data(this,r,t))});for(var t=f.call(arguments,1),i=0,n=this.length;i<n;i++){var o=this[i],o=s.data(o,r);if(o)if(s.isFunction(o[e])&&"_"!==e.charAt(0)){o=o[e].apply(o,t);if(void 0!==o)return o}else a("no such method '"+e+"' for "+r+" instance");else a("cannot call methods on "+r+" prior to initialization; attempted to call '"+e+"'")}return this}},s.bridget}}var f=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):i("object"==typeof exports?require("jquery"):t.jQuery)}(window),function(i){function n(t){var e=i.event;return e.target=e.target||e.srcElement||t,e}var t=document.documentElement,e=function(){};t.addEventListener?e=function(t,e,i){t.addEventListener(e,i,!1)}:t.attachEvent&&(e=function(e,t,i){e[t+i]=i.handleEvent?function(){var t=n(e);i.handleEvent.call(i,t)}:function(){var t=n(e);i.call(e,t)},e.attachEvent("on"+t,e[t+i])});var o=function(){};t.removeEventListener?o=function(t,e,i){t.removeEventListener(e,i,!1)}:t.detachEvent&&(o=function(e,i,n){e.detachEvent("on"+i,e[i+n]);try{delete e[i+n]}catch(t){e[i+n]=void 0}}),o={bind:e,unbind:o},"function"==typeof define&&define.amd?define("eventie/eventie",o):"object"==typeof exports?module.exports=o:i.eventie=o}(window),function(){function t(){}function r(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function e(t){return function(){return this[t].apply(this,arguments)}}var i=t.prototype,n=this,o=n.EventEmitter;i.getListeners=function(t){var e,i,n=this._getEvents();if(t instanceof RegExp)for(i in e={},n)n.hasOwnProperty(i)&&t.test(i)&&(e[i]=n[i]);else e=n[t]||(n[t]=[]);return e},i.flattenListeners=function(t){for(var e=[],i=0;i<t.length;i+=1)e.push(t[i].listener);return e},i.getListenersAsObject=function(t){var e,i=this.getListeners(t);return i instanceof Array&&((e={})[t]=i),e||i},i.addListener=function(t,e){var i,n=this.getListenersAsObject(t),o="object"==typeof e;for(i in n)n.hasOwnProperty(i)&&-1===r(n[i],e)&&n[i].push(o?e:{listener:e,once:!1});return this},i.on=e("addListener"),i.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},i.once=e("addOnceListener"),i.defineEvent=function(t){return this.getListeners(t),this},i.defineEvents=function(t){for(var e=0;e<t.length;e+=1)this.defineEvent(t[e]);return this},i.removeListener=function(t,e){var i,n,o=this.getListenersAsObject(t);for(n in o)o.hasOwnProperty(n)&&(i=r(o[n],e),-1!==i&&o[n].splice(i,1));return this},i.off=e("removeListener"),i.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},i.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},i.manipulateListeners=function(t,e,i){var n,o,r=t?this.removeListener:this.addListener,u=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(n=i.length;n--;)r.call(this,e,i[n]);else for(n in e)e.hasOwnProperty(n)&&(o=e[n])&&("function"==typeof o?r:u).call(this,n,o);return this},i.removeEvent=function(t){var e,i=typeof t,n=this._getEvents();if("string"==i)delete n[t];else if(t instanceof RegExp)for(e in n)n.hasOwnProperty(e)&&t.test(e)&&delete n[e];else delete this._events;return this},i.removeAllListeners=e("removeEvent"),i.emitEvent=function(t,e){var i,n,o,r,u=this.getListenersAsObject(t);for(o in u)if(u.hasOwnProperty(o))for(n=u[o].length;n--;)i=u[o][n],!0===i.once&&this.removeListener(t,i.listener),r=i.listener.apply(this,e||[]),r===this._getOnceReturnValue()&&this.removeListener(t,i.listener);return this},i.trigger=e("emitEvent"),i.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},i.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},i._getOnceReturnValue=function(){return!this.hasOwnProperty("_onceReturnValue")||this._onceReturnValue},i._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return n.EventEmitter=o,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof r[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,i=0,n=o.length;i<n;i++)if(e=o[i]+t,"string"==typeof r[e])return e}}var o="Webkit Moz ms Ms O".split(" "),r=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(E){function B(t){var e=parseFloat(t);return-1===t.indexOf("%")&&!isNaN(e)&&e}function t(g){var v,A,C,F=!1;return function(t){if(F||(F=!0,m=E.getComputedStyle,y=m?function(t){return m(t,null)}:function(t){return t.currentStyle},v=function(t){t=y(t);return t||D("Style returned "+t+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),t},(A=g("boxSizing"))&&((p=document.createElement("div")).style.width="200px",p.style.padding="1px 2px 3px 4px",p.style.borderStyle="solid",p.style.borderWidth="1px 2px 3px 4px",p.style[A]="border-box",(l=document.body||document.documentElement).appendChild(p),d=v(p),C=200===B(d.width),l.removeChild(p))),"string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var e=v(t);if("none"===e.display)return function(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=b.length;e<i;e++)t[b[e]]=0;return t}();var i={};i.width=t.offsetWidth,i.height=t.offsetHeight;for(var n=i.isBorderBox=!(!A||!e[A]||"border-box"!==e[A]),o=0,r=b.length;o<r;o++){var u=b[o],s=function(t,e){if(E.getComputedStyle||-1===e.indexOf("%"))return e;var i=t.style,n=i.left,o=t.runtimeStyle,r=o&&o.left;return r&&(o.left=t.currentStyle.left),i.left=e,e=i.pixelLeft,i.left=n,r&&(o.left=r),e}(t,s=e[u]),s=parseFloat(s);i[u]=isNaN(s)?0:s}var a=i.paddingLeft+i.paddingRight,f=i.paddingTop+i.paddingBottom,c=i.marginLeft+i.marginRight,h=i.marginTop+i.marginBottom,d=i.borderLeftWidth+i.borderRightWidth,l=i.borderTopWidth+i.borderBottomWidth,p=n&&C,n=B(e.width);!1!==n&&(i.width=n+(p?0:a+d));n=B(e.height);return!1!==n&&(i.height=n+(p?0:f+l)),i.innerWidth=i.width-(a+d),i.innerHeight=i.height-(f+l),i.outerWidth=i.width+c,i.outerHeight=i.height+h,i}var m,p,l,d,y}}var D="undefined"==typeof console?function(){}:function(t){console.error(t)},b=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],t):"object"==typeof exports?module.exports=t(require("desandro-get-style-property")):E.getSize=t(E.getStyleProperty)}(window),function(e){function i(t){"function"==typeof t&&(i.isReady?t():u.push(t))}function n(t){t="readystatechange"===t.type&&"complete"!==r.readyState;i.isReady||t||o()}function o(){i.isReady=!0;for(var t=0,e=u.length;t<e;t++)(0,u[t])()}function t(t){return"complete"===r.readyState?o():(t.bind(r,"DOMContentLoaded",n),t.bind(r,"readystatechange",n),t.bind(e,"load",n)),i}var r=e.document,u=[];i.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],t):"object"==typeof exports?module.exports=t(require("eventie")):e.docReady=t(e.eventie)}(window),function(o){function i(t,e){return t[n](e)}function r(t){t.parentNode||document.createDocumentFragment().appendChild(t)}var t,n=function(){if(o.matches)return"matches";if(o.matchesSelector)return"matchesSelector";for(var t=["webkit","moz","ms","o"],e=0,i=t.length;e<i;e++){var n=t[e]+"MatchesSelector";if(o[n])return n}}();t=n?i(document.createElement("div"),"div")?i:function(t,e){return r(t),i(t,e)}:function(t,e){r(t);for(var i=t.parentNode.querySelectorAll(e),n=0,o=i.length;n<o;n++)if(i[n]===t)return!0;return!1},"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return t}):"object"==typeof exports?module.exports=t:window.matchesSelector=t}(Element.prototype),function(i,n){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["doc-ready/doc-ready","matches-selector/matches-selector"],function(t,e){return n(i,t,e)}):"object"==typeof exports?module.exports=n(i,require("doc-ready"),require("desandro-matches-selector")):i.fizzyUIUtils=n(i,i.docReady,i.matchesSelector)}(window,function(d,t,f){var i,l={extend:function(t,e){for(var i in e)t[i]=e[i];return t},modulo:function(t,e){return(t%e+e)%e}},e=Object.prototype.toString;l.isArray=function(t){return"[object Array]"==e.call(t)},l.makeArray=function(t){var e=[];if(l.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0,n=t.length;i<n;i++)e.push(t[i]);else e.push(t);return e},l.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,n=t.length;i<n;i++)if(t[i]===e)return i;return-1},l.removeFrom=function(t,e){e=l.indexOf(t,e);-1!=e&&t.splice(e,1)},l.isElement="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(t){return t instanceof HTMLElement}:function(t){return t&&"object"==typeof t&&1==t.nodeType&&"string"==typeof t.nodeName},l.setText=function(t,e){t[i=i||(void 0!==document.documentElement.textContent?"textContent":"innerText")]=e},l.getParent=function(t,e){for(;t!=document.body;)if(t=t.parentNode,f(t,e))return t},l.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},l.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},l.filterFindElements=function(t,e){for(var i=[],n=0,o=(t=l.makeArray(t)).length;n<o;n++){var r=t[n];if(l.isElement(r))if(e){f(r,e)&&i.push(r);for(var u=r.querySelectorAll(e),s=0,a=u.length;s<a;s++)i.push(u[s])}else i.push(r)}return i},l.debounceMethod=function(t,e,n){var o=t.prototype[e],r=e+"Timeout";t.prototype[e]=function(){var t=this[r];t&&clearTimeout(t);var e=arguments,i=this;this[r]=setTimeout(function(){o.apply(i,e),delete i[r]},n||100)}},l.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var p=d.console;return l.htmlInit=function(c,h){t(function(){for(var t=l.toDashed(h),e=document.querySelectorAll(".js-"+t),i="data-"+t+"-options",n=0,o=e.length;n<o;n++){var r,u=e[n],s=u.getAttribute(i);try{r=s&&JSON.parse(s)}catch(t){p&&p.error("Error parsing "+i+" on "+u.nodeName.toLowerCase()+(u.id?"#"+u.id:"")+": "+t);continue}var a=new c(u,r),f=d.jQuery;f&&f.data(u,h,a)}})},l}),function(o,r){"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property","fizzy-ui-utils/utils"],function(t,e,i,n){return r(o,t,e,i,n)}):"object"==typeof exports?module.exports=r(o,require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property"),require("fizzy-ui-utils")):(o.Outlayer={},o.Outlayer.Item=r(o,o.EventEmitter,o.getSize,o.getStyleProperty,o.fizzyUIUtils))}(window,function(t,e,i,r,n){function o(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}var u=t.getComputedStyle,s=u?function(t){return u(t,null)}:function(t){return t.currentStyle},a=r("transition"),f=r("transform"),c=a&&f,t=!!r("perspective"),h={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[a],d=["transform","transition","transitionDuration","transitionProperty"],l=function(){for(var t={},e=0,i=d.length;e<i;e++){var n=d[e],o=r(n);o&&o!==n&&(t[n]=o)}return t}();n.extend(o.prototype,e.prototype),o.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},o.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},o.prototype.getSize=function(){this.size=i(this.element)},o.prototype.css=function(t){var e,i=this.element.style;for(e in t)i[l[e]||e]=t[e]},o.prototype.getPosition=function(){var t=s(this.element),e=this.layout.options,i=e.isOriginLeft,n=e.isOriginTop,o=parseInt(t[i?"left":"right"],10),e=parseInt(t[n?"top":"bottom"],10),o=isNaN(o)?0:o,e=isNaN(e)?0:e,t=this.layout.size;o-=i?t.paddingLeft:t.paddingRight,e-=n?t.paddingTop:t.paddingBottom,this.position.x=o,this.position.y=e},o.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={},n=e.isOriginLeft?"paddingLeft":"paddingRight",o=e.isOriginLeft?"left":"right",r=e.isOriginLeft?"right":"left",n=this.position.x+t[n],n=e.percentPosition&&!e.isHorizontal?n/t.width*100+"%":n+"px";i[o]=n,i[r]="";o=e.isOriginTop?"paddingTop":"paddingBottom",n=e.isOriginTop?"top":"bottom",r=e.isOriginTop?"bottom":"top",o=this.position.y+t[o],o=e.percentPosition&&e.isHorizontal?o/t.height*100+"%":o+"px";i[n]=o,i[r]="",this.css(i),this.emitEvent("layout",[this])};var p=t?function(t,e){return"translate3d("+t+"px, "+e+"px, 0)"}:function(t,e){return"translate("+t+"px, "+e+"px)"};o.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),r=parseInt(e,10),r=o===this.position.x&&r===this.position.y;this.setPosition(t,e),!r||this.isTransitioning?(t-=i,i=e-n,e={},t=(n=this.layout.options).isOriginLeft?t:-t,i=n.isOriginTop?i:-i,e.transform=p(t,i),this.transition({to:e,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})):this.layoutPosition()},o.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},o.prototype.moveTo=c?o.prototype._transitionTo:o.prototype.goTo,o.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},o.prototype._nonTransition=function(t){for(var e in this.css(t.to),t.isCleaning&&this._removeStyles(t.to),t.onTransitionEnd)t.onTransitionEnd[e].call(this)},o.prototype._transition=function(t){if(parseFloat(this.layout.options.transitionDuration)){var e,i=this._transn;for(e in t.onTransitionEnd)i.onEnd[e]=t.onTransitionEnd[e];for(e in t.to)i.ingProperties[e]=!0,t.isCleaning&&(i.clean[e]=!0);t.from&&(this.css(t.from),this.element.offsetHeight,0),this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0}else this._nonTransition(t)};var m=f&&n.toDashed(f)+",opacity";o.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:m,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(h,this,!1))},o.prototype.transition=o.prototype[a?"_transition":"_nonTransition"],o.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},o.prototype.onotransitionend=function(t){this.ontransitionend(t)};var y={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};o.prototype.ontransitionend=function(t){var e,i;t.target===this.element&&(e=this._transn,i=y[t.propertyName]||t.propertyName,delete e.ingProperties[i],function(t){for(var e in t)return;return 1}(e.ingProperties)&&this.disableTransition(),i in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[i]),i in e.onEnd&&(e.onEnd[i].call(this),delete e.onEnd[i]),this.emitEvent("transitionEnd",[this]))},o.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(h,this,!1),this.isTransitioning=!1},o.prototype._removeStyles=function(t){var e,i={};for(e in t)i[e]="";this.css(i)};var g={transitionProperty:"",transitionDuration:""};return o.prototype.removeTransitionStyles=function(){this.css(g)},o.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},o.prototype.remove=function(){var t;a&&parseFloat(this.layout.options.transitionDuration)?((t=this).once("transitionEnd",function(){t.removeElem()}),this.hide()):this.removeElem()},o.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={};e[this.getHideRevealTransitionEndProperty("visibleStyle")]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},o.prototype.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},o.prototype.getHideRevealTransitionEndProperty=function(t){var e,t=this.layout.options[t];if(t.opacity)return"opacity";for(e in t)return e},o.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={};e[this.getHideRevealTransitionEndProperty("hiddenStyle")]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},o.prototype.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},o.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},o}),function(r,u){"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","eventEmitter/EventEmitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(t,e,i,n,o){return u(r,t,e,i,n,o)}):"object"==typeof exports?module.exports=u(r,require("eventie"),require("wolfy87-eventemitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):r.Outlayer=u(r,r.eventie,r.EventEmitter,r.getSize,r.fizzyUIUtils,r.Outlayer.Item)}(window,function(t,e,i,o,r,n){function u(t,e){var i=r.getQueryElement(t);i?(this.element=i,f&&(this.$element=f(this.element)),this.options=r.extend({},this.constructor.defaults),this.option(e),e=++c,this.element.outlayerGUID=e,(h[e]=this)._create(),this.options.isInitLayout&&this.layout()):a&&a.error("Bad element for "+this.constructor.namespace+": "+(i||t))}function s(){}var a=t.console,f=t.jQuery,c=0,h={};return u.namespace="outlayer",u.Item=n,u.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},r.extend(u.prototype,i.prototype),u.prototype.option=function(t){r.extend(this.options,t)},u.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),r.extend(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},u.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},u.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0,r=e.length;o<r;o++){var u=new i(e[o],this);n.push(u)}return n},u.prototype._filterFindItemElements=function(t){return r.filterFindElements(t,this.options.itemSelector)},u.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;e<i;e++)t.push(this.items[e].element);return t},u.prototype._init=u.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},u.prototype._resetLayout=function(){this.getSize()},u.prototype.getSize=function(){this.size=o(this.element)},u.prototype._getMeasurement=function(t,e){var i,n=this.options[t];n?("string"==typeof n?i=this.element.querySelector(n):r.isElement(n)&&(i=n),this[t]=i?o(i)[e]:n):this[t]=0},u.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},u.prototype._getItemsForLayout=function(t){for(var e=[],i=0,n=t.length;i<n;i++){var o=t[i];o.isIgnored||e.push(o)}return e},u.prototype._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){for(var i=[],n=0,o=t.length;n<o;n++){var r=t[n],u=this._getItemLayoutPosition(r);u.item=r,u.isInstant=e||r.isLayoutInstant,i.push(u)}this._processLayoutQueue(i)}},u.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},u.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;e<i;e++){var n=t[e];this._positionItem(n.item,n.x,n.y,n.isInstant)}},u.prototype._positionItem=function(t,e,i,n){n?t.goTo(e,i):t.moveTo(e,i)},u.prototype._postLayout=function(){this.resizeContainer()},u.prototype.resizeContainer=function(){var t;!this.options.isResizingContainer||(t=this._getContainerSize())&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))},u.prototype._getContainerSize=s,u.prototype._setContainerMeasure=function(t,e){var i;void 0!==t&&((i=this.size).isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px")},u.prototype._emitCompleteOnItems=function(t,e){function i(){o.emitEvent(t+"Complete",[e])}function n(){++u===r&&i()}var o=this,r=e.length;if(e&&r)for(var u=0,s=0,a=e.length;s<a;s++)e[s].once(t,n);else i()},u.prototype.ignore=function(t){t=this.getItem(t);t&&(t.isIgnored=!0)},u.prototype.unignore=function(t){t=this.getItem(t);t&&delete t.isIgnored},u.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;e<i;e++){var n=t[e];this.ignore(n)}}},u.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;e<i;e++){var n=t[e];r.removeFrom(this.stamps,n),this.unignore(n)}},u.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=r.makeArray(t)):void 0},u.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var t=0,e=this.stamps.length;t<e;t++){var i=this.stamps[t];this._manageStamp(i)}}},u.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},u.prototype._manageStamp=s,u.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,t=o(t);return{left:e.left-i.left-t.marginLeft,top:e.top-i.top-t.marginTop,right:i.right-e.right-t.marginRight,bottom:i.bottom-e.bottom-t.marginBottom}},u.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},u.prototype.bindResize=function(){this.isResizeBound||(e.bind(t,"resize",this),this.isResizeBound=!0)},u.prototype.unbindResize=function(){this.isResizeBound&&e.unbind(t,"resize",this),this.isResizeBound=!1},u.prototype.onresize=function(){this.resizeTimeout&&clearTimeout(this.resizeTimeout);var t=this;this.resizeTimeout=setTimeout(function(){t.resize(),delete t.resizeTimeout},100)},u.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},u.prototype.needsResizeLayout=function(){var t=o(this.element);return this.size&&t&&t.innerWidth!==this.size.innerWidth},u.prototype.addItems=function(t){t=this._itemize(t);return t.length&&(this.items=this.items.concat(t)),t},u.prototype.appended=function(t){t=this.addItems(t);t.length&&(this.layoutItems(t,!0),this.reveal(t))},u.prototype.prepended=function(t){var e=this._itemize(t);e.length&&(t=this.items.slice(0),this.items=e.concat(t),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(t))},u.prototype.reveal=function(t){this._emitCompleteOnItems("reveal",t);for(var e=t&&t.length,i=0;e&&i<e;i++)t[i].reveal()},u.prototype.hide=function(t){this._emitCompleteOnItems("hide",t);for(var e=t&&t.length,i=0;e&&i<e;i++)t[i].hide()},u.prototype.revealItemElements=function(t){t=this.getItems(t);this.reveal(t)},u.prototype.hideItemElements=function(t){t=this.getItems(t);this.hide(t)},u.prototype.getItem=function(t){for(var e=0,i=this.items.length;e<i;e++){var n=this.items[e];if(n.element===t)return n}},u.prototype.getItems=function(t){for(var e=[],i=0,n=(t=r.makeArray(t)).length;i<n;i++){var o=t[i],o=this.getItem(o);o&&e.push(o)}return e},u.prototype.remove=function(t){var e=this.getItems(t);if(this._emitCompleteOnItems("remove",e),e&&e.length)for(var i=0,n=e.length;i<n;i++){var o=e[i];o.remove(),r.removeFrom(this.items,o)}},u.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;e<i;e++)this.items[e].destroy();this.unbindResize();t=this.element.outlayerGUID;delete h[t],delete this.element.outlayerGUID,f&&f.removeData(this.element,this.constructor.namespace)},u.data=function(t){t=(t=r.getQueryElement(t))&&t.outlayerGUID;return t&&h[t]},u.create=function(t,e){function i(){u.apply(this,arguments)}return Object.create?i.prototype=Object.create(u.prototype):r.extend(i.prototype,u.prototype),(i.prototype.constructor=i).defaults=r.extend({},u.defaults),r.extend(i.defaults,e),i.prototype.settings={},i.namespace=t,i.data=u.data,(i.Item=function(){n.apply(this,arguments)}).prototype=new n,r.htmlInit(i,t),f&&f.bridget&&f.bridget(t,i),i},u.Item=n,u}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","fizzy-ui-utils/utils"],e):"object"==typeof exports?module.exports=e(require("outlayer"),require("get-size"),require("fizzy-ui-utils")):t.Masonry=e(t.Outlayer,t.getSize,t.fizzyUIUtils)}(window,function(t,s,a){t=t.create("masonry");return t.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},t.prototype.measureColumns=function(){this.getContainerWidth(),this.columnWidth||(i=(e=this.items[0])&&e.element,this.columnWidth=i&&s(i).outerWidth||this.containerWidth);var t=this.columnWidth+=this.gutter,e=this.containerWidth+this.gutter,i=e/t,t=t-e%t,i=Math[t&&t<1?"round":"floor"](i);this.cols=Math.max(i,1)},t.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,t=s(t);this.containerWidth=t&&t.innerWidth},t.prototype._getItemLayoutPosition=function(t){t.getSize();for(var e=t.size.outerWidth%this.columnWidth,i=Math[e&&e<1?"round":"ceil"](t.size.outerWidth/this.columnWidth),i=Math.min(i,this.cols),n=this._getColGroup(i),e=Math.min.apply(Math,n),o=a.indexOf(n,e),i={x:this.columnWidth*o,y:e},r=e+t.size.outerHeight,u=this.cols+1-n.length,s=0;s<u;s++)this.colYs[o+s]=r;return i},t.prototype._getColGroup=function(t){if(t<2)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;n<i;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},t.prototype._manageStamp=function(t){var e=s(t),i=this._getElementOffset(t),n=this.options.isOriginLeft?i.left:i.right,t=n+e.outerWidth,n=Math.floor(n/this.columnWidth),n=Math.max(0,n),o=Math.floor(t/this.columnWidth);o-=t%this.columnWidth?0:1,o=Math.min(this.cols-1,o);for(var r=(this.options.isOriginTop?i.top:i.bottom)+e.outerHeight,u=n;u<=o;u++)this.colYs[u]=Math.max(r,this.colYs[u])},t.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},t.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},t.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},t})),cff_init(),jQuery(document).ready(function(){var t,e=jQuery;e("#cookie-notice a").on("click",function(){setTimeout(function(){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(checkConsent(jQuery(this)),jQuery(this))})},1e3)}),e("#cookie-law-info-bar a").on("click",function(){setTimeout(function(){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(checkConsent(jQuery(this)),jQuery(this))})},1e3)}),e(".cli-user-preference-checkbox").on("click",function(){setTimeout(function(){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!1,jQuery(this))})},1e3)}),e(window).on("CookiebotOnAccept",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!0,jQuery(this))})}),e(document).on("cmplzAcceptAll",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!0,jQuery(this))})}),e(document).on("cmplzRevoke",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!1,jQuery(this))})}),e(document).on("borlabs-cookie-consent-saved",function(t){jQuery(".cff-wrapper").each(function(t){afterConsentToggled(!0,jQuery(this))})}),e(".cff-list-container").length&&(t=cffGetFeedLocatorDataArray(),e.ajax({url:cffajaxurl,type:"POST",data:{action:"feed_locator",feedLocatorData:t}}))}));
custom-facebook-feed.php CHANGED
@@ -3,7 +3,7 @@
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.18.3
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  License: GPLv2 or later
@@ -25,11 +25,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
  */
26
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
27
 
28
- define('CFFVER', '2.18.3');
29
 
30
  // Db version.
31
  if ( ! defined( 'CFF_DBVERSION' ) ) {
32
- define( 'CFF_DBVERSION', '1.2' );
33
  }
34
 
35
  // Plugin Folder Path.
@@ -50,14 +50,16 @@ if ( ! defined( 'CFF_FILE' ) ) {
50
  if ( ! defined( 'CFF_FILE' ) ) {
51
  define( 'CFF_PLUGIN_BASE', plugin_basename( CFF_FILE ) );
52
  }
53
-
 
 
54
 
55
  /**
56
  * Check PHP version
57
  *
58
  * Check for minimum PHP 5.6 version
59
  *
60
- * @since X.X.X
61
  */
62
  if ( version_compare( phpversion(), '5.6', '<' ) ) {
63
  if( !function_exists( 'cff_check_php_notice' ) ){
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.19
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  License: GPLv2 or later
25
  */
26
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
27
 
28
+ define('CFFVER', '2.19');
29
 
30
  // Db version.
31
  if ( ! defined( 'CFF_DBVERSION' ) ) {
32
+ define( 'CFF_DBVERSION', '1.3' );
33
  }
34
 
35
  // Plugin Folder Path.
50
  if ( ! defined( 'CFF_FILE' ) ) {
51
  define( 'CFF_PLUGIN_BASE', plugin_basename( CFF_FILE ) );
52
  }
53
+ if ( ! defined( 'CFF_FEED_LOCATOR' ) ) {
54
+ define( 'CFF_FEED_LOCATOR', 'cff_facebook_feed_locator' );
55
+ }
56
 
57
  /**
58
  * Check PHP version
59
  *
60
  * Check for minimum PHP 5.6 version
61
  *
62
+ * @since 2.19
63
  */
64
  if ( version_compare( phpversion(), '5.6', '<' ) ) {
65
  if( !function_exists( 'cff_check_php_notice' ) ){
inc/Admin/CFF_Admin.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * Contains everything about the Admin area
6
  *
7
- * @since X.X.X
8
  */
9
 
10
  namespace CustomFacebookFeed\Admin;
@@ -17,7 +17,7 @@ class CFF_Admin{
17
  /**
18
  * Admin constructor
19
  *
20
- * @since X.X.X
21
  */
22
  public function __construct(){
23
  $this->admin_hook();
@@ -28,10 +28,10 @@ class CFF_Admin{
28
  /**
29
  * Admin Hooks + Enqueue
30
  *
31
- * @since X.X.X
32
  */
33
  protected function admin_hook(){
34
- //Adding Dashboard Menu
35
  add_action( 'admin_menu', array( $this, 'register_dashboard_menus' ), 9 );
36
  }
37
 
@@ -39,7 +39,7 @@ class CFF_Admin{
39
  /**
40
  * Register CFF dashboard Menus.
41
  *
42
- * @since X.X.X
43
  */
44
  public function register_dashboard_menus(){
45
  $notice = '';
@@ -56,7 +56,7 @@ class CFF_Admin{
56
  $cap,
57
  'cff-top',
58
  'cff_settings_page'
59
- );
60
 
61
  add_submenu_page(
62
  'cff-top',
@@ -138,9 +138,9 @@ class CFF_Admin{
138
  }
139
 
140
  /**
141
- * Register Assets
142
  *
143
- * @since X.X.X
144
  */
145
  public function register_assets(){
146
  add_action( 'admin_enqueue_scripts' , array( $this, 'enqueue_styles_assets' ) );
@@ -150,42 +150,42 @@ class CFF_Admin{
150
 
151
 
152
  /**
153
- * Enqueue & Register Styles
154
  *
155
- * @since X.X.X
156
  */
157
  public function enqueue_styles_assets(){
158
  wp_register_style(
159
- 'custom_wp_admin_css',
160
- CFF_PLUGIN_URL . 'admin/assets/css/cff-admin-style.css',
161
- false,
162
- CFFVER
163
  );
164
  wp_enqueue_style( 'custom_wp_admin_css' );
165
- wp_enqueue_style(
166
- 'cff-font-awesome',
167
- 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css',
168
- array(),
169
- '4.5.0'
170
  );
171
  wp_enqueue_style( 'wp-color-picker' );
172
  }
173
 
174
 
175
  /**
176
- * Enqueue & Register Scripts
177
  *
178
- * @since X.X.X
179
  */
180
- public function enqueue_scripts_assets(){
181
  //Declare color-picker as a dependency
182
- wp_enqueue_script(
183
- 'cff_admin_script',
184
- CFF_PLUGIN_URL . 'admin/assets/js/cff-admin-scripts.js',
185
  false,
186
- CFFVER
187
  );
188
-
189
  wp_localize_script( 'cff_admin_script', 'cffA', array(
190
  'ajax_url' => admin_url( 'admin-ajax.php' ),
191
  'cff_nonce' => wp_create_nonce( 'cff_nonce' )
@@ -219,7 +219,7 @@ class CFF_Admin{
219
  'cff_admin',
220
  $strings
221
  );
222
- if( !wp_script_is('jquery-ui-draggable') ) {
223
  wp_enqueue_script(
224
  array(
225
  'jquery',
4
  *
5
  * Contains everything about the Admin area
6
  *
7
+ * @since 2.19
8
  */
9
 
10
  namespace CustomFacebookFeed\Admin;
17
  /**
18
  * Admin constructor
19
  *
20
+ * @since 2.19
21
  */
22
  public function __construct(){
23
  $this->admin_hook();
28
  /**
29
  * Admin Hooks + Enqueue
30
  *
31
+ * @since 2.19
32
  */
33
  protected function admin_hook(){
34
+ //Adding Dashboard Menu
35
  add_action( 'admin_menu', array( $this, 'register_dashboard_menus' ), 9 );
36
  }
37
 
39
  /**
40
  * Register CFF dashboard Menus.
41
  *
42
+ * @since 2.19
43
  */
44
  public function register_dashboard_menus(){
45
  $notice = '';
56
  $cap,
57
  'cff-top',
58
  'cff_settings_page'
59
+ );
60
 
61
  add_submenu_page(
62
  'cff-top',
138
  }
139
 
140
  /**
141
+ * Register Assets
142
  *
143
+ * @since 2.19
144
  */
145
  public function register_assets(){
146
  add_action( 'admin_enqueue_scripts' , array( $this, 'enqueue_styles_assets' ) );
150
 
151
 
152
  /**
153
+ * Enqueue & Register Styles
154
  *
155
+ * @since 2.19
156
  */
157
  public function enqueue_styles_assets(){
158
  wp_register_style(
159
+ 'custom_wp_admin_css',
160
+ CFF_PLUGIN_URL . 'admin/assets/css/cff-admin-style.css',
161
+ false,
162
+ CFFVER
163
  );
164
  wp_enqueue_style( 'custom_wp_admin_css' );
165
+ wp_enqueue_style(
166
+ 'cff-font-awesome',
167
+ 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css',
168
+ array(),
169
+ '4.5.0'
170
  );
171
  wp_enqueue_style( 'wp-color-picker' );
172
  }
173
 
174
 
175
  /**
176
+ * Enqueue & Register Scripts
177
  *
178
+ * @since 2.19
179
  */
180
+ public function enqueue_scripts_assets(){
181
  //Declare color-picker as a dependency
182
+ wp_enqueue_script(
183
+ 'cff_admin_script',
184
+ CFF_PLUGIN_URL . 'admin/assets/js/cff-admin-scripts.js',
185
  false,
186
+ CFFVER
187
  );
188
+
189
  wp_localize_script( 'cff_admin_script', 'cffA', array(
190
  'ajax_url' => admin_url( 'admin-ajax.php' ),
191
  'cff_nonce' => wp_create_nonce( 'cff_nonce' )
219
  'cff_admin',
220
  $strings
221
  );
222
+ if( !wp_script_is('jquery-ui-draggable') ) {
223
  wp_enqueue_script(
224
  array(
225
  'jquery',
inc/CFF_Autolink.php CHANGED
@@ -3,7 +3,7 @@
3
  * Autolink
4
  *
5
  *
6
- * @since X.X.X
7
  */
8
 
9
  namespace CustomFacebookFeed;
@@ -144,7 +144,7 @@ class CFF_Autolink{
144
  #
145
  # add the url
146
  #
147
-
148
  if ($display_url != $link_url && !preg_match('@title=@msi',$tagfill) && $auto_title) {
149
 
150
  $display_quoted = preg_quote($display_url, '!');
@@ -158,11 +158,11 @@ class CFF_Autolink{
158
  $link_url_enc = HtmlSpecialChars($link_url);
159
  $display_url_enc = HtmlSpecialChars($display_url);
160
 
161
-
162
  if( substr( $link_url_enc, 0, 4 ) !== "http" ) $link_url_enc = 'http://' . $link_url_enc;
163
  $buffer .= "<a href=\"{$link_url_enc}\" rel='nofollow noopener noreferrer'>{$display_url_enc}</a>";
164
-
165
-
166
  }else{
167
  #echo "fail 3 at $cursor<br />\n";
168
 
3
  * Autolink
4
  *
5
  *
6
+ * @since 2.19
7
  */
8
 
9
  namespace CustomFacebookFeed;
144
  #
145
  # add the url
146
  #
147
+
148
  if ($display_url != $link_url && !preg_match('@title=@msi',$tagfill) && $auto_title) {
149
 
150
  $display_quoted = preg_quote($display_url, '!');
158
  $link_url_enc = HtmlSpecialChars($link_url);
159
  $display_url_enc = HtmlSpecialChars($display_url);
160
 
161
+
162
  if( substr( $link_url_enc, 0, 4 ) !== "http" ) $link_url_enc = 'http://' . $link_url_enc;
163
  $buffer .= "<a href=\"{$link_url_enc}\" rel='nofollow noopener noreferrer'>{$display_url_enc}</a>";
164
+
165
+
166
  }else{
167
  #echo "fail 3 at $cursor<br />\n";
168
 
inc/CFF_Error_Reporter.php CHANGED
@@ -6,10 +6,13 @@
6
  *
7
  * @since
8
  */
9
- namespace CustomFacebookFeed;
10
 
 
11
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
 
 
 
 
13
 
14
  class CFF_Error_Reporter
15
  {
@@ -22,22 +25,46 @@ class CFF_Error_Reporter
22
  * @var array
23
  */
24
  var $frontend_error;
25
-
 
 
 
26
  var $reporter_key;
27
 
 
 
 
 
 
 
28
  /**
29
  * CFF_Error_Reporter constructor.
30
  */
31
  public function __construct() {
32
  $this->reporter_key = 'cff_error_reporter';
33
- $this->errors = get_option( $this->reporter_key, array() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  $this->frontend_error = '';
35
- add_action( 'cff_feed_issue_email', array( $this, 'maybe_trigger_report_email_send' ) );
36
- add_action( 'wp_ajax_cff_dismiss_critical_notice', array( $this, 'dismiss_critical_notice' ) );
37
- add_action( 'wp_footer', array( $this, 'critical_error_notice' ), 300 );
38
- add_action( 'admin_notices', array( $this, 'admin_error_notices' ) );
 
39
  }
40
-
41
  /**
42
  * @return array
43
  *
@@ -53,64 +80,230 @@ class CFF_Error_Reporter
53
  *
54
  * @since 2.0/4.0
55
  */
56
- public function add_error( $type, $args ) {
57
- if ( $type === 'accesstoken' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  $accesstoken_error_exists = false;
59
- if ( isset( $this->errors['accesstoken'] ) ) {
60
- foreach ($this->errors['accesstoken'] as $accesstoken ) {
61
- if ( $args['accesstoken'] === $accesstoken['accesstoken'] ) {
62
  $accesstoken_error_exists = true;
63
  }
64
  }
65
  }
66
-
67
  if ( !$accesstoken_error_exists ) {
68
- $this->errors['accesstoken'][] = array(
69
- 'accesstoken' => $args['accesstoken'],
70
- 'post_id' => $args['post_id'],
71
- 'errorno' => $args['errorno']
 
 
72
  );
 
73
  }
 
74
 
75
- } else {
76
- $this->errors[ $type ] = array(
77
- 'accesstoken' => $args['accesstoken'],
78
- 'public_message' => $args['public_message'],
79
- 'admin_message' => $args['admin_message'],
80
- 'frontend_directions' => $args['frontend_directions'],
81
- 'backend_directions' => $args['backend_directions'],
82
- 'post_id' => $args['post_id'],
83
- 'errorno' => $args['errorno']
84
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  update_option( $this->reporter_key, $this->errors, false );
 
88
  }
89
 
 
90
  /**
91
- * @param $type
92
  *
93
- * @since 2.0/4.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  */
95
- public function remove_error( $type ) {
96
- $errors = $this->errors;
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- if ( isset( $errors[ $type ] ) ) {
99
- unset( $errors[ $type ] );
 
 
 
 
 
 
 
 
 
100
  }
101
 
102
- if ( empty( $errors ) ) {
103
- delete_option( $this->reporter_key );
104
- $this->errors = array();
105
- } else {
106
- update_option( $this->reporter_key, $errors, false );
107
- $this->errors = $errors;
108
  }
 
109
  }
110
 
111
  public function remove_all_errors() {
112
  delete_option( $this->reporter_key );
113
- $this->errors = array();
114
  }
115
 
116
  /**
@@ -137,23 +330,83 @@ class CFF_Error_Reporter
137
  }
138
 
139
  public function get_critical_errors() {
140
- $errors = $this->get_errors();
 
 
 
 
 
 
 
 
 
141
 
142
- return $errors;
 
 
 
 
 
 
 
 
 
 
 
 
143
  }
144
 
145
  public function are_critical_errors() {
146
  $are_errors = false;
147
-
148
  $errors = $this->get_errors();
149
-
150
- foreach ( $errors as $error ) {
151
- $are_errors = true;
 
 
 
 
 
 
 
 
 
152
  }
153
 
 
154
  return $are_errors;
155
  }
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
  /**
159
  * Load the critical notice for logged in users.
@@ -179,7 +432,8 @@ class CFF_Error_Reporter
179
  return;
180
  }
181
 
182
- $options = get_option('cff_style_settings');
 
183
  if ( isset( $options['disable_admin_notice'] ) && $options['disable_admin_notice'] === 'on' ) {
184
  return;
185
  }
@@ -190,7 +444,7 @@ class CFF_Error_Reporter
190
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/cff-icon.png'; ?>" width="45" alt="Custom Facebook Feed icon" />
191
  </div>
192
  <div class="cff-critical-notice-text">
193
- <h3><?php esc_html_e( 'Custom Facebook Feed Critical Issue', 'custom-facebook-feed' ); ?></h3>
194
  <p>
195
  <?php
196
  $doc_url = admin_url() . 'admin.php?page=cff-top';
@@ -203,21 +457,21 @@ class CFF_Error_Reporter
203
  </div>
204
  <style type="text/css">
205
  .cff-critical-notice {
206
- position: fixed;
207
- bottom: 20px;
208
- right: 15px;
209
- font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
210
- background: #fff;
211
- box-shadow: 0 0 10px 0 #dedede;
212
- padding: 10px 10px;
213
- display: flex;
214
- align-items: center;
215
- justify-content: center;
216
- width: 325px;
217
- max-width: calc( 100% - 30px );
218
- border-radius: 6px;
219
- transition: bottom 700ms ease;
220
- z-index: 10000;
221
  }
222
 
223
  .cff-critical-notice h3 {
@@ -365,7 +619,7 @@ class CFF_Error_Reporter
365
  $details = '<p>' . __( 'A Custom Facebook Feed on your website is currently unable to connect to Facebook to retrieve new posts. Don\'t worry, your feed is still being displayed using a cached version, but is no longer able to display new posts.', 'custom-facebook-feed' ) . '</p>';
366
  $details .= '<p>' . sprintf( __( 'This is caused by an issue with your Facebook account connecting to the Facebook API. For information on the exact issue and directions on how to resolve it, please visit the %sCustom Facebook Feed settings page%s on your website.', 'custom-facebook-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' ). '</p>';
367
  $message_content = '<h6 style="padding:0;word-wrap:normal;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;font-weight:bold;line-height:130%;font-size: 16px;color:#444444;text-align:inherit;margin:0 0 20px 0;Margin:0 0 20px 0;">' . $bold . '</h6>' . $details;
368
- #include_once CFF_PLUGIN_DIR . 'class-cff-education.php';
369
  $educator = new CFF_Education();
370
  $dyk_message = $educator->dyk_display();
371
  ob_start();
@@ -381,7 +635,8 @@ class CFF_Error_Reporter
381
  if ( ! $this->are_critical_errors() ) {
382
  return;
383
  }
384
- $options = get_option('cff_style_settings');
 
385
 
386
  if ( isset( $options['enable_email_report'] ) && empty( $options['enable_email_report'] ) ) {
387
  return;
@@ -392,9 +647,31 @@ class CFF_Error_Reporter
392
 
393
  public function admin_error_notices() {
394
  if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'cff-top', 'cff-style' )) ) {
395
-
 
 
 
 
 
 
 
 
396
  $errors = $this->get_critical_errors();
397
- if ( $this->are_critical_errors() && ! empty( $errors ) ) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  if ( isset( $errors['wp_remote_get'] ) ) {
399
  $error = $errors['wp_remote_get'];
400
  $error_message = $error['admin_message'];
@@ -415,14 +692,14 @@ class CFF_Error_Reporter
415
  $directions .= '</p>';
416
  } else {
417
  $error = $errors['accesstoken'];
418
-
419
  $tokens = array();
420
  $post_id = false;
421
  foreach ( $error as $token ) {
422
  $tokens[] = $token['accesstoken'];
423
  $post_id = $token['post_id'];
424
  }
425
- $error_message = sprintf( __( 'The access token %s is invalid or has expired.', 'custom-facebook-feed' ), implode( $tokens, ', ' ) );
426
  $directions = '<p class="cff-error-directions">';
427
  $directions .= '<button class="button button-primary cff-reconnect">' . __( 'Reconnect Your Account', 'custom-facebook-feed' ) . '</button>';
428
  $directions .= '<button data-url="'.get_the_permalink( $post_id ).'" class="cff-clear-errors-visit-page cff-space-left button button-secondary">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>';
@@ -437,6 +714,8 @@ class CFF_Error_Reporter
437
  <?php echo $directions; ?>
438
  </div>
439
  <?php endif;
 
 
440
  }
441
 
442
  }
6
  *
7
  * @since
8
  */
 
9
 
10
+ namespace CustomFacebookFeed;
11
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
 
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ die( '-1' );
15
+ }
16
 
17
  class CFF_Error_Reporter
18
  {
25
  * @var array
26
  */
27
  var $frontend_error;
28
+
29
+ /**
30
+ * @var string
31
+ */
32
  var $reporter_key;
33
 
34
+ /**
35
+ * @var array
36
+ */
37
+ var $display_error;
38
+
39
+
40
  /**
41
  * CFF_Error_Reporter constructor.
42
  */
43
  public function __construct() {
44
  $this->reporter_key = 'cff_error_reporter';
45
+ $this->errors = get_option( $this->reporter_key, [] );
46
+ if ( ! isset( $this->errors['connection'] ) ) {
47
+ $this->errors = array(
48
+ 'connection' => [],
49
+ 'resizing' => [],
50
+ 'database_create' => [],
51
+ 'upload_dir' => [],
52
+ 'accounts' => [],
53
+ 'error_log' => [],
54
+ 'action_log' => []
55
+ );
56
+ }
57
+
58
+
59
+ $this->display_error = [];
60
  $this->frontend_error = '';
61
+
62
+ add_action( 'cff_feed_issue_email', [ $this, 'maybe_trigger_report_email_send'] );
63
+ add_action( 'wp_ajax_cff_dismiss_critical_notice', [ $this, 'dismiss_critical_notice'] );
64
+ add_action( 'wp_footer', [ $this, 'critical_error_notice'] , 300 );
65
+ add_action( 'admin_notices', [ $this, 'admin_error_notices'] );
66
  }
67
+
68
  /**
69
  * @return array
70
  *
80
  *
81
  * @since 2.0/4.0
82
  */
83
+ public function add_error( $type, $args, $connected_account_term = false ) {
84
+ $connected_account = false;
85
+
86
+ $log_item = date( 'm-d H:i:s' ) . ' - ';
87
+
88
+ if( $connected_account_term !== false ){
89
+ if ( ! is_array( $connected_account_term ) ) {
90
+ $connected_account = CFF_Utils::cff_get_account( $connected_account_term );
91
+ } else {
92
+ $connected_account = $connected_account_term;
93
+ }
94
+ $log_item .= $args['error']['message'];
95
+ $this->add_connected_account_error( $connected_account, $type, $args );
96
+ }
97
+
98
+ //Access Token Error
99
+ if( $type === 'accesstoken' ){
100
  $accesstoken_error_exists = false;
101
+ if ( isset( $this->errors['accounts'] ) ) {
102
+ foreach ($this->errors['accounts'] as $account ) {
103
+ if ( $args['accesstoken'] === $account['accesstoken'] ) {
104
  $accesstoken_error_exists = true;
105
  }
106
  }
107
  }
 
108
  if ( !$accesstoken_error_exists ) {
109
+ $this->errors['accounts'][ $connected_account['id'] ][] = array(
110
+ 'accesstoken' => $args['accesstoken'],
111
+ 'post_id' => $args['post_id'],
112
+ 'critical' => true,
113
+ 'type' => $type,
114
+ 'errorno' => $args['errorno']
115
  );
116
+
117
  }
118
+ }
119
 
120
+ //Connection Error API & WP REMOTE CALL
121
+ if( $type === 'api' || $type === 'wp_remote_get' ){
122
+ $connection_details = array(
123
+ 'error_id' => ''
 
 
 
 
 
124
  );
125
+ $connection_details['critical'] = false;
126
+
127
+ if( isset( $args['error']['code'] ) ){
128
+ $connection_details['error_id'] = $args['error']['code'];
129
+ if ( $this->is_critical_error( $args ) ) {
130
+ $connection_details['critical'] = true;
131
+ }
132
+
133
+ }elseif( isset( $args['response'] ) && is_wp_error( $args['response'] )){
134
+ foreach ( $args['response']->errors as $key => $item ) {
135
+ $connection_details['error_id'] = $key;
136
+ }
137
+ $connection_details['critical'] = true;
138
+ }
139
+
140
+ $connection_details['error_message'] = $this->generate_error_message( $args, $connected_account );
141
+ $log_item .= $connection_details['error_message']['admin_message'];
142
+ $this->errors['connection'] = $connection_details;
143
+ #var_dump($connection_details);
144
  }
145
 
146
+ if ( $type === 'image_editor'
147
+ || $type === 'storage' ) {
148
+
149
+ $this->errors['resizing'] = $args;
150
+ $log_item .= $args;
151
+ }
152
+
153
+ if ( $type === 'database_create' ) {
154
+ $this->errors['database_create'] = $args;
155
+ $log_item .= $args;
156
+ }
157
+
158
+ if ( $type === 'upload_dir' ) {
159
+ $this->errors['upload_dir'] = $args;
160
+ $log_item .= $args;
161
+ }
162
+
163
+ $current_log = $this->errors['error_log'];
164
+ if ( is_array( $current_log ) && count( $current_log ) >= 10 ) {
165
+ reset( $current_log );
166
+ unset( $current_log[ key( $current_log ) ] );
167
+ }
168
+ $current_log[] = $log_item;
169
+ $this->errors['error_log'] = $current_log;
170
  update_option( $this->reporter_key, $this->errors, false );
171
+
172
  }
173
 
174
+
175
  /**
176
+ * Stores information about an encountered error related to a connected account
177
  *
178
+ * @param $connected_account array
179
+ * @param $error_type string
180
+ * @param $details mixed/array/string
181
+ *
182
+ * @since 2.19
183
+ */
184
+ public function add_connected_account_error( $connected_account, $error_type, $details ) {
185
+ $account_id = $connected_account['id'];
186
+ $this->errors['accounts'][ $account_id ][ $error_type ] = $details;
187
+
188
+ if ( $error_type === 'api' || $error_type === 'accesstoken' ) {
189
+ $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 3;
190
+ }
191
+
192
+ if ( isset( $details['error']['code'] )
193
+ && (int)$details['error']['code'] === 18 ) {
194
+ $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 15;
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @return mixed
200
+ *
201
+ * @since 2.19
202
+ */
203
+ public function get_error_log() {
204
+ return $this->errors['error_log'];
205
+ }
206
+
207
+
208
+
209
+ /**
210
+ * Creates an array of information for easy display of API errors
211
+ *
212
+ * @param $response
213
+ * @param array $connected_account
214
+ *
215
+ * @return array
216
+ *
217
+ * @since 2.19
218
+ */
219
+ public function generate_error_message( $response, $connected_account = array( 'username' => '' ) ) {
220
+ $error_message_return = array(
221
+ 'public_message' => '',
222
+ 'admin_message' => '',
223
+ 'frontend_directions' => '',
224
+ 'backend_directions' => '',
225
+ 'post_id' => get_the_ID(),
226
+ 'errorno' => '',
227
+ 'time' => time()
228
+ );
229
+
230
+ if( isset( $response['error']['code'] ) ){
231
+ $error_code = (int)$response['error']['code'];
232
+ $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $error_code );
233
+ $error_message_return['public_message'] = __( 'Error connecting to the Facebook API.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
234
+ $ppca_error = ( strpos($response['error']['message'], 'Public Content Access') !== false ) ? true : false;
235
+
236
+ $error_message_return['admin_message'] = ( $ppca_error)
237
+ ? '<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.'
238
+ : '<strong>' . $api_error_number_message . '</strong><br>' . $response['error']['message'];
239
+
240
+ $error_message_return['frontend_directions'] = ( $ppca_error )
241
+ ? '<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>'
242
+ : '<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>';
243
+
244
+ $error_message_return['backend_directions'] = ( $ppca_error )
245
+ ? '<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>'
246
+ : '<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>';
247
+
248
+ $error_message_return['errorno'] = $error_code;
249
+
250
+ }else{
251
+ $error_message_return['error_message'] = __( 'An unknown error has occurred.', 'custom-facebook-feed' );
252
+ $error_message_return['admin_message'] = json_encode( $response );
253
+ }
254
+
255
+ return $error_message_return;
256
+
257
+ }
258
+
259
+
260
+
261
+
262
+ /**
263
+ * Certain API errors are considered critical and will trigger
264
+ * the various notifications to users to correct them.
265
+ *
266
+ * @param $details
267
+ *
268
+ * @return bool
269
+ *
270
+ * @since 2.7/5.10
271
  */
272
+ public function is_critical_error( $details ) {
273
+ $error_code = (int)$details['error']['code'];
274
+
275
+ $critical_codes = array(
276
+ 10,
277
+ 100,
278
+ 200,
279
+ 190,
280
+ 104
281
+ );
282
+
283
+ return in_array( $error_code, $critical_codes, true );
284
+ }
285
 
286
+ /**
287
+ * @param $type
288
+ *
289
+ * @since 2.19
290
+ */
291
+ public function remove_error( $type, $connected_account = false ) {
292
+ $update = false;
293
+ if ( ! empty( $this->errors[ $type ] ) ) {
294
+ $this->errors[ $type ] = array();
295
+ $this->add_action_log( 'Cleared ' . $type .' error.' );
296
+ $update = true;
297
  }
298
 
299
+ if ( $update ) {
300
+ update_option( $this->reporter_key, $this->errors, false );
 
 
 
 
301
  }
302
+
303
  }
304
 
305
  public function remove_all_errors() {
306
  delete_option( $this->reporter_key );
 
307
  }
308
 
309
  /**
330
  }
331
 
332
  public function get_critical_errors() {
333
+ if ( ! $this->are_critical_errors() ) {
334
+ return '';
335
+ }
336
+ $error_message = $directions = false;
337
+ if ( isset( $this->errors['connection']['critical'] ) ) {
338
+ $errors = $this->get_errors();
339
+ $error = $errors['connection'];
340
+ $error_message_array = $error['error_message'];
341
+
342
+ $error_message = $error_message_array['admin_message'];
343
 
344
+ $directions = '<p class="cff-error-directions">';
345
+ $directions .= $error_message_array['backend_directions'];
346
+ $directions .= '<button data-url="'.get_the_permalink( $error_message_array['post_id'] ).'" class="cff-clear-errors-visit-page cff-space-left button button-secondary">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>';
347
+ $directions .= '</p>';
348
+ }else{
349
+
350
+ }
351
+
352
+
353
+ return [
354
+ 'error_message' => $error_message,
355
+ 'directions' => $directions
356
+ ];
357
  }
358
 
359
  public function are_critical_errors() {
360
  $are_errors = false;
 
361
  $errors = $this->get_errors();
362
+ if( isset( $errors['connection']['critical'] ) && $errors['connection']['critical'] === true){
363
+ return true;
364
+ }else{
365
+ $connected_accounts = CFF_Utils::cff_get_connected_accounts();
366
+ foreach ( $connected_accounts as $connected_account ) {
367
+ $connected_account = (array)$connected_account;
368
+ if ( isset( $this->errors['accounts'][ $connected_account['id' ] ]['api'] ) ) {
369
+ if ( isset( $this->errors['accounts'][ $connected_account['id'] ]['api']['error'] ) ) {
370
+ return $this->is_critical_error( $this->errors['accounts'][ $connected_account['id'] ]['api'] );
371
+ }
372
+ }
373
+ }
374
  }
375
 
376
+
377
  return $are_errors;
378
  }
379
 
380
+ /**
381
+ * Stores a time stamped string of information about
382
+ * actions that might lead to correcting an error
383
+ *
384
+ * @param string $log_item
385
+ *
386
+ * @since 2.19
387
+ */
388
+ public function add_action_log( $log_item ) {
389
+ $current_log = $this->errors['action_log'];
390
+
391
+ if ( is_array( $current_log ) && count( $current_log ) >= 10 ) {
392
+ reset( $current_log );
393
+ unset( $current_log[ key( $current_log ) ] );
394
+ }
395
+ $current_log[] = date( 'm-d H:i:s' ) . ' - ' . $log_item;
396
+
397
+ $this->errors['action_log'] = $current_log;
398
+ update_option( $this->reporter_key, $this->errors, false );
399
+ }
400
+
401
+ /**
402
+ * @return mixed
403
+ *
404
+ * @since 2.19
405
+ */
406
+ public function get_action_log() {
407
+ return $this->errors['action_log'];
408
+ }
409
+
410
 
411
  /**
412
  * Load the critical notice for logged in users.
432
  return;
433
  }
434
 
435
+ /** TODO: Match real option */
436
+ $options = get_option('cff_settings' );
437
  if ( isset( $options['disable_admin_notice'] ) && $options['disable_admin_notice'] === 'on' ) {
438
  return;
439
  }
444
  <img src="<?php echo CFF_PLUGIN_URL . 'admin/assets/img/cff-icon.png'; ?>" width="45" alt="Custom Facebook Feed icon" />
445
  </div>
446
  <div class="cff-critical-notice-text">
447
+ <h3><?php esc_html_e( 'Facebook Feed Critical Issue', 'custom-facebook-feed' ); ?></h3>
448
  <p>
449
  <?php
450
  $doc_url = admin_url() . 'admin.php?page=cff-top';
457
  </div>
458
  <style type="text/css">
459
  .cff-critical-notice {
460
+ position: fixed;
461
+ bottom: 20px;
462
+ right: 15px;
463
+ font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
464
+ background: #fff;
465
+ box-shadow: 0 0 10px 0 #dedede;
466
+ padding: 10px 10px;
467
+ display: flex;
468
+ align-items: center;
469
+ justify-content: center;
470
+ width: 325px;
471
+ max-width: calc( 100% - 30px );
472
+ border-radius: 6px;
473
+ transition: bottom 700ms ease;
474
+ z-index: 10000;
475
  }
476
 
477
  .cff-critical-notice h3 {
619
  $details = '<p>' . __( 'A Custom Facebook Feed on your website is currently unable to connect to Facebook to retrieve new posts. Don\'t worry, your feed is still being displayed using a cached version, but is no longer able to display new posts.', 'custom-facebook-feed' ) . '</p>';
620
  $details .= '<p>' . sprintf( __( 'This is caused by an issue with your Facebook account connecting to the Facebook API. For information on the exact issue and directions on how to resolve it, please visit the %sCustom Facebook Feed settings page%s on your website.', 'custom-facebook-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' ). '</p>';
621
  $message_content = '<h6 style="padding:0;word-wrap:normal;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;font-weight:bold;line-height:130%;font-size: 16px;color:#444444;text-align:inherit;margin:0 0 20px 0;Margin:0 0 20px 0;">' . $bold . '</h6>' . $details;
622
+ include_once CFF_PLUGIN_DIR . 'class-cff-education.php';
623
  $educator = new CFF_Education();
624
  $dyk_message = $educator->dyk_display();
625
  ob_start();
635
  if ( ! $this->are_critical_errors() ) {
636
  return;
637
  }
638
+ /** TODO: Match real option */
639
+ $options = get_option('cff_settings' );
640
 
641
  if ( isset( $options['enable_email_report'] ) && empty( $options['enable_email_report'] ) ) {
642
  return;
647
 
648
  public function admin_error_notices() {
649
  if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'cff-top', 'cff-style' )) ) {
650
+ $errors = $this->get_errors();
651
+ if ( ! empty( $errors ) && (! empty( $errors['database_create'] ) || ! empty( $errors['upload_dir'] )) ) : ?>
652
+ <div class="notice notice-warning is-dismissible sbi-admin-notice">
653
+ <?php if ( ! empty( $errors['database_create'] ) ) echo '<p>' . $errors['database_create'] . '</p>'; ?>
654
+ <?php if ( ! empty( $errors['upload_dir'] ) ) echo '<p>' . $errors['upload_dir'] . '</p>'; ?>
655
+ <p><?php _e( sprintf( 'Visit our %s page for help', '<a href="https://smashballoon.com/custom-facebook-feed/faq/" target="_blank">FAQ</a>' ), 'custom-facebook-feed' ); ?></p>
656
+ </div>
657
+
658
+ <?php endif;
659
  $errors = $this->get_critical_errors();
660
+ if ( $this->are_critical_errors() && is_array( $errors ) && $errors['error_message'] !== false && $errors['directions'] !== false ) :
661
+ ?>
662
+ <div class="notice notice-warning is-dismissible cff-admin-notice">
663
+ <p><strong><?php echo esc_html__( 'Custom Facebook Feed is encountering an error and your feeds may not be updating due to the following reasons:', 'custom-facebook-feed') ; ?></strong></p>
664
+
665
+ <?php echo $errors['error_message']; ?>
666
+
667
+ <?php echo $errors['directions']; ?>
668
+ </div>
669
+ <?php
670
+ endif;
671
+
672
+ /*
673
+ $errors = $this->get_critical_errors();
674
+ if ( $this->are_critical_errors() && ! empty( $errors ) ) :
675
  if ( isset( $errors['wp_remote_get'] ) ) {
676
  $error = $errors['wp_remote_get'];
677
  $error_message = $error['admin_message'];
692
  $directions .= '</p>';
693
  } else {
694
  $error = $errors['accesstoken'];
695
+
696
  $tokens = array();
697
  $post_id = false;
698
  foreach ( $error as $token ) {
699
  $tokens[] = $token['accesstoken'];
700
  $post_id = $token['post_id'];
701
  }
702
+ $error_message = sprintf( __( 'The access token %s is invalid or has expired.', 'custom-facebook-feed' ), implode( ', ', $tokens ) );
703
  $directions = '<p class="cff-error-directions">';
704
  $directions .= '<button class="button button-primary cff-reconnect">' . __( 'Reconnect Your Account', 'custom-facebook-feed' ) . '</button>';
705
  $directions .= '<button data-url="'.get_the_permalink( $post_id ).'" class="cff-clear-errors-visit-page cff-space-left button button-secondary">' . __( 'View Feed and Retry', 'custom-facebook-feed' ) . '</button>';
714
  <?php echo $directions; ?>
715
  </div>
716
  <?php endif;
717
+ */
718
+
719
  }
720
 
721
  }
inc/CFF_FB_Settings.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * Creates a list of necessary options and atts for the Shortcode class
6
  *
7
- * @since X.X.X
8
  */
9
  namespace CustomFacebookFeed;
10
  if ( ! defined( 'ABSPATH' ) ) {
@@ -37,7 +37,6 @@ class CFF_FB_Settings {
37
  */
38
  protected $access_token;
39
 
40
-
41
  /**
42
  * CFF_FB_Options constructor.
43
  *
@@ -45,7 +44,7 @@ class CFF_FB_Settings {
45
  * @param array $atts shortcode settings
46
  * @param array $options settings from the wp_options table
47
  *
48
- * @since X.X.X
49
  */
50
  public function __construct( $atts, $options ) {
51
  $this->atts = $atts;
@@ -218,11 +217,11 @@ class CFF_FB_Settings {
218
  'seelesstext' => isset( $options[ 'cff_see_less_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_see_less_text' ] ) ) : '',
219
  'photostext' => isset( $options[ 'cff_translate_photos_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_photos_text' ] ) ) : '',
220
  'phototext' => isset( $options[ 'cff_translate_photo_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_photo_text' ] ) ) : '',
221
- 'videotext' => isset( $options[ 'cff_translate_video_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_video_text' ] ) ) : '',
222
 
223
- 'learnmoretext' => isset( $options[ 'cff_translate_learn_more_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_learn_more_text' ] ) ) : '',
224
- 'shopnowtext' => isset( $options[ 'cff_translate_shop_now_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_shop_now_text' ] ) ) : '',
225
- 'messagepage' => isset( $options[ 'cff_translate_message_page_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_message_page_text' ] ) ) : '',
226
 
227
  'facebooklinktext' => isset( $options[ 'cff_facebook_link_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_facebook_link_text' ] ) ) : '',
228
  'sharelinktext' => isset( $options[ 'cff_facebook_share_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_facebook_share_text' ] ) ) : '',
@@ -250,18 +249,18 @@ class CFF_FB_Settings {
250
 
251
  /**
252
  * @return array
253
- *
254
- * @since X.X.X
255
  */
256
  public function get_settings() {
257
  return $this->settings;
258
  }
259
 
260
  /**
261
- * Get Include String for the Shortcode
262
  * @return array
263
- *
264
- * @since X.X.X
265
  */
266
  public function get_include_string() {
267
  $include_string = '';
@@ -279,7 +278,7 @@ class CFF_FB_Settings {
279
  'cff_show_link' => 'link,',
280
  'cff_show_like_box' => 'likebox,'
281
  ];
282
- foreach ($include_str_array as $key => $value) {
283
  if( isset( $this->options[$key] ) && $this->options[$key]) $include_string .= $value;
284
  }
285
  return $include_string;
@@ -287,44 +286,56 @@ class CFF_FB_Settings {
287
 
288
  /**
289
  * @return array
290
- *
291
- * @since X.X.X
292
  */
293
  public function get_id_and_token() {
294
  $id_and_token = [
295
  'id' => trim($this->settings['id']),
296
- 'token' => $this->settings['accesstoken']
 
297
  ];
298
  //If an 'account' is specified then use that instead of the Page ID/token from the settings
299
  $cff_account = trim($this->settings['account']);
 
 
300
  if( !empty( $cff_account ) ){
301
- $cff_connected_accounts = get_option('cff_connected_accounts');
302
  if( !empty($cff_connected_accounts) ){
303
- $cff_connected_accounts = json_decode( str_replace('\"','"', $cff_connected_accounts) );
304
  //Grab the ID and token from the connected accounts setting
305
  $id_and_token = [
306
  'id' => $cff_connected_accounts->{ $cff_account }->{'id'},
307
- 'token' => $cff_connected_accounts->{ $cff_account }->{'accesstoken'}
308
- ];
 
 
309
  //Replace the encryption string in the Access Token
310
  if (strpos($id_and_token['token'], '02Sb981f26534g75h091287a46p5l63') !== false) {
311
  $id_and_token['token'] = str_replace("02Sb981f26534g75h091287a46p5l63","",$id_and_token['token']);
312
  }
313
  }
314
- }
 
 
 
 
 
315
  $id_and_token['id'] = $this->check_page_id( $id_and_token['id'] );
316
  $this->page_id = $id_and_token['id'];
317
  $this->access_token = $id_and_token['token'];
 
318
  return $id_and_token;
319
  }
320
 
 
 
 
321
 
322
 
323
  /**
324
  *
325
  * Check the Page ID
326
  * @return array
327
- * @since X.X.X
328
  */
329
  function check_page_id( $page_id ){
330
  //If user pastes their full URL into the Page ID field then strip it out
@@ -336,4 +347,24 @@ class CFF_FB_Settings {
336
  return $page_id;
337
  }
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  }
4
  *
5
  * Creates a list of necessary options and atts for the Shortcode class
6
  *
7
+ * @since 2.19
8
  */
9
  namespace CustomFacebookFeed;
10
  if ( ! defined( 'ABSPATH' ) ) {
37
  */
38
  protected $access_token;
39
 
 
40
  /**
41
  * CFF_FB_Options constructor.
42
  *
44
  * @param array $atts shortcode settings
45
  * @param array $options settings from the wp_options table
46
  *
47
+ * @since 2.19
48
  */
49
  public function __construct( $atts, $options ) {
50
  $this->atts = $atts;
217
  'seelesstext' => isset( $options[ 'cff_see_less_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_see_less_text' ] ) ) : '',
218
  'photostext' => isset( $options[ 'cff_translate_photos_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_photos_text' ] ) ) : '',
219
  'phototext' => isset( $options[ 'cff_translate_photo_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_photo_text' ] ) ) : '',
220
+ 'videotext' => isset( $options[ 'cff_translate_video_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_video_text' ] ) ) : '',
221
 
222
+ 'learnmoretext' => isset( $options[ 'cff_translate_learn_more_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_learn_more_text' ] ) ) : '',
223
+ 'shopnowtext' => isset( $options[ 'cff_translate_shop_now_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_shop_now_text' ] ) ) : '',
224
+ 'messagepage' => isset( $options[ 'cff_translate_message_page_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_translate_message_page_text' ] ) ) : '',
225
 
226
  'facebooklinktext' => isset( $options[ 'cff_facebook_link_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_facebook_link_text' ] ) ) : '',
227
  'sharelinktext' => isset( $options[ 'cff_facebook_share_text' ] ) ? stripslashes( esc_attr( $options[ 'cff_facebook_share_text' ] ) ) : '',
249
 
250
  /**
251
  * @return array
252
+ *
253
+ * @since 2.19
254
  */
255
  public function get_settings() {
256
  return $this->settings;
257
  }
258
 
259
  /**
260
+ * Get Include String for the Shortcode
261
  * @return array
262
+ *
263
+ * @since 2.19
264
  */
265
  public function get_include_string() {
266
  $include_string = '';
278
  'cff_show_link' => 'link,',
279
  'cff_show_like_box' => 'likebox,'
280
  ];
281
+ foreach ($include_str_array as $key => $value) {
282
  if( isset( $this->options[$key] ) && $this->options[$key]) $include_string .= $value;
283
  }
284
  return $include_string;
286
 
287
  /**
288
  * @return array
289
+ *
290
+ * @since 2.19
291
  */
292
  public function get_id_and_token() {
293
  $id_and_token = [
294
  'id' => trim($this->settings['id']),
295
+ 'token' => $this->settings['accesstoken'],
296
+ 'pagetype' => $this->settings['pagetype']
297
  ];
298
  //If an 'account' is specified then use that instead of the Page ID/token from the settings
299
  $cff_account = trim($this->settings['account']);
300
+ $cff_connected_accounts = get_option('cff_connected_accounts');
301
+ $cff_connected_accounts = json_decode( str_replace('\"','"', $cff_connected_accounts) );
302
  if( !empty( $cff_account ) ){
 
303
  if( !empty($cff_connected_accounts) ){
 
304
  //Grab the ID and token from the connected accounts setting
305
  $id_and_token = [
306
  'id' => $cff_connected_accounts->{ $cff_account }->{'id'},
307
+ 'token' => $cff_connected_accounts->{ $cff_account }->{'accesstoken'},
308
+ 'name' => $cff_connected_accounts->{ $cff_account }->{'name'},
309
+ 'pagetype' => $cff_connected_accounts->{ $cff_account }->{'pagetype'}
310
+ ];
311
  //Replace the encryption string in the Access Token
312
  if (strpos($id_and_token['token'], '02Sb981f26534g75h091287a46p5l63') !== false) {
313
  $id_and_token['token'] = str_replace("02Sb981f26534g75h091287a46p5l63","",$id_and_token['token']);
314
  }
315
  }
316
+ }else{
317
+ if( !empty($cff_connected_accounts) ){
318
+ $id_and_token['name'] = isset($cff_connected_accounts->{ $this->settings['id'] }->{'name'}) ? $cff_connected_accounts->{ $this->settings['id'] }->{'name'} : $this->settings['id'];
319
+ $id_and_token['pagetype'] = isset($cff_connected_accounts->{ $this->settings['id'] }->{'pagetype'}) ? $cff_connected_accounts->{ $this->settings['id'] }->{'pagetype'} : $this->settings['pagetype'];
320
+ }
321
+ }
322
  $id_and_token['id'] = $this->check_page_id( $id_and_token['id'] );
323
  $this->page_id = $id_and_token['id'];
324
  $this->access_token = $id_and_token['token'];
325
+
326
  return $id_and_token;
327
  }
328
 
329
+ function set_page_id($page_id){
330
+ $this->settings['id'] = $page_id;
331
+ }
332
 
333
 
334
  /**
335
  *
336
  * Check the Page ID
337
  * @return array
338
+ * @since 2.19
339
  */
340
  function check_page_id( $page_id ){
341
  //If user pastes their full URL into the Page ID field then strip it out
347
  return $page_id;
348
  }
349
 
350
+ public static function feed_type_and_terms_display($connected_accounts, $result, $database_settings) {
351
+ $feeds_list = explode(',', $result['feed_id']);
352
+ $types = []; $names =[];
353
+ foreach ($feeds_list as $feed_id) {
354
+ $account_settings = new CFF_FB_Settings(json_decode($result['shortcode_atts']), $database_settings);
355
+ $account_settings->set_page_id($feed_id);
356
+ $account_info = $account_settings->get_id_and_token();
357
+ if(!in_array($account_info['pagetype'], $types)){
358
+ array_push($types, $account_info['pagetype']);
359
+ }
360
+ $account_name = ($account_info['name'] != '') ? urldecode($account_info['name']) : $feed_id;
361
+ array_push($names, $account_name);
362
+
363
+ }
364
+ return [
365
+ 'type' => $types,
366
+ 'name' => $names,
367
+ ];
368
+ }
369
+
370
  }
inc/CFF_Feed_Locator.php ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class CFF_Feed_Locator
4
+ *
5
+ *
6
+ * @since 2.19
7
+ */
8
+ namespace CustomFacebookFeed;
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ class CFF_Feed_Locator{
12
+
13
+ private $feed_details;
14
+
15
+ private $expiration_time;
16
+
17
+ private $matching_entries;
18
+
19
+ public function __construct( $feed_details ) {
20
+ $this->feed_details = $feed_details;
21
+
22
+ $this->matching_entries = array();
23
+
24
+ $this->expiration_time = time() - 2 * WEEK_IN_SECONDS;
25
+ }
26
+
27
+ /**
28
+ * Returns records that match the post ID and feed ID
29
+ * of the feed being located
30
+ *
31
+ * @return array
32
+ *
33
+ * @since 2.19
34
+ */
35
+ public function retrieve_matching_entries() {
36
+ global $wpdb;
37
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
38
+
39
+ $results = $wpdb->get_results( $wpdb->prepare("
40
+ SELECT *
41
+ FROM $feed_locator_table_name
42
+ WHERE post_id = %d
43
+ AND feed_id = %s", $this->feed_details['location']['post_id'], $this->feed_details['feed_id'] ),ARRAY_A );
44
+
45
+ return $results;
46
+ }
47
+
48
+ /**
49
+ * Add feed being located to the database
50
+ *
51
+ * @since 2.19
52
+ */
53
+ public function insert_entry() {
54
+ global $wpdb;
55
+
56
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
57
+
58
+ $affected = $wpdb->query( $wpdb->prepare( "INSERT INTO $feed_locator_table_name
59
+ (feed_id,
60
+ post_id,
61
+ html_location,
62
+ shortcode_atts,
63
+ last_update)
64
+ VALUES (
65
+ %s,
66
+ %d,
67
+ %s,
68
+ %s,
69
+ %s);",
70
+ $this->feed_details['feed_id'],
71
+ $this->feed_details['location']['post_id'],
72
+ $this->feed_details['location']['html'],
73
+ CFF_Utils::cff_json_encode( $this->feed_details['atts'] ),
74
+ date( 'Y-m-d H:i:s' ) ) );
75
+ }
76
+
77
+ /**
78
+ * Update a record based on the existing "id" column. Location can change
79
+ * from "unknown" to one of footer, content, header, or sidebar.
80
+ *
81
+ * @param $id
82
+ * @param $location
83
+ *
84
+ * @since 2.19
85
+ */
86
+ public function update_entry( $id, $location ) {
87
+ global $wpdb;
88
+
89
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
90
+
91
+ $query = $wpdb->query( $wpdb->prepare( "
92
+ UPDATE $feed_locator_table_name
93
+ SET last_update = %s, html_location = %s
94
+ WHERE id = %d;", date( 'Y-m-d H:i:s' ), $location, $id ) );
95
+ }
96
+
97
+ /**
98
+ * Processes a feed being located based on whether or not the record
99
+ * exists as well as whether or not an unknown location needs to be
100
+ * updated.
101
+ *
102
+ * @since 2.19
103
+ */
104
+ public function add_or_update_entry() {
105
+ if ( empty( $this->feed_details['feed_id'] ) ) {
106
+ return;
107
+ }
108
+
109
+ $this->matching_entries = $this->retrieve_matching_entries();
110
+
111
+ if ( empty( $this->matching_entries ) ) {
112
+ $this->insert_entry();
113
+ } else {
114
+ $matching_indices = array();
115
+ $matched_location = false;
116
+ $non_unknown_match = false;
117
+ $unknown_match = false;
118
+
119
+ foreach ( $this->matching_entries as $index => $matching_entry ) {
120
+ $shortcode_atts = json_decode( $matching_entry['shortcode_atts'], true );
121
+ $shortcode_atts = ( $shortcode_atts == null) ? [] : $shortcode_atts;
122
+ $atts_diff = array_diff($shortcode_atts , $this->feed_details['atts'] ); // determines if the shortcode settings match the shortcode settings of an existing feed
123
+ if ( empty( $atts_diff ) ) {
124
+ $matching_indices[] = $matching_entry['id'];
125
+ if ( $matching_entry['html_location'] === $this->feed_details['location']['html'] ) {
126
+ $matched_location = $index;
127
+ $this->update_entry( $matching_entry['id'], $matching_entry['html_location'] );
128
+ }
129
+ if ( $matching_entry['html_location'] !== 'unknown' ) {
130
+ $non_unknown_match = $index;
131
+ } else {
132
+ $unknown_match = $index;
133
+ }
134
+ }
135
+ }
136
+
137
+ if ( false === $matched_location ) {
138
+ // if there is no matched location, there is only one feed on the page, and the feed being checked has an unknown location, update the known location
139
+ if ( count( $matching_indices ) === 1
140
+ && $this->feed_details['location']['html'] === 'unknown'
141
+ && false !== $non_unknown_match ) {
142
+
143
+ $this->update_entry( $this->matching_entries[ $non_unknown_match ]['id'], $this->matching_entries[ $non_unknown_match ]['html_location'] );
144
+ } else {
145
+ if ( $this->feed_details['location']['html'] !== 'unknown'
146
+ && false !== $unknown_match ) {
147
+ $this->update_entry( $this->matching_entries[ $unknown_match ]['id'], $this->feed_details['location']['html'] );
148
+ } else {
149
+ $this->insert_entry();
150
+ }
151
+
152
+ }
153
+ }
154
+
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Old feeds are only detected once a day to keep load on the server low.
160
+ *
161
+ * @return bool
162
+ *
163
+ * @since 2.19
164
+ */
165
+ public static function should_clear_old_locations() {
166
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
167
+ $last_old_feed_check = isset( $cff_statuses_option['feed_locator']['last_check'] ) ? $cff_statuses_option['feed_locator']['last_check'] : 0;
168
+
169
+ return $last_old_feed_check < time() - DAY_IN_SECONDS;
170
+ }
171
+
172
+ /**
173
+ * Old feeds are removed if they haven't been updated in two weeks.
174
+ *
175
+ * @since 2.19
176
+ */
177
+ public static function delete_old_locations() {
178
+ global $wpdb;
179
+
180
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
181
+ $two_weeks_ago = date( 'Y-m-d H:i:s', time() - 2 * WEEK_IN_SECONDS );
182
+
183
+ $affected = $wpdb->query( $wpdb->prepare(
184
+ "DELETE FROM $feed_locator_table_name WHERE last_update < %s;", $two_weeks_ago ) );
185
+
186
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
187
+ $cff_statuses_option['feed_locator']['last_check'] = time();
188
+ if ( ! isset( $cff_statuses_option['feed_locator']['initialized'] ) ) {
189
+ $cff_statuses_option['feed_locator']['initialized'] = time();
190
+ }
191
+
192
+ update_option( 'cff_statuses', $cff_statuses_option, true );
193
+ }
194
+
195
+ /**
196
+ * Feeds are located with the page load randomly (5% or 1/30 loads)
197
+ * to decrease load on the server.
198
+ *
199
+ * If the locating just started (within 5 minutes) it is run more often
200
+ * to collect feed locations quickly.
201
+ *
202
+ * @return bool
203
+ *
204
+ * @since 2.19
205
+ */
206
+ public static function should_do_locating() {
207
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
208
+ if ( isset( $cff_statuses_option['feed_locator']['initialized'] )
209
+ && $cff_statuses_option['feed_locator']['initialized'] < (time() - 300) ) {
210
+ $should_do_locating = rand( 1, 10 ) === 10;
211
+ } else {
212
+ $should_do_locating = rand( 1, 30 ) === 30;
213
+ }
214
+ $should_do_locating = apply_filters( 'cff_should_do_locating', $should_do_locating );
215
+
216
+ return $should_do_locating;
217
+ }
218
+
219
+
220
+ /**
221
+ * Simliar to the should_do_locating method but will add an additional
222
+ * database query to see if there is a feed with an unknown location that
223
+ * matches the details of the feed in question.
224
+ *
225
+ * @param $feed_id
226
+ * @param $post_id
227
+ *
228
+ * @return bool
229
+ *
230
+ * @since 2.19
231
+ */
232
+ public static function should_do_ajax_locating( $feed_id, $post_id ) {
233
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
234
+ if ( isset( $cff_statuses_option['feed_locator']['initialized'] )
235
+ && $cff_statuses_option['feed_locator']['initialized'] < (time() - 300) ) {
236
+ $should_do_locating = rand( 1, 10 ) === 10;
237
+ } else {
238
+ $should_do_locating = rand( 1, 30 ) === 30;
239
+ }
240
+ if ( $should_do_locating ) {
241
+ $should_do_locating = CFF_Feed_Locator::entries_need_locating( $feed_id, $post_id );
242
+ }
243
+
244
+ $should_do_locating = apply_filters( 'cff_should_do_ajax_locating', $should_do_locating );
245
+
246
+ return $should_do_locating;
247
+ }
248
+
249
+ /**
250
+ * Feeds are located with the page load randomly (1/30 loads)
251
+ * to decrease load on the server.
252
+ *
253
+ * If the locating just started (within 5 minutes) it is run more often
254
+ * to collect feed locations quickly.
255
+ *
256
+ * @param $feed_id
257
+ * @param $post_id
258
+ *
259
+ * @return bool
260
+ *
261
+ * @since 2.19
262
+ */
263
+ public static function entries_need_locating( $feed_id, $post_id ) {
264
+ global $wpdb;
265
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
266
+
267
+ $one_day_ago = date( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS );
268
+
269
+ $results = $wpdb->get_results( $wpdb->prepare("
270
+ SELECT id
271
+ FROM $feed_locator_table_name
272
+ WHERE html_location = 'unknown'
273
+ AND last_update < %s
274
+ AND feed_id = %s
275
+ AND post_id = %d
276
+ LIMIT 1;", $one_day_ago, $feed_id, $post_id ),ARRAY_A );
277
+
278
+ return isset( $results[0] );
279
+ }
280
+
281
+
282
+
283
+ /**
284
+ * A custom table stores locations
285
+ *
286
+ * @since 2.19
287
+ */
288
+ public static function create_table() {
289
+ global $wpdb;
290
+
291
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
292
+
293
+ if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) != $feed_locator_table_name ) {
294
+ $sql = "CREATE TABLE " . $feed_locator_table_name . " (
295
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
296
+ feed_id VARCHAR(50) DEFAULT '' NOT NULL,
297
+ post_id BIGINT(20) UNSIGNED NOT NULL,
298
+ html_location VARCHAR(50) DEFAULT 'unknown' NOT NULL,
299
+ shortcode_atts LONGTEXT NOT NULL,
300
+ last_update DATETIME
301
+ );";
302
+ $wpdb->query( $sql );
303
+ }
304
+ $error = $wpdb->last_error;
305
+ $query = $wpdb->last_query;
306
+ $had_error = false;
307
+ if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) != $feed_locator_table_name ) {
308
+ $had_error = true;
309
+ #\cff_main()->cff_error_reporter->add_error( 'database_create', '<strong>' . __( 'There was an error when trying to create the database tables used to locate feeds.', 'custom-facebook-feed' ) .'</strong><br>' . $error . '<br><code>' . $query . '</code>' );
310
+ }
311
+
312
+ if ( ! $had_error ) {
313
+ $wpdb->query( "ALTER TABLE $feed_locator_table_name ADD INDEX feed_id (feed_id)" );
314
+ $wpdb->query( "ALTER TABLE $feed_locator_table_name ADD INDEX post_id (post_id)" );
315
+
316
+ #\cff_main()->cff_error_reporter->remove_error( 'database_create' );
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Counts the number of unique feeds in the database.
322
+ *
323
+ * @return int
324
+ *
325
+ * @since 2.19
326
+ */
327
+ public static function count_unique() {
328
+ global $wpdb;
329
+
330
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
331
+ $results_content = $wpdb->get_results( "
332
+ SELECT COUNT(*) AS num_entries
333
+ FROM $feed_locator_table_name
334
+ WHERE html_location = 'content'
335
+ ", ARRAY_A );
336
+
337
+ $results_other = $wpdb->get_results( "
338
+ SELECT COUNT(*) AS num_entries
339
+ FROM $feed_locator_table_name
340
+ WHERE html_location != 'content'
341
+ AND html_location != 'unknown'
342
+ GROUP BY feed_id
343
+ ", ARRAY_A );
344
+ //var_dump( $results_other );
345
+
346
+ $total = 0;
347
+ if ( isset( $results_content[0]['num_entries'] ) ) {
348
+ $total += (int)$results_content[0]['num_entries'];
349
+ }
350
+ if ( isset( $results_other[0]['num_entries'] ) ) {
351
+ $total += (int)$results_other[0]['num_entries'];
352
+ }
353
+
354
+ return $total;
355
+ }
356
+
357
+ /**
358
+ * Creates a summary of the located feeds in an array
359
+ *
360
+ * @return array
361
+ *
362
+ * @since 2.19
363
+ */
364
+ public static function summary() {
365
+ global $wpdb;
366
+
367
+ $feed_locator_table_name = esc_sql( $wpdb->prefix . CFF_FEED_LOCATOR );
368
+
369
+ $locations = array(
370
+ array(
371
+ 'label' => __( 'Content', 'custom-facebook-feed' ),
372
+ 'html_locations' => array( 'content', 'unknown' )
373
+ ),
374
+ array(
375
+ 'label' => __( 'Header', 'custom-facebook-feed' ),
376
+ 'html_locations' => array( 'header' ),
377
+ 'group_by' => 'feed_id'
378
+ ),
379
+ array(
380
+ 'label' => __( 'Sidebar', 'custom-facebook-feed' ),
381
+ 'html_locations' => array( 'sidebar' ),
382
+ 'group_by' => 'feed_id'
383
+ ),
384
+ array(
385
+ 'label' => __( 'Footer', 'custom-facebook-feed' ),
386
+ 'html_locations' => array( 'footer' ),
387
+ 'group_by' => 'feed_id'
388
+ )
389
+ );
390
+
391
+ $one_result_found = false;
392
+
393
+ foreach ( $locations as $key => $location ) {
394
+ $in = implode( "', '", $location['html_locations'] );
395
+ $group_by = isset( $location['group_by'] ) ? "GROUP BY " . $location['group_by'] : "";
396
+ $results = $wpdb->get_results("
397
+ SELECT *
398
+ FROM $feed_locator_table_name
399
+ WHERE html_location IN ('$in')
400
+ $group_by
401
+ ORDER BY last_update ASC",ARRAY_A );
402
+
403
+ if ( isset( $results[0] ) ) {
404
+ $one_result_found = true;
405
+ }
406
+
407
+ $locations[ $key ]['results'] = $results;
408
+ }
409
+
410
+ if ( ! $one_result_found ) {
411
+ return array();
412
+ }
413
+
414
+ return $locations;
415
+ }
416
+
417
+ /**
418
+ * Do Locator Ajax Process
419
+ *
420
+ *
421
+ * @since 2.19
422
+ */
423
+ public static function cff_do_locator(){
424
+ if ( ! isset( $_POST['feed_id'] ) ) {
425
+ die( 'invalid feed ID');
426
+ }
427
+ $feed_id = sanitize_text_field( $_POST['feed_id'] );
428
+ $atts_raw = isset( $_POST['atts'] ) ? json_decode( stripslashes( $_POST['atts'] ), true ) : array();
429
+ if ( is_array( $atts_raw ) ) {
430
+ array_map( 'sanitize_text_field', $atts_raw );
431
+ } else {
432
+ $atts_raw = array();
433
+ }
434
+ $atts = $atts_raw; // now sanitized
435
+
436
+ $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown';
437
+ $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
438
+ $feed_details = array(
439
+ 'feed_id' => $feed_id,
440
+ 'atts' => $atts,
441
+ 'location' => array(
442
+ 'post_id' => $post_id,
443
+ 'html' => $location
444
+ )
445
+ );
446
+ CFF_Feed_Locator::do_background_tasks( $feed_details );
447
+ wp_die( 'locating success' );
448
+ }
449
+
450
+
451
+ /**
452
+ * Do Background tasks
453
+ *
454
+ *
455
+ * @since 2.19
456
+ */
457
+
458
+ public static function do_background_tasks( $feed_details ){
459
+ if(isset($feed_details['shortcode_atts']) && trim( $feed_details['shortcode_atts'] ) == ""){
460
+ $feed_details['shortcode_atts'] = [];
461
+ }
462
+
463
+ $locator = new CFF_Feed_Locator( $feed_details );
464
+ $locator->add_or_update_entry();
465
+ if ( $locator->should_clear_old_locations() ) {
466
+ $locator->delete_old_locations();
467
+ }
468
+ }
469
+
470
+
471
+ }
inc/CFF_Shortcode.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Custom Facebook Feed Main Shortcode Class
4
  *
5
- * @since X.X.X
6
  */
7
 
8
  namespace CustomFacebookFeed;
@@ -42,7 +42,7 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
42
  /**
43
  * Shortcode constructor
44
  *
45
- * @since X.X.X
46
  */
47
  public function __construct(){
48
  $this->init();
@@ -53,7 +53,7 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
53
  /**
54
  * Init.
55
  *
56
- * @since X.X.X
57
  */
58
  public function init(){
59
  add_shortcode('custom-facebook-feed', array($this, 'display_cff'));
@@ -65,7 +65,7 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
65
  *
66
  * Returns a list of posts JSON form the FaceBook API API
67
  *
68
- * @since X.X.X
69
  * @return JSON OBJECT
70
  */
71
  public function get_feed_json( $graph_query, $cff_post_limit, $cff_locale, $cff_show_access_token, $cache_seconds, $cff_cache_time, $show_posts_by ){
@@ -141,7 +141,7 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
141
  *
142
  * Getting the FaceBook Graph Query depending on the settings
143
  *
144
- * @since X.X.X
145
  * @return array
146
  */
147
  public function get_graph_query($show_posts_by, $cff_is_group){
@@ -182,7 +182,7 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
182
  *
183
  * Getting the FaceBook Graph Query depending on the settings
184
  *
185
- * @since X.X.X
186
  * @return int
187
  */
188
  public function get_post_limit($show_posts){
@@ -202,7 +202,39 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
202
  }
203
 
204
 
 
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
 
208
 
@@ -210,10 +242,11 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
210
  * Display.
211
  * The main Shortcode display
212
  *
213
- * @since X.X.X
214
  */
215
  public function display_cff($atts) {
216
  $this->options = get_option('cff_style_settings');
 
217
  $this->fb_feed_settings = new CFF_FB_Settings($atts, $this->options);
218
  $this->atts = $this->fb_feed_settings->get_settings();
219
  $id_and_token = $this->fb_feed_settings->get_id_and_token();
@@ -233,7 +266,6 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
233
  ($cff_page_type == 'group') ? $cff_is_group = true : $cff_is_group = false;
234
 
235
 
236
-
237
  $cff_show_author = $this->atts[ 'showauthornew' ];
238
  $cff_cache_time = $this->atts[ 'cachetime' ];
239
  $cff_locale = $this->atts[ 'locale' ];
@@ -947,17 +979,18 @@ class CFF_Shortcode extends CFF_Shortcode_Display{
947
  $cff_content .= CFF_Utils::print_template_part( 'credit', get_defined_vars());
948
 
949
  //End the feed
 
950
  $cff_content .= '</div></div><div class="cff-clear"></div>';
951
 
952
- //Add the Like Box outside
953
  if ($cff_like_box_position == 'bottom' && $cff_show_like_box && $cff_like_box_outside) $cff_content .= $like_box;
954
 
955
- //If the feed is loaded via Ajax then put the scripts into the shortcode itself
956
  $cff_content .= $this->ajax_loaded();
957
  $cff_content .= '</div>';
958
 
959
  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>';
960
- //Return our feed HTML to display
961
  return $cff_content;
962
  }
963
 
2
  /**
3
  * Custom Facebook Feed Main Shortcode Class
4
  *
5
+ * @since 2.19
6
  */
7
 
8
  namespace CustomFacebookFeed;
42
  /**
43
  * Shortcode constructor
44
  *
45
+ * @since 2.19
46
  */
47
  public function __construct(){
48
  $this->init();
53
  /**
54
  * Init.
55
  *
56
+ * @since 2.19
57
  */
58
  public function init(){
59
  add_shortcode('custom-facebook-feed', array($this, 'display_cff'));
65
  *
66
  * Returns a list of posts JSON form the FaceBook API API
67
  *
68
+ * @since 2.19
69
  * @return JSON OBJECT
70
  */
71
  public function get_feed_json( $graph_query, $cff_post_limit, $cff_locale, $cff_show_access_token, $cache_seconds, $cff_cache_time, $show_posts_by ){
141
  *
142
  * Getting the FaceBook Graph Query depending on the settings
143
  *
144
+ * @since 2.19
145
  * @return array
146
  */
147
  public function get_graph_query($show_posts_by, $cff_is_group){
182
  *
183
  * Getting the FaceBook Graph Query depending on the settings
184
  *
185
+ * @since 2.19
186
  * @return int
187
  */
188
  public function get_post_limit($show_posts){
202
  }
203
 
204
 
205
+ function cff_get_shortcode_data_attribute_html( $feed_options ) {
206
 
207
+ //If an access token is set in the shortcode then set "use own access token" to be enabled
208
+ if( isset($feed_options['accesstoken']) ){
209
+ //Add an encryption string to protect token
210
+ if ( strpos($feed_options['accesstoken'], ',') !== false ) {
211
+ //If there are multiple tokens then just add the string after the colon to avoid having to de/reconstruct the array
212
+ $feed_options['accesstoken'] = str_replace(":", ":02Sb981f26534g75h091287a46p5l63", $feed_options['accesstoken']);
213
+ } else {
214
+ //Add an encryption string to protect token
215
+ $feed_options['accesstoken'] = substr_replace($feed_options['accesstoken'], '02Sb981f26534g75h091287a46p5l63', 25, 0);
216
+ }
217
+ $feed_options['ownaccesstoken'] = 'on';
218
+ }
219
+
220
+ if( !empty($feed_options) ){
221
+ $json_data = '{';
222
+ $i = 0;
223
+ $len = count($feed_options);
224
+ foreach( $feed_options as $key => $value ) {
225
+ if ($i == $len - 1) {
226
+ $json_data .= '&quot;'.$key.'&quot;: &quot;'.$value.'&quot;';
227
+ } else {
228
+ $json_data .= '&quot;'.$key.'&quot;: &quot;'.$value.'&quot;, ';
229
+ }
230
+ $i++;
231
+ }
232
+ $json_data .= '}';
233
+
234
+ return $json_data;
235
+ }
236
+
237
+ }
238
 
239
 
240
 
242
  * Display.
243
  * The main Shortcode display
244
  *
245
+ * @since 2.19
246
  */
247
  public function display_cff($atts) {
248
  $this->options = get_option('cff_style_settings');
249
+ $data_att_html = $this->cff_get_shortcode_data_attribute_html( $atts );
250
  $this->fb_feed_settings = new CFF_FB_Settings($atts, $this->options);
251
  $this->atts = $this->fb_feed_settings->get_settings();
252
  $id_and_token = $this->fb_feed_settings->get_id_and_token();
266
  ($cff_page_type == 'group') ? $cff_is_group = true : $cff_is_group = false;
267
 
268
 
 
269
  $cff_show_author = $this->atts[ 'showauthornew' ];
270
  $cff_cache_time = $this->atts[ 'cachetime' ];
271
  $cff_locale = $this->atts[ 'locale' ];
979
  $cff_content .= CFF_Utils::print_template_part( 'credit', get_defined_vars());
980
 
981
  //End the feed
982
+ $cff_content .= '<input class="cff-pag-url" type="hidden" data-cff-shortcode="'.$data_att_html.'" data-post-id="' . get_the_ID() . '" data-feed-id="'.$atts['id'].'">';
983
  $cff_content .= '</div></div><div class="cff-clear"></div>';
984
 
985
+ //Add the Like Box outside
986
  if ($cff_like_box_position == 'bottom' && $cff_show_like_box && $cff_like_box_outside) $cff_content .= $like_box;
987
 
988
+ //If the feed is loaded via Ajax then put the scripts into the shortcode itself
989
  $cff_content .= $this->ajax_loaded();
990
  $cff_content .= '</div>';
991
 
992
  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>';
993
+ //Return our feed HTML to display
994
  return $cff_content;
995
  }
996
 
inc/CFF_Shortcode_Display.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * Contains all the functions for the diplay purposes! (Generates CSS, CSS Classes, HTML Attributes...)
6
  *
7
- * @since X.X.X
8
  */
9
 
10
  namespace CustomFacebookFeed;
@@ -24,7 +24,7 @@ class CFF_Shortcode_Display {
24
  *
25
  * Check if is Ajax Loaded then put the script inside the content
26
  *
27
- * @since X.X.X
28
  */
29
  public function ajax_loaded(){
30
  $ajax_loaded_content = '';
@@ -45,7 +45,7 @@ class CFF_Shortcode_Display {
45
  *
46
  * Returns an array containing all the styles for the Feed
47
  *
48
- * @since X.X.X
49
  * @return String
50
  */
51
  public function style_compiler( $style_array ){
@@ -68,7 +68,7 @@ class CFF_Shortcode_Display {
68
  *
69
  * Returns custom CSS classes for the CFF list container shortcode
70
  *
71
- * @since X.X.X
72
  * @return Array
73
  */
74
  public function feed_style_class_compiler(){
@@ -143,7 +143,7 @@ class CFF_Shortcode_Display {
143
  *
144
  * Returns the post item feed class atrribute
145
  *
146
- * @since X.X.X
147
  * @return Array
148
  */
149
  public function get_item_attributes($cff_post_type, $cff_album, $cff_post_bg_color_check, $cff_post_style, $cff_box_shadow, $name, $cff_post_id){
@@ -175,7 +175,7 @@ class CFF_Shortcode_Display {
175
  *
176
  * Returns the post item feed style attribute
177
  *
178
- * @since X.X.X
179
  * @return String
180
  */
181
  public function get_post_item_style(){
@@ -197,7 +197,7 @@ class CFF_Shortcode_Display {
197
  * Style Attribute
198
  * Generates the Style attribute for the Feed Elements
199
  *
200
- * @since X.X.X
201
  * @return String
202
  */
203
  public function get_style_attribute( $element ){
@@ -304,7 +304,7 @@ class CFF_Shortcode_Display {
304
  * Style Attribute
305
  * Generates the Style attribute for the Feed Elements
306
  *
307
- * @since X.X.X
308
  * @return String
309
  */
310
  public function check_show_section( $section_name ){
@@ -320,7 +320,7 @@ class CFF_Shortcode_Display {
320
  * Get Author Template Data
321
  * Get Authors the data for the templates
322
  *
323
- * @since X.X.X
324
  * -----------------------------------------
325
  */
326
 
@@ -366,7 +366,7 @@ class CFF_Shortcode_Display {
366
  * Get Date Data
367
  * Get Date the data for the templates
368
  *
369
- * @since X.X.X
370
  * -----------------------------------------
371
  */
372
  static function get_date( $options, $atts, $news ){
@@ -406,7 +406,7 @@ class CFF_Shortcode_Display {
406
  * Get Media Link Data
407
  * Get the Media link data for the templates
408
  *
409
- * @since X.X.X
410
  * -----------------------------------------
411
  */
412
  static function get_media_link_text( $atts, $cff_post_type, $cff_album ){
@@ -425,7 +425,7 @@ class CFF_Shortcode_Display {
425
  * Get Post Link Data
426
  * Get the Post link data for the templates
427
  *
428
- * @since X.X.X
429
  * -----------------------------------------
430
  */
431
  static function get_post_link_social_links( $link, $cff_post_text_to_share ){
@@ -480,7 +480,7 @@ class CFF_Shortcode_Display {
480
  * Get Post Text Data
481
  * Get the Post text data for the templates
482
  *
483
- * @since X.X.X
484
  * -----------------------------------------
485
  */
486
  static function get_post_text_title_format( $atts ){
@@ -549,7 +549,7 @@ class CFF_Shortcode_Display {
549
  * Get Shared Link Data
550
  * Get the Shared Link data for the templates
551
  *
552
- * @since X.X.X
553
  * -----------------------------------------
554
  */
555
  static function get_shared_link_caption( $news ){
@@ -600,7 +600,7 @@ class CFF_Shortcode_Display {
600
  * Get Error Message Data
601
  * Get the error message data for the templates
602
  *
603
- * @since X.X.X
604
  * -----------------------------------------
605
  */
606
 
@@ -639,7 +639,7 @@ class CFF_Shortcode_Display {
639
  * Get Likebox Data
640
  * Get the likebox data for the templates
641
  *
642
- * @since X.X.X
643
  * -----------------------------------------
644
  */
645
 
@@ -675,7 +675,7 @@ class CFF_Shortcode_Display {
675
  * Get Header Data
676
  * Get the Header data for the templates
677
  *
678
- * @since X.X.X
679
  * -----------------------------------------
680
  */
681
  static function get_header_txt_classes( $cff_header_outside ){
4
  *
5
  * Contains all the functions for the diplay purposes! (Generates CSS, CSS Classes, HTML Attributes...)
6
  *
7
+ * @since 2.19
8
  */
9
 
10
  namespace CustomFacebookFeed;
24
  *
25
  * Check if is Ajax Loaded then put the script inside the content
26
  *
27
+ * @since 2.19
28
  */
29
  public function ajax_loaded(){
30
  $ajax_loaded_content = '';
45
  *
46
  * Returns an array containing all the styles for the Feed
47
  *
48
+ * @since 2.19
49
  * @return String
50
  */
51
  public function style_compiler( $style_array ){
68
  *
69
  * Returns custom CSS classes for the CFF list container shortcode
70
  *
71
+ * @since 2.19
72
  * @return Array
73
  */
74
  public function feed_style_class_compiler(){
143
  *
144
  * Returns the post item feed class atrribute
145
  *
146
+ * @since 2.19
147
  * @return Array
148
  */
149
  public function get_item_attributes($cff_post_type, $cff_album, $cff_post_bg_color_check, $cff_post_style, $cff_box_shadow, $name, $cff_post_id){
175
  *
176
  * Returns the post item feed style attribute
177
  *
178
+ * @since 2.19
179
  * @return String
180
  */
181
  public function get_post_item_style(){
197
  * Style Attribute
198
  * Generates the Style attribute for the Feed Elements
199
  *
200
+ * @since 2.19
201
  * @return String
202
  */
203
  public function get_style_attribute( $element ){
304
  * Style Attribute
305
  * Generates the Style attribute for the Feed Elements
306
  *
307
+ * @since 2.19
308
  * @return String
309
  */
310
  public function check_show_section( $section_name ){
320
  * Get Author Template Data
321
  * Get Authors the data for the templates
322
  *
323
+ * @since 2.19
324
  * -----------------------------------------
325
  */
326
 
366
  * Get Date Data
367
  * Get Date the data for the templates
368
  *
369
+ * @since 2.19
370
  * -----------------------------------------
371
  */
372
  static function get_date( $options, $atts, $news ){
406
  * Get Media Link Data
407
  * Get the Media link data for the templates
408
  *
409
+ * @since 2.19
410
  * -----------------------------------------
411
  */
412
  static function get_media_link_text( $atts, $cff_post_type, $cff_album ){
425
  * Get Post Link Data
426
  * Get the Post link data for the templates
427
  *
428
+ * @since 2.19
429
  * -----------------------------------------
430
  */
431
  static function get_post_link_social_links( $link, $cff_post_text_to_share ){
480
  * Get Post Text Data
481
  * Get the Post text data for the templates
482
  *
483
+ * @since 2.19
484
  * -----------------------------------------
485
  */
486
  static function get_post_text_title_format( $atts ){
549
  * Get Shared Link Data
550
  * Get the Shared Link data for the templates
551
  *
552
+ * @since 2.19
553
  * -----------------------------------------
554
  */
555
  static function get_shared_link_caption( $news ){
600
  * Get Error Message Data
601
  * Get the error message data for the templates
602
  *
603
+ * @since 2.19
604
  * -----------------------------------------
605
  */
606
 
639
  * Get Likebox Data
640
  * Get the likebox data for the templates
641
  *
642
+ * @since 2.19
643
  * -----------------------------------------
644
  */
645
 
675
  * Get Header Data
676
  * Get the Header data for the templates
677
  *
678
+ * @since 2.19
679
  * -----------------------------------------
680
  */
681
  static function get_header_txt_classes( $cff_header_outside ){
inc/CFF_Utils.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * Contains miscellaneous CFF functions
6
  *
7
- * @since X.X.X
8
  */
9
  namespace CustomFacebookFeed;
10
 
@@ -17,7 +17,7 @@ class CFF_Utils{
17
  * Get JSON object of feed data
18
  * @access public
19
  * @static
20
- * @since X.X.X
21
  */
22
  static function cff_fetchUrl($url){
23
  $response = wp_remote_get( $url );
@@ -26,10 +26,9 @@ class CFF_Utils{
26
  $feedData = wp_remote_retrieve_body( $response );
27
 
28
  if ( ! CFF_Utils::cff_is_fb_error( $feedData ) ) {
29
-
30
 
31
- \cff_main()->cff_error_reporter->remove_error( 'api' );
32
- \cff_main()->cff_error_reporter->remove_error( 'wp_remote_get' );
33
 
34
  $feedData = apply_filters( 'cff_filter_api_data', $feedData );
35
 
@@ -53,10 +52,10 @@ class CFF_Utils{
53
 
54
 
55
  /**
56
- *
57
  * @access public
58
  * @static
59
- * @since X.X.X
60
  */
61
  static function cff_desc_tags($description){
62
  preg_match_all( "/@\[(.*?)\]/", $description, $cff_tag_matches );
@@ -79,13 +78,13 @@ class CFF_Utils{
79
 
80
  return $cff_description_tagged;
81
  }
82
-
83
 
84
  /**
85
  * Sort message tags by offset value
86
  * @access public
87
  * @static
88
- * @since X.X.X
89
  */
90
  static function cffSortTags($a, $b){
91
  return $a['offset'] - $b['offset'];
@@ -93,10 +92,10 @@ class CFF_Utils{
93
 
94
 
95
  /**
96
- *
97
  * @access public
98
  * @static
99
- * @since X.X.X
100
  */
101
  static function cff_is_wp_error( $response ) {
102
  return is_wp_error( $response );
@@ -104,14 +103,14 @@ class CFF_Utils{
104
 
105
 
106
  /**
107
- *
108
  * @access public
109
  * @static
110
- * @since X.X.X
111
  */
112
  static function cff_log_wp_error( $response, $url ) {
113
  if ( is_wp_error( $response ) ) {
114
-
115
  delete_option( 'cff_dismiss_critical_notice' );
116
 
117
  $admin_message_error = '';
@@ -134,18 +133,18 @@ class CFF_Utils{
134
  'post_id' => get_the_ID(),
135
  'errorno' => 'wp_remote_get'
136
  );
137
-
138
-
139
  \cff_main()->cff_error_reporter->add_error( 'wp_remote_get', $error );
 
 
140
  }
141
  }
142
 
143
 
144
  /**
145
- *
146
  * @access public
147
  * @static
148
- * @since X.X.X
149
  */
150
  static function cff_is_fb_error( $response ) {
151
  return (strpos( $response, '{"error":' ) === 0);
@@ -153,16 +152,16 @@ class CFF_Utils{
153
 
154
 
155
  /**
156
- *
157
  * @access public
158
  * @static
159
- * @since X.X.X
160
  */
161
  static function cff_log_fb_error( $response, $url ) {
162
  if ( is_admin() ) {
163
  return;
164
  }
165
-
166
  delete_option( 'cff_dismiss_critical_notice' );
167
 
168
  $access_token_refresh_errors = array( 10, 4, 200 );
@@ -180,45 +179,16 @@ class CFF_Utils{
180
  $accesstoken = $accesstoken_parts[0];
181
 
182
  $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $api_error_code );
183
- $admin_message = '<strong>' . $api_error_number_message . '</strong><br>' . $response['error']['message'];
184
- $public_message = __( 'There is a problem with your access token.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
185
  $link = admin_url( 'admin.php?page=cff-top' );
186
- $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>';
187
- $backend_directions = '<button class="cff-reconnect button button-primary" >' . __( 'Reconnect Your Account', 'custom-facebook-feed') . '</button>';
188
  $error = array(
189
  'accesstoken' => $accesstoken,
190
  'post_id' => get_the_ID(),
191
  'errorno' => $api_error_code
192
  );
193
 
194
- \cff_main()->cff_error_reporter->add_error( 'accesstoken', $error );
195
  } else {
196
- $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $api_error_code );
197
- $admin_message = '<strong>' . $api_error_number_message . '</strong><br>' . $response['error']['message'];
198
- $public_message = __( 'Error connecting to the Facebook API.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
199
- $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>';
200
- $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>';
201
-
202
- //Page Public Content Access admin error
203
- if( $ppca_error ){
204
- $api_error_number_message = false;
205
- $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.';
206
- $public_message = __( 'Error connecting to the Facebook API.', 'custom-facebook-feed' ) . ' ' . $api_error_number_message;
207
- $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>';
208
- $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>';
209
- }
210
-
211
- $error = array(
212
- 'accesstoken' => 'none',
213
- 'public_message' => $public_message,
214
- 'admin_message' => $admin_message,
215
- 'frontend_directions' => $frontend_directions,
216
- 'backend_directions' => $backend_directions,
217
- 'post_id' => get_the_ID(),
218
- 'errorno' => $api_error_code
219
- );
220
-
221
- \cff_main()->cff_error_reporter->add_error( 'api', $error );
222
  }
223
  }
224
 
@@ -227,19 +197,27 @@ class CFF_Utils{
227
  * Make links into span instead when the post text is made clickable
228
  * @access public
229
  * @static
230
- * @since X.X.X
231
  */
232
  static function cff_wrap_span($text) {
233
  $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
234
  return preg_replace_callback($pattern, array('CustomFacebookFeed\CFF_Utils','cff_wrap_span_callback'), $text);
235
  }
236
-
237
 
238
  /**
239
- *
 
 
 
 
 
 
 
 
 
240
  * @access public
241
  * @static
242
- * @since X.X.X
243
  */
244
  static function cff_wrap_span_callback($matches) {
245
  $max_url_length = 100;
@@ -284,7 +262,7 @@ class CFF_Utils{
284
  * Use the timezone to offset the date as all post dates are in UTC +0000
285
  * @access public
286
  * @static
287
- * @since X.X.X
288
  */
289
  static function cff_set_timezone($original, $cff_timezone){
290
  $cff_date_time = new \DateTime(date('m/d g:i a'), new \DateTimeZone('UTC'));
@@ -295,13 +273,13 @@ class CFF_Utils{
295
 
296
  return $original;
297
  }
298
-
299
 
300
  /**
301
  * Time stamp functison - used for posts
302
  * @access public
303
  * @static
304
- * @since X.X.X
305
  */
306
  static function cff_getdate($original, $date_format, $custom_date, $cff_date_translate_strings, $cff_timezone) {
307
  //Offset the date by the timezone
@@ -368,7 +346,7 @@ class CFF_Utils{
368
  $now = time();
369
 
370
  // is it future date or past date
371
- if($now > $original) {
372
  $difference = $now - $original;
373
  $tense = $cff_ago;
374
  } else {
@@ -398,10 +376,10 @@ class CFF_Utils{
398
 
399
 
400
  /**
401
- *
402
  * @access public
403
  * @static
404
- * @since X.X.X
405
  */
406
  static function cff_eventdate($original, $date_format, $custom_date) {
407
  switch ($date_format) {
@@ -456,7 +434,7 @@ class CFF_Utils{
456
  * Use custom stripos function if it's not available (only available in PHP 5+)
457
  * @access public
458
  * @static
459
- * @since X.X.X
460
  */
461
  static function stripos($haystack, $needle){
462
  if( empty( stristr( $haystack, $needle ) ) )
@@ -466,10 +444,10 @@ class CFF_Utils{
466
 
467
 
468
  /**
469
- *
470
  * @access public
471
  * @static
472
- * @since X.X.X
473
  */
474
  static function cff_stripos_arr($haystack, $needle) {
475
  if(!is_array($needle)) $needle = array($needle);
@@ -481,10 +459,10 @@ class CFF_Utils{
481
 
482
 
483
  /**
484
- *
485
  * @access public
486
  * @static
487
- * @since X.X.X
488
  */
489
  static function cff_mb_substr_replace($string, $replacement, $start, $length=NULL) {
490
  if (is_array($string)) {
@@ -527,8 +505,8 @@ class CFF_Utils{
527
  * Push to assoc array
528
  * @access public
529
  * @static
530
- * @since X.X.X
531
- */
532
  static function cff_array_push_assoc($array, $key, $value){
533
  $array[$key] = $value;
534
  return $array;
@@ -539,7 +517,7 @@ class CFF_Utils{
539
  * Convert string to slug
540
  * @access public
541
  * @static
542
- * @since X.X.X
543
  */
544
  static function cff_to_slug($string){
545
  return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $string)));
@@ -550,7 +528,7 @@ class CFF_Utils{
550
  * Convert string to slug
551
  * @access public
552
  * @static
553
- * @since X.X.X
554
  */
555
  static function cff_get_utc_offset() {
556
  return get_option( 'gmt_offset', 0 ) * HOUR_IN_SECONDS;
@@ -568,20 +546,20 @@ class CFF_Utils{
568
 
569
 
570
  /**
571
- *
572
  * @access public
573
  * @static
574
- * @since X.X.X
575
  */
576
  static function cff_is_pro_version() {
577
  return defined( 'CFFWELCOME_VER' );
578
  }
579
 
580
  /**
581
- *
582
  * @access public
583
  * @static
584
- * @since X.X.X
585
  */
586
  static 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) {
587
  if( $cff_show_access_token && strlen($access_token) > 130 ){
@@ -683,10 +661,10 @@ class CFF_Utils{
683
  /**
684
  * Check if On
685
  * Function to check if a shortcode options is set to ON or TRUE
686
- *
687
  * @access public
688
  * @static
689
- * @since X.X.X
690
  * @return boolean
691
  */
692
  static function check_if_on( $value ){
@@ -696,10 +674,10 @@ class CFF_Utils{
696
  /**
697
  * Check if On
698
  * Function to check if a shortcode options is set to ON or TRUE
699
- *
700
  * @access public
701
  * @static
702
- * @since X.X.X
703
  * @return boolean
704
  */
705
  static function check_if_onexist( $value ){
@@ -708,11 +686,11 @@ class CFF_Utils{
708
 
709
  /**
710
  * Check Value
711
- * Function to check a value if exists or return a default one
712
- *
713
  * @access public
714
  * @static
715
- * @since X.X.X
716
  * @return mixed
717
  */
718
  static function return_value( $value , $default = ''){
@@ -723,10 +701,10 @@ class CFF_Utils{
723
  /**
724
  * Get CSS value
725
  * Checks if the value is a valid CSS distance
726
- *
727
  * @access public
728
  * @static
729
- * @since X.X.X
730
  * @return string
731
  */
732
  static function get_css_distance( $value ){
@@ -735,14 +713,14 @@ class CFF_Utils{
735
 
736
 
737
  /**
738
- *
739
- *
740
- * This function will get the Profile Pic, Cover, Name, About
741
  * For the visual header display
742
- *
743
  * @access public
744
  * @static
745
- * @since X.X.X
746
  */
747
  static function fetch_header_data( $page_id, $cff_is_group, $access_token, $cff_cache_time ){
748
  // Create Transient Name
@@ -767,14 +745,14 @@ class CFF_Utils{
767
 
768
 
769
  /**
770
- *
771
- *
772
  * Print Template
773
  * returns an HTML Template
774
- *
775
  * @access public
776
  * @static
777
- * @since X.X.X
778
  */
779
  static function print_template_part( $template_name, $args = array(), $this_class = null){
780
  $this_class = $this_class;
@@ -786,4 +764,21 @@ class CFF_Utils{
786
  return $template;
787
  }
788
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
789
  }
4
  *
5
  * Contains miscellaneous CFF functions
6
  *
7
+ * @since 2.19
8
  */
9
  namespace CustomFacebookFeed;
10
 
17
  * Get JSON object of feed data
18
  * @access public
19
  * @static
20
+ * @since 2.19
21
  */
22
  static function cff_fetchUrl($url){
23
  $response = wp_remote_get( $url );
26
  $feedData = wp_remote_retrieve_body( $response );
27
 
28
  if ( ! CFF_Utils::cff_is_fb_error( $feedData ) ) {
 
29
 
30
+
31
+ \cff_main()->cff_error_reporter->remove_error( 'connection' );
32
 
33
  $feedData = apply_filters( 'cff_filter_api_data', $feedData );
34
 
52
 
53
 
54
  /**
55
+ *
56
  * @access public
57
  * @static
58
+ * @since 2.19
59
  */
60
  static function cff_desc_tags($description){
61
  preg_match_all( "/@\[(.*?)\]/", $description, $cff_tag_matches );
78
 
79
  return $cff_description_tagged;
80
  }
81
+
82
 
83
  /**
84
  * Sort message tags by offset value
85
  * @access public
86
  * @static
87
+ * @since 2.19
88
  */
89
  static function cffSortTags($a, $b){
90
  return $a['offset'] - $b['offset'];
92
 
93
 
94
  /**
95
+ *
96
  * @access public
97
  * @static
98
+ * @since 2.19
99
  */
100
  static function cff_is_wp_error( $response ) {
101
  return is_wp_error( $response );
103
 
104
 
105
  /**
106
+ *
107
  * @access public
108
  * @static
109
+ * @since 2.19
110
  */
111
  static function cff_log_wp_error( $response, $url ) {
112
  if ( is_wp_error( $response ) ) {
113
+
114
  delete_option( 'cff_dismiss_critical_notice' );
115
 
116
  $admin_message_error = '';
133
  'post_id' => get_the_ID(),
134
  'errorno' => 'wp_remote_get'
135
  );
 
 
136
  \cff_main()->cff_error_reporter->add_error( 'wp_remote_get', $error );
137
+ }else{
138
+ \cff_main()->cff_error_reporter->remove_error( 'connection' );
139
  }
140
  }
141
 
142
 
143
  /**
144
+ *
145
  * @access public
146
  * @static
147
+ * @since 2.19
148
  */
149
  static function cff_is_fb_error( $response ) {
150
  return (strpos( $response, '{"error":' ) === 0);
152
 
153
 
154
  /**
155
+ *
156
  * @access public
157
  * @static
158
+ * @since 2.19
159
  */
160
  static function cff_log_fb_error( $response, $url ) {
161
  if ( is_admin() ) {
162
  return;
163
  }
164
+
165
  delete_option( 'cff_dismiss_critical_notice' );
166
 
167
  $access_token_refresh_errors = array( 10, 4, 200 );
179
  $accesstoken = $accesstoken_parts[0];
180
 
181
  $api_error_number_message = sprintf( __( 'API Error %s:', 'custom-facebook-feed' ), $api_error_code );
 
 
182
  $link = admin_url( 'admin.php?page=cff-top' );
 
 
183
  $error = array(
184
  'accesstoken' => $accesstoken,
185
  'post_id' => get_the_ID(),
186
  'errorno' => $api_error_code
187
  );
188
 
189
+ \cff_main()->cff_error_reporter->add_error( 'accesstoken', $error, $accesstoken );
190
  } else {
191
+ \cff_main()->cff_error_reporter->add_error( 'api', $response );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  }
193
  }
194
 
197
  * Make links into span instead when the post text is made clickable
198
  * @access public
199
  * @static
200
+ * @since 2.19
201
  */
202
  static function cff_wrap_span($text) {
203
  $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
204
  return preg_replace_callback($pattern, array('CustomFacebookFeed\CFF_Utils','cff_wrap_span_callback'), $text);
205
  }
 
206
 
207
  /**
208
+ * @return Json Encode
209
+ *
210
+ * @since 2.1.1
211
+ */
212
+ static function cff_json_encode( $thing ) {
213
+ return wp_json_encode( $thing );
214
+ }
215
+
216
+ /**
217
+ *
218
  * @access public
219
  * @static
220
+ * @since 2.19
221
  */
222
  static function cff_wrap_span_callback($matches) {
223
  $max_url_length = 100;
262
  * Use the timezone to offset the date as all post dates are in UTC +0000
263
  * @access public
264
  * @static
265
+ * @since 2.19
266
  */
267
  static function cff_set_timezone($original, $cff_timezone){
268
  $cff_date_time = new \DateTime(date('m/d g:i a'), new \DateTimeZone('UTC'));
273
 
274
  return $original;
275
  }
276
+
277
 
278
  /**
279
  * Time stamp functison - used for posts
280
  * @access public
281
  * @static
282
+ * @since 2.19
283
  */
284
  static function cff_getdate($original, $date_format, $custom_date, $cff_date_translate_strings, $cff_timezone) {
285
  //Offset the date by the timezone
346
  $now = time();
347
 
348
  // is it future date or past date
349
+ if($now > $original) {
350
  $difference = $now - $original;
351
  $tense = $cff_ago;
352
  } else {
376
 
377
 
378
  /**
379
+ *
380
  * @access public
381
  * @static
382
+ * @since 2.19
383
  */
384
  static function cff_eventdate($original, $date_format, $custom_date) {
385
  switch ($date_format) {
434
  * Use custom stripos function if it's not available (only available in PHP 5+)
435
  * @access public
436
  * @static
437
+ * @since 2.19
438
  */
439
  static function stripos($haystack, $needle){
440
  if( empty( stristr( $haystack, $needle ) ) )
444
 
445
 
446
  /**
447
+ *
448
  * @access public
449
  * @static
450
+ * @since 2.19
451
  */
452
  static function cff_stripos_arr($haystack, $needle) {
453
  if(!is_array($needle)) $needle = array($needle);
459
 
460
 
461
  /**
462
+ *
463
  * @access public
464
  * @static
465
+ * @since 2.19
466
  */
467
  static function cff_mb_substr_replace($string, $replacement, $start, $length=NULL) {
468
  if (is_array($string)) {
505
  * Push to assoc array
506
  * @access public
507
  * @static
508
+ * @since 2.19
509
+ */
510
  static function cff_array_push_assoc($array, $key, $value){
511
  $array[$key] = $value;
512
  return $array;
517
  * Convert string to slug
518
  * @access public
519
  * @static
520
+ * @since 2.19
521
  */
522
  static function cff_to_slug($string){
523
  return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $string)));
528
  * Convert string to slug
529
  * @access public
530
  * @static
531
+ * @since 2.19
532
  */
533
  static function cff_get_utc_offset() {
534
  return get_option( 'gmt_offset', 0 ) * HOUR_IN_SECONDS;
546
 
547
 
548
  /**
549
+ *
550
  * @access public
551
  * @static
552
+ * @since 2.19
553
  */
554
  static function cff_is_pro_version() {
555
  return defined( 'CFFWELCOME_VER' );
556
  }
557
 
558
  /**
559
+ *
560
  * @access public
561
  * @static
562
+ * @since 2.19
563
  */
564
  static 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) {
565
  if( $cff_show_access_token && strlen($access_token) > 130 ){
661
  /**
662
  * Check if On
663
  * Function to check if a shortcode options is set to ON or TRUE
664
+ *
665
  * @access public
666
  * @static
667
+ * @since 2.19
668
  * @return boolean
669
  */
670
  static function check_if_on( $value ){
674
  /**
675
  * Check if On
676
  * Function to check if a shortcode options is set to ON or TRUE
677
+ *
678
  * @access public
679
  * @static
680
+ * @since 2.19
681
  * @return boolean
682
  */
683
  static function check_if_onexist( $value ){
686
 
687
  /**
688
  * Check Value
689
+ * Function to check a value if exists or return a default one
690
+ *
691
  * @access public
692
  * @static
693
+ * @since 2.19
694
  * @return mixed
695
  */
696
  static function return_value( $value , $default = ''){
701
  /**
702
  * Get CSS value
703
  * Checks if the value is a valid CSS distance
704
+ *
705
  * @access public
706
  * @static
707
+ * @since 2.19
708
  * @return string
709
  */
710
  static function get_css_distance( $value ){
713
 
714
 
715
  /**
716
+ *
717
+ *
718
+ * This function will get the Profile Pic, Cover, Name, About
719
  * For the visual header display
720
+ *
721
  * @access public
722
  * @static
723
+ * @since 2.19
724
  */
725
  static function fetch_header_data( $page_id, $cff_is_group, $access_token, $cff_cache_time ){
726
  // Create Transient Name
745
 
746
 
747
  /**
748
+ *
749
+ *
750
  * Print Template
751
  * returns an HTML Template
752
+ *
753
  * @access public
754
  * @static
755
+ * @since 2.19
756
  */
757
  static function print_template_part( $template_name, $args = array(), $this_class = null){
758
  $this_class = $this_class;
764
  return $template;
765
  }
766
 
767
+ /**
768
+ *
769
+ * Get Connected Accounts
770
+ * @since 2.19
771
+ */
772
+ static function cff_get_connected_accounts() {
773
+ $cff_connected_accounts = get_option('cff_connected_accounts', array());
774
+ if( !empty($cff_connected_accounts) ){
775
+ $cff_connected_accounts = str_replace('\"','"', $cff_connected_accounts);
776
+ $cff_connected_accounts = str_replace("\'","'", $cff_connected_accounts);
777
+ $cff_connected_accounts = json_decode( $cff_connected_accounts );
778
+ }else{
779
+ $cff_connected_accounts = [];
780
+ }
781
+ return $cff_connected_accounts;
782
+ }
783
+
784
  }
inc/Custom_Facebook_Feed.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The main Custom_Facebook_Feed class that runs the plugins & registers all the ressources.
6
  *
7
- * @since X.X.X
8
  */
9
 
10
  namespace CustomFacebookFeed;
@@ -23,7 +23,7 @@ final class Custom_Facebook_Feed{
23
  /**
24
  * Instance
25
  *
26
- * @since X.X.X
27
  * @access private
28
  * @static
29
  * @var Custom_Facebook_Feed
@@ -36,7 +36,7 @@ final class Custom_Facebook_Feed{
36
  *
37
  * Admin admin panel.
38
  *
39
- * @since X.X.X
40
  * @access public
41
  *
42
  * @var CFF_Admin
@@ -49,7 +49,7 @@ final class Custom_Facebook_Feed{
49
  *
50
  * About page panel.
51
  *
52
- * @since X.X.X
53
  * @access public
54
  *
55
  * @var CFF_About
@@ -61,7 +61,7 @@ final class Custom_Facebook_Feed{
61
  *
62
  * Error Reporter panel.
63
  *
64
- * @since X.X.X
65
  * @access public
66
  *
67
  * @var CFF_Error_Reporter
@@ -73,7 +73,7 @@ final class Custom_Facebook_Feed{
73
  *
74
  * Blocks.
75
  *
76
- * @since X.X.X
77
  * @access public
78
  *
79
  * @var cff_blocks
@@ -85,7 +85,7 @@ final class Custom_Facebook_Feed{
85
  *
86
  * Notifications System.
87
  *
88
- * @since X.X.X
89
  * @access public
90
  *
91
  * @var CFF_Notifications
@@ -97,7 +97,7 @@ final class Custom_Facebook_Feed{
97
  *
98
  * New User.
99
  *
100
- * @since X.X.X
101
  * @access public
102
  *
103
  * @var CFF_New_User
@@ -109,7 +109,7 @@ final class Custom_Facebook_Feed{
109
  *
110
  * Oembed Element.
111
  *
112
- * @since X.X.X
113
  * @access public
114
  *
115
  * @var CFF_Oembed
@@ -121,7 +121,7 @@ final class Custom_Facebook_Feed{
121
  *
122
  * Tracking System.
123
  *
124
- * @since X.X.X
125
  * @access public
126
  *
127
  * @var CFF_Tracking
@@ -133,7 +133,7 @@ final class Custom_Facebook_Feed{
133
  *
134
  * Shortcode Class.
135
  *
136
- * @since X.X.X
137
  * @access public
138
  *
139
  * @var CFF_Shortcode
@@ -144,7 +144,7 @@ final class Custom_Facebook_Feed{
144
  * CFF_SiteHealth.
145
  *
146
  *
147
- * @since X.X.X
148
  * @access public
149
  *
150
  * @var CFF_SiteHealth
@@ -158,7 +158,7 @@ final class Custom_Facebook_Feed{
158
  *
159
  * Just one instance of the Custom_Facebook_Feed class
160
  *
161
- * @since X.X.X
162
  * @access public
163
  * @static
164
  *
@@ -184,6 +184,9 @@ final class Custom_Facebook_Feed{
184
  add_filter( 'cron_schedules', [ self::$instance, 'cff_cron_custom_interval' ] );
185
  add_filter('widget_text', 'do_shortcode');
186
 
 
 
 
187
  register_activation_hook( CFF_FILE, [ self::$instance, 'cff_activate' ] );
188
  register_deactivation_hook( CFF_FILE, [ self::$instance, 'cff_deactivate' ] );
189
  register_uninstall_hook( CFF_FILE, array('CustomFacebookFeed\Custom_Facebook_Feed','cff_uninstall'));
@@ -196,7 +199,7 @@ final class Custom_Facebook_Feed{
196
  /**
197
  * Load Custom_Facebook_Feed textdomain.
198
  *
199
- * @since X.X.X
200
  *
201
  * @return void
202
  * @access public
@@ -211,7 +214,7 @@ final class Custom_Facebook_Feed{
211
  *
212
  * Initialize Custom_Facebook_Feed plugin.
213
  *
214
- * @since X.X.X
215
  * @access public
216
  */
217
  public function init() {
@@ -254,7 +257,7 @@ final class Custom_Facebook_Feed{
254
  /**
255
  * Register Assets
256
  *
257
- * @since X.X.X
258
  */
259
  public function register_assets(){
260
  add_action( 'wp_enqueue_scripts' , array( $this, 'enqueue_styles_assets' ) );
@@ -265,7 +268,7 @@ final class Custom_Facebook_Feed{
265
  /**
266
  * Enqueue & Register Styles
267
  *
268
- * @since X.X.X
269
  */
270
  public function enqueue_styles_assets(){
271
  //Minify files?
@@ -312,7 +315,7 @@ final class Custom_Facebook_Feed{
312
  * Enqueue & Register Scripts
313
  *
314
  *
315
- * @since X.X.X
316
  * @access public
317
  */
318
  public function enqueue_scripts_assets(){
@@ -339,7 +342,7 @@ final class Custom_Facebook_Feed{
339
  *
340
  * Check for the db updates
341
  *
342
- * @since X.X.X
343
  * @access public
344
  */
345
  function cff_check_for_db_updates(){
@@ -389,6 +392,11 @@ final class Custom_Facebook_Feed{
389
  }
390
  update_option( 'cff_db_version', CFF_DBVERSION );
391
  }
 
 
 
 
 
392
  }
393
 
394
 
@@ -397,7 +405,7 @@ final class Custom_Facebook_Feed{
397
  *
398
  * CFF activation action.
399
  *
400
- * @since X.X.X
401
  * @access public
402
  */
403
  function cff_activate() {
@@ -463,7 +471,7 @@ final class Custom_Facebook_Feed{
463
  *
464
  * CFF deactivation action.
465
  *
466
- * @since X.X.X
467
  * @access public
468
  */
469
  function cff_deactivate() {
@@ -477,7 +485,7 @@ final class Custom_Facebook_Feed{
477
  *
478
  * CFF uninstallation action.
479
  *
480
- * @since X.X.X
481
  * @access public
482
  */
483
  public static function cff_uninstall(){
@@ -528,7 +536,7 @@ final class Custom_Facebook_Feed{
528
  *
529
  * Adding custom CSS
530
  *
531
- * @since X.X.X
532
  * @access public
533
  */
534
  function cff_custom_css() {
@@ -552,7 +560,7 @@ final class Custom_Facebook_Feed{
552
  *
553
  * Adding custom JS
554
  *
555
- * @since X.X.X
556
  * @access public
557
  */
558
  function cff_js() {
@@ -571,6 +579,7 @@ final class Custom_Facebook_Feed{
571
  echo '<!-- Custom Facebook Feed JS -->';
572
  echo "\r\n";
573
  echo '<script type="text/javascript">';
 
574
  echo "\r\n";
575
  echo 'var cfflinkhashtags = "' . $cff_link_hashtags . '";';
576
  echo "\r\n";
@@ -590,7 +599,7 @@ final class Custom_Facebook_Feed{
590
  *
591
  * PPCA Check Notice Dismiss
592
  *
593
- * @since X.X.X
594
  * @access public
595
  */
596
  function cff_ppca_check_notice_dismiss() {
@@ -607,7 +616,7 @@ final class Custom_Facebook_Feed{
607
  *
608
  * Cron Job Custom Interval
609
  *
610
- * @since X.X.X
611
  * @access public
612
  */
613
  function cff_cron_custom_interval( $schedules ) {
@@ -618,6 +627,31 @@ final class Custom_Facebook_Feed{
618
  return $schedules;
619
  }
620
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  }
622
 
623
 
4
  *
5
  * The main Custom_Facebook_Feed class that runs the plugins & registers all the ressources.
6
  *
7
+ * @since 2.19
8
  */
9
 
10
  namespace CustomFacebookFeed;
23
  /**
24
  * Instance
25
  *
26
+ * @since 2.19
27
  * @access private
28
  * @static
29
  * @var Custom_Facebook_Feed
36
  *
37
  * Admin admin panel.
38
  *
39
+ * @since 2.19
40
  * @access public
41
  *
42
  * @var CFF_Admin
49
  *
50
  * About page panel.
51
  *
52
+ * @since 2.19
53
  * @access public
54
  *
55
  * @var CFF_About
61
  *
62
  * Error Reporter panel.
63
  *
64
+ * @since 2.19
65
  * @access public
66
  *
67
  * @var CFF_Error_Reporter
73
  *
74
  * Blocks.
75
  *
76
+ * @since 2.19
77
  * @access public
78
  *
79
  * @var cff_blocks
85
  *
86
  * Notifications System.
87
  *
88
+ * @since 2.19
89
  * @access public
90
  *
91
  * @var CFF_Notifications
97
  *
98
  * New User.
99
  *
100
+ * @since 2.19
101
  * @access public
102
  *
103
  * @var CFF_New_User
109
  *
110
  * Oembed Element.
111
  *
112
+ * @since 2.19
113
  * @access public
114
  *
115
  * @var CFF_Oembed
121
  *
122
  * Tracking System.
123
  *
124
+ * @since 2.19
125
  * @access public
126
  *
127
  * @var CFF_Tracking
133
  *
134
  * Shortcode Class.
135
  *
136
+ * @since 2.19
137
  * @access public
138
  *
139
  * @var CFF_Shortcode
144
  * CFF_SiteHealth.
145
  *
146
  *
147
+ * @since 2.19
148
  * @access public
149
  *
150
  * @var CFF_SiteHealth
158
  *
159
  * Just one instance of the Custom_Facebook_Feed class
160
  *
161
+ * @since 2.19
162
  * @access public
163
  * @static
164
  *
184
  add_filter( 'cron_schedules', [ self::$instance, 'cff_cron_custom_interval' ] );
185
  add_filter('widget_text', 'do_shortcode');
186
 
187
+ add_action('wp_ajax_feed_locator', [self::$instance, 'cff_feed_locator']);
188
+ add_action('wp_ajax_nopriv_feed_locator', [self::$instance, 'cff_feed_locator']);
189
+
190
  register_activation_hook( CFF_FILE, [ self::$instance, 'cff_activate' ] );
191
  register_deactivation_hook( CFF_FILE, [ self::$instance, 'cff_deactivate' ] );
192
  register_uninstall_hook( CFF_FILE, array('CustomFacebookFeed\Custom_Facebook_Feed','cff_uninstall'));
199
  /**
200
  * Load Custom_Facebook_Feed textdomain.
201
  *
202
+ * @since 2.19
203
  *
204
  * @return void
205
  * @access public
214
  *
215
  * Initialize Custom_Facebook_Feed plugin.
216
  *
217
+ * @since 2.19
218
  * @access public
219
  */
220
  public function init() {
257
  /**
258
  * Register Assets
259
  *
260
+ * @since 2.19
261
  */
262
  public function register_assets(){
263
  add_action( 'wp_enqueue_scripts' , array( $this, 'enqueue_styles_assets' ) );
268
  /**
269
  * Enqueue & Register Styles
270
  *
271
+ * @since 2.19
272
  */
273
  public function enqueue_styles_assets(){
274
  //Minify files?
315
  * Enqueue & Register Scripts
316
  *
317
  *
318
+ * @since 2.19
319
  * @access public
320
  */
321
  public function enqueue_scripts_assets(){
342
  *
343
  * Check for the db updates
344
  *
345
+ * @since 2.19
346
  * @access public
347
  */
348
  function cff_check_for_db_updates(){
392
  }
393
  update_option( 'cff_db_version', CFF_DBVERSION );
394
  }
395
+
396
+ if ( (float) $db_ver < 1.3 ) {
397
+ CFF_Feed_Locator::create_table();
398
+ update_option( 'cff_db_version', CFF_DBVERSION );
399
+ }
400
  }
401
 
402
 
405
  *
406
  * CFF activation action.
407
  *
408
+ * @since 2.19
409
  * @access public
410
  */
411
  function cff_activate() {
471
  *
472
  * CFF deactivation action.
473
  *
474
+ * @since 2.19
475
  * @access public
476
  */
477
  function cff_deactivate() {
485
  *
486
  * CFF uninstallation action.
487
  *
488
+ * @since 2.19
489
  * @access public
490
  */
491
  public static function cff_uninstall(){
536
  *
537
  * Adding custom CSS
538
  *
539
+ * @since 2.19
540
  * @access public
541
  */
542
  function cff_custom_css() {
560
  *
561
  * Adding custom JS
562
  *
563
+ * @since 2.19
564
  * @access public
565
  */
566
  function cff_js() {
579
  echo '<!-- Custom Facebook Feed JS -->';
580
  echo "\r\n";
581
  echo '<script type="text/javascript">';
582
+ echo 'var cffajaxurl = "' . admin_url('admin-ajax.php') . '";';
583
  echo "\r\n";
584
  echo 'var cfflinkhashtags = "' . $cff_link_hashtags . '";';
585
  echo "\r\n";
599
  *
600
  * PPCA Check Notice Dismiss
601
  *
602
+ * @since 2.19
603
  * @access public
604
  */
605
  function cff_ppca_check_notice_dismiss() {
616
  *
617
  * Cron Job Custom Interval
618
  *
619
+ * @since 2.19
620
  * @access public
621
  */
622
  function cff_cron_custom_interval( $schedules ) {
627
  return $schedules;
628
  }
629
 
630
+ /**
631
+ * Feed Locator Ajax Call
632
+ *
633
+ *
634
+ * @since 2.19
635
+ * @access public
636
+ */
637
+ function cff_feed_locator(){
638
+ $feed_locator_data_array = isset($_POST['feedLocatorData']) && !empty($_POST['feedLocatorData']) && is_array($_POST['feedLocatorData']) ? $_POST['feedLocatorData'] : false;
639
+ if($feed_locator_data_array != false):
640
+ foreach ($feed_locator_data_array as $single_feed_locator) {
641
+ $feed_details = array(
642
+ 'feed_id' => $single_feed_locator['feedID'],
643
+ 'atts' => $single_feed_locator['shortCodeAtts'],
644
+ 'location' => array(
645
+ 'post_id' => $single_feed_locator['postID'],
646
+ 'html' => $single_feed_locator['location']
647
+ )
648
+ );
649
+ $locator = new CFF_Feed_Locator( $feed_details );
650
+ $locator->add_or_update_entry();
651
+ }
652
+ endif;
653
+ die();
654
+ }
655
  }
656
 
657
 
templates/credit.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed : Credit
4
  * Show a credit message to Smashballoon
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
@@ -25,4 +25,4 @@ if($cff_show_credit) :
25
  </a>
26
  </p>
27
  <?php
28
- endif;
3
  * Custom Facebook Feed : Credit
4
  * Show a credit message to Smashballoon
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
25
  </a>
26
  </p>
27
  <?php
28
+ endif;
templates/error-message.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed : Error Message Template
4
  * Display different error message
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
@@ -27,18 +27,18 @@ if( empty($FBdata->data) || isset($FBdata->cached_error) || $cff_ppca_check_erro
27
  $FBdata->error->message = esc_html__('(#10) To use "Page Public Content Access", your use of this endpoint must be reviewed and approved by Facebook.' , 'custom-facebook-feed');
28
  $FBdata->error->type = $FBdata->error->code = $FBdata->error->error_subcode = NULL;
29
  }
30
-
31
  $cap = CFF_Shortcode_Display::get_error_message_cap();
32
  $cff_ppca_error = CFF_Shortcode_Display::get_error_check_ppca( $FBdata )
33
 
34
  ?>
35
  <div class="cff-error-msg">
36
  <div>
37
- <i class="fa fa-lock" aria-hidden="true" style="margin-right: 5px;"></i><b><?php echo esc_html__('This message is only visible to admins.', 'custom-facebook-feed'); ?></b><br/>
38
- <?php
39
  if ( !$cff_ppca_check_error ) echo esc_html__('Problem displaying Facebook posts.', 'custom-facebook-feed');
40
  if ( isset($FBdata->cached_error) ) echo esc_html__(' Backup cache in use.', 'custom-facebook-feed');
41
- ?>
42
  <?php if( $cff_ppca_check_error || $cff_ppca_error ): ?>
43
  </div>
44
  <?php if( $cff_ppca_error ): ?>
@@ -46,11 +46,11 @@ if( empty($FBdata->data) || isset($FBdata->cached_error) || $cff_ppca_check_erro
46
  <?php else: ?>
47
  <a class="cff_notice_dismiss" href="<?php echo esc_url( add_query_arg( 'cff_ppca_check_notice_dismiss', '0' ) ); ?>"><span class="fa fa-times-circle" aria-hidden="true"></span></a>
48
  <b class="cff-warning-notice">PPCA Error:</b> <?php echo esc_html__('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.', 'custom-facebook-feed'); ?>
49
- <?php endif; ?>
50
  <?php if( current_user_can( $cap ) ): ?>
51
  <br /><b style="margin-top: 5px; display: inline-block;"><?php echo esc_html__('Action Required.', 'custom-facebook-feed'); ?>:</b> <?php echo esc_html__('Please', 'custom-facebook-feed'); ?> <a href="https://smashballoon.com/facebook-ppca-error-notice/" target="_blank"><?php echo esc_html__('see here', 'custom-facebook-feed'); ?></a> <?php echo esc_html__('for information on how to fix this.', 'custom-facebook-feed'); ?>
52
- <?php endif; ?>
53
-
54
  <?php else: ?>
55
  <br/><a href="javascript:void(0);" id="cff-show-error" onclick="cffShowError()"><?php echo esc_html__('Click to show error', 'custom-facebook-feed'); ?></a>
56
  <script type="text/javascript">function cffShowError() { document.getElementById("cff-error-reason").style.display = "block"; document.getElementById("cff-show-error").style.display = "none"; }</script>
@@ -58,22 +58,22 @@ if( empty($FBdata->data) || isset($FBdata->cached_error) || $cff_ppca_check_erro
58
  <div id="cff-error-reason">
59
  <?php if( isset($FBdata->error->message) ): ?>
60
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error->message; ?>
61
- <?php endif; ?>
62
  <?php if( isset($FBdata->error->type) ): ?>
63
  <b><?php echo esc_html__('Type', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error->type; ?>
64
- <?php endif; ?>
65
  <?php if( isset($FBdata->error->error_subcode) ): ?>
66
  <b><?php echo esc_html__('Subcode', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error->error_subcode; ?>
67
- <?php endif; ?>
68
  <?php if( isset($FBdata->error_msg) ): ?>
69
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error_msg; ?>
70
- <?php endif; ?>
71
  <?php if( isset($FBdata->error_code) ): ?>
72
  <?php echo esc_html__('Code', 'custom-facebook-feed'); ?>: <?php echo $FBdata->error_code; ?>
73
- <?php endif; ?>
74
  <?php if( $FBdata == null ): ?>
75
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo esc_html__('Server configuration issue', 'custom-facebook-feed'); ?>
76
- <?php endif; ?>
77
  <?php if( empty($FBdata->error) && empty($FBdata->error_msg) && $FBdata !== null ): ?>
78
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo esc_html__('No posts available for this Facebook ID', 'custom-facebook-feed'); ?>
79
  <?php endif; ?>
3
  * Custom Facebook Feed : Error Message Template
4
  * Display different error message
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
27
  $FBdata->error->message = esc_html__('(#10) To use "Page Public Content Access", your use of this endpoint must be reviewed and approved by Facebook.' , 'custom-facebook-feed');
28
  $FBdata->error->type = $FBdata->error->code = $FBdata->error->error_subcode = NULL;
29
  }
30
+
31
  $cap = CFF_Shortcode_Display::get_error_message_cap();
32
  $cff_ppca_error = CFF_Shortcode_Display::get_error_check_ppca( $FBdata )
33
 
34
  ?>
35
  <div class="cff-error-msg">
36
  <div>
37
+ <i class="fa fa-lock" aria-hidden="true" style="margin-right: 5px;"></i><b><?php echo esc_html__('This message is only visible to admins.', 'custom-facebook-feed'); ?></b><br/>
38
+ <?php
39
  if ( !$cff_ppca_check_error ) echo esc_html__('Problem displaying Facebook posts.', 'custom-facebook-feed');
40
  if ( isset($FBdata->cached_error) ) echo esc_html__(' Backup cache in use.', 'custom-facebook-feed');
41
+ ?>
42
  <?php if( $cff_ppca_check_error || $cff_ppca_error ): ?>
43
  </div>
44
  <?php if( $cff_ppca_error ): ?>
46
  <?php else: ?>
47
  <a class="cff_notice_dismiss" href="<?php echo esc_url( add_query_arg( 'cff_ppca_check_notice_dismiss', '0' ) ); ?>"><span class="fa fa-times-circle" aria-hidden="true"></span></a>
48
  <b class="cff-warning-notice">PPCA Error:</b> <?php echo esc_html__('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.', 'custom-facebook-feed'); ?>
49
+ <?php endif; ?>
50
  <?php if( current_user_can( $cap ) ): ?>
51
  <br /><b style="margin-top: 5px; display: inline-block;"><?php echo esc_html__('Action Required.', 'custom-facebook-feed'); ?>:</b> <?php echo esc_html__('Please', 'custom-facebook-feed'); ?> <a href="https://smashballoon.com/facebook-ppca-error-notice/" target="_blank"><?php echo esc_html__('see here', 'custom-facebook-feed'); ?></a> <?php echo esc_html__('for information on how to fix this.', 'custom-facebook-feed'); ?>
52
+ <?php endif; ?>
53
+
54
  <?php else: ?>
55
  <br/><a href="javascript:void(0);" id="cff-show-error" onclick="cffShowError()"><?php echo esc_html__('Click to show error', 'custom-facebook-feed'); ?></a>
56
  <script type="text/javascript">function cffShowError() { document.getElementById("cff-error-reason").style.display = "block"; document.getElementById("cff-show-error").style.display = "none"; }</script>
58
  <div id="cff-error-reason">
59
  <?php if( isset($FBdata->error->message) ): ?>
60
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error->message; ?>
61
+ <?php endif; ?>
62
  <?php if( isset($FBdata->error->type) ): ?>
63
  <b><?php echo esc_html__('Type', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error->type; ?>
64
+ <?php endif; ?>
65
  <?php if( isset($FBdata->error->error_subcode) ): ?>
66
  <b><?php echo esc_html__('Subcode', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error->error_subcode; ?>
67
+ <?php endif; ?>
68
  <?php if( isset($FBdata->error_msg) ): ?>
69
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo $FBdata->error_msg; ?>
70
+ <?php endif; ?>
71
  <?php if( isset($FBdata->error_code) ): ?>
72
  <?php echo esc_html__('Code', 'custom-facebook-feed'); ?>: <?php echo $FBdata->error_code; ?>
73
+ <?php endif; ?>
74
  <?php if( $FBdata == null ): ?>
75
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo esc_html__('Server configuration issue', 'custom-facebook-feed'); ?>
76
+ <?php endif; ?>
77
  <?php if( empty($FBdata->error) && empty($FBdata->error_msg) && $FBdata !== null ): ?>
78
  <b><?php echo esc_html__('Error', 'custom-facebook-feed'); ?>:</b> <?php echo esc_html__('No posts available for this Facebook ID', 'custom-facebook-feed'); ?>
79
  <?php endif; ?>
templates/item/author.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Item : Author Template
4
  * Displays the item author
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
@@ -12,11 +12,11 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  }
13
  use CustomFacebookFeed\CFF_Shortcode_Display;
14
 
15
- //Author Style
16
 
17
  $cff_author_styles = $this_class->get_style_attribute( 'author' );
18
-
19
- if( isset($news->from->id) ) :
20
 
21
  $cff_author_name = CFF_Shortcode_Display::get_author_name( $news );
22
  $cff_author_link_atts = CFF_Shortcode_Display::get_author_link_atts( $news, $target, $cff_nofollow, $cff_author_styles );
@@ -51,18 +51,18 @@ if( isset($news->from->id) ) :
51
  <?php else: ?>
52
  <div class="cff-author cff-no-author-info">
53
  <div class="cff-author-text">
54
- <?php if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'): ?>
55
  <?php if(!empty($post_text_story)): ?>
56
  <div class="cff-page-name cff-author-date"><span class="cff-story"> <?php echo $post_text_story ?></span></div>
57
  <?php echo $cff_date ?>
58
- <?php endif; ?>
59
  <?php else: ?>
60
  <?php if(!empty($post_text_story)): ?>
61
  <span class="cff-page-name"><span class="cff-story"> <?php echo $post_text_story ?></span></span>
62
- <?php endif; ?>
63
  <?php endif; ?>
64
  </div>
65
  <div class="cff-author-img"></div>
66
  </div>
67
- <?php
68
- endif;
3
  * Custom Facebook Feed Item : Author Template
4
  * Displays the item author
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
12
  }
13
  use CustomFacebookFeed\CFF_Shortcode_Display;
14
 
15
+ //Author Style
16
 
17
  $cff_author_styles = $this_class->get_style_attribute( 'author' );
18
+ $cff_from_id = isset($news->from->id) ? $news->from->id : '';
19
+ if( isset($cff_from_id) ) :
20
 
21
  $cff_author_name = CFF_Shortcode_Display::get_author_name( $news );
22
  $cff_author_link_atts = CFF_Shortcode_Display::get_author_link_atts( $news, $target, $cff_nofollow, $cff_author_styles );
51
  <?php else: ?>
52
  <div class="cff-author cff-no-author-info">
53
  <div class="cff-author-text">
54
+ <?php if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'): ?>
55
  <?php if(!empty($post_text_story)): ?>
56
  <div class="cff-page-name cff-author-date"><span class="cff-story"> <?php echo $post_text_story ?></span></div>
57
  <?php echo $cff_date ?>
58
+ <?php endif; ?>
59
  <?php else: ?>
60
  <?php if(!empty($post_text_story)): ?>
61
  <span class="cff-page-name"><span class="cff-story"> <?php echo $post_text_story ?></span></span>
62
+ <?php endif; ?>
63
  <?php endif; ?>
64
  </div>
65
  <div class="cff-author-img"></div>
66
  </div>
67
+ <?php
68
+ endif;
templates/item/container.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Item : Item Container
4
  * This is the item container
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  $name = isset($news->from->name) ? $news->from->name : false;
@@ -19,7 +19,7 @@ $post_item_attr = $this_class->get_item_attributes($cff_post_type, $cff_album, $
19
  echo $cff_date;
20
  if( $cff_show_text || $cff_show_desc )
21
  echo $cff_post_text;
22
- if( $cff_show_shared_links )
23
  echo $cff_shared_link;
24
  if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below' )
25
  echo $cff_date;
3
  * Custom Facebook Feed Item : Item Container
4
  * This is the item container
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  $name = isset($news->from->name) ? $news->from->name : false;
19
  echo $cff_date;
20
  if( $cff_show_text || $cff_show_desc )
21
  echo $cff_post_text;
22
+ if( $cff_show_shared_links )
23
  echo $cff_shared_link;
24
  if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below' )
25
  echo $cff_date;
templates/item/date.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Item : Date Template
4
  * Displays the item date
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
@@ -18,7 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  $cff_date_styles = $this_class->get_style_attribute( 'date' );
19
  ?>
20
 
21
- <p class="cff-date" <?php echo $cff_date_styles ?>><?php
22
  echo CFF_Shortcode_Display::get_date( $options, $atts, $news );
23
  if($cff_date_position == 'below' || (!$cff_show_author && $cff_date_position == 'author') ):
24
  ?>
3
  * Custom Facebook Feed Item : Date Template
4
  * Displays the item date
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
18
  $cff_date_styles = $this_class->get_style_attribute( 'date' );
19
  ?>
20
 
21
+ <p class="cff-date" <?php echo $cff_date_styles ?>><?php
22
  echo CFF_Shortcode_Display::get_date( $options, $atts, $news );
23
  if($cff_date_position == 'below' || (!$cff_show_author && $cff_date_position == 'author') ):
24
  ?>
templates/item/media-link.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Item : Media Link
4
  * Displays the custom feed item media link
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  use CustomFacebookFeed\CFF_Utils;
@@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) {
15
 
16
 
17
  if( $cff_show_media_link && ($cff_post_type == 'photo' || $cff_post_type == 'video' || $cff_album) ):
18
-
19
  $media_link_txt = CFF_Shortcode_Display::get_media_link_text( $atts, $cff_post_type, $cff_album );
20
  $media_link_icon = CFF_Shortcode_Display::get_media_link_icon( $cff_post_type, $cff_album );
21
 
@@ -25,5 +25,5 @@ if( $cff_show_media_link && ($cff_post_type == 'photo' || $cff_post_type == 'vid
25
  <span style="padding-right: 5px;" class="fa fas fa-<?php echo $media_link_icon ?>"></span><?php echo $media_link_txt ?>
26
  </a>
27
  </p>
28
- <?php
29
  endif;
3
  * Custom Facebook Feed Item : Media Link
4
  * Displays the custom feed item media link
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  use CustomFacebookFeed\CFF_Utils;
15
 
16
 
17
  if( $cff_show_media_link && ($cff_post_type == 'photo' || $cff_post_type == 'video' || $cff_album) ):
18
+
19
  $media_link_txt = CFF_Shortcode_Display::get_media_link_text( $atts, $cff_post_type, $cff_album );
20
  $media_link_icon = CFF_Shortcode_Display::get_media_link_icon( $cff_post_type, $cff_album );
21
 
25
  <span style="padding-right: 5px;" class="fa fas fa-<?php echo $media_link_icon ?>"></span><?php echo $media_link_txt ?>
26
  </a>
27
  </p>
28
+ <?php
29
  endif;
templates/item/post-link.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Item : Post Links
4
  * Displays the custom feed item post links (View on Facebook & Share)
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  use CustomFacebookFeed\CFF_Utils;
@@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) {
16
 
17
 
18
  $cff_link_styles = $this_class->get_style_attribute( 'post_link' );
19
- $cff_show_facebook_link = CFF_Utils::check_if_on( $atts['showfacebooklink'] );
20
  $cff_show_facebook_share = CFF_Utils::check_if_on( $atts['showsharelink'] );
21
  $cff_post_text_to_share = CFF_Shortcode_Display::get_post_link_text_to_share( $cff_post_text );
22
  $link_text = CFF_Shortcode_Display::get_post_link_text_link( $atts, $cff_post_type );
@@ -40,12 +40,12 @@ if( $cff_show_facebook_link || $cff_show_facebook_share ):
40
  <a href="<?php echo esc_url($social['share_link']) ?>" target="_blank" class="cff-<?php echo $social_key ?>-icon">
41
  <span class="fa fab fa-<?php echo $social['icon'] ?>" aria-hidden="true"></span>
42
  <span class="cff-screenreader"><?php echo $social['text'] ?></span>
43
- </a>
44
  <?php endforeach; ?>
45
  </p>
46
- <?php endif; ?>
47
  </div>
48
  <?php endif; ?>
49
  </div>
50
- <?php
51
  endif;
3
  * Custom Facebook Feed Item : Post Links
4
  * Displays the custom feed item post links (View on Facebook & Share)
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  use CustomFacebookFeed\CFF_Utils;
16
 
17
 
18
  $cff_link_styles = $this_class->get_style_attribute( 'post_link' );
19
+ $cff_show_facebook_link = CFF_Utils::check_if_on( $atts['showfacebooklink'] );
20
  $cff_show_facebook_share = CFF_Utils::check_if_on( $atts['showsharelink'] );
21
  $cff_post_text_to_share = CFF_Shortcode_Display::get_post_link_text_to_share( $cff_post_text );
22
  $link_text = CFF_Shortcode_Display::get_post_link_text_link( $atts, $cff_post_type );
40
  <a href="<?php echo esc_url($social['share_link']) ?>" target="_blank" class="cff-<?php echo $social_key ?>-icon">
41
  <span class="fa fab fa-<?php echo $social['icon'] ?>" aria-hidden="true"></span>
42
  <span class="cff-screenreader"><?php echo $social['text'] ?></span>
43
+ </a>
44
  <?php endforeach; ?>
45
  </p>
46
+ <?php endif; ?>
47
  </div>
48
  <?php endif; ?>
49
  </div>
50
+ <?php
51
  endif;
templates/item/post-text.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
  /**
3
  * Custom Facebook Feed Item : Post Text Template
4
- * Displays the custom feed item post text
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
@@ -21,13 +21,13 @@ if( !empty($post_text) ):
21
  ?>
22
 
23
  <<?php echo $cff_title_format ?> class="cff-post-text" <?php echo $cff_title_styles; ?>>
24
- <span class="cff-text" data-color="<?php echo esc_attr($cff_posttext_link_color ) ?>">
25
- <?php
26
- if( $cff_title_link ):
27
  $text_link = CFF_Shortcode_Display::get_post_text_link( $cff_post_type, $this_class, $link, $PostID );
28
- ?>
29
- <a class="cff-post-text-link" href="<?php echo esc_url($text_link); ?>" <?php echo $cff_title_styles . ' ' . $target . ' ' . $cff_nofollow ;?> >
30
- <?php
31
  endif;
32
  echo CFF_Shortcode_Display::get_post_text_contenttext( $post_text, $cff_linebreak_el, $cff_title_link );
33
  ?>
1
  <?php
2
  /**
3
  * Custom Facebook Feed Item : Post Text Template
4
+ * Displays the custom feed item post text
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
21
  ?>
22
 
23
  <<?php echo $cff_title_format ?> class="cff-post-text" <?php echo $cff_title_styles; ?>>
24
+ <span class="cff-text" data-color="<?php echo esc_attr($cff_posttext_link_color ) ?>">
25
+ <?php
26
+ if( $cff_title_link ):
27
  $text_link = CFF_Shortcode_Display::get_post_text_link( $cff_post_type, $this_class, $link, $PostID );
28
+ ?>
29
+ <a class="cff-post-text-link" href="<?php echo esc_url($text_link); ?>" <?php echo $cff_title_styles . ' ' . $target . ' ' . $cff_nofollow ;?> >
30
+ <?php
31
  endif;
32
  echo CFF_Shortcode_Display::get_post_text_contenttext( $post_text, $cff_linebreak_el, $cff_title_link );
33
  ?>
templates/item/shared-link.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
  /**
3
  * Custom Facebook Feed Item : Shared Link
4
- * Displays the item shared link
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
@@ -30,7 +30,7 @@ if($cff_post_type == 'link' || $cff_soundcloud || $cff_is_video_embed):
30
  <div class="cff-text-link cff-no-image">
31
  <?php if( isset($news->name) ) : ?>
32
  <<?php echo $cff_link_title_format ?> class="cff-link-title" <?php echo $cff_link_title_styles; ?>>
33
- <a href="<?php echo esc_url($link) ?>" <?php echo $target.' '.$cff_nofollow_referrer; ?> style="color:#<?php echo $cff_link_title_color; ?>;"><?php echo $news->name; ?></a>
34
  </<?php echo $cff_link_title_format ?>>
35
  <?php endif; ?>
36
 
@@ -38,20 +38,20 @@ if($cff_post_type == 'link' || $cff_soundcloud || $cff_is_video_embed):
38
  <p class="cff-link-caption" <?php echo $cff_link_styles_html ?>><?php echo $cff_link_caption ?></p>
39
  <?php endif; ?>
40
 
41
- <?php
42
  //Description Text
43
- if( $cff_show_desc ) :
44
  $description_text = CFF_Shortcode_Display::get_shared_link_description_text( $body_limit, $description_text, $cff_title_link, $cff_posttext_link_color );
45
- $cff_link_description = CFF_Shortcode_Display::get_shared_link_description( $cff_title_link, $description_text );
46
  if( $description_text != $cff_link_caption ):
47
  ?>
48
  <span class="cff-post-desc" <?php echo $cff_link_desc_styles_html ?>><?php echo $cff_link_description; ?></span>
49
- <?php
50
  endif;
51
- endif;
52
  ?>
53
 
54
- </div>
55
  </div>
56
 
57
  <?php endif; ?>
1
  <?php
2
  /**
3
  * Custom Facebook Feed Item : Shared Link
4
+ * Displays the item shared link
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
30
  <div class="cff-text-link cff-no-image">
31
  <?php if( isset($news->name) ) : ?>
32
  <<?php echo $cff_link_title_format ?> class="cff-link-title" <?php echo $cff_link_title_styles; ?>>
33
+ <a href="<?php echo esc_url($link) ?>" <?php echo $target.' '.$cff_nofollow_referrer; ?> style="color:#<?php echo $cff_link_title_color; ?>;"><?php echo $news->name; ?></a>
34
  </<?php echo $cff_link_title_format ?>>
35
  <?php endif; ?>
36
 
38
  <p class="cff-link-caption" <?php echo $cff_link_styles_html ?>><?php echo $cff_link_caption ?></p>
39
  <?php endif; ?>
40
 
41
+ <?php
42
  //Description Text
43
+ if( $cff_show_desc ) :
44
  $description_text = CFF_Shortcode_Display::get_shared_link_description_text( $body_limit, $description_text, $cff_title_link, $cff_posttext_link_color );
45
+ $cff_link_description = CFF_Shortcode_Display::get_shared_link_description( $cff_title_link, $description_text );
46
  if( $description_text != $cff_link_caption ):
47
  ?>
48
  <span class="cff-post-desc" <?php echo $cff_link_desc_styles_html ?>><?php echo $cff_link_description; ?></span>
49
+ <?php
50
  endif;
51
+ endif;
52
  ?>
53
 
54
+ </div>
55
  </div>
56
 
57
  <?php endif; ?>
templates/item/type/note.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Item : Note Post Type
4
  * Displays the feed note post type!
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
@@ -19,7 +19,7 @@ if ( false !== ( $cff_note_json = get_transient( $transient_name ) ) ) {
19
  //Interpret data with JSON
20
  $cff_note_obj = json_decode($cff_note_json);
21
  $cff_note_object = $cff_note_obj->attachments->data[0];
22
-
23
  $cff_note_title = isset($cff_note_object->title) ? htmlentities($cff_note_object->title, ENT_QUOTES, 'UTF-8') : '';
24
  $cff_note_description = isset($cff_note_object->description) ? htmlentities($cff_note_object->description, ENT_QUOTES, 'UTF-8') : '';
25
  $cff_note_link = isset($cff_note_object->url) ? $cff_note_object->url : '';
@@ -28,10 +28,10 @@ if ( false !== ( $cff_note_json = get_transient( $transient_name ) ) ) {
28
  } else {
29
  $attachment_data = '';
30
  if(isset($news->attachments->data[0])){
31
- $attachment_data = $news->attachments->data[0];
32
  $cff_note_title = isset($attachment_data->title) ? htmlentities($attachment_data->title, ENT_QUOTES, 'UTF-8') : '';
33
  $cff_note_description = isset($attachment_data->description) ? htmlentities($attachment_data->description, ENT_QUOTES, 'UTF-8') : '';
34
- $cff_note_link = isset($attachment_data->unshimmed_url) ? $attachment_data->unshimmed_url : '';
35
  $cff_note_media_src = '';
36
  }
37
  }
3
  * Custom Facebook Feed Item : Note Post Type
4
  * Displays the feed note post type!
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
19
  //Interpret data with JSON
20
  $cff_note_obj = json_decode($cff_note_json);
21
  $cff_note_object = $cff_note_obj->attachments->data[0];
22
+
23
  $cff_note_title = isset($cff_note_object->title) ? htmlentities($cff_note_object->title, ENT_QUOTES, 'UTF-8') : '';
24
  $cff_note_description = isset($cff_note_object->description) ? htmlentities($cff_note_object->description, ENT_QUOTES, 'UTF-8') : '';
25
  $cff_note_link = isset($cff_note_object->url) ? $cff_note_object->url : '';
28
  } else {
29
  $attachment_data = '';
30
  if(isset($news->attachments->data[0])){
31
+ $attachment_data = $news->attachments->data[0];
32
  $cff_note_title = isset($attachment_data->title) ? htmlentities($attachment_data->title, ENT_QUOTES, 'UTF-8') : '';
33
  $cff_note_description = isset($attachment_data->description) ? htmlentities($attachment_data->description, ENT_QUOTES, 'UTF-8') : '';
34
+ $cff_note_link = isset($attachment_data->unshimmed_url) ? $attachment_data->unshimmed_url : '';
35
  $cff_note_media_src = '';
36
  }
37
  }
templates/likebox.php CHANGED
@@ -3,7 +3,7 @@
3
  * Custom Facebook Feed Like Box Template
4
  * Display the Facebook page likebox
5
  *
6
- * @version X.X.X Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
@@ -32,5 +32,5 @@ $like_box_page_id = explode(",", str_replace(' ', '', $page_id) );
32
 
33
  <<?php echo $lkbx_tag . ' class="'. $lkbx_class .'" '?>>
34
  <?php CFF_Shortcode_Display::print_gdpr_notice('Like Box'); ?>
35
- <iframe src="" class="fb_iframe_widget" data-likebox-id="<?php echo esc_attr($like_box_page_id[0]); ?>" data-likebox-width="<?php echo esc_attr($cff_likebox_width); ?>" data-likebox-header="<?php echo esc_attr($cff_like_box_small_header); ?>" data-hide-cover="<?php echo esc_attr($cff_like_box_cover); ?>" data-hide-cta="<?php echo esc_attr($cff_like_box_hide_cta); ?>" data-likebox-faces="<?php echo esc_attr($cff_like_box_faces); ?>" data-height="<?php echo esc_attr($cff_likebox_height); ?>" data-locale="<?php echo esc_attr($cff_locale); ?>" scrolling="no" allowTransparency="true" allow="encrypted-media" ></iframe>
36
  </<?php echo $lkbx_tag ?>>
3
  * Custom Facebook Feed Like Box Template
4
  * Display the Facebook page likebox
5
  *
6
+ * @version 2.19 Custom Facebook Feed by Smash Balloon
7
  *
8
  */
9
 
32
 
33
  <<?php echo $lkbx_tag . ' class="'. $lkbx_class .'" '?>>
34
  <?php CFF_Shortcode_Display::print_gdpr_notice('Like Box'); ?>
35
+ <iframe src="" class="fb_iframe_widget" data-likebox-id="<?php echo esc_attr($like_box_page_id[0]); ?>" data-likebox-width="<?php echo esc_attr($cff_likebox_width); ?>" data-likebox-header="<?php echo esc_attr($cff_like_box_small_header); ?>" data-hide-cover="<?php echo esc_attr($cff_like_box_cover); ?>" data-hide-cta="<?php echo esc_attr($cff_like_box_hide_cta); ?>" data-likebox-faces="<?php echo esc_attr($cff_like_box_faces); ?>" data-height="<?php echo esc_attr($cff_likebox_height); ?>" data-locale="<?php echo esc_attr($cff_locale); ?>" scrolling="no" allowTransparency="true" allow="encrypted-media" ></iframe>
36
  </<?php echo $lkbx_tag ?>>