Feeds for YouTube (YouTube video, channel, and gallery plugin) - Version 1.0.2

Version Description

  • New: Changed the method used to update feeds to reduce YouTube API requests.
  • Tweak: More posts cached in the wp_posts table when a YouTube API request is made.
  • Tweak: Channel data cached to reduce YouTube API requests.
  • Fix: Error when deactivating and reactivating plugin with background caching enabled.
Download this release

Release Info

Developer smashballoon
Plugin Icon 128x128 Feeds for YouTube (YouTube video, channel, and gallery plugin)
Version 1.0.2
Comparing to
See all releases

Code changes from version 1.0.1 to 1.0.2

README.txt CHANGED
@@ -1,11 +1,11 @@
1
- === Feeds for YouTube ===
2
  Author: Smash Balloon
3
  Contributors: smashballoon, craig-at-smash-balloon
4
  Support Website: http://smashballoon/youtube-feed/
5
  Tags: YouTube, YouTube feed, YouTube widget, YouTube channel, YouTube gallery
6
  Requires at least: 3.4
7
  Tested up to: 5.3
8
- Stable tag: 1.0.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -72,6 +72,29 @@ We're Smash Balloon; a fun-loving WordPress plugin development company birthed i
72
 
73
  To find out more about the team, see [here](https://smashballoon.com/about/ "Team Smash Balloon").
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  == Installation ==
76
  1. Install the Feeds for YouTube plugin either via the WordPress plugin directory, or by uploading the files to your web server (in the /wp-content/plugins/ directory).
77
  2. Activate the plugin through the 'Plugins' menu in WordPress.
@@ -133,6 +156,30 @@ This free plugin has several layout options built into it. Use the settings in t
133
 
134
  Yep, you can choose to display between 1-50 YouTube videos in your feed by using the following setting: Feeds for YouTube > Customize > Layout > Number of Videos. The plugin also contains a "Load More" button to allow you to infinitely load more YouTube videos into your feed.
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  == Screenshots ==
137
 
138
  1. By default the plugin inherits styles from your theme
@@ -144,6 +191,12 @@ Yep, you can choose to display between 1-50 YouTube videos in your feed by using
144
  7. To display a YouTube feed just copy and paste the [youtube-feed] shortcode into a widget or page
145
 
146
  == Changelog ==
 
 
 
 
 
 
147
  = 1.0.1 =
148
  * Fix: Optimized API calls to reduce requests.
149
  * Fix: Minor bug fixes.
1
+ === Feeds for YouTube (YouTube video, channel, and gallery plugin) ===
2
  Author: Smash Balloon
3
  Contributors: smashballoon, craig-at-smash-balloon
4
  Support Website: http://smashballoon/youtube-feed/
5
  Tags: YouTube, YouTube feed, YouTube widget, YouTube channel, YouTube gallery
6
  Requires at least: 3.4
7
  Tested up to: 5.3
8
+ Stable tag: 1.0.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
72
 
73
  To find out more about the team, see [here](https://smashballoon.com/about/ "Team Smash Balloon").
74
 
75
+ ### YouTube Feed Shortcode Settings
76
+
77
+ You can edit the settings globally for all YouTube feeds on your site using the plugin settings page, but if you want to change settings for specific YouTube feeds then you can do so by using the shortcode settings listed below:
78
+
79
+ **channel** - Display videos from a YouTube channel. Eg: [youtube-feed channel="smashballoon"]
80
+ **width** - The width of your YouTube feed. Any number with a unit like "px" or "%". Eg: [youtube-feed width="300px"]
81
+ **height** - The height of your YouTube feed. Any number with a unit like "px" or "em". Eg: [youtube-feed height="500px"]
82
+ **background** - Background color for your YouTube feed. Any hex color code. Eg: [youtube-feed background="#f00"]
83
+ **playvideo** - What the user needs to do to play a YouTube video: **onclick**, **automatically**. Eg: [youtube-feed playvideo="onclick"]
84
+ **layout** - How your YouTube videos are displayed visually. Eg: [youtube-feed layout="list"]
85
+ **num** - The number of YouTube videos in the feed. Eg: [youtube-feed num="5"]
86
+ **itemspacing** - The spacing/padding around the YouTube videos in the feed. Any number with a unit like "px" or "em". Eg: [youtube-feed itemspacing="5px"]
87
+ **showheader** - Include a header for this YouTube feed. Eg: [youtube-feed showheader="false"]
88
+ **showdescription** Include the channel description in the YouTube feed header. Eg: [youtube-feed showdescription="false"]
89
+ **showbutton** - Include a "Load More" button at the bottom of the feed to load more YouTube videos. Eg: [youtube-feed showbutton="false"]
90
+ **buttoncolor** - Background color for the "Load More" button at the bottom of the YouTube feed. Any hex color code Eg: [youtube-feed buttoncolor="#0f0"]
91
+ **buttontextcolor** - Text color for the "Load More" button. Any hex color code. Eg: [youtube-feed buttontextcolor="#00f"]
92
+ **buttontext** - The text that appers on the "Load More" button. Eg: [youtube-feed buttontext=""More Videos""]
93
+ **showsubscribe** - Include a "Subscribe" button at the bottom of the YouTube feed to load more YouTube videos. Eg: [youtube-feed showsubscribe="false"]
94
+ **subscribecolor** - Background color for the YouTube "Subscribe" button. Any hex color code. Eg: [youtube-feed subscribecolor="#0f0"]
95
+ **subscribetextcolor** - Text color for the YouTube "Subscribe" button. Any hex color code. Eg: [youtube-feed subscribetextcolor="#00f"]
96
+ **subscribetext** - The text that appers on the YouTube "Subscribe" button. Eg: [youtube-feed subscribetext=""Subscribe to My Channel""]
97
+
98
  == Installation ==
99
  1. Install the Feeds for YouTube plugin either via the WordPress plugin directory, or by uploading the files to your web server (in the /wp-content/plugins/ directory).
100
  2. Activate the plugin through the 'Plugins' menu in WordPress.
156
 
157
  Yep, you can choose to display between 1-50 YouTube videos in your feed by using the following setting: Feeds for YouTube > Customize > Layout > Number of Videos. The plugin also contains a "Load More" button to allow you to infinitely load more YouTube videos into your feed.
158
 
159
+ = Will my YouTube gallery be responsive to accommodate mobile visitors? =
160
+
161
+ Yes. All YouTube feed layouts are completely mobile responsive. Using the plugin's gallery layout will automatically scroll visitors to the YouTube video player to view the video when the video thumbnail is clicked.
162
+
163
+ = Will videos from my YouTube channel be cached? =
164
+
165
+ Yes. The Feeds for YouTube plugin will cache all of the posts collected from the YouTube API. Your YouTube videos and information about your YouTube channel can then be retrieved and used for future page loads.
166
+
167
+ = How do I find the nickname of channel ID for different YouTube channels? =
168
+
169
+ You can display videos from any YouTube channel using the unique YouTube channel ID. This can be found by viewing the channel page on YouTube and looking at the end of the URL. ex: https://www.youtube.com/channel/UC1a2b3c4D5F6g7i8j9k. You can also use the channel nickname.
170
+
171
+ = How does the plugin retrieve my YouTube videos? =
172
+
173
+ The plugin connects to YouTube and requests data about videos from your YouTube channel in three ways: The RSS feed associated with each YouTube Channel, using the Smash Balloon app and the YouTube API, and using an API Key to connect to the YouTube API. The plugin uses each connection type in certain circumstances with the main concern of optimizing API calls overall.
174
+
175
+ = Will displaying my YouTube channel affect the time it takes to load the page? =
176
+
177
+ The Feeds for YouTube plugin has a few features to minimize the impact it has on page load time. For example, iframes for playing YouTube videos are not loaded until the feed is interacted with by a visitor. Thumbnails of your YouTube videos are the smallest resolution necessary relative to the size of the feed. Also, these video thumbnails are not loaded until the rest of the content on the page is loaded.
178
+
179
+ = How often do new videos from my YouTube channel appear in the YouTube gallery? =
180
+
181
+ By default, the plugin retrieves new YouTube videos for your YouTube gallery once every hour. You can reduce this to as little as 15 minutes if needed. You can even set your YouTube gallery to update using WordPress cron in the background so the caching process is not relying on the page with your YouTube gallery being visited.
182
+
183
  == Screenshots ==
184
 
185
  1. By default the plugin inherits styles from your theme
191
  7. To display a YouTube feed just copy and paste the [youtube-feed] shortcode into a widget or page
192
 
193
  == Changelog ==
194
+ = 1.0.2 =
195
+ * New: Changed the method used to update feeds to reduce YouTube API requests.
196
+ * Tweak: More posts cached in the wp_posts table when a YouTube API request is made.
197
+ * Tweak: Channel data cached to reduce YouTube API requests.
198
+ * Fix: Error when deactivating and reactivating plugin with background caching enabled.
199
+
200
  = 1.0.1 =
201
  * Fix: Optimized API calls to reduce requests.
202
  * Fix: Minor bug fixes.
css/admin.css CHANGED
@@ -20,7 +20,18 @@
20
  width: 16px;
21
  color: #7ad03a;
22
  }
23
-
 
 
 
 
 
 
 
 
 
 
 
24
  /* Tooltips */
25
  #sbspf_admin .sbspf_tooltip {
26
  display: none;
@@ -698,4 +709,34 @@
698
  #sbspf_admin .sbspf_table_header{
699
  background: #ddd;
700
  font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
701
  }
20
  width: 16px;
21
  color: #7ad03a;
22
  }
23
+ #sbspf_admin .sbspf_fade {
24
+ opacity: .6;
25
+ }
26
+ #sbspf_admin .sbspf_aside {
27
+ font-style: italic;
28
+ font-weight: normal;
29
+ font-size: 12px;
30
+ margin: .3em 0;
31
+ }
32
+ #sbspf_admin .sbspf_red {
33
+ color: #eb381c;
34
+ }
35
  /* Tooltips */
36
  #sbspf_admin .sbspf_tooltip {
37
  display: none;
709
  #sbspf_admin .sbspf_table_header{
710
  background: #ddd;
711
  font-weight: bold;
712
+ }
713
+
714
+
715
+ /* SBY Specific */
716
+ #sbspf_admin .sby_mode_option {
717
+ position: relative;
718
+ margin-bottom: 20px;
719
+ }
720
+ #sbspf_admin .sby_mode_option label {
721
+ display: inline-block;
722
+ font-weight: bold;
723
+ }
724
+ #sbspf_admin .sby_mode_option .sbspf_note {
725
+ display: block;
726
+ margin-left: 0;
727
+ }
728
+ #sbspf_admin .sby_mode_option .sbspf_note,
729
+ #sbspf_admin .sby_mode_option label {
730
+ margin-bottom: 5px;
731
+ }
732
+ #sbspf_admin .sby_mode_option input[type=radio] {
733
+ position: absolute;
734
+ top: 6px;
735
+ }
736
+ #sbspf_admin .sby_mode_option_text {
737
+ margin-left: 22px;
738
+ }
739
+ #sbspf_admin .sby_mode_option.sbspf_fade .sby_important,
740
+ #sbspf_admin .sby_mode_option.sbspf_fade .sbspf_note {
741
+ opacity: 1;
742
  }
inc/admin/admin-functions.php CHANGED
@@ -407,7 +407,6 @@ add_action( 'wp_ajax_sbspf_account_search', 'sbspf_account_search' );
407
  function sby_reset_cron( $settings ) {
408
  $sbi_caching_type = isset( $settings['caching_type'] ) ? $settings['caching_type'] : '';
409
  $sbi_cache_cron_interval = isset( $settings['cache_cron_interval'] ) ? $settings['cache_cron_interval'] : '';
410
- $sbi_cache_cron_interval = $sbi_cache_cron_interval === '30mins' ? '1hour' : $sbi_cache_cron_interval;
411
  $sbi_cache_cron_time = isset( $settings['cache_cron_time'] ) ? $settings['cache_cron_time'] : '';
412
  $sbi_cache_cron_am_pm = isset( $settings['cache_cron_am_pm'] ) ? $settings['cache_cron_am_pm'] : '';
413
 
407
  function sby_reset_cron( $settings ) {
408
  $sbi_caching_type = isset( $settings['caching_type'] ) ? $settings['caching_type'] : '';
409
  $sbi_cache_cron_interval = isset( $settings['cache_cron_interval'] ) ? $settings['cache_cron_interval'] : '';
 
410
  $sbi_cache_cron_time = isset( $settings['cache_cron_time'] ) ? $settings['cache_cron_time'] : '';
411
  $sbi_cache_cron_am_pm = isset( $settings['cache_cron_am_pm'] ) ? $settings['cache_cron_am_pm'] : '';
412
 
inc/admin/class-sbspf-admin.php CHANGED
@@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  class SB_YOUTUBE_Admin {
7
 
8
- protected $vars;
9
 
10
  protected $base_path;
11
 
@@ -49,7 +49,7 @@ class SB_YOUTUBE_Admin {
49
  } else {
50
  $this->set_active_tab( $tabs[0]['slug'] );
51
  }
52
- $this->settings = $settings;
53
  $this->option_name = $option_name;
54
  $this->false_fields = array();
55
  $this->textarea_fields = array();
@@ -57,23 +57,23 @@ class SB_YOUTUBE_Admin {
57
  }
58
 
59
  public function get_vars() {
60
- return $this->vars;
61
- }
62
 
63
  public function get_option_name() {
64
- return $this->option_name;
65
- }
66
 
67
- public function verify_post( $post ) {
68
- return wp_verify_nonce( $post[ $this->option_name . '_validate' ], $this->option_name . '_validate' );
69
- }
70
 
71
- public function hidden_fields_for_tab( $tab ) {
72
- wp_nonce_field( $this->get_option_name() . '_validate', $this->get_option_name() . '_validate', true, true );
73
- ?>
74
  <input type="hidden" name="<?php echo $this->get_option_name() . '_tab_marker'; ?>" value="<?php echo esc_attr( $tab ); ?>"/>
75
- <?php
76
- }
77
 
78
  public function init() {
79
  add_action( 'admin_menu', array( $this, 'create_menus' ) );
@@ -83,14 +83,14 @@ class SB_YOUTUBE_Admin {
83
  }
84
 
85
  public function settings_init() {
86
- $text_domain = $this->vars->text_domain();
87
  /**
88
  * Configure Tab
89
  */
90
  $args = array(
91
  'id' => 'sbspf_types',
92
  'tab' => 'configure',
93
- 'save_after' => 'true'
94
  );
95
  $this->add_settings_section( $args );
96
 
@@ -104,7 +104,7 @@ class SB_YOUTUBE_Admin {
104
  'key' => 'channel',
105
  'example' => 'smashballoon',
106
  'description' => __( 'Display videos from a YouTube channel (channel)', $text_domain ),
107
- 'display_section' => 'configure'
108
  ),
109
  'types' => $this->types
110
  );
@@ -116,7 +116,7 @@ class SB_YOUTUBE_Admin {
116
  'callback' => 'checkbox',
117
  'title' => __( 'Preserve settings when plugin is removed', $text_domain ),
118
  'default' => false,
119
- 'tooltip_info' => __( 'When removing the plugin your settings are automatically erased. Checking this box will prevent any settings from being deleted. This means that you can uninstall and reinstall the plugin without losing your settings.', $text_domain )
120
  );
121
  $this->add_settings_field( $args );
122
 
@@ -133,7 +133,7 @@ class SB_YOUTUBE_Admin {
133
  * Customize Tab
134
  */
135
  $args = array(
136
- 'title' => __( 'General', $text_domain ),
137
  'id' => 'sbspf_general',
138
  'tab' => 'customize',
139
  'save_after' => 'true'
@@ -146,11 +146,11 @@ class SB_YOUTUBE_Admin {
146
  'label' => '%',
147
  'value' => '%'
148
  ),
149
- array(
150
- 'label' => 'px',
151
- 'value' => 'px'
152
- )
153
- );
154
 
155
  $args = array(
156
  'name' => 'width',
@@ -160,22 +160,22 @@ class SB_YOUTUBE_Admin {
160
  'min' => 1,
161
  'size' => 4,
162
  'title' => __( 'Width of Feed', $text_domain ),
163
- 'shortcode' => array(
164
- 'key' => 'width',
165
- 'example' => '300px',
166
- 'description' => __( 'The width of your feed. Any number with a unit like "px" or "%".', $text_domain ),
167
- 'display_section' => 'customize'
168
- ),
169
- 'select_name' => 'widthunit',
170
- 'select_options' => $select_options,
171
- 'hidden' => array(
172
- 'callback' => 'checkbox',
173
- 'name' => 'width_responsive',
174
- 'label' => __( 'Set to be 100% width on mobile?', $text_domain ),
175
- 'before' => '<div id="sbspf_width_options">',
176
- 'after' => '</div>',
177
- 'tooltip_info' => __( 'If you set a width on the feed then this will be used on mobile as well as desktop. Check this setting to set the feed width to be 100% on mobile so that it is responsive.', $text_domain )
178
- ),
179
  );
180
  $this->add_settings_field( $args );
181
 
@@ -214,17 +214,17 @@ class SB_YOUTUBE_Admin {
214
  'section' => 'sbspf_general',
215
  'callback' => 'color',
216
  'title' => __( 'Background Color', $text_domain ),
217
- 'shortcode' => array(
218
- 'key' => 'background',
219
- 'example' => '#f00',
220
- 'description' => __( 'Background color for the feed. Any hex color code.', $text_domain ),
221
- 'display_section' => 'customize'
222
- ),
223
  );
224
  $this->add_settings_field( $args );
225
 
226
  $args = array(
227
- 'title' => __( 'Layout', $text_domain ),
228
  'id' => 'sbspf_layout',
229
  'tab' => 'customize',
230
  'save_after' => 'true'
@@ -252,15 +252,15 @@ class SB_YOUTUBE_Admin {
252
  }
253
 
254
  public function add_false_field( $name, $tab ) {
255
- $this->false_fields[ $tab ][] = $name;
256
- }
257
 
258
  public function get_false_fields( $tab ) {
259
- if ( isset( $this->false_fields[ $tab ] ) ) {
260
- return $this->false_fields[ $tab ];
261
- }
262
 
263
- return array();
264
  }
265
 
266
  public function add_textarea_field( $name, $tab ) {
@@ -291,32 +291,32 @@ class SB_YOUTUBE_Admin {
291
 
292
  $save_after = isset( $args['save_after'] ) ? $args['save_after'] : false;
293
  $this->settings_sections[ $args['tab'] ][] = array(
294
- 'id' => $args['id'],
295
- 'save_after' => $save_after
296
- );
297
  }
298
 
299
  public function add_settings_field( $args ) {
300
  $title_after = '';
301
  $shortcode = false;
302
- if ( isset( $args['shortcode'] ) ) {
303
- $title_after = isset( $args['shortcode']['after'] ) ? $args['shortcode']['after'] : '';
304
- $shortcode = $args['shortcode'];
305
- }
306
  $title = $this->format_title( $args['title'], $args['name'], $shortcode, $title_after );
307
 
308
- if ( $args['callback'] === 'checkbox' || (isset( $args['falsefield'] ) && $args['falsefield'] === true) ) {
309
- $tab = 'none';
310
- foreach ( $this->settings_sections as $key => $settings_sections ) {
311
- foreach ( $settings_sections as $this_tab_sections ) {
312
- if ( $this_tab_sections['id'] === $args['section'] ) {
313
- $tab = $key;
314
- }
315
- }
316
 
317
- }
318
- $this->add_false_field( $args['name'], $tab );
319
- }
320
 
321
  if ( $args['callback'] === 'textarea' ) {
322
  $tab = 'none';
@@ -345,51 +345,51 @@ class SB_YOUTUBE_Admin {
345
  }
346
 
347
  if ( isset( $args['hidden'] ) ) {
348
- if ( $args['hidden']['callback'] === 'checkbox' ) {
349
- $tab = 'none';
350
- foreach ( $this->settings_sections as $key => $settings_sections ) {
351
- foreach ( $settings_sections as $this_tab_sections ) {
352
- if ( $this_tab_sections['id'] === $args['section'] ) {
353
- $tab = $key;
354
- }
355
- }
356
-
357
- }
358
- $this->add_false_field( $args['hidden']['name'], $tab );
359
- }
360
  }
361
  }
362
 
363
  public function set_feed_types( $types ) {
364
- $this->types = $types;
365
- }
366
 
367
  public function set_feed_layouts( $layouts ) {
368
  $this->layouts = $layouts;
369
  }
370
 
371
- public function set_display_table_sections( $headings ) {
372
- foreach ( $headings as $heading ) {
373
- $this->display_your_feed_sections[ $heading['slug'] ] = array(
374
- 'label' => $heading['label'],
375
- 'settings' => array()
376
- );
377
- }
378
- }
379
 
380
  public function checkbox( $args ) {
381
- $default = isset( $args['default'] ) ? $args['default'] : false;
382
  $selected = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
383
  $label = isset( $args['label'] ) ? $args['label'] : __( 'Yes' );
384
  $tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
385
  ?>
386
  <input name="<?php echo $this->option_name .'['.esc_attr( $args['name'] ).']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>" type="checkbox"<?php if ( $selected ) echo ' checked'; ?>/>
387
  <label for="<?php echo $this->option_name . '_' . $args['name']; ?>"><?php echo esc_html( $label ); ?></label>
388
- <?php if ( isset( $args['tooltip_info'] ) ) : ?>
389
- <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
390
- <p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
391
- <?php
392
- endif;
393
  }
394
 
395
  public function text( $args ) {
@@ -414,20 +414,20 @@ class SB_YOUTUBE_Admin {
414
  <?php endif; ?>
415
 
416
  <?php if ( isset( $args['select_options'] ) ) :
417
- $value = isset( $this->settings[ $args['select_name'] ] ) ? $this->settings[ $args['select_name'] ] : $args['select_options'][0]['value'];
418
- ?>
419
- <select name="<?php echo $this->option_name.'['.$args['select_name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['select_name']; ?>">
420
- <?php foreach ( $args['select_options'] as $select_option ) : ?>
421
- <option value="<?php echo esc_attr( $select_option['value'] ); ?>"<?php if ( (string)$select_option['value'] === (string)$value ) echo ' selected'; ?>><?php echo esc_html( $select_option['label'] ); ?></option>
422
- <?php endforeach; ?>
423
- </select>
424
- <?php endif; ?>
425
 
426
  <?php if ( isset( $args['hidden'] ) ) : ?>
427
 
428
  <?php
429
  if ( is_callable( array( $this, $args['hidden']['callback'] ) ) ){
430
- echo $args['hidden']['before'];
431
  call_user_func_array(
432
  array( $this, $args['hidden']['callback'] ),
433
  array( $args['hidden'] )
@@ -438,14 +438,14 @@ class SB_YOUTUBE_Admin {
438
  <?php endif; ?>
439
 
440
  <?php if ( isset( $args['additional'] ) ) : ?>
441
- <?php echo $args['additional']; ?>
442
- <?php endif; ?>
443
 
444
  <?php if ( isset( $args['tooltip_info'] ) ) : ?>
445
  <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
446
  <p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
447
- <?php
448
- endif;
449
  }
450
 
451
  public function select( $args ) {
@@ -458,12 +458,12 @@ class SB_YOUTUBE_Admin {
458
 
459
  while ( $i <= (int)$args['max'] ) {
460
  $args['options'][] = array(
461
- 'label' => $i,
462
- 'value' => $i
463
- );
464
  $i++;
465
  }
466
- }
467
 
468
  $tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
469
  ?>
@@ -474,8 +474,8 @@ class SB_YOUTUBE_Admin {
474
  </select>
475
 
476
  <?php if ( isset( $args['additional'] ) ) : ?>
477
- <?php echo $args['additional']; ?>
478
- <?php endif; ?>
479
 
480
  <?php if ( isset( $args['tooltip_info'] ) ) : ?>
481
  <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
@@ -487,20 +487,20 @@ class SB_YOUTUBE_Admin {
487
  $default = isset( $args['default'] ) ? $args['default'] : '';
488
  $value = isset( $this->settings[ $args['name'] ] ) ? stripslashes( $this->settings[ $args['name'] ] ) : $default;
489
 
490
- if ( isset( $args['tooltip_info'] ) ) : ?>
491
  <span><?php echo $args['tooltip_info']; ?></span><br>
492
  <?php endif; ?>
493
 
494
  <textarea name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>"rows="7"><?php echo $value; ?></textarea>
495
 
496
- <?php if ( isset( $args['note'] ) ) : ?>
497
  <br><span class="sbspf_note"><?php echo $args['note']; ?></span>
498
  <?php endif;
499
  }
500
 
501
  public function color( $args ) {
502
- $args['color'] = true;
503
- $this->text( $args );
504
  }
505
 
506
  public function types( $args ) {
@@ -532,12 +532,12 @@ class SB_YOUTUBE_Admin {
532
  </div>
533
  <?php if ( empty( $selected ) ) : ?>
534
  <p class="sbspf_no_accounts" style="margin-top: -3px; margin-right: 10px;"><?php _e( 'Connect an account above', $this->vars->text_domain() ); ?></p>
535
- <?php endif; ?>
536
 
537
- <?php endif; ?>
538
- <?php if ( isset( $type['note'] ) ) : ?>
539
  <br><span class="sbspf_note"><?php echo $type['note']; ?></span>
540
- <?php endif; ?>
541
  </div>
542
 
543
  <div class="sbspf_tooltip sbspf_type_tooltip sbspf_more_info">
@@ -550,92 +550,92 @@ class SB_YOUTUBE_Admin {
550
  }
551
 
552
  public function cache( $args ) {
553
- $social_network = $this->vars->social_network();
554
  $type_selected = isset( $this->settings['caching_type'] ) ? $this->settings['caching_type'] : 'page';
555
  $caching_time = isset( $this->settings['caching_time'] ) ? $this->settings['caching_time'] : 1;
556
  $cache_time_unit_selected = isset( $this->settings['cache_time_unit'] ) ? $this->settings['cache_time_unit'] : 'hours';
557
  $cache_cron_interval_selected = isset( $this->settings['cache_cron_interval'] ) ? $this->settings['cache_cron_interval'] : '';
558
  $cache_cron_time = isset( $this->settings['cache_cron_time'] ) ? $this->settings['cache_cron_time'] : '';
559
  $cache_cron_am_pm = isset( $this->settings['cache_cron_am_pm'] ) ? $this->settings['cache_cron_am_pm'] : '';
560
-
561
  ?>
562
  <div class="sbspf_cache_settings_wrap">
563
- <div class="sbspf_row">
564
- <input type="radio" name="<?php echo $this->option_name.'[caching_type]'; ?>" class="sbspf_caching_type_input" id="sbspf_caching_type_page" value="page"<?php if ( $type_selected === 'page' ) echo ' checked'?>>
565
- <label class="sbspf_radio_label" for="sbspf_caching_type_page"><?php _e ( 'When the page loads', $this->vars->text_domain() ); ?></label>
566
- <a class="sbspf_tooltip_link sbspf_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 2px;"><?php echo $this->default_tooltip_text() ?></a>
567
- <p class="sbspf_tooltip sbspf_more_info"><?php echo sprintf( __( "Your %s data is temporarily cached by the plugin in your WordPress database. There are two ways that you can set the plugin to check for new data:<br><br>
568
- <b>1. When the page loads</b><br>Selecting this option means that when the cache expires then the plugin will check %s for new posts the next time that the feed is loaded. You can choose how long this data should be cached for. If you set the time to 60 minutes then the plugin will clear the cached data after that length of time, and the next time the page is viewed it will check for new data. <b>Tip:</b> If you're experiencing an issue with the plugin not updating automatically then try enabling the setting labeled <b>'Force cache to clear on interval'</b> which is located on the 'Customize' tab.<br><br>
569
  <b>2. In the background</b><br>Selecting this option means that the plugin will check for new data in the background so that the feed is updated behind the scenes. You can select at what time and how often the plugin should check for new data using the settings below. <b>Please note</b> that the plugin will initially check for data from Instagram when the page first loads, but then after that will check in the background on the schedule selected - unless the cache is cleared.", $this->vars->text_domain() ), $social_network, $social_network ); ?>
570
- </p>
571
- </div>
572
- <div class="sbspf_row sbspf-caching-page-options" style="display: none;">
573
- <?php _e ( 'Every', $this->vars->text_domain() ); ?>:
574
- <input name="<?php echo $this->option_name.'[caching_time]'; ?>" type="text" value="<?php echo esc_attr( $caching_time ); ?>" size="4">
575
- <select name="<?php echo $this->option_name.'[caching_time_unit]'; ?>">
576
- <option value="minutes"<?php if ( $cache_time_unit_selected === 'minutes' ) echo ' selected'?>><?php _e ( 'Minutes', $this->vars->text_domain() ); ?></option>
577
- <option value="hours"<?php if ( $cache_time_unit_selected === 'hours' ) echo ' selected'?>><?php _e ( 'Hours', $this->vars->text_domain() ); ?></option>
578
- <option value="days"<?php if ( $cache_time_unit_selected === 'days' ) echo ' selected'?>><?php _e ( 'Days', $this->vars->text_domain() ); ?></option>
579
- </select>
580
- <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php _e ( 'What does this mean?', $this->vars->text_domain() ); ?></a>
581
- <p class="sbspf_tooltip sbspf_more_info"><?php echo sprintf( __("Your %s posts are temporarily cached by the plugin in your WordPress database. You can choose how long the posts should be cached for. If you set the time to 1 hour then the plugin will clear the cache after that length of time and check %s for posts again.", $this->vars->text_domain() ), $social_network, $social_network ); ?></p>
582
- </div>
583
-
584
- <div class="sbspf_row">
585
- <input type="radio" name="<?php echo $this->option_name.'[caching_type]'; ?>" id="sbspf_caching_type_cron" class="sbspf_caching_type_input" value="background" <?php if ( $type_selected === 'background' ) echo ' checked'?>>
586
- <label class="sbspf_radio_label" for="sbspf_caching_type_cron"><?php _e ( 'In the background', $this->vars->text_domain() ); ?></label>
587
- </div>
588
- <div class="sbspf_row sbspf-caching-cron-options" style="display: block;">
589
 
590
- <select name="<?php echo $this->option_name.'[cache_cron_interval]'; ?>" id="sbspf_cache_cron_interval">
591
- <option value="30mins"<?php if ( $cache_cron_interval_selected === '30mins' ) echo ' selected'?>><?php _e ( 'Every 30 minutes', $this->vars->text_domain() ); ?></option>
592
- <option value="1hour"<?php if ( $cache_cron_interval_selected === '1hour' ) echo ' selected'?>><?php _e ( 'Every hour', $this->vars->text_domain() ); ?></option>
593
- <option value="12hours"<?php if ( $cache_cron_interval_selected === '12hours' ) echo ' selected'?>><?php _e ( 'Every 12 hours', $this->vars->text_domain() ); ?></option>
594
- <option value="24hours"<?php if ( $cache_cron_interval_selected === '24hours' ) echo ' selected'?>><?php _e ( 'Every 24 hours', $this->vars->text_domain() ); ?></option>
595
- </select>
596
 
597
- <div id="sbspf-caching-time-settings" style="">
598
- <?php _e ( 'at', $this->vars->text_domain() ); ?>
599
- <select name="<?php echo $this->option_name.'[cache_cron_time]'; ?>" style="width: 80px">
600
- <option value="1"<?php if ( (int)$cache_cron_time === 1 ) echo ' selected'?>>1:00</option>
601
- <option value="2"<?php if ( (int)$cache_cron_time === 2 ) echo ' selected'?>>2:00</option>
602
- <option value="3"<?php if ( (int)$cache_cron_time === 3 ) echo ' selected'?>>3:00</option>
603
- <option value="4"<?php if ( (int)$cache_cron_time === 4 ) echo ' selected'?>>4:00</option>
604
- <option value="5"<?php if ( (int)$cache_cron_time === 5 ) echo ' selected'?>>5:00</option>
605
- <option value="6"<?php if ( (int)$cache_cron_time === 6 ) echo ' selected'?>>6:00</option>
606
- <option value="7"<?php if ( (int)$cache_cron_time === 7 ) echo ' selected'?>>7:00</option>
607
- <option value="8"<?php if ( (int)$cache_cron_time === 8 ) echo ' selected'?>>8:00</option>
608
- <option value="9"<?php if ( (int)$cache_cron_time === 9 ) echo ' selected'?>>9:00</option>
609
- <option value="10"<?php if ( (int)$cache_cron_time === 10 ) echo ' selected'?>>10:00</option>
610
- <option value="11"<?php if ( (int)$cache_cron_time === 11 ) echo ' selected'?>>11:00</option>
611
- <option value="0"<?php if ( (int)$cache_cron_time === 0 ) echo ' selected'?>>12:00</option>
612
  </select>
613
 
614
- <select name="<?php echo $this->option_name.'[cache_cron_am_pm]'; ?>" style="width: 50px">
615
- <option value="am"<?php if ( $cache_cron_am_pm === 'am' ) echo ' selected'?>><?php _e ( 'AM', $this->vars->text_domain() ); ?></option>
616
- <option value="pm"<?php if ( $cache_cron_am_pm === 'pm' ) echo ' selected'?>><?php _e ( 'PM', $this->vars->text_domain() ); ?></option>
617
- </select>
618
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
 
620
- <?php
621
- if ( wp_next_scheduled( 'sbspf_feed_update' ) ) {
622
- $time_format = get_option( 'time_format' );
623
- if ( ! $time_format ) {
624
- $time_format = 'g:i a';
625
- }
626
- //
627
- $schedule = wp_get_schedule( 'sbspf_feed_update' );
628
- if ( $schedule == '30mins' ) $schedule = __( 'every 30 minutes', $this->vars->text_domain() );
629
- if ( $schedule == 'twicedaily' ) $schedule = __( 'every 12 hours', $this->vars->text_domain() );
630
- $sbspf_next_cron_event = wp_next_scheduled( 'sbspf_feed_update' );
631
- echo '<p class="sbspf-caching-sched-notice"><span><b>' . __( 'Next check', $this->vars->text_domain() ) . ': ' . date( $time_format, $sbspf_next_cron_event + sbspf_get_utc_offset() ) . ' (' . $schedule . ')</b> - ' . __( 'Note: Saving the settings on this page will clear the cache and reset this schedule', $this->vars->text_domain() ) . '</span></p>';
632
- } else {
633
- echo '<p style="font-size: 11px; color: #666;">' . __( 'Nothing currently scheduled', $this->vars->text_domain() ) . '</p>';
634
- }
635
- ?>
636
- </div>
637
  </div>
638
- <?php
639
  }
640
 
641
  public function layout( $args ) {
@@ -643,54 +643,54 @@ class SB_YOUTUBE_Admin {
643
  $value = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
644
  ?>
645
  <div class="sbspf_layouts">
646
- <?php foreach ( $args['layouts'] as $layout ) : ?>
647
  <div class="sbspf_layout_cell">
648
  <input class="sbspf_layout_type" id="sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>" name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" type="radio" value="<?php echo esc_attr( $layout['slug'] ); ?>"<?php if ( $layout['slug'] === $value ) echo ' checked'?>><label for="sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>"><span class="sbspf_label"><?php echo $layout['label']; ?></span><img src="<?php echo esc_url( $this->vars->plugin_url() . $layout['image'] ); ?>"></label>
649
  </div>
650
- <?php endforeach; ?>
651
 
652
  <div class="sbspf_layout_options_wrap">
653
- <?php foreach ( $args['layouts'] as $layout ) : ?>
654
- <div class="sbspf_layout_settings sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>">
655
 
656
- <div class="sbspf_layout_setting">
657
- <?php echo sby_admin_icon( 'info-circle' ); ?>&nbsp;&nbsp;&nbsp;<span class="sbspf_note" style="margin-left: 0;"><?php echo $layout['note']; ?></span>
658
- </div>
659
- <?php if ( ! empty( $layout['options'] ) ) : ?>
660
- <div class="sbspf_layout_setting">
661
- <?php foreach ( $layout['options'] as $option ) :
662
- $option['name'] = $layout['slug'].$option['name'];
663
- ?>
664
- <div class="ctf_layout_setting">
 
 
 
 
665
 
666
- <label title="<?php echo __( 'Click for shortcode option', $this->vars->text_domain() ); ?>"><?php echo $option['label']; ?></label><code class="sbspf_shortcode"> <?php echo $option['name'] . "\n"; ?>
667
- Eg: <?php echo $option['name']; ?>=<?php echo $option['shortcode_example']; ?></code><br>
668
- <?php call_user_func_array( array( $this, $option['callback'] ), array( $option ) ); ?>
669
 
 
670
  </div>
 
671
 
672
- <?php endforeach; ?>
673
  </div>
674
- <?php endif; ?>
675
 
676
- </div>
677
-
678
- <?php endforeach; ?>
679
  </div>
680
  </div>
681
- <?php
682
- }
683
-
684
- public function format_title( $label, $name, $shortcode_args = false, $after = '' ) {
685
- $formatted_label = '<label for="' . $this->option_name . '_' . $name . '">' . $label .'</label>';
686
- if ( $shortcode_args ) {
687
- $formatted_label .= '<code class="sbspf_shortcode"> ' . $shortcode_args['key'] . "\n";
688
- $formatted_label .= 'Eg: ' . $shortcode_args['key'] . '=' . $shortcode_args['example'] . '</code><br>';
689
- }
690
- $formatted_label .= $after;
691
-
692
- return $formatted_label;
693
- }
694
 
695
  public function validate_options( $input, $tab ) {
696
  $updated_options = get_option( $this->option_name, array() );
@@ -699,25 +699,25 @@ class SB_YOUTUBE_Admin {
699
 
700
  foreach ( $false_if_empty_keys as $false_key ) {
701
  $updated_options[ $false_key ] = false;
702
- }
703
 
704
  foreach ( $input as $key => $val ) {
705
- if ( in_array( $key, $false_if_empty_keys ) ) {
706
- $updated_options[ $key ] = ($val === 'on');
707
- } elseif ( in_array( $key, $textarea_keys ) ) {
708
- $updated_options[ $key ] = sanitize_textarea_field( $val );
709
- } elseif ( is_array( $val ) ) {
710
- foreach ( $val as $key2 => $val2 ) {
711
- $updated_options[ $key ][ $key2 ] = sanitize_text_field( $val2 );
712
- }
713
- } else {
714
- $updated_options[ $key ] = sanitize_text_field( $val );
715
- }
716
- }
717
 
718
  if ( $tab === 'configure' ) {
719
- do_action( $this->option_name . '_after_configure_save', $updated_options );
720
- }
721
 
722
  return $updated_options;
723
  }
@@ -726,7 +726,7 @@ class SB_YOUTUBE_Admin {
726
  public function update_options( $new_settings ) {
727
  update_option( $this->get_option_name(), $new_settings );
728
  $this->settings = $new_settings;
729
- }
730
 
731
  public function get_sections( $tab ) {
732
  if ( isset( $this->settings_sections[ $tab ] ) ) {
@@ -844,6 +844,6 @@ class SB_YOUTUBE_Admin {
844
  }
845
 
846
  public function default_tooltip_text() {
847
- return '<span class="screen-reader-text">' . __( 'What does this mean?', $this->vars->text_domain() ) . '</span>' . sby_admin_icon( 'question-circle' );
848
- }
849
  }
5
 
6
  class SB_YOUTUBE_Admin {
7
 
8
+ protected $vars;
9
 
10
  protected $base_path;
11
 
49
  } else {
50
  $this->set_active_tab( $tabs[0]['slug'] );
51
  }
52
+ $this->settings = $settings;
53
  $this->option_name = $option_name;
54
  $this->false_fields = array();
55
  $this->textarea_fields = array();
57
  }
58
 
59
  public function get_vars() {
60
+ return $this->vars;
61
+ }
62
 
63
  public function get_option_name() {
64
+ return $this->option_name;
65
+ }
66
 
67
+ public function verify_post( $post ) {
68
+ return wp_verify_nonce( $post[ $this->option_name . '_validate' ], $this->option_name . '_validate' );
69
+ }
70
 
71
+ public function hidden_fields_for_tab( $tab ) {
72
+ wp_nonce_field( $this->get_option_name() . '_validate', $this->get_option_name() . '_validate', true, true );
73
+ ?>
74
  <input type="hidden" name="<?php echo $this->get_option_name() . '_tab_marker'; ?>" value="<?php echo esc_attr( $tab ); ?>"/>
75
+ <?php
76
+ }
77
 
78
  public function init() {
79
  add_action( 'admin_menu', array( $this, 'create_menus' ) );
83
  }
84
 
85
  public function settings_init() {
86
+ $text_domain = $this->vars->text_domain();
87
  /**
88
  * Configure Tab
89
  */
90
  $args = array(
91
  'id' => 'sbspf_types',
92
  'tab' => 'configure',
93
+ 'save_after' => 'true'
94
  );
95
  $this->add_settings_section( $args );
96
 
104
  'key' => 'channel',
105
  'example' => 'smashballoon',
106
  'description' => __( 'Display videos from a YouTube channel (channel)', $text_domain ),
107
+ 'display_section' => 'configure'
108
  ),
109
  'types' => $this->types
110
  );
116
  'callback' => 'checkbox',
117
  'title' => __( 'Preserve settings when plugin is removed', $text_domain ),
118
  'default' => false,
119
+ 'tooltip_info' => __( 'When removing the plugin your settings are automatically erased. Checking this box will prevent any settings from being deleted. This means that you can uninstall and reinstall the plugin without losing your settings.', $text_domain )
120
  );
121
  $this->add_settings_field( $args );
122
 
133
  * Customize Tab
134
  */
135
  $args = array(
136
+ 'title' => __( 'General', $text_domain ),
137
  'id' => 'sbspf_general',
138
  'tab' => 'customize',
139
  'save_after' => 'true'
146
  'label' => '%',
147
  'value' => '%'
148
  ),
149
+ array(
150
+ 'label' => 'px',
151
+ 'value' => 'px'
152
+ )
153
+ );
154
 
155
  $args = array(
156
  'name' => 'width',
160
  'min' => 1,
161
  'size' => 4,
162
  'title' => __( 'Width of Feed', $text_domain ),
163
+ 'shortcode' => array(
164
+ 'key' => 'width',
165
+ 'example' => '300px',
166
+ 'description' => __( 'The width of your feed. Any number with a unit like "px" or "%".', $text_domain ),
167
+ 'display_section' => 'customize'
168
+ ),
169
+ 'select_name' => 'widthunit',
170
+ 'select_options' => $select_options,
171
+ 'hidden' => array(
172
+ 'callback' => 'checkbox',
173
+ 'name' => 'width_responsive',
174
+ 'label' => __( 'Set to be 100% width on mobile?', $text_domain ),
175
+ 'before' => '<div id="sbspf_width_options">',
176
+ 'after' => '</div>',
177
+ 'tooltip_info' => __( 'If you set a width on the feed then this will be used on mobile as well as desktop. Check this setting to set the feed width to be 100% on mobile so that it is responsive.', $text_domain )
178
+ ),
179
  );
180
  $this->add_settings_field( $args );
181
 
214
  'section' => 'sbspf_general',
215
  'callback' => 'color',
216
  'title' => __( 'Background Color', $text_domain ),
217
+ 'shortcode' => array(
218
+ 'key' => 'background',
219
+ 'example' => '#f00',
220
+ 'description' => __( 'Background color for the feed. Any hex color code.', $text_domain ),
221
+ 'display_section' => 'customize'
222
+ ),
223
  );
224
  $this->add_settings_field( $args );
225
 
226
  $args = array(
227
+ 'title' => __( 'Layout', $text_domain ),
228
  'id' => 'sbspf_layout',
229
  'tab' => 'customize',
230
  'save_after' => 'true'
252
  }
253
 
254
  public function add_false_field( $name, $tab ) {
255
+ $this->false_fields[ $tab ][] = $name;
256
+ }
257
 
258
  public function get_false_fields( $tab ) {
259
+ if ( isset( $this->false_fields[ $tab ] ) ) {
260
+ return $this->false_fields[ $tab ];
261
+ }
262
 
263
+ return array();
264
  }
265
 
266
  public function add_textarea_field( $name, $tab ) {
291
 
292
  $save_after = isset( $args['save_after'] ) ? $args['save_after'] : false;
293
  $this->settings_sections[ $args['tab'] ][] = array(
294
+ 'id' => $args['id'],
295
+ 'save_after' => $save_after
296
+ );
297
  }
298
 
299
  public function add_settings_field( $args ) {
300
  $title_after = '';
301
  $shortcode = false;
302
+ if ( isset( $args['shortcode'] ) ) {
303
+ $title_after = isset( $args['shortcode']['after'] ) ? $args['shortcode']['after'] : '';
304
+ $shortcode = $args['shortcode'];
305
+ }
306
  $title = $this->format_title( $args['title'], $args['name'], $shortcode, $title_after );
307
 
308
+ if ( $args['callback'] === 'checkbox' || (isset( $args['falsefield'] ) && $args['falsefield'] === true) ) {
309
+ $tab = 'none';
310
+ foreach ( $this->settings_sections as $key => $settings_sections ) {
311
+ foreach ( $settings_sections as $this_tab_sections ) {
312
+ if ( $this_tab_sections['id'] === $args['section'] ) {
313
+ $tab = $key;
314
+ }
315
+ }
316
 
317
+ }
318
+ $this->add_false_field( $args['name'], $tab );
319
+ }
320
 
321
  if ( $args['callback'] === 'textarea' ) {
322
  $tab = 'none';
345
  }
346
 
347
  if ( isset( $args['hidden'] ) ) {
348
+ if ( $args['hidden']['callback'] === 'checkbox' ) {
349
+ $tab = 'none';
350
+ foreach ( $this->settings_sections as $key => $settings_sections ) {
351
+ foreach ( $settings_sections as $this_tab_sections ) {
352
+ if ( $this_tab_sections['id'] === $args['section'] ) {
353
+ $tab = $key;
354
+ }
355
+ }
356
+
357
+ }
358
+ $this->add_false_field( $args['hidden']['name'], $tab );
359
+ }
360
  }
361
  }
362
 
363
  public function set_feed_types( $types ) {
364
+ $this->types = $types;
365
+ }
366
 
367
  public function set_feed_layouts( $layouts ) {
368
  $this->layouts = $layouts;
369
  }
370
 
371
+ public function set_display_table_sections( $headings ) {
372
+ foreach ( $headings as $heading ) {
373
+ $this->display_your_feed_sections[ $heading['slug'] ] = array(
374
+ 'label' => $heading['label'],
375
+ 'settings' => array()
376
+ );
377
+ }
378
+ }
379
 
380
  public function checkbox( $args ) {
381
+ $default = isset( $args['default'] ) ? $args['default'] : false;
382
  $selected = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
383
  $label = isset( $args['label'] ) ? $args['label'] : __( 'Yes' );
384
  $tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
385
  ?>
386
  <input name="<?php echo $this->option_name .'['.esc_attr( $args['name'] ).']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>" type="checkbox"<?php if ( $selected ) echo ' checked'; ?>/>
387
  <label for="<?php echo $this->option_name . '_' . $args['name']; ?>"><?php echo esc_html( $label ); ?></label>
388
+ <?php if ( isset( $args['tooltip_info'] ) ) : ?>
389
+ <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
390
+ <p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
391
+ <?php
392
+ endif;
393
  }
394
 
395
  public function text( $args ) {
414
  <?php endif; ?>
415
 
416
  <?php if ( isset( $args['select_options'] ) ) :
417
+ $value = isset( $this->settings[ $args['select_name'] ] ) ? $this->settings[ $args['select_name'] ] : $args['select_options'][0]['value'];
418
+ ?>
419
+ <select name="<?php echo $this->option_name.'['.$args['select_name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['select_name']; ?>">
420
+ <?php foreach ( $args['select_options'] as $select_option ) : ?>
421
+ <option value="<?php echo esc_attr( $select_option['value'] ); ?>"<?php if ( (string)$select_option['value'] === (string)$value ) echo ' selected'; ?>><?php echo esc_html( $select_option['label'] ); ?></option>
422
+ <?php endforeach; ?>
423
+ </select>
424
+ <?php endif; ?>
425
 
426
  <?php if ( isset( $args['hidden'] ) ) : ?>
427
 
428
  <?php
429
  if ( is_callable( array( $this, $args['hidden']['callback'] ) ) ){
430
+ echo $args['hidden']['before'];
431
  call_user_func_array(
432
  array( $this, $args['hidden']['callback'] ),
433
  array( $args['hidden'] )
438
  <?php endif; ?>
439
 
440
  <?php if ( isset( $args['additional'] ) ) : ?>
441
+ <?php echo $args['additional']; ?>
442
+ <?php endif; ?>
443
 
444
  <?php if ( isset( $args['tooltip_info'] ) ) : ?>
445
  <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
446
  <p class="sbspf_tooltip sbspf_more_info"><?php echo $args['tooltip_info']; ?></p>
447
+ <?php
448
+ endif;
449
  }
450
 
451
  public function select( $args ) {
458
 
459
  while ( $i <= (int)$args['max'] ) {
460
  $args['options'][] = array(
461
+ 'label' => $i,
462
+ 'value' => $i
463
+ );
464
  $i++;
465
  }
466
+ }
467
 
468
  $tooltip_text = isset( $args['tooltip_text'] ) ? $args['label'] : $this->default_tooltip_text();
469
  ?>
474
  </select>
475
 
476
  <?php if ( isset( $args['additional'] ) ) : ?>
477
+ <?php echo $args['additional']; ?>
478
+ <?php endif; ?>
479
 
480
  <?php if ( isset( $args['tooltip_info'] ) ) : ?>
481
  <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $tooltip_text; ?></a>
487
  $default = isset( $args['default'] ) ? $args['default'] : '';
488
  $value = isset( $this->settings[ $args['name'] ] ) ? stripslashes( $this->settings[ $args['name'] ] ) : $default;
489
 
490
+ if ( isset( $args['tooltip_info'] ) ) : ?>
491
  <span><?php echo $args['tooltip_info']; ?></span><br>
492
  <?php endif; ?>
493
 
494
  <textarea name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" id="<?php echo $this->option_name . '_' . $args['name']; ?>"rows="7"><?php echo $value; ?></textarea>
495
 
496
+ <?php if ( isset( $args['note'] ) ) : ?>
497
  <br><span class="sbspf_note"><?php echo $args['note']; ?></span>
498
  <?php endif;
499
  }
500
 
501
  public function color( $args ) {
502
+ $args['color'] = true;
503
+ $this->text( $args );
504
  }
505
 
506
  public function types( $args ) {
532
  </div>
533
  <?php if ( empty( $selected ) ) : ?>
534
  <p class="sbspf_no_accounts" style="margin-top: -3px; margin-right: 10px;"><?php _e( 'Connect an account above', $this->vars->text_domain() ); ?></p>
535
+ <?php endif; ?>
536
 
537
+ <?php endif; ?>
538
+ <?php if ( isset( $type['note'] ) ) : ?>
539
  <br><span class="sbspf_note"><?php echo $type['note']; ?></span>
540
+ <?php endif; ?>
541
  </div>
542
 
543
  <div class="sbspf_tooltip sbspf_type_tooltip sbspf_more_info">
550
  }
551
 
552
  public function cache( $args ) {
553
+ $social_network = $this->vars->social_network();
554
  $type_selected = isset( $this->settings['caching_type'] ) ? $this->settings['caching_type'] : 'page';
555
  $caching_time = isset( $this->settings['caching_time'] ) ? $this->settings['caching_time'] : 1;
556
  $cache_time_unit_selected = isset( $this->settings['cache_time_unit'] ) ? $this->settings['cache_time_unit'] : 'hours';
557
  $cache_cron_interval_selected = isset( $this->settings['cache_cron_interval'] ) ? $this->settings['cache_cron_interval'] : '';
558
  $cache_cron_time = isset( $this->settings['cache_cron_time'] ) ? $this->settings['cache_cron_time'] : '';
559
  $cache_cron_am_pm = isset( $this->settings['cache_cron_am_pm'] ) ? $this->settings['cache_cron_am_pm'] : '';
560
+
561
  ?>
562
  <div class="sbspf_cache_settings_wrap">
563
+ <div class="sbspf_row">
564
+ <input type="radio" name="<?php echo $this->option_name.'[caching_type]'; ?>" class="sbspf_caching_type_input" id="sbspf_caching_type_page" value="page"<?php if ( $type_selected === 'page' ) echo ' checked'?>>
565
+ <label class="sbspf_radio_label" for="sbspf_caching_type_page"><?php _e ( 'When the page loads', $this->vars->text_domain() ); ?></label>
566
+ <a class="sbspf_tooltip_link sbspf_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 2px;"><?php echo $this->default_tooltip_text() ?></a>
567
+ <p class="sbspf_tooltip sbspf_more_info"><?php echo sprintf( __( "Your %s data is temporarily cached by the plugin in your WordPress database. There are two ways that you can set the plugin to check for new data:<br><br>
568
+ <b>1. When the page loads</b><br>Selecting this option means that when the cache expires then the plugin will check %s for new posts the next time that the feed is loaded. You can choose how long this data should be cached for with a minimum time of 15 minutes. If you set the time to 60 minutes then the plugin will clear the cached data after that length of time, and the next time the page is viewed it will check for new data. <b>Tip:</b> If you're experiencing an issue with the plugin not updating automatically then try enabling the setting labeled <b>'Force cache to clear on interval'</b> which is located on the 'Customize' tab.<br><br>
569
  <b>2. In the background</b><br>Selecting this option means that the plugin will check for new data in the background so that the feed is updated behind the scenes. You can select at what time and how often the plugin should check for new data using the settings below. <b>Please note</b> that the plugin will initially check for data from Instagram when the page first loads, but then after that will check in the background on the schedule selected - unless the cache is cleared.", $this->vars->text_domain() ), $social_network, $social_network ); ?>
570
+ </p>
571
+ </div>
572
+ <div class="sbspf_row sbspf-caching-page-options" style="display: none;">
573
+ <?php _e ( 'Every', $this->vars->text_domain() ); ?>:
574
+ <input name="<?php echo $this->option_name.'[caching_time]'; ?>" type="text" value="<?php echo esc_attr( $caching_time ); ?>" size="4">
575
+ <select name="<?php echo $this->option_name.'[caching_time_unit]'; ?>">
576
+ <option value="minutes"<?php if ( $cache_time_unit_selected === 'minutes' ) echo ' selected'?>><?php _e ( 'Minutes', $this->vars->text_domain() ); ?></option>
577
+ <option value="hours"<?php if ( $cache_time_unit_selected === 'hours' ) echo ' selected'?>><?php _e ( 'Hours', $this->vars->text_domain() ); ?></option>
578
+ <option value="days"<?php if ( $cache_time_unit_selected === 'days' ) echo ' selected'?>><?php _e ( 'Days', $this->vars->text_domain() ); ?></option>
579
+ </select>
580
+ <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php _e ( 'What does this mean?', $this->vars->text_domain() ); ?></a>
581
+ <p class="sbspf_tooltip sbspf_more_info"><?php echo sprintf( __("Your %s posts are temporarily cached by the plugin in your WordPress database. You can choose how long the posts should be cached for. If you set the time to 1 hour then the plugin will clear the cache after that length of time and check %s for posts again.", $this->vars->text_domain() ), $social_network, $social_network ); ?></p>
582
+ </div>
 
 
 
 
 
 
583
 
584
+ <div class="sbspf_row">
585
+ <input type="radio" name="<?php echo $this->option_name.'[caching_type]'; ?>" id="sbspf_caching_type_cron" class="sbspf_caching_type_input" value="background" <?php if ( $type_selected === 'background' ) echo ' checked'?>>
586
+ <label class="sbspf_radio_label" for="sbspf_caching_type_cron"><?php _e ( 'In the background', $this->vars->text_domain() ); ?></label>
587
+ </div>
588
+ <div class="sbspf_row sbspf-caching-cron-options" style="display: block;">
 
589
 
590
+ <select name="<?php echo $this->option_name.'[cache_cron_interval]'; ?>" id="sbspf_cache_cron_interval">
591
+ <option value="30mins"<?php if ( $cache_cron_interval_selected === '30mins' ) echo ' selected'?>><?php _e ( 'Every 30 minutes', $this->vars->text_domain() ); ?></option>
592
+ <option value="1hour"<?php if ( $cache_cron_interval_selected === '1hour' ) echo ' selected'?>><?php _e ( 'Every hour', $this->vars->text_domain() ); ?></option>
593
+ <option value="12hours"<?php if ( $cache_cron_interval_selected === '12hours' ) echo ' selected'?>><?php _e ( 'Every 12 hours', $this->vars->text_domain() ); ?></option>
594
+ <option value="24hours"<?php if ( $cache_cron_interval_selected === '24hours' ) echo ' selected'?>><?php _e ( 'Every 24 hours', $this->vars->text_domain() ); ?></option>
 
 
 
 
 
 
 
 
 
 
595
  </select>
596
 
597
+ <div id="sbspf-caching-time-settings" style="">
598
+ <?php _e ( 'at', $this->vars->text_domain() ); ?>
599
+ <select name="<?php echo $this->option_name.'[cache_cron_time]'; ?>" style="width: 80px">
600
+ <option value="1"<?php if ( (int)$cache_cron_time === 1 ) echo ' selected'?>>1:00</option>
601
+ <option value="2"<?php if ( (int)$cache_cron_time === 2 ) echo ' selected'?>>2:00</option>
602
+ <option value="3"<?php if ( (int)$cache_cron_time === 3 ) echo ' selected'?>>3:00</option>
603
+ <option value="4"<?php if ( (int)$cache_cron_time === 4 ) echo ' selected'?>>4:00</option>
604
+ <option value="5"<?php if ( (int)$cache_cron_time === 5 ) echo ' selected'?>>5:00</option>
605
+ <option value="6"<?php if ( (int)$cache_cron_time === 6 ) echo ' selected'?>>6:00</option>
606
+ <option value="7"<?php if ( (int)$cache_cron_time === 7 ) echo ' selected'?>>7:00</option>
607
+ <option value="8"<?php if ( (int)$cache_cron_time === 8 ) echo ' selected'?>>8:00</option>
608
+ <option value="9"<?php if ( (int)$cache_cron_time === 9 ) echo ' selected'?>>9:00</option>
609
+ <option value="10"<?php if ( (int)$cache_cron_time === 10 ) echo ' selected'?>>10:00</option>
610
+ <option value="11"<?php if ( (int)$cache_cron_time === 11 ) echo ' selected'?>>11:00</option>
611
+ <option value="0"<?php if ( (int)$cache_cron_time === 0 ) echo ' selected'?>>12:00</option>
612
+ </select>
613
+
614
+ <select name="<?php echo $this->option_name.'[cache_cron_am_pm]'; ?>" style="width: 50px">
615
+ <option value="am"<?php if ( $cache_cron_am_pm === 'am' ) echo ' selected'?>><?php _e ( 'AM', $this->vars->text_domain() ); ?></option>
616
+ <option value="pm"<?php if ( $cache_cron_am_pm === 'pm' ) echo ' selected'?>><?php _e ( 'PM', $this->vars->text_domain() ); ?></option>
617
+ </select>
618
+ </div>
619
 
620
+ <?php
621
+ if ( wp_next_scheduled( 'sbspf_feed_update' ) ) {
622
+ $time_format = get_option( 'time_format' );
623
+ if ( ! $time_format ) {
624
+ $time_format = 'g:i a';
625
+ }
626
+ //
627
+ $schedule = wp_get_schedule( 'sbspf_feed_update' );
628
+ if ( $schedule == '30mins' ) $schedule = __( 'every 30 minutes', $this->vars->text_domain() );
629
+ if ( $schedule == 'twicedaily' ) $schedule = __( 'every 12 hours', $this->vars->text_domain() );
630
+ $sbspf_next_cron_event = wp_next_scheduled( 'sbspf_feed_update' );
631
+ echo '<p class="sbspf-caching-sched-notice"><span><b>' . __( 'Next check', $this->vars->text_domain() ) . ': ' . date( $time_format, $sbspf_next_cron_event + sbspf_get_utc_offset() ) . ' (' . $schedule . ')</b> - ' . __( 'Note: Saving the settings on this page will clear the cache and reset this schedule', $this->vars->text_domain() ) . '</span></p>';
632
+ } else {
633
+ echo '<p style="font-size: 11px; color: #666;">' . __( 'Nothing currently scheduled', $this->vars->text_domain() ) . '</p>';
634
+ }
635
+ ?>
636
+ </div>
637
  </div>
638
+ <?php
639
  }
640
 
641
  public function layout( $args ) {
643
  $value = isset( $this->settings[ $args['name'] ] ) ? $this->settings[ $args['name'] ] : $default;
644
  ?>
645
  <div class="sbspf_layouts">
646
+ <?php foreach ( $args['layouts'] as $layout ) : ?>
647
  <div class="sbspf_layout_cell">
648
  <input class="sbspf_layout_type" id="sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>" name="<?php echo $this->option_name.'['.$args['name'].']'; ?>" type="radio" value="<?php echo esc_attr( $layout['slug'] ); ?>"<?php if ( $layout['slug'] === $value ) echo ' checked'?>><label for="sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>"><span class="sbspf_label"><?php echo $layout['label']; ?></span><img src="<?php echo esc_url( $this->vars->plugin_url() . $layout['image'] ); ?>"></label>
649
  </div>
650
+ <?php endforeach; ?>
651
 
652
  <div class="sbspf_layout_options_wrap">
653
+ <?php foreach ( $args['layouts'] as $layout ) : ?>
654
+ <div class="sbspf_layout_settings sbspf_layout_type_<?php echo esc_attr( $layout['slug'] ); ?>">
655
 
656
+ <div class="sbspf_layout_setting">
657
+ <?php echo sby_admin_icon( 'info-circle' ); ?>&nbsp;&nbsp;&nbsp;<span class="sbspf_note" style="margin-left: 0;"><?php echo $layout['note']; ?></span>
658
+ </div>
659
+ <?php if ( ! empty( $layout['options'] ) ) : ?>
660
+ <div class="sbspf_layout_setting">
661
+ <?php foreach ( $layout['options'] as $option ) :
662
+ $option['name'] = $layout['slug'].$option['name'];
663
+ ?>
664
+ <div class="ctf_layout_setting">
665
+
666
+ <label title="<?php echo __( 'Click for shortcode option', $this->vars->text_domain() ); ?>"><?php echo $option['label']; ?></label><code class="sbspf_shortcode"> <?php echo $option['name'] . "\n"; ?>
667
+ Eg: <?php echo $option['name']; ?>=<?php echo $option['shortcode_example']; ?></code><br>
668
+ <?php call_user_func_array( array( $this, $option['callback'] ), array( $option ) ); ?>
669
 
670
+ </div>
 
 
671
 
672
+ <?php endforeach; ?>
673
  </div>
674
+ <?php endif; ?>
675
 
 
676
  </div>
 
677
 
678
+ <?php endforeach; ?>
 
 
679
  </div>
680
  </div>
681
+ <?php
682
+ }
683
+
684
+ public function format_title( $label, $name, $shortcode_args = false, $after = '' ) {
685
+ $formatted_label = '<label for="' . $this->option_name . '_' . $name . '">' . $label .'</label>';
686
+ if ( $shortcode_args ) {
687
+ $formatted_label .= '<code class="sbspf_shortcode"> ' . $shortcode_args['key'] . "\n";
688
+ $formatted_label .= 'Eg: ' . $shortcode_args['key'] . '=' . $shortcode_args['example'] . '</code><br>';
689
+ }
690
+ $formatted_label .= $after;
691
+
692
+ return $formatted_label;
693
+ }
694
 
695
  public function validate_options( $input, $tab ) {
696
  $updated_options = get_option( $this->option_name, array() );
699
 
700
  foreach ( $false_if_empty_keys as $false_key ) {
701
  $updated_options[ $false_key ] = false;
702
+ }
703
 
704
  foreach ( $input as $key => $val ) {
705
+ if ( in_array( $key, $false_if_empty_keys ) ) {
706
+ $updated_options[ $key ] = ($val === 'on');
707
+ } elseif ( in_array( $key, $textarea_keys ) ) {
708
+ $updated_options[ $key ] = sanitize_textarea_field( $val );
709
+ } elseif ( is_array( $val ) ) {
710
+ foreach ( $val as $key2 => $val2 ) {
711
+ $updated_options[ $key ][ $key2 ] = sanitize_text_field( $val2 );
712
+ }
713
+ } else {
714
+ $updated_options[ $key ] = sanitize_text_field( $val );
715
+ }
716
+ }
717
 
718
  if ( $tab === 'configure' ) {
719
+ do_action( $this->option_name . '_after_configure_save', $updated_options );
720
+ }
721
 
722
  return $updated_options;
723
  }
726
  public function update_options( $new_settings ) {
727
  update_option( $this->get_option_name(), $new_settings );
728
  $this->settings = $new_settings;
729
+ }
730
 
731
  public function get_sections( $tab ) {
732
  if ( isset( $this->settings_sections[ $tab ] ) ) {
844
  }
845
 
846
  public function default_tooltip_text() {
847
+ return '<span class="screen-reader-text">' . __( 'What does this mean?', $this->vars->text_domain() ) . '</span>' . sby_admin_icon( 'question-circle' );
848
+ }
849
  }
inc/admin/class-sby-admin.php CHANGED
@@ -314,7 +314,7 @@ class SBY_Admin extends SB_YOUTUBE_Admin {
314
  'value' => 'none'
315
  )
316
  );
317
- $additional = '<input id="sby-clear-cache" class="button-secondary sbspf-button-action" data-sby-action="sby_delete_wp_posts" data-sby-confirm="'.esc_attr( 'This will permanently delete all YouTube posts from the wp_posts table and the related data in the postmeta table. Continue?', $text_domain ).'" style="margin-top: 1px;" type="submit" value="'.esc_attr( 'Clear YouTube Posts', $text_domain ).'">';
318
  $args = array(
319
  'name' => 'storage_process',
320
  'default' => '',
@@ -323,7 +323,7 @@ class SBY_Admin extends SB_YOUTUBE_Admin {
323
  'title' => __( 'Local storage process', $text_domain ),
324
  'options' => $select_options,
325
  'additional' => $additional,
326
- 'tooltip_info' => __( 'To preserve your feeds and videos even if the YouTube API is unavailable, a record of each video is added to the wp_posts table in the WordPress database.', $text_domain )
327
  );
328
  $this->add_settings_field( $args );
329
 
@@ -346,15 +346,6 @@ class SBY_Admin extends SB_YOUTUBE_Admin {
346
  $cache_cron_interval_selected = isset( $this->settings['cache_cron_interval'] ) ? $this->settings['cache_cron_interval'] : '';
347
  $cache_cron_time = isset( $this->settings['cache_cron_time'] ) ? $this->settings['cache_cron_time'] : '';
348
  $cache_cron_am_pm = isset( $this->settings['cache_cron_am_pm'] ) ? $this->settings['cache_cron_am_pm'] : '';
349
-
350
- if ( $cache_time_unit_selected === 'minutes' ) {
351
- $cache_time_unit_selected = 'hours';
352
- $caching_time = 1;
353
- }
354
- if ( $cache_cron_interval_selected === '30mins' ) {
355
- $cache_cron_interval_selected = '1hour';
356
- }
357
-
358
  ?>
359
  <div class="sbspf_cache_settings_wrap">
360
  <div class="sbspf_row">
@@ -370,7 +361,8 @@ class SBY_Admin extends SB_YOUTUBE_Admin {
370
  <?php _e ( 'Every', $this->vars->text_domain() ); ?>:
371
  <input name="<?php echo $this->option_name.'[caching_time]'; ?>" type="text" value="<?php echo esc_attr( $caching_time ); ?>" size="4">
372
  <select name="<?php echo $this->option_name.'[caching_time_unit]'; ?>">
373
- <option value="hours"<?php if ( $cache_time_unit_selected === 'hours' ) echo ' selected'?>><?php _e ( 'Hours', $this->vars->text_domain() ); ?></option>
 
374
  <option value="days"<?php if ( $cache_time_unit_selected === 'days' ) echo ' selected'?>><?php _e ( 'Days', $this->vars->text_domain() ); ?></option>
375
  </select>
376
  <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php _e ( 'What does this mean?', $this->vars->text_domain() ); ?></a>
@@ -384,7 +376,8 @@ class SBY_Admin extends SB_YOUTUBE_Admin {
384
  <div class="sbspf_row sbspf-caching-cron-options" style="display: block;">
385
 
386
  <select name="<?php echo $this->option_name.'[cache_cron_interval]'; ?>" id="sbspf_cache_cron_interval">
387
- <option value="1hour"<?php if ( $cache_cron_interval_selected === '1hour' ) echo ' selected'?>><?php _e ( 'Every hour', $this->vars->text_domain() ); ?></option>
 
388
  <option value="12hours"<?php if ( $cache_cron_interval_selected === '12hours' ) echo ' selected'?>><?php _e ( 'Every 12 hours', $this->vars->text_domain() ); ?></option>
389
  <option value="24hours"<?php if ( $cache_cron_interval_selected === '24hours' ) echo ' selected'?>><?php _e ( 'Every 24 hours', $this->vars->text_domain() ); ?></option>
390
  </select>
314
  'value' => 'none'
315
  )
316
  );
317
+ $additional = '<input id="sby-clear-cache" class="button-secondary sbspf-button-action" data-sby-action="sby_delete_wp_posts" data-sby-confirm="'.esc_attr( 'This will permanently delete all YouTube posts from the wp_posts table and the related data in the postmeta table. Existing feeds will only have 15 or fewer videos available initially. Continue?', $text_domain ).'" style="margin-top: 1px;" type="submit" value="'.esc_attr( 'Clear YouTube Posts', $text_domain ).'">';
318
  $args = array(
319
  'name' => 'storage_process',
320
  'default' => '',
323
  'title' => __( 'Local storage process', $text_domain ),
324
  'options' => $select_options,
325
  'additional' => $additional,
326
+ 'tooltip_info' => __( 'To preserve your feeds and videos even if the YouTube API is unavailable, a record of each video is added to the wp_posts table in the WordPress database. Please note that changing this setting to "none" will limit the number of posts available in the feed to 15 or less.', $text_domain )
327
  );
328
  $this->add_settings_field( $args );
329
 
346
  $cache_cron_interval_selected = isset( $this->settings['cache_cron_interval'] ) ? $this->settings['cache_cron_interval'] : '';
347
  $cache_cron_time = isset( $this->settings['cache_cron_time'] ) ? $this->settings['cache_cron_time'] : '';
348
  $cache_cron_am_pm = isset( $this->settings['cache_cron_am_pm'] ) ? $this->settings['cache_cron_am_pm'] : '';
 
 
 
 
 
 
 
 
 
349
  ?>
350
  <div class="sbspf_cache_settings_wrap">
351
  <div class="sbspf_row">
361
  <?php _e ( 'Every', $this->vars->text_domain() ); ?>:
362
  <input name="<?php echo $this->option_name.'[caching_time]'; ?>" type="text" value="<?php echo esc_attr( $caching_time ); ?>" size="4">
363
  <select name="<?php echo $this->option_name.'[caching_time_unit]'; ?>">
364
+ <option value="minutes"<?php if ( $cache_time_unit_selected === 'minutes' ) echo ' selected'?>><?php _e ( 'Minutes', $this->vars->text_domain() ); ?></option>
365
+ <option value="hours"<?php if ( $cache_time_unit_selected === 'hours' ) echo ' selected'?>><?php _e ( 'Hours', $this->vars->text_domain() ); ?></option>
366
  <option value="days"<?php if ( $cache_time_unit_selected === 'days' ) echo ' selected'?>><?php _e ( 'Days', $this->vars->text_domain() ); ?></option>
367
  </select>
368
  <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php _e ( 'What does this mean?', $this->vars->text_domain() ); ?></a>
376
  <div class="sbspf_row sbspf-caching-cron-options" style="display: block;">
377
 
378
  <select name="<?php echo $this->option_name.'[cache_cron_interval]'; ?>" id="sbspf_cache_cron_interval">
379
+ <option value="30mins"<?php if ( $cache_cron_interval_selected === '30mins' ) echo ' selected'?>><?php _e ( 'Every 30 minutes', $this->vars->text_domain() ); ?></option>
380
+ <option value="1hour"<?php if ( $cache_cron_interval_selected === '1hour' ) echo ' selected'?>><?php _e ( 'Every hour', $this->vars->text_domain() ); ?></option>
381
  <option value="12hours"<?php if ( $cache_cron_interval_selected === '12hours' ) echo ' selected'?>><?php _e ( 'Every 12 hours', $this->vars->text_domain() ); ?></option>
382
  <option value="24hours"<?php if ( $cache_cron_interval_selected === '24hours' ) echo ' selected'?>><?php _e ( 'Every 24 hours', $this->vars->text_domain() ); ?></option>
383
  </select>
inc/admin/templates/configure.php CHANGED
@@ -1,5 +1,5 @@
1
  <h3><?php _e( 'Configure', $text_domain ); ?></h3>
2
- <div id="sbspf_config" style="display: none;">
3
  <a href="<?php echo $oauth_processor_url . admin_url( 'admin.php?page=' . esc_attr( $slug ) ); ?>" id="sbspf_get_token"><?php echo sby_icon( $slug, 'sbspf_small_svg' ); ?> <?php echo sprintf( __( 'Log in to %s and connect an account', $text_domain ), $social_network ); ?></a>
4
  <a class="sbspf_not_working" href="https://smashballoon.com/<?php echo esc_attr( $slug ); ?>/token/" target="_blank"><?php _e( "Button not working?", $text_domain ); ?></a>
5
  </div>
@@ -7,40 +7,32 @@
7
  <form method="post" action="">
8
  <?php
9
  $settings = $this->settings;
10
- //$have_own_tokens = isset( $settings['have_own_tokens'] ) ? $settings['have_own_tokens'] : 0;
11
- $have_own_tokens = 'on';
12
  $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
13
  ?>
14
- <input name="<?php echo $this->get_option_name(); ?>[have_own_tokens]" type="hidden" value="0">
15
-
16
- <input style="display: none;" name="<?php echo $this->get_option_name(); ?>[have_own_tokens]" id="sbspf_have_own_tokens" type="checkbox"<?php if ( $have_own_tokens === 'on' ) echo ' checked'; ?>><label for="sbspf_have_own_tokens" style="display: none;"><?php echo sprintf( __( "Or, manually enter my own %s API key", $text_domain ), $social_network ); ?></label>
17
- <span class="sbspf_tooltip_wrap" style="display: none;">
18
- <a class="sbspf_tooltip_link" href="JavaScript:void(0);"><?php echo $this->default_tooltip_text(); ?></a>
19
- <p class="sbspf_tooltip sbspf_more_info"><?php echo __( 'Check this box if you would like to manually enter your own API key. To generate an API key use <a href="https://smashballoon.com/youtube-api-key/" target="_blank" rel="noopener">these instructions.</a>', $text_domain ); ?></p>
20
- </span>
21
  <table class="form-table sbspf_own_credentials_wrap" role="presentation">
22
  <tbody>
23
  <tr>
24
  <th scope="row">
25
  <label for="sby_app_id"><?php _e( "API Key", $text_domain ); ?></label>
 
26
  </th>
27
  <td>
28
  <input name="<?php echo $this->get_option_name(); ?>[api_key]" id="sby_api_key" type="text" value="<?php echo esc_attr( $api_key ); ?>" size="64" minlength="15" maxlength="200" />
29
- <p><?php echo __( 'Get started by entering your own YouTube API key. To generate an API key use <a href="https://smashballoon.com/youtube-api-key/" target="_blank" rel="noopener">these instructions.</a>', $text_domain ); ?></p>
30
  </td>
31
  </tr>
32
 
33
  </tbody>
34
  </table>
35
- <?php $this->hidden_fields_for_tab( 'configure' ); ?>
36
- <?php //include_once $this->get_path( 'connected-accounts' ); ?>
37
 
38
- <?php foreach ( $this->get_sections( 'configure' ) as $section ) : ?>
39
 
40
- <?php do_settings_sections( $section['id'] ); // matches the section name ?>
41
- <?php if ( $section['save_after'] ) : ?>
42
  <p class="submit"><input class="button-primary" type="submit" name="save" value="<?php esc_attr_e( 'Save Changes' ); ?>" /></p>
43
- <?php endif; ?>
44
  <hr>
45
- <?php endforeach; ?>
46
  </form>
1
  <h3><?php _e( 'Configure', $text_domain ); ?></h3>
2
+ <div id="sbspf_config">
3
  <a href="<?php echo $oauth_processor_url . admin_url( 'admin.php?page=' . esc_attr( $slug ) ); ?>" id="sbspf_get_token"><?php echo sby_icon( $slug, 'sbspf_small_svg' ); ?> <?php echo sprintf( __( 'Log in to %s and connect an account', $text_domain ), $social_network ); ?></a>
4
  <a class="sbspf_not_working" href="https://smashballoon.com/<?php echo esc_attr( $slug ); ?>/token/" target="_blank"><?php _e( "Button not working?", $text_domain ); ?></a>
5
  </div>
7
  <form method="post" action="">
8
  <?php
9
  $settings = $this->settings;
 
 
10
  $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
11
  ?>
 
 
 
 
 
 
 
12
  <table class="form-table sbspf_own_credentials_wrap" role="presentation">
13
  <tbody>
14
  <tr>
15
  <th scope="row">
16
  <label for="sby_app_id"><?php _e( "API Key", $text_domain ); ?></label>
17
+ <p class="sbspf_aside sbspf_red"><?php _e( "Recommended", $text_domain ); ?></p>
18
  </th>
19
  <td>
20
  <input name="<?php echo $this->get_option_name(); ?>[api_key]" id="sby_api_key" type="text" value="<?php echo esc_attr( $api_key ); ?>" size="64" minlength="15" maxlength="200" />
21
+ <p class="sbspf_aside"><?php echo __( 'Entering an API key is <strong>optional</strong> but recommended. It allows the plugin to fetch older videos and prevents potential disruption in your feed. It only takes a few minutes: <a href="https://smashballoon.com/youtube-api-key/" target="_blank" rel="noopener">Get my API key.</a>', $text_domain ); ?></p>
22
  </td>
23
  </tr>
24
 
25
  </tbody>
26
  </table>
27
+ <?php $this->hidden_fields_for_tab( 'configure' ); ?>
28
+ <?php include_once $this->get_path( 'connected-accounts' ); ?>
29
 
30
+ <?php foreach ( $this->get_sections( 'configure' ) as $section ) : ?>
31
 
32
+ <?php do_settings_sections( $section['id'] ); // matches the section name ?>
33
+ <?php if ( $section['save_after'] ) : ?>
34
  <p class="submit"><input class="button-primary" type="submit" name="save" value="<?php esc_attr_e( 'Save Changes' ); ?>" /></p>
35
+ <?php endif; ?>
36
  <hr>
37
+ <?php endforeach; ?>
38
  </form>
inc/admin/templates/connected-accounts.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  $connected_accounts = $this->get_connected_accounts();
3
  $connected_channels = array();
 
4
  ?>
5
  <table class="form-table sbspf_connected-accounts-wrap" role="presentation">
6
  <tbody>
@@ -39,4 +40,5 @@ $connected_channels = array();
39
  </td>
40
  </tr>
41
  </tbody>
42
- </table>
 
1
  <?php
2
  $connected_accounts = $this->get_connected_accounts();
3
  $connected_channels = array();
4
+ if ( ! empty( $connected_accounts ) ) :
5
  ?>
6
  <table class="form-table sbspf_connected-accounts-wrap" role="presentation">
7
  <tbody>
40
  </td>
41
  </tr>
42
  </tbody>
43
+ </table>
44
+ <?php endif; ?>
inc/class-sby-api-connect.php CHANGED
@@ -18,6 +18,8 @@ class SBY_API_Connect
18
  public function __construct( $connected_account_or_url, $endpoint = '', $params = array() ) {
19
  if ( is_array( $connected_account_or_url ) && isset( $connected_account_or_url['access_token'] ) ) {
20
  $this->set_url( $connected_account_or_url, $endpoint, $params );
 
 
21
  } elseif ( strpos( $connected_account_or_url, 'https' ) !== false ) {
22
  $this->url = $connected_account_or_url;
23
  } else {
@@ -130,7 +132,7 @@ class SBY_API_Connect
130
  }
131
 
132
  protected function set_url( $connected_account, $endpoint_slug, $params ) {
133
- $num = ! empty( $params['num'] ) ? (int)$params['num'] : 50;
134
 
135
  if ( $endpoint_slug === 'tokeninfo' ) {
136
  $url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' . $connected_account['access_token'];
@@ -141,17 +143,18 @@ class SBY_API_Connect
141
  } elseif ( isset( $params['channel_id'] ) ) {
142
  $channel_param = 'id=' . $params['channel_id'];
143
  }
144
- $next_page = '';
145
- if ( isset( $params['nextPageToken'] ) ) {
146
- $next_page = 'pageToken=' . $params['nextPageToken'];
147
- }
148
  $access_credentials = isset( $connected_account['api_key'] ) ? 'key=' . $connected_account['api_key'] : 'access_token=' . $connected_account['access_token'];
149
 
150
- $url = 'https://www.googleapis.com/youtube/v3/channels?part=id,snippet,contentDetails&'.$channel_param.'&' . $access_credentials . $next_page;
151
  } elseif ( $endpoint_slug === 'playlistItems' ) {
152
  $access_credentials = isset( $connected_account['api_key'] ) ? 'key=' . $connected_account['api_key'] : 'access_token=' . $connected_account['access_token'];
 
 
 
 
153
 
154
- $url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet&maxResults='.$num.'&playlistId='.$params['playlist_id'].'&' . $access_credentials;
155
  } else {
156
  $channel_param = 'mine=true';
157
  if ( isset( $params['username'] ) ) {
18
  public function __construct( $connected_account_or_url, $endpoint = '', $params = array() ) {
19
  if ( is_array( $connected_account_or_url ) && isset( $connected_account_or_url['access_token'] ) ) {
20
  $this->set_url( $connected_account_or_url, $endpoint, $params );
21
+ } elseif ( is_array( $connected_account_or_url ) ) {
22
+ $this->set_url( $connected_account_or_url, $endpoint, $params );
23
  } elseif ( strpos( $connected_account_or_url, 'https' ) !== false ) {
24
  $this->url = $connected_account_or_url;
25
  } else {
132
  }
133
 
134
  protected function set_url( $connected_account, $endpoint_slug, $params ) {
135
+ $num = ! empty( $params['num'] ) && isset( $connected_account['api_key'] ) ? (int)$params['num'] : 50;
136
 
137
  if ( $endpoint_slug === 'tokeninfo' ) {
138
  $url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' . $connected_account['access_token'];
143
  } elseif ( isset( $params['channel_id'] ) ) {
144
  $channel_param = 'id=' . $params['channel_id'];
145
  }
146
+
 
 
 
147
  $access_credentials = isset( $connected_account['api_key'] ) ? 'key=' . $connected_account['api_key'] : 'access_token=' . $connected_account['access_token'];
148
 
149
+ $url = 'https://www.googleapis.com/youtube/v3/channels?part=id,snippet,contentDetails&'.$channel_param.'&' . $access_credentials;
150
  } elseif ( $endpoint_slug === 'playlistItems' ) {
151
  $access_credentials = isset( $connected_account['api_key'] ) ? 'key=' . $connected_account['api_key'] : 'access_token=' . $connected_account['access_token'];
152
+ $next_page = '';
153
+ if ( isset( $params['nextPageToken'] ) ) {
154
+ $next_page = '&pageToken=' . $params['nextPageToken'];
155
+ }
156
 
157
+ $url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet&maxResults='.$num.'&playlistId='.$params['playlist_id'].'&' . $access_credentials . $next_page;
158
  } else {
159
  $channel_param = 'mine=true';
160
  if ( isset( $params['username'] ) ) {
inc/class-sby-cron-update.php CHANGED
@@ -60,10 +60,12 @@ class SBY_Cron_Updater
60
  if ( ! $last_requested || $last_requested > (time() - 60*60*24*30) ) {
61
  $sby_settings_obj = new SBY_Settings( $atts, $database_settings );
62
 
63
- if ( empty( $settings['connected_accounts'] ) && empty( $database_settings['api_key'] ) ) {
64
  $report[ $feed_id ]['did_update'] = 'no - no connected account';
65
  } else {
66
- SBY_Cron_Updater::do_single_feed_cron_update( $sby_settings_obj, $feed_data, $atts );
 
 
67
 
68
  $report[ $feed_id ]['did_update'] = 'yes';
69
  }
@@ -85,6 +87,54 @@ class SBY_Cron_Updater
85
  update_option( 'sby_cron_report', $report, false );
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  /**
89
  * Update a single feed cache based on settings. Local image storing and
90
  * resizing is done in the background here as well unless this is the initial
@@ -199,9 +249,12 @@ class SBY_Cron_Updater
199
  }
200
 
201
  } else {
202
- wp_schedule_event( time(), 'hourly', 'sby_feed_update' );
 
 
 
 
203
  }
204
 
205
  }
206
-
207
  }
60
  if ( ! $last_requested || $last_requested > (time() - 60*60*24*30) ) {
61
  $sby_settings_obj = new SBY_Settings( $atts, $database_settings );
62
 
63
+ if ( empty( $database_settings['connected_accounts'] ) && empty( $database_settings['api_key'] ) ) {
64
  $report[ $feed_id ]['did_update'] = 'no - no connected account';
65
  } else {
66
+ if ( SBY_Cron_Updater::can_update( $sby_settings_obj, $feed_data, $atts, count( $feed_caches ) ) ) {
67
+ SBY_Cron_Updater::do_single_feed_cron_update( $sby_settings_obj, $feed_data, $atts );
68
+ }
69
 
70
  $report[ $feed_id ]['did_update'] = 'yes';
71
  }
87
  update_option( 'sby_cron_report', $report, false );
88
  }
89
 
90
+ public static function can_update( $sby_settings_obj, $feed_data, $atts ) {
91
+ $can_update_return = array(
92
+ 'can_update' => false,
93
+ 'reason' => '',
94
+ );
95
+
96
+ // if no one has visited the page in the last 2 days, don't update
97
+ if ( (int)$feed_data['last_requested'] < (time() - 60*60*24*2) ) {
98
+ $can_update_return['reason'] = 'no one viewing feed';
99
+ return $can_update_return;
100
+ }
101
+
102
+ // get what the person said frequency should be
103
+
104
+ // use that for the first 3 days
105
+
106
+ // get factor, if different use that
107
+
108
+ $last_five = array_slice( $feed_data['data'], 0, 5 );
109
+ $last_of_sample_index = count( $last_five ) - 1;
110
+ //'last_requested' => int 1576097737
111
+ //'last_retrieve' => int 1576114290
112
+
113
+ // get time of last post
114
+ $last_post_time = SBY_Parse::get_timestamp( $last_five[0] ) ;
115
+ // get time since last update
116
+ $time_since_last_post = time() - $last_post_time;
117
+ // get average time between last 5 posts.
118
+ $post_frequency = ($last_post_time - SBY_Parse::get_timestamp( $last_five[ $last_of_sample_index ] )) / $last_of_sample_index + 1;
119
+
120
+ $delay_factor = 0;
121
+
122
+ // how recently was the last video posted
123
+ $hours_since_last_post = $time_since_last_post/60/60;
124
+ $delay_factor += min( $hours_since_last_post/12, 3 );
125
+
126
+ // how often is the typical video posted
127
+ $normal_post_frequency = $post_frequency/60/60;
128
+ $delay_factor += min( $normal_post_frequency/12, 3 );
129
+
130
+ // Minimum 12 hours
131
+ // Maximum 1 week if still active
132
+ // stop updating and add notice if no new posts found by the plugin for a month
133
+ var_dump( $delay_factor, date( 'm-d-Y H:i', $last_post_time ), $time_since_last_post/60/60, $post_frequency/60/60);
134
+ die();
135
+ return $can_update_return;
136
+ }
137
+
138
  /**
139
  * Update a single feed cache based on settings. Local image storing and
140
  * resizing is done in the background here as well unless this is the initial
249
  }
250
 
251
  } else {
252
+ if ( $sby_cache_cron_interval === '30mins' ) {
253
+ wp_schedule_event( time(), 'sby30mins', 'sby_feed_update' );
254
+ } else {
255
+ wp_schedule_event( time(), 'hourly', 'sby_feed_update' );
256
+ }
257
  }
258
 
259
  }
 
260
  }
inc/class-sby-feed.php CHANGED
@@ -85,6 +85,8 @@ class SBY_Feed
85
 
86
  private $successful_video_api_request_made;
87
 
 
 
88
  /**
89
  * SBY_Feed constructor.
90
  *
@@ -116,6 +118,7 @@ class SBY_Feed
116
  // used for errors and the sby_debug report
117
  $this->report = array();
118
  $this->successful_video_api_request_made = false;
 
119
  }
120
 
121
  /**
@@ -175,6 +178,10 @@ class SBY_Feed
175
  }
176
 
177
  public function get_channel_cache( $channel ) {
 
 
 
 
178
  $maybe_cache = get_option( SBY_CHANNEL_CACHE_PREFIX . $channel );
179
  if ( $maybe_cache !== false ) {
180
  $maybe_cache = json_decode( $maybe_cache, true );
@@ -440,115 +447,240 @@ class SBY_Feed
440
  $term = $term_and_params['term'];
441
  $params = array_merge( $params, $term_and_params['params'] );
442
 
443
- $connected_account_for_term = $connected_accounts_for_feed[ $term ];
444
- $api_requests_delayed = $sby_posts_manager->are_current_api_request_delays( $connected_account_for_term['channel_id'] );
 
 
 
 
 
 
 
445
 
446
- if ( $connected_account_for_term['expires'] < time() + 5 ) {
447
- $new_token_data = SBY_API_Connect::refresh_token( sby_get_account_bottom(), $connected_account_for_term['refresh_token'], sby_get_account_top() );
448
 
449
- if ( isset( $new_token_data['access_token'] ) ) {
450
- $connected_account_for_term['access_token'] = $new_token_data['access_token'];
451
- $connected_accounts_for_feed[ $term ]['access_token'] = $new_token_data['access_token'];
452
- $connected_account_for_term['expires'] = $new_token_data['expires_in'] + time();
453
- $connected_accounts_for_feed[ $term ]['expires'] = $new_token_data['expires_in'] + time();
454
 
455
- sby_update_or_connect_account( $connected_account_for_term );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
 
457
- $this->add_report( 'refreshing access token for ' . $connected_account_for_term['channel_id'] );
458
- } else {
459
- $this->add_report( 'refresh failed for ' . $connected_account_for_term['channel_id'] );
460
  }
461
- }
 
 
462
 
463
- if ( ! $api_requests_delayed
464
- && (! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== false) ) {
465
 
466
- $existing_channel_cache = $this->get_channel_cache( $term );
467
 
468
- if ( $existing_channel_cache ) {
469
- $this->channels_data[ $term ] = $existing_channel_cache;
470
- }
471
 
472
- if ( empty( $this->channels_data[ $term ] ) ) {
473
- $channel_data = array();
474
- $api_connect_channels = new SBY_API_Connect( $connected_account_for_term, 'channels', $params );
 
 
475
 
476
- $this->add_report( 'api call made for ' . $term . ' - ' . $type );
 
 
 
 
 
477
 
478
- $api_connect_channels->connect();
479
- if ( ! $api_connect_channels->is_wp_error() && ! $api_connect_channels->is_youtube_error() ) {
480
- $channel_data = $api_connect_channels->get_data();
481
- $this->set_channel_cache( $term, $channel_data );
482
 
483
- } else {
484
- if ( ! $api_connect_channels->is_wp_error() ) {
485
- $return = SBY_API_Connect::handle_youtube_error( $api_connect_channels->get_data(), $connected_account_for_term );
486
- if ( $return && isset( $return['access_token'] ) ) {
487
- $connected_account_for_term['access_token'] = $return['access_token'];
488
- $connected_accounts_for_feed[ $term ]['access_token'] = $return['access_token'];
489
- $connected_account_for_term['expires'] = $return['expires_in'] + time();
490
- $connected_accounts_for_feed[ $term ]['expires'] = $return['expires_in'] + time();
491
-
492
- sby_update_or_connect_account( $connected_account_for_term );
493
- $this->add_report( 'refreshing access token for ' . $connected_account_for_term['channel_id'] );
494
-
495
- $sby_api_connect_channel = new SBY_API_Connect( $connected_account_for_term, 'channels', $params );
496
- $sby_api_connect_channel->connect();
497
- if ( ! $sby_api_connect_channel->is_youtube_error() ) {
498
- $channel_data = $sby_api_connect_channel->get_data();
499
- }
500
- } else {
501
- $this->add_report( 'error connecting to channel' );
502
- }
503
- } else {
504
- $api_connect_channels->handle_wp_remote_get_error( $api_connect_channels->get_data() );
505
- }
506
 
 
507
 
 
 
 
508
  }
509
- $this->channels_data[ $term ] = $channel_data;
510
  }
511
 
512
- $first_playlist = isset( $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['uploads'] ) ? $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['uploads'] : false;
513
- if ( $first_playlist ) {
514
 
515
- $params = array( 'playlist_id' => $first_playlist );
516
- if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
517
- $params['nextPageToken'] = $next_pages[ $term . '_' . $type ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  }
519
 
520
- $api_connect_playlist_items = new SBY_API_Connect( $connected_account_for_term, 'playlistItems', $params );
 
 
 
 
 
 
521
 
522
- $api_connect_playlist_items->connect();
523
- if ( ! $api_connect_playlist_items->is_wp_error() && ! $api_connect_playlist_items->is_youtube_error() ) {
524
  $one_successful_connection = true;
525
 
526
- $data = $api_connect_playlist_items->get_data();
527
 
528
- if ( isset( $data['items'][0] ) ) {
 
 
 
529
  $post_set = $this->filter_posts( $data, $settings );
530
 
531
  $this->successful_video_api_request_made = true;
532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  $new_post_sets[] = $post_set;
534
- }
535
 
536
- $next_page = $api_connect_playlist_items->get_next_page();
537
- if ( ! empty( $next_page ) ) {
538
- $next_pages[ $term . '_' . $type ] = $next_page;
539
- $next_page_found = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  } else {
541
- $next_pages[ $term . '_' . $type ] = false;
542
  }
543
- }
544
- } else {
545
- $this->add_report( 'no first playlist' );
546
- }
547
 
548
 
549
- $this->num_api_calls++;
 
 
 
 
 
550
 
551
- }
552
 
553
  }
554
  }
@@ -573,6 +705,53 @@ class SBY_Feed
573
  }
574
  }
575
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  /**
577
  * Connects to the YouTube API and records returned data. Will use channel data if already
578
  * set by the regular feed
@@ -588,16 +767,27 @@ class SBY_Feed
588
  public function set_remote_header_data( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) {
589
  $first_user = $this->get_first_user( $feed_types_and_terms );
590
  $this->header_data = false;
 
 
 
 
 
 
591
 
592
  if ( isset( $this->channels_data[ $first_user ] ) ) {
593
  $this->header_data = $this->channels_data[ $first_user ];
594
- } elseif ( isset( $connected_accounts_for_feed[ $first_user ] ) ) {
595
- $connection = new SBY_API_Connect( $connected_accounts_for_feed[ $first_user ], 'channels', array() );
596
 
597
  $connection->connect();
 
598
 
599
  if ( ! $connection->is_wp_error() && ! $connection->is_youtube_error() ) {
600
  $this->header_data = $connection->get_data();
 
 
 
 
601
 
602
  if ( isset( $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) && $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) {
603
  $upload = wp_upload_dir();
@@ -740,6 +930,24 @@ class SBY_Feed
740
  return false;
741
  }
742
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  /**
744
  * Generates the HTML for the feed if post data is available. Although it seems
745
  * some of the variables ar not used they are set here to hide where they
@@ -845,6 +1053,11 @@ class SBY_Feed
845
  $flags[] = 'debug';
846
  }
847
 
 
 
 
 
 
848
  if ( ! empty( $flags ) ) {
849
  $other_atts .= ' data-sby-flags="' . implode(',', $flags ) . '"';
850
  }
@@ -958,6 +1171,14 @@ class SBY_Feed
958
  }
959
  }
960
 
 
 
 
 
 
 
 
 
961
  /**
962
  * Adds recorded strings to an array
963
  *
@@ -1017,7 +1238,7 @@ class SBY_Feed
1017
  $removed = array();
1018
 
1019
  foreach ( $posts as $post ) {
1020
- $post_id = SBY_Parse::get_post_id( $post );
1021
  if ( ! in_array( $post_id, $ids_in_feed, true ) ) {
1022
  $ids_in_feed[] = $post_id;
1023
  $non_duplicate_posts[] = $post;
85
 
86
  private $successful_video_api_request_made;
87
 
88
+ private $do_page_cache_all;
89
+
90
  /**
91
  * SBY_Feed constructor.
92
  *
118
  // used for errors and the sby_debug report
119
  $this->report = array();
120
  $this->successful_video_api_request_made = false;
121
+ $this->do_page_cache_all = false;
122
  }
123
 
124
  /**
178
  }
179
 
180
  public function get_channel_cache( $channel ) {
181
+ if ( $this->is_pageable() ) {
182
+ return false;
183
+ }
184
+
185
  $maybe_cache = get_option( SBY_CHANNEL_CACHE_PREFIX . $channel );
186
  if ( $maybe_cache !== false ) {
187
  $maybe_cache = json_decode( $maybe_cache, true );
447
  $term = $term_and_params['term'];
448
  $params = array_merge( $params, $term_and_params['params'] );
449
 
450
+ if ( ! $this->is_pageable()
451
+ && isset( $params['channel_id'] )
452
+ && (! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== 'rss') ) {
453
+ $rss_connect_playlist_items = new SBY_RSS_Connect( 'playlistItems', $params );
454
+ $this->add_report( 'RSS call made for ' . $term );
455
+
456
+ $rss_connect_playlist_items->connect();
457
+
458
+ $one_successful_connection = true;
459
 
460
+ $data = $rss_connect_playlist_items->get_data();
 
461
 
462
+ if ( isset( $data[0] ) ) {
463
+ $data = array(
464
+ 'items' => $data
465
+ );
466
+ $post_set = $this->filter_posts( $data, $settings );
467
 
468
+ $this->successful_video_api_request_made = true;
469
+
470
+ if ( count( $post_set ) > 14 ) {
471
+ if ( (int)self::get_channel_status( $term ) !== 1 ) {
472
+ $next_pages[ $term . '_' . $type ] = 'rss';
473
+ $next_page_found = true;
474
+ } else {
475
+ $this->add_report( 'RSS update only for ' . $term );
476
+ $post_set = $this->merge_cached_posts( $post_set, $term );
477
+ $next_pages[ $term . '_' . $type ] = false;
478
+ }
479
+ } else {
480
+ $next_pages[ $term . '_' . $type ] = false;
481
+ }
482
+
483
+ $new_post_sets[] = $post_set;
484
 
 
 
 
485
  }
486
+ } elseif ( isset( $connected_account_for_term['rss_only'] ) ) {
487
+ $rss_connect_playlist_items = new SBY_RSS_Connect( 'playlistItems', $params );
488
+ $this->add_report( 'RSS Only call made for ' . $term );
489
 
490
+ $rss_connect_playlist_items->connect();
 
491
 
492
+ $one_successful_connection = true;
493
 
494
+ $data = $rss_connect_playlist_items->get_data();
495
+ $next_pages[ $term . '_' . $type ] = false;
 
496
 
497
+ if ( isset( $data[0] ) ) {
498
+ $data = array(
499
+ 'items' => $data
500
+ );
501
+ $post_set = $this->filter_posts( $data, $settings );
502
 
503
+ $this->successful_video_api_request_made = true;
504
+ $new_post_sets[] = $post_set;
505
+ }
506
+ } else {
507
+ $connected_account_for_term = $connected_accounts_for_feed[ $term ];
508
+ $api_requests_delayed = $sby_posts_manager->are_current_api_request_delays( $connected_account_for_term['channel_id'] );
509
 
510
+ if ( $connected_account_for_term['expires'] < time() + 5 ) {
511
+ $new_token_data = SBY_API_Connect::refresh_token( sby_get_account_bottom(), $connected_account_for_term['refresh_token'], sby_get_account_top() );
 
 
512
 
513
+ if ( isset( $new_token_data['access_token'] ) ) {
514
+ $connected_account_for_term['access_token'] = $new_token_data['access_token'];
515
+ $connected_accounts_for_feed[ $term ]['access_token'] = $new_token_data['access_token'];
516
+ $connected_account_for_term['expires'] = $new_token_data['expires_in'] + time();
517
+ $connected_accounts_for_feed[ $term ]['expires'] = $new_token_data['expires_in'] + time();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
 
519
+ sby_update_or_connect_account( $connected_account_for_term );
520
 
521
+ $this->add_report( 'refreshing access token for ' . $connected_account_for_term['channel_id'] );
522
+ } else {
523
+ $this->add_report( 'refresh failed for ' . $connected_account_for_term['channel_id'] );
524
  }
 
525
  }
526
 
527
+ if ( ! $api_requests_delayed
528
+ && (! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== false) ) {
529
 
530
+ $existing_channel_cache = $this->get_channel_cache( $term );
531
+
532
+ if ( $existing_channel_cache ) {
533
+ $this->channels_data[ $term ] = $existing_channel_cache;
534
+ }
535
+
536
+ if ( empty( $this->channels_data[ $term ] ) ) {
537
+ $channel_data = array();
538
+ $api_connect_channels = new SBY_API_Connect( $connected_account_for_term, 'channels', $params );
539
+
540
+ $this->add_report( 'channel api call made for ' . $term . ' - ' . $type );
541
+
542
+ $api_connect_channels->connect();
543
+ if ( ! $api_connect_channels->is_wp_error() && ! $api_connect_channels->is_youtube_error() ) {
544
+ $channel_data = $api_connect_channels->get_data();
545
+ $channel_id = SBY_Parse::get_channel_id( $channel_data );
546
+ $this->set_channel_cache( $channel_id, $channel_data );
547
+
548
+ if ( isset( $params['channel_name'] ) ) {
549
+ sby_set_channel_id_from_channel_name( $params['channel_name'], $channel_id );
550
+ $this->set_channel_cache( $params['channel_name'], $channel_data );
551
+ }
552
+
553
+ $params = array( 'channel_id' => $channel_id );
554
+ $this->channels_data[ $channel_id ] = $channel_data;
555
+ $this->channels_data[ $term ] = $channel_data;
556
+ } else {
557
+ if ( ! $api_connect_channels->is_wp_error() ) {
558
+ $return = SBY_API_Connect::handle_youtube_error( $api_connect_channels->get_data(), $connected_account_for_term );
559
+ if ( $return && isset( $return['access_token'] ) ) {
560
+ $connected_account_for_term['access_token'] = $return['access_token'];
561
+ $connected_accounts_for_feed[ $term ]['access_token'] = $return['access_token'];
562
+ $connected_account_for_term['expires'] = $return['expires_in'] + time();
563
+ $connected_accounts_for_feed[ $term ]['expires'] = $return['expires_in'] + time();
564
+
565
+ sby_update_or_connect_account( $connected_account_for_term );
566
+ $this->add_report( 'refreshing access token for ' . $connected_account_for_term['channel_id'] );
567
+
568
+ $sby_api_connect_channel = new SBY_API_Connect( $connected_account_for_term, 'channels', $params );
569
+ $sby_api_connect_channel->connect();
570
+ if ( ! $sby_api_connect_channel->is_youtube_error() ) {
571
+ $channel_data = $sby_api_connect_channel->get_data();
572
+ $channel_id = SBY_Parse::get_channel_id( $channel_data );
573
+ $this->set_channel_cache( $channel_id, $channel_data );
574
+
575
+ if ( isset( $params['channel_name'] ) ) {
576
+ sby_set_channel_id_from_channel_name( $params['channel_name'], $channel_id );
577
+ $this->set_channel_cache( $params['channel_name'], $channel_data );
578
+ }
579
+
580
+ $params = array( 'channel_id' => $channel_id );
581
+ $this->channels_data[ $channel_id ] = $channel_data;
582
+ $this->channels_data[ $term ] = $channel_data;
583
+
584
+ }
585
+ } else {
586
+ $this->add_report( 'error connecting to channel' );
587
+ }
588
+ } else {
589
+ $api_connect_channels->handle_wp_remote_get_error( $api_connect_channels->get_data() );
590
+ }
591
+ }
592
  }
593
 
594
+ if ( ! $this->is_pageable()
595
+ && empty( $next_pages[ $term . '_' . $type ] ) ) {
596
+ $this->add_report( 'using RSS to get first 15' );
597
+
598
+ $rss_connect_playlist_items = new SBY_RSS_Connect( 'playlistItems', $params );
599
+
600
+ $rss_connect_playlist_items->connect();
601
 
 
 
602
  $one_successful_connection = true;
603
 
604
+ $data = $rss_connect_playlist_items->get_data();
605
 
606
+ if ( isset( $data[0] ) ) {
607
+ $data = array(
608
+ 'items' => $data
609
+ );
610
  $post_set = $this->filter_posts( $data, $settings );
611
 
612
  $this->successful_video_api_request_made = true;
613
 
614
+
615
+ if ( count( $post_set ) > 14 ) {
616
+ if ( (int)self::get_channel_status( $term ) !== 1 ) {
617
+ $next_pages[ $term . '_' . $type ] = 'rss';
618
+ $next_page_found = true;
619
+ } else {
620
+ $this->add_report( 'RSS Only' . $term );
621
+ $post_set = $this->merge_cached_posts( $post_set, $term );
622
+ $next_pages[ $term . '_' . $type ] = false;
623
+ }
624
+ } else {
625
+ $next_pages[ $term . '_' . $type ] = false;
626
+ }
627
+
628
  $new_post_sets[] = $post_set;
 
629
 
630
+ }
631
+ } else {
632
+ $first_playlist = isset( $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['uploads'] ) ? $this->channels_data[ $term ]['items'][0]['contentDetails']['relatedPlaylists']['uploads'] : false;
633
+ if ( $first_playlist ) {
634
+
635
+ $params = array( 'playlist_id' => $first_playlist );
636
+ if ( ! empty( $next_pages[ $term . '_' . $type ] ) && $next_pages[ $term . '_' . $type ] !== 'rss' ) {
637
+ $params['nextPageToken'] = $next_pages[ $term . '_' . $type ];
638
+ }
639
+
640
+ if ( isset( $next_pages[ $term . '_' . $type ] ) && $next_pages[ $term . '_' . $type ] === 'rss' ) {
641
+ self::update_channel_status( $term, 1 );
642
+ $this->do_page_cache_all = true;
643
+ $this->add_report( 'using API request to get first 50 videos' );
644
+ } else {
645
+ $this->add_report( 'using API request to get more videos' );
646
+ }
647
+
648
+ $api_connect_playlist_items = new SBY_API_Connect( $connected_account_for_term, 'playlistItems', $params );
649
+
650
+ $api_connect_playlist_items->connect();
651
+
652
+ if ( ! $api_connect_playlist_items->is_wp_error() && ! $api_connect_playlist_items->is_youtube_error() ) {
653
+ $one_successful_connection = true;
654
+ $data = $api_connect_playlist_items->get_data();
655
+
656
+ if ( isset( $data['items'][0] ) ) {
657
+ $post_set = $this->filter_posts( $data, $settings );
658
+
659
+ $this->successful_video_api_request_made = true;
660
+
661
+ $new_post_sets[] = $post_set;
662
+ }
663
+
664
+ $next_page = $this->is_pageable() ? $api_connect_playlist_items->get_next_page() : false;
665
+ if ( ! empty( $next_page ) ) {
666
+ $next_pages[ $term . '_' . $type ] = $next_page;
667
+ $next_page_found = true;
668
+ } else {
669
+ $next_pages[ $term . '_' . $type ] = false;
670
+ }
671
+ }
672
  } else {
673
+ $this->add_report( 'no first playlist' );
674
  }
 
 
 
 
675
 
676
 
677
+ $this->num_api_calls++;
678
+ }
679
+
680
+ }
681
+ }
682
+
683
 
 
684
 
685
  }
686
  }
705
  }
706
  }
707
 
708
+ private function is_pageable() {
709
+ global $sby_settings;
710
+
711
+ return ! empty( $sby_settings['api_key'] );
712
+ }
713
+
714
+ public function merge_cached_posts( $current_posts, $channel_id ) {
715
+ $args = array(
716
+ 'post_type' => SBY_CPT,
717
+ 'post_status' => array( 'publish', 'pending', 'draft' ),
718
+ 'orderby' => 'date',
719
+ 'order' => 'DESC',
720
+ 'posts_per_page' => 80,
721
+ 'meta_query' => array(
722
+ array(
723
+ 'value' => $channel_id,
724
+ 'key' => 'sby_channel_id'
725
+ )
726
+ )
727
+ );
728
+ $feed_videos = new WP_Query( $args );
729
+
730
+ if ( $feed_videos->have_posts() ) {
731
+ $posts = array();
732
+ while ( $feed_videos->have_posts() ) {
733
+ $feed_videos->the_post();
734
+ $json = get_post_meta( get_the_ID(), 'sby_json', true );
735
+
736
+ if ( $json ) {
737
+ $posts[] = json_decode( $json, true );
738
+ }
739
+ }
740
+
741
+ wp_reset_postdata();
742
+ $this->add_report( 'merging cached posts' );
743
+
744
+ $posts = array_merge( $current_posts, $posts );
745
+
746
+ return $posts;
747
+ } else {
748
+ $this->add_report( 'no cached posts found' );
749
+ wp_reset_postdata();
750
+
751
+ return $current_posts;
752
+ }
753
+ }
754
+
755
  /**
756
  * Connects to the YouTube API and records returned data. Will use channel data if already
757
  * set by the regular feed
767
  public function set_remote_header_data( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) {
768
  $first_user = $this->get_first_user( $feed_types_and_terms );
769
  $this->header_data = false;
770
+ $existing_channel_cache = $this->get_channel_cache( $first_user );
771
+
772
+ if ( $existing_channel_cache ) {
773
+ $this->channels_data[ $first_user ] = $existing_channel_cache;
774
+ $this->add_report( 'header data for ' . $first_user . ' exists in cache' );
775
+ }
776
 
777
  if ( isset( $this->channels_data[ $first_user ] ) ) {
778
  $this->header_data = $this->channels_data[ $first_user ];
779
+ } elseif ( isset( $feed_types_and_terms['channels'][0] ) ) {
780
+ $connection = new SBY_API_Connect( sby_get_first_connected_account(), 'channels', $feed_types_and_terms['channels'][0]['params'] );
781
 
782
  $connection->connect();
783
+ $this->add_report( 'api call made for header - ' . $first_user );
784
 
785
  if ( ! $connection->is_wp_error() && ! $connection->is_youtube_error() ) {
786
  $this->header_data = $connection->get_data();
787
+ $channel_id = SBY_Parse::get_channel_id( $this->header_data );
788
+ $this->set_channel_cache( $channel_id, $this->header_data );
789
+ $this->channels_data[ $channel_id ] = $this->header_data;
790
+ $this->channels_data[ $feed_types_and_terms['channels'][0]['term'] ] = $this->header_data;
791
 
792
  if ( isset( $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) && $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) {
793
  $upload = wp_upload_dir();
930
  return false;
931
  }
932
 
933
+ public static function get_channel_status( $channel ) {
934
+ $channel_setting = get_option( 'sby_channel_status', array() );
935
+
936
+ if ( isset( $channel_setting[ $channel ] ) ) {
937
+ return $channel_setting[ $channel ];
938
+ }
939
+
940
+ return 0;
941
+ }
942
+
943
+ public static function update_channel_status( $channel, $status ) {
944
+ $channel_setting = get_option( 'sby_channel_status', array() );
945
+
946
+ $channel_setting[ $channel ] = $status;
947
+
948
+ update_option( 'sby_channel_status', $channel_setting, false );
949
+ }
950
+
951
  /**
952
  * Generates the HTML for the feed if post data is available. Although it seems
953
  * some of the variables ar not used they are set here to hide where they
1053
  $flags[] = 'debug';
1054
  }
1055
 
1056
+ if ( $this->do_page_cache_all ) {
1057
+ $this->add_report( 'Adding videos to wp_posts ' . count( $this->post_data ) );
1058
+ $flags[] = 'cacheAll';
1059
+ }
1060
+
1061
  if ( ! empty( $flags ) ) {
1062
  $other_atts .= ' data-sby-flags="' . implode(',', $flags ) . '"';
1063
  }
1171
  }
1172
  }
1173
 
1174
+ public function do_page_cache_all() {
1175
+ return $this->do_page_cache_all;
1176
+ }
1177
+
1178
+ public function successful_video_api_request_made() {
1179
+ return $this->successful_video_api_request_made;
1180
+ }
1181
+
1182
  /**
1183
  * Adds recorded strings to an array
1184
  *
1238
  $removed = array();
1239
 
1240
  foreach ( $posts as $post ) {
1241
+ $post_id = SBY_Parse::get_video_id( $post );
1242
  if ( ! in_array( $post_id, $ids_in_feed, true ) ) {
1243
  $ids_in_feed[] = $post_id;
1244
  $non_duplicate_posts[] = $post;
inc/class-sby-parse.php CHANGED
@@ -14,7 +14,11 @@ class SBY_Parse
14
  * @since 1.0
15
  */
16
  public static function get_post_id( $post ) {
17
- return $post['id'];
 
 
 
 
18
  }
19
 
20
  public static function get_video_id( $post ) {
@@ -30,10 +34,9 @@ class SBY_Parse
30
  */
31
  public static function get_timestamp( $post ) {
32
  $timestamp = 0;
33
- // contentDetails->videoPublishedAt gives same result
34
  if ( isset( $post['snippet']['publishedAt'] ) ) {
35
- $remove_plus = trim( str_replace( array( 'T', '+', '.000Z' ), ' ', $post['snippet']['publishedAt'] ) );
36
- $timestamp = strtotime( $remove_plus );
37
  }
38
 
39
  return $timestamp;
14
  * @since 1.0
15
  */
16
  public static function get_post_id( $post ) {
17
+ if ( isset( $post['id'] ) ) {
18
+ return $post['id'];
19
+ } else {
20
+ return SBY_Parse::get_channel_id( $post ) . '_' . SBY_Parse::get_video_id( $post );
21
+ }
22
  }
23
 
24
  public static function get_video_id( $post ) {
34
  */
35
  public static function get_timestamp( $post ) {
36
  $timestamp = 0;
 
37
  if ( isset( $post['snippet']['publishedAt'] ) ) {
38
+ $remove_extra = str_replace( array( 'T', '+00:00', '.000Z', '+' ), ' ', $post['snippet']['publishedAt'] );
39
+ $timestamp = strtotime( $remove_extra );
40
  }
41
 
42
  return $timestamp;
inc/class-sby-rss-connect.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( '-1' );
4
+ }
5
+
6
+ class SBY_RSS_Connect
7
+ {
8
+ /**
9
+ * @var string
10
+ */
11
+ private $url;
12
+
13
+ /**
14
+ * @var object
15
+ */
16
+ private $response;
17
+
18
+ public function __construct( $endpoint = '', $params = array() ) {
19
+ $this->set_url( $endpoint, $params );
20
+ }
21
+
22
+ public function get_data() {
23
+ return $this->response;
24
+ }
25
+
26
+ public function set_url_from_args( $url ) {
27
+ $this->url = $url;
28
+ }
29
+
30
+ public function get_url() {
31
+ return $this->url;
32
+ }
33
+
34
+ public function connect() {
35
+ $parsed_obj = new SimpleXMLElement( $this->url, null, true );
36
+
37
+ $items_array = array();
38
+ if ( isset( $parsed_obj->entry ) ) {
39
+ foreach ( $parsed_obj->entry as $video_xml ) {
40
+
41
+ $this_item_array = array();
42
+
43
+ $high_thumbnail_url = (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->thumbnail->attributes()->url;
44
+
45
+ $this_item_array['snippet'] = array(
46
+ 'publishedAt' => (string) $video_xml->published,
47
+ 'channelId' => (string) $video_xml->children( 'http://www.youtube.com/xml/schemas/2015' )->channelId,
48
+ 'title' => (string) $video_xml->title,
49
+ 'description' => (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->description,
50
+ 'thumbnails' => array(
51
+ 'default' => array(
52
+ 'url' => (string) str_replace( 'hqdefault.jpg', 'default.jpg', $high_thumbnail_url ),
53
+ ),
54
+ 'medium' => array(
55
+ 'url' => str_replace( 'hqdefault.jpg', 'mqdefault.jpg', $high_thumbnail_url ),
56
+ ),
57
+ 'high' => array(
58
+ 'url' => $high_thumbnail_url,
59
+ 'width' => (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->thumbnail->attributes()->width,
60
+ 'height' => (string) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->thumbnail->attributes()->height,
61
+ ),
62
+ 'standard' => array(
63
+ 'url' => str_replace( 'hqdefault.jpg', 'sddefault.jpg', $high_thumbnail_url ),
64
+ ),
65
+ 'maxres' => array(
66
+ 'url' => str_replace( 'hqdefault.jpg', 'maxresdefault.jpg', $high_thumbnail_url ),
67
+ ),
68
+ ),
69
+ 'channelTitle' => (string) $video_xml->author->name,
70
+ 'resourceId' => array(
71
+ 'videoId' => (string) $video_xml->children( 'http://www.youtube.com/xml/schemas/2015' )->videoId
72
+ ),
73
+ );
74
+ $this_item_array['statistics'] = array(
75
+ 'viewCount' => (int) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->community->statistics->attributes()->views,
76
+ 'starRating' => (float) $video_xml->children( 'http://search.yahoo.com/mrss/' )->group->community->starRating->attributes()->average,
77
+ );
78
+ $items_array[] = $this_item_array;
79
+
80
+ }
81
+ }
82
+
83
+
84
+ $this->response = $items_array;
85
+
86
+ }
87
+
88
+ protected function set_url( $endpoint_slug, $params ) {
89
+ if ( $endpoint_slug === 'playlistItems' ) {
90
+ $url = 'https://www.youtube.com/feeds/videos.xml?channel_id=' . $params['channel_id'];
91
+ } else {
92
+ $url = 'https://www.youtube.com/feeds/videos.xml';
93
+ }
94
+
95
+ $this->set_url_from_args( $url );
96
+ }
97
+
98
+
99
+ }
inc/class-sby-settings.php CHANGED
@@ -64,7 +64,7 @@ class SBY_Settings {
64
 
65
  $this->connected_accounts = isset( $db['connected_accounts'] ) ? $db['connected_accounts'] : array();
66
 
67
- if ( $this->db['have_own_tokens'] && ! empty( $this->db['api_key'] ) ) {
68
  $this->connected_accounts = array(
69
  'own' => array(
70
  'access_token' => '',
@@ -83,6 +83,11 @@ class SBY_Settings {
83
 
84
  $this->settings = wp_parse_args( $atts, $db );
85
 
 
 
 
 
 
86
  $this->settings['nummobile'] = $this->settings['num'];
87
  $this->settings['minnum'] = $this->settings['num'];
88
  }
@@ -266,12 +271,25 @@ class SBY_Settings {
266
 
267
  foreach ( $channel_array as $channel ) {
268
  if ( strpos( $channel, 'UC' ) !== 0 ) {
269
- $feed_type_and_terms['channels'][] = array(
270
- 'term' => $channel,
271
- 'params' => array(
272
- 'channel_name' => $channel
273
- )
274
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  } else {
276
  $feed_type_and_terms['channels'][] = array(
277
  'term' => $channel,
@@ -279,8 +297,8 @@ class SBY_Settings {
279
  'channel_id' => $channel
280
  )
281
  );
 
282
  }
283
- $connected_accounts_in_feed[ $channel ] = $an_account;
284
  }
285
 
286
  } else {
@@ -320,7 +338,7 @@ class SBY_Settings {
320
  if ( $cache_time_unit == 'hours' ) $cache_time_unit = 60*60;
321
  if ( $cache_time_unit == 'days' ) $cache_time_unit = 60*60*24;
322
 
323
- $cache_time = max( 3600, $cache_time * $cache_time_unit );
324
 
325
  return $cache_time;
326
  }
64
 
65
  $this->connected_accounts = isset( $db['connected_accounts'] ) ? $db['connected_accounts'] : array();
66
 
67
+ if ( ! empty( $this->db['api_key'] ) ) {
68
  $this->connected_accounts = array(
69
  'own' => array(
70
  'access_token' => '',
83
 
84
  $this->settings = wp_parse_args( $atts, $db );
85
 
86
+ if ( empty( $this->connected_accounts ) ) {
87
+ $this->settings['showheader'] = false;
88
+ $this->connected_accounts = array( 'rss_only' => true );
89
+ }
90
+
91
  $this->settings['nummobile'] = $this->settings['num'];
92
  $this->settings['minnum'] = $this->settings['num'];
93
  }
271
 
272
  foreach ( $channel_array as $channel ) {
273
  if ( strpos( $channel, 'UC' ) !== 0 ) {
274
+ $channel_id = sby_get_channel_id_from_channel_name( $channel );
275
+ if ( $channel_id ) {
276
+ $feed_type_and_terms['channels'][] = array(
277
+ 'term' => $channel_id,
278
+ 'params' => array(
279
+ 'channel_id' => $channel_id
280
+ )
281
+ );
282
+ $connected_accounts_in_feed[ $channel_id ] = $an_account;
283
+ } else {
284
+ $feed_type_and_terms['channels'][] = array(
285
+ 'term' => $channel,
286
+ 'params' => array(
287
+ 'channel_name' => $channel
288
+ )
289
+ );
290
+ $connected_accounts_in_feed[ $channel ] = $an_account;
291
+ }
292
+
293
  } else {
294
  $feed_type_and_terms['channels'][] = array(
295
  'term' => $channel,
297
  'channel_id' => $channel
298
  )
299
  );
300
+ $connected_accounts_in_feed[ $channel ] = $an_account;
301
  }
 
302
  }
303
 
304
  } else {
338
  if ( $cache_time_unit == 'hours' ) $cache_time_unit = 60*60;
339
  if ( $cache_time_unit == 'days' ) $cache_time_unit = 60*60*24;
340
 
341
+ $cache_time = max( 900, $cache_time * $cache_time_unit );
342
 
343
  return $cache_time;
344
  }
inc/class-sby-wp-post.php CHANGED
@@ -59,6 +59,25 @@ class SBY_WP_Post
59
  return true;
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  protected function get_wp_post_id() {
63
  if ( isset( $this->wp_post_id ) ) {
64
  return $this->wp_post_id;
59
  return true;
60
  }
61
 
62
+ public static function maybe_get_channel_id_for_channel_title( $title ) {
63
+ global $wpdb;
64
+
65
+ $channel_id = $wpdb->get_col( $wpdb->prepare( "
66
+ SELECT Max(CASE
67
+ WHEN m.meta_key = 'sby_channel_id' THEN m.meta_value
68
+ ELSE NULL
69
+ END) AS sby_channel_id
70
+ FROM $wpdb->postmeta as m
71
+ WHERE m.post_id IN (SELECT m2.post_id FROM $wpdb->postmeta as m2 WHERE m2.meta_key = 'sby_channel_title' AND m2.meta_value = %s )
72
+ GROUP BY m.post_id
73
+ LIMIT 1", $title ) );
74
+
75
+ if ( isset( $channel_id[0] ) ) {
76
+ return $channel_id[0];
77
+ }
78
+ return false;
79
+ }
80
+
81
  protected function get_wp_post_id() {
82
  if ( isset( $this->wp_post_id ) ) {
83
  return $this->wp_post_id;
inc/sby-functions.php CHANGED
@@ -4,7 +4,6 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
 
5
  add_shortcode('youtube-feed', 'sby_youtube_feed');
6
  function sby_youtube_feed( $atts = array() ) {
7
-
8
  $database_settings = sby_get_database_settings();
9
  if ( !$database_settings['ajaxtheme'] ) {
10
  wp_enqueue_script( 'sby_scripts' );
@@ -14,13 +13,22 @@ function sby_youtube_feed( $atts = array() ) {
14
  wp_enqueue_style( 'sby_styles' );
15
  }
16
 
17
- if ( empty( $database_settings['connected_accounts'] ) && empty( $database_settings['api_key'] ) ) {
 
 
 
 
 
 
 
 
 
18
  $style = current_user_can( 'manage_youtube_feed_options' ) ? ' style="display: block;"' : '';
19
  ob_start(); ?>
20
  <div id="sbi_mod_error" <?php echo $style; ?>>
21
  <span><?php _e('This error message is only visible to WordPress admins', 'youtube-feed' ); ?></span><br />
22
- <p><b><?php _e( 'Error: No API key.', 'youtube-feed' ); ?></b>
23
- <p><?php _e( 'Please go to the YouTube Feed settings page to enter an API key.', 'youtube-feed' ); ?></p>
24
  </div>
25
  <?php
26
  $html = ob_get_contents();
@@ -28,13 +36,6 @@ function sby_youtube_feed( $atts = array() ) {
28
  return $html;
29
  }
30
 
31
- $youtube_feed_settings = new SBY_Settings( $atts, $database_settings );
32
- $youtube_feed_settings->set_feed_type_and_terms();
33
- $youtube_feed_settings->set_transient_name();
34
- $transient_name = $youtube_feed_settings->get_transient_name();
35
- $settings = $youtube_feed_settings->get_settings();
36
- $feed_type_and_terms = $youtube_feed_settings->get_feed_type_and_terms();
37
-
38
  $youtube_feed = new SBY_Feed( $transient_name );
39
 
40
  if ( $database_settings['caching_type'] === 'background' ) {
@@ -172,7 +173,7 @@ function sby_get_next_post_set() {
172
  }
173
 
174
  $youtube_feed_settings->set_feed_type_and_terms();
175
- $youtube_feed_settings->set_transient_name();
176
  $transient_name = $youtube_feed_settings->get_transient_name();
177
 
178
  if ( $transient_name !== $feed_id ) {
@@ -248,14 +249,24 @@ function sby_get_next_post_set() {
248
  $youtube_feed->cache_feed_data( $youtube_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
249
  }
250
  }
251
- /*
252
- $settings['feed_avatars'] = array();
253
- if ( $youtube_feed->need_avatars( $settings ) ) {
254
- $youtube_feed->set_up_feed_avatars( $youtube_feed_settings->get_connected_accounts_in_feed(), $feed_type_and_terms );
255
- $settings['feed_avatars'] = $youtube_feed->get_username_avatars();
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
- */
258
- $feed_status = array( 'shouldPaginate' => $youtube_feed->should_use_pagination( $settings, $offset ) );
259
 
260
  /*if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
261
  global $sby_posts_manager;
@@ -316,6 +327,18 @@ function sby_process_wp_posts() {
316
 
317
  $offset = isset( $_POST['offset'] ) ? (int)$_POST['offset'] : 0;
318
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  $database_settings = sby_get_database_settings();
320
  $sby_settings = new SBY_Settings( $atts, $database_settings );
321
 
@@ -325,7 +348,11 @@ function sby_process_wp_posts() {
325
  if ( $youtube_feed->regular_cache_exists() ) {
326
  $youtube_feed->set_post_data_from_cache();
327
 
328
- $posts = array_slice( $youtube_feed->get_post_data(), max( 0, $offset - $settings['minnum'] ), $settings['minnum'] );
 
 
 
 
329
 
330
  foreach ( $posts as $post ) {
331
  $wp_post = new SBY_WP_Post( $post, $feed_id );
@@ -338,12 +365,55 @@ function sby_process_wp_posts() {
338
  //global $sby_posts_manager;
339
 
340
  //$sby_posts_manager->update_successful_ajax_test();
341
-
 
 
342
  die( 'check success' );
343
  }
344
  add_action( 'wp_ajax_sby_check_wp_submit', 'sby_process_wp_posts' );
345
  add_action( 'wp_ajax_nopriv_sby_check_wp_submit', 'sby_process_wp_posts' );
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  function sby_clear_cache() {
348
  //Delete all transients
349
  global $wpdb;
@@ -450,7 +520,7 @@ function sby_get_first_connected_account() {
450
  global $sby_settings;
451
  $an_account = array();
452
 
453
- if ( $sby_settings['have_own_tokens'] && ! empty( $sby_settings['api_key'] ) ) {
454
  $an_account = array(
455
  'access_token' => '',
456
  'refresh_token' => '',
@@ -472,8 +542,11 @@ function sby_get_first_connected_account() {
472
  }
473
  }
474
 
475
- return $an_account;
 
 
476
 
 
477
  }
478
 
479
  function sby_get_feed_template_part( $part, $settings = array() ) {
@@ -544,6 +617,25 @@ function sby_get_database_settings() {
544
  return array_merge( $defaults, $sby_settings );
545
  }
546
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
  function sby_icon( $icon, $class = '' ) {
548
  $class = ! empty( $class ) ? ' ' . trim( $class ) : '';
549
  if ( $icon === SBY_SLUG ) {
4
 
5
  add_shortcode('youtube-feed', 'sby_youtube_feed');
6
  function sby_youtube_feed( $atts = array() ) {
 
7
  $database_settings = sby_get_database_settings();
8
  if ( !$database_settings['ajaxtheme'] ) {
9
  wp_enqueue_script( 'sby_scripts' );
13
  wp_enqueue_style( 'sby_styles' );
14
  }
15
 
16
+ $youtube_feed_settings = new SBY_Settings( $atts, $database_settings );
17
+ $youtube_feed_settings->set_feed_type_and_terms();
18
+ $youtube_feed_settings->set_transient_name();
19
+ $transient_name = $youtube_feed_settings->get_transient_name();
20
+ $settings = $youtube_feed_settings->get_settings();
21
+ $feed_type_and_terms = $youtube_feed_settings->get_feed_type_and_terms();
22
+
23
+ if ( empty( $database_settings['connected_accounts'] )
24
+ && empty( $database_settings['api_key'] )
25
+ && ! isset( $feed_type_and_terms['channels'][0]['channel_id'] ) ) {
26
  $style = current_user_can( 'manage_youtube_feed_options' ) ? ' style="display: block;"' : '';
27
  ob_start(); ?>
28
  <div id="sbi_mod_error" <?php echo $style; ?>>
29
  <span><?php _e('This error message is only visible to WordPress admins', 'youtube-feed' ); ?></span><br />
30
+ <p><b><?php _e( 'Error: No connected account or API key.', 'youtube-feed' ); ?></b>
31
+ <p><?php _e( 'Please go to the YouTube Feed settings page to enter an API key or connect an account.', 'youtube-feed' ); ?></p>
32
  </div>
33
  <?php
34
  $html = ob_get_contents();
36
  return $html;
37
  }
38
 
 
 
 
 
 
 
 
39
  $youtube_feed = new SBY_Feed( $transient_name );
40
 
41
  if ( $database_settings['caching_type'] === 'background' ) {
173
  }
174
 
175
  $youtube_feed_settings->set_feed_type_and_terms();
176
+ $youtube_feed_settings->set_transient_name( $feed_id );
177
  $transient_name = $youtube_feed_settings->get_transient_name();
178
 
179
  if ( $transient_name !== $feed_id ) {
249
  $youtube_feed->cache_feed_data( $youtube_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
250
  }
251
  }
252
+
253
+ $feed_status = array( 'shouldPaginate' => $youtube_feed->should_use_pagination( $settings, $offset ), );
254
+
255
+ $feed_status['cacheAll'] = $youtube_feed->do_page_cache_all();
256
+
257
+ $post_data = $youtube_feed->get_post_data();
258
+
259
+ if ( $youtube_feed->successful_video_api_request_made() && ! empty( $post_data ) ) {
260
+ if ( $settings['storage_process'] === 'page' ) {
261
+ foreach ( $youtube_feed->get_post_data() as $post ) {
262
+ $wp_post = new SBY_WP_Post( $post, $this->regular_feed_transient_name );
263
+ $wp_post->update_post();
264
+ }
265
+ } elseif ( $settings['storage_process'] === 'background' ) {
266
+ $feed_status['checkWPPosts'] = true;
267
+ $feed_status['cacheAll'] = true;
268
+ }
269
  }
 
 
270
 
271
  /*if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
272
  global $sby_posts_manager;
327
 
328
  $offset = isset( $_POST['offset'] ) ? (int)$_POST['offset'] : 0;
329
 
330
+ $cache_all = isset( $_POST['cache_all'] ) ? $_POST['cache_all'] === 'true' : false;
331
+
332
+ if ( $cache_all ) {
333
+ $database_settings = sby_get_database_settings();
334
+ $youtube_feed_settings = new SBY_Settings( $atts, $database_settings );
335
+ $youtube_feed_settings->set_feed_type_and_terms();
336
+ $youtube_feed_settings->set_transient_name( $feed_id );
337
+ $transient_name = $youtube_feed_settings->get_transient_name();
338
+
339
+ $feed_id = $transient_name;
340
+ }
341
+
342
  $database_settings = sby_get_database_settings();
343
  $sby_settings = new SBY_Settings( $atts, $database_settings );
344
 
348
  if ( $youtube_feed->regular_cache_exists() ) {
349
  $youtube_feed->set_post_data_from_cache();
350
 
351
+ if ( !$cache_all ) {
352
+ $posts = array_slice( $youtube_feed->get_post_data(), max( 0, $offset - $settings['minnum'] ), $settings['minnum'] );
353
+ } else {
354
+ $posts = $youtube_feed->get_post_data();
355
+ }
356
 
357
  foreach ( $posts as $post ) {
358
  $wp_post = new SBY_WP_Post( $post, $feed_id );
365
  //global $sby_posts_manager;
366
 
367
  //$sby_posts_manager->update_successful_ajax_test();
368
+ if ( $cache_all ) {
369
+ die( 'cache all' );
370
+ }
371
  die( 'check success' );
372
  }
373
  add_action( 'wp_ajax_sby_check_wp_submit', 'sby_process_wp_posts' );
374
  add_action( 'wp_ajax_nopriv_sby_check_wp_submit', 'sby_process_wp_posts' );
375
 
376
+ function sby_debug_report( $youtube_feed, $feed_id ) {
377
+
378
+ if ( ! isset( $_GET['sby_debug'] ) ) {
379
+ return;
380
+ }
381
+
382
+ ?>
383
+ <p>Status</p>
384
+ <ul>
385
+ <li>Time: <?php echo date( "Y-m-d H:i:s", time() ); ?></li>
386
+ <?php foreach ( $youtube_feed->get_report() as $item ) : ?>
387
+ <li><?php echo esc_html( $item ); ?></li>
388
+ <?php endforeach; ?>
389
+
390
+ </ul>
391
+
392
+ <?php
393
+ $database_settings = sby_get_database_settings();
394
+
395
+ $public_settings_keys = SBY_Settings::get_public_db_settings_keys();
396
+ ?>
397
+ <p>Settings</p>
398
+ <ul>
399
+ <?php foreach ( $public_settings_keys as $key ) : if ( isset( $database_settings[ $key ] ) ) : ?>
400
+ <li>
401
+ <small><?php echo esc_html( $key ); ?>:</small>
402
+ <?php if ( ! is_array( $database_settings[ $key ] ) ) :
403
+ echo $database_settings[ $key ];
404
+ else : ?>
405
+ <pre>
406
+ <?php var_export( $database_settings[ $key ] ); ?>
407
+ </pre>
408
+ <?php endif; ?>
409
+ </li>
410
+
411
+ <?php endif; endforeach; ?>
412
+ </ul>
413
+ <?php
414
+ }
415
+ add_action( 'sby_before_feed_end', 'sby_debug_report', 11, 2 );
416
+
417
  function sby_clear_cache() {
418
  //Delete all transients
419
  global $wpdb;
520
  global $sby_settings;
521
  $an_account = array();
522
 
523
+ if ( ! empty( $sby_settings['api_key'] ) ) {
524
  $an_account = array(
525
  'access_token' => '',
526
  'refresh_token' => '',
542
  }
543
  }
544
 
545
+ if ( empty( $an_account ) ) {
546
+ $an_account = array( 'rss_only' => true );
547
+ }
548
 
549
+ return $an_account;
550
  }
551
 
552
  function sby_get_feed_template_part( $part, $settings = array() ) {
617
  return array_merge( $defaults, $sby_settings );
618
  }
619
 
620
+
621
+ function sby_get_channel_id_from_channel_name( $channel_name ) {
622
+ $channel_ids = get_option( 'sby_channel_ids', array() );
623
+
624
+ if ( isset( $channel_ids[ strtolower( $channel_name ) ] ) ) {
625
+ return $channel_ids[ strtolower( $channel_name ) ];
626
+ }
627
+
628
+ return false;
629
+ }
630
+
631
+ function sby_set_channel_id_from_channel_name( $channel_name, $channel_id ) {
632
+ $channel_ids = get_option( 'sby_channel_ids', array() );
633
+
634
+ $channel_ids[ strtolower( $channel_name ) ] = $channel_id;
635
+
636
+ update_option( 'sby_channel_ids', $channel_ids, false );
637
+ }
638
+
639
  function sby_icon( $icon, $class = '' ) {
640
  $class = ! empty( $class ) ? ' ' . trim( $class ) : '';
641
  if ( $icon === SBY_SLUG ) {
js/sb-youtube.js CHANGED
@@ -225,14 +225,14 @@ if(!sby_js_exists) {
225
  autoplay = sbyOptions.autoplay;
226
  if (typeof window.sbyLightboxPlayer === 'undefined') {
227
  var args = {
228
- host: window.location.protocol + '//www.youtube-nocookie.com',
229
- videoId: videoID,
230
- playerVars: {
231
- modestbranding: 1,
232
- rel: 0,
233
- autoplay: autoplay
234
- },
235
- };
236
 
237
  window.sbyLightboxPlayer = new window.YT.Player(playerID, args);
238
  } else {
@@ -337,6 +337,7 @@ if(!sby_js_exists) {
337
  favorLocal : (flags.indexOf('favorLocal') > -1),
338
  ajaxPostLoad : (flags.indexOf('ajaxPostLoad') > -1),
339
  checkWPPosts : (flags.indexOf('checkWPPosts') > -1),
 
340
  lightboxEnabled : typeof $self.attr('data-sby-supports-lightbox') !== 'undefined',
341
  autoMinRes : 1,
342
  general : general
@@ -448,8 +449,8 @@ if(!sby_js_exists) {
448
  createPlayer: function(playerID,videoID,autoplay,args) {
449
  var $self = $(this.el),
450
  feed = this;
451
- videoID = typeof videoID !== 'undefined' ? videoID : this.getVideoID($self.find('.sby_item').first());
452
- autoplay = typeof autoplay !== 'undefined' ? autoplay : 0;
453
 
454
  if (typeof args === 'undefined') {
455
  args = {
@@ -638,12 +639,13 @@ if(!sby_js_exists) {
638
  },
639
  sendCheckWPPostsToServer: function() {
640
  var feed = this;
641
- if (feed.settings.checkWPPosts) {
642
  var submitData = {
643
  action: 'sby_check_wp_submit',
644
  feed_id: feed.settings.feedID,
645
  atts: feed.settings.shortCodeAtts,
646
  offset: $(this.el).find('.sby_item').length,
 
647
  };
648
  var onSuccess = function(data) {
649
  if (data.trim().indexOf('{') === 0) {
@@ -681,6 +683,18 @@ if(!sby_js_exists) {
681
  if (feed.settings.debugEnabled) {
682
  console.log(response);
683
  }
 
 
 
 
 
 
 
 
 
 
 
 
684
  feed.appendNewPosts(response.html);
685
  feed.addResizedImages(response.resizedImages);
686
  if (feed.settings.ajaxPostLoad) {
225
  autoplay = sbyOptions.autoplay;
226
  if (typeof window.sbyLightboxPlayer === 'undefined') {
227
  var args = {
228
+ host: window.location.protocol + '//www.youtube-nocookie.com',
229
+ videoId: videoID,
230
+ playerVars: {
231
+ modestbranding: 1,
232
+ rel: 0,
233
+ autoplay: autoplay
234
+ },
235
+ };
236
 
237
  window.sbyLightboxPlayer = new window.YT.Player(playerID, args);
238
  } else {
337
  favorLocal : (flags.indexOf('favorLocal') > -1),
338
  ajaxPostLoad : (flags.indexOf('ajaxPostLoad') > -1),
339
  checkWPPosts : (flags.indexOf('checkWPPosts') > -1),
340
+ cacheAll : (flags.indexOf('cacheAll') > -1),
341
  lightboxEnabled : typeof $self.attr('data-sby-supports-lightbox') !== 'undefined',
342
  autoMinRes : 1,
343
  general : general
449
  createPlayer: function(playerID,videoID,autoplay,args) {
450
  var $self = $(this.el),
451
  feed = this;
452
+ videoID = typeof videoID !== 'undefined' ? videoID : this.getVideoID($self.find('.sby_item').first());
453
+ autoplay = typeof autoplay !== 'undefined' ? autoplay : 0;
454
 
455
  if (typeof args === 'undefined') {
456
  args = {
639
  },
640
  sendCheckWPPostsToServer: function() {
641
  var feed = this;
642
+ if (feed.settings.checkWPPosts || feed.settings.cacheAll) {
643
  var submitData = {
644
  action: 'sby_check_wp_submit',
645
  feed_id: feed.settings.feedID,
646
  atts: feed.settings.shortCodeAtts,
647
  offset: $(this.el).find('.sby_item').length,
648
+ cache_all: feed.settings.cacheAll
649
  };
650
  var onSuccess = function(data) {
651
  if (data.trim().indexOf('{') === 0) {
683
  if (feed.settings.debugEnabled) {
684
  console.log(response);
685
  }
686
+ if (typeof response.feedStatus.cacheAll !== 'undefined'
687
+ && response.feedStatus.cacheAll) {
688
+ feed.settings.cacheAll = true;
689
+ } else {
690
+ feed.settings.cacheAll = false;
691
+ }
692
+ if (typeof response.feedStatus.checkWPPosts !== 'undefined'
693
+ && response.feedStatus.checkWPPosts) {
694
+ feed.settings.checkWPPosts = true;
695
+ } else {
696
+ feed.settings.checkWPPosts = false;
697
+ }
698
  feed.appendNewPosts(response.html);
699
  feed.addResizedImages(response.resizedImages);
700
  if (feed.settings.ajaxPostLoad) {
js/sb-youtube.min.js CHANGED
@@ -1 +1 @@
1
- var sby_js_exists=void 0!==sby_js_exists;if(!sby_js_exists){function sby_supports_video(){return!!document.createElement("video").canPlayType}!function(e){function i(){this.feeds={},this.options=sbyOptions,this.isTouch=function(){if("ontouchstart"in document.documentElement)return!0;return!1}()}function t(e,i,t){this.el=e,this.index=i,this.settings=t,this.playerAPIReady=!1,this.consentGiven=!0,this.players={},this.minImageWidth=0,this.imageResolution=150,this.resizedImages={},this.needsResizing=[],this.outOfPages=!1,this.isInitialized=!1}function s(i,t){e.ajax({url:sbyOptions.adminAjaxUrl,type:"post",data:i,success:t})}i.prototype={createPage:function(i,t){void 0!==window.sbyajaxurl&&-1!==window.sbyajaxurl.indexOf(window.location.hostname)||(window.sbyajaxurl=window.location.hostname+"/wp-admin/admin-ajax.php"),e(".sby_no_js_error_message").remove(),e(".sby_no_js").removeClass("sby_no_js");if(null===document.getElementById("youtube-api")){var s=document.createElement("script"),a=document.getElementsByTagName("script")[0];s.src="http://www.youtube.com/iframe_api",s.id="youtube-api",a.parentNode.insertBefore(s,a)}i(t)},createLightbox:function(){(function(){var i=jQuery,t=function(){function e(){this.fadeDuration=500,this.fitImagesInViewport=!0,this.resizeDuration=700,this.positionFromTop=50,this.showImageNumberLabel=!0,this.alwaysShowNavOnTouchDevices=!1,this.wrapAround=!1}return e.prototype.albumLabel=function(e,i){return e+" / "+i},e}(),s=function(){function t(e){this.options=e,this.album=[],this.currentImageIndex=void 0,this.init()}return t.prototype.init=function(){this.enable(),this.build()},t.prototype.enable=function(){var e=this;i("body").on("click","a[data-sby-lightbox]",function(t){return e.start(i(t.currentTarget)),!1})},t.prototype.build=function(){var e=this;i("<div id='sby_lightboxOverlay' class='sby_lightboxOverlay'></div><div id='sby_lightbox' class='sby_lightbox'><div class='sby_lb-outerContainer'><div class='sby_lb-container'><img class='sby_lb-image' alt='Lightbox image placeholder' src='' /><div class='sby_lb-player' id='sby_lb-player'></div><div class='sby_lb-nav'><a class='sby_lb-prev' href='#' ><p class='sby-screenreader'>Previous Slide</p></a><a class='sby_lb-next' href='#' ><p class='sby-screenreader'>Next Slide</p></a></div><div class='sby_lb-loader'><a class='sby_lb-cancel'></a></div></div></div><div class='sby_lb-dataContainer'><div class='sby_lb-data'><div class='sby_lb-details'><div class='sby_lb-caption'></div><div class='sby_lb-info'><div class='sby_lb-number'></div><div class='sby_lb-closeContainer'><a class='sby_lb-close'></a></div></div></div></div>").appendTo(i("body")),this.$lightbox=i("#sby_lightbox"),this.$overlay=i("#sby_lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".sby_lb-outerContainer"),this.$container=this.$lightbox.find(".sby_lb-container"),this.containerTopPadding=parseInt(this.$container.css("padding-top"),10),this.containerRightPadding=parseInt(this.$container.css("padding-right"),10),this.containerBottomPadding=parseInt(this.$container.css("padding-bottom"),10),this.containerLeftPadding=parseInt(this.$container.css("padding-left"),10),this.$overlay.hide().on("click",function(){return e.end(),!1}),jQuery(document).on("click",function(e,i,t){jQuery(e.target).closest(".sby_lb-outerContainer").length||jQuery(e.target).closest(".sby_lb-dataContainer").length||(void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),jQuery("#sby_lightboxOverlay, #sby_lightbox").fadeOut())}),this.$lightbox.hide(),jQuery("#sby_lightboxOverlay").on("click",function(t){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),"sby_lightbox"===i(t.target).attr("id")&&e.end(),!1}),this.$lightbox.find(".sby_lb-prev").on("click",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(0===e.currentImageIndex?e.album.length-1:e.currentImageIndex-1),!1}),this.$lightbox.find(".sby_lb-container").on("swiperight",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(0===e.currentImageIndex?e.album.length-1:e.currentImageIndex-1),!1}),this.$lightbox.find(".sby_lb-next").on("click",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(e.currentImageIndex===e.album.length-1?0:e.currentImageIndex+1),!1}),this.$lightbox.find(".sby_lb-container").on("swipeleft",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(e.currentImageIndex===e.album.length-1?0:e.currentImageIndex+1),!1}),this.$lightbox.find(".sby_lb-loader, .sby_lb-close").on("click",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.end(),!1})},t.prototype.start=function(e){function t(e){s.album.push({link:e.attr("href"),video:e.attr("data-video-id")})}var s=this,a=i(window);a.on("resize",i.proxy(this.sizeOverlay,this)),i("select, object, embed").css({visibility:"hidden"}),this.sizeOverlay(),this.album=[];var n,o=0,d=e.attr("data-sby-lightbox");if(d){n=i(e.prop("tagName")+'[data-sby-lightbox="'+d+'"]');for(var r=0;r<n.length;r=++r)t(i(n[r])),n[r]===e[0]&&(o=r)}else if("lightbox"===e.attr("rel"))t(e);else{n=i(e.prop("tagName")+'[rel="'+e.attr("rel")+'"]');for(var l=0;l<n.length;l=++l)t(i(n[l])),n[l]===e[0]&&(o=l)}var h=a.scrollTop()+this.options.positionFromTop,b=a.scrollLeft();this.$lightbox.css({top:h+"px",left:b+"px"}).fadeIn(this.options.fadeDuration),this.changeImage(o)},t.prototype.changeImage=function(e){var t=this;this.disableKeyboardNav();var s=this.$lightbox.find(".sby_lb-image");this.$overlay.fadeIn(this.options.fadeDuration),i(".sby_lb-loader").fadeIn("slow"),this.$lightbox.find(".sby_lb-image, .sby_lb-nav, .sby_lb-prev, .sby_lb-next, .sby_lb-dataContainer, .sby_lb-numbers, .sby_lb-caption").hide(),this.$outerContainer.addClass("animating");var a=new Image;a.onload=function(){var n,o,d,r,l,h;s.attr("src",t.album[e].link),i(a),s.width(a.width),s.height(a.height),t.options.fitImagesInViewport&&(h=i(window).width(),l=i(window).height(),r=h-t.containerLeftPadding-t.containerRightPadding-20,d=l-t.containerTopPadding-t.containerBottomPadding-150,(a.width>r||a.height>d)&&(a.width/r>a.height/d?(o=r,n=parseInt(a.height/(a.width/o),10),s.width(o),s.height(n)):(n=d,o=parseInt(a.width/(a.height/n),10),s.width(o),s.height(n)))),t.sizeContainer(s.width(),s.height())},a.src=this.album[e].link,this.currentImageIndex=e},t.prototype.sizeOverlay=function(){this.$overlay.width(i(window).width()).height(i(document).height())},t.prototype.sizeContainer=function(e,i){function t(){s.$lightbox.find(".sby_lb-dataContainer").width(o),s.$lightbox.find(".sby_lb-prevLink").height(d),s.$lightbox.find(".sby_lb-nextLink").height(d),s.showImage()}var s=this,a=this.$outerContainer.outerWidth(),n=this.$outerContainer.outerHeight(),o=e+this.containerLeftPadding+this.containerRightPadding,d=i+this.containerTopPadding+this.containerBottomPadding;a!==o||n!==d?this.$outerContainer.animate({width:o,height:d},this.options.resizeDuration,"swing",function(){t()}):t()},t.prototype.showImage=function(){this.$lightbox.find(".sby_lb-loader").hide(),this.$lightbox.find(".sby_lb-image").fadeIn("slow"),this.updateNav(),this.updateDetails(),this.preloadNeighboringImages(),this.enableKeyboardNav()},t.prototype.updateNav=function(){var e=!1;try{document.createEvent("TouchEvent"),e=!!this.options.alwaysShowNavOnTouchDevices}catch(e){}this.$lightbox.find(".sby_lb-nav").show(),this.album.length>1&&(this.options.wrapAround?(e&&this.$lightbox.find(".sby_lb-prev, .sby_lb-next").css("opacity","1"),this.$lightbox.find(".sby_lb-prev, .sby_lb-next").show()):(this.currentImageIndex>0&&(this.$lightbox.find(".sby_lb-prev").show(),e&&this.$lightbox.find(".sby_lb-prev").css("opacity","1")),this.currentImageIndex<this.album.length-1&&(this.$lightbox.find(".sby_lb-next").show(),e&&this.$lightbox.find(".sby_lb-next").css("opacity","1"))))},t.prototype.updateDetails=function(){if(sby_supports_video()&&(jQuery("#sby_lightbox").removeClass("sby_video_lightbox"),this.album[this.currentImageIndex].video.length)){jQuery("#sby_lightbox").addClass("sby_video_lightbox");var e=this.album[this.currentImageIndex].video,i=sbyOptions.autoplay;if(void 0===window.sbyLightboxPlayer){var t={host:window.location.protocol+"//www.youtube-nocookie.com",videoId:e,playerVars:{modestbranding:1,rel:0,autoplay:i}};window.sbyLightboxPlayer=new window.YT.Player("sby_lb-player",t)}else window.sbyLightboxPlayer.loadVideoById(e)}},t.prototype.preloadNeighboringImages=function(){this.album.length>this.currentImageIndex+1&&((new Image).src=this.album[this.currentImageIndex+1].link);this.currentImageIndex>0&&((new Image).src=this.album[this.currentImageIndex-1].link)},t.prototype.enableKeyboardNav=function(){i(document).on("keyup.keyboard",i.proxy(this.keyboardAction,this))},t.prototype.disableKeyboardNav=function(){i(document).off(".keyboard")},t.prototype.keyboardAction=function(i){var t=event.keyCode,s=String.fromCharCode(t).toLowerCase();27===t||s.match(/x|o|c/)?(sby_supports_video()&&e("#sby_lightbox video.sby_video")[0].pause(),e("#sby_lightbox iframe").attr("src",""),this.end()):"p"===s||37===t?(0!==this.currentImageIndex?this.changeImage(this.currentImageIndex-1):this.options.wrapAround&&this.album.length>1&&this.changeImage(this.album.length-1),sby_supports_video()&&e("#sby_lightbox video.sby_video")[0].pause(),e("#sby_lightbox iframe").attr("src","")):"n"!==s&&39!==t||(this.currentImageIndex!==this.album.length-1?this.changeImage(this.currentImageIndex+1):this.options.wrapAround&&this.album.length>1&&this.changeImage(0),void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo())},t.prototype.end=function(){this.disableKeyboardNav(),i(window).off("resize",this.sizeOverlay),this.$lightbox.fadeOut(this.options.fadeDuration),this.$overlay.fadeOut(this.options.fadeDuration),i("select, object, embed").css({visibility:"visible"})},t}();i(function(){var i=new t;new s(i),e(".sby_lightbox_action a").unbind().bind("click",function(){e(this).parent().find(".sby_lightbox_tooltip").toggle()})})}).call(this)},createFeeds:function(i){window.sby.createLightbox(),i.whenFeedsCreated(e(".sb_youtube").each(function(i){e(this).attr("data-sby-index",i+1),e(this).find(".sby_player").replaceWith('<div id="sby_player'+i+'"></div>');var a=e(this),n=void 0!==a.attr("data-sby-flags")?a.attr("data-sby-flags").split(","):[],o=void 0!==a.attr("data-options")?JSON.parse(a.attr("data-options")):{};if(n.indexOf("testAjax")>-1){window.sby.triggeredTest=!0;s({action:"sby_on_ajax_test_trigger"},function(e){console.log("did test")})}var d={cols:a.attr("data-cols"),colsmobile:"same"!==a.attr("data-colsmobile")?a.attr("data-colsmobile"):a.attr("data-cols"),num:a.attr("data-num"),imgRes:a.attr("data-res"),feedID:a.attr("data-feedid"),shortCodeAtts:a.attr("data-shortcode-atts"),resizingEnabled:-1===n.indexOf("resizeDisable"),imageLoadEnabled:-1===n.indexOf("imageLoadDisable"),debugEnabled:n.indexOf("debug")>-1,favorLocal:n.indexOf("favorLocal")>-1,ajaxPostLoad:n.indexOf("ajaxPostLoad")>-1,checkWPPosts:n.indexOf("checkWPPosts")>-1,lightboxEnabled:void 0!==a.attr("data-sby-supports-lightbox"),autoMinRes:1,general:o};window.sby.feeds[i]=function(e,i,s){return new t(e,i,s)}(this,i,d),window.sby.feeds[i].setResizedImages(),window.sby.feeds[i].init();var r=jQuery.Event("sbyafterfeedcreate");r.feed=window.sby.feeds[i],jQuery(window).trigger(r)}))},afterFeedsCreated:function(){e(".sb_instagram_header").each(function(){var i=e(this);i.find(".sby_header_link").hover(function(){i.find(".sby_header_img_hover").addClass("sby_fade_in")},function(){i.find(".sby_header_img_hover").removeClass("sby_fade_in")})})},encodeHTML:function(e){return void 0===e?"":e.replace(/(>)/g,"&gt;").replace(/(<)/g,"&lt;").replace(/(&lt;br\/&gt;)/g,"<br>").replace(/(&lt;br&gt;)/g,"<br>")},urlDetect:function(e){return e.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/g)}},t.prototype={init:function(){var e=this;this.settings.ajaxPostLoad?this.getNewPostSet():this.afterInitialImagesLoaded();var i,t=(i=0,function(e,t){clearTimeout(i),i=setTimeout(e,t)});jQuery(window).resize(function(){t(function(){e.afterResize()},500)})},initLayout:function(){var i=e(this.el),t=this;i.hasClass("sby_layout_gallery")&&i.find(".sby_player_outer_wrap").length&&(this.maybeRaiseSingleImageResolution(i.find(".sby_player_outer_wrap"),0,!0),i.find(".sby_player_outer_wrap .sby_video_thumbnail").off().click(function(i){i.preventDefault(),t.onThumbnailClick(e(this),!0)}),i.mouseenter(function(){t.canCreatePlayer()&&(i.find(".sby_player_outer_wrap iframe").length||(i.addClass("sby_player_added").find(".sby_player_outer_wrap").addClass("sby_player_loading"),i.find(".sby_player_outer_wrap .sby_video_thumbnail").find(".sby_loader").show().removeClass("sby_hidden"),t.createPlayer("sby_player"+t.index)))}))},createPlayer:function(i,t,s,a){var n=e(this.el),o=this;t=void 0!==t?t:this.getVideoID(n.find(".sby_item").first()),s=void 0!==s?s:0,void 0===a&&(a={host:window.location.protocol+"//www.youtube-nocookie.com",videoId:t,playerVars:{modestbranding:1,rel:0,autoplay:s}}),void 0===a.events&&(a.events={onReady:function(){n.find(".sby_player_outer_wrap").removeClass("sby_player_loading").find(".sby_video_thumbnail").css("z-index",-1).find(".sby_loader").hide().addClass("sby_hidden"),e("#"+i).length&&e("#"+i).closest(".sby_video_thumbnail_wrap").find(".sby_video_thumbnail").length&&e("#"+i).closest(".sby_video_thumbnail_wrap").find(".sby_video_thumbnail").fadeTo(0,"slow",function(){e(this).css("z-index",-1),e(this).find(".sby_loader").hide().addClass("sby_hidden"),e(this).closest(".sby_item").removeClass("sby_player_loading")})},onStateChange:function(i){1===i.data&&void 0!==o.players&&n.find(".sby_item").each(function(){var i=o.getVideoID(e(this));t!==i&&void 0!==o.players[i]&&o.players[i].pauseVideo()})}});var d=new window.YT.Player(i,a);return n.hasClass("sby_layout_list")&&void 0===this.players[t]?this.players[t]=d:void 0===this.player&&(this.player=d),d},afterInitialImagesLoaded:function(){this.initLayout(),this.loadMoreButtonInit(),this.hideExtraItemsForWidth(),this.beforeNewImagesRevealed(),this.revealNewImages(),this.afterNewImagesRevealed()},afterResize:function(){this.setImageHeight(),this.setImageResolution(),this.maybeRaiseImageResolution(),this.setImageSizeClass()},afterLoadMoreClicked:function(e){e.find(".sby_loader").removeClass("sby_hidden"),e.find(".sby_btn_text").addClass("sby_hidden"),e.closest(".sb_youtube").find(".sby_num_diff_hide").addClass("sby_transition").removeClass("sby_num_diff_hide")},afterNewImagesLoaded:function(){var i=e(this.el),t=this;this.beforeNewImagesRevealed(),this.revealNewImages(),this.afterNewImagesRevealed(),setTimeout(function(){i.find(".sby_loader").addClass("sby_hidden"),i.find(".sby_btn_text").removeClass("sby_hidden"),t.maybeRaiseImageResolution()},500)},beforeNewImagesRevealed:function(){this.setImageHeight(),this.maybeRaiseImageResolution(!0),this.setImageSizeClass()},revealNewImages:function(){var i=e(this.el),t=this;"function"==typeof sbyCustomJS&&setTimeout(function(){sbyCustomJS()},100),i.find(".sby_item").each(function(i){var s=jQuery(this);s.find(".sby_video_thumbnail").hover(function(){jQuery(this).fadeTo(200,.85)},function(){jQuery(this).stop().fadeTo(500,1)}),s.find(".sby_video_thumbnail").off().click(function(i){i.preventDefault(),t.onThumbnailClick(e(this),!1)}),s.find(".sby_video_thumbnail").mouseenter(function(){t.onThumbnailEnter(e(this),!1)}),s.find(".sby_player_wrap").mouseleave(function(){t.onThumbnailLeave(e(this),!1)}),t.settings.lightboxEnabled&&(s.find(".sby_video_thumbnail").attr("data-sby-lightbox",t.index),"undefined"!=typeof sbyOptions&&void 0!==sbyOptions.lightboxPlaceholder&&s.find(".sby_video_thumbnail").attr("href",sbyOptions.lightboxPlaceholder))}),setTimeout(function(){i.find(".sby_item.sby_new").removeClass("sby_new");var e=10;i.find(".sby_transition").length;i.find(".sby_transition").each(function(i){var t=jQuery(this);setTimeout(function(){t.removeClass("sby_transition")},e),e+=10})},500)},afterNewImagesRevealed:function(){this.listenForVisibilityChange(),this.sendNeedsResizingToServer(),this.sendCheckWPPostsToServer(),this.settings.imageLoadEnabled||e(".sby_no_resraise").removeClass("sby_no_resraise");var i=e.Event("sbyafterimagesloaded");i.el=e(this.el),e(window).trigger(i)},setResizedImages:function(){e(this.el).find(".sby_resized_image_data").length&&void 0!==e(this.el).find(".sby_resized_image_data").attr("data-resized")&&0===e(this.el).find(".sby_resized_image_data").attr("data-resized").indexOf('{"')&&(this.resizedImages=JSON.parse(e(this.el).find(".sby_resized_image_data").attr("data-resized")),e(this.el).find(".sby_resized_image_data").remove())},sendNeedsResizingToServer:function(){var i=this;if(i.needsResizing.length>0&&i.settings.resizingEnabled){var t=e(this.el).find(".sby_item").length;s({action:"sby_resized_images_submit",needs_resizing:i.needsResizing,offset:t,feed_id:i.settings.feedID,atts:i.settings.shortCodeAtts},function(e){if(0===e.trim().indexOf("{")){var t=JSON.parse(e);i.settings.debugEnabled&&console.log(t)}})}},sendCheckWPPostsToServer:function(){var i=this;if(i.settings.checkWPPosts){s({action:"sby_check_wp_submit",feed_id:i.settings.feedID,atts:i.settings.shortCodeAtts,offset:e(this.el).find(".sby_item").length},function(e){if(0===e.trim().indexOf("{")){var t=JSON.parse(e);i.settings.debugEnabled&&console.log(t)}})}},loadMoreButtonInit:function(){var i=e(this.el),t=this;i.find(".sby_footer .sby_load_btn").off().on("click",function(){t.afterLoadMoreClicked(jQuery(this)),t.getNewPostSet()})},getNewPostSet:function(){var i=e(this.el),t=this;s({action:"sby_load_more_clicked",offset:i.find(".sby_item").length,feed_id:t.settings.feedID,atts:t.settings.shortCodeAtts,current_resolution:t.imageResolution},function(s){if(0===s.trim().indexOf("{")){var a=JSON.parse(s);t.settings.debugEnabled&&console.log(a),t.appendNewPosts(a.html),t.addResizedImages(a.resizedImages),t.settings.ajaxPostLoad?(t.settings.ajaxPostLoad=!1,t.afterInitialImagesLoaded()):t.afterNewImagesLoaded(),a.feedStatus.shouldPaginate?t.outOfPages=!1:(t.outOfPages=!0,i.find(".sby_load_btn").hide()),e(".sby_no_js").removeClass("sby_no_js")}})},appendNewPosts:function(i){var t=e(this.el);t.find(".sby_items_wrap .sby_item").length?t.find(".sby_items_wrap .sby_item").last().after(i):t.find(".sby_items_wrap").append(i)},addResizedImages:function(e){for(var i in e)this.resizedImages[i]=e[i]},setImageHeight:function(){},maybeRaiseSingleImageResolution:function(i,t,s){var a=this,n=a.getImageUrls(i),o=i.find(".sby_video_thumbnail img").attr("src"),d=150;s=void 0!==s&&s;if(!i.hasClass("sby_no_resraise")){e.each(n,function(e,i){i===o&&(d=parseInt(e),s=!1)});var r=640;switch(a.settings.imgRes){case"thumb":r=120;break;case"medium":r=320;break;case"large":r=480;break;case"full":r=640;break;default:var l=Math.max(a.settings.autoMinRes,i.find(".sby_video_thumbnail").innerWidth());switch(a.getBestResolutionForAuto(l,1,e(this.el).find("sby_item").first())){case 480:r=480;break;case 320:r=320;break;case 120:r=120}}if(r>d||o===window.sby.options.placeholder||s){if(a.settings.debugEnabled){var h=o===window.sby.options.placeholder?"was placeholder":"too small";console.log("rais res for "+o,h)}var b=n[r];i.find(".sby_video_thumbnail img").attr("src",b)}i.find("img").on("error",function(){if(e(this).hasClass("sby_img_error"))console.log("unfixed error "+e(this).attr("src"));else{if(e(this).addClass("sby_img_error"),e(this).attr("src").indexOf("i.ytimg.com")>-1)a.settings.favorLocal=!0,a.getImageUrls(e(this).closest(".sby_item"))[640];else void 0!==e(this).closest(".sby_video_thumbnail").attr("data-full-res")||e(this).closest(".sby_video_thumbnail").attr("href");setTimeout(function(){a.afterResize()},1500)}})}},maybeRaiseImageResolution:function(i){var t=this,s=void 0!==i&&!0===i?".sby_item.sby_new":".sby_item",a=!t.isInitialized;e(t.el).find(s).each(function(i){!e(this).hasClass("sby_num_diff_hide")&&e(this).find(".sby_video_thumbnail").length&&void 0!==e(this).find(".sby_video_thumbnail").attr("data-img-src-set")&&t.maybeRaiseSingleImageResolution(e(this),i,a)}),t.isInitialized=!0},getBestResolutionForAuto:function(i,t,s){(isNaN(t)||t<1)&&(t=1);var a=i*t,n=10*Math.ceil(a/10),o=[120,320,480,640];if(s.hasClass("sby_highlighted")&&(n*=2),-1===o.indexOf(parseInt(n))){var d=!1;e.each(o,function(e,i){i>parseInt(n)&&!d&&(n=i,d=!0)})}return n},hideExtraItemsForWidth:function(){if("carousel"!==this.layout){var i=e(this.el),t=void 0!==i.attr("data-num")&&""!==i.attr("data-num")?parseInt(i.attr("data-num")):1,s=void 0!==i.attr("data-nummobile")&&""!==i.attr("data-nummobile")?parseInt(i.attr("data-nummobile")):t;e(window).width()<480?s<i.find(".sby_item").length&&i.find(".sby_item").slice(s-i.find(".sby_item").length).addClass("sby_num_diff_hide"):t<i.find(".sby_item").length&&i.find(".sby_item").slice(t-i.find(".sby_item").length).addClass("sby_num_diff_hide")}},setImageSizeClass:function(){var i=e(this.el);i.removeClass("sby_small sby_medium");var t=i.innerWidth(),s=parseInt(i.find(".sby_items_wrap").outerWidth()-i.find(".sby_items_wrap").width())/2,a=this.getColumnCount(),n=(t-s*(a+2))/a;n>120&&n<240?i.addClass("sby_medium"):n<=120&&i.addClass("sby_small")},setMinImageWidth:function(){e(this.el).find(".sby_item .sby_video_thumbnail").first().length?this.minImageWidth=e(this.el).find(".sby_item .sby_video_thumbnail").first().innerWidth():this.minImageWidth=150},setImageResolution:function(){if("auto"===this.settings.imgRes)this.imageResolution="auto";else switch(this.settings.imgRes){case"thumb":this.imageResolution=150;break;case"medium":this.imageResolution=320;break;default:this.imageResolution=640}},getImageUrls:function(e){var i=JSON.parse(e.find(".sby_video_thumbnail").attr("data-img-src-set").replace(/\\\//g,"/")),t=e.attr("id").replace("sby_","").replace("player_","");if(void 0!==this.resizedImages[t]&&"video"!==this.resizedImages[t]&&"pending"!==this.resizedImages[t]&&"error"!==this.resizedImages[t].id&&"video"!==this.resizedImages[t].id&&"pending"!==this.resizedImages[t].id){if(void 0!==this.resizedImages[t].sizes){var s=[];void 0!==this.resizedImages[t].sizes.full&&(s.push(640),i[640]=sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg",e.find(".sby_link_area").attr("href",sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg"),e.find(".sby_video_thumbnail").attr("data-full-res",sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg")),void 0!==this.resizedImages[t].sizes.low&&(s.push(320),i[320]=sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg",this.settings.favorLocal&&void 0===this.resizedImages[t].sizes.full&&(e.find(".sby_link_area").attr("href",sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg"),e.find(".sby_video_thumbnail").attr("data-full-res",sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg"))),void 0!==this.resizedImages[t].sizes.thumb&&(s.push(150),i[150]=sbyOptions.resized_url+this.resizedImages[t].id+"thumb.jpg"),this.settings.favorLocal&&(-1===s.indexOf(640)&&s.indexOf(320)>-1&&(i[640]=sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg"),-1===s.indexOf(320)&&(s.indexOf(640)>-1?i[320]=sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg":s.indexOf(150)>-1&&(i[320]=sbyOptions.resized_url+this.resizedImages[t].id+"thumb.jpg")),-1===s.indexOf(150)&&(s.indexOf(320)>-1?i[150]=sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg":s.indexOf(640)>-1&&(i[150]=sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg")))}}else(void 0===this.resizedImages[t]||void 0!==this.resizedImages[t].id&&"pending"!==this.resizedImages[t].id&&"error"!==this.resizedImages[t].id)&&this.addToNeedsResizing(t);return i},getVideoID:function(e){if(e.hasClass("sby_item")||e.hasClass("sby_player_item")){if(void 0!==e.find(".sby_video_thumbnail").attr("data-video-id"))return e.find(".sby_video_thumbnail").attr("data-video-id")}else if(e.closest("sby_item").length||e.closest("sby_player_item").length){var i=e.closest("sby_item").length?e.closest("sby_item"):e.closest("sby_player_item");if(void 0!==i.find(".sby_video_thumbnail").attr("data-video-id"))return i.find(".sby_video_thumbnail").attr("data-video-id")}else if(e.hasClass("sb_youtube"))return e.find(".sby_item").first().find(".sby_video_thumbnail").attr("data-video-id");return console.log("no id"),""},getAvatarUrl:function(e,i){if(""===e)return"";var t=this.settings.general.avatars;return"local"===(i=void 0!==i?i:"local")?void 0!==t["LCL"+e]&&1===parseInt(t["LCL"+e])?sbyOptions.resized_url+e+".jpg":void 0!==t[e]?t[e]:"":void 0!==t[e]?t[e]:void 0!==t["LCL"+e]&&1===parseInt(t["LCL"+e])?sbyOptions.resized_url+e+".jpg":""},addToNeedsResizing:function(e){-1===this.needsResizing.indexOf(e)&&this.needsResizing.push(e)},listenForVisibilityChange:function(){var i,t,s,a=this;i=jQuery,t={callback:function(){},runOnLoad:!0,frequency:100,sbyPreviousVisibility:null},s={sbyCheckVisibility:function(e,i){if(jQuery.contains(document,e[0])){var t=i.sbyPreviousVisibility,a=e.is(":visible");i.sbyPreviousVisibility=a,null==t?i.runOnLoad&&i.callback(e,a):t!==a&&i.callback(e,a),setTimeout(function(){s.sbyCheckVisibility(e,i)},i.frequency)}}},i.fn.sbyVisibilityChanged=function(e){var a=i.extend({},t,e);return this.each(function(){s.sbyCheckVisibility(i(this),a)})},"function"==typeof e(this.el).filter(":hidden").sbyVisibilityChanged&&e(this.el).filter(":hidden").sbyVisibilityChanged({callback:function(e,i){a.afterResize()},runOnLoad:!1})},getColumnCount:function(){var i=e(this.el),t=this.settings.cols,s=this.settings.colsmobile,a=t;return sbyWindowWidth=window.innerWidth,i.hasClass("sby_mob_col_auto")?(sbyWindowWidth<640&&parseInt(t)>2&&parseInt(t)<7&&(a=2),sbyWindowWidth<640&&parseInt(t)>6&&parseInt(t)<11&&(a=4),sbyWindowWidth<=480&&parseInt(t)>2&&(a=1)):sbyWindowWidth<=480&&(a=s),parseInt(a)},onThumbnailClick:function(i,t){if(this.canCreatePlayer()){var s=e(this.el);if(s.hasClass("sby_layout_gallery"))s.addClass("sby_player_added").find(".sby_player_outer_wrap").addClass("sby_player_loading"),s.find(".sby_player_outer_wrap .sby_video_thumbnail").find(".sby_loader").show().removeClass("sby_hidden"),s.find(".sby_player_outer_wrap iframe").length?t?this.playVideoInPlayer(this.getVideoID(s.find(".sby_item").first())):(this.playVideoInPlayer(this.getVideoID(i.closest(".sby_item"))),this.afterVideoChanged()):t?this.createPlayer("sby_player"+this.index):this.createPlayer("sby_player"+this.index,this.getVideoID(i.closest(".sby_item")));else if(e(this.el).hasClass("sby_layout_grid")){var a=i.closest(".sby_item"),n=this.getVideoID(a);this.playVideoInPlayer(n),this.afterVideoChanged()}else if(e(this.el).hasClass("sby_layout_list")){a=i.closest(".sby_item"),n=this.getVideoID(a);a.find("iframe").length||(a.find(".sby_loader").show().removeClass("sby_hidden"),a.addClass("sby_player_loading sby_player_loaded"),this.createPlayer("sby_player_"+n,n))}}},onThumbnailEnter:function(i){if(this.canCreatePlayer()&&e(this.el).hasClass("sby_layout_list")){var t=i.closest(".sby_item"),s=this.getVideoID(t);t.find("iframe").length||(t.find(".sby_loader").show().removeClass("sby_hidden"),t.addClass("sby_player_loading sby_player_loaded"),this.createPlayer("sby_player_"+s,s,0))}},onThumbnailLeave:function(e){},canCreatePlayer:function(){return this.playerAPIReady&&this.consentGiven},playVideoInPlayer:function(e){void 0!==this.player&&void 0!==this.player.loadVideoById&&this.player.loadVideoById(e)},afterVideoChanged:function(){e(this.el).hasClass("sby_layout_gallery")&&(e(this.el).find(".sby_player_outer_wrap").removeClass("sby_player_loading"),e(this.el).find(".sby_player_outer_wrap .sby_video_thumbnail").find(".sby_loader").hide().addClass("sby_hidden"),e(window).width()<480&&e("html, body").animate({scrollTop:e(this.el).find(".sby_player_outer_wrap").offset().top},300))}},window.sby_init=function(){window.sby=new i,window.sby.createPage(window.sby.createFeeds,{whenFeedsCreated:window.sby.afterFeedsCreated})}}(jQuery),jQuery(document).ready(function(e){sby_init()})}window.onYouTubeIframeAPIReady=function(){var e=document.getElementsByClassName("sb_youtube").length;if(e>0)for(var i=0;i<e;i++)window.sby.feeds[i].playerAPIReady=!0};
1
+ var sby_js_exists=void 0!==sby_js_exists;if(!sby_js_exists){function sby_supports_video(){return!!document.createElement("video").canPlayType}!function(e){function i(){this.feeds={},this.options=sbyOptions,this.isTouch=function(){if("ontouchstart"in document.documentElement)return!0;return!1}()}function t(e,i,t){this.el=e,this.index=i,this.settings=t,this.playerAPIReady=!1,this.consentGiven=!0,this.players={},this.minImageWidth=0,this.imageResolution=150,this.resizedImages={},this.needsResizing=[],this.outOfPages=!1,this.isInitialized=!1}function s(i,t){e.ajax({url:sbyOptions.adminAjaxUrl,type:"post",data:i,success:t})}i.prototype={createPage:function(i,t){void 0!==window.sbyajaxurl&&-1!==window.sbyajaxurl.indexOf(window.location.hostname)||(window.sbyajaxurl=window.location.hostname+"/wp-admin/admin-ajax.php"),e(".sby_no_js_error_message").remove(),e(".sby_no_js").removeClass("sby_no_js");if(null===document.getElementById("youtube-api")){var s=document.createElement("script"),a=document.getElementsByTagName("script")[0];s.src="http://www.youtube.com/iframe_api",s.id="youtube-api",a.parentNode.insertBefore(s,a)}i(t)},createLightbox:function(){(function(){var i=jQuery,t=function(){function e(){this.fadeDuration=500,this.fitImagesInViewport=!0,this.resizeDuration=700,this.positionFromTop=50,this.showImageNumberLabel=!0,this.alwaysShowNavOnTouchDevices=!1,this.wrapAround=!1}return e.prototype.albumLabel=function(e,i){return e+" / "+i},e}(),s=function(){function t(e){this.options=e,this.album=[],this.currentImageIndex=void 0,this.init()}return t.prototype.init=function(){this.enable(),this.build()},t.prototype.enable=function(){var e=this;i("body").on("click","a[data-sby-lightbox]",function(t){return e.start(i(t.currentTarget)),!1})},t.prototype.build=function(){var e=this;i("<div id='sby_lightboxOverlay' class='sby_lightboxOverlay'></div><div id='sby_lightbox' class='sby_lightbox'><div class='sby_lb-outerContainer'><div class='sby_lb-container'><img class='sby_lb-image' alt='Lightbox image placeholder' src='' /><div class='sby_lb-player' id='sby_lb-player'></div><div class='sby_lb-nav'><a class='sby_lb-prev' href='#' ><p class='sby-screenreader'>Previous Slide</p></a><a class='sby_lb-next' href='#' ><p class='sby-screenreader'>Next Slide</p></a></div><div class='sby_lb-loader'><a class='sby_lb-cancel'></a></div></div></div><div class='sby_lb-dataContainer'><div class='sby_lb-data'><div class='sby_lb-details'><div class='sby_lb-caption'></div><div class='sby_lb-info'><div class='sby_lb-number'></div><div class='sby_lb-closeContainer'><a class='sby_lb-close'></a></div></div></div></div>").appendTo(i("body")),this.$lightbox=i("#sby_lightbox"),this.$overlay=i("#sby_lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".sby_lb-outerContainer"),this.$container=this.$lightbox.find(".sby_lb-container"),this.containerTopPadding=parseInt(this.$container.css("padding-top"),10),this.containerRightPadding=parseInt(this.$container.css("padding-right"),10),this.containerBottomPadding=parseInt(this.$container.css("padding-bottom"),10),this.containerLeftPadding=parseInt(this.$container.css("padding-left"),10),this.$overlay.hide().on("click",function(){return e.end(),!1}),jQuery(document).on("click",function(e,i,t){jQuery(e.target).closest(".sby_lb-outerContainer").length||jQuery(e.target).closest(".sby_lb-dataContainer").length||(void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),jQuery("#sby_lightboxOverlay, #sby_lightbox").fadeOut())}),this.$lightbox.hide(),jQuery("#sby_lightboxOverlay").on("click",function(t){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),"sby_lightbox"===i(t.target).attr("id")&&e.end(),!1}),this.$lightbox.find(".sby_lb-prev").on("click",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(0===e.currentImageIndex?e.album.length-1:e.currentImageIndex-1),!1}),this.$lightbox.find(".sby_lb-container").on("swiperight",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(0===e.currentImageIndex?e.album.length-1:e.currentImageIndex-1),!1}),this.$lightbox.find(".sby_lb-next").on("click",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(e.currentImageIndex===e.album.length-1?0:e.currentImageIndex+1),!1}),this.$lightbox.find(".sby_lb-container").on("swipeleft",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.changeImage(e.currentImageIndex===e.album.length-1?0:e.currentImageIndex+1),!1}),this.$lightbox.find(".sby_lb-loader, .sby_lb-close").on("click",function(){return void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo(),e.end(),!1})},t.prototype.start=function(e){function t(e){s.album.push({link:e.attr("href"),video:e.attr("data-video-id")})}var s=this,a=i(window);a.on("resize",i.proxy(this.sizeOverlay,this)),i("select, object, embed").css({visibility:"hidden"}),this.sizeOverlay(),this.album=[];var n,o=0,d=e.attr("data-sby-lightbox");if(d){n=i(e.prop("tagName")+'[data-sby-lightbox="'+d+'"]');for(var r=0;r<n.length;r=++r)t(i(n[r])),n[r]===e[0]&&(o=r)}else if("lightbox"===e.attr("rel"))t(e);else{n=i(e.prop("tagName")+'[rel="'+e.attr("rel")+'"]');for(var l=0;l<n.length;l=++l)t(i(n[l])),n[l]===e[0]&&(o=l)}var h=a.scrollTop()+this.options.positionFromTop,b=a.scrollLeft();this.$lightbox.css({top:h+"px",left:b+"px"}).fadeIn(this.options.fadeDuration),this.changeImage(o)},t.prototype.changeImage=function(e){var t=this;this.disableKeyboardNav();var s=this.$lightbox.find(".sby_lb-image");this.$overlay.fadeIn(this.options.fadeDuration),i(".sby_lb-loader").fadeIn("slow"),this.$lightbox.find(".sby_lb-image, .sby_lb-nav, .sby_lb-prev, .sby_lb-next, .sby_lb-dataContainer, .sby_lb-numbers, .sby_lb-caption").hide(),this.$outerContainer.addClass("animating");var a=new Image;a.onload=function(){var n,o,d,r,l,h;s.attr("src",t.album[e].link),i(a),s.width(a.width),s.height(a.height),t.options.fitImagesInViewport&&(h=i(window).width(),l=i(window).height(),r=h-t.containerLeftPadding-t.containerRightPadding-20,d=l-t.containerTopPadding-t.containerBottomPadding-150,(a.width>r||a.height>d)&&(a.width/r>a.height/d?(o=r,n=parseInt(a.height/(a.width/o),10),s.width(o),s.height(n)):(n=d,o=parseInt(a.width/(a.height/n),10),s.width(o),s.height(n)))),t.sizeContainer(s.width(),s.height())},a.src=this.album[e].link,this.currentImageIndex=e},t.prototype.sizeOverlay=function(){this.$overlay.width(i(window).width()).height(i(document).height())},t.prototype.sizeContainer=function(e,i){function t(){s.$lightbox.find(".sby_lb-dataContainer").width(o),s.$lightbox.find(".sby_lb-prevLink").height(d),s.$lightbox.find(".sby_lb-nextLink").height(d),s.showImage()}var s=this,a=this.$outerContainer.outerWidth(),n=this.$outerContainer.outerHeight(),o=e+this.containerLeftPadding+this.containerRightPadding,d=i+this.containerTopPadding+this.containerBottomPadding;a!==o||n!==d?this.$outerContainer.animate({width:o,height:d},this.options.resizeDuration,"swing",function(){t()}):t()},t.prototype.showImage=function(){this.$lightbox.find(".sby_lb-loader").hide(),this.$lightbox.find(".sby_lb-image").fadeIn("slow"),this.updateNav(),this.updateDetails(),this.preloadNeighboringImages(),this.enableKeyboardNav()},t.prototype.updateNav=function(){var e=!1;try{document.createEvent("TouchEvent"),e=!!this.options.alwaysShowNavOnTouchDevices}catch(e){}this.$lightbox.find(".sby_lb-nav").show(),this.album.length>1&&(this.options.wrapAround?(e&&this.$lightbox.find(".sby_lb-prev, .sby_lb-next").css("opacity","1"),this.$lightbox.find(".sby_lb-prev, .sby_lb-next").show()):(this.currentImageIndex>0&&(this.$lightbox.find(".sby_lb-prev").show(),e&&this.$lightbox.find(".sby_lb-prev").css("opacity","1")),this.currentImageIndex<this.album.length-1&&(this.$lightbox.find(".sby_lb-next").show(),e&&this.$lightbox.find(".sby_lb-next").css("opacity","1"))))},t.prototype.updateDetails=function(){if(sby_supports_video()&&(jQuery("#sby_lightbox").removeClass("sby_video_lightbox"),this.album[this.currentImageIndex].video.length)){jQuery("#sby_lightbox").addClass("sby_video_lightbox");var e=this.album[this.currentImageIndex].video,i=sbyOptions.autoplay;if(void 0===window.sbyLightboxPlayer){var t={host:window.location.protocol+"//www.youtube-nocookie.com",videoId:e,playerVars:{modestbranding:1,rel:0,autoplay:i}};window.sbyLightboxPlayer=new window.YT.Player("sby_lb-player",t)}else window.sbyLightboxPlayer.loadVideoById(e)}},t.prototype.preloadNeighboringImages=function(){this.album.length>this.currentImageIndex+1&&((new Image).src=this.album[this.currentImageIndex+1].link);this.currentImageIndex>0&&((new Image).src=this.album[this.currentImageIndex-1].link)},t.prototype.enableKeyboardNav=function(){i(document).on("keyup.keyboard",i.proxy(this.keyboardAction,this))},t.prototype.disableKeyboardNav=function(){i(document).off(".keyboard")},t.prototype.keyboardAction=function(i){var t=event.keyCode,s=String.fromCharCode(t).toLowerCase();27===t||s.match(/x|o|c/)?(sby_supports_video()&&e("#sby_lightbox video.sby_video")[0].pause(),e("#sby_lightbox iframe").attr("src",""),this.end()):"p"===s||37===t?(0!==this.currentImageIndex?this.changeImage(this.currentImageIndex-1):this.options.wrapAround&&this.album.length>1&&this.changeImage(this.album.length-1),sby_supports_video()&&e("#sby_lightbox video.sby_video")[0].pause(),e("#sby_lightbox iframe").attr("src","")):"n"!==s&&39!==t||(this.currentImageIndex!==this.album.length-1?this.changeImage(this.currentImageIndex+1):this.options.wrapAround&&this.album.length>1&&this.changeImage(0),void 0!==window.sbyLightboxPlayer&&window.sbyLightboxPlayer.pauseVideo())},t.prototype.end=function(){this.disableKeyboardNav(),i(window).off("resize",this.sizeOverlay),this.$lightbox.fadeOut(this.options.fadeDuration),this.$overlay.fadeOut(this.options.fadeDuration),i("select, object, embed").css({visibility:"visible"})},t}();i(function(){var i=new t;new s(i),e(".sby_lightbox_action a").unbind().bind("click",function(){e(this).parent().find(".sby_lightbox_tooltip").toggle()})})}).call(this)},createFeeds:function(i){window.sby.createLightbox(),i.whenFeedsCreated(e(".sb_youtube").each(function(i){e(this).attr("data-sby-index",i+1),e(this).find(".sby_player").replaceWith('<div id="sby_player'+i+'"></div>');var a=e(this),n=void 0!==a.attr("data-sby-flags")?a.attr("data-sby-flags").split(","):[],o=void 0!==a.attr("data-options")?JSON.parse(a.attr("data-options")):{};if(n.indexOf("testAjax")>-1){window.sby.triggeredTest=!0;s({action:"sby_on_ajax_test_trigger"},function(e){console.log("did test")})}var d={cols:a.attr("data-cols"),colsmobile:"same"!==a.attr("data-colsmobile")?a.attr("data-colsmobile"):a.attr("data-cols"),num:a.attr("data-num"),imgRes:a.attr("data-res"),feedID:a.attr("data-feedid"),shortCodeAtts:a.attr("data-shortcode-atts"),resizingEnabled:-1===n.indexOf("resizeDisable"),imageLoadEnabled:-1===n.indexOf("imageLoadDisable"),debugEnabled:n.indexOf("debug")>-1,favorLocal:n.indexOf("favorLocal")>-1,ajaxPostLoad:n.indexOf("ajaxPostLoad")>-1,checkWPPosts:n.indexOf("checkWPPosts")>-1,cacheAll:n.indexOf("cacheAll")>-1,lightboxEnabled:void 0!==a.attr("data-sby-supports-lightbox"),autoMinRes:1,general:o};window.sby.feeds[i]=function(e,i,s){return new t(e,i,s)}(this,i,d),window.sby.feeds[i].setResizedImages(),window.sby.feeds[i].init();var r=jQuery.Event("sbyafterfeedcreate");r.feed=window.sby.feeds[i],jQuery(window).trigger(r)}))},afterFeedsCreated:function(){e(".sb_instagram_header").each(function(){var i=e(this);i.find(".sby_header_link").hover(function(){i.find(".sby_header_img_hover").addClass("sby_fade_in")},function(){i.find(".sby_header_img_hover").removeClass("sby_fade_in")})})},encodeHTML:function(e){return void 0===e?"":e.replace(/(>)/g,"&gt;").replace(/(<)/g,"&lt;").replace(/(&lt;br\/&gt;)/g,"<br>").replace(/(&lt;br&gt;)/g,"<br>")},urlDetect:function(e){return e.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/g)}},t.prototype={init:function(){var e=this;this.settings.ajaxPostLoad?this.getNewPostSet():this.afterInitialImagesLoaded();var i,t=(i=0,function(e,t){clearTimeout(i),i=setTimeout(e,t)});jQuery(window).resize(function(){t(function(){e.afterResize()},500)})},initLayout:function(){var i=e(this.el),t=this;i.hasClass("sby_layout_gallery")&&i.find(".sby_player_outer_wrap").length&&(this.maybeRaiseSingleImageResolution(i.find(".sby_player_outer_wrap"),0,!0),i.find(".sby_player_outer_wrap .sby_video_thumbnail").off().click(function(i){i.preventDefault(),t.onThumbnailClick(e(this),!0)}),i.mouseenter(function(){t.canCreatePlayer()&&(i.find(".sby_player_outer_wrap iframe").length||(i.addClass("sby_player_added").find(".sby_player_outer_wrap").addClass("sby_player_loading"),i.find(".sby_player_outer_wrap .sby_video_thumbnail").find(".sby_loader").show().removeClass("sby_hidden"),t.createPlayer("sby_player"+t.index)))}))},createPlayer:function(i,t,s,a){var n=e(this.el),o=this;t=void 0!==t?t:this.getVideoID(n.find(".sby_item").first()),s=void 0!==s?s:0,void 0===a&&(a={host:window.location.protocol+"//www.youtube-nocookie.com",videoId:t,playerVars:{modestbranding:1,rel:0,autoplay:s}}),void 0===a.events&&(a.events={onReady:function(){n.find(".sby_player_outer_wrap").removeClass("sby_player_loading").find(".sby_video_thumbnail").css("z-index",-1).find(".sby_loader").hide().addClass("sby_hidden"),e("#"+i).length&&e("#"+i).closest(".sby_video_thumbnail_wrap").find(".sby_video_thumbnail").length&&e("#"+i).closest(".sby_video_thumbnail_wrap").find(".sby_video_thumbnail").fadeTo(0,"slow",function(){e(this).css("z-index",-1),e(this).find(".sby_loader").hide().addClass("sby_hidden"),e(this).closest(".sby_item").removeClass("sby_player_loading")})},onStateChange:function(i){1===i.data&&void 0!==o.players&&n.find(".sby_item").each(function(){var i=o.getVideoID(e(this));t!==i&&void 0!==o.players[i]&&o.players[i].pauseVideo()})}});var d=new window.YT.Player(i,a);return n.hasClass("sby_layout_list")&&void 0===this.players[t]?this.players[t]=d:void 0===this.player&&(this.player=d),d},afterInitialImagesLoaded:function(){this.initLayout(),this.loadMoreButtonInit(),this.hideExtraItemsForWidth(),this.beforeNewImagesRevealed(),this.revealNewImages(),this.afterNewImagesRevealed()},afterResize:function(){this.setImageHeight(),this.setImageResolution(),this.maybeRaiseImageResolution(),this.setImageSizeClass()},afterLoadMoreClicked:function(e){e.find(".sby_loader").removeClass("sby_hidden"),e.find(".sby_btn_text").addClass("sby_hidden"),e.closest(".sb_youtube").find(".sby_num_diff_hide").addClass("sby_transition").removeClass("sby_num_diff_hide")},afterNewImagesLoaded:function(){var i=e(this.el),t=this;this.beforeNewImagesRevealed(),this.revealNewImages(),this.afterNewImagesRevealed(),setTimeout(function(){i.find(".sby_loader").addClass("sby_hidden"),i.find(".sby_btn_text").removeClass("sby_hidden"),t.maybeRaiseImageResolution()},500)},beforeNewImagesRevealed:function(){this.setImageHeight(),this.maybeRaiseImageResolution(!0),this.setImageSizeClass()},revealNewImages:function(){var i=e(this.el),t=this;"function"==typeof sbyCustomJS&&setTimeout(function(){sbyCustomJS()},100),i.find(".sby_item").each(function(i){var s=jQuery(this);s.find(".sby_video_thumbnail").hover(function(){jQuery(this).fadeTo(200,.85)},function(){jQuery(this).stop().fadeTo(500,1)}),s.find(".sby_video_thumbnail").off().click(function(i){i.preventDefault(),t.onThumbnailClick(e(this),!1)}),s.find(".sby_video_thumbnail").mouseenter(function(){t.onThumbnailEnter(e(this),!1)}),s.find(".sby_player_wrap").mouseleave(function(){t.onThumbnailLeave(e(this),!1)}),t.settings.lightboxEnabled&&(s.find(".sby_video_thumbnail").attr("data-sby-lightbox",t.index),"undefined"!=typeof sbyOptions&&void 0!==sbyOptions.lightboxPlaceholder&&s.find(".sby_video_thumbnail").attr("href",sbyOptions.lightboxPlaceholder))}),setTimeout(function(){i.find(".sby_item.sby_new").removeClass("sby_new");var e=10;i.find(".sby_transition").length;i.find(".sby_transition").each(function(i){var t=jQuery(this);setTimeout(function(){t.removeClass("sby_transition")},e),e+=10})},500)},afterNewImagesRevealed:function(){this.listenForVisibilityChange(),this.sendNeedsResizingToServer(),this.sendCheckWPPostsToServer(),this.settings.imageLoadEnabled||e(".sby_no_resraise").removeClass("sby_no_resraise");var i=e.Event("sbyafterimagesloaded");i.el=e(this.el),e(window).trigger(i)},setResizedImages:function(){e(this.el).find(".sby_resized_image_data").length&&void 0!==e(this.el).find(".sby_resized_image_data").attr("data-resized")&&0===e(this.el).find(".sby_resized_image_data").attr("data-resized").indexOf('{"')&&(this.resizedImages=JSON.parse(e(this.el).find(".sby_resized_image_data").attr("data-resized")),e(this.el).find(".sby_resized_image_data").remove())},sendNeedsResizingToServer:function(){var i=this;if(i.needsResizing.length>0&&i.settings.resizingEnabled){var t=e(this.el).find(".sby_item").length;s({action:"sby_resized_images_submit",needs_resizing:i.needsResizing,offset:t,feed_id:i.settings.feedID,atts:i.settings.shortCodeAtts},function(e){if(0===e.trim().indexOf("{")){var t=JSON.parse(e);i.settings.debugEnabled&&console.log(t)}})}},sendCheckWPPostsToServer:function(){var i=this;if(i.settings.checkWPPosts||i.settings.cacheAll){s({action:"sby_check_wp_submit",feed_id:i.settings.feedID,atts:i.settings.shortCodeAtts,offset:e(this.el).find(".sby_item").length,cache_all:i.settings.cacheAll},function(e){if(0===e.trim().indexOf("{")){var t=JSON.parse(e);i.settings.debugEnabled&&console.log(t)}})}},loadMoreButtonInit:function(){var i=e(this.el),t=this;i.find(".sby_footer .sby_load_btn").off().on("click",function(){t.afterLoadMoreClicked(jQuery(this)),t.getNewPostSet()})},getNewPostSet:function(){var i=e(this.el),t=this;s({action:"sby_load_more_clicked",offset:i.find(".sby_item").length,feed_id:t.settings.feedID,atts:t.settings.shortCodeAtts,current_resolution:t.imageResolution},function(s){if(0===s.trim().indexOf("{")){var a=JSON.parse(s);t.settings.debugEnabled&&console.log(a),void 0!==a.feedStatus.cacheAll&&a.feedStatus.cacheAll?t.settings.cacheAll=!0:t.settings.cacheAll=!1,void 0!==a.feedStatus.checkWPPosts&&a.feedStatus.checkWPPosts?t.settings.checkWPPosts=!0:t.settings.checkWPPosts=!1,t.appendNewPosts(a.html),t.addResizedImages(a.resizedImages),t.settings.ajaxPostLoad?(t.settings.ajaxPostLoad=!1,t.afterInitialImagesLoaded()):t.afterNewImagesLoaded(),a.feedStatus.shouldPaginate?t.outOfPages=!1:(t.outOfPages=!0,i.find(".sby_load_btn").hide()),e(".sby_no_js").removeClass("sby_no_js")}})},appendNewPosts:function(i){var t=e(this.el);t.find(".sby_items_wrap .sby_item").length?t.find(".sby_items_wrap .sby_item").last().after(i):t.find(".sby_items_wrap").append(i)},addResizedImages:function(e){for(var i in e)this.resizedImages[i]=e[i]},setImageHeight:function(){},maybeRaiseSingleImageResolution:function(i,t,s){var a=this,n=a.getImageUrls(i),o=i.find(".sby_video_thumbnail img").attr("src"),d=150;s=void 0!==s&&s;if(!i.hasClass("sby_no_resraise")){e.each(n,function(e,i){i===o&&(d=parseInt(e),s=!1)});var r=640;switch(a.settings.imgRes){case"thumb":r=120;break;case"medium":r=320;break;case"large":r=480;break;case"full":r=640;break;default:var l=Math.max(a.settings.autoMinRes,i.find(".sby_video_thumbnail").innerWidth());switch(a.getBestResolutionForAuto(l,1,e(this.el).find("sby_item").first())){case 480:r=480;break;case 320:r=320;break;case 120:r=120}}if(r>d||o===window.sby.options.placeholder||s){if(a.settings.debugEnabled){var h=o===window.sby.options.placeholder?"was placeholder":"too small";console.log("rais res for "+o,h)}var b=n[r];i.find(".sby_video_thumbnail img").attr("src",b)}i.find("img").on("error",function(){if(e(this).hasClass("sby_img_error"))console.log("unfixed error "+e(this).attr("src"));else{if(e(this).addClass("sby_img_error"),e(this).attr("src").indexOf("i.ytimg.com")>-1)a.settings.favorLocal=!0,a.getImageUrls(e(this).closest(".sby_item"))[640];else void 0!==e(this).closest(".sby_video_thumbnail").attr("data-full-res")||e(this).closest(".sby_video_thumbnail").attr("href");setTimeout(function(){a.afterResize()},1500)}})}},maybeRaiseImageResolution:function(i){var t=this,s=void 0!==i&&!0===i?".sby_item.sby_new":".sby_item",a=!t.isInitialized;e(t.el).find(s).each(function(i){!e(this).hasClass("sby_num_diff_hide")&&e(this).find(".sby_video_thumbnail").length&&void 0!==e(this).find(".sby_video_thumbnail").attr("data-img-src-set")&&t.maybeRaiseSingleImageResolution(e(this),i,a)}),t.isInitialized=!0},getBestResolutionForAuto:function(i,t,s){(isNaN(t)||t<1)&&(t=1);var a=i*t,n=10*Math.ceil(a/10),o=[120,320,480,640];if(s.hasClass("sby_highlighted")&&(n*=2),-1===o.indexOf(parseInt(n))){var d=!1;e.each(o,function(e,i){i>parseInt(n)&&!d&&(n=i,d=!0)})}return n},hideExtraItemsForWidth:function(){if("carousel"!==this.layout){var i=e(this.el),t=void 0!==i.attr("data-num")&&""!==i.attr("data-num")?parseInt(i.attr("data-num")):1,s=void 0!==i.attr("data-nummobile")&&""!==i.attr("data-nummobile")?parseInt(i.attr("data-nummobile")):t;e(window).width()<480?s<i.find(".sby_item").length&&i.find(".sby_item").slice(s-i.find(".sby_item").length).addClass("sby_num_diff_hide"):t<i.find(".sby_item").length&&i.find(".sby_item").slice(t-i.find(".sby_item").length).addClass("sby_num_diff_hide")}},setImageSizeClass:function(){var i=e(this.el);i.removeClass("sby_small sby_medium");var t=i.innerWidth(),s=parseInt(i.find(".sby_items_wrap").outerWidth()-i.find(".sby_items_wrap").width())/2,a=this.getColumnCount(),n=(t-s*(a+2))/a;n>120&&n<240?i.addClass("sby_medium"):n<=120&&i.addClass("sby_small")},setMinImageWidth:function(){e(this.el).find(".sby_item .sby_video_thumbnail").first().length?this.minImageWidth=e(this.el).find(".sby_item .sby_video_thumbnail").first().innerWidth():this.minImageWidth=150},setImageResolution:function(){if("auto"===this.settings.imgRes)this.imageResolution="auto";else switch(this.settings.imgRes){case"thumb":this.imageResolution=150;break;case"medium":this.imageResolution=320;break;default:this.imageResolution=640}},getImageUrls:function(e){var i=JSON.parse(e.find(".sby_video_thumbnail").attr("data-img-src-set").replace(/\\\//g,"/")),t=e.attr("id").replace("sby_","").replace("player_","");if(void 0!==this.resizedImages[t]&&"video"!==this.resizedImages[t]&&"pending"!==this.resizedImages[t]&&"error"!==this.resizedImages[t].id&&"video"!==this.resizedImages[t].id&&"pending"!==this.resizedImages[t].id){if(void 0!==this.resizedImages[t].sizes){var s=[];void 0!==this.resizedImages[t].sizes.full&&(s.push(640),i[640]=sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg",e.find(".sby_link_area").attr("href",sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg"),e.find(".sby_video_thumbnail").attr("data-full-res",sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg")),void 0!==this.resizedImages[t].sizes.low&&(s.push(320),i[320]=sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg",this.settings.favorLocal&&void 0===this.resizedImages[t].sizes.full&&(e.find(".sby_link_area").attr("href",sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg"),e.find(".sby_video_thumbnail").attr("data-full-res",sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg"))),void 0!==this.resizedImages[t].sizes.thumb&&(s.push(150),i[150]=sbyOptions.resized_url+this.resizedImages[t].id+"thumb.jpg"),this.settings.favorLocal&&(-1===s.indexOf(640)&&s.indexOf(320)>-1&&(i[640]=sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg"),-1===s.indexOf(320)&&(s.indexOf(640)>-1?i[320]=sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg":s.indexOf(150)>-1&&(i[320]=sbyOptions.resized_url+this.resizedImages[t].id+"thumb.jpg")),-1===s.indexOf(150)&&(s.indexOf(320)>-1?i[150]=sbyOptions.resized_url+this.resizedImages[t].id+"low.jpg":s.indexOf(640)>-1&&(i[150]=sbyOptions.resized_url+this.resizedImages[t].id+"full.jpg")))}}else(void 0===this.resizedImages[t]||void 0!==this.resizedImages[t].id&&"pending"!==this.resizedImages[t].id&&"error"!==this.resizedImages[t].id)&&this.addToNeedsResizing(t);return i},getVideoID:function(e){if(e.hasClass("sby_item")||e.hasClass("sby_player_item")){if(void 0!==e.find(".sby_video_thumbnail").attr("data-video-id"))return e.find(".sby_video_thumbnail").attr("data-video-id")}else if(e.closest("sby_item").length||e.closest("sby_player_item").length){var i=e.closest("sby_item").length?e.closest("sby_item"):e.closest("sby_player_item");if(void 0!==i.find(".sby_video_thumbnail").attr("data-video-id"))return i.find(".sby_video_thumbnail").attr("data-video-id")}else if(e.hasClass("sb_youtube"))return e.find(".sby_item").first().find(".sby_video_thumbnail").attr("data-video-id");return console.log("no id"),""},getAvatarUrl:function(e,i){if(""===e)return"";var t=this.settings.general.avatars;return"local"===(i=void 0!==i?i:"local")?void 0!==t["LCL"+e]&&1===parseInt(t["LCL"+e])?sbyOptions.resized_url+e+".jpg":void 0!==t[e]?t[e]:"":void 0!==t[e]?t[e]:void 0!==t["LCL"+e]&&1===parseInt(t["LCL"+e])?sbyOptions.resized_url+e+".jpg":""},addToNeedsResizing:function(e){-1===this.needsResizing.indexOf(e)&&this.needsResizing.push(e)},listenForVisibilityChange:function(){var i,t,s,a=this;i=jQuery,t={callback:function(){},runOnLoad:!0,frequency:100,sbyPreviousVisibility:null},s={sbyCheckVisibility:function(e,i){if(jQuery.contains(document,e[0])){var t=i.sbyPreviousVisibility,a=e.is(":visible");i.sbyPreviousVisibility=a,null==t?i.runOnLoad&&i.callback(e,a):t!==a&&i.callback(e,a),setTimeout(function(){s.sbyCheckVisibility(e,i)},i.frequency)}}},i.fn.sbyVisibilityChanged=function(e){var a=i.extend({},t,e);return this.each(function(){s.sbyCheckVisibility(i(this),a)})},"function"==typeof e(this.el).filter(":hidden").sbyVisibilityChanged&&e(this.el).filter(":hidden").sbyVisibilityChanged({callback:function(e,i){a.afterResize()},runOnLoad:!1})},getColumnCount:function(){var i=e(this.el),t=this.settings.cols,s=this.settings.colsmobile,a=t;return sbyWindowWidth=window.innerWidth,i.hasClass("sby_mob_col_auto")?(sbyWindowWidth<640&&parseInt(t)>2&&parseInt(t)<7&&(a=2),sbyWindowWidth<640&&parseInt(t)>6&&parseInt(t)<11&&(a=4),sbyWindowWidth<=480&&parseInt(t)>2&&(a=1)):sbyWindowWidth<=480&&(a=s),parseInt(a)},onThumbnailClick:function(i,t){if(this.canCreatePlayer()){var s=e(this.el);if(s.hasClass("sby_layout_gallery"))s.addClass("sby_player_added").find(".sby_player_outer_wrap").addClass("sby_player_loading"),s.find(".sby_player_outer_wrap .sby_video_thumbnail").find(".sby_loader").show().removeClass("sby_hidden"),s.find(".sby_player_outer_wrap iframe").length?t?this.playVideoInPlayer(this.getVideoID(s.find(".sby_item").first())):(this.playVideoInPlayer(this.getVideoID(i.closest(".sby_item"))),this.afterVideoChanged()):t?this.createPlayer("sby_player"+this.index):this.createPlayer("sby_player"+this.index,this.getVideoID(i.closest(".sby_item")));else if(e(this.el).hasClass("sby_layout_grid")){var a=i.closest(".sby_item"),n=this.getVideoID(a);this.playVideoInPlayer(n),this.afterVideoChanged()}else if(e(this.el).hasClass("sby_layout_list")){a=i.closest(".sby_item"),n=this.getVideoID(a);a.find("iframe").length||(a.find(".sby_loader").show().removeClass("sby_hidden"),a.addClass("sby_player_loading sby_player_loaded"),this.createPlayer("sby_player_"+n,n))}}},onThumbnailEnter:function(i){if(this.canCreatePlayer()&&e(this.el).hasClass("sby_layout_list")){var t=i.closest(".sby_item"),s=this.getVideoID(t);t.find("iframe").length||(t.find(".sby_loader").show().removeClass("sby_hidden"),t.addClass("sby_player_loading sby_player_loaded"),this.createPlayer("sby_player_"+s,s,0))}},onThumbnailLeave:function(e){},canCreatePlayer:function(){return this.playerAPIReady&&this.consentGiven},playVideoInPlayer:function(e){void 0!==this.player&&void 0!==this.player.loadVideoById&&this.player.loadVideoById(e)},afterVideoChanged:function(){e(this.el).hasClass("sby_layout_gallery")&&(e(this.el).find(".sby_player_outer_wrap").removeClass("sby_player_loading"),e(this.el).find(".sby_player_outer_wrap .sby_video_thumbnail").find(".sby_loader").hide().addClass("sby_hidden"),e(window).width()<480&&e("html, body").animate({scrollTop:e(this.el).find(".sby_player_outer_wrap").offset().top},300))}},window.sby_init=function(){window.sby=new i,window.sby.createPage(window.sby.createFeeds,{whenFeedsCreated:window.sby.afterFeedsCreated})}}(jQuery),jQuery(document).ready(function(e){sby_init()})}window.onYouTubeIframeAPIReady=function(){var e=document.getElementsByClassName("sb_youtube").length;if(e>0)for(var i=0;i<e;i++)window.sby.feeds[i].playerAPIReady=!0};
uninstall.php CHANGED
@@ -16,6 +16,8 @@ if ( ! $sby_preserve_settings ) {
16
 
17
  // clean up options from the database
18
  delete_option( 'sby_settings' );
 
 
19
  delete_option( 'sby_cron_report' );
20
  delete_option( 'sby_errors' );
21
  delete_option( 'sby_ajax_status' );
@@ -46,6 +48,11 @@ if ( ! $sby_preserve_settings ) {
46
  $wpdb->query( "
47
  DELETE
48
  FROM $table_name
 
 
 
 
 
49
  WHERE `option_name` LIKE ('%\_transient\_sby\_%')
50
  " );
51
  $wpdb->query( "
16
 
17
  // clean up options from the database
18
  delete_option( 'sby_settings' );
19
+ delete_option( 'sby_channel_ids' );
20
+ delete_option( 'sby_channel_status' );
21
  delete_option( 'sby_cron_report' );
22
  delete_option( 'sby_errors' );
23
  delete_option( 'sby_ajax_status' );
48
  $wpdb->query( "
49
  DELETE
50
  FROM $table_name
51
+ WHERE `option_name` LIKE ('%\~sby\_%')
52
+ " );
53
+ $wpdb->query( "
54
+ DELETE
55
+ FROM $table_name
56
  WHERE `option_name` LIKE ('%\_transient\_sby\_%')
57
  " );
58
  $wpdb->query( "
youtube-feed.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Feeds for YouTube
4
  Plugin URI: http://smashballoon.com/youtube-feed
5
  Description: The Feeds for YouTube plugin allows you to display completely customizable YouTube feeds from any channel.
6
- Version: 1.0.1
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  Text Domain: feeds-for-youtube
@@ -26,10 +26,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
27
 
28
  if ( ! defined( 'SBYVER' ) ) {
29
- define( 'SBYVER', '1.0.1' );
30
  }
31
  if ( ! defined( 'SBY_DBVERSION' ) ) {
32
- define( 'SBY_DBVERSION', 1.2 );
33
  }
34
  // Upload folder name for local image files for posts
35
  if ( ! defined( 'SBY_UPLOADS_NAME' ) ) {
@@ -130,6 +130,7 @@ if ( function_exists( 'sby_init' ) ) {
130
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-feed.php';
131
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-parse.php';
132
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-posts-manager.php';
 
133
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-settings.php';
134
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-wp-post.php';
135
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/widget.php';
@@ -213,6 +214,8 @@ if ( function_exists( 'sby_init' ) ) {
213
  $sby_settings = get_option( 'sby_settings', array() );
214
  if ( isset( $sby_settings['caching_type'] ) && $sby_settings['caching_type'] === 'background' ) {
215
  require_once trailingslashit( plugin_dir_path( __FILE__ ) ) . 'inc/class-sby-cron-update.php';
 
 
216
  SBY_Cron_Updater::start_cron_job( $sby_settings['cache_cron_interval'], $sby_settings['cache_cron_time'], $sby_settings['cache_cron_am_pm'] );
217
  }
218
 
@@ -305,13 +308,6 @@ if ( function_exists( 'sby_init' ) ) {
305
  update_option( 'sby_db_version', SBY_DBVERSION );
306
  }
307
 
308
- if ( (float) $db_ver < 1.2 ) {
309
- $options = get_option( 'sby_settings', false );
310
- sby_reset_cron( $options );
311
-
312
- update_option( 'sby_db_version', SBY_DBVERSION );
313
- }
314
-
315
  }
316
  add_action( 'wp_loaded', 'sby_check_for_db_updates' );
317
 
3
  Plugin Name: Feeds for YouTube
4
  Plugin URI: http://smashballoon.com/youtube-feed
5
  Description: The Feeds for YouTube plugin allows you to display completely customizable YouTube feeds from any channel.
6
+ Version: 1.0.2
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  Text Domain: feeds-for-youtube
26
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
27
 
28
  if ( ! defined( 'SBYVER' ) ) {
29
+ define( 'SBYVER', '1.0.2' );
30
  }
31
  if ( ! defined( 'SBY_DBVERSION' ) ) {
32
+ define( 'SBY_DBVERSION', 1.1 );
33
  }
34
  // Upload folder name for local image files for posts
35
  if ( ! defined( 'SBY_UPLOADS_NAME' ) ) {
130
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-feed.php';
131
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-parse.php';
132
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-posts-manager.php';
133
+ require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-rss-connect.php';
134
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-settings.php';
135
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/class-sby-wp-post.php';
136
  require_once trailingslashit( SBY_PLUGIN_DIR ) . 'inc/widget.php';
214
  $sby_settings = get_option( 'sby_settings', array() );
215
  if ( isset( $sby_settings['caching_type'] ) && $sby_settings['caching_type'] === 'background' ) {
216
  require_once trailingslashit( plugin_dir_path( __FILE__ ) ) . 'inc/class-sby-cron-update.php';
217
+ require_once trailingslashit( plugin_dir_path( __FILE__ ) ) . 'inc/sby-functions.php';
218
+
219
  SBY_Cron_Updater::start_cron_job( $sby_settings['cache_cron_interval'], $sby_settings['cache_cron_time'], $sby_settings['cache_cron_am_pm'] );
220
  }
221
 
308
  update_option( 'sby_db_version', SBY_DBVERSION );
309
  }
310
 
 
 
 
 
 
 
 
311
  }
312
  add_action( 'wp_loaded', 'sby_check_for_db_updates' );
313