Instagram Feed - Version 2.9.7

Version Description

  • Tweak: A prompt will now be displayed if the ability to save settings requires a page refresh.
  • Fix: Fixed several accessibility issues in the admin area.
  • Fix: Made a significant number of code quality improvements.
Download this release

Release Info

Developer smashballoon
Plugin Icon 128x128 Instagram Feed
Version 2.9.7
Comparing to
See all releases

Code changes from version 2.9.6 to 2.9.7

Files changed (40) hide show
  1. README.txt +6 -1
  2. css/admin-notifications.css +1 -1
  3. css/sb-instagram-2-2.css +28 -43
  4. css/sb-instagram-admin.css +15 -51
  5. css/sbi-styles.css +27 -41
  6. inc/admin/PluginSilentUpgrader.php +8 -19
  7. inc/admin/actions.php +433 -418
  8. inc/admin/addon-functions.php +12 -5
  9. inc/admin/blocks/class-sbi-blocks.php +13 -13
  10. inc/admin/class-sbi-about.php +63 -82
  11. inc/admin/class-sbi-account-connector.php +56 -47
  12. inc/admin/class-sbi-new-user.php +79 -50
  13. inc/admin/class-sbi-notifications.php +32 -38
  14. inc/admin/class-sbi-sitehealth.php +6 -8
  15. inc/admin/class-sbi-tracking.php +88 -76
  16. inc/admin/main.php +2288 -1809
  17. inc/admin/templates/locator-summary.php +78 -72
  18. inc/class-sb-instagram-api-connect.php +19 -16
  19. inc/class-sb-instagram-connected-account.php +23 -33
  20. inc/class-sb-instagram-cron-updater.php +41 -36
  21. inc/class-sb-instagram-data-manager.php +90 -57
  22. inc/class-sb-instagram-display-elements.php +90 -43
  23. inc/class-sb-instagram-education.php +30 -27
  24. inc/class-sb-instagram-feed-locator.php +123 -74
  25. inc/class-sb-instagram-feed.php +194 -182
  26. inc/class-sb-instagram-gdpr-integrations.php +16 -15
  27. inc/class-sb-instagram-oembed.php +29 -22
  28. inc/class-sb-instagram-parse.php +32 -33
  29. inc/class-sb-instagram-post-set.php +24 -13
  30. inc/class-sb-instagram-post.php +107 -87
  31. inc/class-sb-instagram-posts-manager.php +119 -121
  32. inc/class-sb-instagram-settings.php +386 -372
  33. inc/class-sb-instagram-single.php +29 -24
  34. inc/class-sb-instagram-token-refresher.php +19 -20
  35. inc/email.php +8 -8
  36. inc/if-functions.php +470 -425
  37. instagram-feed.php +8 -8
  38. js/sb-blocks.js +0 -1
  39. js/sb-instagram-2-2.js +9 -19
  40. js/sb-instagram-admin-2-2.js +1039 -840
README.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: smashballoon, craig-at-smash-balloon
3
  Tags: Instagram, Instagram feed, Instagram photos, Instagram widget, Instagram gallery
4
  Requires at least: 3.4
5
  Tested up to: 5.8
6
- Stable tag: 2.9.6
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -331,6 +331,11 @@ We understand that sometimes you need help, have issues or just have questions.
331
  * Plus more customization options added all the time!
332
 
333
  == Changelog ==
 
 
 
 
 
334
  = 2.9.6 =
335
  * Fix: Periods and underscores in usernames when used as part of the shortcode would cause the load more button not to work.
336
  * Tweak: The WooCommerce orders post type will no longer be scanned for oembeds.
3
  Tags: Instagram, Instagram feed, Instagram photos, Instagram widget, Instagram gallery
4
  Requires at least: 3.4
5
  Tested up to: 5.8
6
+ Stable tag: 2.9.7
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
331
  * Plus more customization options added all the time!
332
 
333
  == Changelog ==
334
+ = 2.9.7 =
335
+ * Tweak: A prompt will now be displayed if the ability to save settings requires a page refresh.
336
+ * Fix: Fixed several accessibility issues in the admin area.
337
+ * Fix: Made a significant number of code quality improvements.
338
+
339
  = 2.9.6 =
340
  * Fix: Periods and underscores in usernames when used as part of the shortcode would cause the load more button not to work.
341
  * Tweak: The WooCommerce orders post type will no longer be scanned for oembeds.
css/admin-notifications.css CHANGED
@@ -1,7 +1,7 @@
1
  #sbi-notifications {
2
  position: relative;
3
  background: #FFFFFF 0 0 no-repeat padding-box;
4
- box-shadow: 0px 5px 15px #0000000D;
5
  border-radius: 6px;
6
  opacity: 1;
7
  min-height: 48px;
1
  #sbi-notifications {
2
  position: relative;
3
  background: #FFFFFF 0 0 no-repeat padding-box;
4
+ box-shadow: 0 5px 15px #0000000D;
5
  border-radius: 6px;
6
  opacity: 1;
7
  min-height: 48px;
css/sb-instagram-2-2.css CHANGED
@@ -348,20 +348,19 @@
348
  }
349
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3 {
350
  font-size: 20px;
 
 
 
351
  }
352
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
353
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
354
  font-size: 14px;
355
  }
356
- #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3,
357
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
358
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
359
  margin-left: 95px !important;
360
  line-height: 1.4
361
  }
362
- #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3{
363
- margin-right: -85px !important;
364
- }
365
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info{
366
  margin-top: 4px !important;
367
  }
@@ -381,20 +380,19 @@
381
  }
382
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3 {
383
  font-size: 28px;
 
 
 
384
  }
385
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
386
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
387
  font-size: 16px;
388
  }
389
- #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3,
390
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
391
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
392
  margin-left: 140px !important;
393
  line-height: 1.5;
394
  }
395
- #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3{
396
- margin-right: -120px !important;
397
- }
398
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info{
399
  margin-top: 12px !important;
400
  }
@@ -427,17 +425,6 @@
427
  }
428
  /* Profile pic hover */
429
  /* Profile pic hover */
430
- #sb_instagram .sb_instagram_header .sbi_header_img_hover{
431
- opacity: 0;
432
- position: absolute;
433
- width: 100%;
434
- top: 0;
435
- bottom: 0;
436
- left: 0;
437
- text-align: center;
438
- color: #fff;
439
- background: rgba(0,0,0,0.75);
440
- }
441
 
442
  #sb_instagram .sb_instagram_header .sbi_header_img_hover .sbi_new_logo,
443
  #sb_instagram .sb_instagram_header .sbi_header_hashtag_icon .sbi_new_logo{
@@ -471,10 +458,7 @@
471
  overflow: hidden;
472
  background: url('../img/small-logo.png') no-repeat 0 0;
473
  }
474
- #sb_instagram .sb_instagram_header .sbi_header_img_hover{
475
- z-index: 2;
476
- transition: opacity 0.4s ease-in-out;
477
- }
478
  #sb_instagram .sb_instagram_header .sbi_fade_in{
479
  opacity: 1;
480
  transition: opacity 0.2s ease-in-out;
@@ -488,6 +472,7 @@
488
  text-align: center;
489
  color: #fff;
490
  background: rgba(0,0,0,0.75);
 
491
 
492
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
493
  filter: alpha(opacity=0);
@@ -507,9 +492,6 @@
507
  width: 100%;
508
  padding-top: 5px;
509
  }
510
- #sb_instagram .sb_instagram_header a{
511
- text-decoration: none;
512
- }
513
  #sb_instagram .sb_instagram_header .sbi_header_text .sbi_bio,
514
  #sb_instagram .sb_instagram_header .sbi_header_text h3{
515
  float: left;
@@ -548,6 +530,8 @@
548
  clear: both;
549
  width: 100%;
550
  text-align: center;
 
 
551
  }
552
  #sb_instagram #sbi_load .fa-spinner{
553
  display: none;
@@ -557,10 +541,6 @@
557
  margin: -8px 0 0 -7px;
558
  font-size: 15px;
559
  }
560
- #sb_instagram #sbi_load{
561
- opacity: 1;
562
- transition: all 0.5s ease-in;
563
- }
564
  #sb_instagram .sbi_load_btn .sbi_btn_text, #sb_instagram .sbi_load_btn .sbi_loader{
565
  opacity: 1;
566
  transition: all 0.1s ease-in;
@@ -568,8 +548,7 @@
568
  #sb_instagram .sbi_hidden{
569
  opacity: 0 !important;
570
  }
571
- #sb_instagram #sbi_load .sbi_load_btn,
572
- #sb_instagram .sbi_follow_btn a{
573
  display: inline-block;
574
  vertical-align: top;
575
  zoom: 1;
@@ -582,14 +561,25 @@
582
  text-decoration: none;
583
  font-size: 13px;
584
  line-height: 1.5;
585
-
586
- -moz-border-radius: 4px;
587
- -webkit-border-radius: 4px;
588
  border-radius: 4px;
 
 
589
 
590
- -webkit-box-sizing: border-box;
591
- -moz-box-sizing: border-box;
 
 
 
 
 
 
 
 
 
592
  box-sizing: border-box;
 
 
 
593
  }
594
  #sb_instagram #sbi_load .sbi_load_btn {
595
  position: relative;
@@ -605,12 +595,7 @@
605
  display: block;
606
  margin-bottom: 5px;
607
  }
608
- #sb_instagram .sbi_follow_btn a{
609
- background: #408bd1;
610
- color: #fff;
611
- }
612
- #sb_instagram .sbi_follow_btn a,
613
- #sb_instagram .sbi_follow_btn a,
614
  #sb_instagram #sbi_load .sbi_load_btn{
615
  transition: all 0.1s ease-in;
616
  }
348
  }
349
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3 {
350
  font-size: 20px;
351
+ margin-left: 95px !important;
352
+ line-height: 1.4;
353
+ margin-right: -85px !important;
354
  }
355
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
356
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
357
  font-size: 14px;
358
  }
 
359
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
360
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
361
  margin-left: 95px !important;
362
  line-height: 1.4
363
  }
 
 
 
364
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info{
365
  margin-top: 4px !important;
366
  }
380
  }
381
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3 {
382
  font-size: 28px;
383
+ line-height: 1.5;
384
+ margin-left: 140px !important;
385
+ margin-right: -120px !important;
386
  }
387
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
388
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
389
  font-size: 16px;
390
  }
 
391
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
392
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
393
  margin-left: 140px !important;
394
  line-height: 1.5;
395
  }
 
 
 
396
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info{
397
  margin-top: 12px !important;
398
  }
425
  }
426
  /* Profile pic hover */
427
  /* Profile pic hover */
 
 
 
 
 
 
 
 
 
 
 
428
 
429
  #sb_instagram .sb_instagram_header .sbi_header_img_hover .sbi_new_logo,
430
  #sb_instagram .sb_instagram_header .sbi_header_hashtag_icon .sbi_new_logo{
458
  overflow: hidden;
459
  background: url('../img/small-logo.png') no-repeat 0 0;
460
  }
461
+
 
 
 
462
  #sb_instagram .sb_instagram_header .sbi_fade_in{
463
  opacity: 1;
464
  transition: opacity 0.2s ease-in-out;
472
  text-align: center;
473
  color: #fff;
474
  background: rgba(0,0,0,0.75);
475
+ z-index: 2;
476
 
477
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
478
  filter: alpha(opacity=0);
492
  width: 100%;
493
  padding-top: 5px;
494
  }
 
 
 
495
  #sb_instagram .sb_instagram_header .sbi_header_text .sbi_bio,
496
  #sb_instagram .sb_instagram_header .sbi_header_text h3{
497
  float: left;
530
  clear: both;
531
  width: 100%;
532
  text-align: center;
533
+ opacity: 1;
534
+ transition: all 0.5s ease-in;
535
  }
536
  #sb_instagram #sbi_load .fa-spinner{
537
  display: none;
541
  margin: -8px 0 0 -7px;
542
  font-size: 15px;
543
  }
 
 
 
 
544
  #sb_instagram .sbi_load_btn .sbi_btn_text, #sb_instagram .sbi_load_btn .sbi_loader{
545
  opacity: 1;
546
  transition: all 0.1s ease-in;
548
  #sb_instagram .sbi_hidden{
549
  opacity: 0 !important;
550
  }
551
+ #sb_instagram #sbi_load .sbi_load_btn{
 
552
  display: inline-block;
553
  vertical-align: top;
554
  zoom: 1;
561
  text-decoration: none;
562
  font-size: 13px;
563
  line-height: 1.5;
 
 
 
564
  border-radius: 4px;
565
+ box-sizing: border-box;
566
+ }
567
 
568
+ #sb_instagram .sbi_follow_btn a{
569
+ display: inline-block;
570
+ vertical-align: top;
571
+ zoom: 1;
572
+ padding: 7px 14px;
573
+ margin: 5px auto 0 auto;
574
+ border: none;
575
+ text-decoration: none;
576
+ font-size: 13px;
577
+ line-height: 1.5;
578
+ border-radius: 4px;
579
  box-sizing: border-box;
580
+ background: #408bd1;
581
+ color: #fff;
582
+ transition: all 0.1s ease-in;
583
  }
584
  #sb_instagram #sbi_load .sbi_load_btn {
585
  position: relative;
595
  display: block;
596
  margin-bottom: 5px;
597
  }
598
+
 
 
 
 
 
599
  #sb_instagram #sbi_load .sbi_load_btn{
600
  transition: all 0.1s ease-in;
601
  }
css/sb-instagram-admin.css CHANGED
@@ -26,7 +26,7 @@
26
  font-size: 13px;
27
  }
28
  #sbi_admin .sbi_tooltip ul{
29
- margin-top: 0;
30
  margin-bottom: 0;
31
  }
32
  #sbi_admin .sbi_tooltip li{
@@ -96,7 +96,7 @@
96
  #sbi_admin .sbi-success {
97
  position: relative;
98
  top: -1px;
99
-
100
  background: #68a30b;
101
  color: #fff;
102
  font-size: 13px;
@@ -159,15 +159,22 @@
159
  padding: 5px 15px;
160
  margin: 10px 0 0 0;
161
 
162
- background: #fff;
163
  border: 1px solid #ddd;
164
 
165
  -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
166
  box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
167
 
168
- -moz-border-radius: 2px;
169
- -webkit-border-radius: 2px;
170
  border-radius: 2px;
 
 
 
 
 
 
 
 
 
 
171
  }
172
  /* Caching settings */
173
  #sbi_admin #sbi-caching-time-settings{
@@ -619,7 +626,7 @@
619
  font-size: 13px;
620
  background: #f9f9f9;
621
  background: rgba(255,255,255,0.8);
622
-
623
  -moz-border-radius: 8px;
624
  -webkit-border-radius: 8px;
625
  border-radius: 8px;
@@ -955,9 +962,6 @@
955
  #sbi_admin .sbi_ca_info{
956
  overflow: hidden;
957
  }
958
- #sbi_admin .sbi_ca_show_token .fa {
959
- margin-right: 0;
960
- }
961
  #sbi_admin .sbi_ca_show_token{
962
  display: inline-block;
963
  padding: 10px 5px 0px 5px;
@@ -1039,25 +1043,7 @@
1039
  }
1040
  }
1041
 
1042
- /* Config info */
1043
- #sbi_config{
1044
- float: left;
1045
- width: 100%;
1046
- clear: both;
1047
- margin: 10px 0 10px 0;
1048
- }
1049
- #sbi_config_info{
1050
- box-sizing: border-box;
1051
- position: fixed;
1052
- z-index: 999;
1053
- width: 100%;
1054
- top: 0;
1055
- right: 0;
1056
- bottom: 0;
1057
- left: 0;
1058
 
1059
- background: rgba(0,0,0,0.3);
1060
- }
1061
  #sbi_config_info .sbi_config_modal{
1062
  position: absolute;
1063
  top: 160px;
@@ -1087,11 +1073,6 @@
1087
  #sbi_config_info.sb_get_token .sbi_config_modal {
1088
  text-align: center;
1089
  }
1090
- .sb_get_token .submit {
1091
- display: inline-block;
1092
- margin: 0 0 0 10px;
1093
- padding: 0;
1094
- }
1095
  .sbi_config_modal .sbi_submit{
1096
  clear: both;
1097
  width: 100%;
@@ -1366,7 +1347,7 @@
1366
  position: absolute;
1367
  bottom: 12px;
1368
  left: -8px;
1369
-
1370
  background: #333;
1371
  color: #eee;
1372
  padding: 8px 10px 10px 10px;
@@ -1456,15 +1437,6 @@
1456
  margin-top: -10px;
1457
  }
1458
 
1459
- .sbi_notice .sbi_other_notice{
1460
- padding-top: 10px;
1461
- font-style: italic;
1462
- font-size: 12px;
1463
- }
1464
- .sbi_notice .sbi_other_notice a {
1465
- padding: 0;
1466
- }
1467
-
1468
  .sbi_notice .sbi_offer_btn {
1469
  padding: 4px 12px 6px 12px;
1470
  background: green;
@@ -1564,9 +1536,6 @@
1564
  .sbi_tooltip_under_text {
1565
  padding: 10px 15px !important;
1566
  }
1567
- .sb_instagram_box_setting textarea {
1568
- width: 100%;
1569
- }
1570
  #sbi_admin .sbi_ca_show_token .fa {
1571
  margin-right: 0;
1572
  }
@@ -2008,9 +1977,6 @@
2008
  color: #fff
2009
  }
2010
 
2011
- #sbi-admin-about #sbi-admin-addons .addon-item .action-button .button.button-primary .fa-spinner {
2012
- color: #fff
2013
- }
2014
 
2015
  #sbi-admin-about #sbi-admin-addons .addon-item .action-button .button.button-secondary {
2016
  color: #555;
@@ -2810,7 +2776,6 @@
2810
  Add Source Loading
2811
  */
2812
  #sbi_config_info .sbi_config_modal.sbi-popup-inside {
2813
- width: 880px;
2814
  max-width: calc(100% - 200px);
2815
  background: #fff;
2816
  color: #141B38;
@@ -2820,14 +2785,13 @@
2820
  overflow-y: auto;
2821
  max-height: 80vh;
2822
  padding: 0;
2823
- }
2824
- #sbi_config_info .sbi_config_modal.sbi-popup-inside{
2825
  width: 575px;
2826
  height: 320px;
2827
  display: flex;
2828
  justify-content: center;
2829
  align-items: center;
2830
  }
 
2831
  .sbi-source-redirect-ld{
2832
  text-align: center;
2833
  }
26
  font-size: 13px;
27
  }
28
  #sbi_admin .sbi_tooltip ul{
29
+ margin-top: 0;
30
  margin-bottom: 0;
31
  }
32
  #sbi_admin .sbi_tooltip li{
96
  #sbi_admin .sbi-success {
97
  position: relative;
98
  top: -1px;
99
+
100
  background: #68a30b;
101
  color: #fff;
102
  font-size: 13px;
159
  padding: 5px 15px;
160
  margin: 10px 0 0 0;
161
 
 
162
  border: 1px solid #ddd;
163
 
164
  -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
165
  box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
166
 
 
 
167
  border-radius: 2px;
168
+ box-sizing: border-box;
169
+ position: fixed;
170
+ z-index: 999;
171
+ width: 100%;
172
+ top: 0;
173
+ right: 0;
174
+ bottom: 0;
175
+ left: 0;
176
+
177
+ background: rgba(0,0,0,0.3);
178
  }
179
  /* Caching settings */
180
  #sbi_admin #sbi-caching-time-settings{
626
  font-size: 13px;
627
  background: #f9f9f9;
628
  background: rgba(255,255,255,0.8);
629
+
630
  -moz-border-radius: 8px;
631
  -webkit-border-radius: 8px;
632
  border-radius: 8px;
962
  #sbi_admin .sbi_ca_info{
963
  overflow: hidden;
964
  }
 
 
 
965
  #sbi_admin .sbi_ca_show_token{
966
  display: inline-block;
967
  padding: 10px 5px 0px 5px;
1043
  }
1044
  }
1045
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1046
 
 
 
1047
  #sbi_config_info .sbi_config_modal{
1048
  position: absolute;
1049
  top: 160px;
1073
  #sbi_config_info.sb_get_token .sbi_config_modal {
1074
  text-align: center;
1075
  }
 
 
 
 
 
1076
  .sbi_config_modal .sbi_submit{
1077
  clear: both;
1078
  width: 100%;
1347
  position: absolute;
1348
  bottom: 12px;
1349
  left: -8px;
1350
+
1351
  background: #333;
1352
  color: #eee;
1353
  padding: 8px 10px 10px 10px;
1437
  margin-top: -10px;
1438
  }
1439
 
 
 
 
 
 
 
 
 
 
1440
  .sbi_notice .sbi_offer_btn {
1441
  padding: 4px 12px 6px 12px;
1442
  background: green;
1536
  .sbi_tooltip_under_text {
1537
  padding: 10px 15px !important;
1538
  }
 
 
 
1539
  #sbi_admin .sbi_ca_show_token .fa {
1540
  margin-right: 0;
1541
  }
1977
  color: #fff
1978
  }
1979
 
 
 
 
1980
 
1981
  #sbi-admin-about #sbi-admin-addons .addon-item .action-button .button.button-secondary {
1982
  color: #555;
2776
  Add Source Loading
2777
  */
2778
  #sbi_config_info .sbi_config_modal.sbi-popup-inside {
 
2779
  max-width: calc(100% - 200px);
2780
  background: #fff;
2781
  color: #141B38;
2785
  overflow-y: auto;
2786
  max-height: 80vh;
2787
  padding: 0;
 
 
2788
  width: 575px;
2789
  height: 320px;
2790
  display: flex;
2791
  justify-content: center;
2792
  align-items: center;
2793
  }
2794
+
2795
  .sbi-source-redirect-ld{
2796
  text-align: center;
2797
  }
css/sbi-styles.css CHANGED
@@ -348,20 +348,19 @@
348
  }
349
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3 {
350
  font-size: 20px;
 
 
 
351
  }
352
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
353
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
354
  font-size: 14px;
355
  }
356
- #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3,
357
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
358
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
359
  margin-left: 95px !important;
360
  line-height: 1.4
361
  }
362
- #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3{
363
- margin-right: -85px !important;
364
- }
365
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info{
366
  margin-top: 4px !important;
367
  }
@@ -381,20 +380,19 @@
381
  }
382
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3 {
383
  font-size: 28px;
 
 
 
384
  }
385
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
386
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
387
  font-size: 16px;
388
  }
389
- #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3,
390
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
391
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
392
  margin-left: 140px !important;
393
  line-height: 1.5;
394
  }
395
- #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3{
396
- margin-right: -120px !important;
397
- }
398
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info{
399
  margin-top: 12px !important;
400
  }
@@ -427,18 +425,6 @@
427
  }
428
  /* Profile pic hover */
429
  /* Profile pic hover */
430
- #sb_instagram .sb_instagram_header .sbi_header_img_hover{
431
- opacity: 0;
432
- position: absolute;
433
- width: 100%;
434
- top: 0;
435
- bottom: 0;
436
- left: 0;
437
- text-align: center;
438
- color: #fff;
439
- background: rgba(0,0,0,0.75);
440
- }
441
-
442
  #sb_instagram .sb_instagram_header .sbi_header_img_hover .sbi_new_logo,
443
  #sb_instagram .sb_instagram_header .sbi_header_hashtag_icon .sbi_new_logo{
444
  position: absolute;
@@ -471,10 +457,6 @@
471
  overflow: hidden;
472
  background: url('../img/small-logo.png') no-repeat 0 0;
473
  }
474
- #sb_instagram .sb_instagram_header .sbi_header_img_hover{
475
- z-index: 2;
476
- transition: opacity 0.4s ease-in-out;
477
- }
478
  #sb_instagram .sb_instagram_header .sbi_fade_in{
479
  opacity: 1;
480
  transition: opacity 0.2s ease-in-out;
@@ -488,6 +470,7 @@
488
  text-align: center;
489
  color: #fff;
490
  background: rgba(0,0,0,0.75);
 
491
 
492
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
493
  filter: alpha(opacity=0);
@@ -548,6 +531,8 @@
548
  clear: both;
549
  width: 100%;
550
  text-align: center;
 
 
551
  }
552
  #sb_instagram #sbi_load .fa-spinner{
553
  display: none;
@@ -557,10 +542,6 @@
557
  margin: -8px 0 0 -7px;
558
  font-size: 15px;
559
  }
560
- #sb_instagram #sbi_load{
561
- opacity: 1;
562
- transition: all 0.5s ease-in;
563
- }
564
  #sb_instagram .sbi_load_btn .sbi_btn_text, #sb_instagram .sbi_load_btn .sbi_loader{
565
  opacity: 1;
566
  transition: all 0.1s ease-in;
@@ -568,8 +549,7 @@
568
  #sb_instagram .sbi_hidden{
569
  opacity: 0 !important;
570
  }
571
- #sb_instagram #sbi_load .sbi_load_btn,
572
- #sb_instagram .sbi_follow_btn a{
573
  display: inline-block;
574
  vertical-align: top;
575
  zoom: 1;
@@ -582,14 +562,25 @@
582
  text-decoration: none;
583
  font-size: 13px;
584
  line-height: 1.5;
585
-
586
- -moz-border-radius: 4px;
587
- -webkit-border-radius: 4px;
588
  border-radius: 4px;
 
 
589
 
590
- -webkit-box-sizing: border-box;
591
- -moz-box-sizing: border-box;
 
 
 
 
 
 
 
 
 
592
  box-sizing: border-box;
 
 
 
593
  }
594
  #sb_instagram #sbi_load .sbi_load_btn {
595
  position: relative;
@@ -605,12 +596,7 @@
605
  display: block;
606
  margin-bottom: 5px;
607
  }
608
- #sb_instagram .sbi_follow_btn a{
609
- background: #408bd1;
610
- color: #fff;
611
- }
612
- #sb_instagram .sbi_follow_btn a,
613
- #sb_instagram .sbi_follow_btn a,
614
  #sb_instagram #sbi_load .sbi_load_btn{
615
  transition: all 0.1s ease-in;
616
  }
348
  }
349
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text h3 {
350
  font-size: 20px;
351
+ line-height: 1.4;
352
+ margin-left: 95px !important;
353
+ margin-right: -85px !important;
354
  }
355
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
356
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
357
  font-size: 14px;
358
  }
 
359
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info,
360
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio{
361
  margin-left: 95px !important;
362
  line-height: 1.4
363
  }
 
 
 
364
  #sb_instagram .sb_instagram_header.sbi_medium .sbi_header_text .sbi_bio_info{
365
  margin-top: 4px !important;
366
  }
380
  }
381
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text h3 {
382
  font-size: 28px;
383
+ line-height: 1.5;
384
+ margin-left: 140px !important;
385
+ margin-right: -120px !important;
386
  }
387
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
388
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
389
  font-size: 16px;
390
  }
 
391
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info,
392
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio{
393
  margin-left: 140px !important;
394
  line-height: 1.5;
395
  }
 
 
 
396
  #sb_instagram .sb_instagram_header.sbi_large .sbi_header_text .sbi_bio_info{
397
  margin-top: 12px !important;
398
  }
425
  }
426
  /* Profile pic hover */
427
  /* Profile pic hover */
 
 
 
 
 
 
 
 
 
 
 
 
428
  #sb_instagram .sb_instagram_header .sbi_header_img_hover .sbi_new_logo,
429
  #sb_instagram .sb_instagram_header .sbi_header_hashtag_icon .sbi_new_logo{
430
  position: absolute;
457
  overflow: hidden;
458
  background: url('../img/small-logo.png') no-repeat 0 0;
459
  }
 
 
 
 
460
  #sb_instagram .sb_instagram_header .sbi_fade_in{
461
  opacity: 1;
462
  transition: opacity 0.2s ease-in-out;
470
  text-align: center;
471
  color: #fff;
472
  background: rgba(0,0,0,0.75);
473
+ z-index: 2;
474
 
475
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
476
  filter: alpha(opacity=0);
531
  clear: both;
532
  width: 100%;
533
  text-align: center;
534
+ opacity: 1;
535
+ transition: all 0.5s ease-in;
536
  }
537
  #sb_instagram #sbi_load .fa-spinner{
538
  display: none;
542
  margin: -8px 0 0 -7px;
543
  font-size: 15px;
544
  }
 
 
 
 
545
  #sb_instagram .sbi_load_btn .sbi_btn_text, #sb_instagram .sbi_load_btn .sbi_loader{
546
  opacity: 1;
547
  transition: all 0.1s ease-in;
549
  #sb_instagram .sbi_hidden{
550
  opacity: 0 !important;
551
  }
552
+ #sb_instagram #sbi_load .sbi_load_btn{
 
553
  display: inline-block;
554
  vertical-align: top;
555
  zoom: 1;
562
  text-decoration: none;
563
  font-size: 13px;
564
  line-height: 1.5;
 
 
 
565
  border-radius: 4px;
566
+ box-sizing: border-box;
567
+ }
568
 
569
+ #sb_instagram .sbi_follow_btn a{
570
+ display: inline-block;
571
+ vertical-align: top;
572
+ zoom: 1;
573
+ padding: 7px 14px;
574
+ margin: 5px auto 0 auto;
575
+ border: none;
576
+ text-decoration: none;
577
+ font-size: 13px;
578
+ line-height: 1.5;
579
+ border-radius: 4px;
580
  box-sizing: border-box;
581
+ background: #408bd1;
582
+ color: #fff;
583
+ transition: all 0.1s ease-in;
584
  }
585
  #sb_instagram #sbi_load .sbi_load_btn {
586
  position: relative;
596
  display: block;
597
  margin-bottom: 5px;
598
  }
599
+
 
 
 
 
 
600
  #sb_instagram #sbi_load .sbi_load_btn{
601
  transition: all 0.1s ease-in;
602
  }
inc/admin/PluginSilentUpgrader.php CHANGED
@@ -138,7 +138,7 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
138
  if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
139
 
140
  // Don't output the 'no signature could be found' failure message for now.
141
- if ( 'signature_verification_no_signature' != $download->get_error_code() || WP_DEBUG ) {
142
  // Outout the failure error as a normal feedback, and not as an error:
143
  //$this->skin->feedback( $download->get_error_message() );
144
 
@@ -164,7 +164,7 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
164
  return $download;
165
  }
166
 
167
- $delete_package = ( $download != $options['package'] ); // Do not delete a "local" file
168
 
169
  // Unzips the file into a temporary directory.
170
  $working_dir = $this->unpack_package( $download, $delete_package );
@@ -192,10 +192,6 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
192
  $this->skin->set_result( $result );
193
  if ( is_wp_error( $result ) ) {
194
  $this->skin->error( $result );
195
- //$this->skin->feedback( 'process_failed' );
196
- } else {
197
- // Installation succeeded.
198
- //$this->skin->feedback( 'process_success' );
199
  }
200
 
201
  $this->skin->after();
@@ -255,13 +251,11 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
255
  global $wp_filesystem;
256
  $file = $wp_filesystem->abspath() . '.maintenance';
257
  if ( $enable ) {
258
- //$this->skin->feedback( 'maintenance_start' );
259
  // Create maintenance file to signal that we are upgrading
260
  $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
261
  $wp_filesystem->delete( $file );
262
  $wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
263
- } elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
264
- //$this->skin->feedback( 'maintenance_end' );
265
  $wp_filesystem->delete( $file );
266
  }
267
  }
@@ -301,8 +295,6 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
301
  return new WP_Error( 'no_package', $this->strings['no_package'] );
302
  }
303
 
304
- //$this->skin->feedback( 'downloading_package', $package );
305
-
306
  $download_file = download_url( $package, 300, $check_signatures );
307
 
308
  if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
@@ -327,8 +319,6 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
327
  public function unpack_package( $package, $delete_package = true ) {
328
  global $wp_filesystem;
329
 
330
- //$this->skin->feedback( 'unpack_package' );
331
-
332
  $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
333
 
334
  //Clean up contents of upgrade directory beforehand.
@@ -357,7 +347,7 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
357
 
358
  if ( is_wp_error( $result ) ) {
359
  $wp_filesystem->delete( $working_dir, true );
360
- if ( 'incompatible_archive' == $result->get_error_code() ) {
361
  return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
362
  }
363
  return $result;
@@ -420,7 +410,6 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
420
  if ( empty( $source ) || empty( $destination ) ) {
421
  return new WP_Error( 'bad_request', $this->strings['bad_request'] );
422
  }
423
- //$this->skin->feedback( 'installing_package' );
424
 
425
  /**
426
  * Filters the install response before the installation has started.
@@ -448,9 +437,9 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
448
  $remote_destination = $wp_filesystem->find_folder( $local_destination );
449
 
450
  //Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
451
- if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents.
452
  $source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
453
- } elseif ( count( $source_files ) == 0 ) {
454
  return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
455
  } else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
456
  $source = trailingslashit( $args['source'] );
@@ -491,7 +480,7 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
491
  $protected_directories = array_merge( $protected_directories, $wp_theme_directories );
492
  }
493
 
494
- if ( in_array( $destination, $protected_directories ) ) {
495
  $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
496
  $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
497
  }
@@ -548,7 +537,7 @@ class PluginSilentUpgrader extends \Plugin_Upgrader {
548
  }
549
 
550
  $destination_name = basename( str_replace( $local_destination, '', $destination ) );
551
- if ( '.' == $destination_name ) {
552
  $destination_name = '';
553
  }
554
 
138
  if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
139
 
140
  // Don't output the 'no signature could be found' failure message for now.
141
+ if ( 'signature_verification_no_signature' !== $download->get_error_code() || WP_DEBUG ) {
142
  // Outout the failure error as a normal feedback, and not as an error:
143
  //$this->skin->feedback( $download->get_error_message() );
144
 
164
  return $download;
165
  }
166
 
167
+ $delete_package = ( $download !== $options['package'] ); // Do not delete a "local" file
168
 
169
  // Unzips the file into a temporary directory.
170
  $working_dir = $this->unpack_package( $download, $delete_package );
192
  $this->skin->set_result( $result );
193
  if ( is_wp_error( $result ) ) {
194
  $this->skin->error( $result );
 
 
 
 
195
  }
196
 
197
  $this->skin->after();
251
  global $wp_filesystem;
252
  $file = $wp_filesystem->abspath() . '.maintenance';
253
  if ( $enable ) {
 
254
  // Create maintenance file to signal that we are upgrading
255
  $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
256
  $wp_filesystem->delete( $file );
257
  $wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
258
+ } elseif ( $wp_filesystem->exists( $file ) ) {
 
259
  $wp_filesystem->delete( $file );
260
  }
261
  }
295
  return new WP_Error( 'no_package', $this->strings['no_package'] );
296
  }
297
 
 
 
298
  $download_file = download_url( $package, 300, $check_signatures );
299
 
300
  if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
319
  public function unpack_package( $package, $delete_package = true ) {
320
  global $wp_filesystem;
321
 
 
 
322
  $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
323
 
324
  //Clean up contents of upgrade directory beforehand.
347
 
348
  if ( is_wp_error( $result ) ) {
349
  $wp_filesystem->delete( $working_dir, true );
350
+ if ( 'incompatible_archive' === $result->get_error_code() ) {
351
  return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
352
  }
353
  return $result;
410
  if ( empty( $source ) || empty( $destination ) ) {
411
  return new WP_Error( 'bad_request', $this->strings['bad_request'] );
412
  }
 
413
 
414
  /**
415
  * Filters the install response before the installation has started.
437
  $remote_destination = $wp_filesystem->find_folder( $local_destination );
438
 
439
  //Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
440
+ if ( 1 === count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents.
441
  $source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
442
+ } elseif ( empty( $source_files ) ) {
443
  return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
444
  } else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
445
  $source = trailingslashit( $args['source'] );
480
  $protected_directories = array_merge( $protected_directories, $wp_theme_directories );
481
  }
482
 
483
+ if ( in_array( $destination, $protected_directories, true ) ) {
484
  $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
485
  $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
486
  }
537
  }
538
 
539
  $destination_name = basename( str_replace( $local_destination, '', $destination ) );
540
+ if ( '.' === $destination_name ) {
541
  $destination_name = '';
542
  }
543
 
inc/admin/actions.php CHANGED
@@ -10,7 +10,9 @@
10
  * - Displaying admin notices
11
  * - Clearing caches
12
  */
13
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
 
14
 
15
  function sb_instagram_admin_style() {
16
  wp_register_style( 'sb_instagram_admin_css', SBI_PLUGIN_URL . 'css/sb-instagram-admin.css', array(), SBIVER );
@@ -24,10 +26,13 @@ function sb_instagram_admin_scripts() {
24
  if ( ! current_user_can( 'manage_instagram_feed_options' ) ) {
25
  return;
26
  }
27
- wp_enqueue_script( 'sb_instagram_admin_js', SBI_PLUGIN_URL . 'js/sb-instagram-admin-2-2.js', array(), SBIVER );
28
- wp_localize_script( 'sb_instagram_admin_js', 'sbiA', array(
29
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
30
- 'sbi_nonce' => wp_create_nonce( 'sbi_nonce' )
 
 
 
31
  )
32
  );
33
  $strings = array(
@@ -58,39 +63,28 @@ function sb_instagram_admin_scripts() {
58
  'sbi_admin',
59
  $strings
60
  );
61
- if( !wp_script_is('jquery-ui-draggable') ) {
62
- wp_enqueue_script(
63
- array(
64
- 'jquery',
65
- 'jquery-ui-core',
66
- 'jquery-ui-draggable'
67
- )
68
- );
69
- }
70
- wp_enqueue_script(
71
- array(
72
- 'hoverIntent',
73
- 'wp-color-picker'
74
- )
75
- );
76
  }
77
  add_action( 'admin_enqueue_scripts', 'sb_instagram_admin_scripts' );
78
 
79
  // Add a Settings link to the plugin on the Plugins page
80
  $sbi_plugin_file = 'instagram-feed/instagram-feed.php';
81
- add_filter( "plugin_action_links_{$sbi_plugin_file}", 'sbi_add_settings_link', 10, 2 );
82
 
83
  //modify the link by unshifting the array
84
- function sbi_add_settings_link( $links, $file ) {
85
  $pro_link = '<a href="https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=plugins-page&utm_medium=upgrade-link" target="_blank" style="font-weight: bold; color: #1da867;">' . __( 'Try the Pro Demo', 'instagram-feed' ) . '</a>';
86
 
87
- $sbi_settings_link = '<a href="' . admin_url( 'admin.php?page=sb-instagram-feed' ) . '">' . __( 'Settings', 'instagram-feed' ) . '</a>';
88
  array_unshift( $links, $pro_link, $sbi_settings_link );
89
 
90
  return $links;
91
  }
92
 
93
-
94
  /**
95
  * Called via ajax to automatically save access token and access token secret
96
  * retrieved with the big blue button
@@ -102,45 +96,42 @@ function sbi_auto_save_tokens() {
102
  wp_send_json_error();
103
  }
104
 
105
- $options = sbi_get_database_settings();
106
- $new_access_token = isset( $_POST['access_token'] ) ? sanitize_text_field( wp_unslash( $_POST['access_token'] ) ) : false;
107
- $split_token = $new_access_token ? explode( '.', $new_access_token ) : array();
108
- $new_user_id = isset( $split_token[0] ) ? $split_token[0] : '';
109
-
110
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
111
- $test_connection_data = sbi_account_data_for_token( $new_access_token );
112
-
113
- $connected_accounts[ $new_user_id ] = array(
114
- 'access_token' => sbi_get_parts( $new_access_token ),
115
- 'user_id' => $test_connection_data['id'],
116
- 'username' => $test_connection_data['username'],
117
- 'is_valid' => $test_connection_data['is_valid'],
118
- 'last_checked' => $test_connection_data['last_checked'],
119
- 'profile_picture' => $test_connection_data['profile_picture'],
120
- );
121
-
122
- if ( !$options['sb_instagram_disable_resize'] ) {
123
- if ( sbi_create_local_avatar( $test_connection_data['username'], $test_connection_data['profile_picture'] ) ) {
124
- $connected_accounts[ $new_user_id ]['local_avatar'] = true;
125
- }
126
- } else {
127
- $connected_accounts[ $new_user_id ]['local_avatar'] = false;
128
- }
129
 
130
- $options['connected_accounts'] = $connected_accounts;
 
 
 
 
 
 
131
 
132
- update_option( 'sb_instagram_settings', $options );
133
 
134
- echo sbi_json_encode( $connected_accounts[ $new_user_id ] );
135
 
136
- die();
137
  }
138
  add_action( 'wp_ajax_sbi_auto_save_tokens', 'sbi_auto_save_tokens' );
139
 
140
  function sbi_delete_local_avatar( $username ) {
141
  $upload = wp_upload_dir();
142
 
143
- $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg' ); // get all matching images
144
  foreach ( $image_files as $file ) { // iterate files
145
  if ( is_file( $file ) ) {
146
  unlink( $file );
@@ -155,25 +146,68 @@ function sbi_connect_business_accounts() {
155
  wp_send_json_error();
156
  }
157
 
158
- $accounts = isset( $_POST['accounts'] ) ? json_decode( stripslashes( $_POST['accounts'] ), true ) : false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
  $return = array();
161
- foreach ( $accounts as $account ) {
162
- $account['type'] = 'business';
163
 
164
- $connector = new SBI_Account_Connector();
 
165
 
166
- $connector->add_account_data( $account );
167
- if ( $connector->update_stored_account() ) {
168
- $connector->after_update();
169
 
170
- $return[ $connector->get_id() ] = $connector->get_account_data();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  }
172
  }
173
 
174
- echo sbi_json_encode( $return );
175
-
176
- die();
177
  }
178
  add_action( 'wp_ajax_sbi_connect_business_accounts', 'sbi_connect_business_accounts' );
179
 
@@ -184,33 +218,33 @@ function sbi_auto_save_id() {
184
  wp_send_json_error();
185
  }
186
 
187
- $options = get_option( 'sb_instagram_settings', array() );
188
 
189
- $options['sb_instagram_user_id'] = array( sanitize_text_field( wp_unslash( $_POST['id'] ) ) );
190
 
191
- update_option( 'sb_instagram_settings', $options );
192
 
193
- die();
194
  }
195
  add_action( 'wp_ajax_sbi_auto_save_id', 'sbi_auto_save_id' );
196
 
197
  function sbi_formatted_error( $response ) {
198
  if ( isset( $response['error'] ) ) {
199
- $error = '<p>' . sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message'] . '</p>';
200
- $error .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
201
 
202
- return $error;
203
- } else {
204
- $message = '<p>' . sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] ). '</p>';
205
  if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) {
206
  foreach ( $response['response']->errors as $key => $item ) {
207
- '<p>' .$message .= ' '.$key . ' - ' . $item[0] . '</p>';
208
  }
209
  }
210
- $message .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
211
 
212
  return $message;
213
- }
214
  }
215
 
216
  function sbi_test_token() {
@@ -221,12 +255,16 @@ function sbi_test_token() {
221
  }
222
 
223
  $access_token = isset( $_POST['access_token'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['access_token'] ) ) ) : false;
224
- $account_id = isset( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : false;
 
225
 
226
- $return = sbi_connect_new_account( $access_token, $account_id );
 
 
 
 
227
 
228
- echo $return;
229
- die();
230
  }
231
  add_action( 'wp_ajax_sbi_test_token', 'sbi_test_token' );
232
 
@@ -237,25 +275,24 @@ function sbi_delete_account() {
237
  wp_send_json_error();
238
  }
239
  $account_id = isset( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : false;
240
-
241
  sbi_do_account_delete( $account_id );
242
 
243
- die();
244
  }
245
  add_action( 'wp_ajax_sbi_delete_account', 'sbi_delete_account' );
246
 
247
  function sbi_account_data_for_token( $access_token ) {
248
  $return = array(
249
- 'id' => false,
250
- 'username' => false,
251
- 'is_valid' => false,
252
- 'last_checked' => time()
253
  );
254
- $url = 'https://api.instagram.com/v1/users/self/?access_token=' . sbi_maybe_clean( $access_token );
255
- $args = array(
256
- 'timeout' => 20
257
  );
258
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
259
  $args['sslverify'] = false;
260
  }
261
  $result = wp_remote_get( $url, $args );
@@ -267,9 +304,9 @@ function sbi_account_data_for_token( $access_token ) {
267
  }
268
 
269
  if ( isset( $data->data->id ) ) {
270
- $return['id'] = $data->data->id;
271
- $return['username'] = $data->data->username;
272
- $return['is_valid'] = true;
273
  $return['profile_picture'] = $data->data->profile_picture;
274
 
275
  } elseif ( isset( $data->error_type ) && $data->error_type === 'OAuthRateLimitException' ) {
@@ -278,7 +315,7 @@ function sbi_account_data_for_token( $access_token ) {
278
  $return = false;
279
  }
280
 
281
- $sbi_options = get_option( 'sb_instagram_settings', array() );
282
  $sbi_options['sb_instagram_at'] = '';
283
  update_option( 'sb_instagram_settings', $sbi_options );
284
 
@@ -286,8 +323,8 @@ function sbi_account_data_for_token( $access_token ) {
286
  }
287
 
288
  function sbi_do_account_delete( $account_id ) {
289
- $options = get_option( 'sb_instagram_settings', array() );
290
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
291
  global $sb_instagram_posts_manager;
292
  $sb_instagram_posts_manager->reset_api_errors();
293
 
@@ -330,17 +367,17 @@ function sbi_delete_platform_data_listener() {
330
  add_action( 'wp_ajax_sbi_delete_platform_data', 'sbi_delete_platform_data_listener' );
331
 
332
  function sbi_connect_new_account( $access_token, $account_id ) {
333
- $split_id = explode( ' ', trim( $account_id ) );
334
- $account_id = preg_replace("/[^A-Za-z0-9 ]/", '', $split_id[0] );
335
  if ( ! empty( $account_id ) ) {
336
- $split_token = explode( ' ', trim( $access_token ) );
337
- $access_token = preg_replace("/[^A-Za-z0-9 ]/", '', $split_token[0] );
338
  }
339
 
340
  $account = array(
341
  'access_token' => $access_token,
342
- 'user_id' => $account_id,
343
- 'type' => 'business'
344
  );
345
 
346
  if ( sbi_code_check( $access_token ) ) {
@@ -365,50 +402,58 @@ function sbi_no_js_connected_account_management() {
365
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
366
  return;
367
  }
 
 
 
 
 
368
  if ( isset( $_POST['sb_manual_at'] ) ) {
369
- $access_token = isset( $_POST['sb_manual_at'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['sb_manual_at'] ) ) ) : false;
370
- $account_id = isset( $_POST['sb_manual_account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['sb_manual_account_id'] ) ) : false;
371
  if ( ! $access_token || ! $account_id ) {
372
  return;
373
  }
374
  sbi_connect_new_account( $access_token, $account_id );
375
- } elseif ( isset( $_GET['disconnect'] ) && isset( $_GET['page'] ) && $_GET['page'] === 'sb-instagram-feed' ) {
376
- $account_id = sanitize_text_field( wp_unslash( $_GET['disconnect'] ) );
377
  sbi_do_account_delete( $account_id );
378
  }
379
 
380
  }
381
  add_action( 'admin_init', 'sbi_no_js_connected_account_management' );
382
 
383
- add_action('admin_notices', 'sbi_admin_ssl_notice');
384
  function sbi_admin_ssl_notice() {
385
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
386
  return;
387
  }
388
- if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'sb-instagram-feed' )) ) {
 
389
  global $current_user;
390
- $user_id = $current_user->ID;
391
- $was_dismissed = get_user_meta($user_id, 'sbi_ignore_openssl', true);
392
 
393
  if ( ! $was_dismissed && ! sbi_doing_openssl() ) : ?>
394
- <div class="notice notice-warning is-dismissible sbi-admin-notice">
395
- <p><?php _e( sprintf( 'Instagram Feed recommends Open SSL for encrypting Instagram platform data in your database. Contact your host or follow %1$sthese%2$s directions.', '<a href="https://www.php.net/manual/en/openssl.installation.php" target="_blank">', '</a>' ), 'instagram-feed' ); ?> <a href="<?php echo admin_url( 'admin.php?page=sb-instagram-feed&openssldismiss=1' ); ?>"><?php _e('Dismiss', 'instagram-feed' ); ?></a></p>
396
- </div>
397
- <?php endif;
 
398
  }
399
 
400
  }
401
 
402
  add_action( 'admin_init', 'sbi_check_notice_dismiss' );
403
  function sbi_check_notice_dismiss() {
404
- if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
405
  return;
406
  }
407
  global $current_user;
408
  $user_id = $current_user->ID;
409
 
 
410
  if ( isset( $_GET['openssldismiss'] ) ) {
411
- add_user_meta($user_id, 'sbi_ignore_openssl', 'true', true);
412
  }
413
  }
414
 
@@ -419,36 +464,32 @@ function sbi_check_notice_dismiss() {
419
  function sbi_get_connected_accounts_data() {
420
  $sbi_options = get_option( 'sb_instagram_settings', array() );
421
 
422
- return isset( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
423
  }
424
 
425
  function sbi_connect_basic_account( $new_account_details ) {
 
 
426
 
427
- $options = sbi_get_database_settings();
428
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
429
-
430
- $accounts_to_save = array();
431
  $old_account_user_id = '';
432
- $ids_to_save = array();
433
- $user_ids = is_array( $options[ 'sb_instagram_user_id' ] ) ? $options[ 'sb_instagram_user_id' ] : explode( ',', str_replace( ' ', '', $options[ 'sb_instagram_user_id' ] ) );
434
 
435
  $profile_picture = '';
436
 
437
  // do not connect as a basic display account if already connected as a business account
438
- if ( isset( $connected_accounts[ $new_account_details['user_id'] ] )
439
- && isset( $connected_accounts[ $new_account_details['user_id'] ]['type'] )
440
- && $connected_accounts[ $new_account_details['user_id'] ]['type'] === 'business' ) {
441
  return $options;
442
  }
443
 
444
  foreach ( $connected_accounts as $account ) {
445
- $account_type = isset( $account['type'] ) ? $account['type'] : 'personal';
446
- if ( ($account['username'] !== $new_account_details['username'])
447
- || $account_type === 'business' ) {
448
  $accounts_to_save[ $account['user_id'] ] = $account;
449
  } else {
450
  $old_account_user_id = $account['user_id'];
451
- $profile_picture = isset( $account['profile_picture'] ) ? $account['profile_picture'] : '';
452
  }
453
  }
454
 
@@ -461,15 +502,15 @@ function sbi_connect_basic_account( $new_account_details ) {
461
  }
462
 
463
  $accounts_to_save[ $new_account_details['user_id'] ] = array(
464
- 'access_token' => sbi_fixer( $new_account_details['access_token'] ),
465
- 'user_id' => $new_account_details['user_id'],
466
- 'username' => $new_account_details['username'],
467
- 'is_valid' => true,
468
- 'last_checked' => time(),
469
  'expires_timestamp' => $new_account_details['expires_timestamp'],
470
- 'profile_picture' => $profile_picture,
471
- 'account_type' => strtolower( $new_account_details['account_type'] ),
472
- 'type' => 'basic',
473
  );
474
 
475
  if ( ! empty( $old_account_user_id ) && $old_account_user_id !== $new_account_details['user_id'] ) {
@@ -479,13 +520,12 @@ function sbi_connect_basic_account( $new_account_details ) {
479
  $fuzzy_matches = sbi_fuzzy_matching_header_data( $old_account_user_id );
480
  if ( ! empty( $fuzzy_matches[0] ) ) {
481
  $header_data = sbi_find_matching_data_from_results( $fuzzy_matches, $old_account_user_id );
482
- $bio = SB_Instagram_Parse::get_bio( $header_data );
483
  $accounts_to_save[ $new_account_details['user_id'] ]['bio'] = sbi_sanitize_emoji( $bio );
484
  }
485
-
486
  }
487
 
488
- if ( ! empty( $profile_picture ) && !$options['sb_instagram_disable_resize'] ) {
489
  if ( sbi_create_local_avatar( $new_account_details['username'], $profile_picture ) ) {
490
  $accounts_to_save[ $new_account_details['user_id'] ]['local_avatar'] = true;
491
  }
@@ -493,47 +533,41 @@ function sbi_connect_basic_account( $new_account_details ) {
493
  $accounts_to_save[ $new_account_details['user_id'] ]['local_avatar'] = false;
494
  }
495
 
496
- delete_transient( SBI_USE_BACKUP_PREFIX . 'sbi_' . $new_account_details['user_id'] );
497
  $refresher = new SB_Instagram_Token_Refresher( $accounts_to_save[ $new_account_details['user_id'] ] );
498
  $refresher->attempt_token_refresh();
499
 
500
- if ( $refresher->get_last_error_code() === 10 ) {
501
  $accounts_to_save[ $new_account_details['user_id'] ]['private'] = true;
502
  }
503
 
504
  $accounts_to_save[ $new_account_details['user_id'] ] = SB_Instagram_Connected_Account::encrypt_connected_account_tokens( $accounts_to_save[ $new_account_details['user_id'] ] );
505
 
506
- $options['connected_accounts'] = $accounts_to_save;
507
  $options['sb_instagram_user_id'] = $ids_to_save;
508
 
509
  update_option( 'sb_instagram_settings', $options );
510
- //global $sb_instagram_posts_manager;
511
 
512
- //$sb_instagram_posts_manager->remove_all_errors();
513
  return $options;
514
  }
515
 
516
  function sbi_fuzzy_matching_header_data( $user_id ) {
517
-
518
  if ( empty( $user_id ) || strlen( $user_id ) < 4 ) {
519
  return array();
520
  }
521
  global $wpdb;
522
- $escaped_id = esc_sql( $user_id );
523
-
524
- $values = $wpdb->get_results( "
525
- SELECT option_value
526
- FROM $wpdb->options
527
- WHERE option_name LIKE ('%!sbi\_header\_".$escaped_id."%')
528
- LIMIT 10", ARRAY_A );
529
 
530
- $regular_values = $wpdb->get_results( "
 
 
531
  SELECT option_value
532
  FROM $wpdb->options
533
- WHERE option_name LIKE ('%sbi\_header\_".$escaped_id."%')
534
- LIMIT 10", ARRAY_A );
535
-
536
- $values = array_merge( $values, $regular_values );
 
 
537
 
538
  return $values;
539
  }
@@ -541,13 +575,12 @@ function sbi_fuzzy_matching_header_data( $user_id ) {
541
  function sbi_find_matching_data_from_results( $results, $user_id ) {
542
 
543
  $match = array();
 
544
 
545
- $i = 0;
546
-
547
- while( empty( $match ) && isset( $results[ $i ] ) ) {
548
  if ( ! empty( $results[ $i ] ) ) {
549
  $header_data = json_decode( $results[ $i ]['option_value'], true );
550
- if ( isset( $header_data['id'] ) && (string)$header_data['id'] === (string)$user_id ) {
551
  $match = $header_data;
552
  }
553
  }
@@ -558,28 +591,25 @@ function sbi_find_matching_data_from_results( $results, $user_id ) {
558
  }
559
 
560
  function sbi_matches_existing_personal( $new_account_details ) {
561
-
562
- $options = sbi_get_database_settings();
563
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
564
 
565
  $matches_one_account = false;
566
  foreach ( $connected_accounts as $account ) {
567
- $account_type = isset( $account['type'] ) ? $account['type'] : 'personal';
568
- if ( ($account_type === 'personal' || $account_type === 'basic')
569
- && $account['username'] == $new_account_details['username'] ) {
570
  $matches_one_account = true;
571
  }
572
  }
573
 
574
  return $matches_one_account;
575
-
576
  }
577
 
578
  function sbi_business_account_request( $url, $account, $remove_access_token = true ) {
579
  $args = array(
580
- 'timeout' => 20
581
  );
582
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
583
  $args['sslverify'] = false;
584
  }
585
  $result = wp_remote_get( $url, $args );
@@ -598,89 +628,108 @@ function sbi_after_connection() {
598
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
599
  wp_send_json_error();
600
  }
601
-
602
  if ( isset( $_POST['access_token'] ) ) {
603
- $access_token = sanitize_text_field( wp_unslash( $_POST['access_token'] ) );
604
- $account_info = sbi_account_data_for_token( $access_token );
605
- echo sbi_json_encode( $account_info );
 
606
  }
607
 
608
- die();
609
  }
610
  add_action( 'wp_ajax_sbi_after_connection', 'sbi_after_connection' );
611
 
612
- function sbi_get_business_account_connection_modal( $sb_instagram_user_id ) {
613
- $access_token = sbi_maybe_clean(urldecode( ( $_GET['sbi_access_token'] ) ));
614
- //
615
- $url = 'https://graph.facebook.com/me/accounts?fields=instagram_business_account,access_token&limit=500&access_token='.$access_token;
616
  $args = array(
617
- 'timeout' => 20
618
  );
619
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
620
  $args['sslverify'] = false;
621
  }
622
  $result = wp_remote_get( $url, $args );
623
- $pages_data = '{}';
624
  if ( ! is_wp_error( $result ) ) {
625
  $pages_data = $result['body'];
 
 
626
  } else {
627
- $page_error = $result;
628
  }
629
 
630
- $pages_data_arr = json_decode($pages_data);
631
- $num_accounts = 0;
632
- if(isset($pages_data_arr)){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
  $num_accounts = is_array( $pages_data_arr->data ) ? count( $pages_data_arr->data ) : 0;
634
  }
635
  ?>
636
- <div id="sbi_config_info" class="sb_list_businesses sbi_num_businesses_<?php echo $num_accounts; ?>">
637
- <div class="sbi_config_modal">
638
- <div class="sbi-managed-pages">
639
- <?php if ( isset( $page_error ) && isset( $page_error->errors ) ) {
640
- foreach ($page_error->errors as $key => $item) {
641
- echo '<div class="sbi_user_id_error" style="display:block;"><strong>Connection Error: </strong>' . $key . ': ' . $item[0] . '</div>';
 
642
  }
643
  }
644
  ?>
645
- <?php if( empty($pages_data_arr->data) ) : ?>
646
- <span id="sbi-bus-account-error">
647
- <p style="margin-top: 5px;"><strong style="font-size: 16px">Couldn't find Business Profile</strong><br />
648
- Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the <a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">Facebook account</a> in this browser which is associated with your Instagram Business Profile.</p>
649
- <p><strong style="font-size: 16px">Why do I need a Business Profile?</strong><br />
650
- A Business Profile is only required if you are displaying a Hashtag feed. If you want to display a regular User feed then you can do this by selecting to connect a Personal account instead. For directions on how to convert your Personal profile into a Business profile please <a href="https://smashballoon.com/instagram-business-profiles" target="_blank">see here</a>.</p>
651
- </span>
652
-
653
- <?php elseif ( $num_accounts === 0 ): ?>
654
- <span id="sbi-bus-account-error">
655
- <p style="margin-top: 5px;"><strong style="font-size: 16px">Couldn't find Business Profile</strong><br />
656
- Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the <a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">Facebook account</a> in this browser which is associated with your Instagram Business Profile.</p>
657
- <p>If you are, in fact, logged-in to the correct account please make sure you have Instagram accounts connected with your Facebook account by following <a href="https://smashballoon.com/reconnecting-an-instagram-business-profile/" target="_blank">this FAQ</a></p>
658
- </span>
659
- <?php else: ?>
660
- <p class="sbi-managed-page-intro"><strong style="font-size: 16px;">Instagram Business profiles for this account</strong><br /><em style="color: #666;">Note: In order to display a Hashtag feed you first need to select a Business profile below.</em></p>
661
  <?php if ( $num_accounts > 1 ) : ?>
662
- <div class="sbi-managed-page-select-all"><input type="checkbox" id="sbi-select-all" class="sbi-select-all"><label for="sbi-select-all">Select All</label></div>
663
  <?php endif; ?>
664
- <div class="sbi-scrollable-accounts">
665
 
666
  <?php foreach ( $pages_data_arr->data as $page => $page_data ) : ?>
667
 
668
- <?php if( isset( $page_data->instagram_business_account ) ) :
 
669
 
670
- $instagram_business_id = $page_data->instagram_business_account->id;
671
 
672
- $page_access_token = isset( $page_data->access_token ) ? $page_data->access_token : '';
673
 
674
  //Make another request to get page info
675
- $instagram_account_url = 'https://graph.facebook.com/'.$instagram_business_id.'?fields=name,username,profile_picture_url&access_token='.$access_token;
676
 
677
  $args = array(
678
- 'timeout' => 20
679
  );
680
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
681
  $args['sslverify'] = false;
682
  }
683
- $result = wp_remote_get( $instagram_account_url, $args );
684
  $instagram_account_info = '{}';
685
  if ( ! is_wp_error( $result ) ) {
686
  $instagram_account_info = $result['body'];
@@ -688,97 +737,102 @@ function sbi_get_business_account_connection_modal( $sb_instagram_user_id ) {
688
  $page_error = $result;
689
  }
690
 
691
- $instagram_account_data = json_decode($instagram_account_info);
692
 
693
- $instagram_biz_img = isset( $instagram_account_data->profile_picture_url ) ? $instagram_account_data->profile_picture_url : false;
694
- $selected_class = $instagram_business_id == $sb_instagram_user_id ? ' sbi-page-selected' : '';
695
 
696
  ?>
697
- <?php if ( isset( $page_error ) && isset( $page_error->errors ) ) :
698
- foreach ($page_error->errors as $key => $item) {
699
- echo '<div class="sbi_user_id_error" style="display:block;"><strong>Connection Error: </strong>' . $key . ': ' . $item[0] . '</div>';
700
- }
701
- else : ?>
702
- <div class="sbi-managed-page<?php echo $selected_class; ?>" data-page-token="<?php echo esc_attr( $page_access_token ); ?>" data-token="<?php echo esc_attr( $access_token ); ?>" data-page-id="<?php echo esc_attr( $instagram_business_id ); ?>">
703
- <div class="sbi-add-checkbox">
704
- <input id="sbi-<?php echo esc_attr( $instagram_business_id ); ?>" type="checkbox" name="sbi_managed_pages[]" value="<?php echo esc_attr( $instagram_account_info ); ?>">
705
- </div>
706
- <div class="sbi-managed-page-details">
707
- <label for="sbi-<?php echo esc_attr( $instagram_business_id ); ?>"><img class="sbi-page-avatar" border="0" height="50" width="50" src="<?php echo esc_url( $instagram_biz_img ); ?>" alt="<?php echo esc_attr( $instagram_business_id ); ?>"><strong style="font-size: 16px;"><?php echo esc_html( $instagram_account_data->name ); ?></strong>
708
- <br />@<?php echo esc_html( $instagram_account_data->username); ?><span style="font-size: 11px; margin-left: 5px;">(<?php echo esc_html( $instagram_business_id ); ?>)</span></label>
709
- </div>
710
- </div>
 
 
711
  <?php endif; ?>
712
 
713
  <?php endif; ?>
714
 
715
  <?php endforeach; ?>
716
 
717
- </div> <!-- end scrollable -->
718
- <p style="font-size: 11px; line-height: 1.5; margin-bottom: 0;"><em style="color: #666;">*<?php echo sprintf( __( 'Changing the password, updating privacy settings, or removing page admins for the related Facebook page may require %smanually reauthorizing our app%s to reconnect an account.', 'instagram-feed' ), '<a href="https://smashballoon.com/reauthorizing-our-instagram-facebook-app/" target="_blank" rel="noopener noreferrer">', '</a>' ); ?></em></p>
719
 
720
- <button id="sbi-connect-business-accounts" class="button button-primary" disabled="disabled" style="margin-top: 20px;"><?php _e( 'Connect Accounts', 'instagram-feed' ); ?></button>
721
 
722
  <?php endif; ?>
723
 
724
- <a href="JavaScript:void(0);" class="sbi_modal_close"><i class="fa fa-times"></i></a>
725
- </div>
726
- </div>
727
- </div><?php
 
728
  }
729
 
730
  function sbi_get_personal_connection_modal( $connected_accounts, $action_url = 'admin.php?page=sb-instagram-feed' ) {
731
- $access_token = sanitize_text_field( wp_unslash( $_GET['sbi_access_token'] ) );
732
- $account_type = sanitize_text_field( wp_unslash( $_GET['sbi_account_type'] ) );
733
- $user_id = sanitize_text_field( wp_unslash( $_GET['sbi_id'] ) );
734
- $user_name = sanitize_text_field( wp_unslash( $_GET['sbi_username'] ) );
735
- $expires_in = (int)$_GET['sbi_expires_in'];
 
 
 
736
  $expires_timestamp = time() + $expires_in;
737
 
738
  $new_account_details = array(
739
- 'access_token' => $access_token,
740
- 'account_type' => $account_type,
741
- 'user_id' => $user_id,
742
- 'username' => $user_name,
743
  'expires_timestamp' => $expires_timestamp,
744
- 'profile_picture' => '',
745
- 'type' => 'basic'
746
  );
747
 
748
-
749
  $matches_existing_personal = sbi_matches_existing_personal( $new_account_details );
750
- $button_text = $matches_existing_personal ? __( 'Update This Account', 'instagram-feed' ) : __( 'Connect This Account', 'instagram-feed' );
751
 
752
  $account_json = sbi_json_encode( $new_account_details );
753
 
754
- $already_connected_as_business_account = (isset( $connected_accounts[ $user_id ] ) && $connected_accounts[ $user_id ]['type'] === 'business');
755
-
756
  ?>
757
 
758
- <div id="sbi_config_info" class="sb_get_token">
759
- <div class="sbi_config_modal">
760
- <div class="sbi_ca_username"><strong><?php echo esc_html( $user_name ); ?></strong></div>
761
- <form action="<?php echo admin_url( $action_url ); ?>" method="post">
762
- <p class="sbi_submit">
763
- <?php if ( $already_connected_as_business_account ) :
764
- _e( 'The Instagram account you are logged into is already connected as a "business" account. Remove the business account if you\'d like to connect as a basic account instead (not recommended).', 'instagram-feed' );
 
765
  ?>
766
  <?php else : ?>
767
- <input type="submit" name="sbi_submit" id="sbi_connect_account" class="button button-primary" value="<?php echo esc_html( $button_text ); ?>">
768
- <?php endif; ?>
769
- <input type="hidden" name="sbi_account_json" value="<?php echo esc_attr( $account_json ) ; ?>">
770
- <input type="hidden" name="sbi_connect_username" value="<?php echo esc_attr( $user_name ); ?>">
771
- <a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts"><?php esc_html_e( 'Switch Accounts', 'instagram-feed' ); ?></a>
772
- </p>
773
- </form>
774
- <a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>
775
- </div>
776
- </div>
777
  <?php
778
  }
779
 
780
  function sbi_account_type_display( $type, $private = false ) {
781
- if ( $type === 'basic' ) {
782
  $type = 'personal';
783
  if ( $private ) {
784
  $type .= ' (private)';
@@ -793,27 +847,33 @@ function sbi_clear_backups() {
793
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
794
  wp_send_json_error();
795
  }
796
-
797
  //Delete all transients
798
  global $wpdb;
799
- $table_name = $wpdb->prefix . "options";
800
- $wpdb->query( "
 
801
  DELETE
802
- FROM $table_name
803
  WHERE `option_name` LIKE ('%!sbi\_%')
804
- " );
805
- $wpdb->query( "
 
 
806
  DELETE
807
- FROM $table_name
808
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
809
- " );
810
- $wpdb->query( "
 
 
811
  DELETE
812
- FROM $table_name
813
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
814
- " );
 
815
 
816
- die();
817
  }
818
  add_action( 'wp_ajax_sbi_clear_backups', 'sbi_clear_backups' );
819
 
@@ -823,16 +883,14 @@ function sbi_reset_resized() {
823
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
824
  wp_send_json_error();
825
  }
826
-
827
  global $sb_instagram_posts_manager;
828
  $sb_instagram_posts_manager->delete_all_sbi_instagram_posts();
829
  delete_option( 'sbi_top_api_calls' );
830
 
831
  $sb_instagram_posts_manager->add_action_log( 'Reset resizing tables.' );
832
 
833
- echo "1";
834
-
835
- die();
836
  }
837
  add_action( 'wp_ajax_sbi_reset_resized', 'sbi_reset_resized' );
838
 
@@ -842,14 +900,12 @@ function sbi_reset_log() {
842
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
843
  wp_send_json_error();
844
  }
845
-
846
  global $sb_instagram_posts_manager;
847
 
848
  $sb_instagram_posts_manager->remove_all_errors();
849
 
850
- echo "1";
851
-
852
- die();
853
  }
854
  add_action( 'wp_ajax_sbi_reset_log', 'sbi_reset_log' );
855
 
@@ -859,15 +915,13 @@ function sbi_reset_api_errors() {
859
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
860
  wp_send_json_error();
861
  }
862
-
863
  global $sb_instagram_posts_manager;
864
  $sb_instagram_posts_manager->add_action_log( 'View feed and retry button clicked.' );
865
 
866
  $sb_instagram_posts_manager->reset_api_errors();
867
 
868
- echo "1";
869
-
870
- die();
871
  }
872
  add_action( 'wp_ajax_sbi_reset_api_errors', 'sbi_reset_api_errors' );
873
 
@@ -880,41 +934,50 @@ function sbi_lite_dismiss() {
880
 
881
  set_transient( 'instagram_feed_dismiss_lite', 'dismiss', 1 * WEEK_IN_SECONDS );
882
 
883
- die();
884
  }
885
  add_action( 'wp_ajax_sbi_lite_dismiss', 'sbi_lite_dismiss' );
886
 
887
- add_action('admin_notices', 'sbi_admin_error_notices');
888
  function sbi_admin_error_notices() {
889
  if ( ! current_user_can( 'manage_instagram_feed_options' ) ) {
890
  return;
891
  }
892
- if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'sb-instagram-feed' )) ) {
 
893
 
894
  global $sb_instagram_posts_manager;
895
 
896
  $errors = $sb_instagram_posts_manager->get_errors();
897
- if ( ! empty( $errors ) && (! empty( $errors['database_create'] ) || ! empty( $errors['upload_dir'] )) ) : ?>
898
- <div class="notice notice-warning is-dismissible sbi-admin-notice">
899
- <?php if ( ! empty( $errors['database_create'] ) ) echo '<p>' . $errors['database_create'] . '</p>'; ?>
900
-
901
- <?php if ( ! empty( $errors['upload_dir'] ) ) echo '<p>' . $errors['upload_dir'] . '</p>'; ?>
902
- <p><?php _e( sprintf( 'Visit our %s page for help', '<a href="https://smashballoon.com/instagram-feed/support/faq/" target="_blank">FAQ</a>' ), 'instagram-feed' ); ?></p>
 
 
 
 
 
 
903
 
904
- </div>
905
 
906
- <?php endif;
 
907
  $errors = $sb_instagram_posts_manager->get_critical_errors();
908
- if ( $sb_instagram_posts_manager->are_critical_errors() && ! empty( $errors ) ) : ?>
909
- <div class="notice notice-warning is-dismissible sbi-admin-notice">
910
- <p><strong><?php echo esc_html__( 'Instagram Feed is encountering an error and your feeds may not be updating due to the following reasons:', 'instagram-feed') ; ?></strong></p>
 
911
 
912
- <?php echo $errors; ?>
913
 
914
  <?php
915
  $error_page = $sb_instagram_posts_manager->get_error_page();
916
  if ( $error_page ) {
917
- echo '<a href="' . get_the_permalink( $error_page ) . '" class="sbi-clear-errors-visit-page sbi-space-left button button-secondary">' . __( 'View Feed and Retry', 'instagram-feed' ) . '</a>';
918
  }
919
  if ( $sb_instagram_posts_manager->was_app_permission_related_error() ) :
920
  $accounts_revoked = $sb_instagram_posts_manager->get_app_permission_related_error_ids();
@@ -924,81 +987,19 @@ function sbi_admin_error_notices() {
924
  $accounts_revoked = $accounts_revoked[0];
925
  }
926
  ?>
927
- <p class="sbi_notice"><?php echo sprintf( __('Instagram Feed related data for the account(s) %s was removed due to permission for the Smash Balloon App on Facebook or Instagram being revoked.', 'instagram-feed'), $accounts_revoked ); ?></p>
928
- <?php endif;?>
929
- </div>
930
- <?php endif;
931
- }
932
-
933
- }
934
-
935
- function sbi_get_user_names_of_personal_accounts_not_also_already_updated() {
936
- $sbi_options = get_option( 'sb_instagram_settings', array() );
937
- $users_in_personal_accounts = array();
938
- $non_personal_account_users = array();
939
-
940
- $connected_accounts = isset( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
941
-
942
- if ( ! empty( $connected_accounts ) ) {
943
-
944
- foreach ( $connected_accounts as $account ) {
945
- $account_type = isset( $account['type'] ) ? $account['type'] : 'personal';
946
-
947
- if ( $account_type === 'personal' ) {
948
- $users_in_personal_accounts[] = $account['username'];
949
- } else {
950
- $non_personal_account_users[] = $account['username'];
951
- }
952
-
953
- }
954
-
955
- if ( ! empty( $users_in_personal_accounts ) ) {
956
- $user_accounts_that_need_updating = array();
957
- foreach ( $users_in_personal_accounts as $personal_user ) {
958
- if ( ! in_array( $personal_user, $non_personal_account_users, true ) && $personal_user !== '' ) {
959
- $user_accounts_that_need_updating[] = $personal_user;
960
- }
961
- }
962
-
963
- return $user_accounts_that_need_updating;
964
- }
965
- } elseif ( empty( $connected_accounts ) && ! empty( $sbi_options['sb_instagram_at'] ) ) {
966
- return array( 'your Instagram feed');
967
- }
968
-
969
- return array();
970
- }
971
-
972
- // generates the html for the admin notices
973
- function sbi_notices_html() {
974
-
975
- }
976
- //add_action( 'admin_notices', 'sbi_notices_html', 8 ); // priority 12 for Twitter, priority 10 for Facebook
977
-
978
-
979
- function sbi_get_future_date( $month, $year, $week, $day, $direction ) {
980
- if ( $direction > 0 ) {
981
- $startday = 1;
982
- } else {
983
- $startday = date( 't', mktime(0, 0, 0, $month, 1, $year ) );
984
- }
985
-
986
- $start = mktime( 0, 0, 0, $month, $startday, $year );
987
- $weekday = date( 'N', $start );
988
-
989
- $offset = 0;
990
- if ( $direction * $day >= $direction * $weekday ) {
991
- $offset = -$direction * 7;
992
  }
993
 
994
- $offset += $direction * ($week * 7) + ($day - $weekday);
995
- return mktime( 0, 0, 0, $month, $startday + $offset, $year );
996
  }
997
 
998
  function sbi_admin_hide_unrelated_notices() {
999
 
1000
- // Bail if we're not on a sbi screen or page.
1001
- if ( ! isset( $_GET['page'] ) || ( strpos( $_GET['page'], 'sb-instagram-feed') === false && strpos( $_GET['page'], 'sbi-') === false ) ) {
1002
  return;
1003
  }
1004
 
@@ -1048,11 +1049,24 @@ add_action( 'admin_print_scripts', 'sbi_admin_hide_unrelated_notices' );
1048
  /* Usage */
1049
  add_action( 'admin_notices', 'sbi_usage_opt_in' );
1050
  function sbi_usage_opt_in() {
1051
- if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
 
 
 
1052
  return;
1053
  }
 
1054
  if ( isset( $_GET['trackingdismiss'] ) ) {
1055
- $usage_tracking = get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => false ) );
 
 
 
 
 
 
 
 
 
1056
 
1057
  $usage_tracking['enabled'] = false;
1058
 
@@ -1061,32 +1075,27 @@ function sbi_usage_opt_in() {
1061
  return;
1062
  }
1063
 
1064
- $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options';
1065
-
1066
- $cap = apply_filters( 'sbi_settings_pages_capability', $cap );
1067
- if ( ! current_user_can( $cap ) ) {
1068
- return;
1069
- }
1070
  $usage_tracking = sbi_get_option( 'sbi_usage_tracking', false );
1071
  if ( $usage_tracking ) {
1072
- return;
1073
- }
1074
- ?>
1075
- <div class="notice notice-warning is-dismissible sbi-admin-notice">
1076
-
1077
- <p>
1078
- <strong><?php echo __( 'Help us improve the Instagram Feed plugin', 'instagram-feed' ); ?></strong><br>
1079
- <?php echo __( 'Understanding how you are using the plugin allows us to further improve it. Opt-in below to agree to send a weekly report of plugin usage data.', 'instagram-feed' ); ?>
1080
- <a target="_blank" rel="noopener noreferrer" href="https://smashballoon.com/instagram-feed/usage-tracking/"><?php echo __( 'More information', 'instagram-feed' ); ?></a>
1081
- </p>
1082
- <p>
1083
- <a href="<?php echo admin_url('admin.php?page=sb-instagram-feed&trackingdismiss=1') ?>" class="button button-primary sb-opt-in"><?php echo __( 'Yes, I\'d like to help', 'instagram-feed' ); ?></a>
1084
- <a href="<?php echo admin_url('admin.php?page=sb-instagram-feed&trackingdismiss=1') ?>" class="sb-no-usage-opt-out sbi-space-left button button-secondary"><?php echo __( 'No, thanks', 'instagram-feed' ); ?></a>
1085
- </p>
1086
-
1087
- </div>
1088
 
1089
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
1090
  }
1091
 
1092
  function sbi_usage_opt_in_or_out() {
@@ -1096,13 +1105,19 @@ function sbi_usage_opt_in_or_out() {
1096
  wp_send_json_error();
1097
  }
1098
 
1099
- $usage_tracking = sbi_get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => false ) );
 
 
 
 
 
 
1100
 
1101
- $usage_tracking['enabled'] = isset( $_POST['opted_in'] ) ? $_POST['opted_in'] === 'true' : false;
1102
 
1103
  sbi_update_option( 'sbi_usage_tracking', $usage_tracking, false );
1104
 
1105
- die();
1106
  }
1107
  add_action( 'wp_ajax_sbi_usage_opt_in_or_out', 'sbi_usage_opt_in_or_out' );
1108
 
@@ -1112,15 +1127,15 @@ function sbi_oembed_disable() {
1112
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
1113
  wp_send_json_error();
1114
  }
1115
-
1116
- $oembed_settings = get_option( 'sbi_oembed_token', array() );
1117
  $oembed_settings['access_token'] = '';
1118
- $oembed_settings['disabled'] = true;
1119
  echo '<strong>';
1120
  if ( update_option( 'sbi_oembed_token', $oembed_settings ) ) {
1121
- _e( 'Instagram oEmbeds will no longer be handled by Instagram Feed.', 'instagram-feed' );
1122
  } else {
1123
- _e( 'An error occurred when trying to delete your oEmbed token.', 'instagram-feed' );
1124
  }
1125
  echo '</strong>';
1126
 
10
  * - Displaying admin notices
11
  * - Clearing caches
12
  */
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ die( '-1' );
15
+ }
16
 
17
  function sb_instagram_admin_style() {
18
  wp_register_style( 'sb_instagram_admin_css', SBI_PLUGIN_URL . 'css/sb-instagram-admin.css', array(), SBIVER );
26
  if ( ! current_user_can( 'manage_instagram_feed_options' ) ) {
27
  return;
28
  }
29
+ wp_enqueue_script( 'sb_instagram_admin_js', SBI_PLUGIN_URL . 'js/sb-instagram-admin-2-2.js', array(), SBIVER, true );
30
+ wp_localize_script(
31
+ 'sb_instagram_admin_js',
32
+ 'sbiA',
33
+ array(
34
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
35
+ 'sbi_nonce' => wp_create_nonce( 'sbi_nonce' ),
36
  )
37
  );
38
  $strings = array(
63
  'sbi_admin',
64
  $strings
65
  );
66
+
67
+ wp_enqueue_script( 'jquery' );
68
+ wp_enqueue_script( 'jquery-ui-core' );
69
+ wp_enqueue_script( 'jquery-ui-draggable' );
70
+ wp_enqueue_script( 'wp-color-picker' );
 
 
 
 
 
 
 
 
 
 
71
  }
72
  add_action( 'admin_enqueue_scripts', 'sb_instagram_admin_scripts' );
73
 
74
  // Add a Settings link to the plugin on the Plugins page
75
  $sbi_plugin_file = 'instagram-feed/instagram-feed.php';
76
+ add_filter( "plugin_action_links_$sbi_plugin_file", 'sbi_add_settings_link', 10, 2 );
77
 
78
  //modify the link by unshifting the array
79
+ function sbi_add_settings_link( $links ) {
80
  $pro_link = '<a href="https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=plugins-page&utm_medium=upgrade-link" target="_blank" style="font-weight: bold; color: #1da867;">' . __( 'Try the Pro Demo', 'instagram-feed' ) . '</a>';
81
 
82
+ $sbi_settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=sb-instagram-feed' ) ) . '">' . esc_html__( 'Settings', 'instagram-feed' ) . '</a>';
83
  array_unshift( $links, $pro_link, $sbi_settings_link );
84
 
85
  return $links;
86
  }
87
 
 
88
  /**
89
  * Called via ajax to automatically save access token and access token secret
90
  * retrieved with the big blue button
96
  wp_send_json_error();
97
  }
98
 
99
+ $options = sbi_get_database_settings();
100
+ $new_access_token = isset( $_POST['access_token'] ) ? sanitize_text_field( wp_unslash( $_POST['access_token'] ) ) : false;
101
+ $split_token = $new_access_token ? explode( '.', $new_access_token ) : array();
102
+ $new_user_id = isset( $split_token[0] ) ? $split_token[0] : '';
103
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
104
+ $test_connection_data = sbi_account_data_for_token( $new_access_token );
105
+
106
+ $connected_accounts[ $new_user_id ] = array(
107
+ 'access_token' => sbi_get_parts( $new_access_token ),
108
+ 'user_id' => $test_connection_data['id'],
109
+ 'username' => $test_connection_data['username'],
110
+ 'is_valid' => $test_connection_data['is_valid'],
111
+ 'last_checked' => $test_connection_data['last_checked'],
112
+ 'profile_picture' => $test_connection_data['profile_picture'],
113
+ );
 
 
 
 
 
 
 
 
 
114
 
115
+ if ( ! $options['sb_instagram_disable_resize'] ) {
116
+ if ( sbi_create_local_avatar( $test_connection_data['username'], $test_connection_data['profile_picture'] ) ) {
117
+ $connected_accounts[ $new_user_id ]['local_avatar'] = true;
118
+ }
119
+ } else {
120
+ $connected_accounts[ $new_user_id ]['local_avatar'] = false;
121
+ }
122
 
123
+ $options['connected_accounts'] = $connected_accounts;
124
 
125
+ update_option( 'sb_instagram_settings', $options );
126
 
127
+ wp_send_json_success( $connected_accounts[ $new_user_id ] );
128
  }
129
  add_action( 'wp_ajax_sbi_auto_save_tokens', 'sbi_auto_save_tokens' );
130
 
131
  function sbi_delete_local_avatar( $username ) {
132
  $upload = wp_upload_dir();
133
 
134
+ $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg' ); // get all matching images
135
  foreach ( $image_files as $file ) { // iterate files
136
  if ( is_file( $file ) ) {
137
  unlink( $file );
146
  wp_send_json_error();
147
  }
148
 
149
+ $raw_accounts = ! empty( $_POST['accounts'] ) ? json_decode( wp_unslash( $_POST['accounts'] ), true ) : array();
150
+ $access_token = ! empty( $raw_accounts[0] ) ? sbi_sanitize_alphanumeric_and_equals( $raw_accounts[0]['access_token'] ) : '';
151
+ if ( empty( $access_token ) ) {
152
+ wp_send_json_success( 'No access token' );
153
+ }
154
+
155
+ $ids_to_connect = array();
156
+ foreach ( $raw_accounts as $raw_account ) {
157
+ $ids_to_connect[] = sbi_sanitize_instagram_ids( $raw_account['id'] );
158
+ }
159
+
160
+ $api_accounts = sbi_get_business_pages_list( $access_token );
161
+ if ( empty( $api_accounts ) || is_wp_error( $api_accounts ) ) {
162
+ wp_send_json_success( 'Could not connect' );
163
+ }
164
 
165
  $return = array();
166
+ foreach ( $api_accounts->data as $page => $page_data ) {
167
+ if ( isset( $page_data->instagram_business_account ) && in_array( $page_data->instagram_business_account->id, $ids_to_connect, true ) ) {
168
 
169
+ $instagram_business_id = sbi_sanitize_instagram_ids( $page_data->instagram_business_account->id );
170
+ $page_access_token = isset( $page_data->access_token ) ? sbi_sanitize_alphanumeric_and_equals( $page_data->access_token ) : '';
171
 
172
+ //Make another request to get page info
173
+ $instagram_account_url = 'https://graph.facebook.com/' . $instagram_business_id . '?fields=name,username,profile_picture_url&access_token=' . $access_token;
 
174
 
175
+ $args = array(
176
+ 'timeout' => 20,
177
+ );
178
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
179
+ $args['sslverify'] = false;
180
+ }
181
+ $result = wp_remote_get( $instagram_account_url, $args );
182
+ $instagram_account_info = '{}';
183
+ if ( ! is_wp_error( $result ) ) {
184
+ $instagram_account_info = $result['body'];
185
+ $instagram_account_data = json_decode( $instagram_account_info, true );
186
+
187
+ $instagram_biz_img = ! empty( $instagram_account_data['profile_picture_url'] ) ? $instagram_account_data['profile_picture_url'] : false;
188
+ $account = array(
189
+ 'id' => $instagram_account_data['id'],
190
+ 'name' => $instagram_account_data['name'],
191
+ 'username' => $instagram_account_data['username'],
192
+ 'profile_picture_url' => $instagram_biz_img,
193
+ 'access_token' => $access_token,
194
+ 'page_access_token' => $page_access_token,
195
+ 'type' => 'business',
196
+ );
197
+
198
+ $connector = new SBI_Account_Connector();
199
+
200
+ $connector->add_account_data( $account );
201
+ if ( $connector->update_stored_account() ) {
202
+ $connector->after_update();
203
+
204
+ $return[ $connector->get_id() ] = $connector->get_account_data();
205
+ }
206
+ }
207
  }
208
  }
209
 
210
+ wp_send_json_success( $return );
 
 
211
  }
212
  add_action( 'wp_ajax_sbi_connect_business_accounts', 'sbi_connect_business_accounts' );
213
 
218
  wp_send_json_error();
219
  }
220
 
221
+ $options = get_option( 'sb_instagram_settings', array() );
222
 
223
+ $options['sb_instagram_user_id'] = array( sanitize_text_field( wp_unslash( $_POST['id'] ) ) );
224
 
225
+ update_option( 'sb_instagram_settings', $options );
226
 
227
+ wp_send_json_success();
228
  }
229
  add_action( 'wp_ajax_sbi_auto_save_id', 'sbi_auto_save_id' );
230
 
231
  function sbi_formatted_error( $response ) {
232
  if ( isset( $response['error'] ) ) {
233
+ $error = '<p>' . esc_html( sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) ) . ' ' . esc_html( $response['error']['message'] ) . '</p>';
234
+ $error .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . esc_html__( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
235
 
236
+ return $error;
237
+ } else {
238
+ $message = '<p>' . esc_html( sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] ) ) . '</p>';
239
  if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) {
240
  foreach ( $response['response']->errors as $key => $item ) {
241
+ '<p>' . $message .= ' ' . esc_html( $key ) . ' - ' . esc_html( $item[0] ) . '</p>';
242
  }
243
  }
244
+ $message .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . esc_html__( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
245
 
246
  return $message;
247
+ }
248
  }
249
 
250
  function sbi_test_token() {
255
  }
256
 
257
  $access_token = isset( $_POST['access_token'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['access_token'] ) ) ) : false;
258
+ $account_id = isset( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : false;
259
+ $return_json = sbi_connect_new_account( $access_token, $account_id );
260
 
261
+ if ( strpos( $return_json, '{' ) === 0 ) {
262
+ $return_arr = json_decode( $return_json );
263
+ } else {
264
+ $return_arr = array( 'error_message' => $return_json );
265
+ }
266
 
267
+ wp_send_json_success( $return_arr );
 
268
  }
269
  add_action( 'wp_ajax_sbi_test_token', 'sbi_test_token' );
270
 
275
  wp_send_json_error();
276
  }
277
  $account_id = isset( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : false;
 
278
  sbi_do_account_delete( $account_id );
279
 
280
+ wp_send_json_success();
281
  }
282
  add_action( 'wp_ajax_sbi_delete_account', 'sbi_delete_account' );
283
 
284
  function sbi_account_data_for_token( $access_token ) {
285
  $return = array(
286
+ 'id' => false,
287
+ 'username' => false,
288
+ 'is_valid' => false,
289
+ 'last_checked' => time(),
290
  );
291
+ $url = 'https://api.instagram.com/v1/users/self/?access_token=' . sbi_maybe_clean( $access_token );
292
+ $args = array(
293
+ 'timeout' => 20,
294
  );
295
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
296
  $args['sslverify'] = false;
297
  }
298
  $result = wp_remote_get( $url, $args );
304
  }
305
 
306
  if ( isset( $data->data->id ) ) {
307
+ $return['id'] = $data->data->id;
308
+ $return['username'] = $data->data->username;
309
+ $return['is_valid'] = true;
310
  $return['profile_picture'] = $data->data->profile_picture;
311
 
312
  } elseif ( isset( $data->error_type ) && $data->error_type === 'OAuthRateLimitException' ) {
315
  $return = false;
316
  }
317
 
318
+ $sbi_options = get_option( 'sb_instagram_settings', array() );
319
  $sbi_options['sb_instagram_at'] = '';
320
  update_option( 'sb_instagram_settings', $sbi_options );
321
 
323
  }
324
 
325
  function sbi_do_account_delete( $account_id ) {
326
+ $options = get_option( 'sb_instagram_settings', array() );
327
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
328
  global $sb_instagram_posts_manager;
329
  $sb_instagram_posts_manager->reset_api_errors();
330
 
367
  add_action( 'wp_ajax_sbi_delete_platform_data', 'sbi_delete_platform_data_listener' );
368
 
369
  function sbi_connect_new_account( $access_token, $account_id ) {
370
+ $split_id = explode( ' ', trim( $account_id ) );
371
+ $account_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $split_id[0] );
372
  if ( ! empty( $account_id ) ) {
373
+ $split_token = explode( ' ', trim( $access_token ) );
374
+ $access_token = preg_replace( '/[^A-Za-z0-9 ]/', '', $split_token[0] );
375
  }
376
 
377
  $account = array(
378
  'access_token' => $access_token,
379
+ 'user_id' => $account_id,
380
+ 'type' => 'business',
381
  );
382
 
383
  if ( sbi_code_check( $access_token ) ) {
402
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
403
  return;
404
  }
405
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
406
+ $nonce = isset( $_POST['sb_instagram_settings_nonce'] ) ? $_POST['sb_instagram_settings_nonce'] : false;
407
+ if ( ! wp_verify_nonce( $nonce, 'sb_instagram_saving_settings' ) ) {
408
+ return;
409
+ }
410
  if ( isset( $_POST['sb_manual_at'] ) ) {
411
+ $access_token = isset( $_POST['sb_manual_at'] ) ? sbi_sanitize_alphanumeric_and_equals( $_POST['sb_manual_at'] ) : false;
412
+ $account_id = isset( $_POST['sb_manual_account_id'] ) ? sbi_sanitize_instagram_ids( $_POST['sb_manual_account_id'] ) : false;
413
  if ( ! $access_token || ! $account_id ) {
414
  return;
415
  }
416
  sbi_connect_new_account( $access_token, $account_id );
417
+ } elseif ( isset( $_GET['disconnect'] ) && isset( $_GET['page'] ) && 'sb-instagram-feed' === $_GET['page'] ) {
418
+ $account_id = sbi_sanitize_instagram_ids( $_GET['disconnect'] );
419
  sbi_do_account_delete( $account_id );
420
  }
421
 
422
  }
423
  add_action( 'admin_init', 'sbi_no_js_connected_account_management' );
424
 
425
+ add_action( 'admin_notices', 'sbi_admin_ssl_notice' );
426
  function sbi_admin_ssl_notice() {
427
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
428
  return;
429
  }
430
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
431
+ if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'sb-instagram-feed' ), true ) ) {
432
  global $current_user;
433
+ $user_id = $current_user->ID;
434
+ $was_dismissed = get_user_meta( $user_id, 'sbi_ignore_openssl', true );
435
 
436
  if ( ! $was_dismissed && ! sbi_doing_openssl() ) : ?>
437
+ <div class="notice notice-warning is-dismissible sbi-admin-notice">
438
+ <p><?php echo wp_kses_post( sprintf( __( 'Instagram Feed recommends Open SSL for encrypting Instagram platform data in your database. Contact your host or follow %1$sthese%2$s directions.', 'instagram-feed' ), '<a href="https://www.php.net/manual/en/openssl.installation.php" target="_blank">', '</a>' ) ); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=sb-instagram-feed&openssldismiss=1' ) ); ?>"><?php esc_html_e( 'Dismiss', 'instagram-feed' ); ?></a></p>
439
+ </div>
440
+ <?php
441
+ endif;
442
  }
443
 
444
  }
445
 
446
  add_action( 'admin_init', 'sbi_check_notice_dismiss' );
447
  function sbi_check_notice_dismiss() {
448
+ if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
449
  return;
450
  }
451
  global $current_user;
452
  $user_id = $current_user->ID;
453
 
454
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
455
  if ( isset( $_GET['openssldismiss'] ) ) {
456
+ add_user_meta( $user_id, 'sbi_ignore_openssl', 'true', true );
457
  }
458
  }
459
 
464
  function sbi_get_connected_accounts_data() {
465
  $sbi_options = get_option( 'sb_instagram_settings', array() );
466
 
467
+ return ! empty( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
468
  }
469
 
470
  function sbi_connect_basic_account( $new_account_details ) {
471
+ $options = sbi_get_database_settings();
472
+ $connected_accounts = ! empty( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
473
 
474
+ $accounts_to_save = array();
 
 
 
475
  $old_account_user_id = '';
476
+ $ids_to_save = array();
477
+ $user_ids = is_array( $options['sb_instagram_user_id'] ) ? $options['sb_instagram_user_id'] : explode( ',', str_replace( ' ', '', $options['sb_instagram_user_id'] ) );
478
 
479
  $profile_picture = '';
480
 
481
  // do not connect as a basic display account if already connected as a business account
482
+ if ( isset( $connected_accounts[ $new_account_details['user_id'] ]['type'] ) && 'business' === $connected_accounts[ $new_account_details['user_id'] ]['type'] ) {
 
 
483
  return $options;
484
  }
485
 
486
  foreach ( $connected_accounts as $account ) {
487
+ $account_type = ! empty( $account['type'] ) ? $account['type'] : 'personal';
488
+ if ( ( $account['username'] !== $new_account_details['username'] ) || 'business' === $account_type ) {
 
489
  $accounts_to_save[ $account['user_id'] ] = $account;
490
  } else {
491
  $old_account_user_id = $account['user_id'];
492
+ $profile_picture = ! empty( $account['profile_picture'] ) ? $account['profile_picture'] : '';
493
  }
494
  }
495
 
502
  }
503
 
504
  $accounts_to_save[ $new_account_details['user_id'] ] = array(
505
+ 'access_token' => sbi_fixer( $new_account_details['access_token'] ),
506
+ 'user_id' => $new_account_details['user_id'],
507
+ 'username' => $new_account_details['username'],
508
+ 'is_valid' => true,
509
+ 'last_checked' => time(),
510
  'expires_timestamp' => $new_account_details['expires_timestamp'],
511
+ 'profile_picture' => $profile_picture,
512
+ 'account_type' => strtolower( $new_account_details['account_type'] ),
513
+ 'type' => 'basic',
514
  );
515
 
516
  if ( ! empty( $old_account_user_id ) && $old_account_user_id !== $new_account_details['user_id'] ) {
520
  $fuzzy_matches = sbi_fuzzy_matching_header_data( $old_account_user_id );
521
  if ( ! empty( $fuzzy_matches[0] ) ) {
522
  $header_data = sbi_find_matching_data_from_results( $fuzzy_matches, $old_account_user_id );
523
+ $bio = SB_Instagram_Parse::get_bio( $header_data );
524
  $accounts_to_save[ $new_account_details['user_id'] ]['bio'] = sbi_sanitize_emoji( $bio );
525
  }
 
526
  }
527
 
528
+ if ( ! empty( $profile_picture ) && ! $options['sb_instagram_disable_resize'] ) {
529
  if ( sbi_create_local_avatar( $new_account_details['username'], $profile_picture ) ) {
530
  $accounts_to_save[ $new_account_details['user_id'] ]['local_avatar'] = true;
531
  }
533
  $accounts_to_save[ $new_account_details['user_id'] ]['local_avatar'] = false;
534
  }
535
 
536
+ delete_transient( SBI_USE_BACKUP_PREFIX . 'sbi_' . $new_account_details['user_id'] );
537
  $refresher = new SB_Instagram_Token_Refresher( $accounts_to_save[ $new_account_details['user_id'] ] );
538
  $refresher->attempt_token_refresh();
539
 
540
+ if ( (int) $refresher->get_last_error_code() === 10 ) {
541
  $accounts_to_save[ $new_account_details['user_id'] ]['private'] = true;
542
  }
543
 
544
  $accounts_to_save[ $new_account_details['user_id'] ] = SB_Instagram_Connected_Account::encrypt_connected_account_tokens( $accounts_to_save[ $new_account_details['user_id'] ] );
545
 
546
+ $options['connected_accounts'] = $accounts_to_save;
547
  $options['sb_instagram_user_id'] = $ids_to_save;
548
 
549
  update_option( 'sb_instagram_settings', $options );
 
550
 
 
551
  return $options;
552
  }
553
 
554
  function sbi_fuzzy_matching_header_data( $user_id ) {
 
555
  if ( empty( $user_id ) || strlen( $user_id ) < 4 ) {
556
  return array();
557
  }
558
  global $wpdb;
 
 
 
 
 
 
 
559
 
560
+ $values = $wpdb->get_results(
561
+ $wpdb->prepare(
562
+ "
563
  SELECT option_value
564
  FROM $wpdb->options
565
+ WHERE option_name LIKE (%s)
566
+ LIMIT 10",
567
+ '%!sbi\_header\_' . $user_id . '%'
568
+ ),
569
+ ARRAY_A
570
+ );
571
 
572
  return $values;
573
  }
575
  function sbi_find_matching_data_from_results( $results, $user_id ) {
576
 
577
  $match = array();
578
+ $i = 0;
579
 
580
+ while ( empty( $match ) && isset( $results[ $i ] ) ) {
 
 
581
  if ( ! empty( $results[ $i ] ) ) {
582
  $header_data = json_decode( $results[ $i ]['option_value'], true );
583
+ if ( isset( $header_data['id'] ) && (string) $header_data['id'] === (string) $user_id ) {
584
  $match = $header_data;
585
  }
586
  }
591
  }
592
 
593
  function sbi_matches_existing_personal( $new_account_details ) {
594
+ $options = sbi_get_database_settings();
595
+ $connected_accounts = ! empty( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
 
596
 
597
  $matches_one_account = false;
598
  foreach ( $connected_accounts as $account ) {
599
+ $account_type = ! empty( $account['type'] ) ? $account['type'] : 'personal';
600
+ if ( ( 'personal' === $account_type || 'basic' === $account_type ) && $account['username'] === $new_account_details['username'] ) {
 
601
  $matches_one_account = true;
602
  }
603
  }
604
 
605
  return $matches_one_account;
 
606
  }
607
 
608
  function sbi_business_account_request( $url, $account, $remove_access_token = true ) {
609
  $args = array(
610
+ 'timeout' => 20,
611
  );
612
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
613
  $args['sslverify'] = false;
614
  }
615
  $result = wp_remote_get( $url, $args );
628
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
629
  wp_send_json_error();
630
  }
631
+
632
  if ( isset( $_POST['access_token'] ) ) {
633
+ $access_token = sbi_sanitize_alphanumeric_and_equals( wp_unslash( $_POST['access_token'] ) );
634
+ $account_info = sbi_account_data_for_token( $access_token );
635
+
636
+ wp_send_json_success( $account_info );
637
  }
638
 
639
+ wp_send_json_error();
640
  }
641
  add_action( 'wp_ajax_sbi_after_connection', 'sbi_after_connection' );
642
 
643
+ function sbi_get_business_pages_list( $access_token ) {
644
+ $url = 'https://graph.facebook.com/me/accounts?fields=instagram_business_account,access_token&limit=500&access_token=' . $access_token;
 
 
645
  $args = array(
646
+ 'timeout' => 20,
647
  );
648
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
649
  $args['sslverify'] = false;
650
  }
651
  $result = wp_remote_get( $url, $args );
 
652
  if ( ! is_wp_error( $result ) ) {
653
  $pages_data = $result['body'];
654
+ $return = json_decode( $pages_data );
655
+
656
  } else {
657
+ $return = $result;
658
  }
659
 
660
+ return $return;
661
+ }
662
+
663
+ function sbi_get_business_account_connection_modal( $sb_instagram_user_id ) {
664
+ if ( ! isset( $_GET['sbi_con'] ) || ! wp_verify_nonce( $_GET['sbi_con'], 'sbi-connect' ) ) {
665
+ return;
666
+ }
667
+
668
+ $access_token = ! empty( $_GET['sbi_access_token'] ) ? sbi_sanitize_alphanumeric_and_equals( sbi_maybe_clean( urldecode( ( $_GET['sbi_access_token'] ) ) ) ) : '';
669
+ $api_response = sbi_get_business_pages_list( $access_token );
670
+ $pages_data = array();
671
+ if ( ! is_wp_error( $api_response ) ) {
672
+ $pages_data = $api_response;
673
+ } else {
674
+ $page_error = $api_response;
675
+ }
676
+
677
+ $pages_data_arr = $pages_data;
678
+ $num_accounts = 0;
679
+ if ( isset( $pages_data_arr ) ) {
680
  $num_accounts = is_array( $pages_data_arr->data ) ? count( $pages_data_arr->data ) : 0;
681
  }
682
  ?>
683
+ <div id="sbi_config_info" class="sb_list_businesses sbi_num_businesses_<?php echo esc_attr( $num_accounts ); ?>">
684
+ <div class="sbi_config_modal">
685
+ <div class="sbi-managed-pages">
686
+ <?php
687
+ if ( isset( $page_error ) && isset( $page_error->errors ) ) {
688
+ foreach ( $page_error->errors as $key => $item ) {
689
+ echo '<div class="sbi_user_id_error" style="display:block;"><strong>Connection Error: </strong>' . esc_html( $key ) . ': ' . esc_html( $item[0] ) . '</div>';
690
  }
691
  }
692
  ?>
693
+ <?php if ( empty( $pages_data_arr->data ) ) : ?>
694
+ <div id="sbi-bus-account-error">
695
+ <p style="margin-top: 5px;"><strong style="font-size: 16px">Couldn't find Business Profile</strong><br />
696
+ Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the <a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">Facebook account</a> in this browser which is associated with your Instagram Business Profile.</p>
697
+ <p><strong style="font-size: 16px">Why do I need a Business Profile?</strong><br />
698
+ A Business Profile is only required if you are displaying a Hashtag feed. If you want to display a regular User feed then you can do this by selecting to connect a Personal account instead. For directions on how to convert your Personal profile into a Business profile please <a href="https://smashballoon.com/instagram-business-profiles" target="_blank">see here</a>.</p>
699
+ </div>
700
+
701
+ <?php elseif ( empty( $num_accounts ) ) : ?>
702
+ <div id="sbi-bus-account-error">
703
+ <p style="margin-top: 5px;"><strong style="font-size: 16px">Couldn't find Business Profile</strong><br />
704
+ Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the <a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">Facebook account</a> in this browser which is associated with your Instagram Business Profile.</p>
705
+ <p>If you are, in fact, logged-in to the correct account please make sure you have Instagram accounts connected with your Facebook account by following <a href="https://smashballoon.com/reconnecting-an-instagram-business-profile/" target="_blank">this FAQ</a></p>
706
+ </div>
707
+ <?php else : ?>
708
+ <p class="sbi-managed-page-intro"><strong style="font-size: 16px;">Instagram Business profiles for this account</strong><br /><em style="color: #666;">Note: In order to display a Hashtag feed you first need to select a Business profile below.</em></p>
709
  <?php if ( $num_accounts > 1 ) : ?>
710
+ <div class="sbi-managed-page-select-all"><input type="checkbox" id="sbi-select-all" class="sbi-select-all"><label for="sbi-select-all">Select All</label></div>
711
  <?php endif; ?>
712
+ <div class="sbi-scrollable-accounts">
713
 
714
  <?php foreach ( $pages_data_arr->data as $page => $page_data ) : ?>
715
 
716
+ <?php
717
+ if ( isset( $page_data->instagram_business_account ) ) :
718
 
719
+ $instagram_business_id = sbi_sanitize_instagram_ids( $page_data->instagram_business_account->id );
720
 
721
+ $page_access_token = isset( $page_data->access_token ) ? sbi_sanitize_alphanumeric_and_equals( $page_data->access_token ) : '';
722
 
723
  //Make another request to get page info
724
+ $instagram_account_url = 'https://graph.facebook.com/' . $instagram_business_id . '?fields=name,username,profile_picture_url&access_token=' . $access_token;
725
 
726
  $args = array(
727
+ 'timeout' => 20,
728
  );
729
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
730
  $args['sslverify'] = false;
731
  }
732
+ $result = wp_remote_get( $instagram_account_url, $args );
733
  $instagram_account_info = '{}';
734
  if ( ! is_wp_error( $result ) ) {
735
  $instagram_account_info = $result['body'];
737
  $page_error = $result;
738
  }
739
 
740
+ $instagram_account_data = json_decode( $instagram_account_info );
741
 
742
+ $instagram_biz_img = ! empty( $instagram_account_data->profile_picture_url ) ? $instagram_account_data->profile_picture_url : false;
743
+ $selected_class = $instagram_business_id === $sb_instagram_user_id ? ' sbi-page-selected' : '';
744
 
745
  ?>
746
+ <?php
747
+ if ( isset( $page_error ) && isset( $page_error->errors ) ) :
748
+ foreach ( $page_error->errors as $key => $item ) {
749
+ echo '<div class="sbi_user_id_error" style="display:block;"><strong>Connection Error: </strong>' . esc_html( $key ) . ': ' . esc_html( $item[0] ) . '</div>';
750
+ }
751
+ else :
752
+ ?>
753
+ <div class="sbi-managed-page<?php echo esc_attr( $selected_class ); ?>" data-page-token="<?php echo esc_attr( $page_access_token ); ?>" data-token="<?php echo esc_attr( $access_token ); ?>" data-page-id="<?php echo esc_attr( $instagram_business_id ); ?>">
754
+ <div class="sbi-add-checkbox">
755
+ <input id="sbi-<?php echo esc_attr( $instagram_business_id ); ?>" type="checkbox" name="sbi_managed_pages[]" value="<?php echo esc_attr( $instagram_account_info ); ?>">
756
+ </div>
757
+ <div class="sbi-managed-page-details">
758
+ <label for="sbi-<?php echo esc_attr( $instagram_business_id ); ?>"><img class="sbi-page-avatar" height="50" width="50" src="<?php echo esc_url( $instagram_biz_img ); ?>" alt="<?php echo esc_attr( $instagram_business_id ); ?>"><strong style="font-size: 16px;"><?php echo esc_html( $instagram_account_data->name ); ?></strong>
759
+ <br />@<?php echo esc_html( $instagram_account_data->username ); ?><span style="font-size: 11px; margin-left: 5px;">(<?php echo esc_html( $instagram_business_id ); ?>)</span></label>
760
+ </div>
761
+ </div>
762
  <?php endif; ?>
763
 
764
  <?php endif; ?>
765
 
766
  <?php endforeach; ?>
767
 
768
+ </div> <!-- end scrollable -->
769
+ <p style="font-size: 11px; line-height: 1.5; margin-bottom: 0;"><em style="color: #666;">*<?php echo wp_kses_post( sprintf( __( 'Changing the password, updating privacy settings, or removing page admins for the related Facebook page may require %1$smanually reauthorizing our app%2$s to reconnect an account.', 'instagram-feed' ), '<a href="https://smashballoon.com/reauthorizing-our-instagram-facebook-app/" target="_blank" rel="noopener noreferrer">', '</a>' ) ); ?></em></p>
770
 
771
+ <button id="sbi-connect-business-accounts" class="button button-primary" disabled="disabled" style="margin-top: 20px;"><?php esc_html_e( 'Connect Accounts', 'instagram-feed' ); ?></button>
772
 
773
  <?php endif; ?>
774
 
775
+ <a href="JavaScript:void(0);" class="sbi_modal_close"><i class="fa fa-times"></i></a>
776
+ </div>
777
+ </div>
778
+ </div>
779
+ <?php
780
  }
781
 
782
  function sbi_get_personal_connection_modal( $connected_accounts, $action_url = 'admin.php?page=sb-instagram-feed' ) {
783
+ if ( ! isset( $_GET['sbi_con'] ) || ! wp_verify_nonce( $_GET['sbi_con'], 'sbi-connect' ) ) {
784
+ return;
785
+ }
786
+ $access_token = ! empty( $_GET['sbi_access_token'] ) ? sbi_sanitize_alphanumeric_and_equals( sbi_maybe_clean( urldecode( ( $_GET['sbi_access_token'] ) ) ) ) : '';
787
+ $account_type = ! empty( $_GET['sbi_account_type'] ) ? sbi_sanitize_alphanumeric_and_equals( wp_unslash( $_GET['sbi_account_type'] ) ) : '';
788
+ $user_id = ! empty( $_GET['sbi_id'] ) ? sbi_sanitize_alphanumeric_and_equals( wp_unslash( $_GET['sbi_id'] ) ) : '';
789
+ $user_name = ! empty( $_GET['sbi_username'] ) ? sbi_sanitize_username( wp_unslash( $_GET['sbi_username'] ) ) : '';
790
+ $expires_in = ! empty( $_GET['sbi_expires_in'] ) ? (int) $_GET['sbi_expires_in'] : '';
791
  $expires_timestamp = time() + $expires_in;
792
 
793
  $new_account_details = array(
794
+ 'access_token' => $access_token,
795
+ 'account_type' => $account_type,
796
+ 'user_id' => $user_id,
797
+ 'username' => $user_name,
798
  'expires_timestamp' => $expires_timestamp,
799
+ 'profile_picture' => '',
800
+ 'type' => 'basic',
801
  );
802
 
 
803
  $matches_existing_personal = sbi_matches_existing_personal( $new_account_details );
804
+ $button_text = $matches_existing_personal ? __( 'Update This Account', 'instagram-feed' ) : __( 'Connect This Account', 'instagram-feed' );
805
 
806
  $account_json = sbi_json_encode( $new_account_details );
807
 
808
+ $already_connected_as_business_account = ! empty( $connected_accounts[ $user_id ] ) && 'business' === $connected_accounts[ $user_id ]['type'];
 
809
  ?>
810
 
811
+ <div id="sbi_config_info" class="sb_get_token">
812
+ <div class="sbi_config_modal">
813
+ <div class="sbi_ca_username"><strong><?php echo esc_html( $user_name ); ?></strong></div>
814
+ <form action="<?php echo esc_url( admin_url( $action_url ) ); ?>" method="post">
815
+ <p class="sbi_submit">
816
+ <?php
817
+ if ( $already_connected_as_business_account ) :
818
+ esc_html_e( 'The Instagram account you are logged into is already connected as a "business" account. Remove the business account if you\'d like to connect as a basic account instead (not recommended).', 'instagram-feed' );
819
  ?>
820
  <?php else : ?>
821
+ <input type="submit" name="sbi_submit" id="sbi_connect_account" class="button button-primary" value="<?php echo esc_html( $button_text ); ?>">
822
+ <?php endif; ?>
823
+ <input type="hidden" name="sbi_account_json" value="<?php echo esc_attr( $account_json ); ?>">
824
+ <input type="hidden" name="sbi_connect_username" value="<?php echo esc_attr( $user_name ); ?>">
825
+ <a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts"><?php esc_html_e( 'Switch Accounts', 'instagram-feed' ); ?></a>
826
+ </p>
827
+ </form>
828
+ <a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>
829
+ </div>
830
+ </div>
831
  <?php
832
  }
833
 
834
  function sbi_account_type_display( $type, $private = false ) {
835
+ if ( 'basic' === $type ) {
836
  $type = 'personal';
837
  if ( $private ) {
838
  $type .= ' (private)';
847
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
848
  wp_send_json_error();
849
  }
850
+
851
  //Delete all transients
852
  global $wpdb;
853
+
854
+ $wpdb->query(
855
+ "
856
  DELETE
857
+ FROM $wpdb->options
858
  WHERE `option_name` LIKE ('%!sbi\_%')
859
+ "
860
+ );
861
+ $wpdb->query(
862
+ "
863
  DELETE
864
+ FROM $wpdb->options
865
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
866
+ "
867
+ );
868
+ $wpdb->query(
869
+ "
870
  DELETE
871
+ FROM $wpdb->options
872
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
873
+ "
874
+ );
875
 
876
+ wp_send_json_success();
877
  }
878
  add_action( 'wp_ajax_sbi_clear_backups', 'sbi_clear_backups' );
879
 
883
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
884
  wp_send_json_error();
885
  }
886
+
887
  global $sb_instagram_posts_manager;
888
  $sb_instagram_posts_manager->delete_all_sbi_instagram_posts();
889
  delete_option( 'sbi_top_api_calls' );
890
 
891
  $sb_instagram_posts_manager->add_action_log( 'Reset resizing tables.' );
892
 
893
+ wp_send_json_success( '1' );
 
 
894
  }
895
  add_action( 'wp_ajax_sbi_reset_resized', 'sbi_reset_resized' );
896
 
900
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
901
  wp_send_json_error();
902
  }
903
+
904
  global $sb_instagram_posts_manager;
905
 
906
  $sb_instagram_posts_manager->remove_all_errors();
907
 
908
+ wp_send_json_success( '1' );
 
 
909
  }
910
  add_action( 'wp_ajax_sbi_reset_log', 'sbi_reset_log' );
911
 
915
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
916
  wp_send_json_error();
917
  }
918
+
919
  global $sb_instagram_posts_manager;
920
  $sb_instagram_posts_manager->add_action_log( 'View feed and retry button clicked.' );
921
 
922
  $sb_instagram_posts_manager->reset_api_errors();
923
 
924
+ wp_send_json_success( '1' );
 
 
925
  }
926
  add_action( 'wp_ajax_sbi_reset_api_errors', 'sbi_reset_api_errors' );
927
 
934
 
935
  set_transient( 'instagram_feed_dismiss_lite', 'dismiss', 1 * WEEK_IN_SECONDS );
936
 
937
+ wp_send_json_success( '1' );
938
  }
939
  add_action( 'wp_ajax_sbi_lite_dismiss', 'sbi_lite_dismiss' );
940
 
941
+ add_action( 'admin_notices', 'sbi_admin_error_notices' );
942
  function sbi_admin_error_notices() {
943
  if ( ! current_user_can( 'manage_instagram_feed_options' ) ) {
944
  return;
945
  }
946
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
947
+ if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'sb-instagram-feed' ), true ) ) {
948
 
949
  global $sb_instagram_posts_manager;
950
 
951
  $errors = $sb_instagram_posts_manager->get_errors();
952
+ if ( ! empty( $errors ) && ( ! empty( $errors['database_create'] ) || ! empty( $errors['upload_dir'] ) ) ) :
953
+ ?>
954
+ <div class="notice notice-warning is-dismissible sbi-admin-notice">
955
+ <?php
956
+ if ( ! empty( $errors['database_create'] ) ) {
957
+ echo '<p>' . wp_kses_post( $errors['database_create'] ) . '</p>';
958
+ }
959
+ if ( ! empty( $errors['upload_dir'] ) ) {
960
+ echo '<p>' . wp_kses_post( $errors['upload_dir'] ) . '</p>';
961
+ }
962
+ ?>
963
+ <p><?php echo wp_kses_post( sprintf( __( 'Visit our %s page for help', 'instagram-feed' ), '<a href="https://smashballoon.com/instagram-feed/support/faq/" target="_blank">FAQ</a>' ) ); ?></p>
964
 
965
+ </div>
966
 
967
+ <?php
968
+ endif;
969
  $errors = $sb_instagram_posts_manager->get_critical_errors();
970
+ if ( $sb_instagram_posts_manager->are_critical_errors() && ! empty( $errors ) ) :
971
+ ?>
972
+ <div class="notice notice-warning is-dismissible sbi-admin-notice">
973
+ <p><strong><?php echo esc_html__( 'Instagram Feed is encountering an error and your feeds may not be updating due to the following reasons:', 'instagram-feed' ); ?></strong></p>
974
 
975
+ <?php echo wp_kses_post( $errors ); ?>
976
 
977
  <?php
978
  $error_page = $sb_instagram_posts_manager->get_error_page();
979
  if ( $error_page ) {
980
+ echo '<a href="' . esc_url( get_the_permalink( $error_page ) ) . '" class="sbi-clear-errors-visit-page sbi-space-left button button-secondary">' . esc_html__( 'View Feed and Retry', 'instagram-feed' ) . '</a>';
981
  }
982
  if ( $sb_instagram_posts_manager->was_app_permission_related_error() ) :
983
  $accounts_revoked = $sb_instagram_posts_manager->get_app_permission_related_error_ids();
987
  $accounts_revoked = $accounts_revoked[0];
988
  }
989
  ?>
990
+ <p class="sbi_notice"><?php echo esc_html( sprintf( __( 'Instagram Feed related data for the account(s) %s was removed due to permission for the Smash Balloon App on Facebook or Instagram being revoked.', 'instagram-feed' ), $accounts_revoked ) ); ?></p>
991
+ <?php endif; ?>
992
+ </div>
993
+ <?php
994
+ endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
995
  }
996
 
 
 
997
  }
998
 
999
  function sbi_admin_hide_unrelated_notices() {
1000
 
1001
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1002
+ if ( ! isset( $_GET['page'] ) || ( strpos( $_GET['page'], 'sb-instagram-feed' ) === false && strpos( $_GET['page'], 'sbi-' ) === false ) ) {
1003
  return;
1004
  }
1005
 
1049
  /* Usage */
1050
  add_action( 'admin_notices', 'sbi_usage_opt_in' );
1051
  function sbi_usage_opt_in() {
1052
+ $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options';
1053
+
1054
+ $cap = apply_filters( 'sbi_settings_pages_capability', $cap );
1055
+ if ( ! current_user_can( $cap ) ) {
1056
  return;
1057
  }
1058
+
1059
  if ( isset( $_GET['trackingdismiss'] ) ) {
1060
+ if ( ! isset( $_GET['sbi_nonce'] ) || ! wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-trackingdismiss' ) ) {
1061
+ return;
1062
+ }
1063
+ $usage_tracking = get_option(
1064
+ 'sbi_usage_tracking',
1065
+ array(
1066
+ 'last_send' => 0,
1067
+ 'enabled' => false,
1068
+ )
1069
+ );
1070
 
1071
  $usage_tracking['enabled'] = false;
1072
 
1075
  return;
1076
  }
1077
 
 
 
 
 
 
 
1078
  $usage_tracking = sbi_get_option( 'sbi_usage_tracking', false );
1079
  if ( $usage_tracking ) {
1080
+ return;
1081
+ }
1082
+ $dismiss_href = wp_nonce_url( admin_url( 'admin.php?page=sb-instagram-feed&trackingdismiss=1' ), 'sbi-trackingdismiss', 'sbi_nonce' );
1083
+ ?>
1084
+ <div class="notice notice-warning is-dismissible sbi-admin-notice">
 
 
 
 
 
 
 
 
 
 
 
1085
 
1086
+ <p>
1087
+ <strong><?php esc_html_e( 'Help us improve the Instagram Feed plugin', 'instagram-feed' ); ?></strong><br>
1088
+ <?php esc_html_e( 'Understanding how you are using the plugin allows us to further improve it. Opt-in below to agree to send a weekly report of plugin usage data.', 'instagram-feed' ); ?>
1089
+ <a target="_blank" rel="noopener noreferrer" href="https://smashballoon.com/instagram-feed/usage-tracking/"><?php esc_html_e( 'More information', 'instagram-feed' ); ?></a>
1090
+ </p>
1091
+ <p>
1092
+ <a href="<?php echo esc_url( $dismiss_href ); ?>" class="button button-primary sb-opt-in"><?php esc_html_e( 'Yes, I\'d like to help', 'instagram-feed' ); ?></a>
1093
+ <a href="<?php echo esc_url( $dismiss_href ); ?>" class="sb-no-usage-opt-out sbi-space-left button button-secondary"><?php esc_html_e( 'No, thanks', 'instagram-feed' ); ?></a>
1094
+ </p>
1095
+
1096
+ </div>
1097
+
1098
+ <?php
1099
  }
1100
 
1101
  function sbi_usage_opt_in_or_out() {
1105
  wp_send_json_error();
1106
  }
1107
 
1108
+ $usage_tracking = sbi_get_option(
1109
+ 'sbi_usage_tracking',
1110
+ array(
1111
+ 'last_send' => 0,
1112
+ 'enabled' => false,
1113
+ )
1114
+ );
1115
 
1116
+ $usage_tracking['enabled'] = ! empty( $_POST['opted_in'] ) && 'true' === $_POST['opted_in'];
1117
 
1118
  sbi_update_option( 'sbi_usage_tracking', $usage_tracking, false );
1119
 
1120
+ wp_send_json_success( '1' );
1121
  }
1122
  add_action( 'wp_ajax_sbi_usage_opt_in_or_out', 'sbi_usage_opt_in_or_out' );
1123
 
1127
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
1128
  wp_send_json_error();
1129
  }
1130
+
1131
+ $oembed_settings = get_option( 'sbi_oembed_token', array() );
1132
  $oembed_settings['access_token'] = '';
1133
+ $oembed_settings['disabled'] = true;
1134
  echo '<strong>';
1135
  if ( update_option( 'sbi_oembed_token', $oembed_settings ) ) {
1136
+ esc_html_e( 'Instagram oEmbeds will no longer be handled by Instagram Feed.', 'instagram-feed' );
1137
  } else {
1138
+ esc_html_e( 'An error occurred when trying to delete your oEmbed token.', 'instagram-feed' );
1139
  }
1140
  echo '</strong>';
1141
 
inc/admin/addon-functions.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
 
3
 
4
  /**
5
  * Deactivate addon.
@@ -22,7 +24,7 @@ function sbi_deactivate_addon() {
22
  }
23
 
24
  if ( isset( $_POST['plugin'] ) ) {
25
- deactivate_plugins( wp_unslash( $_POST['plugin'] ) );
26
 
27
  if ( 'plugin' === $type ) {
28
  wp_send_json_success( esc_html__( 'Plugin deactivated.', 'instagram-feed' ) );
@@ -47,7 +49,7 @@ function sbi_activate_addon() {
47
 
48
  // Check for permissions.
49
  if ( ! current_user_can( 'activate_plugins' ) ) {
50
- wp_send_json_error(esc_html__( 'Cant deactivate.', 'instagram-feed' ));
51
  }
52
 
53
  if ( isset( $_POST['plugin'] ) ) {
@@ -57,7 +59,7 @@ function sbi_activate_addon() {
57
  $type = sanitize_key( wp_unslash( $_POST['type'] ) );
58
  }
59
 
60
- $activate = activate_plugins( wp_unslash( $_POST['plugin'] ) );
61
 
62
  if ( ! is_wp_error( $activate ) ) {
63
  if ( 'plugin' === $type ) {
@@ -93,6 +95,11 @@ function sbi_install_addon() {
93
  wp_send_json_error( $error );
94
  }
95
 
 
 
 
 
 
96
  // Set the current screen to avoid undefined notices.
97
  set_current_screen( 'sb-instagram-feed-about' );
98
 
@@ -172,4 +179,4 @@ function sbi_install_addon() {
172
 
173
  wp_send_json_error( $error );
174
  }
175
- add_action( 'wp_ajax_sbi_install_addon', 'sbi_install_addon' );
1
  <?php
2
+ if ( ! defined( 'ABSPATH' ) ){
3
+ exit;
4
+ } // Exit if accessed directly
5
 
6
  /**
7
  * Deactivate addon.
24
  }
25
 
26
  if ( isset( $_POST['plugin'] ) ) {
27
+ deactivate_plugins( preg_replace( '/[^a-z-_\/]/', '', wp_unslash( str_replace( '.php', '', $_POST['plugin'] ) ) ) . '.php' );
28
 
29
  if ( 'plugin' === $type ) {
30
  wp_send_json_success( esc_html__( 'Plugin deactivated.', 'instagram-feed' ) );
49
 
50
  // Check for permissions.
51
  if ( ! current_user_can( 'activate_plugins' ) ) {
52
+ wp_send_json_error( esc_html__( 'Cant deactivate.', 'instagram-feed' ) );
53
  }
54
 
55
  if ( isset( $_POST['plugin'] ) ) {
59
  $type = sanitize_key( wp_unslash( $_POST['type'] ) );
60
  }
61
 
62
+ $activate = activate_plugins( preg_replace( '/[^a-z-_\/]/', '', wp_unslash( str_replace( '.php', '', $_POST['plugin'] ) ) ) . '.php' );
63
 
64
  if ( ! is_wp_error( $activate ) ) {
65
  if ( 'plugin' === $type ) {
95
  wp_send_json_error( $error );
96
  }
97
 
98
+ // Only install plugins from the .org repo
99
+ if ( strpos( $_POST['plugin'], 'https://downloads.wordpress.org/plugin/' ) !== 0 ) {
100
+ wp_send_json_error( $error );
101
+ }
102
+
103
  // Set the current screen to avoid undefined notices.
104
  set_current_screen( 'sb-instagram-feed-about' );
105
 
179
 
180
  wp_send_json_error( $error );
181
  }
182
+ add_action( 'wp_ajax_sbi_install_addon', 'sbi_install_addon' );
inc/admin/blocks/class-sbi-blocks.php CHANGED
@@ -54,9 +54,9 @@ class SB_Instagram_Blocks {
54
  'shortcodeSettings' => array(
55
  'type' => 'string',
56
  ),
57
- 'noNewChanges' => array(
58
  'type' => 'boolean',
59
- )
60
  );
61
 
62
  register_block_type(
@@ -90,10 +90,10 @@ class SB_Instagram_Blocks {
90
  $shortcodeSettings = '';
91
 
92
  $i18n = array(
93
- 'addSettings' => esc_html__( 'Add Settings', 'instagram-feed' ),
94
- 'shortcodeSettings' => esc_html__( 'Shortcode Settings', 'instagram-feed' ),
95
- 'example' => esc_html__( 'Example', 'instagram-feed' ),
96
- 'preview' => esc_html__( 'Apply Changes', 'instagram-feed' ),
97
 
98
  );
99
 
@@ -101,11 +101,11 @@ class SB_Instagram_Blocks {
101
  'sbi-feed-block',
102
  'sbi_block_editor',
103
  array(
104
- 'wpnonce' => wp_create_nonce( 'sb-instagram-blocks' ),
105
- 'canShowFeed' => ! empty( $db['connected_accounts'] ),
106
- 'configureLink' => get_admin_url() . '?page=sb-instagram-feed',
107
- 'shortcodeSettings' => $shortcodeSettings,
108
- 'i18n' => $i18n,
109
  )
110
  );
111
  }
@@ -125,9 +125,9 @@ class SB_Instagram_Blocks {
125
 
126
  $shortcode_settings = isset( $attr['shortcodeSettings'] ) ? $attr['shortcodeSettings'] : '';
127
 
128
- $shortcode_settings = str_replace(array( '[instagram-feed', ']' ), '', $shortcode_settings );
129
 
130
- $return .= do_shortcode( '[instagram-feed '.$shortcode_settings.']' );
131
 
132
  return $return;
133
 
54
  'shortcodeSettings' => array(
55
  'type' => 'string',
56
  ),
57
+ 'noNewChanges' => array(
58
  'type' => 'boolean',
59
+ ),
60
  );
61
 
62
  register_block_type(
90
  $shortcodeSettings = '';
91
 
92
  $i18n = array(
93
+ 'addSettings' => esc_html__( 'Add Settings', 'instagram-feed' ),
94
+ 'shortcodeSettings' => esc_html__( 'Shortcode Settings', 'instagram-feed' ),
95
+ 'example' => esc_html__( 'Example', 'instagram-feed' ),
96
+ 'preview' => esc_html__( 'Apply Changes', 'instagram-feed' ),
97
 
98
  );
99
 
101
  'sbi-feed-block',
102
  'sbi_block_editor',
103
  array(
104
+ 'wpnonce' => wp_create_nonce( 'sb-instagram-blocks' ),
105
+ 'canShowFeed' => ! empty( $db['connected_accounts'] ),
106
+ 'configureLink' => get_admin_url() . '?page=sb-instagram-feed',
107
+ 'shortcodeSettings' => $shortcodeSettings,
108
+ 'i18n' => $i18n,
109
  )
110
  );
111
  }
125
 
126
  $shortcode_settings = isset( $attr['shortcodeSettings'] ) ? $attr['shortcodeSettings'] : '';
127
 
128
+ $shortcode_settings = str_replace( array( '[instagram-feed', ']' ), '', $shortcode_settings );
129
 
130
+ $return .= do_shortcode( '[instagram-feed ' . $shortcode_settings . ']' );
131
 
132
  return $return;
133
 
inc/admin/class-sbi-about.php CHANGED
@@ -74,12 +74,11 @@ class SB_Instagram_About {
74
  'fields' => esc_html__( 'Layouts', 'instagram-feed' ),
75
  'templates' => esc_html__( 'Post Information', 'instagram-feed' ),
76
  'conditionals' => esc_html__( 'Image and Video Display', 'instagram-feed' ),
77
- 'addons' => esc_html__( 'Filtering', 'instagram-feed' ),
78
- //'marketing' => esc_html__( 'Filtering', 'instagram-feed' ),
79
- 'marketing' => esc_html__( 'Instagram Stories', 'instagram-feed' ),
80
- 'payments' => esc_html__( 'Feed Moderation', 'instagram-feed' ),
81
- 'surveys' => esc_html__( 'Header Display', 'instagram-feed' ),
82
- 'advanced' => esc_html__( 'Post Linking', 'instagram-feed' ),
83
  'support' => esc_html__( 'Customer Support', 'instagram-feed' ),
84
  );
85
 
@@ -95,7 +94,8 @@ class SB_Instagram_About {
95
  public function init() {
96
 
97
  // Check what page we are on.
98
- $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
 
99
 
100
  // Only load if we are actually on the settings page.
101
  if ( self::SLUG !== $page ) {
@@ -110,20 +110,14 @@ class SB_Instagram_About {
110
  $this->views = apply_filters(
111
  'sbi_admin_about_views',
112
  array(
113
- esc_html__( 'About Us', 'instagram-feed' ) => array( 'about' ),
114
  esc_html__( 'Getting Started', 'instagram-feed' ) => array( 'getting-started' ),
115
  )
116
  );
117
 
118
  $license = $this->get_license_type();
119
 
120
- if (
121
- (
122
- $license === 'pro' ||
123
- ! in_array( $license, self::$licenses_top, true )
124
- )
125
- //sbi_debug()
126
- ) {
127
  $vs_tab_name = sprintf( /* translators: %1$s - current license type, %2$s - suggested license type. */
128
  esc_html__( '%1$s vs %2$s', 'instagram-feed' ),
129
  ucfirst( $license ),
@@ -134,6 +128,7 @@ class SB_Instagram_About {
134
  }
135
 
136
  // Determine the current active settings tab.
 
137
  $this->view = ! empty( $_GET['view'] ) ? esc_html( wp_unslash( $_GET['view'] ) ) : self::DEFAULT_TAB;
138
 
139
  // If the user tries to load an invalid view - fallback to About Us.
@@ -307,9 +302,9 @@ class SB_Instagram_About {
307
  */
308
  protected function output_about_addons() {
309
 
310
- if ( ! current_user_can( 'manage_instagram_feed_options' ) || version_compare( PHP_VERSION, '5.3.0' ) <= 0
311
- || version_compare( PHP_VERSION, '5.3.0' ) <= 0
312
- || version_compare( get_bloginfo('version'), '4.6' , '<' ) ){
313
  return;
314
  }
315
 
@@ -319,15 +314,15 @@ class SB_Instagram_About {
319
  ?>
320
  <div id="sbi-admin-addons">
321
  <div class="addons-container">
322
- <h3><?php esc_html_e( 'Our Other Plugins', 'instagram-feed' ); ?></h3>
323
  <?php
324
  foreach ( $am_plugins as $plugin => $details ) :
325
 
326
  $plugin_data = $this->get_plugin_data( $plugin, $details, $all_plugins );
327
 
328
  if ( $plugin === 'wpforms-lite/wpforms.php' ) {
329
- echo '<h3>' . esc_html__( 'Plugins We Recommend', 'instagram-feed' ). '</h3>';
330
- }
331
 
332
  ?>
333
  <div class="addon-container">
@@ -467,9 +462,9 @@ class SB_Instagram_About {
467
  <?php esc_html_e( 'Click on the large blue button to connect your Instagram account. Select "Personal" if your Instagram account is a personal account, "Business" if it is a business or creator account.', 'instagram-feed' ); ?>
468
  </p>
469
 
470
- <p>
471
  <?php esc_html_e( 'Once you connect an Instagram account, you can display your feed on any post, page or widget using the shortcode [instagram-feed]. You can also use the Instagram Feed Gutenberg block if your site has the WordPress block editor enabled.', 'instagram-feed' ); ?>
472
- </p>
473
 
474
  <ul class="list-plain">
475
  <li>
@@ -492,7 +487,7 @@ class SB_Instagram_About {
492
  </div>
493
 
494
  <div class="sbi-admin-about-section-first-form-video">
495
- <iframe src="https://www.youtube-nocookie.com/embed/q6ZXVU4g970?rel=0" width="540" height="304" frameborder="0" allow="autoplay; encrypted-media" title="<?php esc_attr_e( 'Watch a video', 'instagram-feed' ); ?>" allowfullscreen></iframe>
496
  </div>
497
 
498
  </div>
@@ -593,13 +588,10 @@ class SB_Instagram_About {
593
 
594
  <h3 class="call-to-action">
595
  <?php
596
- if ( 'lite' === $license ) {
597
- echo '<a href="https://smashballoon.com/instagram-feed/pricing?utm_campaign=instagram-free&utm_source=gettingstarted&utm_medium=profeaturescompare" target="_blank" rel="noopener noreferrer">';
598
- } else {
599
- echo '<a href="https://smashballoon.com/instagram-feed/pricing?utm_campaign=instagram-pro&utm_source=gettingstarted&utm_medium=profeaturescompare" target="_blank" rel="noopener noreferrer">';
600
- }
601
- esc_html_e( 'Get Instagram Feed Pro Today and Unlock all the Powerful Features', 'instagram-feed' );
602
  ?>
 
 
603
  </a>
604
  </h3>
605
 
@@ -623,28 +615,28 @@ class SB_Instagram_About {
623
  <?php } ?>
624
 
625
 
626
- <div class="sbi-admin-about-section sbi-admin-about-section-squashed sbi-admin-about-section-post sbi-admin-columns">
627
- <div class="sbi-admin-column-20">
628
- <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/about/steps.png' ); ?>" alt="">
629
- </div>
630
- <div class="sbi-admin-column-80">
631
- <h2>
632
  <?php esc_html_e( 'Detailed Step-By-Step Guide', 'instagram-feed' ); ?>
633
- </h2>
634
 
635
- <p>
636
  <?php esc_html_e( 'View detailed steps with related images on our website. We have a comprehensive guide to getting up and running with Instagram Feed.', 'instagram-feed' ); ?>
637
- </p>
638
 
639
- <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=gettingstarted&utm_medium=readsetup" target="_blank" rel="noopener noreferrer" class="sbi-admin-about-section-post-link">
640
  <?php esc_html_e( 'Read Documentation', 'instagram-feed' ); ?><i class="fa fa-external-link" aria-hidden="true"></i>
641
- </a>
642
- </div>
643
- </div>
644
 
645
  <div class="sbi-admin-about-section sbi-admin-about-section-squashed sbi-admin-about-section-post sbi-admin-columns">
646
  <div class="sbi-admin-column-20">
647
- <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/about/api-error.png' ); ?>" alt="">
648
  </div>
649
  <div class="sbi-admin-column-80">
650
  <h2>
@@ -692,9 +684,6 @@ class SB_Instagram_About {
692
  * @since 2.4/5.5
693
  */
694
  protected function output_versus() {
695
-
696
- //$license = $this->get_license_type();
697
- //$next_license = $this->get_next_license( $license );
698
  $license = 'lite';
699
  $next_license = 'pro';
700
  ?>
@@ -704,7 +693,7 @@ class SB_Instagram_About {
704
  <strong><?php echo esc_html( ucfirst( $license ) ); ?></strong> vs <strong><?php echo esc_html( ucfirst( $next_license ) ); ?></strong>
705
  </h1>
706
 
707
- <p class="centered" id="sbi_tabledesc">
708
  <?php esc_html_e( 'Get the most out of your Instagram Feeds by upgrading to Pro and unlocking all of the powerful features.', 'instagram-feed' ); ?>
709
  </p>
710
  </div>
@@ -772,11 +761,10 @@ class SB_Instagram_About {
772
  <div class="sbi-admin-about-section-hero-main no-border">
773
  <h3 class="call-to-action centered">
774
  <?php
775
- if ( 'lite' === $license ) {
776
- echo '<a href="https://smashballoon.com/instagram-feed/pricing?utm_campaign=instagram-free&utm_source=gettingstarted&utm_medium=profeaturescompare" target="_blank" rel="noopener noreferrer">';
777
- } else {
778
- echo '<a href="https://smashballoon.com/instagram-feed/pricing?utm_campaign=instagram-pro&utm_source=gettingstarted&utm_medium=profeaturescompare" target="_blank" rel="noopener noreferrer">';
779
- }
780
  printf( /* translators: %s - next license level. */
781
  esc_html__( 'Get Instagram Feed Pro Today and Unlock all the Powerful Features', 'instagram-feed' ),
782
  esc_html( $next_license )
@@ -786,7 +774,7 @@ class SB_Instagram_About {
786
  </h3>
787
 
788
  <?php if ( 'lite' === $license ) { ?>
789
- <p class="centered">
790
  <?php
791
  echo wp_kses(
792
  __( 'Bonus: Instagram Feed Lite users get <span class="price-20-off">50% off regular price</span>, automatically applied at checkout.', 'instagram-feed' ),
@@ -797,7 +785,7 @@ class SB_Instagram_About {
797
  )
798
  );
799
  ?>
800
- </p>
801
  <?php } ?>
802
  </div>
803
  </div>
@@ -847,7 +835,7 @@ class SB_Instagram_About {
847
  ),
848
  ),
849
 
850
- 'feeds-for-youtube/youtube-feed.php' => array(
851
  'icon' => $images_url . 'plugin-yt.png',
852
  'name' => esc_html__( 'Feeds for YouTube', 'instagram-feed' ),
853
  'desc' => esc_html__( 'Feeds for YouTube is a simple yet powerful way to display videos from YouTube on your website. Increase engagement with your channel while keeping visitors on your website.', 'instagram-feed' ),
@@ -862,20 +850,20 @@ class SB_Instagram_About {
862
  ),
863
  ),
864
 
865
- 'wpforms-lite/wpforms.php' => array(
866
- 'icon' => $images_url . 'plugin-wpforms.png',
867
- 'name' => esc_html__( 'WPForms', 'instagram-feed' ),
868
- 'desc' => esc_html__( 'The most beginner friendly drag & drop WordPress forms plugin allowing you to create beautiful contact forms, subscription forms, payment forms, and more in minutes, not hours!', 'instagram-feed' ),
869
- 'url' => 'https://downloads.wordpress.org/plugin/wpforms-lite.zip',
870
- 'pro' => array(
871
- 'plug' => 'wpforms/wpforms.php',
872
- 'icon' => $images_url . 'plugin-wpforms.png',
873
- 'name' => esc_html__( 'WPForms', 'instagram-feed' ),
874
- 'desc' => esc_html__( 'The most beginner friendly drag & drop WordPress forms plugin allowing you to create beautiful contact forms, subscription forms, payment forms, and more in minutes, not hours!', 'instagram-feed' ),
875
- 'url' => 'https://wpforms.com/lite-upgrade/?utm_source=WordPress&utm_campaign=liteplugin&utm_medium=sbi-about-page',
876
- 'act' => 'go-to-url',
877
- ),
878
- ),
879
 
880
  'google-analytics-for-wordpress/googleanalytics.php' => array(
881
  'icon' => $images_url . 'plugin-mi.png',
@@ -892,14 +880,14 @@ class SB_Instagram_About {
892
  ),
893
  ),
894
 
895
- 'optinmonster/optin-monster-wp-api.php' => array(
896
  'icon' => $images_url . 'plugin-om.png',
897
  'name' => esc_html__( 'OptinMonster', 'instagram-feed' ),
898
  'desc' => esc_html__( 'Our high-converting optin forms like Exit-Intent® popups, Fullscreen Welcome Mats, and Scroll boxes help you dramatically boost conversions and get more email subscribers.', 'instagram-feed' ),
899
  'url' => 'https://downloads.wordpress.org/plugin/optinmonster.zip',
900
  ),
901
 
902
- 'wp-mail-smtp/wp_mail_smtp.php' => array(
903
  'icon' => $images_url . 'plugin-smtp.png',
904
  'name' => esc_html__( 'WP Mail SMTP', 'instagram-feed' ),
905
  'desc' => esc_html__( 'Make sure your website\'s emails reach the inbox. Our goal is to make email deliverability easy and reliable. Trusted by over 1 million websites.', 'instagram-feed' ),
@@ -914,7 +902,7 @@ class SB_Instagram_About {
914
  ),
915
  ),
916
 
917
- 'rafflepress/rafflepress.php' => array(
918
  'icon' => $images_url . 'plugin-rp.png',
919
  'name' => esc_html__( 'RafflePress', 'instagram-feed' ),
920
  'desc' => esc_html__( 'Turn your visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with powerful viral giveaways & contests.', 'instagram-feed' ),
@@ -929,7 +917,7 @@ class SB_Instagram_About {
929
  ),
930
  ),
931
 
932
- 'all-in-one-seo-pack/all_in_one_seo_pack.php' => array(
933
  'icon' => $images_url . 'plugin-seo.png',
934
  'name' => esc_html__( 'All In One SEO Pack', 'instagram-feed' ),
935
  'desc' => esc_html__( 'Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007.', 'instagram-feed' ),
@@ -1305,14 +1293,7 @@ class SB_Instagram_About {
1305
  * @return string
1306
  */
1307
  protected function get_license_type() {
1308
-
1309
- //$type = sbi_setting( 'type', '', 'sbi_license' );
1310
-
1311
- //if ( empty( $type ) || ! sbi()->pro ) {
1312
- $type = 'lite';
1313
- //}
1314
-
1315
- return strtolower( $type );
1316
  }
1317
  }
1318
 
74
  'fields' => esc_html__( 'Layouts', 'instagram-feed' ),
75
  'templates' => esc_html__( 'Post Information', 'instagram-feed' ),
76
  'conditionals' => esc_html__( 'Image and Video Display', 'instagram-feed' ),
77
+ 'addons' => esc_html__( 'Filtering', 'instagram-feed' ),
78
+ 'marketing' => esc_html__( 'Instagram Stories', 'instagram-feed' ),
79
+ 'payments' => esc_html__( 'Feed Moderation', 'instagram-feed' ),
80
+ 'surveys' => esc_html__( 'Header Display', 'instagram-feed' ),
81
+ 'advanced' => esc_html__( 'Post Linking', 'instagram-feed' ),
 
82
  'support' => esc_html__( 'Customer Support', 'instagram-feed' ),
83
  );
84
 
94
  public function init() {
95
 
96
  // Check what page we are on.
97
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
98
+ $page = ! empty( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
99
 
100
  // Only load if we are actually on the settings page.
101
  if ( self::SLUG !== $page ) {
110
  $this->views = apply_filters(
111
  'sbi_admin_about_views',
112
  array(
113
+ esc_html__( 'About Us', 'instagram-feed' ) => array( 'about' ),
114
  esc_html__( 'Getting Started', 'instagram-feed' ) => array( 'getting-started' ),
115
  )
116
  );
117
 
118
  $license = $this->get_license_type();
119
 
120
+ if ( 'pro' === $license || ! in_array( $license, self::$licenses_top, true ) ) {
 
 
 
 
 
 
121
  $vs_tab_name = sprintf( /* translators: %1$s - current license type, %2$s - suggested license type. */
122
  esc_html__( '%1$s vs %2$s', 'instagram-feed' ),
123
  ucfirst( $license ),
128
  }
129
 
130
  // Determine the current active settings tab.
131
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
132
  $this->view = ! empty( $_GET['view'] ) ? esc_html( wp_unslash( $_GET['view'] ) ) : self::DEFAULT_TAB;
133
 
134
  // If the user tries to load an invalid view - fallback to About Us.
302
  */
303
  protected function output_about_addons() {
304
 
305
+ if ( ! current_user_can( 'manage_instagram_feed_options' ) || version_compare( PHP_VERSION, '5.3.0' ) <= 0
306
+ || version_compare( PHP_VERSION, '5.3.0' ) <= 0
307
+ || version_compare( get_bloginfo( 'version' ), '4.6', '<' ) ) {
308
  return;
309
  }
310
 
314
  ?>
315
  <div id="sbi-admin-addons">
316
  <div class="addons-container">
317
+ <h3><?php esc_html_e( 'Our Other Plugins', 'instagram-feed' ); ?></h3>
318
  <?php
319
  foreach ( $am_plugins as $plugin => $details ) :
320
 
321
  $plugin_data = $this->get_plugin_data( $plugin, $details, $all_plugins );
322
 
323
  if ( $plugin === 'wpforms-lite/wpforms.php' ) {
324
+ echo '<h3>' . esc_html__( 'Plugins We Recommend', 'instagram-feed' ) . '</h3>';
325
+ }
326
 
327
  ?>
328
  <div class="addon-container">
462
  <?php esc_html_e( 'Click on the large blue button to connect your Instagram account. Select "Personal" if your Instagram account is a personal account, "Business" if it is a business or creator account.', 'instagram-feed' ); ?>
463
  </p>
464
 
465
+ <p>
466
  <?php esc_html_e( 'Once you connect an Instagram account, you can display your feed on any post, page or widget using the shortcode [instagram-feed]. You can also use the Instagram Feed Gutenberg block if your site has the WordPress block editor enabled.', 'instagram-feed' ); ?>
467
+ </p>
468
 
469
  <ul class="list-plain">
470
  <li>
487
  </div>
488
 
489
  <div class="sbi-admin-about-section-first-form-video">
490
+ <iframe src="https://www.youtube-nocookie.com/embed/q6ZXVU4g970?rel=0" width="540" height="304" allow="autoplay; encrypted-media" title="<?php esc_attr_e( 'Watch a video', 'instagram-feed' ); ?>" allowfullscreen></iframe>
491
  </div>
492
 
493
  </div>
588
 
589
  <h3 class="call-to-action">
590
  <?php
591
+ $type = 'lite' === $license ? 'free' : 'pro';
 
 
 
 
 
592
  ?>
593
+ <a href="https://smashballoon.com/instagram-feed/pricing?utm_campaign=instagram-<?php echo esc_attr( $type ); ?>&utm_source=gettingstarted&utm_medium=profeaturescompare" target="_blank" rel="noopener noreferrer">
594
+ <?php esc_html_e( 'Get Instagram Feed Pro Today and Unlock all the Powerful Features', 'instagram-feed' ); ?>
595
  </a>
596
  </h3>
597
 
615
  <?php } ?>
616
 
617
 
618
+ <div class="sbi-admin-about-section sbi-admin-about-section-squashed sbi-admin-about-section-post sbi-admin-columns">
619
+ <div class="sbi-admin-column-20">
620
+ <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/about/steps.png' ); ?>" alt="">
621
+ </div>
622
+ <div class="sbi-admin-column-80">
623
+ <h2>
624
  <?php esc_html_e( 'Detailed Step-By-Step Guide', 'instagram-feed' ); ?>
625
+ </h2>
626
 
627
+ <p>
628
  <?php esc_html_e( 'View detailed steps with related images on our website. We have a comprehensive guide to getting up and running with Instagram Feed.', 'instagram-feed' ); ?>
629
+ </p>
630
 
631
+ <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=gettingstarted&utm_medium=readsetup" target="_blank" rel="noopener noreferrer" class="sbi-admin-about-section-post-link">
632
  <?php esc_html_e( 'Read Documentation', 'instagram-feed' ); ?><i class="fa fa-external-link" aria-hidden="true"></i>
633
+ </a>
634
+ </div>
635
+ </div>
636
 
637
  <div class="sbi-admin-about-section sbi-admin-about-section-squashed sbi-admin-about-section-post sbi-admin-columns">
638
  <div class="sbi-admin-column-20">
639
+ <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/about/api-error.png' ); ?>" alt="">
640
  </div>
641
  <div class="sbi-admin-column-80">
642
  <h2>
684
  * @since 2.4/5.5
685
  */
686
  protected function output_versus() {
 
 
 
687
  $license = 'lite';
688
  $next_license = 'pro';
689
  ?>
693
  <strong><?php echo esc_html( ucfirst( $license ) ); ?></strong> vs <strong><?php echo esc_html( ucfirst( $next_license ) ); ?></strong>
694
  </h1>
695
 
696
+ <p class="centered" id="sbi_tabledesc">
697
  <?php esc_html_e( 'Get the most out of your Instagram Feeds by upgrading to Pro and unlocking all of the powerful features.', 'instagram-feed' ); ?>
698
  </p>
699
  </div>
761
  <div class="sbi-admin-about-section-hero-main no-border">
762
  <h3 class="call-to-action centered">
763
  <?php
764
+ $type = 'lite' === $license ? 'free' : 'pro';
765
+ ?>
766
+ <a href="https://smashballoon.com/instagram-feed/pricing?utm_campaign=instagram-<?php echo esc_attr( $type ); ?>&utm_source=gettingstarted&utm_medium=profeaturescompare" target="_blank" rel="noopener noreferrer">
767
+ <?php
 
768
  printf( /* translators: %s - next license level. */
769
  esc_html__( 'Get Instagram Feed Pro Today and Unlock all the Powerful Features', 'instagram-feed' ),
770
  esc_html( $next_license )
774
  </h3>
775
 
776
  <?php if ( 'lite' === $license ) { ?>
777
+ <p class="centered">
778
  <?php
779
  echo wp_kses(
780
  __( 'Bonus: Instagram Feed Lite users get <span class="price-20-off">50% off regular price</span>, automatically applied at checkout.', 'instagram-feed' ),
785
  )
786
  );
787
  ?>
788
+ </p>
789
  <?php } ?>
790
  </div>
791
  </div>
835
  ),
836
  ),
837
 
838
+ 'feeds-for-youtube/youtube-feed.php' => array(
839
  'icon' => $images_url . 'plugin-yt.png',
840
  'name' => esc_html__( 'Feeds for YouTube', 'instagram-feed' ),
841
  'desc' => esc_html__( 'Feeds for YouTube is a simple yet powerful way to display videos from YouTube on your website. Increase engagement with your channel while keeping visitors on your website.', 'instagram-feed' ),
850
  ),
851
  ),
852
 
853
+ 'wpforms-lite/wpforms.php' => array(
854
+ 'icon' => $images_url . 'plugin-wpforms.png',
855
+ 'name' => esc_html__( 'WPForms', 'instagram-feed' ),
856
+ 'desc' => esc_html__( 'The most beginner friendly drag & drop WordPress forms plugin allowing you to create beautiful contact forms, subscription forms, payment forms, and more in minutes, not hours!', 'instagram-feed' ),
857
+ 'url' => 'https://downloads.wordpress.org/plugin/wpforms-lite.zip',
858
+ 'pro' => array(
859
+ 'plug' => 'wpforms/wpforms.php',
860
+ 'icon' => $images_url . 'plugin-wpforms.png',
861
+ 'name' => esc_html__( 'WPForms', 'instagram-feed' ),
862
+ 'desc' => esc_html__( 'The most beginner friendly drag & drop WordPress forms plugin allowing you to create beautiful contact forms, subscription forms, payment forms, and more in minutes, not hours!', 'instagram-feed' ),
863
+ 'url' => 'https://wpforms.com/lite-upgrade/?utm_source=WordPress&utm_campaign=liteplugin&utm_medium=sbi-about-page',
864
+ 'act' => 'go-to-url',
865
+ ),
866
+ ),
867
 
868
  'google-analytics-for-wordpress/googleanalytics.php' => array(
869
  'icon' => $images_url . 'plugin-mi.png',
880
  ),
881
  ),
882
 
883
+ 'optinmonster/optin-monster-wp-api.php' => array(
884
  'icon' => $images_url . 'plugin-om.png',
885
  'name' => esc_html__( 'OptinMonster', 'instagram-feed' ),
886
  'desc' => esc_html__( 'Our high-converting optin forms like Exit-Intent® popups, Fullscreen Welcome Mats, and Scroll boxes help you dramatically boost conversions and get more email subscribers.', 'instagram-feed' ),
887
  'url' => 'https://downloads.wordpress.org/plugin/optinmonster.zip',
888
  ),
889
 
890
+ 'wp-mail-smtp/wp_mail_smtp.php' => array(
891
  'icon' => $images_url . 'plugin-smtp.png',
892
  'name' => esc_html__( 'WP Mail SMTP', 'instagram-feed' ),
893
  'desc' => esc_html__( 'Make sure your website\'s emails reach the inbox. Our goal is to make email deliverability easy and reliable. Trusted by over 1 million websites.', 'instagram-feed' ),
902
  ),
903
  ),
904
 
905
+ 'rafflepress/rafflepress.php' => array(
906
  'icon' => $images_url . 'plugin-rp.png',
907
  'name' => esc_html__( 'RafflePress', 'instagram-feed' ),
908
  'desc' => esc_html__( 'Turn your visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with powerful viral giveaways & contests.', 'instagram-feed' ),
917
  ),
918
  ),
919
 
920
+ 'all-in-one-seo-pack/all_in_one_seo_pack.php' => array(
921
  'icon' => $images_url . 'plugin-seo.png',
922
  'name' => esc_html__( 'All In One SEO Pack', 'instagram-feed' ),
923
  'desc' => esc_html__( 'Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007.', 'instagram-feed' ),
1293
  * @return string
1294
  */
1295
  protected function get_license_type() {
1296
+ return 'lite';
 
 
 
 
 
 
 
1297
  }
1298
  }
1299
 
inc/admin/class-sbi-account-connector.php CHANGED
@@ -40,10 +40,20 @@ class SBI_Account_Connector {
40
  * @since 5.10
41
  */
42
  public static function maybe_launch_modals( $sb_instagram_user_id ) {
 
 
 
 
 
 
 
 
 
 
43
  if ( ! empty( $_POST ) ) {
44
  return;
45
  }
46
- $connected_accounts = SBI_Account_Connector::stored_connected_accounts();
47
  if ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_graph_api'] ) ) {
48
  sbi_get_business_account_connection_modal( $sb_instagram_user_id );
49
  } elseif ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_account_type'] ) ) {
@@ -90,7 +100,7 @@ class SBI_Account_Connector {
90
  $connection = new SB_Instagram_API_Connect( $data, 'header', array() );
91
  $connection->connect();
92
 
93
- if ( !$connection->is_wp_error() && ! $connection->is_instagram_error() ) {
94
  $new_data = $connection->get_data();
95
 
96
  if ( $data['type'] === 'basic' ) {
@@ -98,32 +108,32 @@ class SBI_Account_Connector {
98
  $basic_account_access_token_connect->connect();
99
  $token_data = $basic_account_access_token_connect->get_data();
100
 
101
- if ( !$basic_account_access_token_connect->is_wp_error() && ! $basic_account_access_token_connect->is_instagram_error() ) {
102
- $expires_in = $token_data['expires_in'];
103
  $expires_timestamp = time() + $expires_in;
104
  } else {
105
  $expires_timestamp = time() + 60 * DAY_IN_SECONDS;
106
  }
107
 
108
  $new_connected_account = array(
109
- 'access_token' => $data['access_token'],
110
- 'account_type' => 'personal',
111
- 'user_id' => $new_data['id'],
112
- 'username' => $new_data['username'],
113
  'expires_timestamp' => $expires_timestamp,
114
- 'type' => 'basic',
115
- 'profile_picture' => ''
116
  );
117
 
118
  } else {
119
  $new_connected_account = array(
120
- 'access_token' => $data['access_token'],
121
- 'id' => $new_data['id'],
122
- 'username' => $new_data['username'],
123
- 'type' => 'business',
124
- 'is_valid' => true,
125
- 'last_checked' => time(),
126
- 'profile_picture' => $new_data['profile_picture_url']
127
  );
128
  }
129
 
@@ -139,7 +149,6 @@ class SBI_Account_Connector {
139
  return array( 'error' => sbi_formatted_error( $error ) );
140
  }
141
 
142
-
143
  }
144
 
145
  /**
@@ -161,39 +170,39 @@ class SBI_Account_Connector {
161
  return false;
162
  }
163
 
164
- $access_token = isset( $data['access_token'] ) ? $data['access_token'] : '';
165
- $page_access_token = isset( $data['page_access_token'] ) ? $data['page_access_token'] : '';
166
- $username = isset( $data['username'] ) ? $data['username'] : '';
167
- $name = isset( $data['name'] ) ? $data['name'] : '';
168
- $profile_picture = isset( $data['profile_picture_url'] ) ? $data['profile_picture_url'] : '';
169
  if ( empty( $profile_picture ) ) {
170
- $profile_picture = isset( $data['profile_picture'] ) ? $data['profile_picture'] : '';
171
  }
172
- $user_id = isset( $data['id'] ) ? $data['id'] : '';
173
- $type = isset( $data['type'] ) ? $data['type'] : 'basic';
174
- $account_type = isset( $data['account_type'] ) ? $data['account_type'] : 'business';
175
- $this->id = $user_id;
176
  $this->account_data = array(
177
- 'access_token' => $access_token,
178
- 'user_id' => $user_id,
179
- 'username' => $username,
180
- 'is_valid' => true,
181
- 'last_checked' => time(),
182
- 'type' => $type,
183
- 'account_type' => $account_type,
184
- 'profile_picture' => ''
185
  );
186
 
187
  if ( $type === 'business' ) {
188
- $this->account_data['use_tagged'] = '1';
189
- $this->account_data['name'] = sbi_sanitize_emoji( $name );
190
- $this->account_data['profile_picture'] = $profile_picture;
191
- $this->account_data['local_avatar'] = SB_Instagram_Connected_Account::create_local_avatar( $username, $profile_picture );
192
  $this->account_data['page_access_token'] = $page_access_token;
193
  }
194
 
195
- if ( isset( $data[ 'expires_timestamp']) ) {
196
- $this->account_data['expires_timestamp'] = $data[ 'expires_timestamp'];
197
  }
198
 
199
  $this->account_data = SB_Instagram_Connected_Account::encrypt_connected_account_tokens( $this->account_data );
@@ -209,8 +218,8 @@ class SBI_Account_Connector {
209
  * @since 5.10
210
  */
211
  public function update_stored_account() {
212
- $options = sbi_get_database_settings();
213
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
214
  $options['connected_accounts'] = $connected_accounts;
215
 
216
  if ( ! empty( $this->account_data ) ) {
@@ -241,8 +250,8 @@ class SBI_Account_Connector {
241
  * @since 5.10
242
  */
243
  public static function stored_connected_accounts() {
244
- $options = sbi_get_database_settings();
245
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
246
  return $connected_accounts;
247
  }
248
- }
40
  * @since 5.10
41
  */
42
  public static function maybe_launch_modals( $sb_instagram_user_id ) {
43
+ if ( ! isset( $_GET['sbi_con'] ) || ! wp_verify_nonce( $_GET['sbi_con'], 'sbi-connect' ) ) {
44
+ if ( isset( $_GET['sbi_con'] ) && ! wp_verify_nonce( $_GET['sbi_con'], 'sbi-connect' ) ) :
45
+ ?>
46
+ <div class="sbi_deprecated">
47
+ <span><?php esc_html_e( 'Oops! The link to connect your account expired. Please try connecting your account again.', 'instagram-feed' ); ?></span>
48
+ </div>
49
+ <?php
50
+ endif;
51
+ return;
52
+ }
53
  if ( ! empty( $_POST ) ) {
54
  return;
55
  }
56
+ $connected_accounts = self::stored_connected_accounts();
57
  if ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_graph_api'] ) ) {
58
  sbi_get_business_account_connection_modal( $sb_instagram_user_id );
59
  } elseif ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_account_type'] ) ) {
100
  $connection = new SB_Instagram_API_Connect( $data, 'header', array() );
101
  $connection->connect();
102
 
103
+ if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
104
  $new_data = $connection->get_data();
105
 
106
  if ( $data['type'] === 'basic' ) {
108
  $basic_account_access_token_connect->connect();
109
  $token_data = $basic_account_access_token_connect->get_data();
110
 
111
+ if ( ! $basic_account_access_token_connect->is_wp_error() && ! $basic_account_access_token_connect->is_instagram_error() ) {
112
+ $expires_in = $token_data['expires_in'];
113
  $expires_timestamp = time() + $expires_in;
114
  } else {
115
  $expires_timestamp = time() + 60 * DAY_IN_SECONDS;
116
  }
117
 
118
  $new_connected_account = array(
119
+ 'access_token' => $data['access_token'],
120
+ 'account_type' => 'personal',
121
+ 'user_id' => $new_data['id'],
122
+ 'username' => $new_data['username'],
123
  'expires_timestamp' => $expires_timestamp,
124
+ 'type' => 'basic',
125
+ 'profile_picture' => '',
126
  );
127
 
128
  } else {
129
  $new_connected_account = array(
130
+ 'access_token' => $data['access_token'],
131
+ 'id' => $new_data['id'],
132
+ 'username' => $new_data['username'],
133
+ 'type' => 'business',
134
+ 'is_valid' => true,
135
+ 'last_checked' => time(),
136
+ 'profile_picture' => $new_data['profile_picture_url'],
137
  );
138
  }
139
 
149
  return array( 'error' => sbi_formatted_error( $error ) );
150
  }
151
 
 
152
  }
153
 
154
  /**
170
  return false;
171
  }
172
 
173
+ $access_token = ! empty( $data['access_token'] ) ? $data['access_token'] : '';
174
+ $page_access_token = ! empty( $data['page_access_token'] ) ? $data['page_access_token'] : '';
175
+ $username = ! empty( $data['username'] ) ? $data['username'] : '';
176
+ $name = ! empty( $data['name'] ) ? $data['name'] : '';
177
+ $profile_picture = ! empty( $data['profile_picture_url'] ) ? $data['profile_picture_url'] : '';
178
  if ( empty( $profile_picture ) ) {
179
+ $profile_picture = ! empty( $data['profile_picture'] ) ? $data['profile_picture'] : '';
180
  }
181
+ $user_id = ! empty( $data['id'] ) ? $data['id'] : '';
182
+ $type = ! empty( $data['type'] ) ? $data['type'] : 'basic';
183
+ $account_type = ! empty( $data['account_type'] ) ? $data['account_type'] : 'business';
184
+ $this->id = $user_id;
185
  $this->account_data = array(
186
+ 'access_token' => $access_token,
187
+ 'user_id' => $user_id,
188
+ 'username' => $username,
189
+ 'is_valid' => true,
190
+ 'last_checked' => time(),
191
+ 'type' => $type,
192
+ 'account_type' => $account_type,
193
+ 'profile_picture' => '',
194
  );
195
 
196
  if ( $type === 'business' ) {
197
+ $this->account_data['use_tagged'] = '1';
198
+ $this->account_data['name'] = sbi_sanitize_emoji( $name );
199
+ $this->account_data['profile_picture'] = $profile_picture;
200
+ $this->account_data['local_avatar'] = SB_Instagram_Connected_Account::create_local_avatar( $username, $profile_picture );
201
  $this->account_data['page_access_token'] = $page_access_token;
202
  }
203
 
204
+ if ( isset( $data['expires_timestamp'] ) ) {
205
+ $this->account_data['expires_timestamp'] = $data['expires_timestamp'];
206
  }
207
 
208
  $this->account_data = SB_Instagram_Connected_Account::encrypt_connected_account_tokens( $this->account_data );
218
  * @since 5.10
219
  */
220
  public function update_stored_account() {
221
+ $options = sbi_get_database_settings();
222
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
223
  $options['connected_accounts'] = $connected_accounts;
224
 
225
  if ( ! empty( $this->account_data ) ) {
250
  * @since 5.10
251
  */
252
  public static function stored_connected_accounts() {
253
+ $options = sbi_get_database_settings();
254
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
255
  return $connected_accounts;
256
  }
257
+ }
inc/admin/class-sbi-new-user.php CHANGED
@@ -37,10 +37,16 @@ class SBI_New_User extends SBI_Notifications {
37
  add_action( 'admin_init', array( $this, 'dismiss' ) );
38
  }
39
 
 
 
 
40
  public function option_name() {
41
  return self::OPTION_NAME;
42
  }
43
 
 
 
 
44
  public function source_url() {
45
  return self::SOURCE_URL;
46
  }
@@ -96,21 +102,21 @@ class SBI_New_User extends SBI_Notifications {
96
  }
97
 
98
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
99
- $current_time = sbi_get_current_time();
100
 
101
  // rating notice logic
102
- $sbi_rating_notice_option = get_option( 'sbi_rating_notice', false );
103
  $sbi_rating_notice_waiting = get_transient( 'instagram_feed_rating_notice_waiting' );
104
- $should_show_rating_notice = ($sbi_rating_notice_waiting !== 'waiting' && $sbi_rating_notice_option !== 'dismissed');
105
 
106
  // new user discount logic
107
- $in_new_user_month_range = true;
108
- $should_show_new_user_discount = false;
109
- $has_been_one_month_since_rating_dismissal = isset( $sbi_statuses_option['rating_notice_dismissed'] ) ? ((int)$sbi_statuses_option['rating_notice_dismissed'] + ((int)$notifications['review']['wait'] * DAY_IN_SECONDS)) < $current_time + 1: true;
110
 
111
  if ( isset( $sbi_statuses_option['first_install'] ) && $sbi_statuses_option['first_install'] === 'from_update' ) {
112
  global $current_user;
113
- $user_id = $current_user->ID;
114
  $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
115
  $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
116
  if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
@@ -118,13 +124,14 @@ class SBI_New_User extends SBI_Notifications {
118
  }
119
  } elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $sbi_rating_notice_waiting !== 'waiting' ) {
120
  global $current_user;
121
- $user_id = $current_user->ID;
122
  $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
123
  $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
124
 
125
- if ( $ignore_new_user_sale_notice_meta !== 'always'
126
- && isset( $sbi_statuses_option['first_install'] )
127
- && $current_time > (int)$sbi_statuses_option['first_install'] + ((int)$notifications['discount']['wait'] * DAY_IN_SECONDS) ) {
 
128
  $should_show_new_user_discount = true;
129
  }
130
  }
@@ -243,9 +250,9 @@ class SBI_New_User extends SBI_Notifications {
243
 
244
  // new user notices included in regular settings page notifications so this
245
  // checks to see if user is one of those pages
246
- if ( ! empty( $_GET['page'] )
247
- && strpos( $_GET['page'], 'sb-instagram-feed' ) !== false ) {
248
- return;
249
  }
250
 
251
  $content_allowed_tags = array(
@@ -260,13 +267,13 @@ class SBI_New_User extends SBI_Notifications {
260
  'rel' => array(),
261
  ),
262
  );
263
- $image_overlay = '';
264
 
265
  foreach ( $notifications as $notification ) {
266
- $type = sanitize_text_field( $notification['id'] );
267
- $close_href = add_query_arg( array( 'sbi_dismiss' => $type ) );
268
- $img_src = SBI_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
269
- $content = '';
270
  if ( ! empty( $notification['content'] ) ) {
271
  $content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
272
  }
@@ -276,7 +283,8 @@ class SBI_New_User extends SBI_Notifications {
276
  if ( ! is_array( $btn['url'] ) ) {
277
  $buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
278
  } elseif ( is_array( $btn['url'] ) ) {
279
- $buttons[ $btn_type ]['url'] = add_query_arg( $btn['url'] );
 
280
  }
281
 
282
  $buttons[ $btn_type ]['attr'] = '';
@@ -296,26 +304,31 @@ class SBI_New_User extends SBI_Notifications {
296
  }
297
  }
298
  if ( isset( $notification['image_overlay'] ) ) {
299
- $image_overlay = '<div class="img-overlay">'. esc_html( $notification['image_overlay'] ).'</div>';
300
  }
301
  }
302
  ?>
303
 
304
- <div class="sbi_notice sbi_<?php echo esc_attr( $type ); ?>_notice">
305
- <div class="sbi_thumb">
306
- <img src="<?php echo esc_url( $img_src ); ?>" alt="notice">
307
- <?php echo $image_overlay; ?>
308
- </div>
309
- <div class="sbi-notice-text">
310
- <p style="padding-top: 4px;"><?php echo $content; ?></p>
311
- <p class="links">
312
  <?php foreach ( $buttons as $button ) : ?>
313
- <a class="<?php echo esc_attr( $button['class'] ); ?>" href="<?php echo esc_attr( $button['url'] ); ?>"<?php echo $button['attr']; ?>><?php echo $button['text']; ?></a>
 
 
 
 
 
314
  <?php endforeach; ?>
315
- </p>
316
- </div>
317
- <a class="sbi_notice_close" href="<?php echo esc_attr( $close_href ); ?>"><i class="fa fa-close"></i></a>
318
- </div>
319
  <?php
320
  }
321
 
@@ -326,62 +339,78 @@ class SBI_New_User extends SBI_Notifications {
326
  */
327
  public function dismiss() {
328
  global $current_user;
329
- $user_id = $current_user->ID;
330
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
331
 
332
  if ( isset( $_GET['sbi_ignore_rating_notice_nag'] ) ) {
333
- if ( (int)$_GET['sbi_ignore_rating_notice_nag'] === 1 ) {
 
 
 
 
334
  update_option( 'sbi_rating_notice', 'dismissed', false );
335
  $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
336
  update_option( 'sbi_statuses', $sbi_statuses_option, false );
337
 
338
- } elseif ( $_GET['sbi_ignore_rating_notice_nag'] === 'later' ) {
339
  set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
340
  update_option( 'sbi_rating_notice', 'pending', false );
341
  }
342
  }
343
 
344
  if ( isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ) {
345
- $response = sanitize_text_field( $_GET['sbi_ignore_new_user_sale_notice'] );
346
- if ( $response === 'always' ) {
 
 
 
347
  update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
348
 
349
- $current_month_number = (int)date('n', sbi_get_current_time() );
350
- $not_early_in_the_year = ($current_month_number > 5);
351
 
352
  if ( $not_early_in_the_year ) {
353
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
354
  }
355
-
356
  }
357
  }
358
 
359
  if ( isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ) {
360
- $response = sanitize_text_field( $_GET['sbi_ignore_bfcm_sale_notice'] );
361
- if ( $response === 'always' ) {
 
 
 
362
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', 'always' );
363
- } elseif ( $response === date( 'Y', sbi_get_current_time() ) ) {
364
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
365
  }
366
  update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
367
  }
368
 
369
  if ( isset( $_GET['sbi_dismiss'] ) ) {
370
- if ( $_GET['sbi_dismiss'] === 'review' ) {
 
 
 
 
371
  update_option( 'sbi_rating_notice', 'dismissed', false );
372
  $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
373
  update_option( 'sbi_statuses', $sbi_statuses_option, false );
374
- } elseif ( $_GET['sbi_dismiss'] === 'discount' ) {
 
 
375
  update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
376
 
377
- $current_month_number = (int)date('n', sbi_get_current_time() );
378
- $not_early_in_the_year = ($current_month_number > 5);
379
 
380
  if ( $not_early_in_the_year ) {
381
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
382
  }
 
 
383
  }
384
- update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
385
  }
386
  }
387
  }
37
  add_action( 'admin_init', array( $this, 'dismiss' ) );
38
  }
39
 
40
+ /**
41
+ * @return string
42
+ */
43
  public function option_name() {
44
  return self::OPTION_NAME;
45
  }
46
 
47
+ /**
48
+ * @return string
49
+ */
50
  public function source_url() {
51
  return self::SOURCE_URL;
52
  }
102
  }
103
 
104
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
105
+ $current_time = sbi_get_current_time();
106
 
107
  // rating notice logic
108
+ $sbi_rating_notice_option = get_option( 'sbi_rating_notice', false );
109
  $sbi_rating_notice_waiting = get_transient( 'instagram_feed_rating_notice_waiting' );
110
+ $should_show_rating_notice = ( $sbi_rating_notice_waiting !== 'waiting' && $sbi_rating_notice_option !== 'dismissed' );
111
 
112
  // new user discount logic
113
+ $in_new_user_month_range = true;
114
+ $should_show_new_user_discount = false;
115
+ $has_been_one_month_since_rating_dismissal = isset( $sbi_statuses_option['rating_notice_dismissed'] ) ? ( (int) $sbi_statuses_option['rating_notice_dismissed'] + ( (int) $notifications['review']['wait'] * DAY_IN_SECONDS ) ) < $current_time + 1 : true;
116
 
117
  if ( isset( $sbi_statuses_option['first_install'] ) && $sbi_statuses_option['first_install'] === 'from_update' ) {
118
  global $current_user;
119
+ $user_id = $current_user->ID;
120
  $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
121
  $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
122
  if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
124
  }
125
  } elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $sbi_rating_notice_waiting !== 'waiting' ) {
126
  global $current_user;
127
+ $user_id = $current_user->ID;
128
  $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
129
  $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
130
 
131
+ if (
132
+ 'always' !== $ignore_new_user_sale_notice_meta &&
133
+ isset( $sbi_statuses_option['first_install'] ) &&
134
+ $current_time > (int) $sbi_statuses_option['first_install'] + ( (int) $notifications['discount']['wait'] * DAY_IN_SECONDS ) ) {
135
  $should_show_new_user_discount = true;
136
  }
137
  }
250
 
251
  // new user notices included in regular settings page notifications so this
252
  // checks to see if user is one of those pages
253
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
254
+ if ( ! empty( $_GET['page'] ) && strpos( $_GET['page'], 'sb-instagram-feed' ) !== false ) {
255
+ return;
256
  }
257
 
258
  $content_allowed_tags = array(
267
  'rel' => array(),
268
  ),
269
  );
270
+ $image_overlay = '';
271
 
272
  foreach ( $notifications as $notification ) {
273
+ $type = sanitize_text_field( $notification['id'] );
274
+ $close_href = wp_nonce_url( add_query_arg( array( 'sbi_dismiss' => $type ) ), 'sbi-' . $type, 'sbi_nonce' );
275
+ $img_src = SBI_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
276
+ $content = '';
277
  if ( ! empty( $notification['content'] ) ) {
278
  $content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
279
  }
283
  if ( ! is_array( $btn['url'] ) ) {
284
  $buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
285
  } elseif ( is_array( $btn['url'] ) ) {
286
+ $buttons[ $btn_type ]['url'] = wp_nonce_url( add_query_arg( $btn['url'] ), 'sbi-' . $type, 'sbi_nonce' );
287
+ $close_href = $buttons[ $btn_type ]['url'];
288
  }
289
 
290
  $buttons[ $btn_type ]['attr'] = '';
304
  }
305
  }
306
  if ( isset( $notification['image_overlay'] ) ) {
307
+ $image_overlay = '<div class="img-overlay">' . esc_html( $notification['image_overlay'] ) . '</div>';
308
  }
309
  }
310
  ?>
311
 
312
+ <div class="sbi_notice sbi_<?php echo esc_attr( $type ); ?>_notice">
313
+ <div class="sbi_thumb">
314
+ <img src="<?php echo esc_url( $img_src ); ?>" alt="notice">
315
+ <?php echo $image_overlay; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
316
+ </div>
317
+ <div class="sbi-notice-text">
318
+ <p style="padding-top: 4px;"><?php echo wp_kses( $content, $content_allowed_tags ); ?></p>
319
+ <p class="links">
320
  <?php foreach ( $buttons as $button ) : ?>
321
+ <a class="<?php echo esc_attr( $button['class'] ); ?>" href="<?php echo esc_attr( $button['url'] ); ?>"
322
+ <?php
323
+ if ( ! empty( $button['attr'] ) ) {
324
+ echo ' target="_blank" rel="noopener noreferrer"'; }
325
+ ?>
326
+ ><?php echo wp_kses( $button['text'], $content_allowed_tags ); ?></a>
327
  <?php endforeach; ?>
328
+ </p>
329
+ </div>
330
+ <a class="sbi_notice_close" href="<?php echo esc_attr( $close_href ); ?>"><i class="fa fa-close"></i></a>
331
+ </div>
332
  <?php
333
  }
334
 
339
  */
340
  public function dismiss() {
341
  global $current_user;
342
+ $user_id = $current_user->ID;
343
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
344
 
345
  if ( isset( $_GET['sbi_ignore_rating_notice_nag'] ) ) {
346
+ $rating_ignore = false;
347
+ if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-review' ) ) {
348
+ $rating_ignore = isset( $_GET['sbi_ignore_rating_notice_nag'] ) ? sanitize_text_field( $_GET['sbi_ignore_rating_notice_nag'] ) : false;
349
+ }
350
+ if ( 1 === (int) $rating_ignore ) {
351
  update_option( 'sbi_rating_notice', 'dismissed', false );
352
  $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
353
  update_option( 'sbi_statuses', $sbi_statuses_option, false );
354
 
355
+ } elseif ( 'later' === $rating_ignore ) {
356
  set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
357
  update_option( 'sbi_rating_notice', 'pending', false );
358
  }
359
  }
360
 
361
  if ( isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ) {
362
+ $new_user_ignore = false;
363
+ if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-discount' ) ) {
364
+ $new_user_ignore = isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ? sanitize_text_field( $_GET['sbi_ignore_new_user_sale_notice'] ) : false;
365
+ }
366
+ if ( 'always' === $new_user_ignore ) {
367
  update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
368
 
369
+ $current_month_number = (int) date( 'n', sbi_get_current_time() );
370
+ $not_early_in_the_year = ( $current_month_number > 5 );
371
 
372
  if ( $not_early_in_the_year ) {
373
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
374
  }
 
375
  }
376
  }
377
 
378
  if ( isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ) {
379
+ $bfcm_ignore = false;
380
+ if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-bfcm' ) ) {
381
+ $bfcm_ignore = isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ? sanitize_text_field( $_GET['sbi_ignore_bfcm_sale_notice'] ) : false;
382
+ }
383
+ if ( 'always' === $bfcm_ignore ) {
384
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', 'always' );
385
+ } elseif ( date( 'Y', sbi_get_current_time() ) === $bfcm_ignore ) {
386
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
387
  }
388
  update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
389
  }
390
 
391
  if ( isset( $_GET['sbi_dismiss'] ) ) {
392
+ $notice_dismiss = false;
393
+ if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-notice-dismiss' ) ) {
394
+ $notice_dismiss = sanitize_text_field( $_GET['sbi_dismiss'] );
395
+ }
396
+ if ( 'review' === $notice_dismiss ) {
397
  update_option( 'sbi_rating_notice', 'dismissed', false );
398
  $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
399
  update_option( 'sbi_statuses', $sbi_statuses_option, false );
400
+
401
+ update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
402
+ } elseif ( 'discount' === $notice_dismiss ) {
403
  update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
404
 
405
+ $current_month_number = (int) date( 'n', sbi_get_current_time() );
406
+ $not_early_in_the_year = ( $current_month_number > 5 );
407
 
408
  if ( $not_early_in_the_year ) {
409
  update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
410
  }
411
+
412
+ update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
413
  }
 
414
  }
415
  }
416
  }
inc/admin/class-sbi-notifications.php CHANGED
@@ -139,9 +139,9 @@ class SBI_Notifications {
139
  */
140
  public function fetch_feed() {
141
  $args = array(
142
- 'timeout' => 20
143
  );
144
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
145
  $args['sslverify'] = false;
146
  }
147
  $res = wp_remote_get( $this->source_url(), $args );
@@ -179,7 +179,7 @@ class SBI_Notifications {
179
 
180
  foreach ( $notifications as $notification ) {
181
  // Ignore if max wp version detected
182
- if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'] , '>=' ) ) {
183
  continue;
184
  }
185
 
@@ -208,9 +208,7 @@ class SBI_Notifications {
208
  // TODO: Ignore if notification existed before installing SBI.
209
  // Prevents bombarding the user with notifications after activation.
210
  $activated = false;
211
- if ( ! empty( $activated )
212
- && ! empty( $notification['start'] )
213
- && $activated > strtotime( $notification['start'] ) ) {
214
  continue;
215
  }
216
 
@@ -237,12 +235,11 @@ class SBI_Notifications {
237
  // Remove notfications that are not active.
238
  foreach ( $notifications as $key => $notification ) {
239
  // Ignore if max wp version detected
240
- if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'] , '>=' ) ) {
241
  unset( $notifications[ $key ] );
242
  }
243
 
244
- if ( ( ! empty( $notification['start'] ) && sbi_get_current_time() < strtotime( $notification['start'] ) )
245
- || ( ! empty( $notification['end'] ) && sbi_get_current_time() > strtotime( $notification['end'] ) ) ) {
246
  unset( $notifications[ $key ] );
247
  }
248
  }
@@ -273,7 +270,7 @@ class SBI_Notifications {
273
  $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
274
 
275
  // If there is a new user notification, add it to the beginning of the notification list
276
- $sbi_newuser = new SBI_New_User();
277
  $newuser_notifications = $sbi_newuser->get();
278
 
279
  if ( ! empty( $newuser_notifications ) ) {
@@ -398,18 +395,18 @@ class SBI_Notifications {
398
  */
399
  public function replace_merge_fields( $content, $notification ) {
400
  $merge_fields = array(
401
- '{plugin}' => 'Instagram Feed',
402
- '{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '',
403
- '{platform}' => 'Instagram',
404
  '{lowerplatform}' => 'instagram',
405
- '{review-url}' => 'https://wordpress.org/support/plugin/instagram-feed/reviews/',
406
- '{slug}' => 'instagram-feed',
407
- '{campaign}' => 'instagram-free'
408
  );
409
 
410
  if ( sbi_is_pro_version() ) {
411
  $merge_fields['{campaign}'] = 'instagram-pro';
412
- $merge_fields['{plugin}'] = 'Instagram Feed Pro';
413
  }
414
 
415
  foreach ( $merge_fields as $find => $replace ) {
@@ -447,13 +444,12 @@ class SBI_Notifications {
447
  );
448
 
449
  foreach ( $notifications as $notification ) {
450
-
451
  // Buttons HTML.
452
  $buttons_html = '';
453
  if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
454
  foreach ( $notification['btns'] as $btn_type => $btn ) {
455
  if ( is_array( $btn['url'] ) ) {
456
- $btn['url'] = add_query_arg( $btn['url'] );
457
  }
458
  if ( ! empty( $btn['attr'] ) ) {
459
  $btn['target'] = '_blank';
@@ -475,9 +471,7 @@ class SBI_Notifications {
475
  $image_html .= '<svg xmlns="http://www.w3.org/2000/svg" width="42" height="48" viewBox="0 0 42 48"><defs><style>.a{fill:#777;}.b{fill:#ca4a1f;}</style></defs><path class="a" d="M23-79a6.005,6.005,0,0,1-6-6h10.06a12.066,12.066,0,0,0,1.791,1.308,6.021,6.021,0,0,1-2.077,3.352A6.008,6.008,0,0,1,23-79Zm1.605-9H5.009a2.955,2.955,0,0,1-2.173-.923A3.088,3.088,0,0,1,2-91a2.919,2.919,0,0,1,.807-2.036c.111-.12.229-.243.351-.371a14.936,14.936,0,0,0,3.126-4.409A23.283,23.283,0,0,0,8.007-107.5a14.846,14.846,0,0,1,.906-5.145,14.5,14.5,0,0,1,2.509-4.324A15.279,15.279,0,0,1,20-122.046V-124a3,3,0,0,1,3-3,3,3,0,0,1,3,3v1.954a15.28,15.28,0,0,1,8.58,5.078,14.5,14.5,0,0,1,2.509,4.324,14.846,14.846,0,0,1,.906,5.145c0,.645.016,1.281.047,1.888A12.036,12.036,0,0,0,35-106a11.921,11.921,0,0,0-8.485,3.515A11.923,11.923,0,0,0,23-94a12,12,0,0,0,1.6,6Z" transform="translate(-2 127)"/><circle class="b" cx="9" cy="9" r="9" transform="translate(24 24)"/></svg>';
476
  $image_html .= '</div>';
477
  } else {
478
- if ( $notification['image'] === 'balloon'
479
- || $notification['id'] === 'review'
480
- || $notification['id'] === 'discount') {
481
  $image_html = '<div class="bell">';
482
 
483
  $image_html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1438 1878" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2">';
@@ -485,12 +479,12 @@ class SBI_Notifications {
485
  $image_html .= ' <path d="M847.02422 174.46342c35.15674 136.02379 29.15212 313.20771 52.0046 461.53578 143.8023 5.71443 285.63982 13.38636 422.53658 26.0027-96.85317 76.4964-198.51497 148.18216-299.02579 221.0189 67.92355 116.26239 137.87024 230.49432 214.51864 338.03024-109.24093-27.28662-245.62461-83.72577-357.53106-130.01269-72.51454 163.67274-127.5956 344.78017-188.51553 520.0459-40.90926-132.4395-55.74329-290.95384-84.50796-435.53712-130.90066 5.79549-294.84493 34.37738-435.53754 52.00418 32.5358-76.00075 166.05902-163.156 234.02026-247.02038-84.84516-64.67037-191.33222-107.69074-266.52363-182.01486 88.35892-50.32349 180.8436-96.51314 260.02295-156.0162-39.69708-114.14683-78.05674-229.63108-123.50878-338.027C402.89923 345.5722 539.9423 433.86629 671.51004 492.98839c59.54684-105.13342 122.3209-207.03677 175.51418-318.52497" fill="#fff"/>';
486
  $image_html .= '</svg>';
487
  } else {
488
- $image_html = '<div class="thumb">';
489
- $img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
490
- $image_html .= '<img src="'.esc_url( $img_src ).'" alt="notice">';
491
 
492
  if ( isset( $notification['image_overlay'] ) ) {
493
- $image_html .= '<div class="img-overlay">'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'</div>';
494
  }
495
  }
496
  $image_html .= '</div>';
@@ -516,18 +510,18 @@ class SBI_Notifications {
516
  }
517
  ?>
518
 
519
- <div id="sbi-notifications">
520
- <a class="dismiss" title="<?php echo esc_attr__( 'Dismiss this message', 'instagram-feed' ); ?>"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
521
 
522
- <div class="navigation">
523
- <a class="prev disabled" title="<?php echo esc_attr__( 'Previous message', 'instagram-feed' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-left" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-left fa-w-10"><path fill="currentColor" d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z" class=""></path></svg></a>
524
- <a class="next disabled" title="<?php echo esc_attr__( 'Next message', 'instagram-feed' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-right fa-w-10"><path fill="currentColor" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" class=""></path></svg></a>
525
- </div>
526
 
527
- <div class="messages">
528
  <?php echo $notifications_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
529
- </div>
530
- </div>
531
  <?php
532
  }
533
 
@@ -546,7 +540,7 @@ class SBI_Notifications {
546
  wp_send_json_error();
547
  }
548
 
549
- $id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
550
 
551
  if ( $id === 'review' ) {
552
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
@@ -557,8 +551,8 @@ class SBI_Notifications {
557
  } elseif ( $id === 'discount' ) {
558
  update_user_meta( get_current_user_id(), 'sbi_ignore_new_user_sale_notice', 'always' );
559
 
560
- $current_month_number = (int)date('n', sbi_get_current_time() );
561
- $not_early_in_the_year = ($current_month_number > 5);
562
 
563
  if ( $not_early_in_the_year ) {
564
  update_user_meta( get_current_user_id(), 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
139
  */
140
  public function fetch_feed() {
141
  $args = array(
142
+ 'timeout' => 20,
143
  );
144
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
145
  $args['sslverify'] = false;
146
  }
147
  $res = wp_remote_get( $this->source_url(), $args );
179
 
180
  foreach ( $notifications as $notification ) {
181
  // Ignore if max wp version detected
182
+ if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'], '>=' ) ) {
183
  continue;
184
  }
185
 
208
  // TODO: Ignore if notification existed before installing SBI.
209
  // Prevents bombarding the user with notifications after activation.
210
  $activated = false;
211
+ if ( ! empty( $activated ) && ! empty( $notification['start'] ) && $activated > strtotime( $notification['start'] ) ) {
 
 
212
  continue;
213
  }
214
 
235
  // Remove notfications that are not active.
236
  foreach ( $notifications as $key => $notification ) {
237
  // Ignore if max wp version detected
238
+ if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'], '>=' ) ) {
239
  unset( $notifications[ $key ] );
240
  }
241
 
242
+ if ( ( ! empty( $notification['start'] ) && sbi_get_current_time() < strtotime( $notification['start'] ) ) || ( ! empty( $notification['end'] ) && sbi_get_current_time() > strtotime( $notification['end'] ) ) ) {
 
243
  unset( $notifications[ $key ] );
244
  }
245
  }
270
  $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
271
 
272
  // If there is a new user notification, add it to the beginning of the notification list
273
+ $sbi_newuser = new SBI_New_User();
274
  $newuser_notifications = $sbi_newuser->get();
275
 
276
  if ( ! empty( $newuser_notifications ) ) {
395
  */
396
  public function replace_merge_fields( $content, $notification ) {
397
  $merge_fields = array(
398
+ '{plugin}' => 'Instagram Feed',
399
+ '{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '',
400
+ '{platform}' => 'Instagram',
401
  '{lowerplatform}' => 'instagram',
402
+ '{review-url}' => 'https://wordpress.org/support/plugin/instagram-feed/reviews/',
403
+ '{slug}' => 'instagram-feed',
404
+ '{campaign}' => 'instagram-free',
405
  );
406
 
407
  if ( sbi_is_pro_version() ) {
408
  $merge_fields['{campaign}'] = 'instagram-pro';
409
+ $merge_fields['{plugin}'] = 'Instagram Feed Pro';
410
  }
411
 
412
  foreach ( $merge_fields as $find => $replace ) {
444
  );
445
 
446
  foreach ( $notifications as $notification ) {
 
447
  // Buttons HTML.
448
  $buttons_html = '';
449
  if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
450
  foreach ( $notification['btns'] as $btn_type => $btn ) {
451
  if ( is_array( $btn['url'] ) ) {
452
+ $btn['url'] = wp_nonce_url( add_query_arg( $btn['url'] ), 'sbi-' . sanitize_key( $notification['id'] ), 'sbi_nonce' );
453
  }
454
  if ( ! empty( $btn['attr'] ) ) {
455
  $btn['target'] = '_blank';
471
  $image_html .= '<svg xmlns="http://www.w3.org/2000/svg" width="42" height="48" viewBox="0 0 42 48"><defs><style>.a{fill:#777;}.b{fill:#ca4a1f;}</style></defs><path class="a" d="M23-79a6.005,6.005,0,0,1-6-6h10.06a12.066,12.066,0,0,0,1.791,1.308,6.021,6.021,0,0,1-2.077,3.352A6.008,6.008,0,0,1,23-79Zm1.605-9H5.009a2.955,2.955,0,0,1-2.173-.923A3.088,3.088,0,0,1,2-91a2.919,2.919,0,0,1,.807-2.036c.111-.12.229-.243.351-.371a14.936,14.936,0,0,0,3.126-4.409A23.283,23.283,0,0,0,8.007-107.5a14.846,14.846,0,0,1,.906-5.145,14.5,14.5,0,0,1,2.509-4.324A15.279,15.279,0,0,1,20-122.046V-124a3,3,0,0,1,3-3,3,3,0,0,1,3,3v1.954a15.28,15.28,0,0,1,8.58,5.078,14.5,14.5,0,0,1,2.509,4.324,14.846,14.846,0,0,1,.906,5.145c0,.645.016,1.281.047,1.888A12.036,12.036,0,0,0,35-106a11.921,11.921,0,0,0-8.485,3.515A11.923,11.923,0,0,0,23-94a12,12,0,0,0,1.6,6Z" transform="translate(-2 127)"/><circle class="b" cx="9" cy="9" r="9" transform="translate(24 24)"/></svg>';
472
  $image_html .= '</div>';
473
  } else {
474
+ if ( 'balloon' === $notification['image'] || 'review' === $notification['id'] || 'discount' === $notification['id'] ) {
 
 
475
  $image_html = '<div class="bell">';
476
 
477
  $image_html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1438 1878" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2">';
479
  $image_html .= ' <path d="M847.02422 174.46342c35.15674 136.02379 29.15212 313.20771 52.0046 461.53578 143.8023 5.71443 285.63982 13.38636 422.53658 26.0027-96.85317 76.4964-198.51497 148.18216-299.02579 221.0189 67.92355 116.26239 137.87024 230.49432 214.51864 338.03024-109.24093-27.28662-245.62461-83.72577-357.53106-130.01269-72.51454 163.67274-127.5956 344.78017-188.51553 520.0459-40.90926-132.4395-55.74329-290.95384-84.50796-435.53712-130.90066 5.79549-294.84493 34.37738-435.53754 52.00418 32.5358-76.00075 166.05902-163.156 234.02026-247.02038-84.84516-64.67037-191.33222-107.69074-266.52363-182.01486 88.35892-50.32349 180.8436-96.51314 260.02295-156.0162-39.69708-114.14683-78.05674-229.63108-123.50878-338.027C402.89923 345.5722 539.9423 433.86629 671.51004 492.98839c59.54684-105.13342 122.3209-207.03677 175.51418-318.52497" fill="#fff"/>';
480
  $image_html .= '</svg>';
481
  } else {
482
+ $image_html = '<div class="thumb">';
483
+ $img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
484
+ $image_html .= '<img src="' . esc_url( $img_src ) . '" alt="notice">';
485
 
486
  if ( isset( $notification['image_overlay'] ) ) {
487
+ $image_html .= '<div class="img-overlay">' . esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ) . '</div>';
488
  }
489
  }
490
  $image_html .= '</div>';
510
  }
511
  ?>
512
 
513
+ <div id="sbi-notifications">
514
+ <a class="dismiss" title="<?php echo esc_attr__( 'Dismiss this message', 'instagram-feed' ); ?>"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
515
 
516
+ <div class="navigation">
517
+ <a class="prev disabled" title="<?php echo esc_attr__( 'Previous message', 'instagram-feed' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-left" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-left fa-w-10"><path fill="currentColor" d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z" class=""></path></svg></a>
518
+ <a class="next disabled" title="<?php echo esc_attr__( 'Next message', 'instagram-feed' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-right fa-w-10"><path fill="currentColor" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" class=""></path></svg></a>
519
+ </div>
520
 
521
+ <div class="messages">
522
  <?php echo $notifications_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
523
+ </div>
524
+ </div>
525
  <?php
526
  }
527
 
540
  wp_send_json_error();
541
  }
542
 
543
+ $id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
544
 
545
  if ( $id === 'review' ) {
546
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
551
  } elseif ( $id === 'discount' ) {
552
  update_user_meta( get_current_user_id(), 'sbi_ignore_new_user_sale_notice', 'always' );
553
 
554
+ $current_month_number = (int) date( 'n', sbi_get_current_time() );
555
+ $not_early_in_the_year = ( $current_month_number > 5 );
556
 
557
  if ( $not_early_in_the_year ) {
558
  update_user_meta( get_current_user_id(), 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
inc/admin/class-sbi-sitehealth.php CHANGED
@@ -45,7 +45,7 @@ class SB_Instagram_SiteHealth {
45
  public function add_tests( $tests ) {
46
  $tests['direct']['sbi_test_check_errors'] = array(
47
  'label' => __( 'Instagram Feed Errors', 'instagram-feed' ),
48
- 'test' => array( $this, 'test_check_errors' )
49
  );
50
 
51
  return $tests;
@@ -68,15 +68,13 @@ class SB_Instagram_SiteHealth {
68
 
69
  global $sb_instagram_posts_manager;
70
 
71
-
72
  if ( $sb_instagram_posts_manager->are_critical_errors() ) {
73
- $link = admin_url( '?page=sb-instagram-feed');
74
- $result['status'] = 'critical';
75
- $result['label'] = __( 'Your Instagram Feed is experiencing an error.', 'instagram-feed' );
76
- $result['description'] = sprintf( __( 'A critical issue has been detected with your Instagram Feed. Visit the %sInstagram Feed settings page%s to fix the issue.', 'instagram-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' );
77
  }
78
 
79
-
80
  return $result;
81
  }
82
- }
45
  public function add_tests( $tests ) {
46
  $tests['direct']['sbi_test_check_errors'] = array(
47
  'label' => __( 'Instagram Feed Errors', 'instagram-feed' ),
48
+ 'test' => array( $this, 'test_check_errors' ),
49
  );
50
 
51
  return $tests;
68
 
69
  global $sb_instagram_posts_manager;
70
 
 
71
  if ( $sb_instagram_posts_manager->are_critical_errors() ) {
72
+ $link = admin_url( '?page=sb-instagram-feed' );
73
+ $result['status'] = 'critical';
74
+ $result['label'] = __( 'Your Instagram Feed is experiencing an error.', 'instagram-feed' );
75
+ $result['description'] = sprintf( __( 'A critical issue has been detected with your Instagram Feed. Visit the %1$sInstagram Feed settings page%2$s to fix the issue.', 'instagram-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' );
76
  }
77
 
 
78
  return $result;
79
  }
80
+ }
inc/admin/class-sbi-tracking.php CHANGED
@@ -27,7 +27,7 @@ class SB_Instagram_Tracking {
27
  }
28
 
29
  private function normalize_and_format( $key, $value ) {
30
- $normal_bools = array(
31
  'sb_instagram_preserve_settings',
32
  'sb_instagram_ajax_theme',
33
  'enqueue_js_in_head',
@@ -72,14 +72,14 @@ class SB_Instagram_Tracking {
72
  'sb_instagram_carousel_pag',
73
  'sb_instagram_carousel_autoplay',
74
  );
75
- $custom_text_settings = array(
76
  'sb_instagram_btn_text',
77
  'sb_instagram_follow_btn_text',
78
  'sb_instagram_custom_bio',
79
  'sb_instagram_custom_avatar',
80
  'sb_instagram_custom_css',
81
  'sb_instagram_custom_js',
82
- 'email_notification_addresses'
83
  );
84
  $comma_separate_counts_settings = array(
85
  'sb_instagram_user_id',
@@ -89,9 +89,9 @@ class SB_Instagram_Tracking {
89
  'sb_instagram_highlight_hashtag',
90
  'sb_instagram_hide_photos',
91
  'sb_instagram_exclude_words',
92
- 'sb_instagram_include_words'
93
  );
94
- $defaults = class_exists( 'SB_Instagram_Settings_Pro' ) ? SB_Instagram_Settings_Pro::default_settings() : SB_Instagram_Settings::default_settings();
95
 
96
  if ( is_array( $value ) ) {
97
  if ( empty( $value ) ) {
@@ -127,7 +127,7 @@ class SB_Instagram_Tracking {
127
  $data = array();
128
 
129
  // Retrieve current theme info
130
- $theme_data = wp_get_theme();
131
 
132
  $count_b = 1;
133
  if ( is_multisite() ) {
@@ -142,68 +142,65 @@ class SB_Instagram_Tracking {
142
  $php_version = ! empty( $php_version ) ? substr( $php_version, 0, strpos( $php_version, '.', strpos( $php_version, '.' ) + 1 ) ) : phpversion();
143
 
144
  global $wp_version;
145
- $data['this_plugin'] = 'if';
146
- $data['php_version'] = $php_version;
147
- $data['mi_version'] = SBIVER;
148
- $data['wp_version'] = $wp_version;
149
- $data['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
150
- $data['multisite'] = is_multisite();
151
- $data['url'] = home_url();
152
- $data['themename'] = $theme_data->Name;
153
- $data['themeversion'] = $theme_data->Version;
154
- $data['pro'] = (int) sbi_is_pro_version();
155
- $data['sites'] = $count_b;
156
- $data['usagetracking'] = get_option( 'sbi_usage_tracking_config', false );
157
- $num_users = function_exists( 'count_users' ) ? count_users() : 'Not Set';
158
- $data['usercount'] = is_array( $num_users ) ? $num_users['total_users'] : 1;
159
- $data['timezoneoffset']= date('P');
160
 
161
  $settings_to_send = array();
162
- $raw_settings = get_option( 'sb_instagram_settings', array() );
163
 
164
  foreach ( $raw_settings as $key => $value ) {
165
  $value = $this->normalize_and_format( $key, $value );
166
 
167
  if ( $value !== false ) {
168
- $key = str_replace( array( 'sb_instagram_', 'sbi_' ), '', $key );
169
  $settings_to_send[ $key ] = $value;
170
  }
171
  }
172
- $con_bus_accounts = 0;
173
  $recently_searched_hashtags = 0;
174
- $access_tokens_tried = array();
175
  if ( isset( $raw_settings['connected_accounts'] ) ) {
176
  foreach ( $raw_settings['connected_accounts'] as $connected_account ) {
177
- if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business') {
178
  $con_bus_accounts++;
179
 
180
  if ( ! in_array( $connected_account['access_token'], $access_tokens_tried, true ) && class_exists( 'SB_Instagram_API_Connect_Pro' ) ) {
181
  $access_tokens_tried[] = $connected_account['access_token'];
182
- $connection = new SB_Instagram_API_Connect_Pro( $connected_account, 'recently_searched_hashtags', array( 'hashtag' => '' ) );
183
  $connection->connect();
184
 
185
- $recently_searched_data = !$connection->is_wp_error() ? $connection->get_data() : false;
186
- $num_hashatags_searched = $recently_searched_data && isset( $recently_searched_data ) && ! isset( $recently_searched_data['data'] ) && is_array( $recently_searched_data ) ? count( $recently_searched_data ) : 0;
187
  $recently_searched_hashtags = $recently_searched_hashtags + $num_hashatags_searched;
188
  }
189
-
190
-
191
  }
192
  }
193
  }
194
- $settings_to_send['business_accounts'] = $con_bus_accounts;
195
  $settings_to_send['recently_searched_hashtags'] = $recently_searched_hashtags;
196
 
197
- $feed_caches = SB_Instagram_Cron_Updater::get_feed_cache_option_names();
198
  $settings_to_send['num_found_feed_caches'] = count( $feed_caches );
199
 
200
-
201
  if ( isset( $settings_to_send['caching_type'] ) && $settings_to_send['caching_type'] !== 'background' ) {
202
  $settings_to_send['recently_requested_caches'] = $settings_to_send['num_found_feed_caches'];
203
  } else {
204
  $settings_to_send['recently_requested_caches'] = 0;
205
  foreach ( $feed_caches as $feed_cache ) {
206
- $feed_id = str_replace( '_transient_', '', $feed_cache['option_name'] );
207
 
208
  $transient = get_transient( $feed_id );
209
 
@@ -211,49 +208,49 @@ class SB_Instagram_Tracking {
211
  $feed_data = json_decode( $transient, true );
212
  $last_requested = isset( $feed_data['last_requested'] ) ? (int) $feed_data['last_requested'] : false;
213
 
214
- if ( !$last_requested || $last_requested > time() - 5 * 3600 * 24 ) {
215
  $settings_to_send['recently_requested_caches']++;
216
  }
217
  }
218
-
219
  }
220
  }
221
 
222
- $settings_to_send['custom_header_template'] = '' !== locate_template( 'sbi/header.php', false, false ) ? 1 : 0;
223
- $settings_to_send['custom_header_boxed_template'] = '' !== locate_template( 'sbi/header-boxed.php', false, false ) ? 1 : 0;
224
  $settings_to_send['custom_header_generic_template'] = '' !== locate_template( 'sbi/header-generic.php', false, false ) ? 1 : 0;
225
- $settings_to_send['custom_item_template'] = '' !== locate_template( 'sbi/item.php', false, false ) ? 1 : 0;
226
- $settings_to_send['custom_footer_template'] = '' !== locate_template( 'sbi/footer.php', false, false ) ? 1 : 0;
227
- $settings_to_send['custom_feed_template'] = '' !== locate_template( 'sbi/feed.php', false, false ) ? 1 : 0;
228
 
229
  $sbi_current_white_names = get_option( 'sb_instagram_white_list_names', array() );
230
- if( empty( $sbi_current_white_names ) ){
231
  $settings_to_send['num_white_lists'] = 0;
232
  } else {
233
  $settings_to_send['num_white_lists'] = count( $sbi_current_white_names );
234
  }
235
 
236
- $data['settings'] = $settings_to_send;
237
 
238
  // Retrieve current plugin information
239
- if( ! function_exists( 'get_plugins' ) ) {
240
  include ABSPATH . '/wp-admin/includes/plugin.php';
241
  }
242
 
243
- $plugins = get_plugins();
244
- $active_plugins = get_option( 'active_plugins', array() );
245
  $plugins_to_send = array();
246
 
247
  foreach ( $plugins as $plugin_path => $plugin ) {
248
  // If the plugin isn't active, don't show it.
249
- if ( ! in_array( $plugin_path, $active_plugins ) )
250
  continue;
 
251
 
252
  $plugins_to_send[] = $plugin['Name'];
253
  }
254
 
255
- $data['active_plugins'] = $plugins_to_send;
256
- $data['locale'] = get_locale();
257
 
258
  return $data;
259
  }
@@ -265,25 +262,34 @@ class SB_Instagram_Tracking {
265
  return false;
266
  }
267
 
268
- if( ! $this->tracking_allowed() && ! $override ) {
269
  return false;
270
  }
271
 
272
  // Send a maximum of once per week
273
- $usage_tracking = get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => sbi_is_pro_version() ) );
 
 
 
 
 
 
274
  if ( is_numeric( $usage_tracking['last_send'] ) && $usage_tracking['last_send'] > strtotime( '-1 week' ) && ! $ignore_last_checkin ) {
275
  return false;
276
  }
277
 
278
- $request = wp_remote_post( 'https://usage.smashballoon.com/v1/checkin/', array(
279
- 'method' => 'POST',
280
- 'timeout' => 5,
281
- 'redirection' => 5,
282
- 'httpversion' => '1.1',
283
- 'blocking' => false,
284
- 'body' => $this->get_data(),
285
- 'user-agent' => 'MI/' . SBIVER . '; ' . get_bloginfo( 'url' )
286
- ) );
 
 
 
287
 
288
  // If we have completed successfully, recheck in 1 week
289
  $usage_tracking['last_send'] = time();
@@ -292,7 +298,13 @@ class SB_Instagram_Tracking {
292
  }
293
 
294
  private function tracking_allowed() {
295
- $usage_tracking = sbi_get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => sbi_is_pro_version() ) );
 
 
 
 
 
 
296
  $tracking_allowed = isset( $usage_tracking['enabled'] ) ? $usage_tracking['enabled'] : sbi_is_pro_version();
297
 
298
  return $tracking_allowed;
@@ -300,20 +312,20 @@ class SB_Instagram_Tracking {
300
 
301
  public function schedule_send() {
302
  if ( ! wp_next_scheduled( 'sbi_usage_tracking_cron' ) ) {
303
- $tracking = array();
304
- $tracking['day'] = rand( 0, 6 );
305
- $tracking['hour'] = rand( 0, 23 );
306
- $tracking['minute'] = rand( 0, 59 );
307
- $tracking['second'] = rand( 0, 59 );
308
- $tracking['offset'] = ( $tracking['day'] * DAY_IN_SECONDS ) +
309
- ( $tracking['hour'] * HOUR_IN_SECONDS ) +
310
- ( $tracking['minute'] * MINUTE_IN_SECONDS ) +
311
- $tracking['second'];
312
- $last_sunday = strtotime("next sunday") - (7 * DAY_IN_SECONDS);
313
- if ( ($last_sunday + $tracking['offset']) > time() + 6 * HOUR_IN_SECONDS ) {
314
  $tracking['initsend'] = $last_sunday + $tracking['offset'];
315
  } else {
316
- $tracking['initsend'] = strtotime("next sunday") + $tracking['offset'];
317
  }
318
 
319
  wp_schedule_event( $tracking['initsend'], 'weekly', 'sbi_usage_tracking_cron' );
@@ -325,9 +337,9 @@ class SB_Instagram_Tracking {
325
  // Adds once weekly to the existing schedules.
326
  $schedules['weekly'] = array(
327
  'interval' => 604800,
328
- 'display' => __( 'Once Weekly', 'instagram-feed' )
329
  );
330
  return $schedules;
331
  }
332
  }
333
- new SB_Instagram_Tracking();
27
  }
28
 
29
  private function normalize_and_format( $key, $value ) {
30
+ $normal_bools = array(
31
  'sb_instagram_preserve_settings',
32
  'sb_instagram_ajax_theme',
33
  'enqueue_js_in_head',
72
  'sb_instagram_carousel_pag',
73
  'sb_instagram_carousel_autoplay',
74
  );
75
+ $custom_text_settings = array(
76
  'sb_instagram_btn_text',
77
  'sb_instagram_follow_btn_text',
78
  'sb_instagram_custom_bio',
79
  'sb_instagram_custom_avatar',
80
  'sb_instagram_custom_css',
81
  'sb_instagram_custom_js',
82
+ 'email_notification_addresses',
83
  );
84
  $comma_separate_counts_settings = array(
85
  'sb_instagram_user_id',
89
  'sb_instagram_highlight_hashtag',
90
  'sb_instagram_hide_photos',
91
  'sb_instagram_exclude_words',
92
+ 'sb_instagram_include_words',
93
  );
94
+ $defaults = class_exists( 'SB_Instagram_Settings_Pro' ) ? SB_Instagram_Settings_Pro::default_settings() : SB_Instagram_Settings::default_settings();
95
 
96
  if ( is_array( $value ) ) {
97
  if ( empty( $value ) ) {
127
  $data = array();
128
 
129
  // Retrieve current theme info
130
+ $theme_data = wp_get_theme();
131
 
132
  $count_b = 1;
133
  if ( is_multisite() ) {
142
  $php_version = ! empty( $php_version ) ? substr( $php_version, 0, strpos( $php_version, '.', strpos( $php_version, '.' ) + 1 ) ) : phpversion();
143
 
144
  global $wp_version;
145
+ $data['this_plugin'] = 'if';
146
+ $data['php_version'] = $php_version;
147
+ $data['mi_version'] = SBIVER;
148
+ $data['wp_version'] = $wp_version;
149
+ $data['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
150
+ $data['multisite'] = is_multisite();
151
+ $data['url'] = home_url();
152
+ $data['themename'] = $theme_data->Name;
153
+ $data['themeversion'] = $theme_data->Version;
154
+ $data['pro'] = (int) sbi_is_pro_version();
155
+ $data['sites'] = $count_b;
156
+ $data['usagetracking'] = get_option( 'sbi_usage_tracking_config', false );
157
+ $num_users = function_exists( 'count_users' ) ? count_users() : 'Not Set';
158
+ $data['usercount'] = is_array( $num_users ) ? $num_users['total_users'] : 1;
159
+ $data['timezoneoffset'] = date( 'P' );
160
 
161
  $settings_to_send = array();
162
+ $raw_settings = get_option( 'sb_instagram_settings', array() );
163
 
164
  foreach ( $raw_settings as $key => $value ) {
165
  $value = $this->normalize_and_format( $key, $value );
166
 
167
  if ( $value !== false ) {
168
+ $key = str_replace( array( 'sb_instagram_', 'sbi_' ), '', $key );
169
  $settings_to_send[ $key ] = $value;
170
  }
171
  }
172
+ $con_bus_accounts = 0;
173
  $recently_searched_hashtags = 0;
174
+ $access_tokens_tried = array();
175
  if ( isset( $raw_settings['connected_accounts'] ) ) {
176
  foreach ( $raw_settings['connected_accounts'] as $connected_account ) {
177
+ if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) {
178
  $con_bus_accounts++;
179
 
180
  if ( ! in_array( $connected_account['access_token'], $access_tokens_tried, true ) && class_exists( 'SB_Instagram_API_Connect_Pro' ) ) {
181
  $access_tokens_tried[] = $connected_account['access_token'];
182
+ $connection = new SB_Instagram_API_Connect_Pro( $connected_account, 'recently_searched_hashtags', array( 'hashtag' => '' ) );
183
  $connection->connect();
184
 
185
+ $recently_searched_data = ! $connection->is_wp_error() ? $connection->get_data() : false;
186
+ $num_hashatags_searched = $recently_searched_data && isset( $recently_searched_data ) && ! isset( $recently_searched_data['data'] ) && is_array( $recently_searched_data ) ? count( $recently_searched_data ) : 0;
187
  $recently_searched_hashtags = $recently_searched_hashtags + $num_hashatags_searched;
188
  }
 
 
189
  }
190
  }
191
  }
192
+ $settings_to_send['business_accounts'] = $con_bus_accounts;
193
  $settings_to_send['recently_searched_hashtags'] = $recently_searched_hashtags;
194
 
195
+ $feed_caches = SB_Instagram_Cron_Updater::get_feed_cache_option_names();
196
  $settings_to_send['num_found_feed_caches'] = count( $feed_caches );
197
 
 
198
  if ( isset( $settings_to_send['caching_type'] ) && $settings_to_send['caching_type'] !== 'background' ) {
199
  $settings_to_send['recently_requested_caches'] = $settings_to_send['num_found_feed_caches'];
200
  } else {
201
  $settings_to_send['recently_requested_caches'] = 0;
202
  foreach ( $feed_caches as $feed_cache ) {
203
+ $feed_id = str_replace( '_transient_', '', $feed_cache['option_name'] );
204
 
205
  $transient = get_transient( $feed_id );
206
 
208
  $feed_data = json_decode( $transient, true );
209
  $last_requested = isset( $feed_data['last_requested'] ) ? (int) $feed_data['last_requested'] : false;
210
 
211
+ if ( ! $last_requested || $last_requested > time() - 5 * 3600 * 24 ) {
212
  $settings_to_send['recently_requested_caches']++;
213
  }
214
  }
 
215
  }
216
  }
217
 
218
+ $settings_to_send['custom_header_template'] = '' !== locate_template( 'sbi/header.php', false, false ) ? 1 : 0;
219
+ $settings_to_send['custom_header_boxed_template'] = '' !== locate_template( 'sbi/header-boxed.php', false, false ) ? 1 : 0;
220
  $settings_to_send['custom_header_generic_template'] = '' !== locate_template( 'sbi/header-generic.php', false, false ) ? 1 : 0;
221
+ $settings_to_send['custom_item_template'] = '' !== locate_template( 'sbi/item.php', false, false ) ? 1 : 0;
222
+ $settings_to_send['custom_footer_template'] = '' !== locate_template( 'sbi/footer.php', false, false ) ? 1 : 0;
223
+ $settings_to_send['custom_feed_template'] = '' !== locate_template( 'sbi/feed.php', false, false ) ? 1 : 0;
224
 
225
  $sbi_current_white_names = get_option( 'sb_instagram_white_list_names', array() );
226
+ if ( empty( $sbi_current_white_names ) ) {
227
  $settings_to_send['num_white_lists'] = 0;
228
  } else {
229
  $settings_to_send['num_white_lists'] = count( $sbi_current_white_names );
230
  }
231
 
232
+ $data['settings'] = $settings_to_send;
233
 
234
  // Retrieve current plugin information
235
+ if ( ! function_exists( 'get_plugins' ) ) {
236
  include ABSPATH . '/wp-admin/includes/plugin.php';
237
  }
238
 
239
+ $plugins = get_plugins();
240
+ $active_plugins = get_option( 'active_plugins', array() );
241
  $plugins_to_send = array();
242
 
243
  foreach ( $plugins as $plugin_path => $plugin ) {
244
  // If the plugin isn't active, don't show it.
245
+ if ( ! in_array( $plugin_path, $active_plugins, true ) ) {
246
  continue;
247
+ }
248
 
249
  $plugins_to_send[] = $plugin['Name'];
250
  }
251
 
252
+ $data['active_plugins'] = $plugins_to_send;
253
+ $data['locale'] = get_locale();
254
 
255
  return $data;
256
  }
262
  return false;
263
  }
264
 
265
+ if ( ! $this->tracking_allowed() && ! $override ) {
266
  return false;
267
  }
268
 
269
  // Send a maximum of once per week
270
+ $usage_tracking = get_option(
271
+ 'sbi_usage_tracking',
272
+ array(
273
+ 'last_send' => 0,
274
+ 'enabled' => sbi_is_pro_version(),
275
+ )
276
+ );
277
  if ( is_numeric( $usage_tracking['last_send'] ) && $usage_tracking['last_send'] > strtotime( '-1 week' ) && ! $ignore_last_checkin ) {
278
  return false;
279
  }
280
 
281
+ $request = wp_remote_post(
282
+ 'https://usage.smashballoon.com/v1/checkin/',
283
+ array(
284
+ 'method' => 'POST',
285
+ 'timeout' => 5,
286
+ 'redirection' => 5,
287
+ 'httpversion' => '1.1',
288
+ 'blocking' => false,
289
+ 'body' => $this->get_data(),
290
+ 'user-agent' => 'MI/' . SBIVER . '; ' . get_bloginfo( 'url' ),
291
+ )
292
+ );
293
 
294
  // If we have completed successfully, recheck in 1 week
295
  $usage_tracking['last_send'] = time();
298
  }
299
 
300
  private function tracking_allowed() {
301
+ $usage_tracking = sbi_get_option(
302
+ 'sbi_usage_tracking',
303
+ array(
304
+ 'last_send' => 0,
305
+ 'enabled' => sbi_is_pro_version(),
306
+ )
307
+ );
308
  $tracking_allowed = isset( $usage_tracking['enabled'] ) ? $usage_tracking['enabled'] : sbi_is_pro_version();
309
 
310
  return $tracking_allowed;
312
 
313
  public function schedule_send() {
314
  if ( ! wp_next_scheduled( 'sbi_usage_tracking_cron' ) ) {
315
+ $tracking = array();
316
+ $tracking['day'] = rand( 0, 6 );
317
+ $tracking['hour'] = rand( 0, 23 );
318
+ $tracking['minute'] = rand( 0, 59 );
319
+ $tracking['second'] = rand( 0, 59 );
320
+ $tracking['offset'] = ( $tracking['day'] * DAY_IN_SECONDS ) +
321
+ ( $tracking['hour'] * HOUR_IN_SECONDS ) +
322
+ ( $tracking['minute'] * MINUTE_IN_SECONDS ) +
323
+ $tracking['second'];
324
+ $last_sunday = strtotime( 'next sunday' ) - ( 7 * DAY_IN_SECONDS );
325
+ if ( ( $last_sunday + $tracking['offset'] ) > time() + 6 * HOUR_IN_SECONDS ) {
326
  $tracking['initsend'] = $last_sunday + $tracking['offset'];
327
  } else {
328
+ $tracking['initsend'] = strtotime( 'next sunday' ) + $tracking['offset'];
329
  }
330
 
331
  wp_schedule_event( $tracking['initsend'], 'weekly', 'sbi_usage_tracking_cron' );
337
  // Adds once weekly to the existing schedules.
338
  $schedules['weekly'] = array(
339
  'interval' => 604800,
340
+ 'display' => __( 'Once Weekly', 'instagram-feed' ),
341
  );
342
  return $schedules;
343
  }
344
  }
345
+ new SB_Instagram_Tracking();
inc/admin/main.php CHANGED
@@ -4,7 +4,9 @@
4
  * functions that add menu pages in the dashboard. Also
5
  * has code for saving settings with defaults.
6
  */
7
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
 
8
 
9
  function sb_instagram_menu() {
10
  $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options';
@@ -18,12 +20,12 @@ function sb_instagram_menu() {
18
  }
19
 
20
  $sbi_notifications = new SBI_Notifications();
21
- $notifications = $sbi_notifications->get();
22
 
23
  $notice_bubble = '';
24
  if ( empty( $notice ) && ! empty( $notifications ) && is_array( $notifications ) ) {
25
- $notice_bubble = ' <span class="sbi-notice-alert"><span>'.count( $notifications ).'</span></span>';
26
- }
27
 
28
  add_menu_page(
29
  __( 'Instagram Feed', 'instagram-feed' ),
@@ -59,7 +61,7 @@ function sb_instagram_menu() {
59
  );
60
 
61
  //Show a Instagram plugin menu item if it isn't already installed
62
- if( !is_plugin_active( 'custom-facebook-feed/custom-facebook-feed.php' ) && !is_plugin_active( 'custom-facebook-feed-pro/custom-facebook-feed.php' ) ){
63
  add_submenu_page(
64
  'sb-instagram-feed',
65
  __( 'Facebook Feed', 'instagram-feed' ),
@@ -71,7 +73,7 @@ function sb_instagram_menu() {
71
  }
72
 
73
  //Show a Twitter plugin menu item if it isn't already installed
74
- if( !is_plugin_active( 'custom-twitter-feeds/custom-twitter-feed.php' ) && !is_plugin_active( 'custom-twitter-feeds-pro/custom-twitter-feed.php' ) ){
75
  add_submenu_page(
76
  'sb-instagram-feed',
77
  __( 'Twitter Feed', 'instagram-feed' ),
@@ -83,7 +85,7 @@ function sb_instagram_menu() {
83
  }
84
 
85
  //Show a YouTube plugin menu item if it isn't already installed
86
- if( !is_plugin_active( 'feeds-for-youtube/youtube-feed.php' ) && !is_plugin_active( 'youtube-feed-pro/youtube-feed.php' ) ){
87
  add_submenu_page(
88
  'sb-instagram-feed',
89
  __( 'YouTube Feed', 'instagram-feed' ),
@@ -106,223 +108,231 @@ function sb_instagram_menu() {
106
  add_submenu_page(
107
  'sb-instagram-feed',
108
  __( 'Try the Pro Demo', 'instagram-feed' ),
109
- __( '<span class="sbi_get_pro">Try the Pro Demo</span>', 'instagram-feed' ),
110
  $cap,
111
  'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=menu-link&utm_medium=upgrade-link',
112
  ''
113
  );
114
-
115
-
116
  }
117
- add_action('admin_menu', 'sb_instagram_menu');
118
 
119
  function sb_instagram_about_page() {
120
- do_action('sbi_admin_page' );
121
  }
 
122
  function sbi_oembeds_page() {
123
- ( is_plugin_active( 'social-wall/social-wall.php' ) ) ? $sbi_sw_active = true : $sbi_sw_active = false;
124
  ?>
125
 
126
- <div id="sbi_admin" class="wrap sbi-oembeds">
127
- <?php
128
- $lite_notice_dismissed = get_transient( 'instagram_feed_dismiss_lite' );
129
-
130
- if ( ! $lite_notice_dismissed ) :
131
- ?>
132
- <div id="sbi-notice-bar" style="display:none">
133
- <span class="sbi-notice-bar-message"><?php _e( 'You\'re using Instagram Feed Lite. To unlock more features consider <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=litenotice" target="_blank" rel="noopener noreferrer">upgrading to Pro</a>.', 'instagram-feed'); ?></span>
134
- <button type="button" class="dismiss" title="<?php esc_html_e( 'Dismiss this message.', 'instagram-feed'); ?>" data-page="overview">
135
- </button>
136
- </div>
137
- <?php endif; ?>
138
- <div id="header">
139
- <h1><?php esc_html_e('Instagram oEmbeds', 'instagram-feed'); ?></h1>
140
- </div>
141
-
142
- <p>
143
- <?php
144
- esc_html_e( "You can use the Instagram Feed plugin to power your Instagram oEmbeds, both old and new.", 'instagram-feed' );
145
- if ( ! SB_Instagram_Oembed::can_do_oembed() ) {
146
- echo ' ';
147
- esc_html_e( "Just click the button below and we'll do the rest.", 'instagram-feed' );
148
- }
149
- ?>
150
- </p>
151
-
152
- <div class="sbi-oembed-button">
153
 
154
- <?php
155
- $admin_url_state = admin_url('admin.php?page=sbi-oembeds');
156
- //If the admin_url isn't returned correctly then use a fallback
157
- if ( $admin_url_state == '/wp-admin/admin.php?page=sbi-oembeds' ){
158
- $admin_url_state = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
159
- }
160
- $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
161
- $saved_access_token_data = isset( $oembed_token_settings['access_token'] ) ? $oembed_token_settings['access_token'] : false;
162
-
163
- $access_token_error = false;
164
- $valid_new_access_token = false;
165
- $error_message = '';
166
- $show_token_expiration_modal = false;
167
- if ( ! empty( $_GET['sbi_access_token'] ) && strlen( $_GET['sbi_access_token'] ) <= 20 ) {
168
- $access_token_error = true;
169
- $error_message = __("There was a problem with the access token that was retrieved.", 'instagram-feed' );
170
-
171
- } elseif ( ! empty( $_GET['transfer'] ) ) {
172
- if ( class_exists( 'CFF_Oembed' ) ) {
173
- $cff_oembed_token = CFF_Oembed::last_access_token();
174
- $valid_new_access_token = $cff_oembed_token;
175
- }
176
- } else {
177
- $valid_new_access_token = ! empty( $_GET['sbi_access_token'] ) && strlen( $_GET['sbi_access_token'] ) > 20 && $saved_access_token_data !== $_GET['sbi_access_token'] ? sanitize_text_field( $_GET['sbi_access_token'] ) : false;
178
- if ( $valid_new_access_token && ! empty( $_GET['sbi_access_token'] ) ) {
179
- $url = esc_url_raw( 'https://graph.facebook.com/me/accounts?limit=500&access_token=' . $valid_new_access_token );
180
- $args = array(
181
- 'timeout' => 20
182
- );
183
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
184
- $args['sslverify'] = false;
185
  }
186
- $pages_data_connection = wp_remote_get( $url, $args );
 
187
 
188
- if ( ! is_wp_error( $pages_data_connection ) && isset( $pages_data_connection['body'] ) ) {
189
- $pages_data = json_decode( $pages_data_connection['body'], true );
190
- if ( isset( $pages_data['data'][0]['access_token'] ) ) {
191
- $oembed_token_settings['expiration_date'] = 'never';
192
- } else {
193
- $oembed_token_settings['expiration_date'] = time() + (60 * DAY_IN_SECONDS);
194
- $show_token_expiration_modal = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
  } else {
197
- $oembed_token_settings['expiration_date'] = 'unknown';
198
- }
199
- }
200
 
201
- }
 
 
 
 
 
 
 
 
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
- if ( ! $saved_access_token_data && ! $valid_new_access_token && ! SB_Instagram_Oembed::can_do_oembed() ) {
205
- if ( $access_token_error ) { ?>
206
- <p class="sbi-error"><?php echo $error_message; ?></p>
207
- <?php }
208
- $need_to_connect_class = ' sbi-need-to-connect';
209
- $token_href = 'https://www.facebook.com/dialog/oauth?client_id=254638078422287&redirect_uri=https://api.smashballoon.com/v2/instagram-graph-api-redirect.php&scope=pages_show_list&state=' . $admin_url_state;
210
- if ( class_exists( 'CFF_Oembed' ) ) {
211
- $cff_oembed_token = CFF_Oembed::last_access_token();
212
 
213
- if ( ! empty( $cff_oembed_token ) ) {
214
- $need_to_connect_class = '';
215
- $token_href = add_query_arg( 'transfer', '1', $admin_url_state );
 
216
  }
217
- }
218
 
219
- ?>
220
- <a href="<?php echo esc_url( $token_href ); ?>" class="sbi-oembed-connect-btn<?php echo $need_to_connect_class; ?>"><i class="fa fa-instagram"></i> <?php esc_html_e( 'Enable Instagram oEmbeds', 'instagram-feed' ); ?></a>
221
- <div id="sbi_config_info" class="sb_get_token" style="display: none;">
222
- <div class="sbi_config_modal">
223
- <?php esc_html_e( 'As Instagram is part of Facebook, in order to display Instagram oEmbeds, you must connect to Facebook. Click on the button below to connect', 'instagram-feed' ); ?>
224
-
225
- <p>
226
- <a style="display: inline-block; float: none; margin-bottom: 0;" href="<?php echo esc_url( $token_href ); ?>" class="sbi-oembed-connect-btn"><?php esc_html_e( 'Connect to Facebook', 'instagram-feed' ); ?></a>
227
- </p>
228
-
229
- <a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>
230
- </div>
231
- </div>
232
- <div class="sbi-oembed-promo sbi-oembed-desc">
233
- <div class="sbi-col">
234
- <h2><?php esc_html_e("What are oEmbeds?", "instagram-feed"); ?></h2>
235
- <p><?php _e("Anytime you share a link to an Instagram post in WordPress, it is automatically converted into an embedded version of that Instagram post (an \"oEmbed\").</p><p>However, WordPress is discontinuing support for Instagram oEmbeds due to them now requiring an Access Token to work. Don't worry though, we have your back. Just use the button above to connect to Facebook and we'll make sure your Instagram oEmbeds keep working.", "instagram-feed"); ?></p>
236
- </div>
237
-
238
- <img src="<?php echo SBI_PLUGIN_URL . 'img/sbi-oembed.png'; ?>" style="padding: 0px; background: white;" alt="<?php esc_attr_e( 'Oembed example', 'instagram-feed' ); ?>">
239
- </div>
240
- <?php } else {
241
- if ( $valid_new_access_token ) {
242
- if ( ! is_array( $oembed_token_settings ) ) {
243
- $oembed_token_settings = array(
244
- 'access_token' => '',
245
- 'disabled' => '',
246
- );
247
- }
248
- $oembed_token_settings['access_token'] = $valid_new_access_token;
249
- $oembed_token_settings['disabled'] = false;
250
- update_option( 'sbi_oembed_token', $oembed_token_settings );
251
- ?>
252
- <div><p class="sbi-success-message"><?php _e("You're all set! Instagram Feed will replace your old oEmbeds automatically and generate all new content for all new links.", 'instagram-feed' ); ?> <a href="javascript:void(0);" id="sbi-oembed-disable"><?php _e("Disable", 'instagram-feed' ); ?></a></p></div>
253
- <?php if ( $show_token_expiration_modal ) : ?>
254
- <div id="sbi_config_info" class="sb_get_token">
255
- <div class="sbi_config_modal">
256
- <p><strong><?php esc_html_e( 'Heads up!', 'instagram-feed' ); ?></strong><br></p>
257
-
258
- <p>
259
- <?php esc_html_e( 'Your access token will expire in 60 days. Facebook requires that users have a role on a Facebook page in order to create access tokens that don\'t expire. Click the button below for instructions on creating a Facebook page and extending your access token to never expire.', 'instagram-feed' ); ?>
260
- </p>
261
- <p>
262
- <a style="display: inline-block; float: none; margin-bottom: 0;" href="https://smashballoon.com/doc/how-to-prevent-your-oembed-access-token-from-expiring/?instagram" class="sbi-oembed-connect-btn" target="_blank" rel="noopener"><?php esc_html_e( 'How to Create a Facebook Page', 'instagram-feed' ); ?></a>
263
- &nbsp;&nbsp;<a href="https://www.facebook.com/dialog/oauth?client_id=254638078422287&redirect_uri=https://api.smashballoon.com/v2/instagram-graph-api-redirect.php&scope=pages_show_list&state=<?php echo $admin_url_state; ?>" class="button button-secondary" style="height: 47px;line-height: 47px;font-size: 14px;padding: 0 21px;"><?php esc_html_e( 'Try Again', 'instagram-feed' ); ?></a>
264
- </p>
265
-
266
- <a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>
267
- </div>
268
- </div>
269
- <?php endif; ?>
270
- <?php } else {
271
- if ( ! isset( $oembed_token_settings['expiration_date'] ) || (int)$oembed_token_settings['expiration_date'] === 0 || $oembed_token_settings['expiration_date'] > time() ) :
272
- ?>
273
- <div><p class="sbi-success-message"><?php esc_html_e("The Instagram Feed plugin is now powering your Instagram oEmbeds.", 'instagram-feed' ); ?> <a href="javascript:void(0);" id="sbi-oembed-disable"><?php esc_html_e("Disable", 'instagram-feed' ); ?></a></p></div>
274
- <?php
275
- endif;
276
- if ( ! empty( $oembed_token_settings['expiration_date'] )
277
- && $oembed_token_settings['expiration_date'] !== 'never' ) :
278
- $link_1 = '<a href="https://smashballoon.com/doc/how-to-prevent-your-oembed-access-token-from-expiring/?instagram" target="_blank" rel="noopener">';
279
- $link_2 = '</a>';
280
- $class = 'sbi_warning';
281
- if ( $oembed_token_settings['expiration_date'] > time() ) {
282
- $days_to_expire = floor( ( $oembed_token_settings['expiration_date'] - time() ) / DAY_IN_SECONDS );
283
- $message = sprintf( __( '%1sImportant:%2s Your access token for powering oEmbeds will expire in %3s days.', 'instagram-feed' ), '<strong>', '</strong>', $days_to_expire );
284
- } else {
285
- $class = 'sb_instagram_notice';
286
- $message = __( 'Your access token for powering oEmbeds has expired.', 'instagram-feed' );
287
  }
288
  ?>
289
- <div class="<?php echo $class; ?>" style="display:inline-block;width: auto;">
290
- <p>
291
- <?php echo $message ; ?>
292
- </p>
293
- <p>
294
- <?php echo sprintf( __( 'Instagram requires that users have a role on a Facebook page in order to create access tokens that don\'t expire. Visit %1sthis link%2s for instructions on extending your access token to never expire.', 'instagram-feed' ), $link_1, $link_2 ); ?>
295
- </p>
296
- <p>
297
- <a style="display: inline-block; float: none; margin-bottom: 0;" href="https://www.facebook.com/dialog/oauth?client_id=254638078422287&redirect_uri=https://api.smashballoon.com/v2/instagram-graph-api-redirect.php&scope=pages_show_list&state=<?php echo $admin_url_state; ?>" class="sbi-oembed-connect-btn"><?php esc_html_e( 'Connect to Facebook and Recheck Access Token', 'instagram-feed' ); ?></a>
298
- </p>
299
- </div>
300
-
301
- <?php endif; ?>
302
 
303
- <?php } ?>
304
- <div class="sbi-oembed-promo">
305
- <h2><?php esc_html_e("Did you know, you can also use this Instagram Feed plugin to easily add Instagram content on your website?", 'instagram-feed'); ?></h2>
306
- <div class="sbi-reasons">
307
- <div><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="clock" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-clock fa-w-16 fa-2x"><path fill="currentColor" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z" class=""></path></svg><span><?php esc_html_e("Save time", 'instagram-feed'); ?></span></div>
308
- <div><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="chart-line" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-chart-line fa-w-16 fa-2x"><path fill="currentColor" d="M117.65 277.65c6.25 6.25 16.38 6.25 22.63 0L192 225.94l84.69 84.69c6.25 6.25 16.38 6.25 22.63 0L409.54 200.4l29.49 29.5c15.12 15.12 40.97 4.41 40.97-16.97V112c0-8.84-7.16-16-16-16H363.07c-21.38 0-32.09 25.85-16.97 40.97l29.5 29.49-87.6 87.6-84.69-84.69c-6.25-6.25-16.38-6.25-22.63 0l-74.34 74.34c-6.25 6.25-6.25 16.38 0 22.63l11.31 11.31zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16z" class=""></path></svg><span><?php esc_html_e("Increase social engagement", 'instagram-feed'); ?></span></div>
309
- <div><svg aria-hidden="true" focusable="false" data-prefix="fal" data-icon="heart" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-heart fa-w-16 fa-2x"><path fill="currentColor" d="M462.3 62.7c-54.5-46.4-136-38.7-186.6 13.5L256 96.6l-19.7-20.3C195.5 34.1 113.2 8.7 49.7 62.7c-62.8 53.6-66.1 149.8-9.9 207.8l193.5 199.8c6.2 6.4 14.4 9.7 22.6 9.7 8.2 0 16.4-3.2 22.6-9.7L472 270.5c56.4-58 53.1-154.2-9.7-207.8zm-13.1 185.6L256.4 448.1 62.8 248.3c-38.4-39.6-46.4-115.1 7.7-161.2 54.8-46.8 119.2-12.9 142.8 11.5l42.7 44.1 42.7-44.1c23.2-24 88.2-58 142.8-11.5 54 46 46.1 121.5 7.7 161.2z" class=""></path></svg><span><?php esc_html_e("Keep Your Site Looking Fresh.", 'instagram-feed'); ?></span></div>
310
- </div>
311
- <p>
312
- <?php $check_svg = '<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check fa-w-16 fa-2x"><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg>'; ?>
313
- <?php echo $check_svg; ?><span><?php esc_html_e("Super simple to set up", 'instagram-feed'); ?></span>
314
- <?php echo $check_svg; ?><span><?php esc_html_e("Optimized for speed", 'instagram-feed'); ?></span>
315
- <?php echo $check_svg; ?><span><?php esc_html_e("Completely customizable", 'instagram-feed'); ?></span>
316
- <?php echo $check_svg; ?><span><?php esc_html_e("SEO friendly", 'instagram-feed'); ?></span>
317
- </p>
318
- <a href="?page=sb-instagram-feed" class="button button-primary"><?php esc_html_e("Add an Instagram feed now", 'instagram-feed'); ?></a>
319
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
  <?php } ?>
322
 
323
- </div>
324
- </div>
325
- <?php }
 
326
 
327
  function sbi_social_wall_page() {
328
 
@@ -330,274 +340,287 @@ function sbi_social_wall_page() {
330
 
331
  ?>
332
 
333
- <div id="sbi_admin" class="wrap sw-landing-page">
334
 
335
- <?php $plus_svg = '<span class="sbi-sb-plus"><svg aria-hidden="true" focusable="false" data-prefix="fal" data-icon="plus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-plus fa-w-12 fa-2x"><path fill="currentColor" d="M376 232H216V72c0-4.42-3.58-8-8-8h-32c-4.42 0-8 3.58-8 8v160H8c-4.42 0-8 3.58-8 8v32c0 4.42 3.58 8 8 8h160v160c0 4.42 3.58 8 8 8h32c4.42 0 8-3.58 8-8V280h160c4.42 0 8-3.58 8-8v-32c0-4.42-3.58-8-8-8z" class=""></path></svg></span>'; ?>
336
 
337
- <div class="sbi-sw-icons">
 
 
 
 
 
 
 
 
 
 
 
338
 
339
- <span style="display: inline-block; padding: 0 0 12px 0; width: 360px; max-width: 100%;">
340
- <svg viewBox="0 0 9161 1878" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2">
341
- <path d="M671.51192 492.98498c-131.56765-59.12206-268.60859-147.41608-396.53319-188.5154 45.4516 108.39585 83.81326 223.88002 123.5099 338.03081-79.17849 59.49897-171.6647 105.68858-260.02357 156.01204C213.65642 872.8361 320.1446 915.85885 404.9893 980.52836c-67.96118 83.8619-201.48512 171.0179-234.02089 247.0198 140.6921-17.62678 304.63665-46.21028 435.53762-52.00414 28.76425 144.58318 43.59867 303.0974 84.5075 435.5368 60.92028-175.2656 116.0013-356.3729 188.5158-520.0447 111.90636 46.28566 248.28994 102.72599 357.52876 130.01178-76.6463-107.53462-146.59336-221.76932-214.51645-338.02878 100.51155-72.83872 202.17166-144.52441 299.02516-221.02077-136.89504-12.61227-278.73407-20.28825-422.53587-25.99863-22.85286-148.332-16.84825-325.5158-52.00496-461.53949-53.19323 111.48812-115.96685 213.3914-175.51405 318.52475m65.00509 1228.60643c-18.07949 77.37581 41.48757 109.11319 32.50294 156.01204-58.81404-20.26799-103.0575-30.6796-182.01552-19.50201 2.47017-60.37032 56.76657-68.90954 45.50428-143.0107-841.40803-95.6632-843.09804-1616.06909-6.50107-1709.64388C1672.04777-111.55711 1704.8713 1694.70523 736.517 1721.5914" fill="#e34f0e"/>
342
- <path d="M847.02597 174.46023c35.15671 136.0237 29.1521 313.20749 52.00455 461.53544 143.80221 5.71443 285.63962 13.38636 422.53628 26.00268-96.8531 76.49636-198.51483 148.18205-299.02556 221.01874 67.92349 116.2623 137.87014 230.49416 214.51847 338.03-109.24085-27.2866-245.62443-83.72572-357.5308-130.0126-72.51448 163.67262-127.5955 344.77992-188.51538 520.04553-40.90924-132.4394-55.74325-290.95364-84.5079-435.53681-130.90057 5.79548-294.84472 34.37736-435.53722 52.00415 32.53577-76.0007 166.0589-163.15589 234.02008-247.02021-84.8451-64.67032-191.33207-107.69066-266.52343-182.01472 88.35886-50.32346 180.84346-96.51307 260.02276-156.01609-39.69705-114.14674-78.05668-229.63091-123.50868-338.02675C402.9013 345.5689 539.94427 433.86292 671.51192 492.98498c59.5468-105.13335 122.32082-207.03663 175.51405-318.52475" fill="#fff"/>
343
- <path d="M1782.27033 1236.51938c41.18267 21.61921 126.79927 44.31938 214.58338 44.31938 213.49962 0 311.03752-107.01507 311.03752-232.40646 0-101.61027-58.52274-171.87269-189.65702-220.5159-92.11913-33.50977-131.13429-48.6432-131.13429-85.39586 0-32.4288 32.51263-54.04801 92.11913-54.04801 72.61154 0 126.79927 20.53824 158.22814 34.59073l41.18267-155.65828c-47.6852-21.6192-110.54295-37.83361-197.2433-37.83361-184.23826 0-293.69746 99.44834-293.69746 228.08262 0 108.09602 82.36534 176.19652 205.91335 219.43493 82.36533 28.10497 114.87797 48.64321 114.87797 84.3149 0 36.75265-32.51264 59.45282-99.70541 59.45282-73.6953 0-145.2231-22.70017-189.65703-45.40034l-36.84765 161.06308zM3019.37602 1270.02915h189.65702l-36.84765-728.56722h-256.8498l-55.27148 194.57285c-21.67508 76.74818-45.51768 179.4394-66.10902 268.07815h-3.25126c-15.17256-88.63875-36.84765-185.92517-57.43898-266.99719l-47.6852-195.6538h-263.35233l-45.51768 728.56721h179.90323l11.9213-260.51142c3.25127-83.23394 6.50253-191.32997 10.83755-294.0212h2.1675c17.34008 99.44835 39.01517 207.54438 58.52274 286.45448l60.69025 252.9447h152.80938l72.61154-254.02566c23.8426-79.99106 54.18773-189.16805 76.94657-285.37352h3.25126c0 113.50083 1.08376 210.78726 4.33502 294.0212l8.67004 260.51142zM3699.9738 1101.39935l46.60144 168.6298h211.33211l-217.83464-728.56722H3478.8879l-211.33211 728.56722h202.66208l41.18267-168.6298h188.57327zm-162.56317-143.76772l31.42888-130.79619c9.7538-41.07649 20.59134-101.61026 31.42888-143.76771h2.1675c11.9213 42.15745 26.01012 102.69122 36.84766 143.76771l33.59639 130.7962h-135.4693zM4016.4301 1236.51938c41.18266 21.61921 126.79926 44.31938 214.58337 44.31938 213.49962 0 311.03752-107.01507 311.03752-232.40646 0-101.61027-58.52274-171.87269-189.65702-220.5159-92.11913-33.50977-131.1343-48.6432-131.1343-85.39586 0-32.4288 32.51264-54.04801 92.11914-54.04801 72.61154 0 126.79926 20.53824 158.22814 34.59073l41.18267-155.65828c-47.6852-21.6192-110.54295-37.83361-197.2433-37.83361-184.23826 0-293.69746 99.44834-293.69746 228.08262 0 108.09602 82.36534 176.19652 205.91335 219.43493 82.36533 28.10497 114.87797 48.64321 114.87797 84.3149 0 36.75265-32.51264 59.45282-99.70541 59.45282-73.6953 0-145.2231-22.70017-189.65703-45.40034l-36.84765 161.06308zM4623.27688 541.46193v728.56722h196.15955V981.41276h237.34222v288.6164h196.15955V541.46192h-196.15955v269.1591h-237.34222v-269.1591h-196.15955z" fill="#282828" fill-rule="nonzero"/>
344
- <g>
345
- <path d="M6900.00785 293.7053c5.29-14.371 11.90999-24.77099 19.84998-31.19998 7.94-6.429 16.07-9.644 24.38998-9.644 8.32 0 15.7 2.08 22.12999 6.241 6.43 4.16 10.39999 9.265 11.90999 15.31599 2.27 43.86896 4.16 92.65493 5.67 146.35689 1.51 53.70296 2.65 109.86291 3.4 168.48187.76 58.61796 1.52 118.74891 2.26999 180.39386.76 61.64396 1.33 122.71991 1.71 183.22987.37 60.50695.56 119.1269.56 175.85686 0 56.72996.38 109.28992 1.14 157.69988-3.78 12.1-10.59 20.98999-20.41999 26.65998-9.83999 5.68-19.85998 8.14-30.06997 7.38-10.21-.76-19.28999-4.73-27.22998-11.91-7.94-7.18999-11.91-17.58998-11.91-31.19997l-3.4-983.66226zm173.57987 0c5.3-14.371 11.90999-24.77099 19.85998-31.19998 7.94-6.429 16.06999-9.644 24.38998-9.644 8.32 0 15.69 2.08 22.11999 6.241 6.43 4.16 10.39999 9.265 11.91999 15.31599 2.27 43.86896 4.15 92.65493 5.67 146.35689 1.51 53.70296 2.64 109.86291 3.4 168.48187.76 58.61796 1.51999 118.74891 2.26999 180.39386.76 61.64396 1.33 122.71991 1.7 183.22987.38 60.50695.57 119.1269.57 175.85686 0 56.72996.38 109.28992 1.13 157.69988-3.78 12.1-10.59 20.98999-20.41999 26.65998-9.82999 5.68-19.84998 8.14-30.05998 7.38-10.20999-.76-19.28998-4.73-27.22997-11.91-7.94-7.18999-11.92-17.58998-11.92-31.19997l-3.4-983.66226zm-419.49969 980.25225c-6.81-4.54-13.60999-12.66999-20.41998-24.38998-6.81-11.71999-13.61-24.57998-20.41999-38.57997-6.81-13.98999-13.61999-28.16998-20.41998-42.53997-6.81-14.36999-13.99999-26.84998-21.55998-37.43997-7.56-10.58999-15.51-18.33998-23.82999-23.25998-8.31999-4.92-17.38998-4.73-27.22998.57-15.11998 24.95998-30.43997 49.15996-45.93996 72.60994-15.50999 23.44999-32.52998 43.48997-51.05996 60.12996-18.52999 16.63999-39.70997 28.35998-63.52995 35.16997-23.82999 6.81-51.62997 6.05-83.38994-2.27-31.01998-8.31999-56.16996-24.57998-75.44994-48.77996-19.28999-24.20998-33.65998-52.94996-43.10997-86.22993-9.46-33.27998-14.19-69.77995-14.19-109.48992 0-39.70397 4.35-79.22394 13.05-118.55591 8.7-39.33097 21.36998-77.14894 38.00997-113.45492 16.63999-36.30597 36.67997-67.50595 60.12995-93.60093 23.44999-26.09398 50.10997-45.75996 79.98994-58.99595 29.86998-13.237 62.20996-16.82999 96.99993-10.779 32.51998 6.051 59.36996 19.855 80.54994 41.41198 21.17998 21.55598 38.76997 47.65096 52.75996 78.28394 13.98999 30.63297 24.95998 64.47995 32.89998 101.54192 7.93999 37.06197 15.12998 74.12394 21.55998 111.18692 6.43 37.06197 12.85999 72.42194 19.28999 106.08192 6.41999 33.65997 14.92998 62.58995 25.51998 86.78993 10.58999 24.20998 24.01998 41.97997 40.27997 53.32996 16.25998 11.34 37.62997 12.84999 64.09995 4.53 30.25997-31.00998 54.45996-51.61996 72.60994-61.82996 18.15999-10.20999 31.38998-13.60999 39.70997-10.20999 8.32 3.4 11.91 11.91 10.78 25.52998-1.13 13.61-6.05 28.73998-14.75 45.37997-8.69999 16.63999-20.60998 32.89997-35.73997 48.77996-15.11999 15.88999-32.32997 27.98998-51.61996 36.30997-19.28998 8.32-40.46997 11.16-63.52995 8.51-23.06998-2.65-47.08997-14.56-72.04995-35.73998zm2413.83818 6.81c-2.26-39.32997-5.67-82.25994-10.20999-128.7699-4.53-46.51997-10.58-92.84993-18.14999-138.9899-7.55999-46.13396-16.63998-89.81493-27.22998-131.0369-10.58999-41.22197-23.06998-76.01494-37.43997-104.37892-14.36999-28.36298-30.81997-48.21797-49.34996-59.56396-18.52999-11.34499-39.51997-9.83199-62.96995 4.539-23.44998 14.37099-49.34997 43.30197-77.71994 86.79293-28.35998 43.49097-59.93996 106.08092-94.72993 187.76786-3.03 6.05-7 15.88-11.91 29.49998-4.91999 13.60999-10.20999 28.92998-15.88998 45.94997-5.67 17.01998-11.91 34.97997-18.71999 53.88996-6.8 18.90998-13.03999 37.05997-18.71998 54.45995-5.67 17.4-10.78 32.89998-15.31 46.50997-4.53999 13.61999-7.56999 23.82998-9.07998 30.63998-6.05 15.11998-13.62 23.62998-22.68999 25.52998-9.08 1.89-18.14998.18-27.22998-5.11-9.07999-5.3-17.39998-12.47999-24.95998-21.55998-7.56-9.07-12.09999-17.01999-13.61999-23.81999 6.81-26.47998 12.86-55.96995 18.15999-88.49993 5.29-32.51997 9.45-69.57995 12.47999-111.17991 3.02-41.60397 4.16-88.68794 3.4-141.2559-.76-52.56696-4.54-112.13091-11.35-178.69186 8.32-17.39599 16.65-27.03998 24.96999-28.93098 8.31999-1.891 16.63998.756 24.94998 7.942 8.32 7.18499 16.07999 17.77498 23.25998 31.76697 7.19 13.99299 13.61999 28.17498 19.28999 42.54597 5.67 14.37099 10.20999 27.79698 13.61998 40.27697 3.4 12.47999 5.1 20.61098 5.1 24.39298 16.63999-14.371 31.95998-32.71298 45.94997-55.02596 13.98999-22.31298 28.35997-44.62597 43.10996-66.93895 14.75-22.31298 30.82998-42.16697 48.21997-59.56396 17.39998-17.39598 38.19997-27.98597 62.39995-31.76697 49.91996-9.077 92.27993-3.215 127.0699 17.58499 34.79998 20.79998 63.34996 50.67696 85.65994 89.62993 22.30998 38.95297 39.32997 84.14593 51.05996 135.5789 11.72 51.43296 20.03999 103.05492 24.95998 154.86588 4.91 51.80996 6.99 101.34992 6.24 148.62989-.76 47.26996-2.65 86.02993-5.68 116.2899-8.32 17.39-19.46998 26.08999-33.46997 26.08999-13.99 0-25.13998-8.7-33.46998-26.08998zm-1029.72922-9.08c-43.86997-18.14998-78.46994-41.97996-103.80992-71.46994-25.33998-29.49998-43.10997-61.83995-53.32996-97.00993-10.21-35.16997-13.61-72.03994-10.21-110.61791 3.41-38.57497 12.48-76.20395 27.22999-112.88792 14.74998-36.68397 34.41997-71.28794 58.99995-103.81092 24.57998-32.52398 52.56996-60.32095 83.95994-83.38994 31.38997-23.06898 65.79995-40.08797 103.23992-51.05496 37.43997-10.967 76.20994-13.42599 116.28991-7.375 33.27998 5.295 61.83995 20.99 85.65994 47.08397 23.82998 26.09498 42.73996 58.42996 56.72995 97.00493 13.99 38.57397 22.87999 80.93094 26.65998 127.0699 3.78 46.13797 1.7 91.70893-6.24 136.7079-7.93999 45.00996-21.55997 86.79993-40.83996 125.3699-19.28999 38.57998-44.62997 69.77995-76.01994 93.59993-31.38998 23.82999-69.39995 37.81998-114.01992 41.97997-44.62996 4.16-96.05992-6.24-154.29988-31.19997zm-642.42952 0c-43.86996-18.14998-78.46994-41.97996-103.80992-71.46994-25.33998-29.49998-43.10997-61.83995-53.31996-97.00993-10.20999-35.16997-13.61999-72.03994-10.20999-110.61791 3.4-38.57497 12.48-76.20395 27.21998-112.88792 14.74999-36.68397 34.41997-71.28794 58.99996-103.81092 24.57998-32.52398 52.56996-60.32095 83.95993-83.38994 31.38998-23.06898 65.79995-40.08797 103.23992-51.05496 37.43998-10.967 76.20995-13.42599 116.29992-7.375 33.27997 5.295 61.82995 20.99 85.64993 47.08397 23.82998 26.09498 42.73997 58.42996 56.72996 97.00493 13.98999 38.57397 22.87998 80.93094 26.65998 127.0699 3.79 46.13797 1.71 91.70893-6.24 136.7079-7.94 45.00996-21.54998 86.79993-40.83997 125.3699-19.28998 38.57998-44.62996 69.77995-76.01994 93.59993-31.38997 23.82999-69.38995 37.81998-114.01991 41.97997-44.61997 4.16-96.05993-6.24-154.29989-31.19997zm-1823.64862-14.69998c-5.29-34.31998-9.64-71.39995-13.04999-111.24992-3.4-39.85997-6.24-80.95994-8.5-123.2999-2.27-42.34497-3.79-85.24294-4.54-128.6939-.75999-43.45198-1.13999-86.07294-1.13999-127.86391 0-41.78997.38-81.91994 1.14-120.38991.75-38.46997 1.89-74.30995 3.4-107.52092 2.27-9.41 8.13-15.63699 17.58998-18.68199 9.45-3.044 19.65999-3.736 30.62998-2.075 10.97 1.66 20.98998 5.12 30.06998 10.378 9.07 5.259 13.98999 11.48599 14.73999 18.68198-1.51 31.54998-2.64 62.40896-3.4 92.57593-.76 30.16698-.57 59.91796.57 89.25494 1.13 29.33597 3.4 58.81095 6.81 88.42493 3.4 29.61298 8.12999 59.64095 14.17998 90.08493 35.54998-34.31797 72.03995-55.90596 109.47992-64.76195 37.43997-8.856 72.79995-8.441 106.07992 1.245 33.27998 9.687 63.72995 26.56898 91.32993 50.64796 27.60998 24.07798 49.54996 51.61496 65.80995 82.61194 16.25999 31.00198 25.89998 63.65195 28.92998 97.97192 3.02 34.31998-3.22 66.41995-18.71999 96.30993-15.50998 29.88998-41.40996 55.62996-77.71994 77.21994-36.29997 21.58999-85.46993 35.42998-147.48989 41.50997-27.22998 2.77-50.86996 4.99-70.90994 6.65-20.03999 1.66-38.94997 1.8-56.72996.41-17.76999-1.38-35.91997-5.12-54.45996-11.21-18.52998-6.08999-39.89997-15.49998-64.09995-28.22997zm85.08994-154.42989c-9.83 32.09998-11.34 58.25996-4.53 78.45994 6.8 20.20999 18.89998 35.00998 36.29997 44.41997 17.39999 9.41 38.57997 14.11999 63.53995 14.11999 24.95998 0 50.66997-3.74 77.13995-11.21 26.47998-7.46999 52.37996-18.12998 77.71994-31.96997 25.33998-13.83999 47.08996-30.15997 65.23995-48.97996 13.60999-13.83999 20.79998-30.58998 21.55998-50.23996.75-19.64999-2.84-39.70997-10.78-60.18996-7.94998-20.47998-19.85998-40.13097-35.73996-58.95095-15.88-18.81999-33.65998-34.31798-53.31996-46.49597-19.66999-12.17699-40.65997-19.64998-62.96996-22.41698-22.31998-2.768-44.24996 1.799-65.80995 13.69899-21.54998 11.90099-41.78996 32.10397-60.69995 60.61095-18.90999 28.50398-34.78997 68.22395-47.64996 119.14391zm2380.9882 74.95995c49.15996 31.76997 93.21993 45.00996 132.1799 39.70997 38.94997-5.29 71.65995-21.92999 98.12993-49.91997 26.47998-27.97997 46.32996-63.71995 59.56995-107.20991 13.24-43.48997 18.90999-87.92994 17.01999-133.3119-1.9-45.38197-11.73-87.54994-29.49998-126.5029-17.77999-38.95298-44.81997-68.26196-81.11994-87.92694-20.41998-10.59-44.24997-10.022-71.47994 1.701-27.22998 11.72399-53.88996 30.63297-79.97994 56.72795-26.09998 26.09498-49.73997 57.29496-70.90995 93.60093-21.17999 36.30498-35.54997 73.55695-43.11997 111.75292-7.56 38.19897-6.62 75.06894 2.84 110.61892 9.45 35.54997 31.57998 65.79995 66.36995 90.75993zm-642.42952 0c49.16997 31.76997 93.21993 45.00996 132.1799 39.70997 38.94997-5.29 71.65995-21.92999 98.13993-49.91997 26.46998-27.97997 46.31997-63.71995 59.55996-107.20991 13.23999-43.48997 18.90998-87.92994 17.01998-133.3119-1.89-45.38197-11.71999-87.54994-29.49998-126.5029-17.76998-38.95298-44.80996-68.26196-81.11993-87.92694-20.41999-10.59-44.24997-10.022-71.47995 1.701-27.22998 11.72399-53.88996 30.63297-79.97994 56.72795-26.09998 26.09498-49.72996 57.29496-70.90995 93.60093-21.17998 36.30498-35.54997 73.55695-43.10996 111.75292-7.57 38.19897-6.62 75.06894 2.83 110.61892 9.45999 35.54997 31.57997 65.79995 66.36994 90.75993zm-1159.18912-39.69997c19.65998 30.24997 40.26997 47.64996 61.82995 52.18996 21.55999 4.53 42.53997.56 62.96995-11.92 20.41999-12.47998 39.70997-31.00997 57.85996-55.58995 18.14999-24.57998 33.65998-50.86996 46.51997-78.84994 12.84999-27.98998 22.30998-55.40696 28.35997-82.25794 6.05-26.85098 7.56-48.97496 4.54-66.37095-3.78-18.15299-6.81-34.41497-9.08-48.78596-2.27-14.371-4.72999-27.22898-7.36999-38.57497-2.65-11.345-5.68-21.74599-9.07999-31.19998-3.4-9.455-8.13-19.09799-14.17999-28.93098-30.25998-21.17898-58.42996-29.49898-84.52994-24.95998-26.08998 4.538-49.53996 17.39599-70.33994 38.57397-20.79999 21.17898-38.18997 48.40796-52.18996 81.68794-13.99 33.27997-24.19998 68.07295-30.62998 104.37892-6.43 36.30597-8.51 71.47995-6.24 105.50992 2.27 34.03998 9.45 62.39995 21.55999 85.09994z" fill="#282828" fill-rule="nonzero"/>
346
- <path d="M6892.93785 1141.07765l-2.93-847.33736c-.01-1.191.2-2.374.61-3.492 6.06-16.43098 13.87-28.16497 22.94999-35.51497 9.95999-8.065 20.24998-11.87199 30.67997-11.87199 10.37 0 19.54999 2.66 27.55998 7.845 8.86 5.732 14.1 12.94799 16.18 21.28698.16.625.25 1.264.29 1.908 2.26999 43.93997 4.15999 92.80393 5.67999 146.59289 1.51 53.75096 2.65 109.96191 3.4 168.63387.76 58.61996 1.52 118.75391 2.27 180.39986.76 61.66396 1.33 122.76091 1.71 183.28987.37 60.52995.56 119.1699.56 175.91986 0 56.66996.38 109.18992 1.13999 157.54988.01 1.06-.14 2.12-.46 3.13-4.6 14.73-12.99999 25.43998-24.96998 32.34998-11.7 6.75-23.64998 9.58-35.79997 8.68-12.44-.92-23.51999-5.71-33.19998-14.47-9.87-8.93-15.19999-21.69998-15.19999-38.57997l-.25-72.25994c-2.06 5.06-4.48 10.24999-7.27 15.58998-9.08998 17.41-21.52998 34.43998-37.35996 51.04997-16.08 16.88998-34.38998 29.74997-54.89996 38.58997-20.83999 8.98999-43.70997 12.12999-68.62995 9.25999-24.60998-2.82-50.33996-15.20999-76.94994-37.68997-7.62-5.23-15.41999-14.25-23.02998-27.34998-6.92-11.92-13.84-24.98998-20.75999-39.21997-6.83-14.02-13.64999-28.23998-20.46998-42.63997-6.53-13.77999-13.4-25.75998-20.65999-35.90997-6.62-9.27-13.48999-16.15999-20.76998-20.45999-4.67-2.76-9.71-2.7-15.12-.35-14.69998 24.18998-29.57997 47.66997-44.62996 70.42995-16.00999 24.20998-33.58997 44.87997-52.71996 62.05995-19.67998 17.66999-42.16997 30.11998-67.46995 37.34997-25.32998 7.23-54.88996 6.63-88.72993-2.23-33.15997-8.89999-60.03995-26.31997-80.66994-52.20995-20.07998-25.18998-35.06997-55.08996-44.90996-89.72994-9.7-34.10997-14.57-71.50994-14.57-112.21991 0-40.42697 4.43-80.66694 13.29-120.71491 8.84999-40.02697 21.73998-78.51394 38.67997-115.46191 17.08998-37.28898 37.69997-69.31695 61.77995-96.11793 24.43998-27.19398 52.23996-47.66197 83.36994-61.45595 31.65997-14.024 65.90995-17.899 102.88992-11.467 34.67997 6.452 63.26995 21.24799 85.85994 44.23397 21.94998 22.34798 40.20996 49.38096 54.70995 81.13794 14.28 31.25498 25.48998 65.78695 33.58998 103.60192 7.97 37.19097 15.17999 74.38195 21.62998 111.57192 6.42 37.00197 12.84 72.31194 19.25999 105.91192 6.27 32.82997 14.53999 61.05995 24.85998 84.65993 9.73 22.24999 21.89998 38.70997 36.83997 49.12997 13.55 9.45999 31.25998 10.32999 53.02996 3.92 30.31998-30.90998 54.72996-51.40997 73.05995-61.72996 12.16999-6.84 22.40998-10.8 30.62997-12.17 7.06-1.17999 12.97-.53999 17.76999 1.42 3.08 1.26 5.82 2.97 8.15 5.15zm171.26987-850.82935c-.41 1.118-.62 2.301-.62 3.492l3.4 983.65725c0 16.87999 5.34 29.64998 15.21 38.57997 9.67998 8.76 20.75997 13.55 33.19997 14.47 12.14999.9 24.09998-1.93 35.79997-8.68 11.95999-6.91 20.36998-17.61999 24.96998-32.34998.32-1.01.47-2.07.45-3.13-.75-48.35996-1.13-100.87992-1.13-157.54988 0-56.74995-.19-115.3899-.57-175.91986-.38-60.52896-.94-121.62591-1.7-183.28987-.76-61.64595-1.51-121.7799-2.27-180.39986-.76-58.67196-1.89-114.88291-3.41-168.63387-1.51-53.78896-3.4-102.65292-5.67999-146.5929-.03-.644-.13-1.283-.28-1.90799-2.09-8.339-7.32-15.55499-16.17999-21.28698-8.02-5.185-17.18998-7.845-27.55998-7.845-10.43999 0-20.71998 3.807-30.68997 11.872-9.08 7.34999-16.88999 19.08398-22.93999 35.51497zm1588.0788 521.3466c11.02-11.49199 21.36999-24.98198 31.06998-40.44997 14.03-22.37998 28.44998-44.75996 43.23997-67.13995 15.13999-22.89798 31.63998-43.26796 49.48996-61.12095 18.93999-18.93699 41.57997-30.45998 67.67995-34.53497 52.65996-9.574 97.29993-3.098 133.9899 18.84098 36.21997 21.64899 65.98995 52.69896 89.20993 93.24193 22.76999 39.74697 40.15997 85.84694 52.12996 138.3279 11.82 51.85696 20.20999 103.90492 25.15998 156.14788 4.96 52.18996 7.05 102.09992 6.29 149.72989-.77 47.60996-2.68 86.64993-5.73 117.1199-.11 1.16-.43 2.28-.92 3.32-10.40999 21.74999-24.99998 31.77998-42.49996 31.77998-17.48999 0-32.07998-10.03-42.48997-31.77997-.56-1.17-.88-2.44-.96-3.73-2.26-39.21997-5.65-82.00994-10.18-128.3799-4.51999-46.29997-10.53998-92.40994-18.06998-138.3399-7.51-45.82997-16.51999-89.21993-27.03998-130.1689-10.38999-40.41497-22.58998-74.53795-36.67997-102.34693-13.35999-26.36698-28.42998-45.00796-45.64997-55.55495-15.47998-9.474-32.93997-7.465-52.51996 4.536-22.56998 13.82998-47.26996 41.87496-74.56994 83.72993-28.12998 43.12897-59.40996 105.21592-93.90993 186.22486-.08.19-.17.37-.26.55-2.91 5.83-6.71 15.30999-11.45 28.42998-4.88999 13.53999-10.15998 28.77998-15.79998 45.70996-5.7 17.09-11.95999 35.12998-18.79998 54.11996-6.77 18.80999-12.98 36.85997-18.61999 54.16996-5.68 17.41999-10.79 32.93998-15.33999 46.57997-4.39 13.16999-7.33 23.04998-8.8 29.63997-.12.52-.28 1.04-.48 1.54-7.70999 19.27999-18.35998 29.19998-29.92997 31.59998-11.43 2.39-22.87998.41-34.30997-6.25-10.03-5.85-19.24999-13.76999-27.59998-23.78998-8.86-10.63999-13.93-20.08998-15.7-28.05998-.33999-1.54-.30999-3.14.08-4.66 6.74-26.20997 12.73-55.41995 17.97-87.60993 5.25-32.26997 9.36999-69.03995 12.36999-110.30991 3.01-41.34297 4.13-88.13794 3.38-140.3819-.75-52.31096-4.52-111.58291-11.29-177.81786-.19-1.829.13-3.674.92-5.332 10.19-21.30698 21.57999-32.05198 31.76998-34.36797 11.17999-2.541 22.52998.468 33.70997 10.12499 9.13 7.881 17.73999 19.41898 25.61998 34.76697 7.34 14.288 13.9 28.76898 19.68999 43.44197 5.82 14.74199 10.46999 28.51598 13.95999 41.31797.7 2.54 1.32 4.919 1.87 7.135zm-1260.43904 469.29265c-45.43997-18.81999-81.21994-43.59997-107.46992-74.15995-26.30998-30.62997-44.73997-64.20995-55.34996-100.72992-10.55-36.33997-14.07999-74.42994-10.56-114.28691 3.48-39.54797 12.79-78.12894 27.90999-115.73892 15.06999-37.49597 35.16997-72.86794 60.28995-106.11092 25.18998-33.31797 53.85996-61.78595 86.01994-85.41793 32.32997-23.76398 67.77995-41.29597 106.34992-52.59396 38.82997-11.373 79.02994-13.941 120.6799-7.653 35.51998 5.652 66.02996 22.35899 91.46994 50.21697 24.64998 26.99898 44.25996 60.42495 58.73995 100.33692 14.28 39.36297 23.36998 82.58094 27.22998 129.6629 3.85 46.99997 1.73 93.42293-6.36 139.2649-8.10999 45.98996-22.03998 88.68993-41.74996 128.1099-20.00999 40.01997-46.33997 72.36995-78.90994 97.08993-32.80998 24.89998-72.49995 39.61997-119.13991 43.96996-46.01997 4.29-99.08993-6.22-159.14988-31.95997zm642.41951 0c-45.43996-18.81999-81.21994-43.59997-107.46992-74.15995-26.30998-30.62997-44.73996-64.20995-55.33995-100.72992-10.55-36.33997-14.08-74.42994-10.57-114.28691 3.49-39.54797 12.79-78.12894 27.90998-115.73892 15.08-37.49597 35.17998-72.86794 60.29996-106.11092 25.17998-33.31797 53.85996-61.78595 86.00993-85.41793 32.33998-23.76398 67.78995-41.29597 106.35992-52.59396 38.82997-11.373 79.01994-13.941 120.66991-7.653 35.52997 5.652 66.03995 22.35899 91.47993 50.21697 24.64998 26.99898 44.25997 60.42495 58.73996 100.33692 14.27999 39.36297 23.36998 82.58094 27.22998 129.6629 3.85 46.99997 1.73 93.42293-6.36 139.2649-8.12 45.98996-22.03998 88.68993-41.74997 128.1099-20.00998 40.01997-46.33996 72.36995-78.90994 97.08993-32.80997 24.89998-72.49994 39.61997-119.1399 43.96996-46.01997 4.29-99.09993-6.22-159.15989-31.95997zM6968.3578 276.0543c-1.1-3.399-3.7-6.152-7.41999-8.557-4.84-3.135-10.41999-4.636-16.68999-4.636-6.2 0-12.17999 2.622-18.09998 7.417-6.5 5.259-11.73 13.762-16.13999 25.24198l3.4 981.84726c0 10.31 2.6 18.33999 8.62 23.77998 6.20999 5.62 13.27998 8.76 21.25998 9.36 8.26999.61 16.35998-1.47 24.32998-6.07 7.31-4.21 12.36999-10.78 15.39999-19.52998-.75-47.98997-1.12-100.04993-1.12-156.16989 0-56.70995-.19-115.30991-.56-175.79486-.38-60.48896-.95-121.54591-1.7-183.16987-.76-61.64195-1.52-121.7709-2.27-180.38686-.76-58.56596-1.89-114.67491-3.4-168.32887-1.5-53.15996-3.37-101.49493-5.61-145.0029zm173.57988 0c-1.1-3.399-3.69-6.152-7.41-8.557-4.84-3.135-10.42-4.636-16.68999-4.636-6.21 0-12.17999 2.622-18.09998 7.417-6.5 5.259-11.74 13.762-16.14 25.24198l3.39 981.84726c0 10.31 2.61 18.33999 8.63 23.77998 6.2 5.62 13.27999 8.76 21.25998 9.36 8.27.61 16.36-1.47 24.31999-6.07 7.31-4.21 12.36999-10.78 15.39998-19.52998-.74-47.98997-1.11-100.04993-1.11-156.16989 0-56.70995-.19-115.30991-.57-175.79486-.37-60.48896-.94-121.54591-1.7-183.16987-.75-61.64195-1.51-121.7709-2.27-180.38686-.75-58.56596-1.88999-114.67491-3.39999-168.32887-1.49-53.15996-3.36-101.49493-5.61-145.0029zm-1474.8589 611.05154c32.78998-28.61098 66.40996-46.87097 100.71993-54.98596 39.23997-9.282 76.29994-8.777 111.17992 1.375 34.64997 10.08599 66.35995 27.64098 95.10993 52.71196 28.56997 24.91798 51.24996 53.42596 68.07995 85.50393 16.88998 32.18698 26.89997 66.10695 30.03997 101.73693 3.2 36.27997-3.42 70.20994-19.80998 101.79992-16.27999 31.37997-43.34997 58.53995-81.47994 81.19994-37.32997 22.19998-87.83993 36.60997-151.58989 42.86996-27.29998 2.78-50.99996 5-71.08994 6.66-20.60999 1.71-40.05997 1.84-58.32996.42-18.53999-1.44-37.47997-5.33-56.80996-11.68-18.96998-6.22999-40.84997-15.83998-65.62995-28.87997-2.81-1.47-4.75-4.19-5.23-7.32-5.32999-34.52997-9.70999-71.83994-13.12998-111.92991-3.41-39.95997-6.26-81.15994-8.53-123.6199-2.28-42.45897-3.79-85.47694-4.55-129.0499-.76-43.51098-1.14-86.18994-1.14-128.03791 0-41.85797.38-82.05394 1.14-120.58691.76-38.56197 1.89-74.48795 3.41-107.77892.03-.637.12-1.27.27-1.889 3.13-12.99999 11.18-21.65098 24.23999-25.85598 10.86999-3.498 22.58998-4.353 35.19997-2.445 12.24999 1.856 23.43998 5.739 33.57997 11.614 12.52 7.25499 18.62999 16.35998 19.67999 26.28797.05.506.07 1.016.04 1.524-1.51 31.47298-2.64 62.25596-3.39 92.34793-.75 29.95198-.57 59.49096.56 88.61794 1.12 29.08597 3.37 58.30895 6.75 87.66993 2.72 23.63898 6.28 47.54596 10.70999 71.71995zm992.55926 378.53171c-5.84-3.89-11.48-11.03-17.31999-21.08998-6.7-11.53-13.38999-24.16999-20.07998-37.92998-6.79-13.95998-13.58-28.10997-20.37999-42.44996-7.08-14.97-14.57999-27.94998-22.44998-38.97997-8.51-11.9-17.51999-20.51999-26.87998-26.04998-11.32-6.69-23.67998-6.83-37.05997.37-1.57.85-2.88 2.1-3.81 3.62-15.05999 24.84997-30.29998 48.93996-45.73996 72.27994-15 22.68998-31.45998 42.10997-49.38997 58.20995-17.37998 15.61-37.24997 26.60998-59.59995 32.99998-22.31999 6.37-48.34997 5.46-78.10994-2.33-28.79998-7.73-52.21996-22.82998-70.15995-45.34996-18.49999-23.20999-32.24998-50.79997-41.31997-82.71994-9.21-32.44998-13.79999-68.03995-13.79999-106.75992 0-38.98097 4.27-77.78094 12.81-116.39591 8.54998-38.63497 20.98998-75.78495 37.33996-111.44792 16.19-35.32397 35.65998-65.69495 58.47996-91.08393 22.45998-24.99598 47.97996-43.85797 76.59994-56.53696 28.08998-12.44899 58.50996-15.75999 91.23993-10.069 30.24998 5.628 55.35996 18.44 75.12995 38.56698 20.39998 20.76598 37.30997 45.92097 50.78996 75.43094 13.70999 30.00998 24.43998 63.17396 32.21997 99.48293 7.92 36.93297 15.08 73.86594 21.48999 110.79991 6.43 37.12298 12.86999 72.53295 19.30998 106.24292 6.59 34.48998 15.34 64.12996 26.18998 88.92994 11.45 26.16998 26.13998 45.24996 43.71997 57.51995 18.48999 12.9 42.71997 15.33 72.81994 5.87 1.58-.49 3.01-1.37 4.16-2.55 29.34998-30.08998 52.73996-50.19996 70.35995-60.09995 8.15-4.59 15.17999-7.72 21.11998-9.24 4.06-1.05 7.35-1.48 9.9-.44 4.83 1.98 5.26 7.53 4.6 15.45-1.04 12.47998-5.67 26.31997-13.65 41.57996-8.3 15.86999-19.68998 31.36998-34.11997 46.51997-14.17 14.87998-30.26998 26.22998-48.33997 34.01997-17.73998 7.65-37.21997 10.19-58.42995 7.76-21.40999-2.46-43.55997-13.78-66.71995-33.42998l-.92-.7zm2465.44814 12.35c2.91-29.76999 4.72-67.65996 5.46-113.66992.75-46.92997-1.32-96.09993-6.2-147.5199-4.87-51.38895-13.12999-102.58491-24.74998-153.59388-11.49-50.38496-28.12998-94.67092-49.98996-132.8309-21.39999-37.36197-48.73997-66.06595-82.10994-86.01693-32.88998-19.65999-72.95995-24.90898-120.38991-16.28799-22.05998 3.447-41.01997 13.102-56.87996 28.95798-16.93999 16.93999-32.57997 36.27997-46.93996 58.00796-14.71 22.24498-29.03998 44.49096-42.98997 66.73695-14.56999 23.23798-30.54998 42.31396-47.87996 57.28095-2.96 2.557-7.14 3.153-10.7 1.525-3.56-1.628-5.84-5.181-5.84-9.093 0-3.38099-1.70999-10.60698-4.74999-21.76198-3.32-12.15799-7.74-25.23598-13.26999-39.23597-5.55-14.06799-11.84999-27.95098-18.87998-41.64996-6.49-12.637-13.39-22.27799-20.89999-28.76698-5.47-4.718-10.73999-7-16.20999-5.759-2.45.558-4.67 2.587-7.11999 5.432-3.3 3.817-6.54 9.02999-9.82 15.58699 6.66 65.73995 10.36 124.6399 11.11 176.70886.76 52.89196-.39 100.26493-3.43 142.1199-3.05 41.92996-7.25 79.28994-12.57999 112.06991-5.18 31.79998-11.08 60.72995-17.68999 86.79993 1.68 5.13 5.45 10.9 10.96 17.51 6.77 8.11999 14.18999 14.57998 22.31998 19.31998 6.72 3.93 13.41999 5.36 20.14998 3.96 6.46-1.35 10.86-8.16 15.16-18.77 1.62-7.01999 4.65999-17.27998 9.15999-30.76997 4.53-13.58999 9.62999-29.07998 15.29998-46.44996 5.7-17.48999 11.97-35.73998 18.80999-54.74996 6.78-18.82999 12.99999-36.71997 18.63999-53.65996 5.71-17.10999 11.02999-32.49998 15.96998-46.18997 5.02-13.88999 9.11-23.97298 12.22-30.26797 35.04997-82.24394 66.88994-145.2539 95.45992-189.06286 29.42998-45.12797 56.52996-74.94494 80.85994-89.85593 27.31998-16.744 51.82996-17.75999 73.41995-4.541 19.83998 12.144 37.66997 33.21197 53.04996 63.57295 14.64998 28.91898 27.40998 64.38095 38.20997 106.40992 10.65999 41.49597 19.79998 85.46594 27.40998 131.9149 7.6 46.34997 13.67999 92.88993 18.23998 139.6299 4.47 45.84996 7.84 88.22993 10.12 127.1199 6.08999 12 13.56998 18.70999 23.59998 18.70999 10.08999 0 17.58998-6.77 23.68998-18.86999zm-1725.4887-15.54c-42.25997-17.47998-75.64994-40.33997-100.04992-68.74995-24.36999-28.36997-41.48997-59.44995-51.30996-93.27993-9.87-33.99997-13.14-69.64994-9.85-106.94891 3.31-37.60098 12.17-74.27895 26.53998-110.03592 14.43-35.87297 33.65998-69.70795 57.69996-101.51292 23.97998-31.72998 51.27996-58.85496 81.89994-81.36094 30.43997-22.37399 63.81995-38.87897 100.12992-49.51597 36.05997-10.56199 73.38995-12.91099 111.98992-7.084 30.95997 4.925 57.54995 19.607 79.76994 43.93898 22.99998 25.18998 41.19997 56.43395 54.70996 93.67193 13.70999 37.78597 22.38998 79.28094 26.09998 124.4769 3.71 45.27597 1.67 89.99593-6.12 134.1609-7.77 44.01997-21.07998 84.89994-39.94997 122.6299-18.55999 37.11998-42.89997 67.17996-73.10994 90.10994-29.96998 22.74998-66.29995 36.00997-108.90992 39.98997-43.22997 4.03-93.00993-6.26-149.42989-30.43998l-.11-.05zm642.41952 0c-42.24997-17.47998-75.63995-40.33997-100.04993-68.74995-24.35998-28.36997-41.47997-59.44995-51.29996-93.27993-9.87-33.99997-13.14999-69.64994-9.86-106.94891 3.32-37.60098 12.17-74.27895 26.54999-110.03592 14.41999-35.87297 33.65997-69.70795 57.69995-101.51292 23.97999-31.72998 51.27997-58.85496 81.89994-81.36094 30.43998-22.37399 63.81995-38.87897 100.12993-49.51597 36.05997-10.56199 73.38994-12.91099 111.98991-7.084 30.94998 4.925 57.54996 19.607 79.76994 43.93898 22.99999 25.18998 41.19997 56.43395 54.70996 93.67193 13.7 37.78597 22.38998 79.28094 26.08998 124.4769 3.71 45.27597 1.68 89.99593-6.12 134.1609-7.76999 44.01997-21.06998 84.89994-39.93996 122.6299-18.55999 37.11998-42.90997 67.17996-73.10995 90.10994-29.96998 22.74998-66.29995 36.00997-108.90992 39.98997-43.22996 4.03-93.00993-6.26-149.42988-30.43998l-.12-.05zM5632.4288 546.7151c-.72-4.174-4.34-7.351-9.72999-10.47199-8.01-4.642-16.86999-7.678-26.54998-9.144-9.33-1.413-18.01998-.883-26.06998 1.707-5.56 1.792-9.16 5.322-10.71 10.675-1.47999 32.83197-2.59999 68.23495-3.33999 106.20592-.76 38.40597-1.14 78.47094-1.14 120.1929 0 41.73398.38 84.29694 1.14 127.68891.75 43.32997 2.26 86.10694 4.52 128.3289 2.26 42.23997 5.09 83.22994 8.49 122.97991 3.21999 37.68997 7.27999 72.88995 12.20998 105.58992 21.78999 11.26 41.14997 19.67999 58.09996 25.24998 17.72999 5.83 35.09997 9.42 52.10996 10.74 17.26999 1.35 35.64997 1.2 55.11996-.41 19.99998-1.66 43.56997-3.87 70.75994-6.63 60.26996-5.91 108.08992-19.17999 143.3599-40.15997 34.48997-20.49998 59.21995-44.82997 73.94994-73.21994 14.61999-28.18998 20.48999-58.46996 17.63999-90.82994-2.91-32.99997-12.19-64.39995-27.82998-94.20593-15.68999-29.91597-36.86997-56.48395-63.51995-79.72193-26.46998-23.08499-55.63996-39.29498-87.54994-48.58197-31.67997-9.221-65.34995-9.546-100.98992-1.115-35.87997 8.488-70.76995 29.33298-104.83992 62.22396-2.63 2.541-6.44 3.442-9.93 2.349-3.49-1.093-6.10999-4.005-6.81999-7.594-6.11-30.71598-10.88-61.01395-14.30999-90.89293-3.43-29.86598-5.72-59.59296-6.86-89.17993-1.15-29.54598-1.34-59.50996-.58-89.89194.75-29.94797 1.88-60.57595 3.37-91.88193zm15.14 553.17259c13.18998-52.14997 29.57997-92.78993 48.95996-122.00191 19.95998-30.08698 41.44996-51.27696 64.19995-63.83695 23.53998-12.994 47.49996-17.891 71.86994-14.869 23.73999 2.944 46.07997 10.883 66.99995 23.83899 20.53999 12.71799 39.10997 28.89298 55.69996 48.54796 16.63999 19.71899 29.09998 40.32097 37.41997 61.78096 8.47 21.83998 12.25 43.24996 11.45 64.19995-.86 22.23998-9.01 41.18997-24.34999 56.78995-18.82998 19.51999-41.36997 36.46998-67.63995 50.81997-26.01998 14.20999-52.61996 25.13998-79.79994 32.80997-27.39998 7.74-54.02996 11.59-79.85994 11.59-26.84998 0-49.58996-5.2-68.29994-15.32-19.60999-10.60999-33.33998-27.23998-41.01997-50.02996-7.32-21.70998-6.15-49.83996 4.37-84.31993zm19.33998 5.12c12.51999-49.58997 27.86998-88.30994 46.28996-116.06692 17.85999-26.92498 36.82998-46.14197 57.19996-57.38296 19.56999-10.80799 39.46997-15.04399 59.73996-12.52999 20.87998 2.59 40.51996 9.597 58.92995 20.99499 18.78999 11.63699 35.76997 26.45898 50.94996 44.44396 15.12 17.92099 26.48998 36.61097 34.04998 56.11096 7.42 19.12999 10.81999 37.84997 10.10999 56.19996-.65 17.04998-6.87 31.58997-18.68999 43.59996-17.54998 18.2-38.49997 33.89998-62.89995 47.22997-24.65998 13.46999-49.86996 23.83998-75.63994 31.10998-25.53998 7.20999-50.34996 10.83999-74.42995 10.83999-23.07998 0-42.69996-4.21-58.77995-12.91-15.18-8.20999-25.64998-21.19998-31.58998-38.81996-6.28-18.63999-4.44-42.72997 4.63-72.33995l.13-.48zm1723.4387 80.90993c51.62996 33.36998 98.03992 46.77997 138.9499 41.21997 41.29996-5.61 75.97994-23.27998 104.04991-52.95996 27.45998-29.02998 48.13997-66.05995 61.86996-111.16992 13.55999-44.57996 19.37998-90.12293 17.43998-136.6379-1.95-46.72396-12.08999-90.13293-30.38997-130.2379-18.71999-41.02096-47.21997-71.85994-85.45994-92.56893-23.01998-11.93999-49.70996-11.81599-80.18994 1.31-28.27998 12.173-56.00995 31.74398-83.09993 58.84096-26.66998 26.66498-50.83997 58.53395-72.47995 95.63293-21.75998 37.30897-36.50997 75.59694-44.27997 114.84991-7.87999 39.75097-6.86 78.13094 2.98 115.13091 10.02 37.67997 33.31998 69.85995 70.19995 96.31993l.41.27zm642.41951 0c51.62996 33.36998 98.04993 46.77997 138.9499 41.21997 41.30997-5.61 75.98994-23.27998 104.05992-52.95996 27.45998-29.02998 48.12996-66.05995 61.86995-111.16992 13.56-44.57996 19.37999-90.12293 17.43999-136.6379-1.95-46.72396-12.09-90.13293-30.38998-130.2379-18.71998-41.02096-47.22996-71.85994-85.45993-92.56893-23.01998-11.93999-49.70996-11.81599-80.18994 1.31-28.27998 12.173-56.00996 31.74398-83.10994 58.84096-26.65998 26.66498-50.82996 58.53395-72.46994 95.63293-21.76999 37.30897-36.51998 75.59694-44.28997 114.84991-7.87 39.75097-6.86 78.13094 2.98 115.13091 10.02999 37.67997 33.32997 69.85995 70.20994 96.31993l.4.27zm11.07-16.65999c46.60996 30.07998 88.23993 43.08997 125.1899 38.06997 36.59997-4.98 67.34995-20.58998 92.21993-46.88996 25.47998-26.93998 44.51997-61.38995 57.25996-103.24992 12.90999-42.40997 18.43998-85.73594 16.58999-129.9859-1.83-44.03997-11.35-84.96594-28.59998-122.76691-16.82999-36.88497-42.40997-64.66495-76.62995-83.20194-17.97998-9.323-38.93997-8.313-62.91995 2.009-26.17998 11.274-51.76996 29.52098-76.85994 54.61396-25.52998 25.52498-48.62996 56.05596-69.34995 91.56793-20.58998 35.30297-34.57997 71.51695-41.93997 108.65792-7.24999 36.63597-6.38 72.00594 2.69 106.10592 8.87 33.34997 29.74998 61.62995 62.34996 85.06993zm-642.42952 0c46.60996 30.07998 88.24993 43.08997 125.1899 38.06997 36.59998-4.98 67.34995-20.58998 92.21994-46.88996 25.48998-26.93998 44.51996-61.38995 57.25995-103.24992 12.91-42.40997 18.43999-85.73594 16.59999-129.9859-1.84-44.03997-11.36-84.96594-28.60998-122.76691-16.82999-36.88497-42.39997-64.66495-76.61994-83.20194-17.97999-9.323-38.94997-8.313-62.91995 2.009-26.18998 11.274-51.77996 29.52098-76.86995 54.61396-25.52998 25.52498-48.62996 56.05596-69.33994 91.56793-20.59999 35.30297-34.58998 71.51695-41.94997 108.65792-7.25 36.63597-6.37 72.00594 2.7 106.10592 8.86999 33.34997 29.73997 61.62995 62.33995 85.06993zm-1173.21912-25.98998c21.51999 33.09998 44.56997 51.54996 68.15995 56.51996 24.03999 5.06 47.46997.75 70.23995-13.16999 21.39998-13.06999 41.66997-32.41998 60.68995-58.17996 18.56-25.12998 34.41998-52.00996 47.55997-80.61994 13.16999-28.64997 22.83998-56.73495 29.03998-84.22993 6.4-28.42898 7.83-51.86396 4.63-70.28295l-.06-.326c-3.75-17.97399-6.74-34.07597-8.99-48.30596-2.31-14.636-4.82-27.73198-7.52-39.28697-2.74-11.752-5.86999-22.52199-9.39999-32.31498-3.62-10.059-8.64-20.32498-15.06999-30.78498-.72-1.164-1.67-2.168-2.79-2.952-32.86997-23.00798-63.61995-31.54997-91.96992-26.61997-28.08998 4.885-53.36996 18.62598-75.75995 41.41997-21.60998 21.99998-39.73997 50.24796-54.27996 84.81893-14.26999 33.96098-24.69998 69.46395-31.25997 106.51092-6.57 37.13497-8.69 73.11395-6.37 107.92392 2.38 35.65997 10.03 65.34995 22.70999 89.12993l.44.75zm223.31984-388.7207c-26.98998-18.50399-52.01996-26.18998-75.36995-22.12799-24.10998 4.192-45.70996 16.16699-64.91995 35.72898-19.99998 20.35698-36.65997 46.56796-50.10996 78.55694-13.70999 32.59997-23.70998 66.68295-29.99998 102.24692-6.29 35.47697-8.33 69.84595-6.11 103.10592 2.15 32.21998 8.8 59.13996 20.2 80.67994 17.73998 27.17998 35.82996 43.38997 55.26995 47.47996 19.06999 4.02 37.61997.38 55.68996-10.65999 19.44998-11.87999 37.74997-29.59997 55.02996-52.99996 17.74998-24.02998 32.90997-49.72996 45.47996-77.08994 12.55-27.30998 21.78999-54.06896 27.68998-80.27594 5.69-25.21598 7.29-45.98996 4.46-62.34495-3.79-18.24499-6.83-34.59698-9.12-49.05396-2.22-14.106-4.63-26.72698-7.22999-37.86298-2.55-10.93899-5.47-20.96898-8.75-30.08497-2.98-8.28-7.05999-16.709-12.20998-25.29798z" fill="#fff"/>
347
- </g>
348
- </svg>
349
- </span>
350
- <br />
351
 
352
- <span style="width: 34px; top: -5px;"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-facebook fa-w-16 fa-2x"><path fill="#475e8f" d="M504 256C504 119 393 8 256 8S8 119 8 256c0 123.78 90.69 226.38 209.25 245V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.28c-30.8 0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.31 482.38 504 379.78 504 256z" class=""></path></svg></span>
353
 
354
- <?php echo $plus_svg; ?>
355
 
356
- <span><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="instagram" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-instagram fa-w-14 fa-2x"><path fill="#e15073" d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" class=""></path></svg></span>
357
 
358
- <?php echo $plus_svg; ?>
359
 
360
- <span style="top: -4px;"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-twitter fa-w-16 fa-2x"><path fill="#1a92dc" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z" class=""></path></svg></span>
361
 
362
- <?php echo $plus_svg; ?>
363
-
364
- <span style="width: 35px; top: -5px;"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="youtube" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-youtube fa-w-18 fa-2x"><path fill="#f5413d" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z" class=""></path></svg></span>
365
- </div>
366
 
367
- <h1>Combine all your social media channels into one single wall.</h1>
368
- <h2>Maximize your social content and get more followers.</h2>
369
 
370
- <div style="text-align: center;">
371
- <a href="https://smashballoon.com/social-wall/?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=sw-cta-1" target="_blank" class="cta button button-primary">Get the Social Wall plugin</a>
372
- </div>
373
 
374
- <div class="sbi-sw-info">
375
- <div class="sbi-sw-features">
376
- <p><span>A dash of Instagram</span>Add posts from your profile, public hashtag posts, or posts you're tagged in.</p>
377
- <p><span>A sprinkle of Facebook</span>Include posts from your page or group timeline, or from your photos, videos, albums, and events pages.</p>
378
- <p><span>A spoonful of Twitter</span>Add Tweets from any Twitter account, hashtag Tweets, mentions, and more.</p>
379
- <p><span>And a dollop of YouTube</span>Embed videos from any public YouTube channel, playlists, searches, and more.</p>
380
- <p><span>All in the same feed</span>Combine feeds from all of our Smash Balloon Pro plugins into one single wall feed, and show off all your social media content in one place.</p>
381
- </div>
382
- <a class="sbi-sw-screenshot" href="https://smashballoon.com/social-wall/demo?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=sw-demo" target="_blank">
383
- <span class="cta">View Demo</span>
384
 
385
- <img src="<?php echo SBI_PLUGIN_URL . 'img/sw-screenshot.png'; ?>" alt="Smash Balloon Social Wall plugin screenshot showing Facebook, Instagram, Twitter, and YouTube posts combined into one wall.">
386
- </a>
387
- </div>
388
 
389
- <div class="sbi-sw-footer-cta">
390
- <a href="https://smashballoon.com/social-wall/?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=sw-cta-2" target="_blank"><span>🚀</span>Get Social Wall and Increase Engagement >></a>
391
- </div>
392
 
393
- </div>
394
 
395
  <?php
396
  }
397
 
398
  function sb_instagram_settings_page() {
399
-
400
- //Hidden fields
401
- $sb_instagram_settings_hidden_field = 'sb_instagram_settings_hidden_field';
402
- $sb_instagram_configure_hidden_field = 'sb_instagram_configure_hidden_field';
403
- $sb_instagram_customize_hidden_field = 'sb_instagram_customize_hidden_field';
404
-
405
  //Declare defaults
406
  $sb_instagram_settings_defaults = array(
407
- 'sb_instagram_at' => '',
408
- 'sb_instagram_user_id' => '',
409
- 'sb_instagram_preserve_settings' => '',
410
- 'sb_instagram_cache_time' => 1,
411
- 'sb_instagram_cache_time_unit' => 'hours',
412
- 'sbi_caching_type' => 'page',
413
- 'sbi_cache_cron_interval' => '12hours',
414
- 'sbi_cache_cron_time' => '1',
415
- 'sbi_cache_cron_am_pm' => 'am',
416
- 'sb_instagram_width' => '100',
417
- 'sb_instagram_width_unit' => '%',
418
- 'sb_instagram_feed_width_resp' => false,
419
- 'sb_instagram_height' => '',
420
- 'sb_instagram_num' => '20',
421
- 'sb_instagram_height_unit' => '',
422
- 'sb_instagram_cols' => '4',
423
- 'sb_instagram_disable_mobile' => false,
424
- 'sb_instagram_image_padding' => '5',
425
- 'sb_instagram_image_padding_unit' => 'px',
426
- 'sb_instagram_sort' => 'none',
427
- 'sb_instagram_background' => '',
428
- 'sb_instagram_show_btn' => true,
429
- 'sb_instagram_btn_background' => '',
430
- 'sb_instagram_btn_text_color' => '',
431
- 'sb_instagram_btn_text' => __( 'Load More...', 'instagram-feed' ),
432
- 'sb_instagram_image_res' => 'auto',
433
  //Header
434
- 'sb_instagram_show_header' => true,
435
- 'sb_instagram_header_size' => 'small',
436
- 'sb_instagram_header_color' => '',
437
- 'sb_instagram_custom_bio' => '',
438
- 'sb_instagram_custom_avatar' => '',
439
  //Follow button
440
- 'sb_instagram_show_follow_btn' => true,
441
- 'sb_instagram_folow_btn_background' => '',
442
  'sb_instagram_follow_btn_text_color' => '',
443
- 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
444
  //Misc
445
- 'sb_instagram_custom_css' => '',
446
- 'sb_instagram_custom_js' => '',
447
- 'sb_instagram_cron' => 'no',
448
- 'sb_instagram_backup' => true,
449
- 'sb_ajax_initial' => false,
450
- 'enqueue_css_in_shortcode' => false,
451
- 'sb_instagram_ajax_theme' => false,
452
- 'gdpr' => 'auto',
453
- 'sb_instagram_disable_resize' => false,
454
- 'sb_instagram_favor_local' => true,
455
- 'sb_instagram_minnum' => 0,
456
- 'disable_js_image_loading' => false,
457
- 'enqueue_js_in_head' => false,
458
- 'sb_instagram_disable_mob_swipe' => false,
459
- 'custom_template' => false,
460
- 'disable_admin_notice' => false,
461
- 'enable_email_report' => 'on',
462
- 'email_notification' => 'monday',
463
- 'email_notification_addresses' => get_option( 'admin_email' ),
464
  );
465
  //Save defaults in an array
466
- $options = wp_parse_args(get_option('sb_instagram_settings'), $sb_instagram_settings_defaults);
467
  update_option( 'sb_instagram_settings', $options );
468
 
469
  //Set the page variables
470
- $sb_instagram_user_id = $options[ 'sb_instagram_user_id' ];
471
- $sb_instagram_preserve_settings = $options[ 'sb_instagram_preserve_settings' ];
472
- $sb_instagram_ajax_theme = $options[ 'sb_instagram_ajax_theme' ];
473
- $gdpr = $options[ 'gdpr' ];
474
- $enqueue_js_in_head = $options[ 'enqueue_js_in_head' ];
475
- $disable_js_image_loading = $options[ 'disable_js_image_loading' ];
476
- $sb_instagram_disable_resize = $options[ 'sb_instagram_disable_resize' ];
477
- $sb_instagram_favor_local = $options[ 'sb_instagram_favor_local' ];
478
- $sb_instagram_minnum = $options[ 'sb_instagram_minnum' ];
479
-
480
- $sb_instagram_cache_time = $options[ 'sb_instagram_cache_time' ];
481
- $sb_instagram_cache_time_unit = $options[ 'sb_instagram_cache_time_unit' ];
482
  if ( $sb_instagram_cache_time_unit === 'days' ) {
483
  $sb_instagram_cache_time_unit = 'hours';
484
- $sb_instagram_cache_time = 24;
485
  }
486
- $sbi_caching_type = $options[ 'sbi_caching_type' ];
487
- $sbi_cache_cron_interval = $options[ 'sbi_cache_cron_interval' ];
488
- $sbi_cache_cron_time = $options[ 'sbi_cache_cron_time' ];
489
- $sbi_cache_cron_am_pm = $options[ 'sbi_cache_cron_am_pm' ];
490
-
491
- $sb_instagram_width = $options[ 'sb_instagram_width' ];
492
- $sb_instagram_width_unit = $options[ 'sb_instagram_width_unit' ];
493
- $sb_instagram_feed_width_resp = $options[ 'sb_instagram_feed_width_resp' ];
494
- $sb_instagram_height = $options[ 'sb_instagram_height' ];
495
- $sb_instagram_height_unit = $options[ 'sb_instagram_height_unit' ];
496
- $sb_instagram_num = $options[ 'sb_instagram_num' ];
497
- $sb_instagram_cols = $options[ 'sb_instagram_cols' ];
498
- $sb_instagram_disable_mobile = $options[ 'sb_instagram_disable_mobile' ];
499
- $sb_instagram_image_padding = $options[ 'sb_instagram_image_padding' ];
500
- $sb_instagram_image_padding_unit = $options[ 'sb_instagram_image_padding_unit' ];
501
- $sb_instagram_sort = $options[ 'sb_instagram_sort' ];
502
- $sb_instagram_background = $options[ 'sb_instagram_background' ];
503
- $sb_instagram_show_btn = $options[ 'sb_instagram_show_btn' ];
504
- $sb_instagram_btn_background = $options[ 'sb_instagram_btn_background' ];
505
- $sb_instagram_btn_text_color = $options[ 'sb_instagram_btn_text_color' ];
506
- $sb_instagram_btn_text = $options[ 'sb_instagram_btn_text' ];
507
- $sb_instagram_image_res = $options[ 'sb_instagram_image_res' ];
508
  //Header
509
- $sb_instagram_show_header = $options[ 'sb_instagram_show_header' ];
510
- $sb_instagram_header_size = $options[ 'sb_instagram_header_size' ];
511
- $sb_instagram_show_bio = isset( $options[ 'sb_instagram_show_bio' ] ) ? $options[ 'sb_instagram_show_bio' ] : true;
512
- $sb_instagram_custom_bio = $options[ 'sb_instagram_custom_bio' ];
513
- $sb_instagram_custom_avatar = $options[ 'sb_instagram_custom_avatar' ];
514
- $sb_instagram_header_color = $options[ 'sb_instagram_header_color' ];
515
  //Follow button
516
- $sb_instagram_show_follow_btn = $options[ 'sb_instagram_show_follow_btn' ];
517
- $sb_instagram_folow_btn_background = $options[ 'sb_instagram_folow_btn_background' ];
518
- $sb_instagram_follow_btn_text_color = $options[ 'sb_instagram_follow_btn_text_color' ];
519
- $sb_instagram_follow_btn_text = $options[ 'sb_instagram_follow_btn_text' ];
520
  //Misc
521
- $sb_instagram_custom_css = $options[ 'sb_instagram_custom_css' ];
522
- $sb_instagram_custom_js = $options[ 'sb_instagram_custom_js' ];
523
- $sb_instagram_cron = $options[ 'sb_instagram_cron' ];
524
- $sb_instagram_backup = $options[ 'sb_instagram_backup' ];
525
- $sb_ajax_initial = $options[ 'sb_ajax_initial' ];
526
- $enqueue_css_in_shortcode = $options[ 'enqueue_css_in_shortcode' ];
527
- $sb_instagram_custom_template = $options[ 'custom_template' ];
528
- $sb_instagram_disable_admin_notice = $options[ 'disable_admin_notice' ];
529
- $sb_instagram_enable_email_report = $options[ 'enable_email_report' ];
530
- $sb_instagram_email_notification = $options[ 'email_notification' ];
531
- $sb_instagram_email_notification_addresses = $options[ 'email_notification_addresses' ];
 
532
  //Check nonce before saving data
533
- if ( ! isset( $_POST['sb_instagram_settings_nonce'] ) || ! wp_verify_nonce( $_POST['sb_instagram_settings_nonce'], 'sb_instagram_saving_settings' ) ) {
534
- //Nonce did not verify
535
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  // See if the user has posted us some information. If they did, this hidden field will be set to 'Y'.
537
- if( isset($_POST[ $sb_instagram_settings_hidden_field ]) && $_POST[ $sb_instagram_settings_hidden_field ] == 'Y' ) {
538
 
539
- if( isset($_POST[ $sb_instagram_configure_hidden_field ]) && $_POST[ $sb_instagram_configure_hidden_field ] == 'Y' ) {
540
 
541
- $sb_instagram_at = sanitize_text_field( $_POST[ 'sb_instagram_at' ] );
542
  $sb_instagram_user_id = array();
543
- if ( isset( $_POST[ 'sb_instagram_user_id' ] )) {
544
- if ( is_array( $_POST[ 'sb_instagram_user_id' ] ) ) {
545
- foreach( $_POST[ 'sb_instagram_user_id' ] as $user_id ) {
546
- $sb_instagram_user_id[] = sanitize_text_field( $user_id );
547
  }
548
  } else {
549
- $sb_instagram_user_id[] = sanitize_text_field( $_POST[ 'sb_instagram_user_id' ] );
550
  }
551
  }
552
- isset($_POST[ 'sb_instagram_preserve_settings' ]) ? $sb_instagram_preserve_settings = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_preserve_settings' ] ) ) : $sb_instagram_preserve_settings = '';
553
- isset($_POST[ 'sb_instagram_cache_time' ]) ? $sb_instagram_cache_time = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_cache_time' ] ) ) : $sb_instagram_cache_time = '';
554
- isset($_POST[ 'sb_instagram_cache_time_unit' ]) ? $sb_instagram_cache_time_unit = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_cache_time_unit' ] ) ) : $sb_instagram_cache_time_unit = '';
555
-
556
- isset($_POST[ 'sbi_caching_type' ]) ? $sbi_caching_type = sanitize_text_field( wp_unslash( $_POST[ 'sbi_caching_type' ] ) ) : $sbi_caching_type = '';
557
- isset($_POST[ 'sbi_cache_cron_interval' ]) ? $sbi_cache_cron_interval = sanitize_text_field( wp_unslash( $_POST[ 'sbi_cache_cron_interval' ] ) ) : $sbi_cache_cron_interval = '';
558
- isset($_POST[ 'sbi_cache_cron_time' ]) ? $sbi_cache_cron_time = sanitize_text_field( wp_unslash( $_POST[ 'sbi_cache_cron_time' ] ) ) : $sbi_cache_cron_time = '';
559
- isset($_POST[ 'sbi_cache_cron_am_pm' ]) ? $sbi_cache_cron_am_pm = sanitize_text_field( wp_unslash( $_POST[ 'sbi_cache_cron_am_pm' ] ) ) : $sbi_cache_cron_am_pm = '';
560
-
561
- $options[ 'sb_instagram_at' ] = $sb_instagram_at;
562
- $options[ 'sb_instagram_user_id' ] = $sb_instagram_user_id;
563
- $options[ 'sb_instagram_preserve_settings' ] = $sb_instagram_preserve_settings;
564
  if ( $sb_instagram_cache_time_unit === 'days' ) {
565
  $sb_instagram_cache_time_unit = 'hours';
566
- $sb_instagram_cache_time = 24;
567
- }
568
-
569
- $options[ 'sb_instagram_cache_time' ] = $sb_instagram_cache_time;
570
- $options[ 'sb_instagram_cache_time_unit' ] = $sb_instagram_cache_time_unit;
571
 
572
- $options[ 'sbi_caching_type' ] = $sbi_caching_type;
573
- $options[ 'sbi_cache_cron_interval' ] = $sbi_cache_cron_interval;
574
- $options[ 'sbi_cache_cron_time' ] = $sbi_cache_cron_time;
575
- $options[ 'sbi_cache_cron_am_pm' ] = $sbi_cache_cron_am_pm;
576
 
 
 
 
 
577
 
578
  //Delete all SBI transients
579
  global $wpdb;
580
- $table_name = $wpdb->prefix . "options";
581
- $wpdb->query( "
 
582
  DELETE
583
  FROM $table_name
584
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
585
- " );
586
- $wpdb->query( "
 
 
587
  DELETE
588
  FROM $table_name
589
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
590
- " );
591
- $wpdb->query( "
 
 
592
  DELETE
593
  FROM $table_name
594
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
595
- " );
596
- $wpdb->query( "
 
 
597
  DELETE
598
  FROM $table_name
599
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
600
- " );
 
601
 
602
  if ( $sbi_caching_type === 'background' ) {
603
  delete_option( 'sbi_cron_report' );
@@ -610,202 +633,235 @@ function sb_instagram_settings_page() {
610
 
611
  } //End config tab post
612
 
613
- if( isset($_POST[ $sb_instagram_customize_hidden_field ]) && $_POST[ $sb_instagram_customize_hidden_field ] == 'Y' ) {
614
 
615
  //Validate and sanitize width field
616
- $safe_width = intval( sanitize_text_field( $_POST['sb_instagram_width'] ) );
617
- if ( ! $safe_width ) $safe_width = '';
618
- if ( strlen( $safe_width ) > 4 ) $safe_width = substr( $safe_width, 0, 4 );
 
 
 
 
619
  $sb_instagram_width = $safe_width;
620
 
621
- $sb_instagram_width_unit = sanitize_text_field( $_POST[ 'sb_instagram_width_unit' ] );
622
- isset($_POST[ 'sb_instagram_feed_width_resp' ]) ? $sb_instagram_feed_width_resp = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_feed_width_resp' ] ) ) : $sb_instagram_feed_width_resp = '';
623
 
624
  //Validate and sanitize height field
625
- $safe_height = intval( sanitize_text_field( $_POST['sb_instagram_height'] ) );
626
- if ( ! $safe_height ) $safe_height = '';
627
- if ( strlen( $safe_height ) > 4 ) $safe_height = substr( $safe_height, 0, 4 );
 
 
 
 
628
  $sb_instagram_height = $safe_height;
629
 
630
- $sb_instagram_height_unit = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_height_unit' ] ) );
631
 
632
  //Validate and sanitize number of photos field
633
  $safe_num = intval( sanitize_text_field( $_POST['sb_instagram_num'] ) );
634
- if ( ! $safe_num ) $safe_num = '';
635
- if ( strlen( $safe_num ) > 4 ) $safe_num = substr( $safe_num, 0, 4 );
 
 
 
 
636
  $sb_instagram_num = $safe_num;
637
 
638
- $sb_instagram_cols = sanitize_text_field( $_POST[ 'sb_instagram_cols' ] );
639
- isset($_POST[ 'sb_instagram_disable_mobile' ]) ? $sb_instagram_disable_mobile = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_disable_mobile' ] ) ) : $sb_instagram_disable_mobile = '';
640
 
641
  //Validate and sanitize padding field
642
- $safe_padding = intval( sanitize_text_field( $_POST['sb_instagram_image_padding'] ) );
643
- if ( ! $safe_padding ) $safe_padding = '';
644
- if ( strlen( $safe_padding ) > 4 ) $safe_padding = substr( $safe_padding, 0, 4 );
 
 
 
 
645
  $sb_instagram_image_padding = $safe_padding;
646
 
647
- $sb_instagram_image_padding_unit = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_image_padding_unit' ] ) );
648
- $sb_instagram_sort = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_sort' ] ) );
649
- $sb_instagram_background = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_background' ] ) );
650
- isset($_POST[ 'sb_instagram_show_btn' ]) ? $sb_instagram_show_btn = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_show_btn' ] ) ) : $sb_instagram_show_btn = '';
651
- $sb_instagram_btn_background = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_btn_background' ] ) );
652
- $sb_instagram_btn_text_color = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_btn_text_color' ] ) );
653
- $sb_instagram_btn_text = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_btn_text' ] ) );
654
- $sb_instagram_image_res = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_image_res' ] ) );
655
  //Header
656
- isset($_POST[ 'sb_instagram_show_header' ]) ? $sb_instagram_show_header = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_show_header' ] ) ) : $sb_instagram_show_header = '';
657
- isset($_POST[ 'sb_instagram_show_bio' ]) ? $sb_instagram_show_bio = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_show_bio' ] ) ) : $sb_instagram_show_bio = '';
658
  if ( function_exists( 'sanitize_textarea_field' ) ) {
659
- isset($_POST[ 'sb_instagram_custom_bio' ]) ? $sb_instagram_custom_bio = sanitize_textarea_field( wp_unslash( $_POST[ 'sb_instagram_custom_bio' ] ) ) : $sb_instagram_custom_bio = '';
660
  } else {
661
- isset($_POST[ 'sb_instagram_custom_bio' ]) ? $sb_instagram_custom_bio = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_custom_bio' ] ) ) : $sb_instagram_custom_bio = '';
 
 
 
 
 
662
  }
663
- isset($_POST[ 'sb_instagram_custom_avatar' ]) ? $sb_instagram_custom_avatar = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_custom_avatar' ] ) ) : $sb_instagram_custom_avatar = '';
664
- if (isset($_POST[ 'sb_instagram_header_size' ]) ) $sb_instagram_header_size = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_header_size' ] ) );
665
 
666
- $sb_instagram_header_color = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_header_color' ] ) );
667
  //Follow button
668
- isset($_POST[ 'sb_instagram_show_follow_btn' ]) ? $sb_instagram_show_follow_btn = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_show_follow_btn' ] ) ) : $sb_instagram_show_follow_btn = '';
669
- $sb_instagram_folow_btn_background = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_folow_btn_background' ] ) );
670
- $sb_instagram_follow_btn_text_color = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_follow_btn_text_color' ] ) );
671
- $sb_instagram_follow_btn_text = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_follow_btn_text' ] ) );
672
  //Misc
673
- if ( preg_match( '#</?\w+#', $_POST[ 'sb_instagram_custom_css' ] ) ) {
674
  $sb_instagram_custom_css = '';
675
  } else {
676
- $sb_instagram_custom_css = $_POST[ 'sb_instagram_custom_css' ];
677
- }
678
- $sb_instagram_custom_js = $_POST[ 'sb_instagram_custom_js' ];
679
- isset($_POST[ 'sb_instagram_ajax_theme' ]) ? $sb_instagram_ajax_theme = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_ajax_theme' ] ) ) : $sb_instagram_ajax_theme = '';
680
- isset($_POST[ 'gdpr' ]) ? $gdpr = sanitize_text_field( wp_unslash( $_POST[ 'gdpr' ] ) ) : $gdpr = '';
681
- isset($_POST[ 'enqueue_js_in_head' ]) ? $enqueue_js_in_head = sanitize_text_field( wp_unslash( $_POST[ 'enqueue_js_in_head' ] ) ) : $enqueue_js_in_head = '';
682
- isset($_POST[ 'disable_js_image_loading' ]) ? $disable_js_image_loading = sanitize_text_field( wp_unslash( $_POST[ 'disable_js_image_loading' ] ) ) : $disable_js_image_loading = '';
683
- isset($_POST[ 'sb_instagram_disable_resize' ]) ? $sb_instagram_disable_resize= sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_disable_resize' ] ) ) : $sb_instagram_disable_resize = '';
684
- isset($_POST[ 'sb_instagram_favor_local' ]) ? $sb_instagram_favor_local = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_favor_local' ] ) ) : $sb_instagram_favor_local = '';
685
- isset($_POST[ 'sb_instagram_minnum' ]) ? $sb_instagram_minnum = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_minnum' ] ) ) : $sb_instagram_minnum = '';
686
-
687
- if (isset($_POST[ 'sb_instagram_cron' ]) ) $sb_instagram_cron = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_cron' ] ) );
688
- isset($_POST[ 'sb_instagram_backup' ]) ? $sb_instagram_backup = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_backup' ] ) ) : $sb_instagram_backup = '';
689
- isset($_POST[ 'sb_ajax_initial' ]) ? $sb_ajax_initial = sanitize_text_field( wp_unslash( $_POST[ 'sb_ajax_initial' ] ) ) : $sb_ajax_initial = '';
690
- isset($_POST[ 'enqueue_css_in_shortcode' ]) ? $enqueue_css_in_shortcode = sanitize_text_field( wp_unslash( $_POST[ 'enqueue_css_in_shortcode' ] ) ) : $enqueue_css_in_shortcode = '';
691
-
692
- $options[ 'sb_instagram_width' ] = $sb_instagram_width;
693
- $options[ 'sb_instagram_width_unit' ] = $sb_instagram_width_unit;
694
- $options[ 'sb_instagram_feed_width_resp' ] = $sb_instagram_feed_width_resp;
695
- $options[ 'sb_instagram_height' ] = $sb_instagram_height;
696
- $options[ 'sb_instagram_height_unit' ] = $sb_instagram_height_unit;
697
- $options[ 'sb_instagram_num' ] = $sb_instagram_num;
698
- $options[ 'sb_instagram_cols' ] = $sb_instagram_cols;
699
- $options[ 'sb_instagram_disable_mobile' ] = $sb_instagram_disable_mobile;
700
- $options[ 'sb_instagram_image_padding' ] = $sb_instagram_image_padding;
701
- $options[ 'sb_instagram_image_padding_unit' ] = $sb_instagram_image_padding_unit;
702
- $options[ 'sb_instagram_sort' ] = $sb_instagram_sort;
703
- $options[ 'sb_instagram_background' ] = $sb_instagram_background;
704
- $options[ 'sb_instagram_show_btn' ] = $sb_instagram_show_btn;
705
- $options[ 'sb_instagram_btn_background' ] = $sb_instagram_btn_background;
706
- $options[ 'sb_instagram_btn_text_color' ] = $sb_instagram_btn_text_color;
707
- $options[ 'sb_instagram_btn_text' ] = $sb_instagram_btn_text;
708
- $options[ 'sb_instagram_image_res' ] = $sb_instagram_image_res;
 
 
709
  //Header
710
- $options[ 'sb_instagram_show_header' ] = $sb_instagram_show_header;
711
- $options[ 'sb_instagram_header_size' ] = $sb_instagram_header_size;
712
- $options[ 'sb_instagram_show_bio' ] = $sb_instagram_show_bio;
713
- $options[ 'sb_instagram_custom_bio' ] = $sb_instagram_custom_bio;
714
- $options[ 'sb_instagram_custom_avatar' ] = $sb_instagram_custom_avatar;
715
- $options[ 'sb_instagram_header_color' ] = $sb_instagram_header_color;
716
  //Follow button
717
- $options[ 'sb_instagram_show_follow_btn' ] = $sb_instagram_show_follow_btn;
718
- $options[ 'sb_instagram_folow_btn_background' ] = $sb_instagram_folow_btn_background;
719
- $options[ 'sb_instagram_follow_btn_text_color' ] = $sb_instagram_follow_btn_text_color;
720
- $options[ 'sb_instagram_follow_btn_text' ] = $sb_instagram_follow_btn_text;
721
  //Misc
722
- $options[ 'sb_instagram_custom_css' ] = $sb_instagram_custom_css;
723
- $options[ 'sb_instagram_custom_js' ] = $sb_instagram_custom_js;
724
- $options[ 'sb_instagram_ajax_theme' ] = $sb_instagram_ajax_theme;
725
- $options[ 'gdpr' ] = $gdpr;
726
- $options[ 'enqueue_js_in_head' ] = $enqueue_js_in_head;
727
- $options[ 'disable_js_image_loading' ] = $disable_js_image_loading;
728
- $options[ 'sb_instagram_disable_resize' ] = $sb_instagram_disable_resize;
729
- $options[ 'sb_instagram_favor_local' ] = $sb_instagram_favor_local;
730
- $options[ 'sb_instagram_minnum' ] = $sb_instagram_minnum;
731
-
732
- $options[ 'sb_ajax_initial' ] = $sb_ajax_initial;
733
- $options[ 'sb_instagram_cron' ] = $sb_instagram_cron;
734
- $options['sb_instagram_backup'] = $sb_instagram_backup;
735
  $options['enqueue_css_in_shortcode'] = $enqueue_css_in_shortcode;
736
 
737
- isset($_POST[ 'sb_instagram_custom_template' ]) ? $sb_instagram_custom_template = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_custom_template' ] ) ) : $sb_instagram_custom_template = '';
738
- $options['custom_template'] = $sb_instagram_custom_template;
739
- isset($_POST[ 'sb_instagram_disable_admin_notice' ]) ? $sb_instagram_disable_admin_notice = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_disable_admin_notice' ] ) ) : $sb_instagram_disable_admin_notice = '';
740
- $options['disable_admin_notice'] = $sb_instagram_disable_admin_notice;
741
- isset($_POST[ 'sb_instagram_enable_email_report' ]) ? $sb_instagram_enable_email_report = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_enable_email_report' ] ) ) : $sb_instagram_enable_email_report = '';
742
- $options['enable_email_report'] = $sb_instagram_enable_email_report;
743
- isset($_POST[ 'sb_instagram_email_notification' ]) ? $sb_instagram_email_notification = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_email_notification' ] ) ) : $sb_instagram_email_notification = '';
744
- $original = $options['email_notification'];
745
  $options['email_notification'] = $sb_instagram_email_notification;
746
- isset($_POST[ 'sb_instagram_email_notification_addresses' ]) ? $sb_instagram_email_notification_addresses = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_email_notification_addresses' ] ) ) : $sb_instagram_email_notification_addresses = get_option( 'admin_email' );
747
  $options['email_notification_addresses'] = $sb_instagram_email_notification_addresses;
748
 
749
- if ( $original !== $sb_instagram_email_notification && $sb_instagram_enable_email_report === 'on' ){
750
  //Clear the existing cron event
751
- wp_clear_scheduled_hook('sb_instagram_feed_issue_email');
752
 
753
- $input = sanitize_text_field( wp_unslash( $_POST[ 'sb_instagram_email_notification' ] ) );
754
  $timestamp = strtotime( 'next ' . $input );
755
 
756
- if ( $timestamp - (3600 * 1) < time() ) {
757
- $timestamp = $timestamp + (3600 * 24 * 7);
758
  }
759
- $six_am_local = $timestamp + sbi_get_utc_offset() + (6*60*60);
760
 
761
  wp_schedule_event( $six_am_local, 'sbiweekly', 'sb_instagram_feed_issue_email' );
762
  }
763
 
764
-
765
  //Delete all SBI transients
766
  global $wpdb;
767
- $table_name = $wpdb->prefix . "options";
768
- $wpdb->query( "
 
769
  DELETE
770
  FROM $table_name
771
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
772
- " );
773
- $wpdb->query( "
 
 
774
  DELETE
775
  FROM $table_name
776
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
777
- " );
778
- $wpdb->query( "
 
 
779
  DELETE
780
  FROM $table_name
781
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
782
- " );
783
- $wpdb->query( "
 
 
784
  DELETE
785
  FROM $table_name
786
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
787
- " );
 
788
 
789
- if( $sb_instagram_cron == 'no' ) wp_clear_scheduled_hook('sb_instagram_cron_job');
 
 
790
 
791
  //Run cron when Misc settings are saved
792
- if( $sb_instagram_cron == 'yes' ){
793
  //Clear the existing cron event
794
- wp_clear_scheduled_hook('sb_instagram_cron_job');
795
 
796
- $sb_instagram_cache_time = $options[ 'sb_instagram_cache_time' ];
797
- $sb_instagram_cache_time_unit = $options[ 'sb_instagram_cache_time_unit' ];
798
 
799
  //Set the event schedule based on what the caching time is set to
800
  $sb_instagram_cron_schedule = 'hourly';
801
- if( $sb_instagram_cache_time_unit == 'hours' && $sb_instagram_cache_time > 5 ) $sb_instagram_cron_schedule = 'twicedaily';
802
- if( $sb_instagram_cache_time_unit == 'days' ) $sb_instagram_cron_schedule = 'daily';
 
 
 
 
803
 
804
- wp_schedule_event(time(), $sb_instagram_cron_schedule, 'sb_instagram_cron_job');
805
 
806
  sb_instagram_clear_page_caches();
807
  }
808
-
809
  } //End customize tab post
810
 
811
  //Save the settings to the settings array
@@ -819,247 +875,272 @@ function sb_instagram_settings_page() {
819
 
820
 
821
  <div id="sbi_admin" class="wrap">
822
- <?php
823
- $lite_notice_dismissed = get_transient( 'instagram_feed_dismiss_lite' );
824
 
825
- if ( ! $lite_notice_dismissed ) :
826
- ?>
827
- <div id="sbi-notice-bar" style="display:none">
828
- <span class="sbi-notice-bar-message"><?php _e( 'You\'re using Instagram Feed Lite. To unlock more features consider <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=litenotice" target="_blank" rel="noopener noreferrer">upgrading to Pro</a>.', 'instagram-feed'); ?></span>
829
- <button type="button" class="dismiss" title="<?php esc_html_e( 'Dismiss this message.', 'instagram-feed'); ?>" data-page="overview">
830
- </button>
831
- </div>
832
- <?php endif; ?>
833
 
834
- <?php do_action( 'sbi_admin_overview_before_table' ); ?>
835
 
836
 
837
  <div id="header">
838
  <h1><?php esc_html_e( 'Instagram Feed', 'instagram-feed' ); ?></h1>
839
  </div>
840
  <?php
841
- $sb_instagram_type = 'user';
842
  $connected_accounts = SBI_Account_Connector::stored_connected_accounts();
843
- $user_feed_ids = ! is_array( $sb_instagram_user_id ) ? explode( ',', $sb_instagram_user_id ) : $sb_instagram_user_id;
844
 
845
  $new_user_name = false;
846
 
847
  SBI_Account_Connector::maybe_launch_modals( $sb_instagram_user_id );
848
  if ( isset( $_POST['sbi_connect_username'] ) ) {
849
- $new_user_name = sanitize_text_field( wp_unslash( $_POST['sbi_connect_username'] ) );
850
  $new_account_details = json_decode( wp_unslash( $_POST['sbi_account_json'] ), true );
851
  array_map( 'sanitize_text_field', $new_account_details );
852
 
853
- $updated_options = sbi_connect_basic_account( $new_account_details );
854
  $connected_accounts = $updated_options['connected_accounts'];
855
- $user_feed_ids = $updated_options['sb_instagram_user_id'];
856
  }
857
 
858
  //Display connected page
859
- if (isset( $sbi_connected_page ) && strpos($sbi_connected_page, ':') !== false) {
860
 
861
- $sbi_connected_page_pieces = explode(":", $sbi_connected_page);
862
- $sbi_connected_page_id = $sbi_connected_page_pieces[0];
863
- $sbi_connected_page_name = $sbi_connected_page_pieces[1];
864
- $sbi_connected_page_image = $sbi_connected_page_pieces[2];
865
 
866
  echo '&nbsp;';
867
  echo '<p style="font-weight: bold; margin-bottom: 5px;">Connected Business Profile:</p>';
868
  echo '<div class="sbi-managed-page sbi-no-select">';
869
- echo '<p><img class="sbi-page-avatar" border="0" height="50" width="50" src="'.esc_url($sbi_connected_page_image).'" alt="'.esc_attr( $sbi_connected_page_id ) . '"><strong>'.$sbi_connected_page_name.'</strong> &nbsp; ('.$sbi_connected_page_id.')</p>';
870
  echo '</div>';
871
  }
872
 
873
  ?>
874
 
875
- <form name="form1" method="post" action="">
876
- <input type="hidden" name="<?php echo $sb_instagram_settings_hidden_field; ?>" value="Y">
877
  <?php wp_nonce_field( 'sb_instagram_saving_settings', 'sb_instagram_settings_nonce' ); ?>
878
 
879
- <?php $sbi_active_tab = isset( $_GET[ 'tab' ] ) ? sanitize_text_field( $_GET['tab'] ) : 'configure'; ?>
880
  <h2 class="nav-tab-wrapper">
881
- <a href="?page=sb-instagram-feed&amp;tab=configure" class="nav-tab <?php echo $sbi_active_tab == 'configure' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( '1. Configure', 'instagram-feed' ); ?></a>
882
- <a href="?page=sb-instagram-feed&amp;tab=customize" class="nav-tab <?php echo $sbi_active_tab == 'customize' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( '2. Customize', 'instagram-feed' ); ?></a>
883
- <a href="?page=sb-instagram-feed&amp;tab=display" class="nav-tab <?php echo $sbi_active_tab == 'display' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( '3. Display Your Feed', 'instagram-feed' ); ?></a>
884
- <a href="?page=sb-instagram-feed&amp;tab=support" class="nav-tab <?php echo $sbi_active_tab == 'support' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Support', 'instagram-feed' ); ?></a>
885
- <a href="?page=sb-instagram-feed&amp;tab=more" class="nav-tab <?php echo $sbi_active_tab == 'more' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'More Social Feeds', 'instagram-feed' ); ?>
886
  <?php
887
- $seen_more_plugins_page = get_user_meta(get_current_user_id(), 'seen_more_plugins_page_1', true);
888
- if( !$seen_more_plugins_page ) echo '<span class="sbi-alert-bubble">1</span>';
 
 
889
  ?>
890
  </a>
891
  </h2>
892
 
893
- <?php if( $sbi_active_tab == 'configure' ) { //Start Configure tab ?>
894
- <input type="hidden" name="<?php echo $sb_instagram_configure_hidden_field; ?>" value="Y">
895
-
896
- <table class="form-table" aria-describedby="sbi-con-desc">
897
- <tbody>
898
- <h3 id="sbi-con-desc"><?php _e( 'Configure', 'instagram-feed' ); ?></h3>
899
- <?php $sb_admin_email = get_option('admin_email');
900
- $connect_url = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=' . $sb_admin_email . '&state=' . admin_url('admin.php?page=sb-instagram-feed');
901
- ?>
902
- <div id="sbi_config">
903
- <a data-personal-basic-api="https://api.instagram.com/oauth/authorize?client_id=423965861585747&redirect_uri=https://api.smashballoon.com/v2/instagram-basic-display-redirect.php&response_type=code&scope=user_profile,user_media&state=<?php echo admin_url('admin.php?page=sb-instagram-feed'); ?>"
904
- data-new-api="<?php echo esc_attr( $connect_url ); ?>"
905
- href="https://api.instagram.com/oauth/authorize?client_id=423965861585747&redirect_uri=https://api.smashballoon.com/v2/instagram-basic-display-redirect.php&response_type=code&scope=user_profile,user_media&state=<?php echo admin_url('admin.php?page=sb-instagram-feed'); ?>" class="sbi_admin_btn"><i class="fa fa-user-plus" aria-hidden="true" style="font-size: 20px;"></i>&nbsp; <?php esc_html_e('Connect an Instagram Account', 'instagram-feed' ); ?></a>
906
- <a href="https://smashballoon.com/instagram-feed/token/" target="_blank" style="position: relative; top: 14px; left: 15px;"><?php esc_html_e('Button not working?', 'instagram-feed'); ?></a>
907
- </div>
908
-
909
- <tr valign="top">
910
- <th scope="row"><label><?php esc_html_e( 'Instagram Accounts', 'instagram-feed' ); ?></label><span style="font-weight:normal; font-style:italic; font-size: 12px; display: block;"><?php esc_html_e('Use the button above to connect an Instagram account', 'instagram-feed'); ?></span></th>
911
- <td class="sbi_connected_accounts_wrap">
912
  <?php if ( empty( $connected_accounts ) ) : ?>
913
- <p class="sbi_no_accounts"><?php esc_html_e( 'No Instagram accounts connected. Click the button above to connect an account.', 'instagram-feed' ); ?></p><br />
914
- <?php else:
 
915
  $doing_account_error_messages = count( $connected_accounts ) > 1;
916
  global $sb_instagram_posts_manager;
917
 
918
  ?>
919
- <?php foreach ( $connected_accounts as $account ) :
920
- $username = $account['username'] ? $account['username'] : $account['user_id'];
921
- if ( isset( $account['local_avatar'] ) && $account['local_avatar'] && isset( $options['sb_instagram_favor_local'] ) && $options['sb_instagram_favor_local' ] === 'on' ) {
922
- $upload = wp_upload_dir();
923
- $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
924
- $profile_picture = '<img class="sbi_ca_avatar" src="'.$resized_url . $account['username'].'.jpg" />'; //Could add placeholder avatar image
925
- } else {
926
- $profile_picture = $account['profile_picture'] ? '<img class="sbi_ca_avatar" src="'.$account['profile_picture'].'" />' : ''; //Could add placeholder avatar image
927
- }
 
928
 
929
- $is_invalid_class = ! $account['is_valid'] ? ' sbi_account_invalid' : '';
930
- $in_user_feed = in_array( $account['user_id'], $user_feed_ids, true );
931
- $account_type = isset( $account['type'] ) ? $account['type'] : 'personal';
932
- $use_tagged = isset( $account['use_tagged'] ) && $account['use_tagged'] == '1';
933
- $is_private = isset( $account['private'] ) && $account['private'] !== false;
934
-
935
- if ( empty( $profile_picture ) && $account_type === 'personal' ) {
936
- $account_update = sbi_account_data_for_token( $account['access_token'] );
937
- if ( isset( $account['is_valid'] ) ) {
938
- $split = explode( '.', $account['access_token'] );
939
- $connected_accounts[ $split[0] ] = array(
940
- 'access_token' => $account['access_token'],
941
- 'user_id' => $split[0],
942
- 'username' => $account_update['username'],
943
- 'is_valid' => true,
944
- 'last_checked' => time(),
945
- 'profile_picture' => $account_update['profile_picture']
946
- );
947
-
948
- $sbi_options = get_option( 'sb_instagram_settings', array() );
949
- $sbi_options['connected_accounts'] = $connected_accounts;
950
- update_option( 'sb_instagram_settings', $sbi_options );
 
951
  }
 
952
 
953
- }
954
- $updated_or_new_account_class = $new_user_name === $username && $account_type !== 'business' ? ' sbi_ca_new_or_updated' : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
955
 
956
- ?>
957
- <div class="sbi_connected_account<?php echo $is_invalid_class . $updated_or_new_account_class; ?><?php if ( $in_user_feed ) echo ' sbi_account_active' ?> sbi_account_type_<?php echo $account_type; ?>" id="sbi_connected_account_<?php esc_attr_e( $account['user_id'] ); ?>" data-accesstoken="" data-userid="<?php esc_attr_e( $account['user_id'] ); ?>" data-username="<?php esc_attr_e( $account['username'] ); ?>" data-type="<?php esc_attr_e( $account_type ); ?>" data-permissions="<?php if ( $use_tagged ) echo 'tagged'; ?>">
958
- <?php if ( $doing_account_error_messages && $sb_instagram_posts_manager->connected_account_has_error( $account ) ) : ?>
959
- <div class="sbi_deprecated">
960
- <span><i class="fa fa-exclamation-circle" aria-hidden="true"></i><?php esc_html_e( 'Feeds using this account might not be updating due to an error. Try viewing these feeds after reconnecting the account and saving your settings below.', 'instagram-feed' ); ?></span>
961
- </div>
962
- <?php endif; ?>
963
- <div class="sbi_ca_alert">
964
- <span><?php esc_html_e( 'The Access Token for this account is expired or invalid. Click the button above to attempt to renew it.', 'instagram-feed' ); ?></span>
965
- </div>
966
- <div class="sbi_ca_info">
967
-
968
- <div class="sbi_ca_delete">
969
- <a href="<?php echo add_query_arg( 'disconnect', $account['user_id'], get_admin_url( null, 'admin.php?page=sb-instagram-feed' ) ); ?>" class="sbi_delete_account"><i class="fa fa-times"></i><span class="sbi_remove_text"><?php esc_html_e( 'Remove', 'instagram-feed' ); ?></span></a>
970
- </div>
971
-
972
- <div class="sbi_ca_username">
973
- <?php echo $profile_picture; ?>
974
- <strong><?php echo $username; ?><span><?php echo sbi_account_type_display( $account_type, isset( $account['private'] ) ); ?></span></strong>
975
- </div>
976
-
977
- <div class="sbi_ca_actions">
978
- <?php if ( ! $in_user_feed ) : ?>
979
- <a href="JavaScript:void(0);" class="sbi_use_in_user_feed button-primary"><i class="fa fa-plus-circle" aria-hidden="true"></i><?php esc_html_e( 'Add to Primary Feed', 'instagram-feed' ); ?></a>
980
- <?php else : ?>
981
- <a href="JavaScript:void(0);" class="sbi_remove_from_user_feed button-primary"><i class="fa fa-minus-circle" aria-hidden="true"></i><?php esc_html_e( 'Remove from Primary Feed', 'instagram-feed' ); ?></a>
982
- <?php endif; ?>
983
- <a class="sbi_ca_token_shortcode button-secondary" href="JavaScript:void(0);"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i><?php esc_html_e( 'Add to another Feed', 'instagram-feed' ); ?></a>
984
- <a class="sbi_ca_show_token button-secondary" href="JavaScript:void(0);" title="<?php esc_html_e('Show access token and account info', 'instagram-feed'); ?>"><i class="fa fa-cog"></i></a>
985
- <?php if ( $is_private ) :
986
- $expires_in = max( 0, floor( ($account['expires_timestamp'] - time()) / DAY_IN_SECONDS ) );
987
- $message = $expires_in > 0 ? sprintf( __( 'Expires in %s days', 'instagram-feed' ), $expires_in ) : __( 'Access Token Expired', 'instagram-feed' );
988
- $alert_class = $expires_in < 10 ? ' sbi_alert' : '';
989
- ?>
990
- <div class="sbi_is_private<?php echo esc_attr( $alert_class ); ?>">
991
- <span><?php echo esc_html( $message ); ?></span>
992
- <a class="sbi_tooltip_link sbi_tooltip_outside" href="JavaScript:void(0);" style="position: relative; top: 2px;"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
993
 
994
- <a href="https://api.instagram.com/oauth/authorize?client_id=423965861585747&redirect_uri=https://api.smashballoon.com/v2/instagram-basic-display-redirect.php&response_type=code&scope=user_profile,user_media&state=<?php echo admin_url( 'admin.php?page=sb-instagram-feed' ); ?>" class="button button-secondary"><?php esc_html_e( 'Refresh now', 'instagram-feed' ); ?></a>
995
- </div>
996
- <p class="sbi_tooltip sbi-more-info" style="display: none; width: 100%; box-sizing: border-box;"><?php echo sprintf( __( 'This account is a "private" account on Instagram. It needs to be manually reconnected every 60 days. %sChange this account to be "public"%s to have access tokens that are automatically refreshed.', 'instagram-feed' ), '<a href="https://help.instagram.com/116024195217477/In" target="_blank">', '</a>' ); ?></p>
997
- <?php endif; ?>
998
 
999
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1000
 
1001
- <div class="sbi_ca_shortcode">
1002
 
1003
- <p><?php esc_html_e('Copy and paste this shortcode into your page or widget area', 'instagram-feed'); ?>:<br>
1004
- <?php if ( !empty( $account['username'] ) ) : ?>
1005
- <code>[instagram-feed user="<?php echo $account['username']; ?>"]</code>
1006
- <?php endif; ?>
1007
- </p>
1008
 
1009
- <p><?php esc_html_e('To add multiple users in the same feed, simply separate them using commas', 'instagram-feed'); ?>:<br>
1010
- <?php if ( !empty( $account['username'] ) ) : ?>
1011
- <code>[instagram-feed user="<?php echo $account['username']; ?>, a_second_user, a_third_user"]</code>
1012
- <?php endif; ?>
 
1013
 
1014
- <p><?php echo sprintf( __('Click on the %s tab to learn more about shortcodes', 'instagram-feed'), '<a href="?page=sb-instagram-feed&tab=display" target="_blank">'. __( 'Display Your Feed', 'instagram-feed' ) . '</a>' ); ?></p>
1015
- </div>
 
 
1016
 
1017
- <div class="sbi_ca_accesstoken">
1018
- <span class="sbi_ca_token_label"><?php esc_html_e('User ID', 'instagram-feed');?>:</span><input type="text" class="sbi_ca_user_id" value="<?php echo $account['user_id']; ?>" readonly="readonly" onclick="this.focus();this.select()" title="<?php esc_html_e('To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac).', 'instagram-feed');?>"><br>
1019
- </div>
1020
 
1021
- </div>
 
 
1022
 
1023
- </div>
 
 
1024
 
1025
- <?php endforeach; ?>
1026
  <?php endif; ?>
1027
- <a href="JavaScript:void(0);" class="sbi_manually_connect button-secondary"><?php esc_html_e( 'Manually Connect an Account', 'instagram-feed' ); ?></a>
1028
- <div class="sbi_manually_connect_wrap">
1029
- <input name="sb_manual_at" id="sb_manual_at" type="text" value="" style="margin-top: 4px; padding: 5px 9px; margin-left: 0px;" size="64" minlength="15" maxlength="400" placeholder="<?php esc_attr_e( 'Enter a valid Instagram Access Token', 'instagram-feed' ); ?>" /><span class='sbi_business_profile_tag'><?php esc_html_e('Business or Basic Display', 'instagram-feed');?></span>
1030
- <div class="sbi_manual_account_id_toggle">
1031
- <label><?php esc_html_e('Please enter the User ID for this Profile:', 'instagram-feed');?></label>
1032
- <input name="sb_manual_account_id" id="sb_manual_account_id" type="text" value="" style="margin-top: 4px; padding: 5px 9px; margin-left: 0px;" size="40" minlength="5" maxlength="100" placeholder="Eg: 15641403491391489" />
1033
- </div>
1034
- <p id="sbi_no_js_warning" class="sbi_nojs_notice"><?php echo sprintf( __('It looks like JavaScript is not working on this page. Some features may not work fully. Visit %sthis page%s for help resolving this issue.', 'instagram-feed'), '<a href="https://smashballoon.com/i-cant-connect-or-manage-accounts-on-the-instagram-feed-settings-page/" target="_blank" rel="noopener">', '</a>' ); ?></p>
1035
- <p class="sbi_submit" style="display: inline-block;"><input type="submit" name="sbi_submit" id="sbi_manual_submit" class="button button-primary" value="<?php esc_html_e('Connect This Account', 'instagram-feed' );?>"></p>
1036
- </div>
1037
- </td>
1038
- </tr>
1039
-
1040
- <tr valign="top" class="sbi_feed_type">
1041
- <th scope="row"><label><?php esc_html_e('Select a Feed Type', 'instagram-feed'); ?>:</label><code class="sbi_shortcode"> type
1042
  Eg: type=user user=smashballoon
1043
  </code>
1044
  <?php if ( SB_Instagram_Feed_Locator::count_unique() > 1 ) : ?>
1045
- <div class="sbi_locations_link">
1046
- <a href="?page=sb-instagram-feed&amp;tab=allfeeds"><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-search fa-w-16 fa-2x"><path fill="currentColor" d="M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z" class=""></path></svg> <?php esc_html_e('Feed Finder', 'instagram-feed'); ?></a>
1047
- </div>
1048
  <?php endif; ?>
1049
 
1050
- </th>
1051
  <td>
1052
  <div class="sbi_row">
1053
  <div class="sbi_col sbi_one">
1054
- <input type="radio" name="sb_instagram_type" id="sb_instagram_type_user" value="user" <?php if($sb_instagram_type == "user") echo "checked"; ?> />
 
 
 
 
 
1055
  <label class="sbi_radio_label" for="sb_instagram_type_user"><?php esc_html_e( 'User Account:', 'instagram-feed' ); ?></label>
1056
  </div>
1057
  <div class="sbi_col sbi_two">
1058
  <div class="sbi_user_feed_ids_wrap">
1059
- <?php foreach ( $user_feed_ids as $feed_id ) : if ( $feed_id !== '' ) :?>
1060
- <?php if ( ! empty( $connected_accounts) ) { ?><div id="sbi_user_feed_id_<?php echo esc_attr( $feed_id ); ?>" class="sbi_user_feed_account_wrap"><?php } ?>
 
 
 
 
 
 
1061
 
1062
- <?php if ( isset( $connected_accounts[ $feed_id ] ) && ! empty( $connected_accounts[ $feed_id ]['username'] ) ) : ?>
1063
  <strong><?php echo esc_html( $connected_accounts[ $feed_id ]['username'] ); ?></strong> <span>(<?php echo esc_html( $feed_id ); ?>)</span>
1064
  <input name="sb_instagram_user_id[]" id="sb_instagram_user_id" type="hidden" value="<?php echo esc_attr( $feed_id ); ?>" />
1065
  <?php elseif ( isset( $connected_accounts[ $feed_id ] ) && ! empty( $connected_accounts[ $feed_id ]['access_token'] ) ) : ?>
@@ -1067,29 +1148,40 @@ function sb_instagram_settings_page() {
1067
  <input name="sb_instagram_user_id[]" id="sb_instagram_user_id" type="hidden" value="<?php echo esc_attr( $feed_id ); ?>" />
1068
  <?php endif; ?>
1069
 
1070
- <?php if ( ! empty( $connected_accounts) ) { ?></div><?php } ?>
1071
- <?php endif; endforeach; ?>
 
 
 
 
 
 
1072
  </div>
1073
 
1074
  <?php if ( empty( $user_feed_ids ) ) : ?>
1075
  <p class="sbi_no_accounts" style="margin-top: -3px; margin-right: 10px;"><?php esc_html_e( 'Connect a user account above', 'instagram-feed' ); ?></p>
1076
  <?php endif; ?>
1077
 
1078
- <a class="sbi_tooltip_link" href="JavaScript:void(0);" style="margin: 5px 0 10px 0; display: inline-block; height: 19px;"><?php esc_html_e("How to display User feeds", 'instagram-feed' ); ?></a>
1079
- <div class="sbi_tooltip"><?php _e("<p><strong>Displaying Posts from Your User Account</strong><br />Simply connect an account using the button above.</p><p style='padding-top:8px;'><strong>Displaying Posts from Other Instagram Accounts</strong><br />Due to recent changes in the Instagram API it is no longer possible to display photos from other Instagram accounts which you do not have access to. You can only display the user feed of an account which you connect above. You can connect as many account as you like by logging in using the button above, or manually copy/pasting an Access Token by selecting the 'Manually Connect an Account' option.</p><p style='padding-top:10px;'><strong>Multiple Acounts</strong><br />It is only possible to display feeds from Instagram accounts which you own. In order to display feeds from multiple accounts, first connect them above and then use the buttons to add the account either to your primary feed or to another feed on your site.</p>", 'instagram-feed'); ?></div><br />
1080
  </div>
1081
 
1082
  </div>
1083
 
1084
  <div class="sbi_pro sbi_row">
1085
  <div class="sbi_col sbi_one">
1086
- <input disabled type="radio" name="sb_instagram_type" id="sb_instagram_type_hashtag" value="hashtag" <?php if($sb_instagram_type == "hashtag") echo "checked"; ?> />
 
 
 
 
 
1087
  <label class="sbi_radio_label" for="sb_instagram_type_hashtag"><?php esc_html_e( 'Hashtag:', 'instagram-feed' ); ?></label>
1088
  </div>
1089
  <div class="sbi_col sbi_two">
1090
 
1091
  <p class="sbi_pro_tooltip"><?php esc_html_e( 'Upgrade to the Pro version to display Hashtag and Tagged feeds', 'instagram-feed' ); ?><i class="fa fa-caret-down" aria-hidden="true"></i></p>
1092
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=hashtags" target="_blank" class="sbi_lock"><i class="fa fa-rocket"></i><?php esc_html_e('Pro', 'instagram-feed'); ?></a>
1093
 
1094
  <input readonly type="text" size="25" style="height: 32px; top: -2px; position: relative; box-shadow: none;" disabled />
1095
  &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
@@ -1098,45 +1190,50 @@ function sb_instagram_settings_page() {
1098
  </div>
1099
  </div>
1100
 
1101
- <div class="sbi_pro sbi_row">
1102
- <div class="sbi_col sbi_one">
1103
- <input disabled type="radio" name="sb_instagram_type" id="sb_instagram_type_tagged" value="tagged" <?php if($sb_instagram_type == "tagged") echo "checked"; ?> />
1104
- <label class="sbi_radio_label" for="sb_instagram_type_tagged"><?php esc_html_e( 'Tagged:', 'instagram-feed' ); ?></label>
1105
- </div>
1106
- <div class="sbi_col sbi_two">
1107
- <input readonly type="text" size="25" style="height: 32px; top: -2px; position: relative; box-shadow: none;" disabled />
1108
- &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1109
-
1110
- <p class="sbi_tooltip"><?php esc_html_e( 'Display posts that your account has been tagged in.', 'instagram-feed' ); ?></p>
1111
- </div>
1112
- </div>
1113
-
1114
- <div class="sbi_pro sbi_row sbi_mixed_directions">
1115
- <div class="sbi_col sbi_one">
1116
- <input type="radio" name="sb_instagram_type" disabled />
1117
- <label class="sbi_radio_label" for="sb_instagram_type_mixed">Mixed:</label>
1118
- </div>
1119
- <div class="sbi_col sbi_two">
1120
- <input readonly type="text" size="25" style="height: 32px; top: -2px; position: relative; box-shadow: none;" disabled />
1121
- &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1122
-
1123
- <div class="sbi_tooltip sbi_type_tooltip">
1124
- <p>
1125
- <?php echo sprintf( __('To display multiple feed types in a single feed, use %s in your shortcode and then add the user name or hashtag for each feed into the shortcode, like so: %s. This will combine a user feed and a hashtag feed into the same feed.', 'instagram-feed'), 'type="mixed"', '<code>[instagram-feed type="mixed" user="smashballoon" hashtag="#awesomeplugins"]</code>' ); ?>
1126
- </p>
1127
- <p style="padding-top: 8px;"><strong>Note:</strong> To display a hashtag feed, it is required that you first connect an Instagram Business Profile using the <strong>"Connect an Instagram Account"</strong> button above. &nbsp;<a href="https://smashballoon.com/instagram-business-profiles/" target="_blank">Why is this required?</a>
1128
- </p>
1129
- </div>
1130
- </div>
1131
-
1132
- </div>
 
 
 
 
 
1133
 
1134
  <div class="sbi_row sbi_pro">
1135
  <br>
1136
- <a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);" style="margin-left: 0;"><i class="fa fa-question-circle" aria-hidden="true" style="margin-right: 6px;"></i><?php esc_html_e('Combine multiple feed types into a single feed', 'instagram-feed'); ?></a>
1137
  <p class="sbi_tooltip">
1138
- <strong><?php _e( 'Please note: this is only available in the <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=multipletypes" target="_blank">Pro version</a>', 'instagram-feed' ); ?>.</strong><br />
1139
- <?php echo sprintf( __('To display multiple feed types in a single feed, use %s in your shortcode and then add each user name or hashtag of each feed into the shortcode, like so: %s. This will combine a user feed and a hashtag feed into the same feed.', 'instagram-feed'), 'type="mixed"', '<code>[instagram-feed type="mixed" user="smashballoon" hashtag="#awesomeplugins"]</code>' ); ?>
1140
  </p>
1141
  </div>
1142
 
@@ -1144,118 +1241,246 @@ function sb_instagram_settings_page() {
1144
  </tr>
1145
 
1146
  <tr>
1147
- <th class="bump-left"><label for="sb_instagram_preserve_settings" class="bump-left"><?php esc_html_e("Preserve settings when plugin is removed", 'instagram-feed'); ?></label></th>
1148
  <td>
1149
- <input name="sb_instagram_preserve_settings" type="checkbox" id="sb_instagram_preserve_settings" <?php if($sb_instagram_preserve_settings == true) echo "checked"; ?> />
1150
- <label for="sb_instagram_preserve_settings"><?php esc_html_e('Yes', 'instagram-feed'); ?></label>
1151
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
1152
- <p class="sbi_tooltip"><?php esc_html_e('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.', 'instagram-feed'); ?></p>
 
 
 
 
 
1153
  </td>
1154
  </tr>
1155
 
1156
 
1157
- <tr valign="top" class="sbi_cron_cache_opts">
1158
- <th scope="row"><?php esc_html_e( 'Check for new posts', 'instagram-feed' ); ?></th>
1159
- <td>
1160
- <div class="sbi_row">
1161
- <input type="radio" name="sbi_caching_type" id="sbi_caching_type_cron" value="background" <?php if ( $sbi_caching_type === 'background' ) echo 'checked'; ?>>
1162
- <label for="sbi_caching_type_cron"><?php esc_html_e( 'In the background', 'instagram-feed' ); ?></label>
1163
- <a class="sbi_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 2px;"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
1164
- <p class="sbi_tooltip sbi-more-info"><?php esc_html_e( 'Your Instagram post 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', 'instagram-feed' ); ?>:<br><br>
1165
- <?php _e( '<strong>1. In the background</strong><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. <strong>Please note</strong> 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.', 'instagram-feed' ); ?>
1166
- <br><br>
1167
- <?php _e( '<strong>2. When the page loads</strong><br>Selecting this option means that when the cache expires then the plugin will check Instagram 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. <strong>Tip:</strong> If you\'re experiencing an issue with the plugin not updating automatically then try enabling the setting labeled <strong>\'Force cache to clear on interval\'</strong> which is located on the \'Customize\' tab.', 'instagram-feed' ) . '</p>'; ?>
1168
-
1169
- </div>
1170
- <div class="sbi_row sbi-caching-cron-options" style="display: block;">
1171
-
1172
- <select name="sbi_cache_cron_interval" id="sbi_cache_cron_interval">
1173
- <option value="30mins" <?php if ( $sbi_cache_cron_interval === '30mins' ) echo 'selected'; ?>><?php esc_html_e( 'Every 30 minutes', 'instagram-feed' ); ?></option>
1174
- <option value="1hour" <?php if ( $sbi_cache_cron_interval === '1hour' ) echo 'selected'; ?>><?php esc_html_e( 'Every hour', 'instagram-feed' ); ?></option>
1175
- <option value="12hours" <?php if ( $sbi_cache_cron_interval === '12hours' ) echo 'selected'; ?>><?php esc_html_e( 'Every 12 hours', 'instagram-feed' ); ?></option>
1176
- <option value="24hours" <?php if ( $sbi_cache_cron_interval === '24hours' ) echo 'selected'; ?>><?php esc_html_e( 'Every 24 hours', 'instagram-feed' ); ?></option>
1177
- </select>
1178
-
1179
- <div id="sbi-caching-time-settings" style="display: none;">
1180
- <?php esc_html_e('at' ); ?>
1181
-
1182
- <select name="sbi_cache_cron_time" style="width: 80px">
1183
- <option value="1" <?php if ( $sbi_cache_cron_time === '1' ) echo 'selected'; ?>>1:00</option>
1184
- <option value="2" <?php if ( $sbi_cache_cron_time === '2' ) echo 'selected'; ?>>2:00</option>
1185
- <option value="3" <?php if ( $sbi_cache_cron_time === '3' ) echo 'selected'; ?>>3:00</option>
1186
- <option value="4" <?php if ( $sbi_cache_cron_time === '4' ) echo 'selected'; ?>>4:00</option>
1187
- <option value="5" <?php if ( $sbi_cache_cron_time === '5' ) echo 'selected'; ?>>5:00</option>
1188
- <option value="6" <?php if ( $sbi_cache_cron_time === '6' ) echo 'selected'; ?>>6:00</option>
1189
- <option value="7" <?php if ( $sbi_cache_cron_time === '7' ) echo 'selected'; ?>>7:00</option>
1190
- <option value="8" <?php if ( $sbi_cache_cron_time === '8' ) echo 'selected'; ?>>8:00</option>
1191
- <option value="9" <?php if ( $sbi_cache_cron_time === '9' ) echo 'selected'; ?>>9:00</option>
1192
- <option value="10" <?php if ( $sbi_cache_cron_time === '10' ) echo 'selected'; ?>>10:00</option>
1193
- <option value="11" <?php if ( $sbi_cache_cron_time === '11' ) echo 'selected'; ?>>11:00</option>
1194
- <option value="0" <?php if ( $sbi_cache_cron_time === '0' ) echo 'selected'; ?>>12:00</option>
1195
- </select>
1196
-
1197
- <select name="sbi_cache_cron_am_pm" style="width: 50px">
1198
- <option value="am" <?php if ( $sbi_cache_cron_am_pm === 'am' ) echo 'selected'; ?>>AM</option>
1199
- <option value="pm" <?php if ( $sbi_cache_cron_am_pm === 'pm' ) echo 'selected'; ?>>PM</option>
1200
- </select>
1201
- </div>
1202
-
1203
- <?php
1204
- if ( wp_next_scheduled( 'sbi_feed_update' ) ) {
1205
- $time_format = get_option( 'time_format' );
1206
- if ( ! $time_format ) {
1207
- $time_format = 'g:i a';
1208
- }
1209
- //
1210
- $schedule = wp_get_schedule( 'sbi_feed_update' );
1211
- if ( $schedule == '30mins' ) $schedule = __( 'every 30 minutes', 'instagram-feed' );
1212
- if ( $schedule == 'twicedaily' ) $schedule = __( 'every 12 hours', 'instagram-feed' );
1213
- $sbi_next_cron_event = wp_next_scheduled( 'sbi_feed_update' );
1214
- echo '<p class="sbi-caching-sched-notice"><span><strong>' . __( 'Next check', 'instagram-feed' ) . ': ' . date( $time_format, $sbi_next_cron_event + sbi_get_utc_offset() ) . ' (' . $schedule . ')</strong> - ' . __( 'Note: Saving the settings on this page will clear the cache and reset this schedule', 'instagram-feed' ) . '</span></p>';
1215
- } else {
1216
- echo '<p style="font-size: 11px; color: #666;">' . __( 'Nothing currently scheduled', 'instagram-feed' ) . '</p>';
1217
- }
1218
- ?>
1219
-
1220
- </div>
1221
- <div class="sbi_row">
1222
- <input type="radio" name="sbi_caching_type" id="sbi_caching_type_page" value="page" <?php if ( $sbi_caching_type === 'page' ) echo 'checked'; ?>>
1223
- <label for="sbi_caching_type_page"><?php esc_html_e( 'When the page loads', 'instagram-feed' ); ?></label>
1224
- </div>
1225
- <div class="sbi_row sbi-caching-page-options" style="display: none;">
1226
- <?php esc_html_e( 'Every', 'instagram-feed' ); ?>:
1227
- <input name="sb_instagram_cache_time" type="number" value="<?php echo esc_attr( $sb_instagram_cache_time ); ?>" size="4" min="1" max="<?php if ( $sb_instagram_cache_time_unit == "minutes" ) { echo 1440; } else { echo 24; } ?>"/>
1228
- <select name="sb_instagram_cache_time_unit">
1229
- <option value="minutes" <?php if($sb_instagram_cache_time_unit == "minutes") echo 'selected="selected"' ?>><?php esc_html_e('Minutes', 'instagram-feed'); ?></option>
1230
- <option value="hours" <?php if($sb_instagram_cache_time_unit == "hours") echo 'selected="selected"' ?> ><?php esc_html_e('Hours', 'instagram-feed'); ?></option>
1231
- </select>
1232
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
1233
- <p class="sbi_tooltip"><?php esc_html_e('Your Instagram 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 Instagram for posts again. The maximum caching time is 24 hours.', 'instagram-feed'); ?></p>
1234
- </div>
1235
-
1236
- </td>
1237
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1238
 
1239
  </tbody>
1240
  </table>
1241
 
1242
- <?php submit_button(); ?>
1243
  </form>
1244
 
1245
- <p><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>&nbsp; <?php _e('Next Step: <a href="?page=sb-instagram-feed&tab=customize">Customize your Feed</a>', 'instagram-feed'); ?></p>
1246
 
1247
- <p><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <?php _e('Need help setting up the plugin? Check out our <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=supportpage&utm_medium=setupdirections" target="_blank">setup directions</a>', 'instagram-feed'); ?></p>
1248
 
1249
 
1250
- <?php } // End Configure tab ?>
1251
 
1252
- <?php if ( $sbi_active_tab == 'allfeeds' ) {
 
1253
  $locator_summary = SB_Instagram_Feed_Locator::summary();
1254
  include_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/templates/locator-summary.php';
1255
- } ?>
 
1256
 
1257
 
1258
- <?php if( $sbi_active_tab == 'customize' ) { //Start Configure tab ?>
1259
 
1260
  <p class="sb_instagram_contents_links" id="general">
1261
  <span><?php esc_html_e( 'Quick links:', 'instagram-feed' ); ?> </span>
@@ -1265,46 +1490,71 @@ function sb_instagram_settings_page() {
1265
  <a href="#headeroptions"><?php esc_html_e( 'Header', 'instagram-feed' ); ?></a>
1266
  <a href="#loadmore"><?php esc_html_e( "'Load More' Button", 'instagram-feed' ); ?></a>
1267
  <a href="#follow"><?php esc_html_e( "'Follow' Button", 'instagram-feed' ); ?></a>
1268
- <a href="#gdpr"><?php esc_html_e( 'GDPR', 'instagram-feed' ); ?></a>
1269
- <a href="#customcss"><?php esc_html_e( 'Custom CSS', 'instagram-feed' ); ?></a>
1270
  <a href="#customjs"><?php esc_html_e( 'Custom JavaScript', 'instagram-feed' ); ?></a>
1271
- </p>
1272
 
1273
- <input type="hidden" name="<?php echo $sb_instagram_customize_hidden_field; ?>" value="Y">
1274
 
1275
- <h3 id="sbi_general_heading"><?php _e('General', 'instagram-feed'); ?></h3>
1276
 
1277
- <table class="form-table" aria-describedby="sbi_general_heading">
1278
  <tbody>
1279
- <tr valign="top">
1280
- <th scope="row"><label><?php esc_html_e('Width of Feed', 'instagram-feed'); ?></label><code class="sbi_shortcode"> width widthunit
1281
  Eg: width=50 widthunit=%</code></th>
1282
  <td>
1283
  <input name="sb_instagram_width" type="text" value="<?php echo esc_attr( $sb_instagram_width ); ?>" id="sb_instagram_width" size="4" maxlength="4" />
1284
  <select name="sb_instagram_width_unit" id="sb_instagram_width_unit">
1285
- <option value="px" <?php if($sb_instagram_width_unit == "px") echo 'selected="selected"' ?> ><?php esc_html_e('px', 'instagram-feed'); ?></option>
1286
- <option value="%" <?php if($sb_instagram_width_unit == "%") echo 'selected="selected"' ?> ><?php esc_html_e('%', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
1287
  </select>
1288
  <div id="sb_instagram_width_options">
1289
- <input name="sb_instagram_feed_width_resp" type="checkbox" id="sb_instagram_feed_width_resp" <?php if($sb_instagram_feed_width_resp == true) echo "checked"; ?> /><label for="sb_instagram_feed_width_resp"><?php esc_html_e('Set to be 100% width on mobile?', 'instagram-feed'); ?></label>
 
 
 
 
 
1290
  <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
1291
- <p class="sbi_tooltip"><?php esc_html_e("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.", 'instagram-feed'); ?></p>
1292
  </div>
1293
  </td>
1294
  </tr>
1295
- <tr valign="top">
1296
- <th scope="row"><label><?php esc_html_e('Height of Feed', 'instagram-feed'); ?></label><code class="sbi_shortcode"> height heightunit
1297
  Eg: height=500 heightunit=px</code></th>
1298
  <td>
1299
  <input name="sb_instagram_height" type="text" value="<?php echo esc_attr( $sb_instagram_height ); ?>" size="4" maxlength="4" />
1300
  <select name="sb_instagram_height_unit">
1301
- <option value="px" <?php if($sb_instagram_height_unit == "px") echo 'selected="selected"' ?> ><?php esc_html_e('px', 'instagram-feed'); ?></option>
1302
- <option value="%" <?php if($sb_instagram_height_unit == "%") echo 'selected="selected"' ?> ><?php esc_html_e('%', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
1303
  </select>
1304
  </td>
1305
  </tr>
1306
- <tr valign="top">
1307
- <th scope="row"><label><?php esc_html_e('Background Color', 'instagram-feed'); ?></label><code class="sbi_shortcode"> background
1308
  Eg: background=d89531</code></th>
1309
  <td>
1310
  <input name="sb_instagram_background" type="text" value="<?php echo esc_attr( $sb_instagram_background ); ?>" class="sbi_colorpick" />
@@ -1314,57 +1564,62 @@ function sb_instagram_settings_page() {
1314
  </table>
1315
 
1316
  <hr id="layout" />
1317
- <h3 id="sbi_layout_heading"><?php _e('Layout', 'instagram-feed'); ?></h3>
1318
 
1319
- <table class="form-table" aria-describedby="sbi_layout_heading">
1320
  <tbody>
1321
  <?php
1322
  $selected_type = isset( $sb_instagram_layout_type ) ? $sb_instagram_layout_type : 'grid';
1323
- $layout_types = array(
1324
- 'grid' => __( 'Grid', 'instagram-feed' ),
1325
- 'carousel' => __( 'Carousel', 'instagram-feed' ),
1326
- 'masonry' => __( 'Masonry', 'instagram-feed' ),
1327
- 'highlight' => __( 'Highlight', 'instagram-feed' )
1328
  );
1329
  $layout_images = array(
1330
- 'grid' => SBI_PLUGIN_URL . 'img/grid.png',
1331
- 'carousel' => SBI_PLUGIN_URL . 'img/carousel.png',
1332
- 'masonry' => SBI_PLUGIN_URL . 'img/masonry.png',
1333
- 'highlight' => SBI_PLUGIN_URL . 'img/highlight.png'
1334
  );
1335
  ?>
1336
- <tr valign="top">
1337
- <th scope="row" class="sbi_pro"><label title="<?php esc_html_e('Click for shortcode option', 'instagram-feed'); ?>"><?php esc_html_e('Layout Type', 'instagram-feed'); ?></label><br /><span class="sbi_note" style="margin: 5px 0 0 0; font-weight: normal;"><?php esc_html_e('Select a layout to see associated<br />options', 'instagram-feed'); ?></span></th>
1338
  <td>
1339
  <div class="sbi_layouts">
1340
- <?php foreach( $layout_types as $layout_type => $label ) : ?>
1341
  <div class="sbi_layout_cell sbi_pro">
1342
- <input class="sb_layout_type" id="sb_layout_type_<?php echo esc_attr( $layout_type ); ?>" name="sb_instagram_layout_type" type="radio" value="<?php echo esc_attr( $layout_type ); ?>" <?php if ( $selected_type === $layout_type ) echo 'checked'; ?>/><label for="sb_layout_type_<?php echo esc_attr( $layout_type ); ?>"><span class="sbi_label"><?php echo esc_html( $label ); ?></span><img src="<?php echo esc_url( $layout_images[ $layout_type ] ); ?>" /></label>
 
 
 
 
 
1343
  </div>
1344
  <?php endforeach; ?>
1345
 
1346
- <p class="sbi_pro_tooltip"><?php esc_html_e('Upgrade to the Pro version to unlock these layouts', 'instagram-feed'); ?><i class="fa fa-caret-down" aria-hidden="true"></i></p>
1347
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=layouts" target="_blank" class="sbi_lock"><i class="fa fa-rocket"></i><?php esc_html_e('Pro', 'instagram-feed'); ?></a>
1348
 
1349
  </div>
1350
  <div class="sb_layout_options_wrap sbi_pro">
1351
  <a href="JavaScript:void(0);" class="sbi_close_options"><i class="fa fa-close"></i></a>
1352
  <div class="sb_instagram_layout_settings sbi_layout_type_grid">
1353
- <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('A uniform grid of square-cropped images.', 'instagram-feed'); ?></span>
1354
  </div>
1355
  <div class="sb_instagram_layout_settings sbi_layout_type_masonry">
1356
- <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Images in their original aspect ratios with no vertical space between posts.', 'instagram-feed'); ?></span>
1357
  </div>
1358
  <div class="sb_instagram_layout_settings sbi_layout_type_carousel">
1359
  <div class="sb_instagram_layout_setting">
1360
- <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Posts are displayed in a slideshow carousel.', 'instagram-feed'); ?></span>
1361
  </div>
1362
  <div class="sb_instagram_layout_setting">
1363
 
1364
- <label><?php esc_html_e('Number of Rows', 'instagram-feed'); ?></label><code class="sbi_shortcode"> carouselrows
1365
  Eg: carouselrows=2</code>
1366
  <br>
1367
- <span class="sbi_note" style="margin: -5px 0 -10px 0; display: block;"><?php esc_html_e('Use the "Number of Columns" setting below this section to set how many posts are visible in the carousel at a given time.', 'instagram-feed'); ?></span>
1368
  <br>
1369
  <select name="sb_instagram_carousel_rows" id="sb_instagram_carousel_rows">
1370
  <option value="1">1</option>
@@ -1372,50 +1627,50 @@ function sb_instagram_settings_page() {
1372
  </select>
1373
  </div>
1374
  <div class="sb_instagram_layout_setting">
1375
- <label><?php esc_html_e('Loop Type', 'instagram-feed'); ?></label><code class="sbi_shortcode"> carouselloop
1376
  Eg: carouselloop=rewind
1377
  carouselloop=infinity</code>
1378
  <br>
1379
  <select name="sb_instagram_carousel_loop" id="sb_instagram_carousel_loop">
1380
- <option value="rewind"><?php esc_html_e('Rewind', 'instagram-feed'); ?></option>
1381
- <option value="infinity" selected="selected"><?php esc_html_e('Infinity', 'instagram-feed'); ?></option>
1382
  </select>
1383
  </div>
1384
  <div class="sb_instagram_layout_setting">
1385
  <input type="checkbox" name="sb_instagram_carousel_arrows" id="sb_instagram_carousel_arrows" checked="checked">
1386
- <label><?php esc_html_e('Show Navigation Arrows', 'instagram-feed'); ?></label><code class="sbi_shortcode"> carouselarrows
1387
  Eg: carouselarrows=true</code>
1388
  </div>
1389
  <div class="sb_instagram_layout_setting">
1390
  <input type="checkbox" name="sb_instagram_carousel_pag" id="sb_instagram_carousel_pag">
1391
- <label><?php esc_html_e('Show Pagination', 'instagram-feed'); ?></label><code class="sbi_shortcode"> carouselpag
1392
  Eg: carouselpag=true</code>
1393
  </div>
1394
  <div class="sb_instagram_layout_setting">
1395
  <input type="checkbox" name="sb_instagram_carousel_autoplay" id="sb_instagram_carousel_autoplay">
1396
- <label><?php esc_html_e('Enable Autoplay', 'instagram-feed'); ?></label><code class="sbi_shortcode"> carouselautoplay
1397
  Eg: carouselautoplay=true</code>
1398
  </div>
1399
  <div class="sb_instagram_layout_setting">
1400
- <label><?php esc_html_e('Interval Time', 'instagram-feed'); ?></label><code class="sbi_shortcode"> carouseltime
1401
  Eg: carouseltime=8000</code>
1402
  <br>
1403
- <input name="sb_instagram_carousel_interval" type="text" value="5000" size="6"><?php esc_html_e("miliseconds", 'instagram-feed'); ?>
1404
  </div>
1405
  </div>
1406
 
1407
  <div class="sb_instagram_layout_settings sbi_layout_type_highlight">
1408
  <div class="sb_instagram_layout_setting">
1409
- <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Masonry style, square-cropped, image only (no captions or likes/comments below image). "Highlighted" posts are twice as large.', 'instagram-feed'); ?></span>
1410
  </div>
1411
  <div class="sb_instagram_layout_setting">
1412
- <label title="Click for shortcode option"><?php esc_html_e('Highlighting Type', 'instagram-feed'); ?></label><code class="sbi_shortcode"> highlighttype
1413
  Eg: highlighttype=pattern</code>
1414
  <br>
1415
  <select name="sb_instagram_highlight_type" id="sb_instagram_highlight_type">
1416
- <option value="pattern" selected="selected"><?php esc_html_e('Pattern', 'instagram-feed'); ?></option>
1417
- <option value="id"><?php esc_html_e('Post ID', 'instagram-feed'); ?></option>
1418
- <option value="hashtag"><?php esc_html_e('Hashtag', 'instagram-feed'); ?></option>
1419
  </select>
1420
  </div>
1421
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_pattern sb_instagram_layout_setting" style="display: block;">
@@ -1425,77 +1680,142 @@ function sb_instagram_settings_page() {
1425
  <input name="sb_instagram_highlight_offset" type="number" min="0" value="0" style="width: 50px;">
1426
  </div>
1427
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_pattern sb_instagram_layout_setting" style="display: block;">
1428
- <label><?php esc_html_e('Pattern', 'instagram-feed'); ?></label><code class="sbi_shortcode"> highlightpattern
1429
  Eg: highlightpattern=3</code>
1430
  <br>
1431
- <span><?php esc_html_e('Highlight every', 'instagram-feed'); ?></span><input name="sb_instagram_highlight_factor" type="number" min="2" value="6" style="width: 50px;"><span><?php esc_html_e('posts', 'instagram-feed'); ?></span>
1432
  </div>
1433
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_hashtag sb_instagram_layout_setting" style="display: none;">
1434
- <label><?php esc_html_e('Highlight Posts with these Hashtags', 'instagram-feed'); ?></label>
1435
- <input name="sb_instagram_highlight_hashtag" id="sb_instagram_highlight_hashtag" type="text" size="40" value="#fishing">&nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What is this?', 'instagram-feed'); ?></a>
1436
  <br>
1437
- <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Separate multiple hashtags using commas', 'instagram-feed'); ?></span>
1438
 
1439
 
1440
- <p class="sbi_tooltip"><?php esc_html_e('You can use this setting to highlight posts by a hashtag. Use a specified hashtag in your posts and they will be automatically highlighted in your feed.', 'instagram-feed'); ?></p>
1441
  </div>
1442
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_ids sb_instagram_layout_setting" style="display: none;">
1443
- <label><?php esc_html_e('Highlight Posts by ID', 'instagram-feed'); ?></label>
1444
  <textarea name="sb_instagram_highlight_ids" id="sb_instagram_highlight_ids" style="width: 100%;" rows="3">sbi_1852317219231323590_3269008872</textarea>
1445
  <br>
1446
- <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Separate IDs using commas', 'instagram-feed'); ?></span>
1447
 
1448
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What is this?', 'instagram-feed'); ?></a>
1449
- <p class="sbi_tooltip"><?php esc_html_e('You can use this setting to highlight posts by their ID. Enable and use "moderation mode", check the box to show post IDs underneath posts, then copy and paste IDs into this text box.', 'instagram-feed'); ?></p>
1450
  </div>
1451
  </div>
1452
 
1453
  </div>
1454
  </td>
1455
  </tr>
1456
- <tr valign="top">
1457
- <th scope="row"><label><?php esc_html_e('Number of Photos', 'instagram-feed'); ?></label><code class="sbi_shortcode"> num
1458
  Eg: num=6</code></th>
1459
  <td>
1460
  <input name="sb_instagram_num" type="text" value="<?php echo esc_attr( $sb_instagram_num ); ?>" size="4" maxlength="4" />
1461
- <span class="sbi_note"><?php esc_html_e('Number of photos to show initially.', 'instagram-feed'); ?></span>
1462
  </td>
1463
  </tr>
1464
- <tr valign="top">
1465
- <th scope="row"><label><?php esc_html_e('Number of Columns', 'instagram-feed'); ?></label><code class="sbi_shortcode"> cols
1466
  Eg: cols=3</code></th>
1467
  <td>
1468
  <select name="sb_instagram_cols">
1469
- <option value="1" <?php if($sb_instagram_cols == "1") echo 'selected="selected"' ?> ><?php esc_html_e('1', 'instagram-feed'); ?></option>
1470
- <option value="2" <?php if($sb_instagram_cols == "2") echo 'selected="selected"' ?> ><?php esc_html_e('2', 'instagram-feed'); ?></option>
1471
- <option value="3" <?php if($sb_instagram_cols == "3") echo 'selected="selected"' ?> ><?php esc_html_e('3', 'instagram-feed'); ?></option>
1472
- <option value="4" <?php if($sb_instagram_cols == "4") echo 'selected="selected"' ?> ><?php esc_html_e('4', 'instagram-feed'); ?></option>
1473
- <option value="5" <?php if($sb_instagram_cols == "5") echo 'selected="selected"' ?> ><?php esc_html_e('5', 'instagram-feed'); ?></option>
1474
- <option value="6" <?php if($sb_instagram_cols == "6") echo 'selected="selected"' ?> ><?php esc_html_e('6', 'instagram-feed'); ?></option>
1475
- <option value="7" <?php if($sb_instagram_cols == "7") echo 'selected="selected"' ?> ><?php esc_html_e('7', 'instagram-feed'); ?></option>
1476
- <option value="8" <?php if($sb_instagram_cols == "8") echo 'selected="selected"' ?> ><?php esc_html_e('8', 'instagram-feed'); ?></option>
1477
- <option value="9" <?php if($sb_instagram_cols == "9") echo 'selected="selected"' ?> ><?php esc_html_e('9', 'instagram-feed'); ?></option>
1478
- <option value="10" <?php if($sb_instagram_cols == "10") echo 'selected="selected"' ?> ><?php esc_html_e('10', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1479
  </select>
1480
  </td>
1481
  </tr>
1482
- <tr valign="top">
1483
- <th scope="row"><label><?php esc_html_e('Padding around Images', 'instagram-feed'); ?></label><code class="sbi_shortcode"> imagepadding imagepaddingunit</code></th>
1484
  <td>
1485
  <input name="sb_instagram_image_padding" type="text" value="<?php echo esc_attr( $sb_instagram_image_padding ); ?>" size="4" maxlength="4" />
1486
  <select name="sb_instagram_image_padding_unit">
1487
- <option value="px" <?php if($sb_instagram_image_padding_unit == "px") echo 'selected="selected"' ?> ><?php esc_html_e('px', 'instagram-feed'); ?></option>
1488
- <option value="%" <?php if($sb_instagram_image_padding_unit == "%") echo 'selected="selected"' ?> ><?php esc_html_e('%', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
1489
  </select>
1490
  </td>
1491
  </tr>
1492
- <tr valign="top">
1493
- <th scope="row"><label><?php esc_html_e("Disable mobile layout", 'instagram-feed'); ?></label><code class="sbi_shortcode"> disablemobile
1494
  Eg: disablemobile=true</code></th>
1495
  <td>
1496
- <input type="checkbox" name="sb_instagram_disable_mobile" id="sb_instagram_disable_mobile" <?php if($sb_instagram_disable_mobile == true) echo 'checked="checked"' ?> />
 
 
 
 
 
1497
  &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
1498
- <p class="sbi_tooltip"><?php esc_html_e("By default on mobile devices the layout automatically changes to use fewer columns. Checking this setting disables the mobile layout.", 'instagram-feed'); ?></p>
1499
  </td>
1500
  </tr>
1501
  </tbody>
@@ -1504,71 +1824,101 @@ function sb_instagram_settings_page() {
1504
  <?php submit_button(); ?>
1505
 
1506
  <hr id="photos" />
1507
- <h3 id="sbi_photos_heading"><?php _e("Photos", 'instagram-feed'); ?></h3>
1508
- <table class="form-table" aria-describedby="sbi_photos_heading">
1509
  <tbody>
1510
- <tr valign="top">
1511
- <th scope="row"><label><?php esc_html_e('Sort Photos By', 'instagram-feed'); ?></label><code class="sbi_shortcode"> sortby
1512
  Eg: sortby=random</code></th>
1513
  <td>
1514
  <select name="sb_instagram_sort">
1515
- <option value="none" <?php if($sb_instagram_sort == "none") echo 'selected="selected"' ?> ><?php esc_html_e('Newest to oldest', 'instagram-feed'); ?></option>
1516
- <option value="random" <?php if($sb_instagram_sort == "random") echo 'selected="selected"' ?> ><?php esc_html_e('Random', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
1517
  </select>
1518
  </td>
1519
  </tr>
1520
- <tr valign="top">
1521
- <th scope="row"><label><?php esc_html_e('Image Resolution', 'instagram-feed'); ?></label><code class="sbi_shortcode"> imageres
1522
  Eg: imageres=thumb</code></th>
1523
  <td>
1524
 
1525
  <select name="sb_instagram_image_res">
1526
- <option value="auto" <?php if($sb_instagram_image_res == "auto") echo 'selected="selected"' ?> ><?php esc_html_e('Auto-detect (recommended)', 'instagram-feed'); ?></option>
1527
- <option value="thumb" <?php if($sb_instagram_image_res == "thumb") echo 'selected="selected"' ?> ><?php esc_html_e('Thumbnail (150x150)', 'instagram-feed'); ?></option>
1528
- <option value="medium" <?php if($sb_instagram_image_res == "medium") echo 'selected="selected"' ?> ><?php esc_html_e('Medium (320x320)', 'instagram-feed'); ?></option>
1529
- <option value="full" <?php if($sb_instagram_image_res == "full") echo 'selected="selected"' ?> ><?php esc_html_e('Full size (640x640)', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1530
  </select>
1531
 
1532
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does Auto-detect mean?', 'instagram-feed'); ?></a>
1533
- <p class="sbi_tooltip"><?php esc_html_e("Auto-detect means that the plugin automatically sets the image resolution based on the size of your feed.", 'instagram-feed'); ?></p>
1534
 
1535
  </td>
1536
  </tr>
1537
  </tbody>
1538
  </table>
1539
 
1540
- <span><a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options', 'instagram-feed'); ?></a></span>
1541
 
1542
  <div class="sbi-pro-options">
1543
  <p class="sbi-upgrade-link">
1544
- <i class="fa fa-rocket" aria-hidden="true"></i>&nbsp; <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=general" target="_blank"><?php esc_html_e('Upgrade to Pro to enable these settings', 'instagram-feed'); ?></a>
1545
  </p>
1546
  <table class="form-table" aria-describedby="sbi-mediatype-desc">
1547
  <tbody>
1548
- <tr valign="top" class="sbi_pro">
1549
- <th scope="row"><label id="sbi-mediatype-desc"><?php esc_html_e('Media Type to Display','instagram-feed'); ?></label></th>
1550
  <td>
1551
  <select name="sb_instagram_media_type" disabled>
1552
- <option value="all"><?php esc_html_e('All','instagram-feed'); ?></option>
1553
- <option value="photos"><?php esc_html_e('Photos only','instagram-feed'); ?></option>
1554
- <option value="videos"><?php esc_html_e('Videos only','instagram-feed'); ?></option>
1555
  </select>
1556
  </td>
1557
  </tr>
1558
 
1559
- <tr valign="top" class="sbi_pro">
1560
- <th scope="row"><label><?php esc_html_e("Enable Pop-up Lightbox", 'instagram-feed'); ?></label></th>
1561
  <td>
1562
  <input type="checkbox" name="sb_instagram_captionlinks" id="sb_instagram_captionlinks" disabled />
1563
  </td>
1564
  </tr>
1565
 
1566
- <tr valign="top" class="sbi_pro">
1567
- <th scope="row"><label><?php esc_html_e("Link Posts to URL in Caption (Shoppable feed)",'instagram-feed'); ?></label></th>
1568
  <td>
1569
  <input type="checkbox" name="sb_instagram_captionlinks" id="sb_instagram_captionlinks" disabled />
1570
- &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e("What will this do?",'instagram-feed'); ?></a>
1571
- <p class="sbi_tooltip"><?php _e("Checking this box will change the link for each post to any url included in the caption for that Instagram post. The lightbox will be disabled. Visit <a href='https://smashballoon.com/make-a-shoppable-feed?utm_campaign=instagram-free&utm_source=settings&utm_medium=shoppable'>this link</a> to learn how this works.",'instagram-feed'); ?></p>
1572
  </td>
1573
  </tr>
1574
  </tbody>
@@ -1577,58 +1927,58 @@ function sb_instagram_settings_page() {
1577
 
1578
 
1579
  <hr />
1580
- <h3 id="sbi-hoverstyle-desc"><?php esc_html_e('Photo Hover Style','instagram-feed'); ?></h3>
1581
 
1582
  <p style="padding-bottom: 18px;">
1583
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=photohover" target="_blank"><?php esc_html_e('Upgrade to Pro to enable Photo Hover styles','instagram-feed'); ?></a><br />
1584
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options','instagram-feed'); ?></a>
1585
  </p>
1586
 
1587
  <div class="sbi-pro-options" style="margin-top: -15px;">
1588
  <table class="form-table" aria-describedby="sbi-hoverstyle-desc">
1589
  <tbody>
1590
- <tr valign="top" class="sbi_pro">
1591
- <th scope="row"><label><?php esc_html_e('Hover Background Color', 'instagram-feed'); ?></label></th>
1592
  <td>
1593
  <input name="sb_hover_background" type="text" disabled class="sbi_colorpick" />
1594
  </td>
1595
  </tr>
1596
- <tr valign="top" class="sbi_pro">
1597
- <th scope="row"><label><?php esc_html_e('Hover Text Color', 'instagram-feed'); ?></label></th>
1598
  <td>
1599
  <input name="sb_hover_text" type="text" disabled class="sbi_colorpick" />
1600
  </td>
1601
  </tr>
1602
- <tr valign="top" class="sbi_pro">
1603
- <th scope="row"><label><?php esc_html_e('Information to display', 'instagram-feed'); ?></label></th>
1604
  <td>
1605
  <div>
1606
  <input name="sbi_hover_inc_username" type="checkbox" disabled />
1607
- <label for="sbi_hover_inc_username"><?php esc_html_e('Username', 'instagram-feed'); ?></label>
1608
  </div>
1609
  <div>
1610
  <input name="sbi_hover_inc_icon" type="checkbox" disabled />
1611
- <label for="sbi_hover_inc_icon"><?php esc_html_e('Expand Icon', 'instagram-feed'); ?></label>
1612
  </div>
1613
  <div>
1614
  <input name="sbi_hover_inc_date" type="checkbox" disabled />
1615
- <label for="sbi_hover_inc_date"><?php esc_html_e('Date', 'instagram-feed'); ?></label>
1616
  </div>
1617
  <div>
1618
  <input name="sbi_hover_inc_instagram" type="checkbox" disabled />
1619
- <label for="sbi_hover_inc_instagram"><?php esc_html_e('Instagram Icon/Link', 'instagram-feed'); ?></label>
1620
  </div>
1621
  <div>
1622
  <input name="sbi_hover_inc_location" type="checkbox" disabled />
1623
- <label for="sbi_hover_inc_location"><?php esc_html_e('Location', 'instagram-feed'); ?></label>
1624
  </div>
1625
  <div>
1626
  <input name="sbi_hover_inc_caption" type="checkbox" disabled />
1627
- <label for="sbi_hover_inc_caption"><?php esc_html_e('Caption', 'instagram-feed'); ?></label>
1628
  </div>
1629
  <div>
1630
  <input name="sbi_hover_inc_likes" type="checkbox" disabled />
1631
- <label for="sbi_hover_inc_likes"><?php esc_html_e('Like/Comment Icons', 'instagram-feed'); ?></label>
1632
  </div>
1633
  </td>
1634
  </tr>
@@ -1641,43 +1991,43 @@ function sb_instagram_settings_page() {
1641
  <hr />
1642
  <h3 id="sbi-carousel-desc"><?php esc_html_e( 'Carousel', 'instagram-feed' ); ?></h3>
1643
  <p style="padding-bottom: 18px;">
1644
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=carousel" target="_blank"><?php esc_html_e('Upgrade to Pro to enable Carousels', 'instagram-feed'); ?></a><br />
1645
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options', 'instagram-feed'); ?></a>
1646
  </p>
1647
 
1648
  <div class="sbi-pro-options" style="margin-top: -15px;">
1649
  <table class="form-table" aria-describedby="sbi-carousel-desc">
1650
  <tbody>
1651
- <tr valign="top" class="sbi_pro">
1652
- <th scope="row"><label><?php esc_html_e("Enable Carousel", 'instagram-feed'); ?></label></th>
1653
  <td>
1654
  <input type="checkbox" disabled />
1655
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e("What is this?", 'instagram-feed'); ?></a>
1656
- <p class="sbi_tooltip"><?php esc_html_e("Enable this setting to create a carousel slider out of your photos.", 'instagram-feed'); ?></p>
1657
  </td>
1658
  </tr>
1659
- <tr valign="top" class="sbi_pro">
1660
- <th scope="row"><label><?php esc_html_e("Show Navigation Arrows", 'instagram-feed'); ?></label></th>
1661
  <td>
1662
  <input type="checkbox" disabled />
1663
  </td>
1664
  </tr>
1665
- <tr valign="top" class="sbi_pro">
1666
- <th scope="row"><label><?php esc_html_e("Show Pagination", 'instagram-feed'); ?></label></th>
1667
  <td>
1668
  <input type="checkbox" disabled />
1669
  </td>
1670
  </tr>
1671
- <tr valign="top" class="sbi_pro">
1672
- <th scope="row"><label><?php esc_html_e("Enable Autoplay", 'instagram-feed'); ?></label></th>
1673
  <td>
1674
  <input type="checkbox" disabled />
1675
  </td>
1676
  </tr>
1677
- <tr valign="top" class="sbi_pro">
1678
- <th scope="row"><label><?php esc_html_e("Interval Time", 'instagram-feed'); ?></label></th>
1679
  <td>
1680
- <input name="sb_instagram_carousel_interval" type="text" disabled size="6" /><?php esc_html_e("milliseconds", 'instagram-feed'); ?>
1681
  </td>
1682
  </tr>
1683
  </tbody>
@@ -1687,65 +2037,90 @@ function sb_instagram_settings_page() {
1687
 
1688
 
1689
  <hr id="headeroptions" />
1690
- <h3 id="sbi_header_heading"><?php _e("Header", 'instagram-feed'); ?></h3>
1691
- <table class="form-table" aria-describedby="sbi_header_heading">
1692
  <tbody>
1693
- <tr valign="top">
1694
- <th scope="row"><label><?php esc_html_e("Show Feed Header", 'instagram-feed'); ?></label><code class="sbi_shortcode"> showheader
1695
  Eg: showheader=false</code></th>
1696
  <td>
1697
- <input type="checkbox" name="sb_instagram_show_header" id="sb_instagram_show_header" <?php if($sb_instagram_show_header == true) echo 'checked="checked"' ?> />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1698
  </td>
1699
  </tr>
1700
- <tr valign="top">
1701
- <th scope="row"><label><?php esc_html_e('Header Size', 'instagram-feed'); ?></label><code class="sbi_shortcode"> headersize
1702
- Eg: headersize=medium</code></th>
1703
- <td>
1704
- <select name="sb_instagram_header_size" id="sb_instagram_header_size" style="float: left;">
1705
- <option value="small" <?php if($sb_instagram_header_size == "small") echo 'selected="selected"' ?> ><?php esc_html_e('Small', 'instagram-feed'); ?></option>
1706
- <option value="medium" <?php if($sb_instagram_header_size == "medium") echo 'selected="selected"' ?> ><?php esc_html_e('Medium', 'instagram-feed'); ?></option>
1707
- <option value="large" <?php if($sb_instagram_header_size == "large") echo 'selected="selected"' ?> ><?php esc_html_e('Large', 'instagram-feed'); ?></option>
1708
- </select>
1709
- </td>
1710
- </tr>
1711
- <tr valign="top">
1712
- <th scope="row"><label><?php esc_html_e("Show Bio Text", 'instagram-feed'); ?></label><code class="sbi_shortcode"> showbio
1713
- Eg: showbio=false</code></th>
1714
- <td>
1715
- <?php $sb_instagram_show_bio = isset( $sb_instagram_show_bio ) ? $sb_instagram_show_bio : true; ?>
1716
- <input type="checkbox" name="sb_instagram_show_bio" id="sb_instagram_show_bio" <?php if($sb_instagram_show_bio == true) echo 'checked="checked"' ?> />
1717
- <span class="sbi_note"><?php esc_html_e("Only applies for Instagram accounts with bios", 'instagram-feed'); ?></span>
1718
- <div class="sb_instagram_box" style="display: block;">
1719
- <div class="sb_instagram_box_setting" style="display: block;">
1720
- <label style="padding-bottom: 0;"><?php esc_html_e("Add Custom Bio Text", 'instagram-feed'); ?></label><code class="sbi_shortcode" style="margin-top: 5px;"> custombio
1721
- Eg: custombio="My custom bio."</code>
1722
- <br>
1723
- <span class="sbi_aside" style="padding-bottom: 5px; display: block;"><?php esc_html_e("Use your own custom bio text in the feed header. Bio text is automatically retrieved from Instagram for Business accounts.", 'instagram-feed'); ?></span>
1724
-
1725
- <textarea type="text" name="sb_instagram_custom_bio" id="sb_instagram_custom_bio" ><?php echo esc_textarea( wp_unslash( $sb_instagram_custom_bio ) ); ?></textarea>
1726
- &nbsp;<a class="sbi_tooltip_link sbi_tooltip_under" href="JavaScript:void(0);"><?php esc_html_e("Why is my bio not displaying automatically?", 'instagram-feed'); ?></a>
1727
- <p class="sbi_tooltip" style="padding: 10px 0 0 0; width: 99%;"><?php echo sprintf( __("Instagram is deprecating their old API for Personal accounts on June 1, 2020. The plugin supports their new API, however, their new API does not yet include the bio text for Personal accounts. If you require this feature then it is available if you convert your Instagram account from a Personal to a Business account by following %s. Note: If you previously had a Personal account connected then the plugin has saved the avatar for that feed and will continue to use it automatically.", 'instagram-feed'), '<a href="https://smashballoon.com/instagram-business-profiles/" target="_blank">these directions</a>' ); ?></p>
1728
- </div>
1729
- </div>
1730
-
1731
- </td>
1732
- </tr>
1733
-
1734
- <tr valign="top">
1735
- <th scope="row"><label><?php esc_html_e("Use Custom Avatar", 'instagram-feed'); ?></label><code class="sbi_shortcode"> customavatar
1736
- Eg: customavatar="https://my-website.com/avatar.jpg"</code></th>
1737
- <td>
1738
- <input type="text" name="sb_instagram_custom_avatar" class="large-text" id="sb_instagram_custom_avatar" value="<?php echo esc_attr( wp_unslash( $sb_instagram_custom_avatar ) ); ?>" placeholder="https://example.com/avatar.jpg" />
1739
- <span class="sbi_aside"><?php esc_html_e("Avatar is automatically retrieved from Instagram for Business accounts", 'instagram-feed'); ?></span>
1740
- <br>
1741
- <a class="sbi_tooltip_link sbi_tooltip_under" href="JavaScript:void(0);"><?php esc_html_e("Why is my avatar not displaying automatically?", 'instagram-feed'); ?></a>
1742
-
1743
- <p class="sbi_tooltip sbi_tooltip_under_text" style="padding: 10px 0 0 0;"><?php echo sprintf( __("Instagram is deprecating their old API for Personal accounts on June 1, 2020. The plugin supports their new API, however, their new API does not yet include the avatar image for Personal accounts. If you require this feature then it is available if you convert your Instagram account from a Personal to a Business account by following %s. Note: If you previously had a Personal account connected then the plugin has saved the bio text for that feed and will continue to use it automatically.", 'instagram-feed'), '<a href="https://smashballoon.com/instagram-business-profiles/" target="_blank">these directions</a>' ); ?></p>
1744
-
1745
- </td>
1746
- </tr>
1747
- <tr valign="top">
1748
- <th scope="row"><label><?php esc_html_e('Header Text Color', 'instagram-feed'); ?></label><code class="sbi_shortcode"> headercolor
1749
  Eg: headercolor=fff</code></th>
1750
  <td>
1751
  <input name="sb_instagram_header_color" type="text" value="<?php echo esc_attr( $sb_instagram_header_color ); ?>" class="sbi_colorpick" />
@@ -1754,31 +2129,31 @@ function sb_instagram_settings_page() {
1754
  </tbody>
1755
  </table>
1756
 
1757
- <span><a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options', 'instagram-feed'); ?></a></span>
1758
 
1759
  <div class="sbi-pro-options">
1760
  <p class="sbi-upgrade-link">
1761
- <i class="fa fa-rocket" aria-hidden="true"></i>&nbsp; <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=header" target="_blank"><?php esc_html_e('Upgrade to Pro to enable these settings', 'instagram-feed'); ?></a>
1762
  </p>
1763
- <table class="form-table sbi-expandable-options" aria-describedby="sbi-headerstylesub-desc">
1764
- <tbody>
1765
 
1766
- <tr valign="top">
1767
- <th scope="row" id="sbi-headerstylesub-desc"><label><?php _e('Header Style', 'instagram-feed'); ?></label><code class="sbi_shortcode"> headerstyle
1768
- Eg: headerstyle=boxed</code></th>
1769
- <td>
1770
  <select name="sb_instagram_header_style" style="float: left;">
1771
- <option value="circle"><?php esc_html_e('Standard','instagram-feed'); ?></option>
1772
- <option value="boxed"><?php esc_html_e('Boxed','instagram-feed'); ?></option>
1773
- <option value="centered"><?php esc_html_e('Centered','instagram-feed'); ?></option>
1774
  </select>
1775
  </td>
1776
  </tr>
1777
- <tr valign="top" class="sbi_pro">
1778
- <th scope="row"><label><?php esc_html_e("Show Number of Followers",'instagram-feed'); ?></label></th>
1779
  <td>
1780
  <input type="checkbox" disabled />
1781
- <span class="sbi_note"><?php esc_html_e("This only applies when displaying photos from a User ID",'instagram-feed'); ?></span>
1782
  </td>
1783
  </tr>
1784
  </tbody>
@@ -1789,40 +2164,40 @@ function sb_instagram_settings_page() {
1789
 
1790
 
1791
  <hr />
1792
- <h3 id="sbi_caption_heading"><?php esc_html_e("Caption", 'instagram-feed'); ?></h3>
1793
  <p style="padding-bottom: 18px;">
1794
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=caption" target="_blank"><?php esc_html_e("Upgrade to Pro to enable Photo Captions", 'instagram-feed'); ?></a><br />
1795
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e("Show Pro Options", 'instagram-feed'); ?></a>
1796
  </p>
1797
 
1798
  <div class="sbi-pro-options" style="margin-top: -15px;">
1799
- <table class="form-table" aria-describedby="sbi_caption_heading">
1800
  <tbody>
1801
- <tr valign="top" class="sbi_pro">
1802
- <th scope="row"><label><?php esc_html_e("Show Caption", 'instagram-feed'); ?></label></th>
1803
  <td>
1804
  <input type="checkbox" disabled />
1805
  </td>
1806
  </tr>
1807
- <tr valign="top" class="sbi_pro">
1808
- <th scope="row"><label><?php esc_html_e("Maximum Text Length", 'instagram-feed'); ?></label></th>
1809
  <td>
1810
  <input disabled size="4" />Characters
1811
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e("What is this?", 'instagram-feed'); ?></a>
1812
- <p class="sbi_tooltip"><?php esc_html_e("The number of characters of text to display in the caption. An elipsis link will be added to allow the user to reveal more text if desired.", 'instagram-feed'); ?></p>
1813
  </td>
1814
  </tr>
1815
- <tr valign="top" class="sbi_pro">
1816
- <th scope="row"><label><?php esc_html_e('Text Color', 'instagram-feed'); ?></label></th>
1817
  <td>
1818
  <input type="text" disabled class="sbi_colorpick" />
1819
  </td>
1820
  </tr>
1821
- <tr valign="top" class="sbi_pro">
1822
- <th scope="row"><label><?php esc_html_e('Text Size', 'instagram-feed'); ?></label></th>
1823
  <td>
1824
  <select name="sb_instagram_caption_size" style="width: 180px;" disabled>
1825
- <option value="inherit" ><?php esc_html_e('Inherit from theme', 'instagram-feed'); ?></option>
1826
  <option value="10" >10px</option>
1827
  <option value="11" >11px</option>
1828
  <option value="12" >12px</option>
@@ -1845,32 +2220,32 @@ function sb_instagram_settings_page() {
1845
 
1846
 
1847
  <hr />
1848
- <h3 id="sbi_likescomments_heading"><?php esc_html_e("Likes &amp; Comments", 'instagram-feed'); ?></h3>
1849
  <p style="padding-bottom: 18px;">
1850
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=stats" target="_blank"><?php esc_html_e("Upgrade to Pro to enable Likes &amp; Comments", 'instagram-feed'); ?></a><br />
1851
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e("Show Pro Options", 'instagram-feed'); ?></a>
1852
  </p>
1853
 
1854
  <div class="sbi-pro-options" style="margin-top: -15px;">
1855
  <table class="form-table" aria-describedby="sbi_likescomments_heading">
1856
  <tbody>
1857
- <tr valign="top" class="sbi_pro">
1858
- <th scope="row"><label><?php esc_html_e("Show Icons", 'instagram-feed'); ?></label></th>
1859
  <td>
1860
  <input type="checkbox" disabled />
1861
  </td>
1862
  </tr>
1863
- <tr valign="top" class="sbi_pro">
1864
- <th scope="row"><label><?php esc_html_e('Icon Color', 'instagram-feed'); ?></label></th>
1865
  <td>
1866
  <input type="text" disabled class="sbi_colorpick" />
1867
  </td>
1868
  </tr>
1869
- <tr valign="top" class="sbi_pro">
1870
- <th scope="row"><label><?php esc_html_e('Icon Size', 'instagram-feed'); ?></label></th>
1871
  <td>
1872
  <select disabled name="sb_instagram_meta_size" style="width: 180px;">
1873
- <option value="inherit"><?php esc_html_e('Inherit from theme', 'instagram-feed'); ?></option>
1874
  <option value="10" >10px</option>
1875
  <option value="11" >11px</option>
1876
  <option value="12" >12px</option>
@@ -1893,33 +2268,33 @@ function sb_instagram_settings_page() {
1893
 
1894
 
1895
  <hr />
1896
- <h3 id="sbi-lightboxcomments-heading"><?php esc_html_e('Lightbox Comments', 'instagram-feed'); ?></h3>
1897
 
1898
  <p style="padding-bottom: 18px;">
1899
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=comments" target="_blank"><?php esc_html_e('Upgrade to Pro to enable Comments', 'instagram-feed'); ?></a><br />
1900
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options', 'instagram-feed'); ?></a>
1901
  </p>
1902
 
1903
  <div class="sbi-pro-options" style="margin-top: -15px;">
1904
  <table class="form-table" aria-describedby="sbi-lightboxcomments-heading">
1905
  <tbody>
1906
 
1907
- <tr valign="top" class="sbi_pro">
1908
- <th scope="row"><label><?php esc_html_e('Show Comments in Lightbox', 'instagram-feed'); ?></label></th>
1909
  <td style="padding: 5px 10px 0 10px;">
1910
  <input type="checkbox" disabled style="margin-right: 15px;" />
1911
  <input class="button-secondary" style="margin-top: -5px;" disabled value="<?php esc_attr_e( 'Clear Comment Cache', 'instagram-feed' ); ?>" />
1912
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e("What is this?", 'instagram-feed'); ?></a>
1913
- <p class="sbi_tooltip"><?php esc_html_e("This will remove the cached comments saved in the database", 'instagram-feed'); ?></p>
1914
  </td>
1915
  </tr>
1916
- <tr valign="top" class="sbi_pro">
1917
- <th scope="row"><label><?php esc_html_e('Number of Comments', 'instagram-feed'); ?></label></th>
1918
  <td>
1919
  <input name="sb_instagram_num_comments" type="text" disabled size="4" />
1920
- <span class="sbi_note"><?php esc_html_e('Max number of latest comments.', 'instagram-feed'); ?></span>
1921
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e("What is this?", 'instagram-feed'); ?></a>
1922
- <p class="sbi_tooltip"><?php esc_html_e("This is the maximum number of comments that will be shown in the lightbox. If there are more comments available than the number set, only the latest comments will be shown", 'instagram-feed'); ?></p>
1923
  </td>
1924
  </tr>
1925
 
@@ -1929,32 +2304,37 @@ function sb_instagram_settings_page() {
1929
 
1930
 
1931
  <hr id="loadmore" />
1932
- <h3 id="sbi_button_heading"><?php _e("'Load More' Button", 'instagram-feed'); ?></h3>
1933
- <table class="form-table" aria-describedby="sbi_button_heading">
1934
  <tbody>
1935
- <tr valign="top">
1936
- <th scope="row"><label><?php esc_html_e("Show the 'Load More' button", 'instagram-feed'); ?></label><code class="sbi_shortcode"> showbutton
1937
  Eg: showbutton=false</code></th>
1938
  <td>
1939
- <input type="checkbox" name="sb_instagram_show_btn" id="sb_instagram_show_btn" <?php if($sb_instagram_show_btn == true) echo 'checked="checked"' ?> />
 
 
 
 
 
1940
  </td>
1941
  </tr>
1942
- <tr valign="top">
1943
- <th scope="row"><label><?php esc_html_e('Button Background Color', 'instagram-feed'); ?></label><code class="sbi_shortcode"> buttoncolor
1944
  Eg: buttoncolor=8224e3</code></th>
1945
  <td>
1946
  <input name="sb_instagram_btn_background" type="text" value="<?php echo esc_attr( $sb_instagram_btn_background ); ?>" class="sbi_colorpick" />
1947
  </td>
1948
  </tr>
1949
- <tr valign="top">
1950
- <th scope="row"><label><?php esc_html_e('Button Text Color', 'instagram-feed'); ?></label><code class="sbi_shortcode"> buttontextcolor
1951
  Eg: buttontextcolor=eeee22</code></th>
1952
  <td>
1953
  <input name="sb_instagram_btn_text_color" type="text" value="<?php echo esc_attr( $sb_instagram_btn_text_color ); ?>" class="sbi_colorpick" />
1954
  </td>
1955
  </tr>
1956
- <tr valign="top">
1957
- <th scope="row"><label><?php esc_html_e('Button Text', 'instagram-feed'); ?></label><code class="sbi_shortcode"> buttontext
1958
  Eg: buttontext="Show more.."</code></th>
1959
  <td>
1960
  <input name="sb_instagram_btn_text" type="text" value="<?php echo esc_attr( wp_unslash( $sb_instagram_btn_text ) ); ?>" size="20" />
@@ -1966,33 +2346,38 @@ function sb_instagram_settings_page() {
1966
  <?php submit_button(); ?>
1967
 
1968
  <hr id="follow" />
1969
- <h3 id="sbi_follow_heading"><?php _e("'Follow' Button", 'instagram-feed'); ?></h3>
1970
- <table class="form-table" aria-describedby="sbi_follow_heading">
1971
  <tbody>
1972
- <tr valign="top">
1973
- <th scope="row"><label><?php esc_html_e("Show the Follow button", 'instagram-feed'); ?></label><code class="sbi_shortcode"> showfollow
1974
  Eg: showfollow=true</code></th>
1975
  <td>
1976
- <input type="checkbox" name="sb_instagram_show_follow_btn" id="sb_instagram_show_follow_btn" <?php if($sb_instagram_show_follow_btn == true) echo 'checked="checked"' ?> />
 
 
 
 
 
1977
  </td>
1978
  </tr>
1979
 
1980
- <tr valign="top">
1981
- <th scope="row"><label><?php esc_html_e('Button Background Color', 'instagram-feed'); ?></label><code class="sbi_shortcode"> followcolor
1982
  Eg: followcolor=28a1bf</code></th>
1983
  <td>
1984
  <input name="sb_instagram_folow_btn_background" type="text" value="<?php echo esc_attr( $sb_instagram_folow_btn_background ); ?>" class="sbi_colorpick" />
1985
  </td>
1986
  </tr>
1987
- <tr valign="top">
1988
- <th scope="row"><label><?php esc_html_e('Button Text Color', 'instagram-feed'); ?></label><code class="sbi_shortcode"> followtextcolor
1989
  Eg: followtextcolor=000</code></th>
1990
  <td>
1991
  <input name="sb_instagram_follow_btn_text_color" type="text" value="<?php echo esc_attr( $sb_instagram_follow_btn_text_color ); ?>" class="sbi_colorpick" />
1992
  </td>
1993
  </tr>
1994
- <tr valign="top">
1995
- <th scope="row"><label><?php esc_html_e('Button Text', 'instagram-feed'); ?></label><code class="sbi_shortcode"> followtext
1996
  Eg: followtext="Follow me"</code></th>
1997
  <td>
1998
  <input name="sb_instagram_follow_btn_text" type="text" value="<?php echo esc_attr( wp_unslash( $sb_instagram_follow_btn_text ) ); ?>" size="30" />
@@ -2002,48 +2387,48 @@ function sb_instagram_settings_page() {
2002
  </table>
2003
 
2004
  <hr id="filtering" />
2005
- <h3 id="sbi-filter-heading"><?php esc_html_e('Post Filtering', 'instagram-feed'); ?></h3>
2006
 
2007
  <p style="padding-bottom: 18px;">
2008
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=filtering" target="_blank"><?php esc_html_e('Upgrade to Pro to enable Post Filtering options', 'instagram-feed'); ?></a><br />
2009
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options', 'instagram-feed'); ?></a>
2010
  </p>
2011
 
2012
  <div class="sbi-pro-options" style="margin-top: -15px;">
2013
 
2014
  <table class="form-table" aria-describedby="sbi-filter-heading">
2015
  <tbody>
2016
- <tr valign="top" class="sbi_pro">
2017
- <th scope="row"><label><?php esc_html_e('Remove photos containing these words or hashtags', 'instagram-feed'); ?></label></th>
2018
  <td>
2019
  <div class="sb_instagram_apply_labels">
2020
- <p><?php esc_html_e('Apply to:', 'instagram-feed'); ?></p>
2021
- <input class="sb_instagram_incex_one_all" type="radio" value="all" disabled /><label><?php esc_html_e('All feeds', 'instagram-feed'); ?></label>
2022
- <input class="sb_instagram_incex_one_all" type="radio" value="one" disabled /><label><?php esc_html_e('One feed', 'instagram-feed'); ?></label>
2023
  </div>
2024
 
2025
  <input disabled name="sb_instagram_exclude_words" id="sb_instagram_exclude_words" type="text" style="width: 70%;" value="" />
2026
  <br />
2027
- <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Separate words/hashtags using commas', 'instagram-feed'); ?></span>
2028
- &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed'); ?></a>
2029
- <p class="sbi_tooltip"><?php esc_html_e("You can use this setting to remove photos which contain certain words or hashtags in the caption. Separate multiple words or hashtags using commas.", 'instagram-feed'); ?></p>
2030
  </td>
2031
  </tr>
2032
 
2033
- <tr valign="top" class="sbi_pro">
2034
- <th scope="row"><label><?php esc_html_e('Show photos containing these words or hashtags', 'instagram-feed'); ?></label></th>
2035
  <td>
2036
  <div class="sb_instagram_apply_labels">
2037
- <p><?php esc_html_e('Apply to:', 'instagram-feed'); ?></p>
2038
- <input class="sb_instagram_incex_one_all" type="radio" value="all" disabled /><label><?php esc_html_e('All feeds', 'instagram-feed'); ?></label>
2039
- <input class="sb_instagram_incex_one_all" type="radio" value="one" disabled /><label><?php esc_html_e('One feed', 'instagram-feed'); ?></label>
2040
  </div>
2041
 
2042
  <input disabled name="sb_instagram_include_words" id="sb_instagram_include_words" type="text" style="width: 70%;" value="" />
2043
  <br />
2044
- <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Separate words/hashtags using commas', 'instagram-feed'); ?></span>
2045
- &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed'); ?></a>
2046
- <p class="sbi_tooltip"><?php _e("You can use this setting to only show photos which contain certain words or hashtags in the caption. For example, adding <code>sheep, cow, dog</code> will show any photos which contain either the word sheep, cow, or dog. Separate multiple words or hashtags using commas.", 'instagram-feed'); ?></p>
2047
  </td>
2048
  </tr>
2049
  </tbody>
@@ -2052,47 +2437,47 @@ function sb_instagram_settings_page() {
2052
 
2053
 
2054
  <hr id="moderation" />
2055
- <h3 id="sbi-moderation-heading"><?php esc_html_e('Moderation', 'instagram-feed'); ?></h3>
2056
 
2057
  <p style="padding-bottom: 18px;">
2058
- <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=moderation" target="_blank"><?php esc_html_e('Upgrade to Pro to enable Moderation options', 'instagram-feed'); ?></a><br />
2059
- <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e('Show Pro Options', 'instagram-feed'); ?></a>
2060
  </p>
2061
 
2062
  <div class="sbi-pro-options" style="margin-top: -15px;">
2063
  <table class="form-table" aria-describedby="sbi-moderation-heading">
2064
  <tbody>
2065
- <tr valign="top" class="sbi_pro">
2066
- <th scope="row"><label><?php esc_html_e('Moderation Type', 'instagram-feed'); ?></label></th>
2067
  <td>
2068
- <input class="sb_instagram_moderation_mode" checked="checked" disabled type="radio" value="visual" style="margin-top: 0;" /><label><?php esc_html_e('Visual', 'instagram-feed'); ?></label>
2069
- <input class="sb_instagram_moderation_mode" disabled type="radio" value="manual" style="margin-top: 0; margin-left: 10px;"/><label><?php esc_html_e('Manual', 'instagram-feed'); ?></label>
2070
 
2071
- <p class="sbi_tooltip" style="display: block;"><?php _e("<strong>Visual Moderation Mode</strong><br />This adds a button to each feed that will allow you to hide posts, block users, and create white lists from the front end using a visual interface. Visit <a href='https://smashballoon.com/guide-to-moderation-mode/?utm_campaign=instagram-free&utm_source=settings&utm_medium=moderationmode' target='_blank'>this page</a> for details", 'instagram-feed'); ?></p>
2072
 
2073
  </td>
2074
  </tr>
2075
 
2076
- <tr valign="top" class="sbi_pro">
2077
- <th scope="row"><label><?php esc_html_e('Only show posts by these users', 'instagram-feed'); ?></label></th>
2078
  <td>
2079
  <input type="text" style="width: 70%;" disabled /><br />
2080
- <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e('Separate usernames using commas', 'instagram-feed'); ?></span>
2081
 
2082
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e("What is this?", 'instagram-feed'); ?></a>
2083
- <p class="sbi_tooltip"><?php esc_html_e("You can use this setting to show photos only from certain users in your feed. Just enter the usernames here which you want to show. Separate multiple usernames using commas.", 'instagram-feed'); ?></p>
2084
  </td>
2085
  </tr>
2086
- <tr valign="top" class="sbi_pro">
2087
- <th scope="row"><label><?php esc_html_e('White lists', 'instagram-feed'); ?></label></th>
2088
  <td>
2089
  <div class="sbi_white_list_names_wrapper">
2090
- <?php esc_html_e("No white lists currently created", 'instagram-feed'); ?>
2091
  </div>
2092
 
2093
  <input disabled class="button-secondary" type="submit" value="<?php esc_attr_e( 'Clear White Lists', 'instagram-feed' ); ?>" />
2094
- &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);" style="display: inline-block; margin-top: 5px;"><?php esc_html_e("What is this?", 'instagram-feed'); ?></a>
2095
- <p class="sbi_tooltip"><?php esc_html_e("This will remove all of the white lists from the database", 'instagram-feed'); ?></p>
2096
  </td>
2097
  </tr>
2098
 
@@ -2100,146 +2485,150 @@ function sb_instagram_settings_page() {
2100
  </table>
2101
  </div>
2102
 
2103
- <hr id="gdpr" />
2104
- <h3 id="sbi-gdpr-heading"><?php esc_html_e('GDPR', 'instagram-feed'); ?></h3>
2105
 
2106
- <table class="form-table" aria-describedby="sbi-gdpr-heading">
2107
- <tbody>
2108
- <tr>
2109
- <th class="bump-left"><label class="bump-left"><?php esc_html_e("Enable GDPR settings", 'instagram-feed'); ?></label><code class="sbi_shortcode"> gdpr
2110
- Eg: gdpr=yes</code></th>
2111
- <td>
2112
 
2113
  <?php
2114
  $select_options = array(
2115
  array(
2116
  'label' => __( 'Automatic', 'instagram-feed' ),
2117
- 'value' => 'auto'
2118
  ),
2119
  array(
2120
  'label' => __( 'Yes', 'instagram-feed' ),
2121
- 'value' => 'yes'
2122
  ),
2123
  array(
2124
  'label' => __( 'No', 'instagram-feed' ),
2125
- 'value' => 'no'
2126
- )
2127
  )
2128
  ?>
2129
  <?php
2130
  $gdpr_list = "<ul class='sbi-list'>
2131
- <li>" . __('Only local images (not from Instagram\'s CDN) will be displayed in the feed.', 'instagram-feed') . "</li>
2132
- <li>" . __('Placeholder blank images will be displayed until images are available.', 'instagram-feed') . "</li>
2133
- </ul>";
2134
  ?>
2135
- <div>
2136
- <select name="gdpr" id="sbi_gdpr_setting">
2137
- <?php foreach ( $select_options as $select_option ) :
 
2138
  $selected = $select_option['value'] === $gdpr ? ' selected' : '';
2139
  ?>
2140
- <option value="<?php echo esc_attr( $select_option['value'] ); ?>"<?php echo $selected; ?> ><?php echo esc_html( $select_option['label'] ); ?></option>
2141
  <?php endforeach; ?>
2142
- </select>
2143
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2144
- <div class="sbi_tooltip gdpr_tooltip">
2145
 
2146
- <p><span><?php esc_html_e("Yes", "instagram-feed" ); ?>:</span> <?php esc_html_e("Enabling this setting prevents all images and videos from being loaded directly from Instagram's servers (CDN) to prevent any requests to external websites in your browser. To accommodate this, some features of the plugin will be disabled or limited.", "instagram-feed" ); ?> <a href="JavaScript:void(0);" class="sbi_show_gdpr_list"><?php esc_html_e( 'What will be limited?', 'instagram-feed' ); ?></a></p>
2147
 
2148
- <?php echo "<div class='sbi_gdpr_list'>" . $gdpr_list . '</div>'; ?>
2149
 
2150
 
2151
- <p><span><?php esc_html_e("No", "instagram-feed" ); ?>:</span> <?php esc_html_e("The plugin will still make some requests to load and display images and videos directly from Instagram.", "instagram-feed" ); ?></p>
2152
 
2153
 
2154
- <p><span><?php esc_html_e("Automatic", "instagram-feed" ); ?>:</span> <?php echo sprintf( __( 'The plugin will only load images and videos directly from Instagram if consent has been given by one of these integrated %s', 'instagram-feed' ), '<a href="https://smashballoon.com/doc/gdpr-plugin-list/?instagram" target="_blank" rel="noopener">' . __( 'GDPR cookie plugins', 'instagram-feed' ) . '</a>' ); ?></p>
2155
 
2156
- <p><?php echo sprintf( __( '%s to learn more about GDPR compliance in the Instagram Feed plugin.', 'instagram-feed' ), '<a href="https://smashballoon.com/doc/instagram-feed-gdpr-compliance/?instagram" target="_blank" rel="noopener">'. __( 'Click here', 'instagram-feed' ).'</a>' ); ?></p>
2157
- </div>
2158
- </div>
2159
 
2160
- <?php if ( ! SB_Instagram_GDPR_Integrations::gdpr_tests_successful( isset( $_GET['retest'] ) ) ) :
 
 
2161
  $errors = SB_Instagram_GDPR_Integrations::gdpr_tests_error_message();
2162
  ?>
2163
- <div class="sb_instagram_box sbi_gdpr_error">
2164
- <div class="sb_instagram_box_setting">
2165
- <p>
2166
- <strong><?php esc_html_e( 'Error:', 'instagram-feed' ); ?></strong> <?php esc_html_e("Due to a configuration issue on your web server, the GDPR setting is unable to be enabled.", "instagram-feed" ); ?></p>
2167
- <p>
2168
- <?php echo $errors; ?>
2169
- </p>
2170
- </div>
2171
- </div>
2172
- <?php else: ?>
2173
-
2174
- <div class="sbi_gdpr_auto">
2175
- <?php if ( SB_Instagram_GDPR_Integrations::gdpr_plugins_active() ) :
 
2176
  $active_plugin = SB_Instagram_GDPR_Integrations::gdpr_plugins_active();
2177
  ?>
2178
- <div class="sbi_gdpr_plugin_active">
2179
- <div class="sbi_active">
2180
- <p>
2181
- <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check-circle fa-w-16 fa-2x"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z" class=""></path></svg>
2182
- <strong><?php echo sprintf( __( '%s detected', 'instagram-feed' ), $active_plugin ); ?></strong>
2183
- <br />
2184
  <?php esc_html_e( 'Some Instagram Feed features will be limited for visitors to ensure GDPR compliance until they give consent.', 'instagram-feed' ); ?>
2185
- <a href="JavaScript:void(0);" class="sbi_show_gdpr_list"><?php esc_html_e( 'What will be limited?', 'instagram-feed' ); ?></a>
2186
- </p>
2187
- <?php echo "<div class='sbi_gdpr_list'>" . $gdpr_list . '</div>'; ?>
2188
- </div>
2189
-
2190
- </div>
2191
- <?php else: ?>
2192
- <div class="sb_instagram_box">
2193
- <div class="sb_instagram_box_setting">
2194
- <p><?php echo sprintf( __( 'No GDPR consent plugin detected. Install a compatible %sGDPR consent plugin%s, or manually enable the setting above to display a GDPR compliant version of the feed to all visitors.', 'instagram-feed' ), '<a href="https://smashballoon.com/doc/gdpr-plugin-list/?instagram" target="_blank" rel="noopener">', '</a>' ); ?></p>
2195
- </div>
2196
- </div>
2197
  <?php endif; ?>
2198
- </div>
2199
 
2200
- <div class="sb_instagram_box sbi_gdpr_yes">
2201
- <div class="sb_instagram_box_setting">
2202
- <p><?php esc_html_e( "No requests will be made to third-party websites. To accommodate this, some features of the plugin will be limited:", 'instagram-feed' ); ?></p>
2203
- <?php echo $gdpr_list; ?>
2204
- </div>
2205
- </div>
2206
 
2207
- <div class="sb_instagram_box sbi_gdpr_no">
2208
- <div class="sb_instagram_box_setting">
2209
- <p><?php esc_html_e( "The plugin will function as normal and load images directly from Instagram.", 'instagram-feed' ); ?></p>
2210
- </div>
2211
- </div>
2212
 
2213
  <?php endif; ?>
2214
- </td>
2215
- </tr>
2216
 
2217
- </tbody>
2218
- </table>
2219
 
2220
  <hr id="customcss" />
2221
- <h3 id="sbi-misc-heading"><?php esc_html_e('Misc', 'instagram-feed'); ?></h3>
2222
 
2223
  <table class="form-table" aria-describedby="sbi-misc-heading">
2224
  <tbody>
2225
- <tr valign="top">
2226
  <th scope="row" style="padding-bottom: 0;">
2227
- <?php _e('<strong style="font-size: 15px;">Custom CSS</strong><br />Enter your own custom CSS in the box below', 'instagram-feed'); ?>
2228
  </th>
2229
  </tr>
2230
- <tr valign="top">
2231
  <td>
2232
- <textarea name="sb_instagram_custom_css" id="sb_instagram_custom_css" style="width: 70%;" rows="7"><?php echo esc_textarea( wp_unslash($sb_instagram_custom_css) ); ?></textarea>
2233
  </td>
2234
  </tr>
2235
- <tr valign="top" id="customjs">
2236
  <td style="padding-bottom: 0;">
2237
- <?php _e('<strong style="font-size: 15px;">Custom JavaScript</strong><br />Enter your own custom JavaScript/jQuery in the box below', 'instagram-feed'); ?>
2238
  </td>
2239
  </tr>
2240
- <tr valign="top">
2241
  <td>
2242
- <textarea name="sb_instagram_custom_js" id="sb_instagram_custom_js" style="width: 70%;" rows="7"><?php echo esc_textarea( wp_unslash($sb_instagram_custom_js) ); ?></textarea>
2243
  </td>
2244
  </tr>
2245
  </tbody>
@@ -2247,406 +2636,486 @@ function sb_instagram_settings_page() {
2247
  <table class="form-table" aria-describedby="sbi-misc-heading">
2248
  <tbody>
2249
 
2250
- <tr valign="top">
2251
- <th scope="row"><label for="sb_instagram_ajax_theme" class="bump-left"><?php esc_html_e("Are you using an Ajax powered theme?", 'instagram-feed'); ?></label></th>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2252
  <td>
2253
- <input name="sb_instagram_ajax_theme" type="checkbox" id="sb_instagram_ajax_theme" <?php if($sb_instagram_ajax_theme == true) echo "checked"; ?> />
2254
- <label for="sb_instagram_ajax_theme"><?php esc_html_e('Yes', 'instagram-feed'); ?></label>
2255
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2256
- <p class="sbi_tooltip"><?php esc_html_e("When navigating your site, if your theme uses Ajax to load content into your pages (meaning your page doesn't refresh) then check this setting. If you're not sure then please check with the theme author.", 'instagram-feed'); ?></p>
 
 
 
 
2257
  </td>
2258
  </tr>
2259
 
2260
- <tr>
2261
- <th class="bump-left"><label class="bump-left"><?php esc_html_e("Image Resizing", 'instagram-feed'); ?></label></th>
2262
- <td>
2263
- <input name="sb_instagram_disable_resize" type="checkbox" id="sb_instagram_disable_resize" <?php if($sb_instagram_disable_resize == true) echo "checked"; ?> />
2264
- <label for="sb_instagram_disable_resize"><?php esc_html_e('Disable Local Image Storing and Resizing', 'instagram-feed'); ?></label><br><br>
2265
- <input name="sb_instagram_favor_local" type="checkbox" id="sb_instagram_favor_local" <?php if($sb_instagram_favor_local == true) echo "checked"; ?> />
2266
- <label for="sb_instagram_favor_local"><?php esc_html_e('Favor Local Images', 'instagram-feed'); ?></label><br><br>
2267
-
2268
- <input id="sbi_reset_resized" class="button-secondary" type="submit" value="<?php esc_attr_e( 'Reset Resized Images' ); ?>" style="vertical-align: middle;"/>
2269
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2270
- <p class="sbi_tooltip"><?php esc_html_e("The plugin creates and stores resized versions of images in order to serve a more optimized resolution size in the feed. Click this button to clear all data related to resized images. Enable the setting to favor local images to always use a local, resized image if one is available.", 'instagram-feed'); ?></p>
2271
- </td>
2272
- </tr>
2273
-
2274
- <tr valign="top">
2275
- <th scope="row"><label><?php esc_html_e('API request size', 'instagram-feed'); ?></label><code class="sbi_shortcode"> minnum
2276
- Eg: minnum=25</code></th>
2277
- <td>
2278
- <input name="sb_instagram_minnum" type="number" min="0" max="100" value="<?php echo esc_attr( $sb_instagram_minnum ); ?>" />
2279
- <span class="sbi_note"><?php esc_html_e('Leave at "0" for default', 'instagram-feed'); ?></span>
2280
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2281
- <p class="sbi_tooltip"><?php esc_html_e("If your feed contains a lot of IG TV posts or your feed is not displaying any posts despite there being posts available on Instagram.com, try increasing this number to 25 or more.", 'instagram-feed'); ?></p>
2282
- </td>
2283
- </tr>
2284
-
2285
- <tr valign="top">
2286
- <th scope="row"><label><?php esc_html_e('Enqueue JS file in head', 'instagram-feed'); ?></label></th>
2287
- <td>
2288
- <input type="checkbox" name="enqueue_js_in_head" id="sb_instagram_enqueue_js_in_head" <?php if($enqueue_js_in_head == true) echo 'checked="checked"' ?> />
2289
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2290
- <p class="sbi_tooltip"><?php esc_html_e("Check this box if you'd like to enqueue the JavaScript file for the plugin in the head instead of the footer.", 'instagram-feed'); ?></p>
2291
- </td>
2292
- </tr>
2293
-
2294
- <tr valign="top">
2295
- <th scope="row"><label><?php esc_html_e('Enqueue CSS file with shortcode', 'instagram-feed'); ?></label></th>
2296
- <td>
2297
- <input type="checkbox" name="enqueue_css_in_shortcode" id="sb_instagram_enqueue_css_in_shortcode" <?php if($enqueue_css_in_shortcode == true) echo 'checked="checked"' ?> />
2298
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2299
- <p class="sbi_tooltip"><?php esc_html_e("Check this box if you'd like to only include the CSS file for the plugin when the feed is on the page.", 'instagram-feed'); ?></p>
2300
- </td>
2301
- </tr>
2302
-
2303
- <tr valign="top">
2304
- <th scope="row"><label><?php esc_html_e('Disable JS Image Loading', 'instagram-feed'); ?></label></th>
2305
- <td>
2306
- <input type="checkbox" name="disable_js_image_loading" id="sb_instagram_disable_js_image_loading" <?php if($disable_js_image_loading == true) echo 'checked="checked"' ?> />
2307
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2308
- <p class="sbi_tooltip"><?php esc_html_e("Check this box to have images loaded server side instead of with JS.", 'instagram-feed'); ?></p>
2309
- </td>
2310
- </tr>
2311
-
2312
- <tr valign="top">
2313
- <th><label><?php esc_html_e("Enable Backup Caching", 'instagram-feed'); ?></label></th>
2314
  <td class="sbi-customize-tab-opt">
2315
- <input name="sb_instagram_backup" type="checkbox" id="sb_instagram_backup" <?php if($sb_instagram_backup == true) echo "checked"; ?> />
 
 
 
 
 
2316
  <input id="sbi_clear_backups" class="button-secondary" type="submit" style="position: relative; top: -4px;" value="<?php esc_attr_e( 'Clear Backup Cache', 'instagram-feed' ); ?>" />
2317
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2318
- <p class="sbi_tooltip"><?php esc_html_e('Every feed will save a duplicate version of itself in the database to be used if the normal cache is not available.', 'instagram-feed'); ?></p>
2319
  </td>
2320
  </tr>
2321
 
2322
- <tr>
2323
- <th class="bump-left">
2324
- <label class="bump-left"><?php esc_html_e("Load initial posts with AJAX", 'instagram-feed'); ?></label>
2325
- </th>
2326
- <td>
2327
- <input name="sb_ajax_initial" type="checkbox" id="sb_ajax_initial" <?php if($sb_ajax_initial == true) echo "checked"; ?> />
2328
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2329
- <p class="sbi_tooltip"><?php esc_html_e("Initial posts will be loaded using AJAX instead of added to the page directly. If you use page caching, this will allow the feed to update according to the \"Check for new posts every\" setting on the \"Configure\" tab.", 'instagram-feed'); ?></p>
2330
- </td>
2331
- </tr>
 
 
 
 
 
2332
 
2333
  <tr>
2334
- <th class="bump-left">
2335
- <label for="sb_instagram_cron" class="bump-left"><?php esc_html_e("Force cache to clear on interval", 'instagram-feed'); ?></label>
2336
  </th>
2337
  <td>
2338
  <select name="sb_instagram_cron">
2339
- <option value="unset" <?php if($sb_instagram_cron == "unset") echo 'selected="selected"' ?> > - </option>
2340
- <option value="yes" <?php if($sb_instagram_cron == "yes") echo 'selected="selected"' ?> ><?php esc_html_e('Yes', 'instagram-feed'); ?></option>
2341
- <option value="no" <?php if($sb_instagram_cron == "no") echo 'selected="selected"' ?> ><?php esc_html_e('No', 'instagram-feed'); ?></option>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2342
  </select>
2343
 
2344
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2345
- <p class="sbi_tooltip"><?php esc_html_e("If you're experiencing an issue with the plugin not auto-updating then you can set this to 'Yes' to run a scheduled event behind the scenes which forces the plugin cache to clear on a regular basis and retrieve new data from Instagram.", 'instagram-feed'); ?></p>
2346
  </td>
2347
  </tr>
2348
  </tbody>
2349
  </table>
2350
  <table class="form-table" aria-describedby="sbi-misc-heading">
2351
  <tbody>
2352
- <tr>
2353
- <th class="bump-left"><label class="bump-left"><?php esc_html_e("Enable Custom Templates", 'instagram-feed'); ?></label></th>
2354
- <td>
2355
- <input name="sb_instagram_custom_template" type="checkbox" id="sb_instagram_custom_template" <?php if($sb_instagram_custom_template == true) echo "checked"; ?> />
2356
- <label for="sb_instagram_custom_template"><?php esc_html_e('Yes', 'instagram-feed'); ?></label>
2357
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2358
- <p class="sbi_tooltip"><?php _e("The default HTML for the feed can be replaced with custom templates added to your theme's folder. Enable this setting to use these templates. See <a href=\"https://smashballoon.com/guide-to-creating-custom-templates/\" target=\"_blank\">this guide</a>", 'instagram-feed'); ?></p>
2359
- </td>
2360
- </tr>
2361
- <tr>
2362
- <th class="bump-left"><label class="bump-left"><?php esc_html_e("Disable Admin Error Notice", 'instagram-feed'); ?></label></th>
2363
- <td>
2364
- <input name="sb_instagram_disable_admin_notice" type="checkbox" id="sb_instagram_disable_admin_notice" <?php if($sb_instagram_disable_admin_notice == true) echo "checked"; ?> />
2365
- <label for="sb_instagram_disable_admin_notice"><?php esc_html_e('Yes', 'instagram-feed'); ?></label>
2366
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2367
- <p class="sbi_tooltip"><?php esc_html_e("This will permanently disable the feed error notice that displays in the bottom right corner for admins on the front end of your site.", 'instagram-feed'); ?></p>
2368
- </td>
2369
- </tr>
2370
- <tr>
2371
- <th class="bump-left"><label class="bump-left"><?php esc_html_e("Feed Issue Email Report", 'instagram-feed'); ?></label></th>
2372
- <td>
2373
- <input name="sb_instagram_enable_email_report" type="checkbox" id="sb_instagram_enable_email_report" <?php if($sb_instagram_enable_email_report == 'on') echo "checked"; ?> />
2374
- <label for="sb_instagram_enable_email_report"><?php esc_html_e('Yes', 'instagram-feed'); ?></label>
2375
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2376
- <p class="sbi_tooltip"><?php esc_html_e("Instagram Feed will send a weekly notification email using your site's wp_mail() function if one or more of your feeds is not updating or is not displaying. If you're not receiving the emails in your inbox, you may need to configure an SMTP service using another plugin like WP Mail SMTP.", 'instagram-feed'); ?></p>
2377
-
2378
- <div class="sb_instagram_box" style="display: block;">
2379
- <div class="sb_instagram_box_setting">
2380
- <label><?php esc_html_e('Schedule Weekly on', 'instagram-feed'); ?></label><br>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2381
  <?php
2382
  $schedule_options = array(
2383
  array(
2384
- 'val' => 'monday',
2385
- 'label' => __( 'Monday', 'instagram-feed' )
2386
  ),
2387
  array(
2388
- 'val' => 'tuesday',
2389
- 'label' => __( 'Tuesday', 'instagram-feed' )
2390
  ),
2391
  array(
2392
- 'val' => 'wednesday',
2393
- 'label' => __( 'Wednesday', 'instagram-feed' )
2394
  ),
2395
  array(
2396
- 'val' => 'thursday',
2397
- 'label' => __( 'Thursday', 'instagram-feed' )
2398
  ),
2399
  array(
2400
- 'val' => 'friday',
2401
- 'label' => __( 'Friday', 'instagram-feed' )
2402
  ),
2403
  array(
2404
- 'val' => 'saturday',
2405
- 'label' => __( 'Saturday', 'instagram-feed' )
2406
  ),
2407
  array(
2408
- 'val' => 'sunday',
2409
- 'label' => __( 'Sunday', 'instagram-feed' )
2410
  ),
2411
  );
2412
 
2413
- if ( isset( $_GET['flag'] ) ){
2414
  echo '<span id="sbi-goto"></span>';
2415
  }
2416
  ?>
2417
- <select name="sb_instagram_email_notification" id="sb_instagram_email_notification">
2418
  <?php foreach ( $schedule_options as $schedule_option ) : ?>
2419
- <option value="<?php echo esc_attr( $schedule_option['val'] ) ; ?>" <?php if ( $schedule_option['val'] === $sb_instagram_email_notification ) { echo 'selected';} ?>><?php echo esc_html( $schedule_option['label'] ) ; ?></option>
 
 
 
 
 
2420
  <?php endforeach; ?>
2421
- </select>
2422
- </div>
2423
- <div class="sb_instagram_box_setting">
2424
- <label><?php esc_html_e('Email Recipients', 'instagram-feed'); ?></label><br><input class="regular-text" type="text" name="sb_instagram_email_notification_addresses" value="<?php echo esc_attr( $sb_instagram_email_notification_addresses ); ?>"><span class="sbi_note"><?php esc_html_e('separate multiple emails with commas', 'instagram-feed'); ?></span>
2425
- <br><br><?php esc_html_e( 'Emails not working?', 'instagram-feed' ) ?> <a href="https://smashballoon.com/email-report-is-not-in-my-inbox/" target="_blank"><?php esc_html_e( 'See our related FAQ', 'instagram-feed' ) ?></a>
2426
- </div>
2427
- </div>
2428
-
2429
- </td>
2430
- </tr>
2431
  <?php
2432
  $usage_tracking = get_option( 'sbi_usage_tracking', false );
2433
  if ( $usage_tracking !== false ) :
2434
 
2435
- if ( isset( $_POST['sb_instagram_enable_email_report'] ) ) {
2436
- $usage_tracking['enabled'] = false;
2437
- if ( isset( $_POST['sbi_usage_tracking_enable'] ) ) {
2438
- $usage_tracking['enabled'] = true;
 
 
2439
  }
2440
- update_option( 'sbi_usage_tracking', $usage_tracking, false );
2441
- }
2442
- $sbi_usage_tracking_enable = isset( $usage_tracking['enabled'] ) ? $usage_tracking['enabled'] : true;
2443
 
2444
- // only show this setting after they have opted in or opted out using the admin notice
2445
- ?>
2446
- <tr>
2447
-
2448
- <th class="bump-left"><label class="bump-left"><?php esc_html_e("Enable Usage Tracking", 'instagram-feed'); ?></label></th>
2449
- <td>
2450
- <input name="sbi_usage_tracking_enable" type="checkbox" id="sbi_usage_tracking_enable" <?php if( $sbi_usage_tracking_enable ) echo "checked"; ?> />
2451
- <label for="sbi_usage_tracking_enable"><?php esc_html_e('Yes', 'instagram-feed'); ?></label>
2452
- <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e('What is usage tracking?', 'instagram-feed'); ?></a>
2453
- <p class="sbi_tooltip"><?php esc_html_e("Instagram Feed will record information and statistics about your site in order for the team at Smash Balloon to learn more about how our plugins are used. The plugin will never collect any sensitive information like access tokens, email addresses, or user information.", 'instagram-feed'); ?></p>
2454
- </td>
2455
- </tr>
2456
- <?php endif; ?>
2457
-
2458
- <tr valign="top">
2459
- <th><label><?php esc_html_e("Manage Data", 'instagram-feed'); ?></label></th>
2460
- <td class="sbi-customize-tab-opt">
2461
- <input id="sbi_clear_platform_data" class="button-secondary" type="submit" value="<?php esc_attr_e( 'Delete all Platform Data' ); ?>" />
2462
- <a class="sbi_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 5px;"><?php esc_html_e('What does this mean?', 'instagram-feed'); ?></a>
2463
- <p class="sbi_tooltip"><?php esc_html_e('Warning: Clicking this button will permanently delete all Instagram data, including all connected accounts, cached posts, and stored images.', 'instagram-feed'); ?></p>
2464
- </td>
2465
- </tr>
2466
-
2467
- </tbody>
 
 
 
 
 
2468
  </table>
2469
 
2470
  <?php submit_button(); ?>
2471
 
2472
  </form>
2473
 
2474
- <p><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>&nbsp; <?php _e('Next Step: <a href="?page=sb-instagram-feed&tab=display">Display your Feed</a>', 'instagram-feed'); ?></p>
2475
 
2476
- <p><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <?php _e('Need help setting up the plugin? Check out our <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=settings&utm_medium=display" target="_blank">setup directions</a>', 'instagram-feed'); ?></p>
2477
 
2478
 
2479
  <?php } //End Customize tab ?>
2480
 
2481
 
2482
 
2483
- <?php if( $sbi_active_tab == 'display' ) { //Start Display tab ?>
2484
 
2485
- <h3><?php esc_html_e('Display your Feed', 'instagram-feed'); ?></h3>
2486
- <p><?php esc_html_e("Copy and paste the following shortcode directly into the page, post or widget where you'd like the feed to show up:", 'instagram-feed'); ?></p>
2487
- <input type="text" value="[instagram-feed]" size="16" readonly="readonly" style="text-align: center;" onclick="this.focus();this.select()" title="<?php esc_html_e('To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac).', 'instagram-feed'); ?>" />
2488
 
2489
  <h3 style="padding-top: 10px;"><?php esc_html_e( 'Multiple Feeds', 'instagram-feed' ); ?></h3>
2490
- <p><?php esc_html_e("If you'd like to display multiple feeds then you can set different settings directly in the shortcode like so:", 'instagram-feed'); ?>
2491
  <code>[instagram-feed num=9 cols=3]</code></p>
2492
  <p><?php esc_html_e( 'You can display as many different feeds as you like, on either the same page or on different pages, by just using the shortcode options below. For example:', 'instagram-feed' ); ?><br />
2493
  <code>[instagram-feed]</code><br />
2494
  <code>[instagram-feed num=4 cols=4 showfollow=false]</code><br />
2495
  </p>
2496
- <p><?php esc_html_e("See the table below for a full list of available shortcode options:", 'instagram-feed'); ?></p>
2497
 
2498
- <p id="sbi-proonly-heading"><span class="sbi_table_key"></span><?php esc_html_e('Pro version only', 'instagram-feed'); ?></p>
2499
 
2500
  <table class="sbi_shortcode_table" aria-describedby="sbi-proonly-heading">
2501
  <tbody>
2502
- <tr valign="top">
2503
- <th scope="row"><?php esc_html_e('Shortcode option', 'instagram-feed'); ?></th>
2504
- <th scope="row"><?php esc_html_e('Description', 'instagram-feed'); ?></th>
2505
- <th scope="row"><?php esc_html_e('Example', 'instagram-feed'); ?></th>
2506
  </tr>
2507
 
2508
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Configure Options", 'instagram-feed'); ?></td></tr>
2509
  <tr class="sbi_pro">
2510
  <td>type</td>
2511
- <td><?php _e("Display photos from a User ID (user)<br />Display posts from a Hashtag (hashtag)", 'instagram-feed'); ?><br /><?php _e("Display photos that the account was tagged in (tagged)", 'instagram-feed'); ?></td>
2512
  <td><code>[instagram-feed type=user]</code><br /><code>[instagram-feed type=hashtag]</code><br /><code>[instagram-feed type=tagged]</code></td>
2513
  </tr>
2514
  <tr>
2515
  <td>user</td>
2516
- <td><?php esc_html_e('Your Instagram User Name. This must be from a connected account on the "Configure" tab.', 'instagram-feed'); ?></td>
2517
  <td><code>[instagram-feed user="smashballoon"]</code></td>
2518
  </tr>
2519
  <tr class="sbi_pro">
2520
  <td>hashtag</td>
2521
- <td><?php esc_html_e('Any hashtag. Separate multiple hashtags by commas.', 'instagram-feed'); ?></td>
2522
  <td><code>[instagram-feed hashtag="#awesome"]</code></td>
2523
  </tr>
2524
- <tr class="sbi_pro">
2525
- <td>tagged</td>
2526
- <td><?php esc_html_e('Your Instagram User Name. Separate multiple users by commas.', 'instagram-feed'); ?></td>
2527
- <td><code>[instagram-feed tagged="smashballoon"]</code></td>
2528
- </tr>
2529
 
2530
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Customize Options", 'instagram-feed'); ?></td></tr>
2531
  <tr>
2532
  <td>width</td>
2533
- <td><?php esc_html_e("The width of your feed. Any number.", 'instagram-feed'); ?></td>
2534
  <td><code>[instagram-feed width=50]</code></td>
2535
  </tr>
2536
  <tr>
2537
  <td>widthunit</td>
2538
- <td><?php esc_html_e("The unit of the width. 'px' or '%'", 'instagram-feed'); ?></td>
2539
  <td><code>[instagram-feed widthunit=%]</code></td>
2540
  </tr>
2541
  <tr>
2542
  <td>height</td>
2543
- <td><?php esc_html_e("The height of your feed. Any number.", 'instagram-feed'); ?></td>
2544
  <td><code>[instagram-feed height=250]</code></td>
2545
  </tr>
2546
  <tr>
2547
  <td>heightunit</td>
2548
- <td><?php esc_html_e("The unit of the height. 'px' or '%'", 'instagram-feed'); ?></td>
2549
  <td><code>[instagram-feed heightunit=px]</code></td>
2550
  </tr>
2551
  <tr>
2552
  <td>background</td>
2553
- <td><?php esc_html_e("The background color of the feed. Any hex color code.", 'instagram-feed'); ?></td>
2554
  <td><code>[instagram-feed background=#ffff00]</code></td>
2555
  </tr>
2556
  <tr>
2557
  <td>class</td>
2558
- <td><?php esc_html_e("Add a CSS class to the feed container", 'instagram-feed'); ?></td>
2559
  <td><code>[instagram-feed class=feedOne]</code></td>
2560
  </tr>
2561
 
2562
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Layout Options", 'instagram-feed'); ?></td></tr>
2563
  <tr class="sbi_pro">
2564
  <td>layout</td>
2565
- <td><?php esc_html_e("How posts are arranged visually in the feed. There are four layouts: Grid, Carousel Slider, Masonry Grid, or Highlight Grid. Options:", 'instagram-feed' ); ?> 'grid', 'carousel', 'masonry', or 'highlight'</td>
2566
  <td><code>[instagram-feed layout=grid]</code></td>
2567
  </tr>
2568
  <tr>
2569
  <td>num</td>
2570
- <td><?php esc_html_e("The number of photos to display initially. Maximum is 33.", 'instagram-feed'); ?></td>
2571
  <td><code>[instagram-feed num=10]</code></td>
2572
  </tr>
2573
  <tr class="sbi_pro">
2574
  <td>nummobile</td>
2575
- <td><?php esc_html_e("The number of photos to display initially for mobile screens (smaller than 480 pixels).", 'instagram-feed'); ?></td>
2576
  <td><code>[instagram-feed nummobile=6]</code></td>
2577
  </tr>
2578
  <tr>
2579
  <td>cols</td>
2580
- <td><?php esc_html_e("The number of columns in your feed. 1 - 10.", 'instagram-feed'); ?></td>
2581
  <td><code>[instagram-feed cols=5]</code></td>
2582
  </tr>
2583
  <tr class="sbi_pro">
2584
  <td>colsmobile</td>
2585
- <td><?php esc_html_e("The number of columns in your feed for mobile screens (smaller than 480 pixels).", 'instagram-feed'); ?></td>
2586
  <td><code>[instagram-feed colsmobile=2]</code></td>
2587
  </tr>
2588
  <tr>
2589
  <td>imagepadding</td>
2590
- <td><?php esc_html_e("The spacing around your photos", 'instagram-feed'); ?></td>
2591
  <td><code>[instagram-feed imagepadding=10]</code></td>
2592
  </tr>
2593
  <tr>
2594
  <td>imagepaddingunit</td>
2595
- <td><?php esc_html_e("The unit of the padding. 'px' or '%'", 'instagram-feed'); ?></td>
2596
  <td><code>[instagram-feed imagepaddingunit=px]</code></td>
2597
  </tr>
2598
 
2599
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Carousel Options", 'instagram-feed'); ?></td></tr>
2600
  <tr class="sbi_pro">
2601
  <td>carouselrows</td>
2602
- <td><?php esc_html_e("Choose 1 or 2 rows of posts in the carousel", 'instagram-feed'); ?></td>
2603
  <td><code>[instagram-feed carouselrows=1]</code></td>
2604
  </tr>
2605
  <tr class="sbi_pro">
2606
  <td>carouselloop</td>
2607
- <td><?php esc_html_e("Infinitely loop through posts or rewind", 'instagram-feed'); ?></td>
2608
  <td><code>[instagram-feed carouselloop=rewind]</code></td>
2609
  </tr>
2610
  <tr class="sbi_pro">
2611
  <td>carouselarrows</td>
2612
- <td><?php esc_html_e("Display directional arrows on the carousel", 'instagram-feed'); ?></td>
2613
  <td><code>[instagram-feed carouselarrows=true]</code></td>
2614
  </tr>
2615
  <tr class="sbi_pro">
2616
  <td>carouselpag</td>
2617
- <td><?php esc_html_e("Display pagination links below the carousel", 'instagram-feed'); ?></td>
2618
  <td><code>[instagram-feed carouselpag=true]</code></td>
2619
  </tr>
2620
  <tr class="sbi_pro">
2621
  <td>carouselautoplay</td>
2622
- <td><?php esc_html_e("Make the carousel autoplay", 'instagram-feed'); ?></td>
2623
  <td><code>[instagram-feed carouselautoplay=true]</code></td>
2624
  </tr>
2625
  <tr class="sbi_pro">
2626
  <td>carouseltime</td>
2627
- <td><?php esc_html_e("The interval time between slides for autoplay. Time in miliseconds.", 'instagram-feed'); ?></td>
2628
  <td><code>[instagram-feed carouseltime=8000]</code></td>
2629
  </tr>
2630
 
2631
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Highlight Options", 'instagram-feed'); ?></td></tr>
2632
  <tr class="sbi_pro">
2633
  <td>highlighttype</td>
2634
- <td><?php esc_html_e("Choose from 3 different ways of highlighting posts including by pattern, hashtag, post id or. Options:", 'instagram-feed'); ?> 'pattern', 'hashtag', 'id'.</td>
2635
  <td><code>[instagram-feed highlighttype=hashtag]</code></td>
2636
  </tr>
2637
  <tr class="sbi_pro">
2638
  <td>highlightpattern</td>
2639
- <td><?php esc_html_e("How often a post is highlighted.", 'instagram-feed'); ?></td>
2640
  <td><code>[instagram-feed highlightpattern=7]</code></td>
2641
  </tr>
2642
  <tr class="sbi_pro">
2643
  <td>highlightoffset</td>
2644
- <td><?php esc_html_e("When to start the highlight pattern.", 'instagram-feed'); ?></td>
2645
  <td><code>[instagram-feed highlightoffset=3]</code></td>
2646
  </tr>
2647
  <tr class="sbi_pro">
2648
  <td>highlighthashtag</td>
2649
- <td><?php esc_html_e("Highlight posts with these hashtags.", 'instagram-feed'); ?></td>
2650
  <td><code>[instagram-feed highlighthashtag=best]</code></td>
2651
  </tr>
2652
 
@@ -2654,242 +3123,242 @@ function sb_instagram_settings_page() {
2654
 
2655
 
2656
 
2657
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Photos Options", 'instagram-feed'); ?></td></tr>
2658
  <tr>
2659
  <td>sortby</td>
2660
- <td><?php esc_html_e("Sort the posts by Newest to Oldest (none) or Random (random)", 'instagram-feed'); ?></td>
2661
  <td><code>[instagram-feed sortby=random]</code></td>
2662
  </tr>
2663
  <tr>
2664
  <td>imageres</td>
2665
- <td><?php esc_html_e("The resolution/size of the photos including full, medium, thumbnail, and auto (based on size of image on page). Options:", 'instagram-feed'); ?> 'auto', full', 'medium' or 'thumb'.</td>
2666
  <td><code>[instagram-feed imageres=full]</code></td>
2667
  </tr>
2668
  <tr class="sbi_pro">
2669
  <td>media</td>
2670
- <td><?php esc_html_e("Display all media, only photos, or only videos", 'instagram-feed'); ?></td>
2671
  <td><code>[instagram-feed media=photos]</code></td>
2672
  </tr>
2673
  <tr class="sbi_pro">
2674
  <td>disablelightbox</td>
2675
- <td><?php esc_html_e("Whether to disable the photo Lightbox. It is enabled by default.", 'instagram-feed'); ?></td>
2676
  <td><code>[instagram-feed disablelightbox=true]</code></td>
2677
  </tr>
2678
  <tr>
2679
  <td>disablemobile</td>
2680
- <td><?php esc_html_e("Disable the mobile layout. Options:", 'instagram-feed'); ?> 'true' or 'false'.</td>
2681
  <td><code>[instagram-feed disablemobile=true]</code></td>
2682
  </tr>
2683
  <tr class="sbi_pro">
2684
  <td>captionlinks</td>
2685
- <td><?php esc_html_e("Whether to use urls in captions for the photo's link instead of linking to instagram.com.", 'instagram-feed'); ?></td>
2686
  <td><code>[instagram-feed captionlinks=true]</code></td>
2687
  </tr>
2688
 
2689
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Lightbox Comments Options", 'instagram-feed'); ?></td></tr>
2690
  <tr class="sbi_pro">
2691
  <td>lightboxcomments</td>
2692
- <td><?php esc_html_e("Whether to show comments in the lightbox for this feed.", 'instagram-feed'); ?></td>
2693
  <td><code>[instagram-feed lightboxcomments=true]</code></td>
2694
  </tr>
2695
  <tr class="sbi_pro">
2696
  <td>numcomments</td>
2697
- <td><?php esc_html_e("Number of comments to show starting from the most recent.", 'instagram-feed'); ?></td>
2698
  <td><code>[instagram-feed numcomments=10]</code></td>
2699
  </tr>
2700
 
2701
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Photos Hover Style Options", 'instagram-feed'); ?></td></tr>
2702
  <tr class="sbi_pro">
2703
  <td>hovercolor</td>
2704
- <td><?php esc_html_e("The background color when hovering over a photo. Any hex color code.", 'instagram-feed'); ?></td>
2705
  <td><code>[instagram-feed hovercolor=#ff0000]</code></td>
2706
  </tr>
2707
  <tr class="sbi_pro">
2708
  <td>hovertextcolor</td>
2709
- <td><?php esc_html_e("The text/icon color when hovering over a photo. Any hex color code.", 'instagram-feed'); ?></td>
2710
  <td><code>[instagram-feed hovertextcolor=#fff]</code></td>
2711
  </tr>
2712
  <tr class="sbi_pro">
2713
  <td>hoverdisplay</td>
2714
- <td><?php esc_html_e("The info to display when hovering over the photo such as the user name, post date, Instagram icon, location, caption, and like counts. Options:", 'instagram-feed'); ?><br />username, date, instagram, location, caption, likes</td>
2715
  <td><code>[instagram-feed hoverdisplay="date, location, likes"]</code></td>
2716
  </tr>
2717
 
2718
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Header Options", 'instagram-feed'); ?></td></tr>
2719
  <tr>
2720
  <td>showheader</td>
2721
- <td><?php esc_html_e("Whether to show the feed Header. Options:", 'instagram-feed'); ?> 'true' or 'false'.</td>
2722
  <td><code>[instagram-feed showheader=false]</code></td>
2723
  </tr>
2724
  <tr>
2725
  <td>showbio</td>
2726
- <td><?php esc_html_e("Display the bio in the header. Options:", 'instagram-feed'); ?> 'true' or 'false'</td>
2727
  <td><code>[instagram-feed showbio=true]</code></td>
2728
  </tr>
2729
- <tr>
2730
- <td>custombio</td>
2731
- <td><?php esc_html_e("Display a custom bio in the header", 'instagram-feed'); ?></td>
2732
- <td><code>[instagram-feed custombio="My custom bio."]</code></td>
2733
- </tr>
2734
- <tr>
2735
- <td>customavatar</td>
2736
- <td><?php esc_html_e("Display a custom avatar in the header. Enter the full URL of an image file.", 'instagram-feed'); ?></td>
2737
- <td><code>[instagram-feed customavatar="https://example.com/avatar.jpg"]</code></td>
2738
- </tr>
2739
  <tr>
2740
  <td>headersize</td>
2741
- <td><?php esc_html_e("Size of the header including small, medium and large. Options:", 'instagram-feed'); ?> small, medium, or large.</td>
2742
  <td><code>[instagram-feed headersize=medium]</code></td>
2743
  </tr>
2744
  <tr>
2745
  <td>headercolor</td>
2746
- <td><?php esc_html_e("The color of the Header text. Any hex color code.", 'instagram-feed'); ?></td>
2747
  <td><code>[instagram-feed headercolor=#333]</code></td>
2748
  </tr>
2749
 
2750
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("'Load More' Button Options", 'instagram-feed'); ?></td></tr>
2751
  <tr>
2752
  <td>showbutton</td>
2753
- <td><?php esc_html_e("Whether to show the 'Load More' button. Options:", 'instagram-feed'); ?> 'true' or 'false'.</td>
2754
  <td><code>[instagram-feed showbutton=false]</code></td>
2755
  </tr>
2756
  <tr>
2757
  <td>buttoncolor</td>
2758
- <td><?php esc_html_e("The background color of the button. Any hex color code.", 'instagram-feed'); ?></td>
2759
  <td><code>[instagram-feed buttoncolor=#000]</code></td>
2760
  </tr>
2761
  <tr>
2762
  <td>buttontextcolor</td>
2763
- <td><?php esc_html_e("The text color of the button. Any hex color code.", 'instagram-feed'); ?></td>
2764
  <td><code>[instagram-feed buttontextcolor=#fff]</code></td>
2765
  </tr>
2766
  <tr>
2767
  <td>buttontext</td>
2768
- <td><?php esc_html_e("The text used for the button.", 'instagram-feed'); ?></td>
2769
  <td><code>[instagram-feed buttontext="Load More Photos"]</code></td>
2770
  </tr>
2771
 
2772
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("'Follow on Instagram' Button Options", 'instagram-feed'); ?></td></tr>
2773
  <tr>
2774
  <td>showfollow</td>
2775
- <td><?php esc_html_e("Whether to show the 'Follow on Instagram' button. Options:", 'instagram-feed'); ?> 'true' or 'false'.</td>
2776
  <td><code>[instagram-feed showfollow=false]</code></td>
2777
  </tr>
2778
  <tr>
2779
  <td>followcolor</td>
2780
- <td><?php esc_html_e("The background color of the button. Any hex color code.", 'instagram-feed'); ?></td>
2781
  <td><code>[instagram-feed followcolor=#ff0000]</code></td>
2782
  </tr>
2783
  <tr>
2784
  <td>followtextcolor</td>
2785
- <td><?php esc_html_e("The text color of the button. Any hex color code.", 'instagram-feed'); ?></td>
2786
  <td><code>[instagram-feed followtextcolor=#fff]</code></td>
2787
  </tr>
2788
  <tr>
2789
  <td>followtext</td>
2790
- <td><?php esc_html_e("The text used for the button.", 'instagram-feed'); ?></td>
2791
  <td><code>[instagram-feed followtext="Follow me"]</code></td>
2792
  </tr>
2793
 
2794
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Caption Options", 'instagram-feed'); ?></td></tr>
2795
  <tr class="sbi_pro">
2796
  <td>showcaption</td>
2797
- <td><?php esc_html_e("Whether to show the photo caption. Options:", 'instagram-feed'); ?> 'true' or 'false'.</td>
2798
  <td><code>[instagram-feed showcaption=false]</code></td>
2799
  </tr>
2800
  <tr class="sbi_pro">
2801
  <td>captionlength</td>
2802
- <td><?php esc_html_e("The number of characters of the caption to display", 'instagram-feed'); ?></td>
2803
  <td><code>[instagram-feed captionlength=50]</code></td>
2804
  </tr>
2805
  <tr class="sbi_pro">
2806
  <td>captioncolor</td>
2807
- <td><?php esc_html_e("The text color of the caption. Any hex color code.", 'instagram-feed'); ?></td>
2808
  <td><code>[instagram-feed captioncolor=#000]</code></td>
2809
  </tr>
2810
  <tr class="sbi_pro">
2811
  <td>captionsize</td>
2812
- <td><?php esc_html_e("The size of the caption text. Any number.", 'instagram-feed'); ?></td>
2813
  <td><code>[instagram-feed captionsize=24]</code></td>
2814
  </tr>
2815
 
2816
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Likes &amp; Comments Options", 'instagram-feed'); ?></td></tr>
2817
  <tr class="sbi_pro">
2818
  <td>showlikes</td>
2819
- <td><?php esc_html_e("Whether to show the Likes &amp; Comments. Options:", 'instagram-feed'); ?> 'true' or 'false'.</td>
2820
  <td><code>[instagram-feed showlikes=false]</code></td>
2821
  </tr>
2822
  <tr class="sbi_pro">
2823
  <td>likescolor</td>
2824
- <td><?php esc_html_e("The color of the Likes &amp; Comments. Any hex color code.", 'instagram-feed'); ?></td>
2825
  <td><code>[instagram-feed likescolor=#FF0000]</code></td>
2826
  </tr>
2827
  <tr class="sbi_pro">
2828
  <td>likessize</td>
2829
- <td><?php esc_html_e("The size of the Likes &amp; Comments. Any number.", 'instagram-feed'); ?></td>
2830
  <td><code>[instagram-feed likessize=14]</code></td>
2831
  </tr>
2832
 
2833
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Post Filtering Options", 'instagram-feed'); ?></td></tr>
2834
  <tr class="sbi_pro">
2835
  <td>excludewords</td>
2836
- <td><?php esc_html_e("Remove posts which contain certain words or hashtags in the caption.", 'instagram-feed'); ?></td>
2837
  <td><code>[instagram-feed excludewords="bad, words"]</code></td>
2838
  </tr>
2839
  <tr class="sbi_pro">
2840
  <td>includewords</td>
2841
- <td><?php esc_html_e("Only display posts which contain certain words or hashtags in the caption.", 'instagram-feed'); ?></td>
2842
  <td><code>[instagram-feed includewords="sunshine"]</code></td>
2843
  </tr>
2844
 
2845
- <tr class="sbi_table_header"><td colspan=3><?php esc_html_e("Auto Load More on Scroll", 'instagram-feed'); ?></td></tr>
2846
  <tr class="sbi_pro">
2847
  <td>autoscroll</td>
2848
- <td><?php esc_html_e("Load more posts automatically as the user scrolls down the page.", 'instagram-feed'); ?></td>
2849
  <td><code>[instagram-feed autoscroll=true]</code></td>
2850
  </tr>
2851
  <tr class="sbi_pro">
2852
  <td>autoscrolldistance</td>
2853
- <td><?php esc_html_e("Distance before the end of feed or page that triggers the loading of more posts.", 'instagram-feed'); ?></td>
2854
  <td><code>[instagram-feed autoscrolldistance=200]</code></td>
2855
  </tr>
2856
 
2857
  </tbody>
2858
  </table>
2859
 
2860
- <p><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <?php _e('Need help setting up the plugin? Check out our <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=display&utm_medium=supportsetup" target="_blank">setup directions</a>', 'instagram-feed'); ?></p>
2861
 
2862
  <?php } //End Display tab ?>
2863
 
2864
 
2865
- <?php if( $sbi_active_tab == 'support' ) { //Start Support tab ?>
2866
 
2867
  <div class="sbi_support">
2868
 
2869
- <h3 style="padding-bottom: 10px;"><?php esc_html_e("Need help?", 'instagram-feed'); ?></h3>
2870
 
2871
  <p>
2872
- <span class="sbi-support-title"><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <a
2873
- href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=settings&utm_medium=general"
2874
- target="_blank"><?php esc_html_e( 'Setup Directions', 'instagram-feed' ); ?></a></span>
2875
  <?php esc_html_e( 'A step-by-step guide on how to setup and use the plugin.', 'instagram-feed' ); ?>
2876
  </p>
2877
 
2878
  <p>
2879
- <span class="sbi-support-title"><i class="fa fa-youtube-play" aria-hidden="true"></i>&nbsp; <a
2880
- href="https://www.youtube.com/embed/q6ZXVU4g970" target="_blank" rel="noopener noreferrer"
2881
- id="sbi-play-support-video"><?php esc_html_e( 'Watch a Video', 'instagram-feed' ); ?></a></span>
2882
- <?php _e( "Watch a short video demonstrating how to set up, customize and use the plugin.<br /><strong>Please note</strong> that the video shows the set up and use of the <strong><a href='https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=general' target='_blank'>Pro version</a></strong> of the plugin, but the process is the same for this free version. The only difference is some of the features available.", 'instagram-feed' ); ?>
2883
 
2884
  <iframe id="sbi-support-video"
2885
- src="//www.youtube.com/embed/q6ZXVU4g970?theme=light&amp;showinfo=0&amp;controls=2" width="960"
2886
- height="540" frameborder="0" allowfullscreen="allowfullscreen" title="<?php esc_attr_e( 'Watch a Video', 'instagram-feed' ); ?>"></iframe>
2887
  </p>
2888
 
2889
  <p>
2890
- <span class="sbi-support-title"><i class="fa fa-question-circle" aria-hidden="true"></i>&nbsp; <a
2891
- href="https://smashballoon.com/instagram-feed/support/faq/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqs"
2892
- target="_blank"><?php esc_html_e( 'FAQs and Docs', 'instagram-feed' ); ?></a></span>
2893
  <?php esc_html_e( 'View our expansive library of FAQs and documentation to help solve your problem as quickly as possible.', 'instagram-feed' ); ?>
2894
  </p>
2895
 
@@ -2897,54 +3366,55 @@ function sb_instagram_settings_page() {
2897
 
2898
  <ul>
2899
  <li><strong><?php esc_html_e( 'FAQs', 'instagram-feed' ); ?></strong></li>
2900
- <li>&bull;&nbsp; <?php _e( '<a href="https://smashballoon.com/my-photos-wont-load/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqsnophotos" target="_blank">My Instagram Feed Won\'t Load</a>', 'instagram-feed' ); ?></li>
2901
- <li>&bull;&nbsp; <?php _e( '<a href="https://smashballoon.com/my-instagram-access-token-keep-expiring/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqsexpiring" target="_blank">My Access Token Keeps Expiring</a>', 'instagram-feed' ); ?></li>
2902
  <li style="margin-top: 8px; font-size: 12px;"><a href="https://smashballoon.com/instagram-feed/support/faq/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqs" target="_blank"><?php esc_html_e( 'See All', 'instagram-feed' ); ?><i class="fa fa-chevron-right" aria-hidden="true"></i></a></li>
2903
  </ul>
2904
 
2905
  <ul>
2906
- <li><strong><?php esc_html_e("Documentation", 'instagram-feed'); ?></strong></li>
2907
- <li>&bull;&nbsp; <?php _e( '<a href="https://smashballoon.com/instagram-feed/free?utm_campaign=instagram-free&utm_source=support&utm_medium=installation" target="_blank">Installation and Configuration</a>', 'instagram-feed' ); ?></li>
2908
- <li>&bull;&nbsp; <?php _e( '<a href="https://smashballoon.com/display-multiple-instagram-feeds/?utm_campaign=instagram-free&utm_source=support&utm_medium=multiple" target="_blank">Displaying multiple feeds</a>', 'instagram-feed' ); ?></li>
2909
- <li>&bull;&nbsp; <?php _e( '<a href="https://smashballoon.com/instagram-feed-faq/customization/?utm_campaign=instagram-free&utm_source=support&utm_medium=customizing" target="_blank">Customizing your Feed</a>', 'instagram-feed' ); ?></li>
2910
  </ul>
2911
  </div>
2912
 
2913
  <p>
2914
- <span class="sbi-support-title"><i class="fa fa-envelope" aria-hidden="true"></i>&nbsp; <a
2915
- href="https://smashballoon.com/instagram-feed/support/?utm_campaign=instagram-free&utm_source=support&utm_medium=contact"
2916
- target="_blank"><?php esc_html_e( 'Request Support', 'instagram-feed' ); ?></a></span>
2917
- <?php _e( 'Still need help? Submit a ticket and one of our support experts will get back to you as soon as possible.<br /><strong>Important:</strong> Please include your <strong>System Info</strong> below with all support requests.', 'instagram-feed' ); ?>
2918
  </p>
2919
  </div>
2920
 
2921
  <hr />
2922
 
2923
- <h3><?php _e('System Info &nbsp; <i style="color: #666; font-size: 11px; font-weight: normal;">Click the text below to select all</i>', 'instagram-feed'); ?></h3>
2924
 
2925
 
2926
 
2927
 
2928
- <?php $sbi_options = get_option('sb_instagram_settings'); ?>
2929
  <textarea readonly="readonly" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac)." style="width: 100%; max-width: 960px; height: 500px; white-space: pre; font-family: Menlo,Monaco,monospace;">
2930
  ## SITE/SERVER INFO: ##
2931
- Site URL: <?php echo site_url() . "\n"; ?>
2932
- Home URL: <?php echo home_url() . "\n"; ?>
2933
- WordPress Version: <?php echo get_bloginfo( 'version' ) . "\n"; ?>
2934
- PHP Version: <?php echo PHP_VERSION . "\n"; ?>
2935
- Web Server Info: <?php echo $_SERVER['SERVER_SOFTWARE'] . "\n"; ?>
2936
 
2937
  ## ACTIVE PLUGINS: ##
2938
  <?php
2939
- $plugins = get_plugins();
2940
  $active_plugins = get_option( 'active_plugins', array() );
2941
 
2942
  foreach ( $plugins as $plugin_path => $plugin ) {
2943
  // If the plugin isn't active, don't show it.
2944
- if ( ! in_array( $plugin_path, $active_plugins ) )
2945
  continue;
 
2946
 
2947
- echo $plugin['Name'] . ': ' . $plugin['Version'] ."\n";
2948
  }
2949
  ?>
2950
 
@@ -2952,55 +3422,56 @@ foreach ( $plugins as $plugin_path => $plugin ) {
2952
  sb_instagram_plugin_type => Instagram Feed Free
2953
  <?php
2954
  global $wpdb;
2955
- foreach( $sbi_options as $key => $val ) {
2956
  if ( $key !== 'connected_accounts' ) {
2957
  if ( is_array( $val ) ) {
2958
  foreach ( $val as $item ) {
2959
  if ( is_array( $item ) ) {
2960
  foreach ( $item as $key2 => $val2 ) {
2961
- echo "$key2 => $val2\n";
2962
  }
2963
  } else {
2964
- echo "$key => $item\n";
2965
  }
2966
  }
2967
  } else {
2968
- echo "$key => $val\n";
2969
  }
2970
  }
2971
-
2972
  }
2973
  ?>
2974
 
2975
- ## CONNECTED ACCOUNTS: ##<?php echo "\n";
2976
- $con_accounts = isset( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
 
 
2977
  $business_accounts = array();
2978
- $basic_accounts = array();
2979
- $manager = new SB_Instagram_Data_Manager();
2980
  if ( ! empty( $con_accounts ) ) {
2981
- foreach ( $con_accounts as $account ) {
2982
- $type = isset( $account['type'] ) ? $account['type'] : 'personal';
2983
- $original_access_token = ! empty( $account['access_token'] ) ? $account['access_token'] : '';
2984
- $account['access_token'] = ! empty( $original_access_token ) ? $manager->remote_encrypt( $original_access_token ) : '';
2985
- if ( isset( $account['page_access_token'] ) ) {
2986
- unset( $account['page_access_token'] );
2987
- }
2988
- echo '*' . $account['user_id'] . '*' . "\n";
2989
- var_export( $account );
2990
- echo "\n";
2991
- $account['access_token'] = $original_access_token;
2992
- if ( $type === 'business' ) {
2993
- $business_accounts[] = $account;
2994
- } elseif ( $type === 'basic' ) {
2995
- $basic_accounts[] = $account;
2996
- }
2997
- }
2998
  }
2999
  ?>
3000
 
3001
  ## API RESPONSE: ##
3002
  <?php
3003
- $first_con_basic_account = isset( $basic_accounts[0] ) ? $basic_accounts[0] : array();
3004
  $first_con_business_account = isset( $business_accounts[0] ) ? $business_accounts[0] : array();
3005
 
3006
  if ( ! empty( $first_con_basic_account ) ) {
@@ -3010,12 +3481,12 @@ if ( ! empty( $first_con_basic_account ) ) {
3010
  $connection->connect();
3011
  if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
3012
  foreach ( $connection->get_data() as $key => $item ) {
3013
- if ( is_array ( $item ) ) {
3014
  foreach ( $item as $key2 => $item2 ) {
3015
- echo $key2 . ' => ' . esc_html( $item2 ) . "\n";
3016
  }
3017
  } else {
3018
- echo $key . ' => ' . esc_html( $item ) . "\n";
3019
  }
3020
  }
3021
  } else {
@@ -3023,7 +3494,7 @@ if ( ! empty( $first_con_basic_account ) ) {
3023
  $response = $connection->get_wp_error();
3024
  if ( isset( $response ) && isset( $response->errors ) ) {
3025
  foreach ( $response->errors as $key => $item ) {
3026
- echo $key . ' => ' . $item[0] . "\n";
3027
  }
3028
  }
3029
  } else {
@@ -3043,12 +3514,12 @@ if ( ! empty( $first_con_business_account ) ) {
3043
  $connection->connect();
3044
  if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
3045
  foreach ( $connection->get_data() as $key => $item ) {
3046
- if ( is_array ( $item ) ) {
3047
  foreach ( $item as $key2 => $item2 ) {
3048
- echo $key2 . ' => ' . esc_html( $item2 ) . "\n";
3049
  }
3050
  } else {
3051
- echo $key . ' => ' . esc_html( $item ) . "\n";
3052
  }
3053
  }
3054
  } else {
@@ -3056,7 +3527,7 @@ if ( ! empty( $first_con_business_account ) ) {
3056
  $response = $connection->get_wp_error();
3057
  if ( isset( $response ) && isset( $response->errors ) ) {
3058
  foreach ( $response->errors as $key => $item ) {
3059
- echo $key . ' => ' . $item[0] . "\n";
3060
  }
3061
  }
3062
  } else {
@@ -3066,7 +3537,8 @@ if ( ! empty( $first_con_business_account ) ) {
3066
  }
3067
  } else {
3068
  echo 'no connected business accounts';
3069
- } ?>
 
3070
 
3071
  ## Cron Events: ##
3072
  <?php
@@ -3076,20 +3548,21 @@ foreach ( $cron as $key => $data ) {
3076
  foreach ( $data as $key2 => $val ) {
3077
  if ( strpos( $key2, 'sbi' ) !== false || strpos( $key2, 'sb_instagram' ) !== false ) {
3078
  $is_target = true;
3079
- echo $key2;
3080
  echo "\n";
3081
  }
3082
  }
3083
- if ( $is_target) {
3084
- echo date( "Y-m-d H:i:s", $key );
3085
  echo "\n";
3086
- echo 'Next Scheduled: ' . ((int)$key - time())/60 . ' minutes';
3087
  echo "\n\n";
3088
  }
3089
  }
3090
  ?>
3091
  ## Cron Cache Report: ##
3092
- <?php $cron_report = get_option( 'sbi_cron_report', array() );
 
3093
  if ( ! empty( $cron_report ) ) {
3094
  var_export( $cron_report );
3095
  }
@@ -3097,7 +3570,8 @@ echo "\n";
3097
  ?>
3098
 
3099
  ## Access Token Refresh: ##
3100
- <?php $cron_report = get_option( 'sbi_refresh_report', array() );
 
3101
  if ( ! empty( $cron_report ) ) {
3102
  var_export( $cron_report );
3103
  }
@@ -3105,7 +3579,8 @@ echo "\n";
3105
  ?>
3106
 
3107
  ## Resizing: ##
3108
- <?php $upload = wp_upload_dir();
 
3109
  $upload_dir = $upload['basedir'];
3110
  $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
3111
  if ( file_exists( $upload_dir ) ) {
@@ -3120,10 +3595,10 @@ if ( file_exists( $upload_dir ) ) {
3120
  echo "\n";
3121
  echo "\n";
3122
 
3123
- $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE );
3124
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
3125
 
3126
- if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) != $feeds_posts_table_name ) {
3127
  echo 'no feeds posts table';
3128
  echo "\n";
3129
 
@@ -3136,10 +3611,10 @@ if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) != $feeds_po
3136
  foreach ( $last_result as $column ) {
3137
 
3138
  foreach ( $column as $key => $value ) {
3139
- echo $key . ': ' . esc_html( $value ) . "\n";;
 
3140
  }
3141
  }
3142
-
3143
  } else {
3144
  echo 'feeds posts has no rows';
3145
  echo "\n";
@@ -3147,7 +3622,7 @@ if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) != $feeds_po
3147
  }
3148
  echo "\n";
3149
 
3150
- if ( $wpdb->get_var( "show tables like '$table_name'" ) != $table_name ) {
3151
  echo 'no posts table';
3152
  echo "\n";
3153
 
@@ -3162,10 +3637,10 @@ if ( $wpdb->get_var( "show tables like '$table_name'" ) != $table_name ) {
3162
  }
3163
 
3164
  foreach ( $column as $key => $value ) {
3165
- echo $key . ': ' . esc_html( $value ) . "\n";;
 
3166
  }
3167
  }
3168
-
3169
  } else {
3170
  echo 'feeds posts has no rows';
3171
  echo "\n";
@@ -3179,15 +3654,15 @@ global $sb_instagram_posts_manager;
3179
  $errors = $sb_instagram_posts_manager->get_errors();
3180
  if ( ! empty( $errors['resizing'] ) ) :
3181
  echo '* Resizing *' . "\n";
3182
- echo $errors['resizing'] . "\n";
3183
  endif;
3184
  if ( ! empty( $errors['database_create'] ) ) :
3185
  echo '* Database Create *' . "\n";
3186
- echo $errors['database_create'] . "\n";
3187
  endif;
3188
  if ( ! empty( $errors['upload_dir'] ) ) :
3189
  echo '* Uploads Directory *' . "\n";
3190
- echo $errors['upload_dir'] . "\n";
3191
  endif;
3192
  if ( ! empty( $errors['connection'] ) ) :
3193
  echo '* API/WP_HTTP Request *' . "\n";
@@ -3200,7 +3675,7 @@ endif;
3200
  $error_log = $sb_instagram_posts_manager->get_error_log();
3201
  if ( ! empty( $error_log ) ) :
3202
  foreach ( $error_log as $error ) :
3203
- echo $error . "\n";
3204
  endforeach;
3205
  endif;
3206
  ?>
@@ -3210,21 +3685,17 @@ endif;
3210
  $actions = $sb_instagram_posts_manager->get_action_log();
3211
  if ( ! empty( $actions ) ) :
3212
  foreach ( $actions as $action ) :
3213
- echo $action . "\n";
3214
  endforeach;
3215
  endif;
3216
- /*
3217
- $error_page = $sb_instagram_posts_manager->get_error_page();
3218
- if ( $error_page ) {
3219
- echo 'Feed with error: ' . esc_url( get_the_permalink( $error_page ) ). "\n";
3220
- }*/?>
3221
 
3222
  ## Location Summary: ##
3223
  <?php
3224
- $locator_summary = SB_Instagram_Feed_Locator::summary();
3225
  $condensed_shortcode_atts = array( 'type', 'user', 'hashtag', 'tagged', 'num', 'cols', 'layout', 'whitelist', 'includewords' );
3226
 
3227
- if ( ! empty( $locator_summary) ) {
3228
 
3229
  foreach ( $locator_summary as $locator_section ) {
3230
  if ( ! empty( $locator_section['results'] ) ) {
@@ -3235,337 +3706,345 @@ if ( ! empty( $locator_summary) ) {
3235
  $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array();
3236
  foreach ( $shortcode_atts as $key => $value ) {
3237
  if ( in_array( $key, $condensed_shortcode_atts, true ) ) {
3238
- $condensed_shortcode_string .= ' ' . esc_html( $key ). '="' . esc_html( $value ) . '"';
3239
  }
3240
  }
3241
  $condensed_shortcode_string .= ']';
3242
- echo esc_url( get_the_permalink( $result['post_id'] ) ) . ' ' . $condensed_shortcode_string . "\n";
3243
  }
3244
-
3245
  }
3246
  }
3247
- }?>
 
3248
 
3249
  ## GDPR: ##
3250
  <?php
3251
  if ( ! SB_Instagram_GDPR_Integrations::gdpr_tests_successful() ) :
3252
  $errors = SB_Instagram_GDPR_Integrations::gdpr_tests_error_message();
3253
- ?><?php echo $errors; ?>
 
3254
  <?php endif; ?>
3255
 
3256
  ## oEmbed: ##
3257
  <?php
3258
  $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
3259
- foreach( $oembed_token_settings as $key => $value ) {
3260
- echo $key . ': ' . esc_attr( $value ) . "\n";
3261
  }
3262
 
3263
- $single = new SB_Instagram_Single( 'https://www.instagram.com/p/CCq1D_cMYMF/' );
3264
- $post = $single->fetch();
3265
  $message = '';
3266
  if ( isset( $post['thumbnail_url'] ) ) {
3267
  $message = 'success';
3268
  } else {
3269
- $error = $single->get_error();
3270
 
3271
- if ( ! empty( $error ) ) {
3272
- $message = $error;
3273
- }
3274
  }
3275
- echo 'oEmbed request test: ' . esc_attr( $message );
3276
 
3277
  ?>
3278
  </textarea>
3279
- <div><input id="sbi_reset_log" class="button-secondary" type="submit" value="<?php esc_attr_e( 'Reset Error Log' ); ?>" style="vertical-align: middle;"/></div>
3280
 
3281
  <?php
3282
  } //End Support tab
3283
 
 
3284
 
3285
- if( $sbi_active_tab == 'more' ) { //Start More Social Feeds tab
3286
-
3287
- add_user_meta(get_current_user_id(), 'seen_more_plugins_page_1', 'true', true); //Iterate when adding a new plugin
3288
  ?>
3289
 
3290
  <div class="sbi_more_plugins" id="sbi-admin-about">
3291
 
3292
  <div class="sbi-more-plugins-intro">
3293
- <h3><?php _e( "Here's some more <span>free</span> plugins you might like!", 'instagram-feed' ); ?></h3>
3294
  <p><?php esc_html_e( "As you're already using one of our free plugins we thought we'd suggest some others you might like to. Check out our other free plugins below:", 'instagram-feed' ); ?></p>
3295
  </div>
3296
 
3297
- <?php function get_am_plugins() {
3298
-
3299
- $images_url = SBI_PLUGIN_URL . 'img/about/';
3300
-
3301
- return array(
3302
- 'instagram-feed/instagram-feed.php' => array(
 
 
 
 
 
 
 
3303
  'icon' => $images_url . 'plugin-if.png',
3304
- 'name' => esc_html__( 'Instagram Feed', 'custom-facebook-feed' ),
3305
  'desc' => esc_html__( 'Instagram Feed is a clean and beautiful way to add your Instagram posts to your website. Grab your visitors attention and keep them engaged with your site longer.', 'custom-facebook-feed' ),
3306
- 'url' => 'https://downloads.wordpress.org/plugin/instagram-feed.zip',
3307
- 'pro' => array(
3308
- 'plug' => 'instagram-feed-pro/instagram-feed.php',
3309
- 'icon' => $images_url . 'plugin-if.png',
3310
- 'name' => esc_html__( 'Instagram Feed Pro', 'custom-facebook-feed' ),
3311
- 'desc' => esc_html__( 'Instagram Feed is a clean and beautiful way to add your Instagram posts to your website. Grab your visitors attention and keep them engaged with your site longer.', 'custom-facebook-feed' ),
3312
- 'url' => 'https://smashballoon.com/instagram-feed/?utm_campaign=facebook-free&utm_source=cross&utm_medium=sbiinstaller',
3313
- 'act' => 'go-to-url',
3314
- ),
3315
  ),
3316
- 'custom-facebook-feed/custom-facebook-feed.php' => array(
 
 
 
 
 
 
 
3317
  'icon' => $images_url . 'plugin-fb.png',
3318
- 'name' => esc_html__( 'Custom Facebook Feed', 'instagram-feed' ),
3319
  'desc' => esc_html__( 'Custom Facebook Feed makes displaying your Facebook posts easy. Keep your site visitors informed and increase engagement with your Facebook page by displaying a feed on your website.', 'instagram-feed' ),
3320
- 'url' => 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip',
3321
- 'pro' => array(
3322
- 'plug' => 'custom-facebook-feed-pro/custom-facebook-feed.php',
3323
- 'icon' => $images_url . 'plugin-fb.png',
3324
- 'name' => esc_html__( 'Custom Facebook Feed Pro', 'instagram-feed' ),
3325
- 'desc' => esc_html__( 'Custom Facebook Feed makes displaying your Facebook posts easy. Keep your site visitors informed and increase engagement with your Facebook page by displaying a feed on your website.', 'instagram-feed' ),
3326
- 'url' => 'https://smashballoon.com/custom-facebook-feed/?utm_campaign=instagram-free&utm_source=cross&utm_medium=cffinstaller',
3327
- 'act' => 'go-to-url',
3328
- )
3329
  ),
3330
-
3331
- 'custom-twitter-feeds/custom-twitter-feed.php' => array(
 
 
 
 
 
 
 
3332
  'icon' => $images_url . 'plugin-tw.jpg',
3333
- 'name' => esc_html__( 'Custom Twitter Feeds', 'instagram-feed' ),
3334
  'desc' => esc_html__( 'Custom Twitter Feeds is a highly customizable way to display tweets from your Twitter account. Promote your latest content and update your site content automatically.', 'instagram-feed' ),
3335
- 'url' => 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip',
3336
- 'pro' => array(
3337
- 'plug' => 'custom-twitter-feeds-pro/custom-twitter-feed.php',
3338
- 'icon' => $images_url . 'plugin-tw.jpg',
3339
- 'name' => esc_html__( 'Custom Twitter Feeds Pro', 'instagram-feed' ),
3340
- 'desc' => esc_html__( 'Custom Twitter Feeds is a highly customizable way to display tweets from your Twitter account. Promote your latest content and update your site content automatically.', 'instagram-feed' ),
3341
- 'url' => 'https://smashballoon.com/custom-twitter-feeds/?utm_campaign=instagram-free&utm_source=cross&utm_medium=ctfinstaller',
3342
- 'act' => 'go-to-url',
3343
- )
3344
  ),
3345
-
3346
- 'feeds-for-youtube/youtube-feed.php' => array(
 
 
 
 
 
 
 
3347
  'icon' => $images_url . 'plugin-yt.png',
3348
- 'name' => esc_html__( 'Feeds for YouTube', 'instagram-feed' ),
3349
  'desc' => esc_html__( 'Feeds for YouTube is a simple yet powerful way to display videos from YouTube on your website. Increase engagement with your channel while keeping visitors on your website.', 'instagram-feed' ),
3350
- 'url' => 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip',
3351
- 'pro' => array(
3352
- 'plug' => 'youtube-feed-pro/youtube-feed.php',
3353
- 'icon' => $images_url . 'plugin-yt.png',
3354
- 'name' => esc_html__( 'Feeds for YouTube Pro', 'instagram-feed' ),
3355
- 'desc' => esc_html__( 'Feeds for YouTube is a simple yet powerful way to display videos from YouTube on your website. Increase engagement with your channel while keeping visitors on your website.', 'instagram-feed' ),
3356
- 'url' => 'https://smashballoon.com/youtube-feed/?utm_campaign=instagram-free&utm_source=cross&utm_medium=sbyinstaller',
3357
- 'act' => 'go-to-url',
3358
- )
3359
  ),
3360
- );
3361
-
3362
- }
3363
-
3364
- function output_about_addons() {
3365
 
3366
- if ( version_compare( PHP_VERSION, '5.3.0' ) <= 0
3367
- || version_compare( get_bloginfo('version'), '4.6' , '<' ) ){
3368
- return;
3369
- }
3370
 
3371
- $all_plugins = get_plugins();
3372
- $am_plugins = get_am_plugins();
3373
- $has_all_plugins = true;
3374
 
3375
- ?>
3376
- <div id="sbi-admin-addons">
3377
- <div class="addons-container">
3378
- <?php
3379
- foreach ( $am_plugins as $plugin => $details ) :
3380
 
3381
- $free_only = true;
3382
- $plugin_data = get_the_plugin_data( $plugin, $details, $all_plugins, $free_only );
3383
- $plugin_slug = strtolower( str_replace( ' ', '_', $plugin_data['details']['name'] ) );
3384
 
3385
- //Only show the plugin if both free/pro versions aren't already active
3386
- isset( $plugin_data['details']['plug'] ) ? $pro_plugin_source = $plugin_data['details']['plug'] : $pro_plugin_source = '';
3387
- if( !is_plugin_active( $plugin ) && !is_plugin_active( $pro_plugin_source ) ){
3388
- $has_all_plugins = false;
3389
- ?>
3390
- <div class="addon-container" id="install_<?php echo $plugin_slug; ?>">
3391
- <div class="addon-item">
3392
- <div class="details sbi-clear">
3393
- <img src="<?php echo esc_url( $plugin_data['details']['icon'] ); ?>">
3394
- <h5 class="addon-name">
3395
- <?php echo esc_html( $plugin_data['details']['name'] ); ?>
3396
- </h5>
3397
- <p class="addon-desc">
3398
- <?php echo wp_kses_post( $plugin_data['details']['desc'] ); ?>
3399
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3400
  </div>
3401
- <div class="actions sbi-clear">
3402
- <div class="status">
3403
- <strong>
3404
- <?php esc_html_e( 'Price:', 'instagram-feed' );
3405
- echo ' <span style="color: green;">';
3406
- _e( 'Free', 'instagram-feed' );
3407
- echo '</span>'; ?>
3408
- </strong>
3409
- </div>
3410
- <div class="action-button">
3411
- <button class="<?php echo esc_attr( $plugin_data['action_class'] ); ?>" data-plugin="<?php echo esc_attr( $plugin_data['plugin_src'] ); ?>" data-type="plugin">
3412
- <?php echo wp_kses_post( $plugin_data['action_text'] ); ?>
3413
- </button>
3414
- </div>
3415
  </div>
3416
  </div>
3417
  </div>
 
3418
 
3419
- <?php } ?>
3420
 
3421
- <?php endforeach;
 
3422
 
3423
- if( $has_all_plugins == true ){ ?>
 
3424
 
3425
- <style type="text/css">.sbi-more-plugins-intro{display:none;}</style>
3426
- <h2><?php esc_html_e( 'You already have all of our free plugins. Awesome!', 'instagram-feed' ); ?></h2>
3427
 
3428
- <p><?php esc_html_e( 'Thank you so much for using our plugins. We appreciate you trusting us to power your social media feeds.', 'instagram-feed' ); ?></p>
3429
- <p><?php esc_html_e( 'If you want to support us in our mission to make bringing social media content to your website both easy and reliable, then consider upgrading to one of our Pro plugins.', 'instagram-feed' ); ?></p>
3430
 
3431
- <div class="sbi-cols-4">
3432
- <?php //Show a list of Pro plugins which aren't currently active ?>
3433
- <?php foreach ( $am_plugins as $plugin => $details ) :
 
3434
 
3435
- $plugin_data = get_the_plugin_data( $plugin, $details, $all_plugins );
3436
- $plugin_slug = strtolower( str_replace( ' ', '_', $plugin_data['details']['name'] ) );
3437
 
3438
- isset( $plugin_data['details']['plug'] ) ? $pro_plugin_source = $plugin_data['details']['plug'] : $pro_plugin_source = '';
3439
- if( !is_plugin_active( $pro_plugin_source ) ){
3440
  ?>
3441
 
3442
- <div class="addon-container" id="install_<?php echo $plugin_slug; ?>">
3443
- <div class="addon-item">
3444
- <div class="details sbi-clear">
3445
- <img src="<?php echo esc_url( $plugin_data['details']['icon'] ); ?>">
3446
- <h5 class="addon-name">
3447
- <?php echo esc_html( $plugin_data['details']['name'] ); ?>
3448
- </h5>
3449
- <p class="addon-desc">
3450
- <?php echo wp_kses_post( $plugin_data['details']['desc'] ); ?>
3451
- </p>
3452
- </div>
3453
- <div class="actions sbi-clear">
3454
- <div class="action-button">
3455
- <a href="<?php echo esc_attr( $details['pro']['url'] ); ?>" target="_blank" class="status-go-to-url button button-primary">
3456
- <?php esc_html_e( 'Upgrade to Pro', 'instagram-feed' ); ?>
3457
- </a>
3458
- </div>
3459
  </div>
3460
  </div>
3461
  </div>
 
3462
 
3463
- <?php } ?>
3464
 
3465
- <?php endforeach; ?>
3466
- </div>
3467
 
3468
- <?php } ?>
3469
 
3470
- </div>
3471
  </div>
3472
- <?php
3473
- }
3474
-
3475
 
3476
- function get_the_plugin_data( $plugin, $details, $all_plugins, $free_only = false ) {
3477
 
3478
- $have_pro = ( ! empty( $details['pro'] ) && ! empty( $details['pro']['plug'] ) );
3479
- $show_pro = false;
3480
 
3481
- $plugin_data = array();
3482
 
3483
- if( $free_only ) $have_pro = false;
 
 
3484
 
3485
- if ( $have_pro ) {
3486
- if ( array_key_exists( $plugin, $all_plugins ) ) {
3487
- if ( is_plugin_active( $plugin ) ) {
3488
- $show_pro = true;
3489
- }
3490
- }
3491
- if ( array_key_exists( $details['pro']['plug'], $all_plugins ) ) {
3492
  $show_pro = true;
3493
  }
3494
- if ( $show_pro ) {
3495
- $plugin = $details['pro']['plug'];
3496
- $details = $details['pro'];
3497
- }
3498
  }
 
 
 
 
 
 
 
 
3499
 
3500
- if( $free_only ) $show_pro = false;
 
 
3501
 
3502
- if ( array_key_exists( $plugin, $all_plugins ) ) {
3503
- if ( is_plugin_active( $plugin ) ) {
3504
- // Status text/status.
3505
- $plugin_data['status_class'] = 'status-active';
3506
- $plugin_data['status_text'] = esc_html__( 'Active', 'instagram-feed' );
3507
- // Button text/status.
3508
- $plugin_data['action_class'] = $plugin_data['status_class'] . ' button button-secondary disabled';
3509
- $plugin_data['action_text'] = esc_html__( 'Activated', 'instagram-feed' );
3510
- $plugin_data['plugin_src'] = esc_attr( $plugin );
3511
- } else {
3512
- // Status text/status.
3513
- $plugin_data['status_class'] = 'status-inactive';
3514
- $plugin_data['status_text'] = esc_html__( 'Inactive', 'instagram-feed' );
3515
- // Button text/status.
3516
- $plugin_data['action_class'] = $plugin_data['status_class'] . ' button button-secondary';
3517
- $plugin_data['action_text'] = esc_html__( 'Activate', 'instagram-feed' );
3518
- $plugin_data['plugin_src'] = esc_attr( $plugin );
3519
- }
3520
  } else {
3521
- // Doesn't exist, install.
3522
  // Status text/status.
3523
- $plugin_data['status_class'] = 'status-download';
3524
- if ( isset( $details['act'] ) && 'go-to-url' === $details['act'] ) {
3525
- $plugin_data['status_class'] = 'status-go-to-url';
3526
- }
3527
- $plugin_data['status_text'] = esc_html__( 'Not Installed', 'instagram-feed' );
3528
  // Button text/status.
3529
- $plugin_data['action_class'] = $plugin_data['status_class'] . ' button button-primary';
3530
- $plugin_data['action_text'] = esc_html__( 'Install Plugin', 'instagram-feed' );
3531
- $plugin_data['plugin_src'] = esc_url( $details['url'] );
3532
  }
3533
-
3534
- $plugin_data['details'] = $details;
3535
-
3536
- return $plugin_data;
 
 
 
 
 
 
 
 
3537
  }
3538
 
 
3539
 
3540
- output_about_addons();
3541
-
3542
- ?>
3543
- <style>.sbi_quickstart, .sbi-pro-notice, .sbi_plugins_promo, .sbi_share_plugin{ display: none !Important; }</style>
3544
- </div>
3545
 
3546
- <?php
3547
- } //End More tab ?>
3548
 
 
 
 
3549
 
 
 
 
3550
 
3551
  <div class="sbi_quickstart">
3552
- <h3><i class="fa fa-rocket" aria-hidden="true"></i>&nbsp; <?php esc_html_e('Display your feed', 'instagram-feed'); ?></h3>
3553
- <p><?php esc_html_e('Copy and paste this shortcode directly into the page, post or widget where you\'d like to display the feed:', 'instagram-feed'); ?> <input type="text" value="[instagram-feed]" size="15" readonly="readonly" style="text-align: center;" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac)."></p>
3554
- <p><?php _e('Find out how to display <a href="?page=sb-instagram-feed&amp;tab=display">multiple feeds</a>.', 'instagram-feed'); ?></p>
3555
  </div>
3556
 
3557
  <a href="https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=footer&utm_medium=ad" target="_blank" class="sbi-pro-notice">
3558
- <img src="<?php echo SBI_PLUGIN_URL . 'img/instagram-pro-promo.png?2019'; ?>" alt="<?php esc_attr_e( 'Instagram Feed Pro', 'instagram-feed' ); ?>">
3559
  </a>
3560
 
3561
- <p class="sbi_plugins_promo dashicons-before dashicons-admin-plugins"> <?php _e('Check out our other free plugins: <a href="https://wordpress.org/plugins/custom-facebook-feed/" target="_blank" rel="noopener noreferrer">Facebook</a>, <a href="https://wordpress.org/plugins/custom-twitter-feeds/" target="_blank" rel="noopener noreferrer">Twitter</a>, and <a href="https://wordpress.org/plugins/feeds-for-youtube/" target="_blank" rel="noopener noreferrer">YouTube</a>.', 'instagram-feed' ); ?></p>
3562
 
3563
  <div class="sbi_share_plugin">
3564
- <h3><?php esc_html_e('Like the plugin? Help spread the word!', 'instagram-feed'); ?></h3>
3565
 
3566
  <button id="sbi_admin_show_share_links" class="button secondary" style="margin-bottom: 1px;"><i class="fa fa-share-alt" aria-hidden="true"></i>&nbsp;&nbsp;Share the plugin</button> <div id="sbi_admin_share_links"></div>
3567
  </div>
3568
 
3569
  </div> <!-- end #sbi_admin -->
3570
 
3571
- <?php } //End Settings page
 
4
  * functions that add menu pages in the dashboard. Also
5
  * has code for saving settings with defaults.
6
  */
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
 
11
  function sb_instagram_menu() {
12
  $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options';
20
  }
21
 
22
  $sbi_notifications = new SBI_Notifications();
23
+ $notifications = $sbi_notifications->get();
24
 
25
  $notice_bubble = '';
26
  if ( empty( $notice ) && ! empty( $notifications ) && is_array( $notifications ) ) {
27
+ $notice_bubble = ' <span class="sbi-notice-alert"><span>' . count( $notifications ) . '</span></span>';
28
+ }
29
 
30
  add_menu_page(
31
  __( 'Instagram Feed', 'instagram-feed' ),
61
  );
62
 
63
  //Show a Instagram plugin menu item if it isn't already installed
64
+ if ( ! is_plugin_active( 'custom-facebook-feed/custom-facebook-feed.php' ) && ! is_plugin_active( 'custom-facebook-feed-pro/custom-facebook-feed.php' ) ) {
65
  add_submenu_page(
66
  'sb-instagram-feed',
67
  __( 'Facebook Feed', 'instagram-feed' ),
73
  }
74
 
75
  //Show a Twitter plugin menu item if it isn't already installed
76
+ if ( ! is_plugin_active( 'custom-twitter-feeds/custom-twitter-feed.php' ) && ! is_plugin_active( 'custom-twitter-feeds-pro/custom-twitter-feed.php' ) ) {
77
  add_submenu_page(
78
  'sb-instagram-feed',
79
  __( 'Twitter Feed', 'instagram-feed' ),
85
  }
86
 
87
  //Show a YouTube plugin menu item if it isn't already installed
88
+ if ( ! is_plugin_active( 'feeds-for-youtube/youtube-feed.php' ) && ! is_plugin_active( 'youtube-feed-pro/youtube-feed.php' ) ) {
89
  add_submenu_page(
90
  'sb-instagram-feed',
91
  __( 'YouTube Feed', 'instagram-feed' ),
108
  add_submenu_page(
109
  'sb-instagram-feed',
110
  __( 'Try the Pro Demo', 'instagram-feed' ),
111
+ '<span class="sbi_get_pro">' . __( 'Try the Pro Demo', 'instagram-feed' ) . '</span>',
112
  $cap,
113
  'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=menu-link&utm_medium=upgrade-link',
114
  ''
115
  );
 
 
116
  }
117
+ add_action( 'admin_menu', 'sb_instagram_menu' );
118
 
119
  function sb_instagram_about_page() {
120
+ do_action( 'sbi_admin_page' );
121
  }
122
+
123
  function sbi_oembeds_page() {
 
124
  ?>
125
 
126
+ <div id="sbi_admin" class="wrap sbi-oembeds">
127
+ <?php
128
+ $lite_notice_dismissed = get_transient( 'instagram_feed_dismiss_lite' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ if ( ! $lite_notice_dismissed ) :
131
+ ?>
132
+ <div id="sbi-notice-bar" style="display:none">
133
+ <span class="sbi-notice-bar-message"><?php echo wp_kses_post( __( 'You\'re using Instagram Feed Lite. To unlock more features consider <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=litenotice" target="_blank" rel="noopener noreferrer">upgrading to Pro</a>.', 'instagram-feed' ) ); ?></span>
134
+ <button type="button" class="dismiss" title="<?php esc_html_e( 'Dismiss this message.', 'instagram-feed' ); ?>" data-page="overview">
135
+ </button>
136
+ </div>
137
+ <?php endif; ?>
138
+ <div id="header">
139
+ <h1><?php esc_html_e( 'Instagram oEmbeds', 'instagram-feed' ); ?></h1>
140
+ </div>
141
+
142
+ <p>
143
+ <?php
144
+ esc_html_e( 'You can use the Instagram Feed plugin to power your Instagram oEmbeds, both old and new.', 'instagram-feed' );
145
+ if ( ! SB_Instagram_Oembed::can_do_oembed() ) {
146
+ echo ' ';
147
+ esc_html_e( "Just click the button below and we'll do the rest.", 'instagram-feed' );
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  }
149
+ ?>
150
+ </p>
151
 
152
+ <div class="sbi-oembed-button">
153
+
154
+ <?php
155
+ $admin_url_state = admin_url( 'admin.php?page=sbi-oembeds' );
156
+ $encryption = new SB_Instagram_Data_Encryption();
157
+
158
+ $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
159
+ $saved_access_token_data = isset( $oembed_token_settings['access_token'] ) ? $oembed_token_settings['access_token'] : false;
160
+ if ( $saved_access_token_data && ! $encryption->decrypt( $saved_access_token_data ) ) {
161
+ $saved_access_token_data = $encryption->encrypt( $saved_access_token_data );
162
+ }
163
+
164
+ $access_token_error = false;
165
+ $valid_new_access_token = false;
166
+ $error_message = '';
167
+ $show_token_expiration_modal = false;
168
+
169
+ $nonce_verified = isset( $_GET['sbi_con'] ) && wp_verify_nonce( $_GET['sbi_con'], 'sbi-oembed' );
170
+ if ( $nonce_verified && ! empty( $_GET['sbi_access_token'] ) && strlen( $_GET['sbi_access_token'] ) <= 20 ) {
171
+ $access_token_error = true;
172
+ $error_message = __( 'There was a problem with the access token that was retrieved.', 'instagram-feed' );
173
+
174
+ } elseif ( $nonce_verified && ! empty( $_GET['transfer'] ) ) {
175
+ if ( class_exists( 'CFF_Oembed' ) ) {
176
+ $cff_oembed_token = CFF_Oembed::last_access_token();
177
+ $valid_new_access_token = $cff_oembed_token;
178
  }
179
  } else {
 
 
 
180
 
181
+ $valid_new_access_token = ! empty( $_GET['sbi_access_token'] ) && strlen( $_GET['sbi_access_token'] ) > 20 && $saved_access_token_data !== $_GET['sbi_access_token'] ? sbi_sanitize_alphanumeric_and_equals( $_GET['sbi_access_token'] ) : false;
182
+ if ( $valid_new_access_token ) {
183
+ $args = array(
184
+ 'timeout' => 20,
185
+ );
186
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
187
+ $args['sslverify'] = false;
188
+ }
189
+ $pages_data_connection = wp_remote_get( esc_url_raw( 'https://graph.facebook.com/me/accounts?limit=500&access_token=' . $valid_new_access_token ), $args );
190
 
191
+ if ( ! is_wp_error( $pages_data_connection ) && isset( $pages_data_connection['body'] ) ) {
192
+ $pages_data = json_decode( $pages_data_connection['body'], true );
193
+ if ( isset( $pages_data['data'][0]['access_token'] ) ) {
194
+ $oembed_token_settings['expiration_date'] = 'never';
195
+ } else {
196
+ $oembed_token_settings['expiration_date'] = time() + ( 60 * DAY_IN_SECONDS );
197
+ $show_token_expiration_modal = true;
198
+ }
199
+ } else {
200
+ $oembed_token_settings['expiration_date'] = 'unknown';
201
+ }
202
+ }
203
+ }
204
 
205
+ $token_href = 'https://www.facebook.com/dialog/oauth?client_id=254638078422287&redirect_uri=https://api.smashballoon.com/v2/instagram-graph-api-redirect.php&scope=pages_show_list&state=' . $admin_url_state;
206
+ $need_to_connect_class = ' sbi-need-to-connect';
207
+ if ( class_exists( 'CFF_Oembed' ) ) {
208
+ $cff_oembed_token = CFF_Oembed::last_access_token();
 
 
 
 
209
 
210
+ if ( ! empty( $cff_oembed_token ) ) {
211
+ $need_to_connect_class = '';
212
+ $token_href = add_query_arg( 'transfer', '1', $admin_url_state );
213
+ }
214
  }
215
+ $token_href = str_replace( esc_html( '&sbi_con' ), ',sbi_con', wp_nonce_url( $token_href, 'sbi-oembed', 'sbi_con' ) );
216
 
217
+ if ( ! $saved_access_token_data && ! $valid_new_access_token && ! SB_Instagram_Oembed::can_do_oembed() ) {
218
+ if ( $access_token_error ) {
219
+ ?>
220
+ <p class="sbi-error"><?php echo wp_kses_post( $error_message ); ?></p>
221
+ <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  }
223
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
+ <a href="<?php echo esc_url( $token_href ); ?>" class="sbi-oembed-connect-btn<?php echo esc_attr( $need_to_connect_class ); ?>"><i class="fa fa-instagram"></i> <?php esc_html_e( 'Enable Instagram oEmbeds', 'instagram-feed' ); ?></a>
226
+ <div id="sbi_config_info" class="sb_get_token" style="display: none;">
227
+ <div class="sbi_config_modal">
228
+ <?php esc_html_e( 'As Instagram is part of Facebook, in order to display Instagram oEmbeds, you must connect to Facebook. Click on the button below to connect', 'instagram-feed' ); ?>
229
+
230
+ <p>
231
+ <a style="display: inline-block; float: none; margin-bottom: 0;" href="<?php echo esc_url( $token_href ); ?>" class="sbi-oembed-connect-btn"><?php esc_html_e( 'Connect to Facebook', 'instagram-feed' ); ?></a>
232
+ </p>
233
+
234
+ <a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>
235
+ </div>
236
+ </div>
237
+ <div class="sbi-oembed-promo sbi-oembed-desc">
238
+ <div class="sbi-col">
239
+ <h2><?php esc_html_e( 'What are oEmbeds?', 'instagram-feed' ); ?></h2>
240
+ <p><?php echo wp_kses_post( __( "Anytime you share a link to an Instagram post in WordPress, it is automatically converted into an embedded version of that Instagram post (an \"oEmbed\").</p><p>However, WordPress is discontinuing support for Instagram oEmbeds due to them now requiring an Access Token to work. Don't worry though, we have your back. Just use the button above to connect to Facebook and we'll make sure your Instagram oEmbeds keep working.", 'instagram-feed' ) ); ?></p>
241
+ </div>
242
+
243
+ <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/sbi-oembed.png' ); ?>" style="padding: 0; background: white;" alt="<?php esc_attr_e( 'Oembed example', 'instagram-feed' ); ?>">
244
+ </div>
245
+ <?php
246
+ } else {
247
+ if ( $valid_new_access_token ) {
248
+ if ( ! is_array( $oembed_token_settings ) ) {
249
+ $oembed_token_settings = array(
250
+ 'access_token' => '',
251
+ 'disabled' => '',
252
+ );
253
+ }
254
+ if ( $valid_new_access_token && ! $encryption->decrypt( $valid_new_access_token ) ) {
255
+ $valid_new_access_token = $encryption->encrypt( $valid_new_access_token );
256
+ }
257
+ $oembed_token_settings['access_token'] = $valid_new_access_token;
258
+ $oembed_token_settings['disabled'] = false;
259
+ update_option( 'sbi_oembed_token', $oembed_token_settings );
260
+ ?>
261
+ <div><p class="sbi-success-message"><?php esc_html_e( "You're all set! Instagram Feed will replace your old oEmbeds automatically and generate all new content for all new links.", 'instagram-feed' ); ?> <a href="javascript:void(0);" id="sbi-oembed-disable"><?php esc_html_e( 'Disable', 'instagram-feed' ); ?></a></p></div>
262
+ <?php if ( $show_token_expiration_modal ) : ?>
263
+ <div id="sbi_config_info" class="sb_get_token">
264
+ <div class="sbi_config_modal">
265
+ <p><strong><?php esc_html_e( 'Heads up!', 'instagram-feed' ); ?></strong><br></p>
266
+
267
+ <p>
268
+ <?php esc_html_e( 'Your access token will expire in 60 days. Facebook requires that users have a role on a Facebook page in order to create access tokens that don\'t expire. Click the button below for instructions on creating a Facebook page and extending your access token to never expire.', 'instagram-feed' ); ?>
269
+ </p>
270
+ <p>
271
+ <a style="display: inline-block; float: none; margin-bottom: 0;" href="https://smashballoon.com/doc/how-to-prevent-your-oembed-access-token-from-expiring/?instagram" class="sbi-oembed-connect-btn" target="_blank" rel="noopener"><?php esc_html_e( 'How to Create a Facebook Page', 'instagram-feed' ); ?></a>
272
+ &nbsp;&nbsp;<a href="<?php echo esc_url( $token_href ); ?>" class="button button-secondary" style="height: 47px;line-height: 47px;font-size: 14px;padding: 0 21px;"><?php esc_html_e( 'Try Again', 'instagram-feed' ); ?></a>
273
+ </p>
274
+
275
+ <a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>
276
+ </div>
277
+ </div>
278
+ <?php endif; ?>
279
+ <?php
280
+ } else {
281
+ if ( ! isset( $oembed_token_settings['expiration_date'] ) || (int) $oembed_token_settings['expiration_date'] === 0 || $oembed_token_settings['expiration_date'] > time() ) :
282
+ ?>
283
+ <div><p class="sbi-success-message"><?php esc_html_e( 'The Instagram Feed plugin is now powering your Instagram oEmbeds.', 'instagram-feed' ); ?> <a href="javascript:void(0);" id="sbi-oembed-disable"><?php esc_html_e( 'Disable', 'instagram-feed' ); ?></a></p></div>
284
+ <?php
285
+ endif;
286
+ if ( ! empty( $oembed_token_settings['expiration_date'] )
287
+ && $oembed_token_settings['expiration_date'] !== 'never' ) :
288
+ $link_1 = '<a href="https://smashballoon.com/doc/how-to-prevent-your-oembed-access-token-from-expiring/?instagram" target="_blank" rel="noopener">';
289
+ $link_2 = '</a>';
290
+ $class = 'sbi_warning';
291
+ if ( $oembed_token_settings['expiration_date'] > time() ) {
292
+ $days_to_expire = floor( ( $oembed_token_settings['expiration_date'] - time() ) / DAY_IN_SECONDS );
293
+ $message = sprintf( __( '%1$1sImportant:%2$2s Your access token for powering oEmbeds will expire in %3$3s days.', 'instagram-feed' ), '<strong>', '</strong>', $days_to_expire );
294
+ } else {
295
+ $class = 'sb_instagram_notice';
296
+ $message = __( 'Your access token for powering oEmbeds has expired.', 'instagram-feed' );
297
+ }
298
+ ?>
299
+ <div class="<?php echo esc_attr( $class ); ?>" style="display:inline-block;width: auto;">
300
+ <p>
301
+ <?php echo wp_kses_post( $message ); ?>
302
+ </p>
303
+ <p>
304
+ <?php echo wp_kses_post( sprintf( __( 'Instagram requires that users have a role on a Facebook page in order to create access tokens that don\'t expire. Visit %1$1sthis link%2$2s for instructions on extending your access token to never expire.', 'instagram-feed' ), $link_1, $link_2 ) ); ?>
305
+ </p>
306
+ <p>
307
+ <a style="display: inline-block; float: none; margin-bottom: 0;" href="<?php echo esc_url( $token_href ); ?>" class="sbi-oembed-connect-btn"><?php esc_html_e( 'Connect to Facebook and Recheck Access Token', 'instagram-feed' ); ?></a>
308
+ </p>
309
+ </div>
310
+
311
+ <?php endif; ?>
312
+
313
+ <?php } ?>
314
+ <div class="sbi-oembed-promo">
315
+ <h2><?php esc_html_e( 'Did you know, you can also use this Instagram Feed plugin to easily add Instagram content on your website?', 'instagram-feed' ); ?></h2>
316
+ <div class="sbi-reasons">
317
+ <div><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="clock" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-clock fa-w-16 fa-2x"><path fill="currentColor" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z" class=""></path></svg><span><?php esc_html_e( 'Save time', 'instagram-feed' ); ?></span></div>
318
+ <div><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="chart-line" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-chart-line fa-w-16 fa-2x"><path fill="currentColor" d="M117.65 277.65c6.25 6.25 16.38 6.25 22.63 0L192 225.94l84.69 84.69c6.25 6.25 16.38 6.25 22.63 0L409.54 200.4l29.49 29.5c15.12 15.12 40.97 4.41 40.97-16.97V112c0-8.84-7.16-16-16-16H363.07c-21.38 0-32.09 25.85-16.97 40.97l29.5 29.49-87.6 87.6-84.69-84.69c-6.25-6.25-16.38-6.25-22.63 0l-74.34 74.34c-6.25 6.25-6.25 16.38 0 22.63l11.31 11.31zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16z" class=""></path></svg><span><?php esc_html_e( 'Increase social engagement', 'instagram-feed' ); ?></span></div>
319
+ <div><svg aria-hidden="true" focusable="false" data-prefix="fal" data-icon="heart" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-heart fa-w-16 fa-2x"><path fill="currentColor" d="M462.3 62.7c-54.5-46.4-136-38.7-186.6 13.5L256 96.6l-19.7-20.3C195.5 34.1 113.2 8.7 49.7 62.7c-62.8 53.6-66.1 149.8-9.9 207.8l193.5 199.8c6.2 6.4 14.4 9.7 22.6 9.7 8.2 0 16.4-3.2 22.6-9.7L472 270.5c56.4-58 53.1-154.2-9.7-207.8zm-13.1 185.6L256.4 448.1 62.8 248.3c-38.4-39.6-46.4-115.1 7.7-161.2 54.8-46.8 119.2-12.9 142.8 11.5l42.7 44.1 42.7-44.1c23.2-24 88.2-58 142.8-11.5 54 46 46.1 121.5 7.7 161.2z" class=""></path></svg><span><?php esc_html_e( 'Keep Your Site Looking Fresh.', 'instagram-feed' ); ?></span></div>
320
+ </div>
321
+ <p>
322
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check fa-w-16 fa-2x"><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg><span><?php esc_html_e( 'Super simple to set up', 'instagram-feed' ); ?></span>
323
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check fa-w-16 fa-2x"><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg><span><?php esc_html_e( 'Optimized for speed', 'instagram-feed' ); ?></span>
324
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check fa-w-16 fa-2x"><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg><span><?php esc_html_e( 'Completely customizable', 'instagram-feed' ); ?></span>
325
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check fa-w-16 fa-2x"><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg><span><?php esc_html_e( 'SEO friendly', 'instagram-feed' ); ?></span>
326
+ </p>
327
+ <a href="?page=sb-instagram-feed" class="button button-primary"><?php esc_html_e( 'Add an Instagram feed now', 'instagram-feed' ); ?></a>
328
+ </div>
329
 
330
  <?php } ?>
331
 
332
+ </div>
333
+ </div>
334
+ <?php
335
+ }
336
 
337
  function sbi_social_wall_page() {
338
 
340
 
341
  ?>
342
 
343
+ <div id="sbi_admin" class="wrap sw-landing-page">
344
 
345
+ <div class="sbi-sw-icons">
346
 
347
+ <span style="display: inline-block; padding: 0 0 12px 0; width: 360px; max-width: 100%;">
348
+ <svg viewBox="0 0 9161 1878" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2">
349
+ <path d="M671.51192 492.98498c-131.56765-59.12206-268.60859-147.41608-396.53319-188.5154 45.4516 108.39585 83.81326 223.88002 123.5099 338.03081-79.17849 59.49897-171.6647 105.68858-260.02357 156.01204C213.65642 872.8361 320.1446 915.85885 404.9893 980.52836c-67.96118 83.8619-201.48512 171.0179-234.02089 247.0198 140.6921-17.62678 304.63665-46.21028 435.53762-52.00414 28.76425 144.58318 43.59867 303.0974 84.5075 435.5368 60.92028-175.2656 116.0013-356.3729 188.5158-520.0447 111.90636 46.28566 248.28994 102.72599 357.52876 130.01178-76.6463-107.53462-146.59336-221.76932-214.51645-338.02878 100.51155-72.83872 202.17166-144.52441 299.02516-221.02077-136.89504-12.61227-278.73407-20.28825-422.53587-25.99863-22.85286-148.332-16.84825-325.5158-52.00496-461.53949-53.19323 111.48812-115.96685 213.3914-175.51405 318.52475m65.00509 1228.60643c-18.07949 77.37581 41.48757 109.11319 32.50294 156.01204-58.81404-20.26799-103.0575-30.6796-182.01552-19.50201 2.47017-60.37032 56.76657-68.90954 45.50428-143.0107-841.40803-95.6632-843.09804-1616.06909-6.50107-1709.64388C1672.04777-111.55711 1704.8713 1694.70523 736.517 1721.5914" fill="#e34f0e"/>
350
+ <path d="M847.02597 174.46023c35.15671 136.0237 29.1521 313.20749 52.00455 461.53544 143.80221 5.71443 285.63962 13.38636 422.53628 26.00268-96.8531 76.49636-198.51483 148.18205-299.02556 221.01874 67.92349 116.2623 137.87014 230.49416 214.51847 338.03-109.24085-27.2866-245.62443-83.72572-357.5308-130.0126-72.51448 163.67262-127.5955 344.77992-188.51538 520.04553-40.90924-132.4394-55.74325-290.95364-84.5079-435.53681-130.90057 5.79548-294.84472 34.37736-435.53722 52.00415 32.53577-76.0007 166.0589-163.15589 234.02008-247.02021-84.8451-64.67032-191.33207-107.69066-266.52343-182.01472 88.35886-50.32346 180.84346-96.51307 260.02276-156.01609-39.69705-114.14674-78.05668-229.63091-123.50868-338.02675C402.9013 345.5689 539.94427 433.86292 671.51192 492.98498c59.5468-105.13335 122.32082-207.03663 175.51405-318.52475" fill="#fff"/>
351
+ <path d="M1782.27033 1236.51938c41.18267 21.61921 126.79927 44.31938 214.58338 44.31938 213.49962 0 311.03752-107.01507 311.03752-232.40646 0-101.61027-58.52274-171.87269-189.65702-220.5159-92.11913-33.50977-131.13429-48.6432-131.13429-85.39586 0-32.4288 32.51263-54.04801 92.11913-54.04801 72.61154 0 126.79927 20.53824 158.22814 34.59073l41.18267-155.65828c-47.6852-21.6192-110.54295-37.83361-197.2433-37.83361-184.23826 0-293.69746 99.44834-293.69746 228.08262 0 108.09602 82.36534 176.19652 205.91335 219.43493 82.36533 28.10497 114.87797 48.64321 114.87797 84.3149 0 36.75265-32.51264 59.45282-99.70541 59.45282-73.6953 0-145.2231-22.70017-189.65703-45.40034l-36.84765 161.06308zM3019.37602 1270.02915h189.65702l-36.84765-728.56722h-256.8498l-55.27148 194.57285c-21.67508 76.74818-45.51768 179.4394-66.10902 268.07815h-3.25126c-15.17256-88.63875-36.84765-185.92517-57.43898-266.99719l-47.6852-195.6538h-263.35233l-45.51768 728.56721h179.90323l11.9213-260.51142c3.25127-83.23394 6.50253-191.32997 10.83755-294.0212h2.1675c17.34008 99.44835 39.01517 207.54438 58.52274 286.45448l60.69025 252.9447h152.80938l72.61154-254.02566c23.8426-79.99106 54.18773-189.16805 76.94657-285.37352h3.25126c0 113.50083 1.08376 210.78726 4.33502 294.0212l8.67004 260.51142zM3699.9738 1101.39935l46.60144 168.6298h211.33211l-217.83464-728.56722H3478.8879l-211.33211 728.56722h202.66208l41.18267-168.6298h188.57327zm-162.56317-143.76772l31.42888-130.79619c9.7538-41.07649 20.59134-101.61026 31.42888-143.76771h2.1675c11.9213 42.15745 26.01012 102.69122 36.84766 143.76771l33.59639 130.7962h-135.4693zM4016.4301 1236.51938c41.18266 21.61921 126.79926 44.31938 214.58337 44.31938 213.49962 0 311.03752-107.01507 311.03752-232.40646 0-101.61027-58.52274-171.87269-189.65702-220.5159-92.11913-33.50977-131.1343-48.6432-131.1343-85.39586 0-32.4288 32.51264-54.04801 92.11914-54.04801 72.61154 0 126.79926 20.53824 158.22814 34.59073l41.18267-155.65828c-47.6852-21.6192-110.54295-37.83361-197.2433-37.83361-184.23826 0-293.69746 99.44834-293.69746 228.08262 0 108.09602 82.36534 176.19652 205.91335 219.43493 82.36533 28.10497 114.87797 48.64321 114.87797 84.3149 0 36.75265-32.51264 59.45282-99.70541 59.45282-73.6953 0-145.2231-22.70017-189.65703-45.40034l-36.84765 161.06308zM4623.27688 541.46193v728.56722h196.15955V981.41276h237.34222v288.6164h196.15955V541.46192h-196.15955v269.1591h-237.34222v-269.1591h-196.15955z" fill="#282828" fill-rule="nonzero"/>
352
+ <g>
353
+ <path d="M6900.00785 293.7053c5.29-14.371 11.90999-24.77099 19.84998-31.19998 7.94-6.429 16.07-9.644 24.38998-9.644 8.32 0 15.7 2.08 22.12999 6.241 6.43 4.16 10.39999 9.265 11.90999 15.31599 2.27 43.86896 4.16 92.65493 5.67 146.35689 1.51 53.70296 2.65 109.86291 3.4 168.48187.76 58.61796 1.52 118.74891 2.26999 180.39386.76 61.64396 1.33 122.71991 1.71 183.22987.37 60.50695.56 119.1269.56 175.85686 0 56.72996.38 109.28992 1.14 157.69988-3.78 12.1-10.59 20.98999-20.41999 26.65998-9.83999 5.68-19.85998 8.14-30.06997 7.38-10.21-.76-19.28999-4.73-27.22998-11.91-7.94-7.18999-11.91-17.58998-11.91-31.19997l-3.4-983.66226zm173.57987 0c5.3-14.371 11.90999-24.77099 19.85998-31.19998 7.94-6.429 16.06999-9.644 24.38998-9.644 8.32 0 15.69 2.08 22.11999 6.241 6.43 4.16 10.39999 9.265 11.91999 15.31599 2.27 43.86896 4.15 92.65493 5.67 146.35689 1.51 53.70296 2.64 109.86291 3.4 168.48187.76 58.61796 1.51999 118.74891 2.26999 180.39386.76 61.64396 1.33 122.71991 1.7 183.22987.38 60.50695.57 119.1269.57 175.85686 0 56.72996.38 109.28992 1.13 157.69988-3.78 12.1-10.59 20.98999-20.41999 26.65998-9.82999 5.68-19.84998 8.14-30.05998 7.38-10.20999-.76-19.28998-4.73-27.22997-11.91-7.94-7.18999-11.92-17.58998-11.92-31.19997l-3.4-983.66226zm-419.49969 980.25225c-6.81-4.54-13.60999-12.66999-20.41998-24.38998-6.81-11.71999-13.61-24.57998-20.41999-38.57997-6.81-13.98999-13.61999-28.16998-20.41998-42.53997-6.81-14.36999-13.99999-26.84998-21.55998-37.43997-7.56-10.58999-15.51-18.33998-23.82999-23.25998-8.31999-4.92-17.38998-4.73-27.22998.57-15.11998 24.95998-30.43997 49.15996-45.93996 72.60994-15.50999 23.44999-32.52998 43.48997-51.05996 60.12996-18.52999 16.63999-39.70997 28.35998-63.52995 35.16997-23.82999 6.81-51.62997 6.05-83.38994-2.27-31.01998-8.31999-56.16996-24.57998-75.44994-48.77996-19.28999-24.20998-33.65998-52.94996-43.10997-86.22993-9.46-33.27998-14.19-69.77995-14.19-109.48992 0-39.70397 4.35-79.22394 13.05-118.55591 8.7-39.33097 21.36998-77.14894 38.00997-113.45492 16.63999-36.30597 36.67997-67.50595 60.12995-93.60093 23.44999-26.09398 50.10997-45.75996 79.98994-58.99595 29.86998-13.237 62.20996-16.82999 96.99993-10.779 32.51998 6.051 59.36996 19.855 80.54994 41.41198 21.17998 21.55598 38.76997 47.65096 52.75996 78.28394 13.98999 30.63297 24.95998 64.47995 32.89998 101.54192 7.93999 37.06197 15.12998 74.12394 21.55998 111.18692 6.43 37.06197 12.85999 72.42194 19.28999 106.08192 6.41999 33.65997 14.92998 62.58995 25.51998 86.78993 10.58999 24.20998 24.01998 41.97997 40.27997 53.32996 16.25998 11.34 37.62997 12.84999 64.09995 4.53 30.25997-31.00998 54.45996-51.61996 72.60994-61.82996 18.15999-10.20999 31.38998-13.60999 39.70997-10.20999 8.32 3.4 11.91 11.91 10.78 25.52998-1.13 13.61-6.05 28.73998-14.75 45.37997-8.69999 16.63999-20.60998 32.89997-35.73997 48.77996-15.11999 15.88999-32.32997 27.98998-51.61996 36.30997-19.28998 8.32-40.46997 11.16-63.52995 8.51-23.06998-2.65-47.08997-14.56-72.04995-35.73998zm2413.83818 6.81c-2.26-39.32997-5.67-82.25994-10.20999-128.7699-4.53-46.51997-10.58-92.84993-18.14999-138.9899-7.55999-46.13396-16.63998-89.81493-27.22998-131.0369-10.58999-41.22197-23.06998-76.01494-37.43997-104.37892-14.36999-28.36298-30.81997-48.21797-49.34996-59.56396-18.52999-11.34499-39.51997-9.83199-62.96995 4.539-23.44998 14.37099-49.34997 43.30197-77.71994 86.79293-28.35998 43.49097-59.93996 106.08092-94.72993 187.76786-3.03 6.05-7 15.88-11.91 29.49998-4.91999 13.60999-10.20999 28.92998-15.88998 45.94997-5.67 17.01998-11.91 34.97997-18.71999 53.88996-6.8 18.90998-13.03999 37.05997-18.71998 54.45995-5.67 17.4-10.78 32.89998-15.31 46.50997-4.53999 13.61999-7.56999 23.82998-9.07998 30.63998-6.05 15.11998-13.62 23.62998-22.68999 25.52998-9.08 1.89-18.14998.18-27.22998-5.11-9.07999-5.3-17.39998-12.47999-24.95998-21.55998-7.56-9.07-12.09999-17.01999-13.61999-23.81999 6.81-26.47998 12.86-55.96995 18.15999-88.49993 5.29-32.51997 9.45-69.57995 12.47999-111.17991 3.02-41.60397 4.16-88.68794 3.4-141.2559-.76-52.56696-4.54-112.13091-11.35-178.69186 8.32-17.39599 16.65-27.03998 24.96999-28.93098 8.31999-1.891 16.63998.756 24.94998 7.942 8.32 7.18499 16.07999 17.77498 23.25998 31.76697 7.19 13.99299 13.61999 28.17498 19.28999 42.54597 5.67 14.37099 10.20999 27.79698 13.61998 40.27697 3.4 12.47999 5.1 20.61098 5.1 24.39298 16.63999-14.371 31.95998-32.71298 45.94997-55.02596 13.98999-22.31298 28.35997-44.62597 43.10996-66.93895 14.75-22.31298 30.82998-42.16697 48.21997-59.56396 17.39998-17.39598 38.19997-27.98597 62.39995-31.76697 49.91996-9.077 92.27993-3.215 127.0699 17.58499 34.79998 20.79998 63.34996 50.67696 85.65994 89.62993 22.30998 38.95297 39.32997 84.14593 51.05996 135.5789 11.72 51.43296 20.03999 103.05492 24.95998 154.86588 4.91 51.80996 6.99 101.34992 6.24 148.62989-.76 47.26996-2.65 86.02993-5.68 116.2899-8.32 17.39-19.46998 26.08999-33.46997 26.08999-13.99 0-25.13998-8.7-33.46998-26.08998zm-1029.72922-9.08c-43.86997-18.14998-78.46994-41.97996-103.80992-71.46994-25.33998-29.49998-43.10997-61.83995-53.32996-97.00993-10.21-35.16997-13.61-72.03994-10.21-110.61791 3.41-38.57497 12.48-76.20395 27.22999-112.88792 14.74998-36.68397 34.41997-71.28794 58.99995-103.81092 24.57998-32.52398 52.56996-60.32095 83.95994-83.38994 31.38997-23.06898 65.79995-40.08797 103.23992-51.05496 37.43997-10.967 76.20994-13.42599 116.28991-7.375 33.27998 5.295 61.83995 20.99 85.65994 47.08397 23.82998 26.09498 42.73996 58.42996 56.72995 97.00493 13.99 38.57397 22.87999 80.93094 26.65998 127.0699 3.78 46.13797 1.7 91.70893-6.24 136.7079-7.93999 45.00996-21.55997 86.79993-40.83996 125.3699-19.28999 38.57998-44.62997 69.77995-76.01994 93.59993-31.38998 23.82999-69.39995 37.81998-114.01992 41.97997-44.62996 4.16-96.05992-6.24-154.29988-31.19997zm-642.42952 0c-43.86996-18.14998-78.46994-41.97996-103.80992-71.46994-25.33998-29.49998-43.10997-61.83995-53.31996-97.00993-10.20999-35.16997-13.61999-72.03994-10.20999-110.61791 3.4-38.57497 12.48-76.20395 27.21998-112.88792 14.74999-36.68397 34.41997-71.28794 58.99996-103.81092 24.57998-32.52398 52.56996-60.32095 83.95993-83.38994 31.38998-23.06898 65.79995-40.08797 103.23992-51.05496 37.43998-10.967 76.20995-13.42599 116.29992-7.375 33.27997 5.295 61.82995 20.99 85.64993 47.08397 23.82998 26.09498 42.73997 58.42996 56.72996 97.00493 13.98999 38.57397 22.87998 80.93094 26.65998 127.0699 3.79 46.13797 1.71 91.70893-6.24 136.7079-7.94 45.00996-21.54998 86.79993-40.83997 125.3699-19.28998 38.57998-44.62996 69.77995-76.01994 93.59993-31.38997 23.82999-69.38995 37.81998-114.01991 41.97997-44.61997 4.16-96.05993-6.24-154.29989-31.19997zm-1823.64862-14.69998c-5.29-34.31998-9.64-71.39995-13.04999-111.24992-3.4-39.85997-6.24-80.95994-8.5-123.2999-2.27-42.34497-3.79-85.24294-4.54-128.6939-.75999-43.45198-1.13999-86.07294-1.13999-127.86391 0-41.78997.38-81.91994 1.14-120.38991.75-38.46997 1.89-74.30995 3.4-107.52092 2.27-9.41 8.13-15.63699 17.58998-18.68199 9.45-3.044 19.65999-3.736 30.62998-2.075 10.97 1.66 20.98998 5.12 30.06998 10.378 9.07 5.259 13.98999 11.48599 14.73999 18.68198-1.51 31.54998-2.64 62.40896-3.4 92.57593-.76 30.16698-.57 59.91796.57 89.25494 1.13 29.33597 3.4 58.81095 6.81 88.42493 3.4 29.61298 8.12999 59.64095 14.17998 90.08493 35.54998-34.31797 72.03995-55.90596 109.47992-64.76195 37.43997-8.856 72.79995-8.441 106.07992 1.245 33.27998 9.687 63.72995 26.56898 91.32993 50.64796 27.60998 24.07798 49.54996 51.61496 65.80995 82.61194 16.25999 31.00198 25.89998 63.65195 28.92998 97.97192 3.02 34.31998-3.22 66.41995-18.71999 96.30993-15.50998 29.88998-41.40996 55.62996-77.71994 77.21994-36.29997 21.58999-85.46993 35.42998-147.48989 41.50997-27.22998 2.77-50.86996 4.99-70.90994 6.65-20.03999 1.66-38.94997 1.8-56.72996.41-17.76999-1.38-35.91997-5.12-54.45996-11.21-18.52998-6.08999-39.89997-15.49998-64.09995-28.22997zm85.08994-154.42989c-9.83 32.09998-11.34 58.25996-4.53 78.45994 6.8 20.20999 18.89998 35.00998 36.29997 44.41997 17.39999 9.41 38.57997 14.11999 63.53995 14.11999 24.95998 0 50.66997-3.74 77.13995-11.21 26.47998-7.46999 52.37996-18.12998 77.71994-31.96997 25.33998-13.83999 47.08996-30.15997 65.23995-48.97996 13.60999-13.83999 20.79998-30.58998 21.55998-50.23996.75-19.64999-2.84-39.70997-10.78-60.18996-7.94998-20.47998-19.85998-40.13097-35.73996-58.95095-15.88-18.81999-33.65998-34.31798-53.31996-46.49597-19.66999-12.17699-40.65997-19.64998-62.96996-22.41698-22.31998-2.768-44.24996 1.799-65.80995 13.69899-21.54998 11.90099-41.78996 32.10397-60.69995 60.61095-18.90999 28.50398-34.78997 68.22395-47.64996 119.14391zm2380.9882 74.95995c49.15996 31.76997 93.21993 45.00996 132.1799 39.70997 38.94997-5.29 71.65995-21.92999 98.12993-49.91997 26.47998-27.97997 46.32996-63.71995 59.56995-107.20991 13.24-43.48997 18.90999-87.92994 17.01999-133.3119-1.9-45.38197-11.73-87.54994-29.49998-126.5029-17.77999-38.95298-44.81997-68.26196-81.11994-87.92694-20.41998-10.59-44.24997-10.022-71.47994 1.701-27.22998 11.72399-53.88996 30.63297-79.97994 56.72795-26.09998 26.09498-49.73997 57.29496-70.90995 93.60093-21.17999 36.30498-35.54997 73.55695-43.11997 111.75292-7.56 38.19897-6.62 75.06894 2.84 110.61892 9.45 35.54997 31.57998 65.79995 66.36995 90.75993zm-642.42952 0c49.16997 31.76997 93.21993 45.00996 132.1799 39.70997 38.94997-5.29 71.65995-21.92999 98.13993-49.91997 26.46998-27.97997 46.31997-63.71995 59.55996-107.20991 13.23999-43.48997 18.90998-87.92994 17.01998-133.3119-1.89-45.38197-11.71999-87.54994-29.49998-126.5029-17.76998-38.95298-44.80996-68.26196-81.11993-87.92694-20.41999-10.59-44.24997-10.022-71.47995 1.701-27.22998 11.72399-53.88996 30.63297-79.97994 56.72795-26.09998 26.09498-49.72996 57.29496-70.90995 93.60093-21.17998 36.30498-35.54997 73.55695-43.10996 111.75292-7.57 38.19897-6.62 75.06894 2.83 110.61892 9.45999 35.54997 31.57997 65.79995 66.36994 90.75993zm-1159.18912-39.69997c19.65998 30.24997 40.26997 47.64996 61.82995 52.18996 21.55999 4.53 42.53997.56 62.96995-11.92 20.41999-12.47998 39.70997-31.00997 57.85996-55.58995 18.14999-24.57998 33.65998-50.86996 46.51997-78.84994 12.84999-27.98998 22.30998-55.40696 28.35997-82.25794 6.05-26.85098 7.56-48.97496 4.54-66.37095-3.78-18.15299-6.81-34.41497-9.08-48.78596-2.27-14.371-4.72999-27.22898-7.36999-38.57497-2.65-11.345-5.68-21.74599-9.07999-31.19998-3.4-9.455-8.13-19.09799-14.17999-28.93098-30.25998-21.17898-58.42996-29.49898-84.52994-24.95998-26.08998 4.538-49.53996 17.39599-70.33994 38.57397-20.79999 21.17898-38.18997 48.40796-52.18996 81.68794-13.99 33.27997-24.19998 68.07295-30.62998 104.37892-6.43 36.30597-8.51 71.47995-6.24 105.50992 2.27 34.03998 9.45 62.39995 21.55999 85.09994z" fill="#282828" fill-rule="nonzero"/>
354
+ <path d="M6892.93785 1141.07765l-2.93-847.33736c-.01-1.191.2-2.374.61-3.492 6.06-16.43098 13.87-28.16497 22.94999-35.51497 9.95999-8.065 20.24998-11.87199 30.67997-11.87199 10.37 0 19.54999 2.66 27.55998 7.845 8.86 5.732 14.1 12.94799 16.18 21.28698.16.625.25 1.264.29 1.908 2.26999 43.93997 4.15999 92.80393 5.67999 146.59289 1.51 53.75096 2.65 109.96191 3.4 168.63387.76 58.61996 1.52 118.75391 2.27 180.39986.76 61.66396 1.33 122.76091 1.71 183.28987.37 60.52995.56 119.1699.56 175.91986 0 56.66996.38 109.18992 1.13999 157.54988.01 1.06-.14 2.12-.46 3.13-4.6 14.73-12.99999 25.43998-24.96998 32.34998-11.7 6.75-23.64998 9.58-35.79997 8.68-12.44-.92-23.51999-5.71-33.19998-14.47-9.87-8.93-15.19999-21.69998-15.19999-38.57997l-.25-72.25994c-2.06 5.06-4.48 10.24999-7.27 15.58998-9.08998 17.41-21.52998 34.43998-37.35996 51.04997-16.08 16.88998-34.38998 29.74997-54.89996 38.58997-20.83999 8.98999-43.70997 12.12999-68.62995 9.25999-24.60998-2.82-50.33996-15.20999-76.94994-37.68997-7.62-5.23-15.41999-14.25-23.02998-27.34998-6.92-11.92-13.84-24.98998-20.75999-39.21997-6.83-14.02-13.64999-28.23998-20.46998-42.63997-6.53-13.77999-13.4-25.75998-20.65999-35.90997-6.62-9.27-13.48999-16.15999-20.76998-20.45999-4.67-2.76-9.71-2.7-15.12-.35-14.69998 24.18998-29.57997 47.66997-44.62996 70.42995-16.00999 24.20998-33.58997 44.87997-52.71996 62.05995-19.67998 17.66999-42.16997 30.11998-67.46995 37.34997-25.32998 7.23-54.88996 6.63-88.72993-2.23-33.15997-8.89999-60.03995-26.31997-80.66994-52.20995-20.07998-25.18998-35.06997-55.08996-44.90996-89.72994-9.7-34.10997-14.57-71.50994-14.57-112.21991 0-40.42697 4.43-80.66694 13.29-120.71491 8.84999-40.02697 21.73998-78.51394 38.67997-115.46191 17.08998-37.28898 37.69997-69.31695 61.77995-96.11793 24.43998-27.19398 52.23996-47.66197 83.36994-61.45595 31.65997-14.024 65.90995-17.899 102.88992-11.467 34.67997 6.452 63.26995 21.24799 85.85994 44.23397 21.94998 22.34798 40.20996 49.38096 54.70995 81.13794 14.28 31.25498 25.48998 65.78695 33.58998 103.60192 7.97 37.19097 15.17999 74.38195 21.62998 111.57192 6.42 37.00197 12.84 72.31194 19.25999 105.91192 6.27 32.82997 14.53999 61.05995 24.85998 84.65993 9.73 22.24999 21.89998 38.70997 36.83997 49.12997 13.55 9.45999 31.25998 10.32999 53.02996 3.92 30.31998-30.90998 54.72996-51.40997 73.05995-61.72996 12.16999-6.84 22.40998-10.8 30.62997-12.17 7.06-1.17999 12.97-.53999 17.76999 1.42 3.08 1.26 5.82 2.97 8.15 5.15zm171.26987-850.82935c-.41 1.118-.62 2.301-.62 3.492l3.4 983.65725c0 16.87999 5.34 29.64998 15.21 38.57997 9.67998 8.76 20.75997 13.55 33.19997 14.47 12.14999.9 24.09998-1.93 35.79997-8.68 11.95999-6.91 20.36998-17.61999 24.96998-32.34998.32-1.01.47-2.07.45-3.13-.75-48.35996-1.13-100.87992-1.13-157.54988 0-56.74995-.19-115.3899-.57-175.91986-.38-60.52896-.94-121.62591-1.7-183.28987-.76-61.64595-1.51-121.7799-2.27-180.39986-.76-58.67196-1.89-114.88291-3.41-168.63387-1.51-53.78896-3.4-102.65292-5.67999-146.5929-.03-.644-.13-1.283-.28-1.90799-2.09-8.339-7.32-15.55499-16.17999-21.28698-8.02-5.185-17.18998-7.845-27.55998-7.845-10.43999 0-20.71998 3.807-30.68997 11.872-9.08 7.34999-16.88999 19.08398-22.93999 35.51497zm1588.0788 521.3466c11.02-11.49199 21.36999-24.98198 31.06998-40.44997 14.03-22.37998 28.44998-44.75996 43.23997-67.13995 15.13999-22.89798 31.63998-43.26796 49.48996-61.12095 18.93999-18.93699 41.57997-30.45998 67.67995-34.53497 52.65996-9.574 97.29993-3.098 133.9899 18.84098 36.21997 21.64899 65.98995 52.69896 89.20993 93.24193 22.76999 39.74697 40.15997 85.84694 52.12996 138.3279 11.82 51.85696 20.20999 103.90492 25.15998 156.14788 4.96 52.18996 7.05 102.09992 6.29 149.72989-.77 47.60996-2.68 86.64993-5.73 117.1199-.11 1.16-.43 2.28-.92 3.32-10.40999 21.74999-24.99998 31.77998-42.49996 31.77998-17.48999 0-32.07998-10.03-42.48997-31.77997-.56-1.17-.88-2.44-.96-3.73-2.26-39.21997-5.65-82.00994-10.18-128.3799-4.51999-46.29997-10.53998-92.40994-18.06998-138.3399-7.51-45.82997-16.51999-89.21993-27.03998-130.1689-10.38999-40.41497-22.58998-74.53795-36.67997-102.34693-13.35999-26.36698-28.42998-45.00796-45.64997-55.55495-15.47998-9.474-32.93997-7.465-52.51996 4.536-22.56998 13.82998-47.26996 41.87496-74.56994 83.72993-28.12998 43.12897-59.40996 105.21592-93.90993 186.22486-.08.19-.17.37-.26.55-2.91 5.83-6.71 15.30999-11.45 28.42998-4.88999 13.53999-10.15998 28.77998-15.79998 45.70996-5.7 17.09-11.95999 35.12998-18.79998 54.11996-6.77 18.80999-12.98 36.85997-18.61999 54.16996-5.68 17.41999-10.79 32.93998-15.33999 46.57997-4.39 13.16999-7.33 23.04998-8.8 29.63997-.12.52-.28 1.04-.48 1.54-7.70999 19.27999-18.35998 29.19998-29.92997 31.59998-11.43 2.39-22.87998.41-34.30997-6.25-10.03-5.85-19.24999-13.76999-27.59998-23.78998-8.86-10.63999-13.93-20.08998-15.7-28.05998-.33999-1.54-.30999-3.14.08-4.66 6.74-26.20997 12.73-55.41995 17.97-87.60993 5.25-32.26997 9.36999-69.03995 12.36999-110.30991 3.01-41.34297 4.13-88.13794 3.38-140.3819-.75-52.31096-4.52-111.58291-11.29-177.81786-.19-1.829.13-3.674.92-5.332 10.19-21.30698 21.57999-32.05198 31.76998-34.36797 11.17999-2.541 22.52998.468 33.70997 10.12499 9.13 7.881 17.73999 19.41898 25.61998 34.76697 7.34 14.288 13.9 28.76898 19.68999 43.44197 5.82 14.74199 10.46999 28.51598 13.95999 41.31797.7 2.54 1.32 4.919 1.87 7.135zm-1260.43904 469.29265c-45.43997-18.81999-81.21994-43.59997-107.46992-74.15995-26.30998-30.62997-44.73997-64.20995-55.34996-100.72992-10.55-36.33997-14.07999-74.42994-10.56-114.28691 3.48-39.54797 12.79-78.12894 27.90999-115.73892 15.06999-37.49597 35.16997-72.86794 60.28995-106.11092 25.18998-33.31797 53.85996-61.78595 86.01994-85.41793 32.32997-23.76398 67.77995-41.29597 106.34992-52.59396 38.82997-11.373 79.02994-13.941 120.6799-7.653 35.51998 5.652 66.02996 22.35899 91.46994 50.21697 24.64998 26.99898 44.25996 60.42495 58.73995 100.33692 14.28 39.36297 23.36998 82.58094 27.22998 129.6629 3.85 46.99997 1.73 93.42293-6.36 139.2649-8.10999 45.98996-22.03998 88.68993-41.74996 128.1099-20.00999 40.01997-46.33997 72.36995-78.90994 97.08993-32.80998 24.89998-72.49995 39.61997-119.13991 43.96996-46.01997 4.29-99.08993-6.22-159.14988-31.95997zm642.41951 0c-45.43996-18.81999-81.21994-43.59997-107.46992-74.15995-26.30998-30.62997-44.73996-64.20995-55.33995-100.72992-10.55-36.33997-14.08-74.42994-10.57-114.28691 3.49-39.54797 12.79-78.12894 27.90998-115.73892 15.08-37.49597 35.17998-72.86794 60.29996-106.11092 25.17998-33.31797 53.85996-61.78595 86.00993-85.41793 32.33998-23.76398 67.78995-41.29597 106.35992-52.59396 38.82997-11.373 79.01994-13.941 120.66991-7.653 35.52997 5.652 66.03995 22.35899 91.47993 50.21697 24.64998 26.99898 44.25997 60.42495 58.73996 100.33692 14.27999 39.36297 23.36998 82.58094 27.22998 129.6629 3.85 46.99997 1.73 93.42293-6.36 139.2649-8.12 45.98996-22.03998 88.68993-41.74997 128.1099-20.00998 40.01997-46.33996 72.36995-78.90994 97.08993-32.80997 24.89998-72.49994 39.61997-119.1399 43.96996-46.01997 4.29-99.09993-6.22-159.15989-31.95997zM6968.3578 276.0543c-1.1-3.399-3.7-6.152-7.41999-8.557-4.84-3.135-10.41999-4.636-16.68999-4.636-6.2 0-12.17999 2.622-18.09998 7.417-6.5 5.259-11.73 13.762-16.13999 25.24198l3.4 981.84726c0 10.31 2.6 18.33999 8.62 23.77998 6.20999 5.62 13.27998 8.76 21.25998 9.36 8.26999.61 16.35998-1.47 24.32998-6.07 7.31-4.21 12.36999-10.78 15.39999-19.52998-.75-47.98997-1.12-100.04993-1.12-156.16989 0-56.70995-.19-115.30991-.56-175.79486-.38-60.48896-.95-121.54591-1.7-183.16987-.76-61.64195-1.52-121.7709-2.27-180.38686-.76-58.56596-1.89-114.67491-3.4-168.32887-1.5-53.15996-3.37-101.49493-5.61-145.0029zm173.57988 0c-1.1-3.399-3.69-6.152-7.41-8.557-4.84-3.135-10.42-4.636-16.68999-4.636-6.21 0-12.17999 2.622-18.09998 7.417-6.5 5.259-11.74 13.762-16.14 25.24198l3.39 981.84726c0 10.31 2.61 18.33999 8.63 23.77998 6.2 5.62 13.27999 8.76 21.25998 9.36 8.27.61 16.36-1.47 24.31999-6.07 7.31-4.21 12.36999-10.78 15.39998-19.52998-.74-47.98997-1.11-100.04993-1.11-156.16989 0-56.70995-.19-115.30991-.57-175.79486-.37-60.48896-.94-121.54591-1.7-183.16987-.75-61.64195-1.51-121.7709-2.27-180.38686-.75-58.56596-1.88999-114.67491-3.39999-168.32887-1.49-53.15996-3.36-101.49493-5.61-145.0029zm-1474.8589 611.05154c32.78998-28.61098 66.40996-46.87097 100.71993-54.98596 39.23997-9.282 76.29994-8.777 111.17992 1.375 34.64997 10.08599 66.35995 27.64098 95.10993 52.71196 28.56997 24.91798 51.24996 53.42596 68.07995 85.50393 16.88998 32.18698 26.89997 66.10695 30.03997 101.73693 3.2 36.27997-3.42 70.20994-19.80998 101.79992-16.27999 31.37997-43.34997 58.53995-81.47994 81.19994-37.32997 22.19998-87.83993 36.60997-151.58989 42.86996-27.29998 2.78-50.99996 5-71.08994 6.66-20.60999 1.71-40.05997 1.84-58.32996.42-18.53999-1.44-37.47997-5.33-56.80996-11.68-18.96998-6.22999-40.84997-15.83998-65.62995-28.87997-2.81-1.47-4.75-4.19-5.23-7.32-5.32999-34.52997-9.70999-71.83994-13.12998-111.92991-3.41-39.95997-6.26-81.15994-8.53-123.6199-2.28-42.45897-3.79-85.47694-4.55-129.0499-.76-43.51098-1.14-86.18994-1.14-128.03791 0-41.85797.38-82.05394 1.14-120.58691.76-38.56197 1.89-74.48795 3.41-107.77892.03-.637.12-1.27.27-1.889 3.13-12.99999 11.18-21.65098 24.23999-25.85598 10.86999-3.498 22.58998-4.353 35.19997-2.445 12.24999 1.856 23.43998 5.739 33.57997 11.614 12.52 7.25499 18.62999 16.35998 19.67999 26.28797.05.506.07 1.016.04 1.524-1.51 31.47298-2.64 62.25596-3.39 92.34793-.75 29.95198-.57 59.49096.56 88.61794 1.12 29.08597 3.37 58.30895 6.75 87.66993 2.72 23.63898 6.28 47.54596 10.70999 71.71995zm992.55926 378.53171c-5.84-3.89-11.48-11.03-17.31999-21.08998-6.7-11.53-13.38999-24.16999-20.07998-37.92998-6.79-13.95998-13.58-28.10997-20.37999-42.44996-7.08-14.97-14.57999-27.94998-22.44998-38.97997-8.51-11.9-17.51999-20.51999-26.87998-26.04998-11.32-6.69-23.67998-6.83-37.05997.37-1.57.85-2.88 2.1-3.81 3.62-15.05999 24.84997-30.29998 48.93996-45.73996 72.27994-15 22.68998-31.45998 42.10997-49.38997 58.20995-17.37998 15.61-37.24997 26.60998-59.59995 32.99998-22.31999 6.37-48.34997 5.46-78.10994-2.33-28.79998-7.73-52.21996-22.82998-70.15995-45.34996-18.49999-23.20999-32.24998-50.79997-41.31997-82.71994-9.21-32.44998-13.79999-68.03995-13.79999-106.75992 0-38.98097 4.27-77.78094 12.81-116.39591 8.54998-38.63497 20.98998-75.78495 37.33996-111.44792 16.19-35.32397 35.65998-65.69495 58.47996-91.08393 22.45998-24.99598 47.97996-43.85797 76.59994-56.53696 28.08998-12.44899 58.50996-15.75999 91.23993-10.069 30.24998 5.628 55.35996 18.44 75.12995 38.56698 20.39998 20.76598 37.30997 45.92097 50.78996 75.43094 13.70999 30.00998 24.43998 63.17396 32.21997 99.48293 7.92 36.93297 15.08 73.86594 21.48999 110.79991 6.43 37.12298 12.86999 72.53295 19.30998 106.24292 6.59 34.48998 15.34 64.12996 26.18998 88.92994 11.45 26.16998 26.13998 45.24996 43.71997 57.51995 18.48999 12.9 42.71997 15.33 72.81994 5.87 1.58-.49 3.01-1.37 4.16-2.55 29.34998-30.08998 52.73996-50.19996 70.35995-60.09995 8.15-4.59 15.17999-7.72 21.11998-9.24 4.06-1.05 7.35-1.48 9.9-.44 4.83 1.98 5.26 7.53 4.6 15.45-1.04 12.47998-5.67 26.31997-13.65 41.57996-8.3 15.86999-19.68998 31.36998-34.11997 46.51997-14.17 14.87998-30.26998 26.22998-48.33997 34.01997-17.73998 7.65-37.21997 10.19-58.42995 7.76-21.40999-2.46-43.55997-13.78-66.71995-33.42998l-.92-.7zm2465.44814 12.35c2.91-29.76999 4.72-67.65996 5.46-113.66992.75-46.92997-1.32-96.09993-6.2-147.5199-4.87-51.38895-13.12999-102.58491-24.74998-153.59388-11.49-50.38496-28.12998-94.67092-49.98996-132.8309-21.39999-37.36197-48.73997-66.06595-82.10994-86.01693-32.88998-19.65999-72.95995-24.90898-120.38991-16.28799-22.05998 3.447-41.01997 13.102-56.87996 28.95798-16.93999 16.93999-32.57997 36.27997-46.93996 58.00796-14.71 22.24498-29.03998 44.49096-42.98997 66.73695-14.56999 23.23798-30.54998 42.31396-47.87996 57.28095-2.96 2.557-7.14 3.153-10.7 1.525-3.56-1.628-5.84-5.181-5.84-9.093 0-3.38099-1.70999-10.60698-4.74999-21.76198-3.32-12.15799-7.74-25.23598-13.26999-39.23597-5.55-14.06799-11.84999-27.95098-18.87998-41.64996-6.49-12.637-13.39-22.27799-20.89999-28.76698-5.47-4.718-10.73999-7-16.20999-5.759-2.45.558-4.67 2.587-7.11999 5.432-3.3 3.817-6.54 9.02999-9.82 15.58699 6.66 65.73995 10.36 124.6399 11.11 176.70886.76 52.89196-.39 100.26493-3.43 142.1199-3.05 41.92996-7.25 79.28994-12.57999 112.06991-5.18 31.79998-11.08 60.72995-17.68999 86.79993 1.68 5.13 5.45 10.9 10.96 17.51 6.77 8.11999 14.18999 14.57998 22.31998 19.31998 6.72 3.93 13.41999 5.36 20.14998 3.96 6.46-1.35 10.86-8.16 15.16-18.77 1.62-7.01999 4.65999-17.27998 9.15999-30.76997 4.53-13.58999 9.62999-29.07998 15.29998-46.44996 5.7-17.48999 11.97-35.73998 18.80999-54.74996 6.78-18.82999 12.99999-36.71997 18.63999-53.65996 5.71-17.10999 11.02999-32.49998 15.96998-46.18997 5.02-13.88999 9.11-23.97298 12.22-30.26797 35.04997-82.24394 66.88994-145.2539 95.45992-189.06286 29.42998-45.12797 56.52996-74.94494 80.85994-89.85593 27.31998-16.744 51.82996-17.75999 73.41995-4.541 19.83998 12.144 37.66997 33.21197 53.04996 63.57295 14.64998 28.91898 27.40998 64.38095 38.20997 106.40992 10.65999 41.49597 19.79998 85.46594 27.40998 131.9149 7.6 46.34997 13.67999 92.88993 18.23998 139.6299 4.47 45.84996 7.84 88.22993 10.12 127.1199 6.08999 12 13.56998 18.70999 23.59998 18.70999 10.08999 0 17.58998-6.77 23.68998-18.86999zm-1725.4887-15.54c-42.25997-17.47998-75.64994-40.33997-100.04992-68.74995-24.36999-28.36997-41.48997-59.44995-51.30996-93.27993-9.87-33.99997-13.14-69.64994-9.85-106.94891 3.31-37.60098 12.17-74.27895 26.53998-110.03592 14.43-35.87297 33.65998-69.70795 57.69996-101.51292 23.97998-31.72998 51.27996-58.85496 81.89994-81.36094 30.43997-22.37399 63.81995-38.87897 100.12992-49.51597 36.05997-10.56199 73.38995-12.91099 111.98992-7.084 30.95997 4.925 57.54995 19.607 79.76994 43.93898 22.99998 25.18998 41.19997 56.43395 54.70996 93.67193 13.70999 37.78597 22.38998 79.28094 26.09998 124.4769 3.71 45.27597 1.67 89.99593-6.12 134.1609-7.77 44.01997-21.07998 84.89994-39.94997 122.6299-18.55999 37.11998-42.89997 67.17996-73.10994 90.10994-29.96998 22.74998-66.29995 36.00997-108.90992 39.98997-43.22997 4.03-93.00993-6.26-149.42989-30.43998l-.11-.05zm642.41952 0c-42.24997-17.47998-75.63995-40.33997-100.04993-68.74995-24.35998-28.36997-41.47997-59.44995-51.29996-93.27993-9.87-33.99997-13.14999-69.64994-9.86-106.94891 3.32-37.60098 12.17-74.27895 26.54999-110.03592 14.41999-35.87297 33.65997-69.70795 57.69995-101.51292 23.97999-31.72998 51.27997-58.85496 81.89994-81.36094 30.43998-22.37399 63.81995-38.87897 100.12993-49.51597 36.05997-10.56199 73.38994-12.91099 111.98991-7.084 30.94998 4.925 57.54996 19.607 79.76994 43.93898 22.99999 25.18998 41.19997 56.43395 54.70996 93.67193 13.7 37.78597 22.38998 79.28094 26.08998 124.4769 3.71 45.27597 1.68 89.99593-6.12 134.1609-7.76999 44.01997-21.06998 84.89994-39.93996 122.6299-18.55999 37.11998-42.90997 67.17996-73.10995 90.10994-29.96998 22.74998-66.29995 36.00997-108.90992 39.98997-43.22996 4.03-93.00993-6.26-149.42988-30.43998l-.12-.05zM5632.4288 546.7151c-.72-4.174-4.34-7.351-9.72999-10.47199-8.01-4.642-16.86999-7.678-26.54998-9.144-9.33-1.413-18.01998-.883-26.06998 1.707-5.56 1.792-9.16 5.322-10.71 10.675-1.47999 32.83197-2.59999 68.23495-3.33999 106.20592-.76 38.40597-1.14 78.47094-1.14 120.1929 0 41.73398.38 84.29694 1.14 127.68891.75 43.32997 2.26 86.10694 4.52 128.3289 2.26 42.23997 5.09 83.22994 8.49 122.97991 3.21999 37.68997 7.27999 72.88995 12.20998 105.58992 21.78999 11.26 41.14997 19.67999 58.09996 25.24998 17.72999 5.83 35.09997 9.42 52.10996 10.74 17.26999 1.35 35.64997 1.2 55.11996-.41 19.99998-1.66 43.56997-3.87 70.75994-6.63 60.26996-5.91 108.08992-19.17999 143.3599-40.15997 34.48997-20.49998 59.21995-44.82997 73.94994-73.21994 14.61999-28.18998 20.48999-58.46996 17.63999-90.82994-2.91-32.99997-12.19-64.39995-27.82998-94.20593-15.68999-29.91597-36.86997-56.48395-63.51995-79.72193-26.46998-23.08499-55.63996-39.29498-87.54994-48.58197-31.67997-9.221-65.34995-9.546-100.98992-1.115-35.87997 8.488-70.76995 29.33298-104.83992 62.22396-2.63 2.541-6.44 3.442-9.93 2.349-3.49-1.093-6.10999-4.005-6.81999-7.594-6.11-30.71598-10.88-61.01395-14.30999-90.89293-3.43-29.86598-5.72-59.59296-6.86-89.17993-1.15-29.54598-1.34-59.50996-.58-89.89194.75-29.94797 1.88-60.57595 3.37-91.88193zm15.14 553.17259c13.18998-52.14997 29.57997-92.78993 48.95996-122.00191 19.95998-30.08698 41.44996-51.27696 64.19995-63.83695 23.53998-12.994 47.49996-17.891 71.86994-14.869 23.73999 2.944 46.07997 10.883 66.99995 23.83899 20.53999 12.71799 39.10997 28.89298 55.69996 48.54796 16.63999 19.71899 29.09998 40.32097 37.41997 61.78096 8.47 21.83998 12.25 43.24996 11.45 64.19995-.86 22.23998-9.01 41.18997-24.34999 56.78995-18.82998 19.51999-41.36997 36.46998-67.63995 50.81997-26.01998 14.20999-52.61996 25.13998-79.79994 32.80997-27.39998 7.74-54.02996 11.59-79.85994 11.59-26.84998 0-49.58996-5.2-68.29994-15.32-19.60999-10.60999-33.33998-27.23998-41.01997-50.02996-7.32-21.70998-6.15-49.83996 4.37-84.31993zm19.33998 5.12c12.51999-49.58997 27.86998-88.30994 46.28996-116.06692 17.85999-26.92498 36.82998-46.14197 57.19996-57.38296 19.56999-10.80799 39.46997-15.04399 59.73996-12.52999 20.87998 2.59 40.51996 9.597 58.92995 20.99499 18.78999 11.63699 35.76997 26.45898 50.94996 44.44396 15.12 17.92099 26.48998 36.61097 34.04998 56.11096 7.42 19.12999 10.81999 37.84997 10.10999 56.19996-.65 17.04998-6.87 31.58997-18.68999 43.59996-17.54998 18.2-38.49997 33.89998-62.89995 47.22997-24.65998 13.46999-49.86996 23.83998-75.63994 31.10998-25.53998 7.20999-50.34996 10.83999-74.42995 10.83999-23.07998 0-42.69996-4.21-58.77995-12.91-15.18-8.20999-25.64998-21.19998-31.58998-38.81996-6.28-18.63999-4.44-42.72997 4.63-72.33995l.13-.48zm1723.4387 80.90993c51.62996 33.36998 98.03992 46.77997 138.9499 41.21997 41.29996-5.61 75.97994-23.27998 104.04991-52.95996 27.45998-29.02998 48.13997-66.05995 61.86996-111.16992 13.55999-44.57996 19.37998-90.12293 17.43998-136.6379-1.95-46.72396-12.08999-90.13293-30.38997-130.2379-18.71999-41.02096-47.21997-71.85994-85.45994-92.56893-23.01998-11.93999-49.70996-11.81599-80.18994 1.31-28.27998 12.173-56.00995 31.74398-83.09993 58.84096-26.66998 26.66498-50.83997 58.53395-72.47995 95.63293-21.75998 37.30897-36.50997 75.59694-44.27997 114.84991-7.87999 39.75097-6.86 78.13094 2.98 115.13091 10.02 37.67997 33.31998 69.85995 70.19995 96.31993l.41.27zm642.41951 0c51.62996 33.36998 98.04993 46.77997 138.9499 41.21997 41.30997-5.61 75.98994-23.27998 104.05992-52.95996 27.45998-29.02998 48.12996-66.05995 61.86995-111.16992 13.56-44.57996 19.37999-90.12293 17.43999-136.6379-1.95-46.72396-12.09-90.13293-30.38998-130.2379-18.71998-41.02096-47.22996-71.85994-85.45993-92.56893-23.01998-11.93999-49.70996-11.81599-80.18994 1.31-28.27998 12.173-56.00996 31.74398-83.10994 58.84096-26.65998 26.66498-50.82996 58.53395-72.46994 95.63293-21.76999 37.30897-36.51998 75.59694-44.28997 114.84991-7.87 39.75097-6.86 78.13094 2.98 115.13091 10.02999 37.67997 33.32997 69.85995 70.20994 96.31993l.4.27zm11.07-16.65999c46.60996 30.07998 88.23993 43.08997 125.1899 38.06997 36.59997-4.98 67.34995-20.58998 92.21993-46.88996 25.47998-26.93998 44.51997-61.38995 57.25996-103.24992 12.90999-42.40997 18.43998-85.73594 16.58999-129.9859-1.83-44.03997-11.35-84.96594-28.59998-122.76691-16.82999-36.88497-42.40997-64.66495-76.62995-83.20194-17.97998-9.323-38.93997-8.313-62.91995 2.009-26.17998 11.274-51.76996 29.52098-76.85994 54.61396-25.52998 25.52498-48.62996 56.05596-69.34995 91.56793-20.58998 35.30297-34.57997 71.51695-41.93997 108.65792-7.24999 36.63597-6.38 72.00594 2.69 106.10592 8.87 33.34997 29.74998 61.62995 62.34996 85.06993zm-642.42952 0c46.60996 30.07998 88.24993 43.08997 125.1899 38.06997 36.59998-4.98 67.34995-20.58998 92.21994-46.88996 25.48998-26.93998 44.51996-61.38995 57.25995-103.24992 12.91-42.40997 18.43999-85.73594 16.59999-129.9859-1.84-44.03997-11.36-84.96594-28.60998-122.76691-16.82999-36.88497-42.39997-64.66495-76.61994-83.20194-17.97999-9.323-38.94997-8.313-62.91995 2.009-26.18998 11.274-51.77996 29.52098-76.86995 54.61396-25.52998 25.52498-48.62996 56.05596-69.33994 91.56793-20.59999 35.30297-34.58998 71.51695-41.94997 108.65792-7.25 36.63597-6.37 72.00594 2.7 106.10592 8.86999 33.34997 29.73997 61.62995 62.33995 85.06993zm-1173.21912-25.98998c21.51999 33.09998 44.56997 51.54996 68.15995 56.51996 24.03999 5.06 47.46997.75 70.23995-13.16999 21.39998-13.06999 41.66997-32.41998 60.68995-58.17996 18.56-25.12998 34.41998-52.00996 47.55997-80.61994 13.16999-28.64997 22.83998-56.73495 29.03998-84.22993 6.4-28.42898 7.83-51.86396 4.63-70.28295l-.06-.326c-3.75-17.97399-6.74-34.07597-8.99-48.30596-2.31-14.636-4.82-27.73198-7.52-39.28697-2.74-11.752-5.86999-22.52199-9.39999-32.31498-3.62-10.059-8.64-20.32498-15.06999-30.78498-.72-1.164-1.67-2.168-2.79-2.952-32.86997-23.00798-63.61995-31.54997-91.96992-26.61997-28.08998 4.885-53.36996 18.62598-75.75995 41.41997-21.60998 21.99998-39.73997 50.24796-54.27996 84.81893-14.26999 33.96098-24.69998 69.46395-31.25997 106.51092-6.57 37.13497-8.69 73.11395-6.37 107.92392 2.38 35.65997 10.03 65.34995 22.70999 89.12993l.44.75zm223.31984-388.7207c-26.98998-18.50399-52.01996-26.18998-75.36995-22.12799-24.10998 4.192-45.70996 16.16699-64.91995 35.72898-19.99998 20.35698-36.65997 46.56796-50.10996 78.55694-13.70999 32.59997-23.70998 66.68295-29.99998 102.24692-6.29 35.47697-8.33 69.84595-6.11 103.10592 2.15 32.21998 8.8 59.13996 20.2 80.67994 17.73998 27.17998 35.82996 43.38997 55.26995 47.47996 19.06999 4.02 37.61997.38 55.68996-10.65999 19.44998-11.87999 37.74997-29.59997 55.02996-52.99996 17.74998-24.02998 32.90997-49.72996 45.47996-77.08994 12.55-27.30998 21.78999-54.06896 27.68998-80.27594 5.69-25.21598 7.29-45.98996 4.46-62.34495-3.79-18.24499-6.83-34.59698-9.12-49.05396-2.22-14.106-4.63-26.72698-7.22999-37.86298-2.55-10.93899-5.47-20.96898-8.75-30.08497-2.98-8.28-7.05999-16.709-12.20998-25.29798z" fill="#fff"/>
355
+ </g>
356
+ </svg>
357
+ </span>
358
+ <br />
359
 
360
+ <span style="width: 34px; top: -5px;"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-facebook fa-w-16 fa-2x"><path fill="#475e8f" d="M504 256C504 119 393 8 256 8S8 119 8 256c0 123.78 90.69 226.38 209.25 245V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.28c-30.8 0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.31 482.38 504 379.78 504 256z" class=""></path></svg></span>
 
 
 
 
 
 
 
 
 
 
 
361
 
362
+ <span class="sbi-sb-plus"><svg aria-hidden="true" focusable="false" data-prefix="fal" data-icon="plus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-plus fa-w-12 fa-2x"><path fill="currentColor" d="M376 232H216V72c0-4.42-3.58-8-8-8h-32c-4.42 0-8 3.58-8 8v160H8c-4.42 0-8 3.58-8 8v32c0 4.42 3.58 8 8 8h160v160c0 4.42 3.58 8 8 8h32c4.42 0 8-3.58 8-8V280h160c4.42 0 8-3.58 8-8v-32c0-4.42-3.58-8-8-8z" class=""></path></svg></span>
363
 
364
+ <span><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="instagram" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-instagram fa-w-14 fa-2x"><path fill="#e15073" d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" class=""></path></svg></span>
365
 
366
+ <span class="sbi-sb-plus"><svg aria-hidden="true" focusable="false" data-prefix="fal" data-icon="plus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-plus fa-w-12 fa-2x"><path fill="currentColor" d="M376 232H216V72c0-4.42-3.58-8-8-8h-32c-4.42 0-8 3.58-8 8v160H8c-4.42 0-8 3.58-8 8v32c0 4.42 3.58 8 8 8h160v160c0 4.42 3.58 8 8 8h32c4.42 0 8-3.58 8-8V280h160c4.42 0 8-3.58 8-8v-32c0-4.42-3.58-8-8-8z" class=""></path></svg></span>
367
 
368
+ <span style="top: -4px;"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-twitter fa-w-16 fa-2x"><path fill="#1a92dc" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z" class=""></path></svg></span>
369
 
370
+ <span class="sbi-sb-plus"><svg aria-hidden="true" focusable="false" data-prefix="fal" data-icon="plus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-plus fa-w-12 fa-2x"><path fill="currentColor" d="M376 232H216V72c0-4.42-3.58-8-8-8h-32c-4.42 0-8 3.58-8 8v160H8c-4.42 0-8 3.58-8 8v32c0 4.42 3.58 8 8 8h160v160c0 4.42 3.58 8 8 8h32c4.42 0 8-3.58 8-8V280h160c4.42 0 8-3.58 8-8v-32c0-4.42-3.58-8-8-8z" class=""></path></svg></span>
371
 
372
+ <span style="width: 35px; top: -5px;"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="youtube" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-youtube fa-w-18 fa-2x"><path fill="#f5413d" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z" class=""></path></svg></span>
373
+ </div>
 
 
374
 
375
+ <h1>Combine all your social media channels into one single wall.</h1>
376
+ <h2>Maximize your social content and get more followers.</h2>
377
 
378
+ <div style="text-align: center;">
379
+ <a href="https://smashballoon.com/social-wall/?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=sw-cta-1" target="_blank" class="cta button button-primary">Get the Social Wall plugin</a>
380
+ </div>
381
 
382
+ <div class="sbi-sw-info">
383
+ <div class="sbi-sw-features">
384
+ <p><span>A dash of Instagram</span>Add posts from your profile, public hashtag posts, or posts you're tagged in.</p>
385
+ <p><span>A sprinkle of Facebook</span>Include posts from your page or group timeline, or from your photos, videos, albums, and events pages.</p>
386
+ <p><span>A spoonful of Twitter</span>Add Tweets from any Twitter account, hashtag Tweets, mentions, and more.</p>
387
+ <p><span>And a dollop of YouTube</span>Embed videos from any public YouTube channel, playlists, searches, and more.</p>
388
+ <p><span>All in the same feed</span>Combine feeds from all of our Smash Balloon Pro plugins into one single wall feed, and show off all your social media content in one place.</p>
389
+ </div>
390
+ <a class="sbi-sw-screenshot" href="https://smashballoon.com/social-wall/demo?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=sw-demo" target="_blank">
391
+ <span class="cta">View Demo</span>
392
 
393
+ <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/sw-screenshot.png' ); ?>" alt="Smash Balloon Social Wall plugin screenshot showing Facebook, Instagram, Twitter, and YouTube posts combined into one wall.">
394
+ </a>
395
+ </div>
396
 
397
+ <div class="sbi-sw-footer-cta">
398
+ <a href="https://smashballoon.com/social-wall/?utm_source=plugin-pro&utm_campaign=sbi&utm_medium=sw-cta-2" target="_blank"><span>🚀</span>Get Social Wall and Increase Engagement >></a>
399
+ </div>
400
 
401
+ </div>
402
 
403
  <?php
404
  }
405
 
406
  function sb_instagram_settings_page() {
 
 
 
 
 
 
407
  //Declare defaults
408
  $sb_instagram_settings_defaults = array(
409
+ 'sb_instagram_user_id' => '',
410
+ 'sb_instagram_preserve_settings' => '',
411
+ 'sb_instagram_cache_time' => 1,
412
+ 'sb_instagram_cache_time_unit' => 'hours',
413
+ 'sbi_caching_type' => 'page',
414
+ 'sbi_cache_cron_interval' => '12hours',
415
+ 'sbi_cache_cron_time' => '1',
416
+ 'sbi_cache_cron_am_pm' => 'am',
417
+ 'sb_instagram_width' => '100',
418
+ 'sb_instagram_width_unit' => '%',
419
+ 'sb_instagram_feed_width_resp' => false,
420
+ 'sb_instagram_height' => '',
421
+ 'sb_instagram_num' => '20',
422
+ 'sb_instagram_height_unit' => '',
423
+ 'sb_instagram_cols' => '4',
424
+ 'sb_instagram_disable_mobile' => false,
425
+ 'sb_instagram_image_padding' => '5',
426
+ 'sb_instagram_image_padding_unit' => 'px',
427
+ 'sb_instagram_sort' => 'none',
428
+ 'sb_instagram_background' => '',
429
+ 'sb_instagram_show_btn' => true,
430
+ 'sb_instagram_btn_background' => '',
431
+ 'sb_instagram_btn_text_color' => '',
432
+ 'sb_instagram_btn_text' => __( 'Load More...', 'instagram-feed' ),
433
+ 'sb_instagram_image_res' => 'auto',
 
434
  //Header
435
+ 'sb_instagram_show_header' => true,
436
+ 'sb_instagram_header_size' => 'small',
437
+ 'sb_instagram_header_color' => '',
438
+ 'sb_instagram_custom_bio' => '',
439
+ 'sb_instagram_custom_avatar' => '',
440
  //Follow button
441
+ 'sb_instagram_show_follow_btn' => true,
442
+ 'sb_instagram_folow_btn_background' => '',
443
  'sb_instagram_follow_btn_text_color' => '',
444
+ 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
445
  //Misc
446
+ 'sb_instagram_custom_css' => '',
447
+ 'sb_instagram_custom_js' => '',
448
+ 'sb_instagram_cron' => 'no',
449
+ 'sb_instagram_backup' => true,
450
+ 'sb_ajax_initial' => false,
451
+ 'enqueue_css_in_shortcode' => false,
452
+ 'sb_instagram_ajax_theme' => false,
453
+ 'gdpr' => 'auto',
454
+ 'sb_instagram_disable_resize' => false,
455
+ 'sb_instagram_favor_local' => true,
456
+ 'sb_instagram_minnum' => 0,
457
+ 'disable_js_image_loading' => false,
458
+ 'enqueue_js_in_head' => false,
459
+ 'sb_instagram_disable_mob_swipe' => false,
460
+ 'custom_template' => false,
461
+ 'disable_admin_notice' => false,
462
+ 'enable_email_report' => true,
463
+ 'email_notification' => 'monday',
464
+ 'email_notification_addresses' => get_option( 'admin_email' ),
465
  );
466
  //Save defaults in an array
467
+ $options = wp_parse_args( get_option( 'sb_instagram_settings' ), $sb_instagram_settings_defaults );
468
  update_option( 'sb_instagram_settings', $options );
469
 
470
  //Set the page variables
471
+ $sb_instagram_user_id = $options['sb_instagram_user_id'];
472
+ $sb_instagram_preserve_settings = $options['sb_instagram_preserve_settings'];
473
+ $sb_instagram_ajax_theme = $options['sb_instagram_ajax_theme'];
474
+ $gdpr = $options['gdpr'];
475
+ $enqueue_js_in_head = $options['enqueue_js_in_head'];
476
+ $disable_js_image_loading = $options['disable_js_image_loading'];
477
+ $sb_instagram_disable_resize = $options['sb_instagram_disable_resize'];
478
+ $sb_instagram_favor_local = $options['sb_instagram_favor_local'];
479
+ $sb_instagram_minnum = $options['sb_instagram_minnum'];
480
+
481
+ $sb_instagram_cache_time = $options['sb_instagram_cache_time'];
482
+ $sb_instagram_cache_time_unit = $options['sb_instagram_cache_time_unit'];
483
  if ( $sb_instagram_cache_time_unit === 'days' ) {
484
  $sb_instagram_cache_time_unit = 'hours';
485
+ $sb_instagram_cache_time = 24;
486
  }
487
+ $sbi_caching_type = $options['sbi_caching_type'];
488
+ $sbi_cache_cron_interval = $options['sbi_cache_cron_interval'];
489
+ $sbi_cache_cron_time = $options['sbi_cache_cron_time'];
490
+ $sbi_cache_cron_am_pm = $options['sbi_cache_cron_am_pm'];
491
+
492
+ $sb_instagram_width = $options['sb_instagram_width'];
493
+ $sb_instagram_width_unit = $options['sb_instagram_width_unit'];
494
+ $sb_instagram_feed_width_resp = $options['sb_instagram_feed_width_resp'];
495
+ $sb_instagram_height = $options['sb_instagram_height'];
496
+ $sb_instagram_height_unit = $options['sb_instagram_height_unit'];
497
+ $sb_instagram_num = $options['sb_instagram_num'];
498
+ $sb_instagram_cols = $options['sb_instagram_cols'];
499
+ $sb_instagram_disable_mobile = $options['sb_instagram_disable_mobile'];
500
+ $sb_instagram_image_padding = $options['sb_instagram_image_padding'];
501
+ $sb_instagram_image_padding_unit = $options['sb_instagram_image_padding_unit'];
502
+ $sb_instagram_sort = $options['sb_instagram_sort'];
503
+ $sb_instagram_background = $options['sb_instagram_background'];
504
+ $sb_instagram_show_btn = $options['sb_instagram_show_btn'];
505
+ $sb_instagram_btn_background = $options['sb_instagram_btn_background'];
506
+ $sb_instagram_btn_text_color = $options['sb_instagram_btn_text_color'];
507
+ $sb_instagram_btn_text = $options['sb_instagram_btn_text'];
508
+ $sb_instagram_image_res = $options['sb_instagram_image_res'];
509
  //Header
510
+ $sb_instagram_show_header = $options['sb_instagram_show_header'];
511
+ $sb_instagram_header_size = $options['sb_instagram_header_size'];
512
+ $sb_instagram_show_bio = isset( $options['sb_instagram_show_bio'] ) ? $options['sb_instagram_show_bio'] : true;
513
+ $sb_instagram_custom_bio = $options['sb_instagram_custom_bio'];
514
+ $sb_instagram_custom_avatar = $options['sb_instagram_custom_avatar'];
515
+ $sb_instagram_header_color = $options['sb_instagram_header_color'];
516
  //Follow button
517
+ $sb_instagram_show_follow_btn = $options['sb_instagram_show_follow_btn'];
518
+ $sb_instagram_folow_btn_background = $options['sb_instagram_folow_btn_background'];
519
+ $sb_instagram_follow_btn_text_color = $options['sb_instagram_follow_btn_text_color'];
520
+ $sb_instagram_follow_btn_text = $options['sb_instagram_follow_btn_text'];
521
  //Misc
522
+ $sb_instagram_custom_css = $options['sb_instagram_custom_css'];
523
+ $sb_instagram_custom_js = $options['sb_instagram_custom_js'];
524
+ $sb_instagram_cron = $options['sb_instagram_cron'];
525
+ $sb_instagram_backup = $options['sb_instagram_backup'];
526
+ $sb_ajax_initial = $options['sb_ajax_initial'];
527
+ $enqueue_css_in_shortcode = $options['enqueue_css_in_shortcode'];
528
+ $sb_instagram_custom_template = $options['custom_template'];
529
+ $sb_instagram_disable_admin_notice = $options['disable_admin_notice'];
530
+ $sb_instagram_enable_email_report = $options['enable_email_report'];
531
+ $sb_instagram_email_notification = $options['email_notification'];
532
+ $sb_instagram_email_notification_addresses = $options['email_notification_addresses'];
533
+
534
  //Check nonce before saving data
535
+ if ( ! isset( $_POST['sb_instagram_settings_nonce'] ) ) {
536
+
537
  } else {
538
+ $nonce = isset( $_POST['sb_instagram_settings_nonce'] ) ? $_POST['sb_instagram_settings_nonce'] : false;
539
+ if ( ! wp_verify_nonce( $nonce, 'sb_instagram_saving_settings' ) ) {
540
+ ?>
541
+ <div id="sbi_admin" class="wrap">
542
+ <div class="sb_instagram_box" style="display: block;">
543
+ <div class="sb_instagram_box_setting" style="display: block;">
544
+
545
+ <?php
546
+ esc_html_e( 'Sorry your settings were not saved! Please refresh the page and try again.', 'instagram-feed' );
547
+ ?>
548
+ </div>
549
+ </div>
550
+ </div>
551
+ <?php
552
+ return;
553
+ }
554
  // See if the user has posted us some information. If they did, this hidden field will be set to 'Y'.
555
+ if ( isset( $_POST['sb_instagram_settings_hidden_field'] ) && $_POST['sb_instagram_settings_hidden_field'] === 'Y' ) {
556
 
557
+ if ( isset( $_POST['sb_instagram_configure_hidden_field'] ) && $_POST['sb_instagram_configure_hidden_field'] === 'Y' ) {
558
 
 
559
  $sb_instagram_user_id = array();
560
+ if ( isset( $_POST['sb_instagram_user_id'] ) ) {
561
+ if ( is_array( $_POST['sb_instagram_user_id'] ) ) {
562
+ foreach ( $_POST['sb_instagram_user_id'] as $user_id ) {
563
+ $sb_instagram_user_id[] = sbi_sanitize_instagram_ids( $user_id );
564
  }
565
  } else {
566
+ $sb_instagram_user_id[] = sbi_sanitize_instagram_ids( $_POST['sb_instagram_user_id'] );
567
  }
568
  }
569
+ $sb_instagram_preserve_settings = isset( $_POST['sb_instagram_preserve_settings'] );
570
+ isset( $_POST['sb_instagram_cache_time'] ) ? $sb_instagram_cache_time = (int) $_POST['sb_instagram_cache_time'] : $sb_instagram_cache_time = 1;
571
+ isset( $_POST['sb_instagram_cache_time_unit'] ) ? $sb_instagram_cache_time_unit = SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_cache_time_unit'], 'enum', array( 'minutes', 'hours', 'days' ) ) : $sb_instagram_cache_time_unit = 'hours';
572
+
573
+ isset( $_POST['sbi_caching_type'] ) ? $sbi_caching_type = SB_Instagram_Settings::sanitize_setting( $_POST['sbi_caching_type'], 'enum', array( 'page', 'background' ) ) : $sbi_caching_type = 'page';
574
+ isset( $_POST['sbi_cache_cron_interval'] ) ? $sbi_cache_cron_interval = SB_Instagram_Settings::sanitize_setting( $_POST['sbi_cache_cron_interval'], 'enum', array( '30mins', '1hour', '12hours', '24hours' ) ) : $sbi_cache_cron_interval = '1hour';
575
+ isset( $_POST['sbi_cache_cron_time'] ) ? $sbi_cache_cron_time = SB_Instagram_Settings::sanitize_setting( (string) $_POST['sbi_cache_cron_time'], 'enum', array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11' ) ) : $sbi_cache_cron_time = '1';
576
+ isset( $_POST['sbi_cache_cron_am_pm'] ) ? $sbi_cache_cron_am_pm = SB_Instagram_Settings::sanitize_setting( $_POST['sbi_cache_cron_am_pm'], 'enum', array( 'am', 'pm' ) ) : $sbi_cache_cron_am_pm = 'am';
577
+
578
+ $options['sb_instagram_user_id'] = $sb_instagram_user_id;
579
+ $options['sb_instagram_preserve_settings'] = $sb_instagram_preserve_settings;
 
580
  if ( $sb_instagram_cache_time_unit === 'days' ) {
581
  $sb_instagram_cache_time_unit = 'hours';
582
+ $sb_instagram_cache_time = 24;
583
+ }
 
 
 
584
 
585
+ $options['sb_instagram_cache_time'] = $sb_instagram_cache_time;
586
+ $options['sb_instagram_cache_time_unit'] = $sb_instagram_cache_time_unit;
 
 
587
 
588
+ $options['sbi_caching_type'] = $sbi_caching_type;
589
+ $options['sbi_cache_cron_interval'] = $sbi_cache_cron_interval;
590
+ $options['sbi_cache_cron_time'] = $sbi_cache_cron_time;
591
+ $options['sbi_cache_cron_am_pm'] = $sbi_cache_cron_am_pm;
592
 
593
  //Delete all SBI transients
594
  global $wpdb;
595
+ $table_name = $wpdb->prefix . 'options';
596
+ $wpdb->query(
597
+ "
598
  DELETE
599
  FROM $table_name
600
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
601
+ "
602
+ );
603
+ $wpdb->query(
604
+ "
605
  DELETE
606
  FROM $table_name
607
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
608
+ "
609
+ );
610
+ $wpdb->query(
611
+ "
612
  DELETE
613
  FROM $table_name
614
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
615
+ "
616
+ );
617
+ $wpdb->query(
618
+ "
619
  DELETE
620
  FROM $table_name
621
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
622
+ "
623
+ );
624
 
625
  if ( $sbi_caching_type === 'background' ) {
626
  delete_option( 'sbi_cron_report' );
633
 
634
  } //End config tab post
635
 
636
+ if ( isset( $_POST['sb_instagram_customize_hidden_field'] ) && $_POST['sb_instagram_customize_hidden_field'] === 'Y' ) {
637
 
638
  //Validate and sanitize width field
639
+ $safe_width = intval( $_POST['sb_instagram_width'] );
640
+ if ( ! $safe_width ) {
641
+ $safe_width = '';
642
+ }
643
+ if ( strlen( $safe_width ) > 4 ) {
644
+ $safe_width = substr( $safe_width, 0, 4 );
645
+ }
646
  $sb_instagram_width = $safe_width;
647
 
648
+ $sb_instagram_width_unit = isset( $_POST['sb_instagram_width_unit'] ) ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_width_unit'], 'enum', array( 'px', '%' ) ) : 'px';
649
+ $sb_instagram_feed_width_resp = isset( $_POST['sb_instagram_feed_width_resp'] );
650
 
651
  //Validate and sanitize height field
652
+ $safe_height = intval( $_POST['sb_instagram_height'] );
653
+ if ( ! $safe_height ) {
654
+ $safe_height = '';
655
+ }
656
+ if ( strlen( $safe_height ) > 4 ) {
657
+ $safe_height = substr( $safe_height, 0, 4 );
658
+ }
659
  $sb_instagram_height = $safe_height;
660
 
661
+ $sb_instagram_height_unit = isset( $_POST['sb_instagram_height_unit'] ) ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_height_unit'], 'enum', array( 'px', '%' ) ) : 'px';
662
 
663
  //Validate and sanitize number of photos field
664
  $safe_num = intval( sanitize_text_field( $_POST['sb_instagram_num'] ) );
665
+ if ( ! $safe_num ) {
666
+ $safe_num = '';
667
+ }
668
+ if ( strlen( $safe_num ) > 4 ) {
669
+ $safe_num = substr( $safe_num, 0, 4 );
670
+ }
671
  $sb_instagram_num = $safe_num;
672
 
673
+ $sb_instagram_cols = isset( $_POST['sb_instagram_cols'] ) ? SB_Instagram_Settings::sanitize_setting( (string) $_POST['sb_instagram_cols'], 'enum', array( '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11' ) ) : 'px';
674
+ $sb_instagram_disable_mobile = isset( $_POST['sb_instagram_disable_mobile'] );
675
 
676
  //Validate and sanitize padding field
677
+ $safe_padding = intval( $_POST['sb_instagram_image_padding'] );
678
+ if ( ! $safe_padding ) {
679
+ $safe_padding = '';
680
+ }
681
+ if ( strlen( $safe_padding ) > 4 ) {
682
+ $safe_padding = substr( $safe_padding, 0, 4 );
683
+ }
684
  $sb_instagram_image_padding = $safe_padding;
685
 
686
+ $sb_instagram_image_padding_unit = isset( $_POST['sb_instagram_image_padding_unit'] ) ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_image_padding_unit'], 'enum', array( 'px', '%' ) ) : 'px';
687
+ $sb_instagram_sort = isset( $_POST['sb_instagram_sort'] ) ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_sort'], 'enum', array( 'none', 'random', 'likes' ) ) : 'none';
688
+ $sb_instagram_background = isset( $_POST['sb_instagram_background'] ) && $_POST['sb_instagram_background'] !== '#' ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_background'], 'color', 'any' ) : '';
689
+ $sb_instagram_show_btn = isset( $_POST['sb_instagram_show_btn'] );
690
+ $sb_instagram_btn_background = isset( $_POST['sb_instagram_btn_background'] ) && $_POST['sb_instagram_btn_background'] !== '#' ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_btn_background'], 'color', 'any' ) : '';
691
+ $sb_instagram_btn_text_color = isset( $_POST['sb_instagram_btn_text_color'] ) && $_POST['sb_instagram_btn_text_color'] !== '#' ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_btn_text_color'], 'color', 'any' ) : '';
692
+ $sb_instagram_btn_text = isset( $_POST['sb_instagram_btn_text'] ) ? sanitize_text_field( wp_unslash( $_POST['sb_instagram_btn_text'] ) ) : __( 'Load More...', 'instagram-feed' );
693
+ $sb_instagram_image_res = isset( $_POST['sb_instagram_image_res'] ) ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_image_res'], 'enum', array( 'auto', 'thumb', 'medium', 'full' ) ) : 'auto';
694
  //Header
695
+ $sb_instagram_show_header = isset( $_POST['sb_instagram_show_header'] );
696
+ $sb_instagram_show_bio = isset( $_POST['sb_instagram_show_bio'] );
697
  if ( function_exists( 'sanitize_textarea_field' ) ) {
698
+ isset( $_POST['sb_instagram_custom_bio'] ) ? $sb_instagram_custom_bio = sanitize_textarea_field( wp_unslash( $_POST['sb_instagram_custom_bio'] ) ) : $sb_instagram_custom_bio = '';
699
  } else {
700
+ isset( $_POST['sb_instagram_custom_bio'] ) ? $sb_instagram_custom_bio = sanitize_text_field( wp_unslash( $_POST['sb_instagram_custom_bio'] ) ) : $sb_instagram_custom_bio = '';
701
+ }
702
+ isset( $_POST['sb_instagram_custom_avatar'] ) && sbi_is_url( $_POST['sb_instagram_custom_avatar'] ) ? $sb_instagram_custom_avatar = esc_url( $_POST['sb_instagram_custom_avatar'] ) : $sb_instagram_custom_avatar = '';
703
+ $sb_instagram_header_size = 'small';
704
+ if ( isset( $_POST['sb_instagram_header_size'] ) ) {
705
+ $sb_instagram_header_size = SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_header_size'], 'enum', array( 'small', 'medium', 'large' ) );
706
  }
 
 
707
 
708
+ $sb_instagram_header_color = isset( $_POST['sb_instagram_header_color'] ) && $_POST['sb_instagram_header_color'] !== '#' ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_header_color'], 'color', 'any' ) : '';
709
  //Follow button
710
+ $sb_instagram_show_follow_btn = isset( $_POST['sb_instagram_show_follow_btn'] );
711
+ $sb_instagram_folow_btn_background = isset( $_POST['sb_instagram_folow_btn_background'] ) && $_POST['sb_instagram_folow_btn_background'] !== '#' ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_folow_btn_background'], 'color', 'any' ) : '';
712
+ $sb_instagram_follow_btn_text_color = isset( $_POST['sb_instagram_follow_btn_text_color'] ) && $_POST['sb_instagram_follow_btn_text_color'] !== '#' ? SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_follow_btn_text_color'], 'color', 'any' ) : '';
713
+ $sb_instagram_follow_btn_text = isset( $_POST['sb_instagram_follow_btn_text'] ) ? sanitize_text_field( wp_unslash( $_POST['sb_instagram_follow_btn_text'] ) ) : __( 'Follow on Instagram', 'instagram-feed' );
714
  //Misc
715
+ if ( preg_match( '#</?\w+#', $_POST['sb_instagram_custom_css'] ) ) {
716
  $sb_instagram_custom_css = '';
717
  } else {
718
+ $sb_instagram_custom_css = $_POST['sb_instagram_custom_css'];
719
+ }
720
+ $sb_instagram_custom_js = $_POST['sb_instagram_custom_js'];
721
+ $sb_instagram_ajax_theme = isset( $_POST['sb_instagram_ajax_theme'] );
722
+ isset( $_POST['gdpr'] ) ? $gdpr = SB_Instagram_Settings::sanitize_setting( $_POST['gdpr'], 'enum', array( 'auto', 'yes', 'no' ) ) : $gdpr = 'auto';
723
+ $enqueue_js_in_head = isset( $_POST['enqueue_js_in_head'] );
724
+ $disable_js_image_loading = isset( $_POST['disable_js_image_loading'] );
725
+ $sb_instagram_disable_resize = isset( $_POST['sb_instagram_disable_resize'] );
726
+ $sb_instagram_favor_local = isset( $_POST['sb_instagram_favor_local'] );
727
+ ! empty( $_POST['sb_instagram_minnum'] ) ? $sb_instagram_minnum = min( 100, (int) $_POST['sb_instagram_minnum'] ) : $sb_instagram_minnum = '';
728
+
729
+ if ( isset( $_POST['sb_instagram_cron'] ) ) {
730
+ $sb_instagram_cron = SB_Instagram_Settings::sanitize_setting( $_POST['sb_instagram_cron'], 'enum', array( 'unset', 'yes', 'no' ) );
731
+ }
732
+ $sb_instagram_backup = isset( $_POST['sb_instagram_backup'] );
733
+ $sb_ajax_initial = isset( $_POST['sb_ajax_initial'] );
734
+ $enqueue_css_in_shortcode = isset( $_POST['enqueue_css_in_shortcode'] );
735
+
736
+ $options['sb_instagram_width'] = $sb_instagram_width;
737
+ $options['sb_instagram_width_unit'] = $sb_instagram_width_unit;
738
+ $options['sb_instagram_feed_width_resp'] = $sb_instagram_feed_width_resp;
739
+ $options['sb_instagram_height'] = $sb_instagram_height;
740
+ $options['sb_instagram_height_unit'] = $sb_instagram_height_unit;
741
+ $options['sb_instagram_num'] = $sb_instagram_num;
742
+ $options['sb_instagram_cols'] = $sb_instagram_cols;
743
+ $options['sb_instagram_disable_mobile'] = $sb_instagram_disable_mobile;
744
+ $options['sb_instagram_image_padding'] = $sb_instagram_image_padding;
745
+ $options['sb_instagram_image_padding_unit'] = $sb_instagram_image_padding_unit;
746
+ $options['sb_instagram_sort'] = $sb_instagram_sort;
747
+ $options['sb_instagram_background'] = $sb_instagram_background;
748
+ $options['sb_instagram_show_btn'] = $sb_instagram_show_btn;
749
+ $options['sb_instagram_btn_background'] = $sb_instagram_btn_background;
750
+ $options['sb_instagram_btn_text_color'] = $sb_instagram_btn_text_color;
751
+ $options['sb_instagram_btn_text'] = $sb_instagram_btn_text;
752
+ $options['sb_instagram_image_res'] = $sb_instagram_image_res;
753
  //Header
754
+ $options['sb_instagram_show_header'] = $sb_instagram_show_header;
755
+ $options['sb_instagram_header_size'] = $sb_instagram_header_size;
756
+ $options['sb_instagram_show_bio'] = $sb_instagram_show_bio;
757
+ $options['sb_instagram_custom_bio'] = $sb_instagram_custom_bio;
758
+ $options['sb_instagram_custom_avatar'] = $sb_instagram_custom_avatar;
759
+ $options['sb_instagram_header_color'] = $sb_instagram_header_color;
760
  //Follow button
761
+ $options['sb_instagram_show_follow_btn'] = $sb_instagram_show_follow_btn;
762
+ $options['sb_instagram_folow_btn_background'] = $sb_instagram_folow_btn_background;
763
+ $options['sb_instagram_follow_btn_text_color'] = $sb_instagram_follow_btn_text_color;
764
+ $options['sb_instagram_follow_btn_text'] = $sb_instagram_follow_btn_text;
765
  //Misc
766
+ $options['sb_instagram_custom_css'] = $sb_instagram_custom_css;
767
+ $options['sb_instagram_custom_js'] = $sb_instagram_custom_js;
768
+ $options['sb_instagram_ajax_theme'] = $sb_instagram_ajax_theme;
769
+ $options['gdpr'] = $gdpr;
770
+ $options['enqueue_js_in_head'] = $enqueue_js_in_head;
771
+ $options['disable_js_image_loading'] = $disable_js_image_loading;
772
+ $options['sb_instagram_disable_resize'] = $sb_instagram_disable_resize;
773
+ $options['sb_instagram_favor_local'] = $sb_instagram_favor_local;
774
+ $options['sb_instagram_minnum'] = $sb_instagram_minnum;
775
+
776
+ $options['sb_ajax_initial'] = $sb_ajax_initial;
777
+ $options['sb_instagram_cron'] = $sb_instagram_cron;
778
+ $options['sb_instagram_backup'] = $sb_instagram_backup;
779
  $options['enqueue_css_in_shortcode'] = $enqueue_css_in_shortcode;
780
 
781
+ $sb_instagram_custom_template = isset( $_POST['sb_instagram_custom_template'] );
782
+ $options['custom_template'] = $sb_instagram_custom_template;
783
+ $sb_instagram_disable_admin_notice = isset( $_POST['sb_instagram_disable_admin_notice'] );
784
+ $options['disable_admin_notice'] = $sb_instagram_disable_admin_notice;
785
+ $sb_instagram_enable_email_report = isset( $_POST['sb_instagram_enable_email_report'] );
786
+ $options['enable_email_report'] = $sb_instagram_enable_email_report;
787
+ isset( $_POST['sb_instagram_email_notification'] ) ? $sb_instagram_email_notification = sanitize_text_field( wp_unslash( $_POST['sb_instagram_email_notification'] ) ) : $sb_instagram_email_notification = '';
788
+ $original = $options['email_notification'];
789
  $options['email_notification'] = $sb_instagram_email_notification;
790
+ isset( $_POST['sb_instagram_email_notification_addresses'] ) ? $sb_instagram_email_notification_addresses = sanitize_text_field( wp_unslash( $_POST['sb_instagram_email_notification_addresses'] ) ) : $sb_instagram_email_notification_addresses = get_option( 'admin_email' );
791
  $options['email_notification_addresses'] = $sb_instagram_email_notification_addresses;
792
 
793
+ if ( $original !== $sb_instagram_email_notification && $sb_instagram_enable_email_report ) {
794
  //Clear the existing cron event
795
+ wp_clear_scheduled_hook( 'sb_instagram_feed_issue_email' );
796
 
797
+ $input = sanitize_text_field( wp_unslash( $_POST['sb_instagram_email_notification'] ) );
798
  $timestamp = strtotime( 'next ' . $input );
799
 
800
+ if ( $timestamp - ( 3600 * 1 ) < time() ) {
801
+ $timestamp = $timestamp + ( 3600 * 24 * 7 );
802
  }
803
+ $six_am_local = $timestamp + sbi_get_utc_offset() + ( 6 * 60 * 60 );
804
 
805
  wp_schedule_event( $six_am_local, 'sbiweekly', 'sb_instagram_feed_issue_email' );
806
  }
807
 
 
808
  //Delete all SBI transients
809
  global $wpdb;
810
+ $table_name = $wpdb->prefix . 'options';
811
+ $wpdb->query(
812
+ "
813
  DELETE
814
  FROM $table_name
815
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
816
+ "
817
+ );
818
+ $wpdb->query(
819
+ "
820
  DELETE
821
  FROM $table_name
822
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
823
+ "
824
+ );
825
+ $wpdb->query(
826
+ "
827
  DELETE
828
  FROM $table_name
829
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
830
+ "
831
+ );
832
+ $wpdb->query(
833
+ "
834
  DELETE
835
  FROM $table_name
836
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
837
+ "
838
+ );
839
 
840
+ if ( $sb_instagram_cron === 'no' ) {
841
+ wp_clear_scheduled_hook( 'sb_instagram_cron_job' );
842
+ }
843
 
844
  //Run cron when Misc settings are saved
845
+ if ( $sb_instagram_cron === 'yes' ) {
846
  //Clear the existing cron event
847
+ wp_clear_scheduled_hook( 'sb_instagram_cron_job' );
848
 
849
+ $sb_instagram_cache_time = $options['sb_instagram_cache_time'];
850
+ $sb_instagram_cache_time_unit = $options['sb_instagram_cache_time_unit'];
851
 
852
  //Set the event schedule based on what the caching time is set to
853
  $sb_instagram_cron_schedule = 'hourly';
854
+ if ( $sb_instagram_cache_time_unit === 'hours' && $sb_instagram_cache_time > 5 ) {
855
+ $sb_instagram_cron_schedule = 'twicedaily';
856
+ }
857
+ if ( $sb_instagram_cache_time_unit === 'days' ) {
858
+ $sb_instagram_cron_schedule = 'daily';
859
+ }
860
 
861
+ wp_schedule_event( time(), $sb_instagram_cron_schedule, 'sb_instagram_cron_job' );
862
 
863
  sb_instagram_clear_page_caches();
864
  }
 
865
  } //End customize tab post
866
 
867
  //Save the settings to the settings array
875
 
876
 
877
  <div id="sbi_admin" class="wrap">
878
+ <?php
879
+ $lite_notice_dismissed = get_transient( 'instagram_feed_dismiss_lite' );
880
 
881
+ if ( ! $lite_notice_dismissed ) :
882
+ ?>
883
+ <div id="sbi-notice-bar" style="display:none">
884
+ <span class="sbi-notice-bar-message"><?php echo wp_kses_post( __( 'You\'re using Instagram Feed Lite. To unlock more features consider <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=litenotice" target="_blank" rel="noopener noreferrer">upgrading to Pro</a>.', 'instagram-feed' ) ); ?></span>
885
+ <button type="button" class="dismiss" title="<?php esc_html_e( 'Dismiss this message.', 'instagram-feed' ); ?>" data-page="overview">
886
+ </button>
887
+ </div>
888
+ <?php endif; ?>
889
 
890
+ <?php do_action( 'sbi_admin_overview_before_table' ); ?>
891
 
892
 
893
  <div id="header">
894
  <h1><?php esc_html_e( 'Instagram Feed', 'instagram-feed' ); ?></h1>
895
  </div>
896
  <?php
897
+ $sb_instagram_type = 'user';
898
  $connected_accounts = SBI_Account_Connector::stored_connected_accounts();
899
+ $user_feed_ids = ! is_array( $sb_instagram_user_id ) ? explode( ',', $sb_instagram_user_id ) : $sb_instagram_user_id;
900
 
901
  $new_user_name = false;
902
 
903
  SBI_Account_Connector::maybe_launch_modals( $sb_instagram_user_id );
904
  if ( isset( $_POST['sbi_connect_username'] ) ) {
905
+ $new_user_name = sanitize_text_field( wp_unslash( $_POST['sbi_connect_username'] ) );
906
  $new_account_details = json_decode( wp_unslash( $_POST['sbi_account_json'] ), true );
907
  array_map( 'sanitize_text_field', $new_account_details );
908
 
909
+ $updated_options = sbi_connect_basic_account( $new_account_details );
910
  $connected_accounts = $updated_options['connected_accounts'];
911
+ $user_feed_ids = $updated_options['sb_instagram_user_id'];
912
  }
913
 
914
  //Display connected page
915
+ if ( isset( $sbi_connected_page ) && strpos( $sbi_connected_page, ':' ) !== false ) {
916
 
917
+ $sbi_connected_page_pieces = explode( ':', $sbi_connected_page );
918
+ $sbi_connected_page_id = $sbi_connected_page_pieces[0];
919
+ $sbi_connected_page_name = $sbi_connected_page_pieces[1];
920
+ $sbi_connected_page_image = $sbi_connected_page_pieces[2];
921
 
922
  echo '&nbsp;';
923
  echo '<p style="font-weight: bold; margin-bottom: 5px;">Connected Business Profile:</p>';
924
  echo '<div class="sbi-managed-page sbi-no-select">';
925
+ echo '<p><img class="sbi-page-avatar" height="50" width="50" src="' . esc_url( $sbi_connected_page_image ) . '" alt="' . esc_attr( $sbi_connected_page_id ) . '"><strong>' . esc_html( $sbi_connected_page_name ) . '</strong> &nbsp; (' . esc_html( $sbi_connected_page_id ) . ')</p>';
926
  echo '</div>';
927
  }
928
 
929
  ?>
930
 
931
+ <form name="form1" method="post" action="">
932
+ <input type="hidden" name="sb_instagram_settings_hidden_field" value="Y">
933
  <?php wp_nonce_field( 'sb_instagram_saving_settings', 'sb_instagram_settings_nonce' ); ?>
934
 
935
+ <?php $sbi_active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : 'configure'; ?>
936
  <h2 class="nav-tab-wrapper">
937
+ <a href="?page=sb-instagram-feed&amp;tab=configure" class="nav-tab <?php echo $sbi_active_tab === 'configure' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( '1. Configure', 'instagram-feed' ); ?></a>
938
+ <a href="?page=sb-instagram-feed&amp;tab=customize" class="nav-tab <?php echo $sbi_active_tab === 'customize' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( '2. Customize', 'instagram-feed' ); ?></a>
939
+ <a href="?page=sb-instagram-feed&amp;tab=display" class="nav-tab <?php echo $sbi_active_tab === 'display' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( '3. Display Your Feed', 'instagram-feed' ); ?></a>
940
+ <a href="?page=sb-instagram-feed&amp;tab=support" class="nav-tab <?php echo $sbi_active_tab === 'support' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Support', 'instagram-feed' ); ?></a>
941
+ <a href="?page=sb-instagram-feed&amp;tab=more" class="nav-tab <?php echo $sbi_active_tab === 'more' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'More Social Feeds', 'instagram-feed' ); ?>
942
  <?php
943
+ $seen_more_plugins_page = get_user_meta( get_current_user_id(), 'seen_more_plugins_page_1', true );
944
+ if ( ! $seen_more_plugins_page ) {
945
+ echo '<span class="sbi-alert-bubble">1</span>';
946
+ }
947
  ?>
948
  </a>
949
  </h2>
950
 
951
+ <?php if ( $sbi_active_tab === 'configure' ) { //Start Configure tab ?>
952
+ <input type="hidden" name="sb_instagram_configure_hidden_field" value="Y">
953
+
954
+ <table class="form-table" aria-describedby="sbi-con-desc">
955
+ <tbody>
956
+ <h3 id="sbi-con-desc"><?php esc_html_e( 'Configure', 'instagram-feed' ); ?></h3>
957
+ <?php
958
+ $sb_admin_email = get_option( 'admin_email' );
959
+ $state_url = wp_nonce_url( admin_url( 'admin.php?page=sb-instagram-feed' ), 'sbi-connect', 'sbi_con' );
960
+ $connect_url = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=' . $sb_admin_email . '&state=' . $state_url;
961
+ ?>
962
+ <div id="sbi_config">
963
+ <a data-new-api="<?php echo esc_attr( $connect_url ); ?>" href="<?php echo esc_attr( $connect_url ); ?>" class="sbi_admin_btn"><i class="fa fa-user-plus" aria-hidden="true" style="font-size: 20px;"></i>&nbsp; <?php esc_html_e( 'Connect an Instagram Account', 'instagram-feed' ); ?></a>
964
+ <a href="https://smashballoon.com/instagram-feed/token/" target="_blank" style="position: relative; top: 14px; left: 15px;"><?php esc_html_e( 'Button not working?', 'instagram-feed' ); ?></a>
965
+ </div>
966
+
967
+ <tr>
968
+ <th scope="row"><label><?php esc_html_e( 'Instagram Accounts', 'instagram-feed' ); ?></label><span style="font-weight:normal; font-style:italic; font-size: 12px; display: block;"><?php esc_html_e( 'Use the button above to connect an Instagram account', 'instagram-feed' ); ?></span></th>
969
+ <td class="sbi_connected_accounts_wrap">
970
  <?php if ( empty( $connected_accounts ) ) : ?>
971
+ <p class="sbi_no_accounts"><?php esc_html_e( 'No Instagram accounts connected. Click the button above to connect an account.', 'instagram-feed' ); ?></p><br />
972
+ <?php
973
+ else :
974
  $doing_account_error_messages = count( $connected_accounts ) > 1;
975
  global $sb_instagram_posts_manager;
976
 
977
  ?>
978
+ <?php
979
+ foreach ( $connected_accounts as $account ) :
980
+ $username = $account['username'];
981
+ if ( isset( $account['local_avatar'] ) && $account['local_avatar'] && isset( $options['sb_instagram_favor_local'] ) && $options['sb_instagram_favor_local'] ) {
982
+ $upload = wp_upload_dir();
983
+ $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
984
+ $profile_picture = '<img class="sbi_ca_avatar" src="' . $resized_url . $account['username'] . '.jpg" />'; //Could add placeholder avatar image
985
+ } else {
986
+ $profile_picture = $account['profile_picture'] ? '<img class="sbi_ca_avatar" src="' . $account['profile_picture'] . '" />' : ''; //Could add placeholder avatar image
987
+ }
988
 
989
+ $is_invalid_class = ! $account['is_valid'] ? ' sbi_account_invalid' : '';
990
+ $in_user_feed = in_array( $account['user_id'], $user_feed_ids, true );
991
+ $account_type = isset( $account['type'] ) ? $account['type'] : 'personal';
992
+ $use_tagged = isset( $account['use_tagged'] ) && $account['use_tagged'] === '1';
993
+ $is_private = isset( $account['private'] ) && $account['private'] !== false;
994
+
995
+ if ( empty( $profile_picture ) && $account_type === 'personal' ) {
996
+ $account_update = sbi_account_data_for_token( $account['access_token'] );
997
+ if ( isset( $account['is_valid'] ) ) {
998
+ $split = explode( '.', $account['access_token'] );
999
+ $connected_accounts[ $split[0] ] = array(
1000
+ 'access_token' => $account['access_token'],
1001
+ 'user_id' => $split[0],
1002
+ 'username' => $account_update['username'],
1003
+ 'is_valid' => true,
1004
+ 'last_checked' => time(),
1005
+ 'profile_picture' => $account_update['profile_picture'],
1006
+ );
1007
+
1008
+ $sbi_options = get_option( 'sb_instagram_settings', array() );
1009
+ $sbi_options['connected_accounts'] = $connected_accounts;
1010
+ update_option( 'sb_instagram_settings', $sbi_options );
1011
+ }
1012
  }
1013
+ $updated_or_new_account_class = $new_user_name === $username && $account_type !== 'business' ? ' sbi_ca_new_or_updated' : '';
1014
 
1015
+ ?>
1016
+ <div class="sbi_connected_account<?php echo esc_attr( $is_invalid_class . $updated_or_new_account_class ); ?>
1017
+ <?php
1018
+ if ( $in_user_feed ) {
1019
+ echo ' sbi_account_active';}
1020
+ ?>
1021
+ sbi_account_type_<?php echo esc_attr( $account_type ); ?>" id="sbi_connected_account_<?php echo esc_attr( $account['user_id'] ); ?>" data-accesstoken="" data-userid="<?php echo esc_attr( $account['user_id'] ); ?>" data-username="<?php echo esc_attr( $account['username'] ); ?>" data-type="<?php echo esc_attr( $account_type ); ?>" data-permissions="
1022
+ <?php
1023
+ if ( $use_tagged ) {
1024
+ echo 'tagged';}
1025
+ ?>
1026
+ ">
1027
+ <?php if ( $doing_account_error_messages && $sb_instagram_posts_manager->connected_account_has_error( $account ) ) : ?>
1028
+ <div class="sbi_deprecated">
1029
+ <span><i class="fa fa-exclamation-circle" aria-hidden="true"></i><?php esc_html_e( 'Feeds using this account might not be updating due to an error. Try viewing these feeds after reconnecting the account and saving your settings below.', 'instagram-feed' ); ?></span>
1030
+ </div>
1031
+ <?php endif; ?>
1032
+ <div class="sbi_ca_alert">
1033
+ <span><?php esc_html_e( 'The Access Token for this account is expired or invalid. Click the button above to attempt to renew it.', 'instagram-feed' ); ?></span>
1034
+ </div>
1035
+ <div class="sbi_ca_info">
1036
 
1037
+ <div class="sbi_ca_delete">
1038
+ <a href="<?php echo esc_url( add_query_arg( 'disconnect', $account['user_id'], admin_url( 'admin.php?page=sb-instagram-feed' ) ) ); ?>" class="sbi_delete_account"><i class="fa fa-times"></i><span class="sbi_remove_text"><?php esc_html_e( 'Remove', 'instagram-feed' ); ?></span></a>
1039
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1040
 
1041
+ <div class="sbi_ca_username">
1042
+ <?php echo wp_kses_post( $profile_picture ); ?>
1043
+ <strong><?php echo esc_html( $username ); ?><span><?php echo esc_html( sbi_account_type_display( $account_type, isset( $account['private'] ) ) ); ?></span></strong>
1044
+ </div>
1045
 
1046
+ <div class="sbi_ca_actions">
1047
+ <?php if ( ! $in_user_feed ) : ?>
1048
+ <a href="JavaScript:void(0);" class="sbi_use_in_user_feed button-primary"><i class="fa fa-plus-circle" aria-hidden="true"></i><?php esc_html_e( 'Add to Primary Feed', 'instagram-feed' ); ?></a>
1049
+ <?php else : ?>
1050
+ <a href="JavaScript:void(0);" class="sbi_remove_from_user_feed button-primary"><i class="fa fa-minus-circle" aria-hidden="true"></i><?php esc_html_e( 'Remove from Primary Feed', 'instagram-feed' ); ?></a>
1051
+ <?php endif; ?>
1052
+ <a class="sbi_ca_token_shortcode button-secondary" href="JavaScript:void(0);"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i><?php esc_html_e( 'Add to another Feed', 'instagram-feed' ); ?></a>
1053
+ <a class="sbi_ca_show_token button-secondary" href="JavaScript:void(0);" title="<?php esc_attr_e( 'Show access token and account info', 'instagram-feed' ); ?>"><i class="fa fa-cog"></i></a>
1054
+ <?php
1055
+ if ( $is_private ) :
1056
+ $expires_in = max( 0, floor( ( $account['expires_timestamp'] - time() ) / DAY_IN_SECONDS ) );
1057
+ $message = $expires_in > 0 ? sprintf( __( 'Expires in %s days', 'instagram-feed' ), $expires_in ) : __( 'Access Token Expired', 'instagram-feed' );
1058
+ $alert_class = $expires_in < 10 ? ' sbi_alert' : '';
1059
+ ?>
1060
+ <div class="sbi_is_private<?php echo esc_attr( $alert_class ); ?>">
1061
+ <span><?php echo esc_html( $message ); ?></span>
1062
+ <a class="sbi_tooltip_link sbi_tooltip_outside" href="JavaScript:void(0);" style="position: relative; top: 2px;"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
1063
+
1064
+ <a href="<?php echo esc_url( 'https://api.instagram.com/oauth/authorize?client_id=423965861585747&redirect_uri=https://api.smashballoon.com/v2/instagram-basic-display-redirect.php&response_type=code&scope=user_profile,user_media&state=' . admin_url( 'admin.php?page=sb-instagram-feed' ) ); ?>" class="button button-secondary"><?php esc_html_e( 'Refresh now', 'instagram-feed' ); ?></a>
1065
+ </div>
1066
+ <p class="sbi_tooltip sbi-more-info" style="display: none; width: 100%; box-sizing: border-box;"><?php echo wp_kses_post( sprintf( __( 'This account is a "private" account on Instagram. It needs to be manually reconnected every 60 days. %1$sChange this account to be "public"%2$s to have access tokens that are automatically refreshed.', 'instagram-feed' ), '<a href="https://help.instagram.com/116024195217477/In" target="_blank">', '</a>' ) ); ?></p>
1067
+ <?php endif; ?>
1068
 
1069
+ </div>
1070
 
1071
+ <div class="sbi_ca_shortcode">
 
 
 
 
1072
 
1073
+ <p><?php esc_html_e( 'Copy and paste this shortcode into your page or widget area', 'instagram-feed' ); ?>:<br>
1074
+ <?php if ( ! empty( $account['username'] ) ) : ?>
1075
+ <code>[instagram-feed user="<?php echo esc_html( $account['username'] ); ?>"]</code>
1076
+ <?php endif; ?>
1077
+ </p>
1078
 
1079
+ <p><?php esc_html_e( 'To add multiple users in the same feed, simply separate them using commas', 'instagram-feed' ); ?>:<br>
1080
+ <?php if ( ! empty( $account['username'] ) ) : ?>
1081
+ <code>[instagram-feed user="<?php echo esc_html( $account['username'] ); ?>, a_second_user, a_third_user"]</code>
1082
+ <?php endif; ?>
1083
 
1084
+ <p><?php echo wp_kses_post( sprintf( __( 'Click on the %s tab to learn more about shortcodes', 'instagram-feed' ), '<a href="?page=sb-instagram-feed&tab=display" target="_blank">' . __( 'Display Your Feed', 'instagram-feed' ) . '</a>' ) ); ?></p>
1085
+ </div>
 
1086
 
1087
+ <div class="sbi_ca_accesstoken">
1088
+ <span class="sbi_ca_token_label"><?php esc_html_e( 'User ID', 'instagram-feed' ); ?>:</span><input type="text" class="sbi_ca_user_id" value="<?php echo esc_attr( $account['user_id'] ); ?>" readonly="readonly" onclick="this.focus();this.select()" title="<?php esc_attr_e( 'To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac).', 'instagram-feed' ); ?>"><br>
1089
+ </div>
1090
 
1091
+ </div>
1092
+
1093
+ </div>
1094
 
1095
+ <?php endforeach; ?>
1096
  <?php endif; ?>
1097
+ <a href="JavaScript:void(0);" class="sbi_manually_connect button-secondary"><?php esc_html_e( 'Manually Connect an Account', 'instagram-feed' ); ?></a>
1098
+ <div class="sbi_manually_connect_wrap">
1099
+ <input name="sb_manual_at" id="sb_manual_at" type="text" value="" style="margin-top: 4px; padding: 5px 9px; margin-left: 0px;" size="64" minlength="15" maxlength="400" placeholder="<?php esc_attr_e( 'Enter a valid Instagram Access Token', 'instagram-feed' ); ?>" /><span class='sbi_business_profile_tag'><?php esc_html_e( 'Business or Basic Display', 'instagram-feed' ); ?></span>
1100
+ <div class="sbi_manual_account_id_toggle">
1101
+ <label><?php esc_html_e( 'Please enter the User ID for this Profile:', 'instagram-feed' ); ?></label>
1102
+ <input name="sb_manual_account_id" id="sb_manual_account_id" type="text" value="" style="margin-top: 4px; padding: 5px 9px; margin-left: 0px;" size="40" minlength="5" maxlength="100" placeholder="Eg: 15641403491391489" />
1103
+ </div>
1104
+ <p id="sbi_no_js_warning" class="sbi_nojs_notice"><?php echo wp_kses_post( sprintf( __( 'It looks like JavaScript is not working on this page. Some features may not work fully. Visit %1$sthis page%2$s for help resolving this issue.', 'instagram-feed' ), '<a href="https://smashballoon.com/i-cant-connect-or-manage-accounts-on-the-instagram-feed-settings-page/" target="_blank" rel="noopener">', '</a>' ) ); ?></p>
1105
+ <p class="sbi_submit" style="display: inline-block;"><input type="submit" name="sbi_submit" id="sbi_manual_submit" class="button button-primary" value="<?php esc_html_e( 'Connect This Account', 'instagram-feed' ); ?>"></p>
1106
+ </div>
1107
+ </td>
1108
+ </tr>
1109
+
1110
+ <tr class="sbi_feed_type">
1111
+ <th scope="row"><label><?php esc_html_e( 'Select a Feed Type', 'instagram-feed' ); ?>:</label><code class="sbi_shortcode"> type
1112
  Eg: type=user user=smashballoon
1113
  </code>
1114
  <?php if ( SB_Instagram_Feed_Locator::count_unique() > 1 ) : ?>
1115
+ <div class="sbi_locations_link">
1116
+ <a href="?page=sb-instagram-feed&amp;tab=allfeeds"><svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-search fa-w-16 fa-2x"><path fill="currentColor" d="M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z" class=""></path></svg> <?php esc_html_e( 'Feed Finder', 'instagram-feed' ); ?></a>
1117
+ </div>
1118
  <?php endif; ?>
1119
 
1120
+ </th>
1121
  <td>
1122
  <div class="sbi_row">
1123
  <div class="sbi_col sbi_one">
1124
+ <input type="radio" name="sb_instagram_type" id="sb_instagram_type_user" value="user"
1125
+ <?php
1126
+ if ( $sb_instagram_type === 'user' ) {
1127
+ echo 'checked';}
1128
+ ?>
1129
+ />
1130
  <label class="sbi_radio_label" for="sb_instagram_type_user"><?php esc_html_e( 'User Account:', 'instagram-feed' ); ?></label>
1131
  </div>
1132
  <div class="sbi_col sbi_two">
1133
  <div class="sbi_user_feed_ids_wrap">
1134
+ <?php
1135
+ foreach ( $user_feed_ids as $feed_id ) :
1136
+ if ( $feed_id !== '' ) :
1137
+ ?>
1138
+ <?php
1139
+ if ( ! empty( $connected_accounts ) ) {
1140
+ ?>
1141
+ <div id="sbi_user_feed_id_<?php echo esc_attr( $feed_id ); ?>" class="sbi_user_feed_account_wrap"><?php } ?>
1142
 
1143
+ <?php if ( isset( $connected_accounts[ $feed_id ] ) && ! empty( $connected_accounts[ $feed_id ]['username'] ) ) : ?>
1144
  <strong><?php echo esc_html( $connected_accounts[ $feed_id ]['username'] ); ?></strong> <span>(<?php echo esc_html( $feed_id ); ?>)</span>
1145
  <input name="sb_instagram_user_id[]" id="sb_instagram_user_id" type="hidden" value="<?php echo esc_attr( $feed_id ); ?>" />
1146
  <?php elseif ( isset( $connected_accounts[ $feed_id ] ) && ! empty( $connected_accounts[ $feed_id ]['access_token'] ) ) : ?>
1148
  <input name="sb_instagram_user_id[]" id="sb_instagram_user_id" type="hidden" value="<?php echo esc_attr( $feed_id ); ?>" />
1149
  <?php endif; ?>
1150
 
1151
+ <?php
1152
+ if ( ! empty( $connected_accounts ) ) {
1153
+ ?>
1154
+ </div><?php } ?>
1155
+ <?php
1156
+ endif;
1157
+ endforeach;
1158
+ ?>
1159
  </div>
1160
 
1161
  <?php if ( empty( $user_feed_ids ) ) : ?>
1162
  <p class="sbi_no_accounts" style="margin-top: -3px; margin-right: 10px;"><?php esc_html_e( 'Connect a user account above', 'instagram-feed' ); ?></p>
1163
  <?php endif; ?>
1164
 
1165
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);" style="margin: 5px 0 10px 0; display: inline-block; height: 19px;"><?php esc_html_e( 'How to display User feeds', 'instagram-feed' ); ?></a>
1166
+ <div class="sbi_tooltip"><?php echo wp_kses_post( __( "<p><strong>Displaying Posts from Your User Account</strong><br />Simply connect an account using the button above.</p><p style='padding-top:8px;'><strong>Displaying Posts from Other Instagram Accounts</strong><br />Due to recent changes in the Instagram API it is no longer possible to display photos from other Instagram accounts which you do not have access to. You can only display the user feed of an account which you connect above. You can connect as many account as you like by logging in using the button above, or manually copy/pasting an Access Token by selecting the 'Manually Connect an Account' option.</p><p style='padding-top:10px;'><strong>Multiple Acounts</strong><br />It is only possible to display feeds from Instagram accounts which you own. In order to display feeds from multiple accounts, first connect them above and then use the buttons to add the account either to your primary feed or to another feed on your site.</p>", 'instagram-feed' ) ); ?></div><br />
1167
  </div>
1168
 
1169
  </div>
1170
 
1171
  <div class="sbi_pro sbi_row">
1172
  <div class="sbi_col sbi_one">
1173
+ <input disabled type="radio" name="sb_instagram_type" id="sb_instagram_type_hashtag" value="hashtag"
1174
+ <?php
1175
+ if ( $sb_instagram_type === 'hashtag' ) {
1176
+ echo 'checked';}
1177
+ ?>
1178
+ />
1179
  <label class="sbi_radio_label" for="sb_instagram_type_hashtag"><?php esc_html_e( 'Hashtag:', 'instagram-feed' ); ?></label>
1180
  </div>
1181
  <div class="sbi_col sbi_two">
1182
 
1183
  <p class="sbi_pro_tooltip"><?php esc_html_e( 'Upgrade to the Pro version to display Hashtag and Tagged feeds', 'instagram-feed' ); ?><i class="fa fa-caret-down" aria-hidden="true"></i></p>
1184
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=hashtags" target="_blank" class="sbi_lock"><i class="fa fa-rocket"></i><?php esc_html_e( 'Pro', 'instagram-feed' ); ?></a>
1185
 
1186
  <input readonly type="text" size="25" style="height: 32px; top: -2px; position: relative; box-shadow: none;" disabled />
1187
  &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1190
  </div>
1191
  </div>
1192
 
1193
+ <div class="sbi_pro sbi_row">
1194
+ <div class="sbi_col sbi_one">
1195
+ <input disabled type="radio" name="sb_instagram_type" id="sb_instagram_type_tagged" value="tagged"
1196
+ <?php
1197
+ if ( $sb_instagram_type === 'tagged' ) {
1198
+ echo 'checked';}
1199
+ ?>
1200
+ />
1201
+ <label class="sbi_radio_label" for="sb_instagram_type_tagged"><?php esc_html_e( 'Tagged:', 'instagram-feed' ); ?></label>
1202
+ </div>
1203
+ <div class="sbi_col sbi_two">
1204
+ <input readonly type="text" size="25" style="height: 32px; top: -2px; position: relative; box-shadow: none;" disabled />
1205
+ &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1206
+
1207
+ <p class="sbi_tooltip"><?php esc_html_e( 'Display posts that your account has been tagged in.', 'instagram-feed' ); ?></p>
1208
+ </div>
1209
+ </div>
1210
+
1211
+ <div class="sbi_pro sbi_row sbi_mixed_directions">
1212
+ <div class="sbi_col sbi_one">
1213
+ <input type="radio" name="sb_instagram_type" disabled />
1214
+ <label class="sbi_radio_label" for="sb_instagram_type_mixed">Mixed:</label>
1215
+ </div>
1216
+ <div class="sbi_col sbi_two">
1217
+ <input readonly type="text" size="25" style="height: 32px; top: -2px; position: relative; box-shadow: none;" disabled />
1218
+ &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1219
+
1220
+ <div class="sbi_tooltip sbi_type_tooltip">
1221
+ <p>
1222
+ <?php echo wp_kses_post( sprintf( __( 'To display multiple feed types in a single feed, use %1$s in your shortcode and then add the user name or hashtag for each feed into the shortcode, like so: %2$s. This will combine a user feed and a hashtag feed into the same feed.', 'instagram-feed' ), 'type="mixed"', '<code>[instagram-feed type="mixed" user="smashballoon" hashtag="#awesomeplugins"]</code>' ) ); ?>
1223
+ </p>
1224
+ <p style="padding-top: 8px;"><strong>Note:</strong> To display a hashtag feed, it is required that you first connect an Instagram Business Profile using the <strong>"Connect an Instagram Account"</strong> button above. &nbsp;<a href="https://smashballoon.com/instagram-business-profiles/" target="_blank">Why is this required?</a>
1225
+ </p>
1226
+ </div>
1227
+ </div>
1228
+
1229
+ </div>
1230
 
1231
  <div class="sbi_row sbi_pro">
1232
  <br>
1233
+ <a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);" style="margin-left: 0;"><i class="fa fa-question-circle" aria-hidden="true" style="margin-right: 6px;"></i><?php esc_html_e( 'Combine multiple feed types into a single feed', 'instagram-feed' ); ?></a>
1234
  <p class="sbi_tooltip">
1235
+ <strong><?php echo wp_kses_post( __( 'Please note: this is only available in the <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=multipletypes" target="_blank">Pro version</a>', 'instagram-feed' ) ); ?>.</strong><br />
1236
+ <?php echo wp_kses_post( sprintf( __( 'To display multiple feed types in a single feed, use %1$s in your shortcode and then add each user name or hashtag of each feed into the shortcode, like so: %2$s. This will combine a user feed and a hashtag feed into the same feed.', 'instagram-feed' ), 'type="mixed"', '<code>[instagram-feed type="mixed" user="smashballoon" hashtag="#awesomeplugins"]</code>' ) ); ?>
1237
  </p>
1238
  </div>
1239
 
1241
  </tr>
1242
 
1243
  <tr>
1244
+ <th scope="row" class="bump-left"><label for="sb_instagram_preserve_settings" class="bump-left"><?php esc_html_e( 'Preserve settings when plugin is removed', 'instagram-feed' ); ?></label></th>
1245
  <td>
1246
+ <input name="sb_instagram_preserve_settings" type="checkbox" id="sb_instagram_preserve_settings"
1247
+ <?php
1248
+ if ( $sb_instagram_preserve_settings ) {
1249
+ echo 'checked';}
1250
+ ?>
1251
+ />
1252
+ <label for="sb_instagram_preserve_settings"><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></label>
1253
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
1254
+ <p class="sbi_tooltip"><?php esc_html_e( '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.', 'instagram-feed' ); ?></p>
1255
  </td>
1256
  </tr>
1257
 
1258
 
1259
+ <tr class="sbi_cron_cache_opts">
1260
+ <th scope="row"><?php esc_html_e( 'Check for new posts', 'instagram-feed' ); ?></th>
1261
+ <td>
1262
+ <div class="sbi_row">
1263
+ <input type="radio" name="sbi_caching_type" id="sbi_caching_type_cron" value="background"
1264
+ <?php
1265
+ if ( $sbi_caching_type === 'background' ) {
1266
+ echo 'checked';}
1267
+ ?>
1268
+ >
1269
+ <label for="sbi_caching_type_cron"><?php esc_html_e( 'In the background', 'instagram-feed' ); ?></label>
1270
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 2px;"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
1271
+ <p class="sbi_tooltip sbi-more-info"><?php esc_html_e( 'Your Instagram post 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', 'instagram-feed' ); ?>:<br><br>
1272
+ <?php echo wp_kses_post( __( '<strong>1. In the background</strong><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. <strong>Please note</strong> 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.', 'instagram-feed' ) ); ?>
1273
+ <br><br>
1274
+ <?php echo wp_kses_post( __( '<strong>2. When the page loads</strong><br>Selecting this option means that when the cache expires then the plugin will check Instagram 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. <strong>Tip:</strong> If you\'re experiencing an issue with the plugin not updating automatically then try enabling the setting labeled <strong>\'Force cache to clear on interval\'</strong> which is located on the \'Customize\' tab.', 'instagram-feed' ) ) . '</p>'; ?>
1275
+
1276
+ </div>
1277
+ <div class="sbi_row sbi-caching-cron-options" style="display: block;">
1278
+
1279
+ <select name="sbi_cache_cron_interval" id="sbi_cache_cron_interval">
1280
+ <option value="30mins"
1281
+ <?php
1282
+ if ( $sbi_cache_cron_interval === '30mins' ) {
1283
+ echo 'selected';}
1284
+ ?>
1285
+ ><?php esc_html_e( 'Every 30 minutes', 'instagram-feed' ); ?></option>
1286
+ <option value="1hour"
1287
+ <?php
1288
+ if ( $sbi_cache_cron_interval === '1hour' ) {
1289
+ echo 'selected';}
1290
+ ?>
1291
+ ><?php esc_html_e( 'Every hour', 'instagram-feed' ); ?></option>
1292
+ <option value="12hours"
1293
+ <?php
1294
+ if ( $sbi_cache_cron_interval === '12hours' ) {
1295
+ echo 'selected';}
1296
+ ?>
1297
+ ><?php esc_html_e( 'Every 12 hours', 'instagram-feed' ); ?></option>
1298
+ <option value="24hours"
1299
+ <?php
1300
+ if ( $sbi_cache_cron_interval === '24hours' ) {
1301
+ echo 'selected';}
1302
+ ?>
1303
+ ><?php esc_html_e( 'Every 24 hours', 'instagram-feed' ); ?></option>
1304
+ </select>
1305
+
1306
+ <div id="sbi-caching-time-settings" style="display: none;">
1307
+ <?php esc_html_e( 'at' ); ?>
1308
+
1309
+ <select name="sbi_cache_cron_time" style="width: 80px">
1310
+ <option value="1"
1311
+ <?php
1312
+ if ( $sbi_cache_cron_time === '1' ) {
1313
+ echo 'selected';}
1314
+ ?>
1315
+ >1:00</option>
1316
+ <option value="2"
1317
+ <?php
1318
+ if ( $sbi_cache_cron_time === '2' ) {
1319
+ echo 'selected';}
1320
+ ?>
1321
+ >2:00</option>
1322
+ <option value="3"
1323
+ <?php
1324
+ if ( $sbi_cache_cron_time === '3' ) {
1325
+ echo 'selected';}
1326
+ ?>
1327
+ >3:00</option>
1328
+ <option value="4"
1329
+ <?php
1330
+ if ( $sbi_cache_cron_time === '4' ) {
1331
+ echo 'selected';}
1332
+ ?>
1333
+ >4:00</option>
1334
+ <option value="5"
1335
+ <?php
1336
+ if ( $sbi_cache_cron_time === '5' ) {
1337
+ echo 'selected';}
1338
+ ?>
1339
+ >5:00</option>
1340
+ <option value="6"
1341
+ <?php
1342
+ if ( $sbi_cache_cron_time === '6' ) {
1343
+ echo 'selected';}
1344
+ ?>
1345
+ >6:00</option>
1346
+ <option value="7"
1347
+ <?php
1348
+ if ( $sbi_cache_cron_time === '7' ) {
1349
+ echo 'selected';}
1350
+ ?>
1351
+ >7:00</option>
1352
+ <option value="8"
1353
+ <?php
1354
+ if ( $sbi_cache_cron_time === '8' ) {
1355
+ echo 'selected';}
1356
+ ?>
1357
+ >8:00</option>
1358
+ <option value="9"
1359
+ <?php
1360
+ if ( $sbi_cache_cron_time === '9' ) {
1361
+ echo 'selected';}
1362
+ ?>
1363
+ >9:00</option>
1364
+ <option value="10"
1365
+ <?php
1366
+ if ( $sbi_cache_cron_time === '10' ) {
1367
+ echo 'selected';}
1368
+ ?>
1369
+ >10:00</option>
1370
+ <option value="11"
1371
+ <?php
1372
+ if ( $sbi_cache_cron_time === '11' ) {
1373
+ echo 'selected';}
1374
+ ?>
1375
+ >11:00</option>
1376
+ <option value="0"
1377
+ <?php
1378
+ if ( $sbi_cache_cron_time === '0' ) {
1379
+ echo 'selected';}
1380
+ ?>
1381
+ >12:00</option>
1382
+ </select>
1383
+
1384
+ <select name="sbi_cache_cron_am_pm" style="width: 50px">
1385
+ <option value="am"
1386
+ <?php
1387
+ if ( $sbi_cache_cron_am_pm === 'am' ) {
1388
+ echo 'selected';}
1389
+ ?>
1390
+ >AM</option>
1391
+ <option value="pm"
1392
+ <?php
1393
+ if ( $sbi_cache_cron_am_pm === 'pm' ) {
1394
+ echo 'selected';}
1395
+ ?>
1396
+ >PM</option>
1397
+ </select>
1398
+ </div>
1399
+
1400
+ <?php
1401
+ if ( wp_next_scheduled( 'sbi_feed_update' ) ) {
1402
+ $time_format = get_option( 'time_format' );
1403
+ if ( ! $time_format ) {
1404
+ $time_format = 'g:i a';
1405
+ }
1406
+ //
1407
+ $schedule = wp_get_schedule( 'sbi_feed_update' );
1408
+ if ( $schedule === '30mins' ) {
1409
+ $schedule = __( 'every 30 minutes', 'instagram-feed' );
1410
+ }
1411
+ if ( $schedule === 'twicedaily' ) {
1412
+ $schedule = __( 'every 12 hours', 'instagram-feed' );
1413
+ }
1414
+ $sbi_next_cron_event = wp_next_scheduled( 'sbi_feed_update' );
1415
+ echo '<p class="sbi-caching-sched-notice"><span><strong>' . esc_html__( 'Next check', 'instagram-feed' ) . ': ' . esc_html( date( $time_format, $sbi_next_cron_event + sbi_get_utc_offset() ) ) . ' (' . esc_html( $schedule ) . ')</strong> - ' . esc_html__( 'Note: Saving the settings on this page will clear the cache and reset this schedule', 'instagram-feed' ) . '</span></p>';
1416
+ } else {
1417
+ echo '<p style="font-size: 11px; color: #666;">' . esc_html__( 'Nothing currently scheduled', 'instagram-feed' ) . '</p>';
1418
+ }
1419
+ ?>
1420
+
1421
+ </div>
1422
+ <div class="sbi_row">
1423
+ <input type="radio" name="sbi_caching_type" id="sbi_caching_type_page" value="page"
1424
+ <?php
1425
+ if ( $sbi_caching_type === 'page' ) {
1426
+ echo 'checked';}
1427
+ ?>
1428
+ >
1429
+ <label for="sbi_caching_type_page"><?php esc_html_e( 'When the page loads', 'instagram-feed' ); ?></label>
1430
+ </div>
1431
+ <div class="sbi_row sbi-caching-page-options" style="display: none;">
1432
+ <?php esc_html_e( 'Every', 'instagram-feed' ); ?>:
1433
+ <?php
1434
+ if ( $sb_instagram_cache_time_unit === 'minutes' ) {
1435
+ $max = 1440;
1436
+ } else {
1437
+ $max = 24;
1438
+ }
1439
+ ?>
1440
+ <input name="sb_instagram_cache_time" type="number" value="<?php echo esc_attr( $sb_instagram_cache_time ); ?>" size="4" min="1" max="<?php echo esc_attr( $max ); ?>"/>
1441
+ <select name="sb_instagram_cache_time_unit">
1442
+ <option value="minutes"
1443
+ <?php
1444
+ if ( $sb_instagram_cache_time_unit === 'minutes' ) {
1445
+ echo 'selected="selected"';}
1446
+ ?>
1447
+ ><?php esc_html_e( 'Minutes', 'instagram-feed' ); ?></option>
1448
+ <option value="hours"
1449
+ <?php
1450
+ if ( $sb_instagram_cache_time_unit === 'hours' ) {
1451
+ echo 'selected="selected"';}
1452
+ ?>
1453
+ ><?php esc_html_e( 'Hours', 'instagram-feed' ); ?></option>
1454
+ </select>
1455
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
1456
+ <p class="sbi_tooltip"><?php esc_html_e( 'Your Instagram 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 Instagram for posts again. The maximum caching time is 24 hours.', 'instagram-feed' ); ?></p>
1457
+ </div>
1458
+
1459
+ </td>
1460
+ </tr>
1461
 
1462
  </tbody>
1463
  </table>
1464
 
1465
+ <?php submit_button(); ?>
1466
  </form>
1467
 
1468
+ <p><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>&nbsp; <?php echo wp_kses_post( __( 'Next Step: <a href="?page=sb-instagram-feed&tab=customize">Customize your Feed</a>', 'instagram-feed' ) ); ?></p>
1469
 
1470
+ <p><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <?php echo wp_kses_post( __( 'Need help setting up the plugin? Check out our <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=supportpage&utm_medium=setupdirections" target="_blank">setup directions</a>', 'instagram-feed' ) ); ?></p>
1471
 
1472
 
1473
+ <?php } // End Configure tab ?>
1474
 
1475
+ <?php
1476
+ if ( $sbi_active_tab === 'allfeeds' ) {
1477
  $locator_summary = SB_Instagram_Feed_Locator::summary();
1478
  include_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/templates/locator-summary.php';
1479
+ }
1480
+ ?>
1481
 
1482
 
1483
+ <?php if ( $sbi_active_tab === 'customize' ) { //Start Configure tab ?>
1484
 
1485
  <p class="sb_instagram_contents_links" id="general">
1486
  <span><?php esc_html_e( 'Quick links:', 'instagram-feed' ); ?> </span>
1490
  <a href="#headeroptions"><?php esc_html_e( 'Header', 'instagram-feed' ); ?></a>
1491
  <a href="#loadmore"><?php esc_html_e( "'Load More' Button", 'instagram-feed' ); ?></a>
1492
  <a href="#follow"><?php esc_html_e( "'Follow' Button", 'instagram-feed' ); ?></a>
1493
+ <a href="#gdpr"><?php esc_html_e( 'GDPR', 'instagram-feed' ); ?></a>
1494
+ <a href="#customcss"><?php esc_html_e( 'Custom CSS', 'instagram-feed' ); ?></a>
1495
  <a href="#customjs"><?php esc_html_e( 'Custom JavaScript', 'instagram-feed' ); ?></a>
1496
+ </p>
1497
 
1498
+ <input type="hidden" name="sb_instagram_customize_hidden_field" value="Y">
1499
 
1500
+ <h3 id="sbi_general_heading"><?php esc_html_e( 'General', 'instagram-feed' ); ?></h3>
1501
 
1502
+ <table class="form-table" aria-describedby="sbi_general_heading">
1503
  <tbody>
1504
+ <tr>
1505
+ <th scope="row"><label><?php esc_html_e( 'Width of Feed', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> width widthunit
1506
  Eg: width=50 widthunit=%</code></th>
1507
  <td>
1508
  <input name="sb_instagram_width" type="text" value="<?php echo esc_attr( $sb_instagram_width ); ?>" id="sb_instagram_width" size="4" maxlength="4" />
1509
  <select name="sb_instagram_width_unit" id="sb_instagram_width_unit">
1510
+ <option value="px"
1511
+ <?php
1512
+ if ( $sb_instagram_width_unit === 'px' ) {
1513
+ echo 'selected="selected"';}
1514
+ ?>
1515
+ ><?php esc_html_e( 'px', 'instagram-feed' ); ?></option>
1516
+ <option value="%"
1517
+ <?php
1518
+ if ( $sb_instagram_width_unit === '%' ) {
1519
+ echo 'selected="selected"';}
1520
+ ?>
1521
+ ><?php esc_html_e( '%', 'instagram-feed' ); ?></option>
1522
  </select>
1523
  <div id="sb_instagram_width_options">
1524
+ <input name="sb_instagram_feed_width_resp" type="checkbox" id="sb_instagram_feed_width_resp"
1525
+ <?php
1526
+ if ( $sb_instagram_feed_width_resp ) {
1527
+ echo 'checked';}
1528
+ ?>
1529
+ /><label for="sb_instagram_feed_width_resp"><?php esc_html_e( 'Set to be 100% width on mobile?', 'instagram-feed' ); ?></label>
1530
  <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
1531
+ <p class="sbi_tooltip"><?php esc_html_e( '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.', 'instagram-feed' ); ?></p>
1532
  </div>
1533
  </td>
1534
  </tr>
1535
+ <tr>
1536
+ <th scope="row"><label><?php esc_html_e( 'Height of Feed', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> height heightunit
1537
  Eg: height=500 heightunit=px</code></th>
1538
  <td>
1539
  <input name="sb_instagram_height" type="text" value="<?php echo esc_attr( $sb_instagram_height ); ?>" size="4" maxlength="4" />
1540
  <select name="sb_instagram_height_unit">
1541
+ <option value="px"
1542
+ <?php
1543
+ if ( $sb_instagram_height_unit === 'px' ) {
1544
+ echo 'selected="selected"';}
1545
+ ?>
1546
+ ><?php esc_html_e( 'px', 'instagram-feed' ); ?></option>
1547
+ <option value="%"
1548
+ <?php
1549
+ if ( $sb_instagram_height_unit === '%' ) {
1550
+ echo 'selected="selected"';}
1551
+ ?>
1552
+ ><?php esc_html_e( '%', 'instagram-feed' ); ?></option>
1553
  </select>
1554
  </td>
1555
  </tr>
1556
+ <tr>
1557
+ <th scope="row"><label><?php esc_html_e( 'Background Color', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> background
1558
  Eg: background=d89531</code></th>
1559
  <td>
1560
  <input name="sb_instagram_background" type="text" value="<?php echo esc_attr( $sb_instagram_background ); ?>" class="sbi_colorpick" />
1564
  </table>
1565
 
1566
  <hr id="layout" />
1567
+ <h3 id="sbi_layout_heading"><?php esc_html_e( 'Layout', 'instagram-feed' ); ?></h3>
1568
 
1569
+ <table class="form-table" aria-describedby="sbi_layout_heading">
1570
  <tbody>
1571
  <?php
1572
  $selected_type = isset( $sb_instagram_layout_type ) ? $sb_instagram_layout_type : 'grid';
1573
+ $layout_types = array(
1574
+ 'grid' => __( 'Grid', 'instagram-feed' ),
1575
+ 'carousel' => __( 'Carousel', 'instagram-feed' ),
1576
+ 'masonry' => __( 'Masonry', 'instagram-feed' ),
1577
+ 'highlight' => __( 'Highlight', 'instagram-feed' ),
1578
  );
1579
  $layout_images = array(
1580
+ 'grid' => SBI_PLUGIN_URL . 'img/grid.png',
1581
+ 'carousel' => SBI_PLUGIN_URL . 'img/carousel.png',
1582
+ 'masonry' => SBI_PLUGIN_URL . 'img/masonry.png',
1583
+ 'highlight' => SBI_PLUGIN_URL . 'img/highlight.png',
1584
  );
1585
  ?>
1586
+ <tr>
1587
+ <th scope="row" class="sbi_pro"><label title="<?php esc_html_e( 'Click for shortcode option', 'instagram-feed' ); ?>"><?php esc_html_e( 'Layout Type', 'instagram-feed' ); ?></label><br /><span class="sbi_note" style="margin: 5px 0 0 0; font-weight: normal;"><?php esc_html_e( 'Select a layout to see associated<br />options', 'instagram-feed' ); ?></span></th>
1588
  <td>
1589
  <div class="sbi_layouts">
1590
+ <?php foreach ( $layout_types as $layout_type => $label ) : ?>
1591
  <div class="sbi_layout_cell sbi_pro">
1592
+ <input class="sb_layout_type" id="sb_layout_type_<?php echo esc_attr( $layout_type ); ?>" name="sb_instagram_layout_type" type="radio" value="<?php echo esc_attr( $layout_type ); ?>"
1593
+ <?php
1594
+ if ( $selected_type === $layout_type ) {
1595
+ echo 'checked';}
1596
+ ?>
1597
+ /><label for="sb_layout_type_<?php echo esc_attr( $layout_type ); ?>"><span class="sbi_label"><?php echo esc_html( $label ); ?></span><img alt="Layout Type" src="<?php echo esc_url( $layout_images[ $layout_type ] ); ?>" /></label>
1598
  </div>
1599
  <?php endforeach; ?>
1600
 
1601
+ <p class="sbi_pro_tooltip"><?php esc_html_e( 'Upgrade to the Pro version to unlock these layouts', 'instagram-feed' ); ?><i class="fa fa-caret-down" aria-hidden="true"></i></p>
1602
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=layouts" target="_blank" class="sbi_lock"><i class="fa fa-rocket"></i><?php esc_html_e( 'Pro', 'instagram-feed' ); ?></a>
1603
 
1604
  </div>
1605
  <div class="sb_layout_options_wrap sbi_pro">
1606
  <a href="JavaScript:void(0);" class="sbi_close_options"><i class="fa fa-close"></i></a>
1607
  <div class="sb_instagram_layout_settings sbi_layout_type_grid">
1608
+ <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'A uniform grid of square-cropped images.', 'instagram-feed' ); ?></span>
1609
  </div>
1610
  <div class="sb_instagram_layout_settings sbi_layout_type_masonry">
1611
+ <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Images in their original aspect ratios with no vertical space between posts.', 'instagram-feed' ); ?></span>
1612
  </div>
1613
  <div class="sb_instagram_layout_settings sbi_layout_type_carousel">
1614
  <div class="sb_instagram_layout_setting">
1615
+ <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Posts are displayed in a slideshow carousel.', 'instagram-feed' ); ?></span>
1616
  </div>
1617
  <div class="sb_instagram_layout_setting">
1618
 
1619
+ <label><?php esc_html_e( 'Number of Rows', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> carouselrows
1620
  Eg: carouselrows=2</code>
1621
  <br>
1622
+ <span class="sbi_note" style="margin: -5px 0 -10px 0; display: block;"><?php esc_html_e( 'Use the "Number of Columns" setting below this section to set how many posts are visible in the carousel at a given time.', 'instagram-feed' ); ?></span>
1623
  <br>
1624
  <select name="sb_instagram_carousel_rows" id="sb_instagram_carousel_rows">
1625
  <option value="1">1</option>
1627
  </select>
1628
  </div>
1629
  <div class="sb_instagram_layout_setting">
1630
+ <label><?php esc_html_e( 'Loop Type', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> carouselloop
1631
  Eg: carouselloop=rewind
1632
  carouselloop=infinity</code>
1633
  <br>
1634
  <select name="sb_instagram_carousel_loop" id="sb_instagram_carousel_loop">
1635
+ <option value="rewind"><?php esc_html_e( 'Rewind', 'instagram-feed' ); ?></option>
1636
+ <option value="infinity" selected="selected"><?php esc_html_e( 'Infinity', 'instagram-feed' ); ?></option>
1637
  </select>
1638
  </div>
1639
  <div class="sb_instagram_layout_setting">
1640
  <input type="checkbox" name="sb_instagram_carousel_arrows" id="sb_instagram_carousel_arrows" checked="checked">
1641
+ <label><?php esc_html_e( 'Show Navigation Arrows', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> carouselarrows
1642
  Eg: carouselarrows=true</code>
1643
  </div>
1644
  <div class="sb_instagram_layout_setting">
1645
  <input type="checkbox" name="sb_instagram_carousel_pag" id="sb_instagram_carousel_pag">
1646
+ <label><?php esc_html_e( 'Show Pagination', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> carouselpag
1647
  Eg: carouselpag=true</code>
1648
  </div>
1649
  <div class="sb_instagram_layout_setting">
1650
  <input type="checkbox" name="sb_instagram_carousel_autoplay" id="sb_instagram_carousel_autoplay">
1651
+ <label><?php esc_html_e( 'Enable Autoplay', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> carouselautoplay
1652
  Eg: carouselautoplay=true</code>
1653
  </div>
1654
  <div class="sb_instagram_layout_setting">
1655
+ <label><?php esc_html_e( 'Interval Time', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> carouseltime
1656
  Eg: carouseltime=8000</code>
1657
  <br>
1658
+ <input name="sb_instagram_carousel_interval" type="text" value="5000" size="6"><?php esc_html_e( 'miliseconds', 'instagram-feed' ); ?>
1659
  </div>
1660
  </div>
1661
 
1662
  <div class="sb_instagram_layout_settings sbi_layout_type_highlight">
1663
  <div class="sb_instagram_layout_setting">
1664
+ <i class="fa fa-info-circle" aria-hidden="true" style="margin-right: 8px;"></i><span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Masonry style, square-cropped, image only (no captions or likes/comments below image). "Highlighted" posts are twice as large.', 'instagram-feed' ); ?></span>
1665
  </div>
1666
  <div class="sb_instagram_layout_setting">
1667
+ <label title="Click for shortcode option"><?php esc_html_e( 'Highlighting Type', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> highlighttype
1668
  Eg: highlighttype=pattern</code>
1669
  <br>
1670
  <select name="sb_instagram_highlight_type" id="sb_instagram_highlight_type">
1671
+ <option value="pattern" selected="selected"><?php esc_html_e( 'Pattern', 'instagram-feed' ); ?></option>
1672
+ <option value="id"><?php esc_html_e( 'Post ID', 'instagram-feed' ); ?></option>
1673
+ <option value="hashtag"><?php esc_html_e( 'Hashtag', 'instagram-feed' ); ?></option>
1674
  </select>
1675
  </div>
1676
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_pattern sb_instagram_layout_setting" style="display: block;">
1680
  <input name="sb_instagram_highlight_offset" type="number" min="0" value="0" style="width: 50px;">
1681
  </div>
1682
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_pattern sb_instagram_layout_setting" style="display: block;">
1683
+ <label><?php esc_html_e( 'Pattern', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> highlightpattern
1684
  Eg: highlightpattern=3</code>
1685
  <br>
1686
+ <span><?php esc_html_e( 'Highlight every', 'instagram-feed' ); ?></span><input name="sb_instagram_highlight_factor" type="number" min="2" value="6" style="width: 50px;"><span><?php esc_html_e( 'posts', 'instagram-feed' ); ?></span>
1687
  </div>
1688
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_hashtag sb_instagram_layout_setting" style="display: none;">
1689
+ <label><?php esc_html_e( 'Highlight Posts with these Hashtags', 'instagram-feed' ); ?></label>
1690
+ <input name="sb_instagram_highlight_hashtag" id="sb_instagram_highlight_hashtag" type="text" size="40" value="#fishing">&nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1691
  <br>
1692
+ <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Separate multiple hashtags using commas', 'instagram-feed' ); ?></span>
1693
 
1694
 
1695
+ <p class="sbi_tooltip"><?php esc_html_e( 'You can use this setting to highlight posts by a hashtag. Use a specified hashtag in your posts and they will be automatically highlighted in your feed.', 'instagram-feed' ); ?></p>
1696
  </div>
1697
  <div class="sb_instagram_highlight_sub_options sb_instagram_highlight_ids sb_instagram_layout_setting" style="display: none;">
1698
+ <label><?php esc_html_e( 'Highlight Posts by ID', 'instagram-feed' ); ?></label>
1699
  <textarea name="sb_instagram_highlight_ids" id="sb_instagram_highlight_ids" style="width: 100%;" rows="3">sbi_1852317219231323590_3269008872</textarea>
1700
  <br>
1701
+ <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Separate IDs using commas', 'instagram-feed' ); ?></span>
1702
 
1703
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
1704
+ <p class="sbi_tooltip"><?php esc_html_e( 'You can use this setting to highlight posts by their ID. Enable and use "moderation mode", check the box to show post IDs underneath posts, then copy and paste IDs into this text box.', 'instagram-feed' ); ?></p>
1705
  </div>
1706
  </div>
1707
 
1708
  </div>
1709
  </td>
1710
  </tr>
1711
+ <tr>
1712
+ <th scope="row"><label><?php esc_html_e( 'Number of Photos', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> num
1713
  Eg: num=6</code></th>
1714
  <td>
1715
  <input name="sb_instagram_num" type="text" value="<?php echo esc_attr( $sb_instagram_num ); ?>" size="4" maxlength="4" />
1716
+ <span class="sbi_note"><?php esc_html_e( 'Number of photos to show initially.', 'instagram-feed' ); ?></span>
1717
  </td>
1718
  </tr>
1719
+ <tr>
1720
+ <th scope="row"><label><?php esc_html_e( 'Number of Columns', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> cols
1721
  Eg: cols=3</code></th>
1722
  <td>
1723
  <select name="sb_instagram_cols">
1724
+ <option value="1"
1725
+ <?php
1726
+ if ( $sb_instagram_cols === '1' ) {
1727
+ echo 'selected="selected"';}
1728
+ ?>
1729
+ ><?php esc_html_e( '1', 'instagram-feed' ); ?></option>
1730
+ <option value="2"
1731
+ <?php
1732
+ if ( $sb_instagram_cols === '2' ) {
1733
+ echo 'selected="selected"';}
1734
+ ?>
1735
+ ><?php esc_html_e( '2', 'instagram-feed' ); ?></option>
1736
+ <option value="3"
1737
+ <?php
1738
+ if ( $sb_instagram_cols === '3' ) {
1739
+ echo 'selected="selected"';}
1740
+ ?>
1741
+ ><?php esc_html_e( '3', 'instagram-feed' ); ?></option>
1742
+ <option value="4"
1743
+ <?php
1744
+ if ( $sb_instagram_cols === '4' ) {
1745
+ echo 'selected="selected"';}
1746
+ ?>
1747
+ ><?php esc_html_e( '4', 'instagram-feed' ); ?></option>
1748
+ <option value="5"
1749
+ <?php
1750
+ if ( $sb_instagram_cols === '5' ) {
1751
+ echo 'selected="selected"';}
1752
+ ?>
1753
+ ><?php esc_html_e( '5', 'instagram-feed' ); ?></option>
1754
+ <option value="6"
1755
+ <?php
1756
+ if ( $sb_instagram_cols === '6' ) {
1757
+ echo 'selected="selected"';}
1758
+ ?>
1759
+ ><?php esc_html_e( '6', 'instagram-feed' ); ?></option>
1760
+ <option value="7"
1761
+ <?php
1762
+ if ( $sb_instagram_cols === '7' ) {
1763
+ echo 'selected="selected"';}
1764
+ ?>
1765
+ ><?php esc_html_e( '7', 'instagram-feed' ); ?></option>
1766
+ <option value="8"
1767
+ <?php
1768
+ if ( $sb_instagram_cols === '8' ) {
1769
+ echo 'selected="selected"';}
1770
+ ?>
1771
+ ><?php esc_html_e( '8', 'instagram-feed' ); ?></option>
1772
+ <option value="9"
1773
+ <?php
1774
+ if ( $sb_instagram_cols === '9' ) {
1775
+ echo 'selected="selected"';}
1776
+ ?>
1777
+ ><?php esc_html_e( '9', 'instagram-feed' ); ?></option>
1778
+ <option value="10"
1779
+ <?php
1780
+ if ( $sb_instagram_cols === '10' ) {
1781
+ echo 'selected="selected"';}
1782
+ ?>
1783
+ ><?php esc_html_e( '10', 'instagram-feed' ); ?></option>
1784
  </select>
1785
  </td>
1786
  </tr>
1787
+ <tr>
1788
+ <th scope="row"><label><?php esc_html_e( 'Padding around Images', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> imagepadding imagepaddingunit</code></th>
1789
  <td>
1790
  <input name="sb_instagram_image_padding" type="text" value="<?php echo esc_attr( $sb_instagram_image_padding ); ?>" size="4" maxlength="4" />
1791
  <select name="sb_instagram_image_padding_unit">
1792
+ <option value="px"
1793
+ <?php
1794
+ if ( $sb_instagram_image_padding_unit === 'px' ) {
1795
+ echo 'selected="selected"';}
1796
+ ?>
1797
+ ><?php esc_html_e( 'px', 'instagram-feed' ); ?></option>
1798
+ <option value="%"
1799
+ <?php
1800
+ if ( $sb_instagram_image_padding_unit === '%' ) {
1801
+ echo 'selected="selected"';}
1802
+ ?>
1803
+ ><?php esc_html_e( '%', 'instagram-feed' ); ?></option>
1804
  </select>
1805
  </td>
1806
  </tr>
1807
+ <tr>
1808
+ <th scope="row"><label><?php esc_html_e( 'Disable mobile layout', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> disablemobile
1809
  Eg: disablemobile=true</code></th>
1810
  <td>
1811
+ <input type="checkbox" name="sb_instagram_disable_mobile" id="sb_instagram_disable_mobile"
1812
+ <?php
1813
+ if ( $sb_instagram_disable_mobile ) {
1814
+ echo 'checked="checked"';}
1815
+ ?>
1816
+ />
1817
  &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
1818
+ <p class="sbi_tooltip"><?php esc_html_e( 'By default on mobile devices the layout automatically changes to use fewer columns. Checking this setting disables the mobile layout.', 'instagram-feed' ); ?></p>
1819
  </td>
1820
  </tr>
1821
  </tbody>
1824
  <?php submit_button(); ?>
1825
 
1826
  <hr id="photos" />
1827
+ <h3 id="sbi_photos_heading"><?php esc_html_e( 'Photos', 'instagram-feed' ); ?></h3>
1828
+ <table class="form-table" aria-describedby="sbi_photos_heading">
1829
  <tbody>
1830
+ <tr>
1831
+ <th scope="row"><label><?php esc_html_e( 'Sort Photos By', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> sortby
1832
  Eg: sortby=random</code></th>
1833
  <td>
1834
  <select name="sb_instagram_sort">
1835
+ <option value="none"
1836
+ <?php
1837
+ if ( $sb_instagram_sort === 'none' ) {
1838
+ echo 'selected="selected"';}
1839
+ ?>
1840
+ ><?php esc_html_e( 'Newest to oldest', 'instagram-feed' ); ?></option>
1841
+ <option value="random"
1842
+ <?php
1843
+ if ( $sb_instagram_sort === 'random' ) {
1844
+ echo 'selected="selected"';}
1845
+ ?>
1846
+ ><?php esc_html_e( 'Random', 'instagram-feed' ); ?></option>
1847
  </select>
1848
  </td>
1849
  </tr>
1850
+ <tr>
1851
+ <th scope="row"><label><?php esc_html_e( 'Image Resolution', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> imageres
1852
  Eg: imageres=thumb</code></th>
1853
  <td>
1854
 
1855
  <select name="sb_instagram_image_res">
1856
+ <option value="auto"
1857
+ <?php
1858
+ if ( $sb_instagram_image_res === 'auto' ) {
1859
+ echo 'selected="selected"';}
1860
+ ?>
1861
+ ><?php esc_html_e( 'Auto-detect (recommended)', 'instagram-feed' ); ?></option>
1862
+ <option value="thumb"
1863
+ <?php
1864
+ if ( $sb_instagram_image_res === 'thumb' ) {
1865
+ echo 'selected="selected"';}
1866
+ ?>
1867
+ ><?php esc_html_e( 'Thumbnail (150x150)', 'instagram-feed' ); ?></option>
1868
+ <option value="medium"
1869
+ <?php
1870
+ if ( $sb_instagram_image_res === 'medium' ) {
1871
+ echo 'selected="selected"';}
1872
+ ?>
1873
+ ><?php esc_html_e( 'Medium (320x320)', 'instagram-feed' ); ?></option>
1874
+ <option value="full"
1875
+ <?php
1876
+ if ( $sb_instagram_image_res === 'full' ) {
1877
+ echo 'selected="selected"';}
1878
+ ?>
1879
+ ><?php esc_html_e( 'Full size (640x640)', 'instagram-feed' ); ?></option>
1880
  </select>
1881
 
1882
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does Auto-detect mean?', 'instagram-feed' ); ?></a>
1883
+ <p class="sbi_tooltip"><?php esc_html_e( 'Auto-detect means that the plugin automatically sets the image resolution based on the size of your feed.', 'instagram-feed' ); ?></p>
1884
 
1885
  </td>
1886
  </tr>
1887
  </tbody>
1888
  </table>
1889
 
1890
+ <span><a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a></span>
1891
 
1892
  <div class="sbi-pro-options">
1893
  <p class="sbi-upgrade-link">
1894
+ <i class="fa fa-rocket" aria-hidden="true"></i>&nbsp; <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=general" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable these settings', 'instagram-feed' ); ?></a>
1895
  </p>
1896
  <table class="form-table" aria-describedby="sbi-mediatype-desc">
1897
  <tbody>
1898
+ <tr class="sbi_pro">
1899
+ <th scope="row"><label id="sbi-mediatype-desc"><?php esc_html_e( 'Media Type to Display', 'instagram-feed' ); ?></label></th>
1900
  <td>
1901
  <select name="sb_instagram_media_type" disabled>
1902
+ <option value="all"><?php esc_html_e( 'All', 'instagram-feed' ); ?></option>
1903
+ <option value="photos"><?php esc_html_e( 'Photos only', 'instagram-feed' ); ?></option>
1904
+ <option value="videos"><?php esc_html_e( 'Videos only', 'instagram-feed' ); ?></option>
1905
  </select>
1906
  </td>
1907
  </tr>
1908
 
1909
+ <tr class="sbi_pro">
1910
+ <th scope="row"><label><?php esc_html_e( 'Enable Pop-up Lightbox', 'instagram-feed' ); ?></label></th>
1911
  <td>
1912
  <input type="checkbox" name="sb_instagram_captionlinks" id="sb_instagram_captionlinks" disabled />
1913
  </td>
1914
  </tr>
1915
 
1916
+ <tr class="sbi_pro">
1917
+ <th scope="row"><label><?php esc_html_e( 'Link Posts to URL in Caption (Shoppable feed)', 'instagram-feed' ); ?></label></th>
1918
  <td>
1919
  <input type="checkbox" name="sb_instagram_captionlinks" id="sb_instagram_captionlinks" disabled />
1920
+ &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What will this do?', 'instagram-feed' ); ?></a>
1921
+ <p class="sbi_tooltip"><?php echo wp_kses_post( __( "Checking this box will change the link for each post to any url included in the caption for that Instagram post. The lightbox will be disabled. Visit <a href='https://smashballoon.com/make-a-shoppable-feed?utm_campaign=instagram-free&utm_source=settings&utm_medium=shoppable'>this link</a> to learn how this works.", 'instagram-feed' ) ); ?></p>
1922
  </td>
1923
  </tr>
1924
  </tbody>
1927
 
1928
 
1929
  <hr />
1930
+ <h3 id="sbi-hoverstyle-desc"><?php esc_html_e( 'Photo Hover Style', 'instagram-feed' ); ?></h3>
1931
 
1932
  <p style="padding-bottom: 18px;">
1933
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=photohover" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Photo Hover styles', 'instagram-feed' ); ?></a><br />
1934
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
1935
  </p>
1936
 
1937
  <div class="sbi-pro-options" style="margin-top: -15px;">
1938
  <table class="form-table" aria-describedby="sbi-hoverstyle-desc">
1939
  <tbody>
1940
+ <tr class="sbi_pro">
1941
+ <th scope="row"><label><?php esc_html_e( 'Hover Background Color', 'instagram-feed' ); ?></label></th>
1942
  <td>
1943
  <input name="sb_hover_background" type="text" disabled class="sbi_colorpick" />
1944
  </td>
1945
  </tr>
1946
+ <tr class="sbi_pro">
1947
+ <th scope="row"><label><?php esc_html_e( 'Hover Text Color', 'instagram-feed' ); ?></label></th>
1948
  <td>
1949
  <input name="sb_hover_text" type="text" disabled class="sbi_colorpick" />
1950
  </td>
1951
  </tr>
1952
+ <tr class="sbi_pro">
1953
+ <th scope="row"><label><?php esc_html_e( 'Information to display', 'instagram-feed' ); ?></label></th>
1954
  <td>
1955
  <div>
1956
  <input name="sbi_hover_inc_username" type="checkbox" disabled />
1957
+ <label for="sbi_hover_inc_username"><?php esc_html_e( 'Username', 'instagram-feed' ); ?></label>
1958
  </div>
1959
  <div>
1960
  <input name="sbi_hover_inc_icon" type="checkbox" disabled />
1961
+ <label for="sbi_hover_inc_icon"><?php esc_html_e( 'Expand Icon', 'instagram-feed' ); ?></label>
1962
  </div>
1963
  <div>
1964
  <input name="sbi_hover_inc_date" type="checkbox" disabled />
1965
+ <label for="sbi_hover_inc_date"><?php esc_html_e( 'Date', 'instagram-feed' ); ?></label>
1966
  </div>
1967
  <div>
1968
  <input name="sbi_hover_inc_instagram" type="checkbox" disabled />
1969
+ <label for="sbi_hover_inc_instagram"><?php esc_html_e( 'Instagram Icon/Link', 'instagram-feed' ); ?></label>
1970
  </div>
1971
  <div>
1972
  <input name="sbi_hover_inc_location" type="checkbox" disabled />
1973
+ <label for="sbi_hover_inc_location"><?php esc_html_e( 'Location', 'instagram-feed' ); ?></label>
1974
  </div>
1975
  <div>
1976
  <input name="sbi_hover_inc_caption" type="checkbox" disabled />
1977
+ <label for="sbi_hover_inc_caption"><?php esc_html_e( 'Caption', 'instagram-feed' ); ?></label>
1978
  </div>
1979
  <div>
1980
  <input name="sbi_hover_inc_likes" type="checkbox" disabled />
1981
+ <label for="sbi_hover_inc_likes"><?php esc_html_e( 'Like/Comment Icons', 'instagram-feed' ); ?></label>
1982
  </div>
1983
  </td>
1984
  </tr>
1991
  <hr />
1992
  <h3 id="sbi-carousel-desc"><?php esc_html_e( 'Carousel', 'instagram-feed' ); ?></h3>
1993
  <p style="padding-bottom: 18px;">
1994
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=carousel" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Carousels', 'instagram-feed' ); ?></a><br />
1995
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
1996
  </p>
1997
 
1998
  <div class="sbi-pro-options" style="margin-top: -15px;">
1999
  <table class="form-table" aria-describedby="sbi-carousel-desc">
2000
  <tbody>
2001
+ <tr class="sbi_pro">
2002
+ <th scope="row"><label><?php esc_html_e( 'Enable Carousel', 'instagram-feed' ); ?></label></th>
2003
  <td>
2004
  <input type="checkbox" disabled />
2005
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2006
+ <p class="sbi_tooltip"><?php esc_html_e( 'Enable this setting to create a carousel slider out of your photos.', 'instagram-feed' ); ?></p>
2007
  </td>
2008
  </tr>
2009
+ <tr class="sbi_pro">
2010
+ <th scope="row"><label><?php esc_html_e( 'Show Navigation Arrows', 'instagram-feed' ); ?></label></th>
2011
  <td>
2012
  <input type="checkbox" disabled />
2013
  </td>
2014
  </tr>
2015
+ <tr class="sbi_pro">
2016
+ <th scope="row"><label><?php esc_html_e( 'Show Pagination', 'instagram-feed' ); ?></label></th>
2017
  <td>
2018
  <input type="checkbox" disabled />
2019
  </td>
2020
  </tr>
2021
+ <tr class="sbi_pro">
2022
+ <th scope="row"><label><?php esc_html_e( 'Enable Autoplay', 'instagram-feed' ); ?></label></th>
2023
  <td>
2024
  <input type="checkbox" disabled />
2025
  </td>
2026
  </tr>
2027
+ <tr class="sbi_pro">
2028
+ <th scope="row"><label><?php esc_html_e( 'Interval Time', 'instagram-feed' ); ?></label></th>
2029
  <td>
2030
+ <input name="sb_instagram_carousel_interval" type="text" disabled size="6" /><?php esc_html_e( 'milliseconds', 'instagram-feed' ); ?>
2031
  </td>
2032
  </tr>
2033
  </tbody>
2037
 
2038
 
2039
  <hr id="headeroptions" />
2040
+ <h3 id="sbi_header_heading"><?php esc_html_e( 'Header', 'instagram-feed' ); ?></h3>
2041
+ <table class="form-table" aria-describedby="sbi_header_heading">
2042
  <tbody>
2043
+ <tr>
2044
+ <th scope="row"><label><?php esc_html_e( 'Show Feed Header', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> showheader
2045
  Eg: showheader=false</code></th>
2046
  <td>
2047
+ <input type="checkbox" name="sb_instagram_show_header" id="sb_instagram_show_header"
2048
+ <?php
2049
+ if ( $sb_instagram_show_header ) {
2050
+ echo 'checked="checked"';}
2051
+ ?>
2052
+ />
2053
+ </td>
2054
+ </tr>
2055
+ <tr>
2056
+ <th scope="row"><label><?php esc_html_e( 'Header Size', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> headersize
2057
+ Eg: headersize=medium</code></th>
2058
+ <td>
2059
+ <select name="sb_instagram_header_size" id="sb_instagram_header_size" style="float: left;">
2060
+ <option value="small"
2061
+ <?php
2062
+ if ( $sb_instagram_header_size === 'small' ) {
2063
+ echo 'selected="selected"';}
2064
+ ?>
2065
+ ><?php esc_html_e( 'Small', 'instagram-feed' ); ?></option>
2066
+ <option value="medium"
2067
+ <?php
2068
+ if ( $sb_instagram_header_size === 'medium' ) {
2069
+ echo 'selected="selected"';}
2070
+ ?>
2071
+ ><?php esc_html_e( 'Medium', 'instagram-feed' ); ?></option>
2072
+ <option value="large"
2073
+ <?php
2074
+ if ( $sb_instagram_header_size === 'large' ) {
2075
+ echo 'selected="selected"';}
2076
+ ?>
2077
+ ><?php esc_html_e( 'Large', 'instagram-feed' ); ?></option>
2078
+ </select>
2079
+ </td>
2080
+ </tr>
2081
+ <tr>
2082
+ <th scope="row"><label><?php esc_html_e( 'Show Bio Text', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> showbio
2083
+ Eg: showbio=false</code></th>
2084
+ <td>
2085
+ <?php $sb_instagram_show_bio = isset( $sb_instagram_show_bio ) ? $sb_instagram_show_bio : true; ?>
2086
+ <input type="checkbox" name="sb_instagram_show_bio" id="sb_instagram_show_bio"
2087
+ <?php
2088
+ if ( $sb_instagram_show_bio ) {
2089
+ echo 'checked="checked"';}
2090
+ ?>
2091
+ />
2092
+ <span class="sbi_note"><?php esc_html_e( 'Only applies for Instagram accounts with bios', 'instagram-feed' ); ?></span>
2093
+ <div class="sb_instagram_box" style="display: block;">
2094
+ <div class="sb_instagram_box_setting" style="display: block;">
2095
+ <label style="padding-bottom: 0;"><?php esc_html_e( 'Add Custom Bio Text', 'instagram-feed' ); ?></label><code class="sbi_shortcode" style="margin-top: 5px;"> custombio
2096
+ Eg: custombio="My custom bio."</code>
2097
+ <br>
2098
+ <span class="sbi_aside" style="padding-bottom: 5px; display: block;"><?php esc_html_e( 'Use your own custom bio text in the feed header. Bio text is automatically retrieved from Instagram for Business accounts.', 'instagram-feed' ); ?></span>
2099
+
2100
+ <textarea type="text" name="sb_instagram_custom_bio" id="sb_instagram_custom_bio" ><?php echo esc_textarea( wp_unslash( $sb_instagram_custom_bio ) ); ?></textarea>
2101
+ &nbsp;<a class="sbi_tooltip_link sbi_tooltip_under" href="JavaScript:void(0);"><?php esc_html_e( 'Why is my bio not displaying automatically?', 'instagram-feed' ); ?></a>
2102
+ <p class="sbi_tooltip" style="padding: 10px 0 0 0; width: 99%;"><?php echo wp_kses_post( sprintf( __( 'Instagram is deprecating their old API for Personal accounts on June 1, 2020. The plugin supports their new API, however, their new API does not yet include the bio text for Personal accounts. If you require this feature then it is available if you convert your Instagram account from a Personal to a Business account by following %s. Note: If you previously had a Personal account connected then the plugin has saved the avatar for that feed and will continue to use it automatically.', 'instagram-feed' ), '<a href="https://smashballoon.com/instagram-business-profiles/" target="_blank">these directions</a>' ) ); ?></p>
2103
+ </div>
2104
+ </div>
2105
+
2106
+ </td>
2107
+ </tr>
2108
+
2109
+ <tr>
2110
+ <th scope="row"><label><?php esc_html_e( 'Use Custom Avatar', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> customavatar
2111
+ Eg: customavatar="https://my-website.com/avatar.jpg"</code></th>
2112
+ <td>
2113
+ <input type="text" name="sb_instagram_custom_avatar" class="large-text" id="sb_instagram_custom_avatar" value="<?php echo esc_attr( wp_unslash( $sb_instagram_custom_avatar ) ); ?>" placeholder="https://example.com/avatar.jpg" />
2114
+ <span class="sbi_aside"><?php esc_html_e( 'Avatar is automatically retrieved from Instagram for Business accounts', 'instagram-feed' ); ?></span>
2115
+ <br>
2116
+ <a class="sbi_tooltip_link sbi_tooltip_under" href="JavaScript:void(0);"><?php esc_html_e( 'Why is my avatar not displaying automatically?', 'instagram-feed' ); ?></a>
2117
+
2118
+ <p class="sbi_tooltip sbi_tooltip_under_text" style="padding: 10px 0 0 0;"><?php echo wp_kses_post( sprintf( __( 'Instagram is deprecating their old API for Personal accounts on June 1, 2020. The plugin supports their new API, however, their new API does not yet include the avatar image for Personal accounts. If you require this feature then it is available if you convert your Instagram account from a Personal to a Business account by following %s. Note: If you previously had a Personal account connected then the plugin has saved the bio text for that feed and will continue to use it automatically.', 'instagram-feed' ), '<a href="https://smashballoon.com/instagram-business-profiles/" target="_blank">these directions</a>' ) ); ?></p>
2119
+
2120
  </td>
2121
  </tr>
2122
+ <tr>
2123
+ <th scope="row"><label><?php esc_html_e( 'Header Text Color', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> headercolor
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2124
  Eg: headercolor=fff</code></th>
2125
  <td>
2126
  <input name="sb_instagram_header_color" type="text" value="<?php echo esc_attr( $sb_instagram_header_color ); ?>" class="sbi_colorpick" />
2129
  </tbody>
2130
  </table>
2131
 
2132
+ <span><a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a></span>
2133
 
2134
  <div class="sbi-pro-options">
2135
  <p class="sbi-upgrade-link">
2136
+ <i class="fa fa-rocket" aria-hidden="true"></i>&nbsp; <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=header" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable these settings', 'instagram-feed' ); ?></a>
2137
  </p>
2138
+ <table class="form-table sbi-expandable-options" aria-describedby="sbi-headerstylesub-desc">
2139
+ <tbody>
2140
 
2141
+ <tr>
2142
+ <th scope="row" id="sbi-headerstylesub-desc"><label><?php esc_html_e( 'Header Style', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> headerstyle
2143
+ Eg: headerstyle=boxed</code></th>
2144
+ <td>
2145
  <select name="sb_instagram_header_style" style="float: left;">
2146
+ <option value="circle"><?php esc_html_e( 'Standard', 'instagram-feed' ); ?></option>
2147
+ <option value="boxed"><?php esc_html_e( 'Boxed', 'instagram-feed' ); ?></option>
2148
+ <option value="centered"><?php esc_html_e( 'Centered', 'instagram-feed' ); ?></option>
2149
  </select>
2150
  </td>
2151
  </tr>
2152
+ <tr class="sbi_pro">
2153
+ <th scope="row"><label><?php esc_html_e( 'Show Number of Followers', 'instagram-feed' ); ?></label></th>
2154
  <td>
2155
  <input type="checkbox" disabled />
2156
+ <span class="sbi_note"><?php esc_html_e( 'This only applies when displaying photos from a User ID', 'instagram-feed' ); ?></span>
2157
  </td>
2158
  </tr>
2159
  </tbody>
2164
 
2165
 
2166
  <hr />
2167
+ <h3 id="sbi_caption_heading"><?php esc_html_e( 'Caption', 'instagram-feed' ); ?></h3>
2168
  <p style="padding-bottom: 18px;">
2169
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=caption" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Photo Captions', 'instagram-feed' ); ?></a><br />
2170
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
2171
  </p>
2172
 
2173
  <div class="sbi-pro-options" style="margin-top: -15px;">
2174
+ <table class="form-table" aria-describedby="sbi_caption_heading">
2175
  <tbody>
2176
+ <tr class="sbi_pro">
2177
+ <th scope="row"><label><?php esc_html_e( 'Show Caption', 'instagram-feed' ); ?></label></th>
2178
  <td>
2179
  <input type="checkbox" disabled />
2180
  </td>
2181
  </tr>
2182
+ <tr class="sbi_pro">
2183
+ <th scope="row"><label><?php esc_html_e( 'Maximum Text Length', 'instagram-feed' ); ?></label></th>
2184
  <td>
2185
  <input disabled size="4" />Characters
2186
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2187
+ <p class="sbi_tooltip"><?php esc_html_e( 'The number of characters of text to display in the caption. An elipsis link will be added to allow the user to reveal more text if desired.', 'instagram-feed' ); ?></p>
2188
  </td>
2189
  </tr>
2190
+ <tr class="sbi_pro">
2191
+ <th scope="row"><label><?php esc_html_e( 'Text Color', 'instagram-feed' ); ?></label></th>
2192
  <td>
2193
  <input type="text" disabled class="sbi_colorpick" />
2194
  </td>
2195
  </tr>
2196
+ <tr class="sbi_pro">
2197
+ <th scope="row"><label><?php esc_html_e( 'Text Size', 'instagram-feed' ); ?></label></th>
2198
  <td>
2199
  <select name="sb_instagram_caption_size" style="width: 180px;" disabled>
2200
+ <option value="inherit" ><?php esc_html_e( 'Inherit from theme', 'instagram-feed' ); ?></option>
2201
  <option value="10" >10px</option>
2202
  <option value="11" >11px</option>
2203
  <option value="12" >12px</option>
2220
 
2221
 
2222
  <hr />
2223
+ <h3 id="sbi_likescomments_heading"><?php esc_html_e( 'Likes &amp; Comments', 'instagram-feed' ); ?></h3>
2224
  <p style="padding-bottom: 18px;">
2225
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=stats" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Likes &amp; Comments', 'instagram-feed' ); ?></a><br />
2226
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
2227
  </p>
2228
 
2229
  <div class="sbi-pro-options" style="margin-top: -15px;">
2230
  <table class="form-table" aria-describedby="sbi_likescomments_heading">
2231
  <tbody>
2232
+ <tr class="sbi_pro">
2233
+ <th scope="row"><label><?php esc_html_e( 'Show Icons', 'instagram-feed' ); ?></label></th>
2234
  <td>
2235
  <input type="checkbox" disabled />
2236
  </td>
2237
  </tr>
2238
+ <tr class="sbi_pro">
2239
+ <th scope="row"><label><?php esc_html_e( 'Icon Color', 'instagram-feed' ); ?></label></th>
2240
  <td>
2241
  <input type="text" disabled class="sbi_colorpick" />
2242
  </td>
2243
  </tr>
2244
+ <tr class="sbi_pro">
2245
+ <th scope="row"><label><?php esc_html_e( 'Icon Size', 'instagram-feed' ); ?></label></th>
2246
  <td>
2247
  <select disabled name="sb_instagram_meta_size" style="width: 180px;">
2248
+ <option value="inherit"><?php esc_html_e( 'Inherit from theme', 'instagram-feed' ); ?></option>
2249
  <option value="10" >10px</option>
2250
  <option value="11" >11px</option>
2251
  <option value="12" >12px</option>
2268
 
2269
 
2270
  <hr />
2271
+ <h3 id="sbi-lightboxcomments-heading"><?php esc_html_e( 'Lightbox Comments', 'instagram-feed' ); ?></h3>
2272
 
2273
  <p style="padding-bottom: 18px;">
2274
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=comments" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Comments', 'instagram-feed' ); ?></a><br />
2275
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
2276
  </p>
2277
 
2278
  <div class="sbi-pro-options" style="margin-top: -15px;">
2279
  <table class="form-table" aria-describedby="sbi-lightboxcomments-heading">
2280
  <tbody>
2281
 
2282
+ <tr class="sbi_pro">
2283
+ <th scope="row"><label><?php esc_html_e( 'Show Comments in Lightbox', 'instagram-feed' ); ?></label></th>
2284
  <td style="padding: 5px 10px 0 10px;">
2285
  <input type="checkbox" disabled style="margin-right: 15px;" />
2286
  <input class="button-secondary" style="margin-top: -5px;" disabled value="<?php esc_attr_e( 'Clear Comment Cache', 'instagram-feed' ); ?>" />
2287
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2288
+ <p class="sbi_tooltip"><?php esc_html_e( 'This will remove the cached comments saved in the database', 'instagram-feed' ); ?></p>
2289
  </td>
2290
  </tr>
2291
+ <tr class="sbi_pro">
2292
+ <th scope="row"><label><?php esc_html_e( 'Number of Comments', 'instagram-feed' ); ?></label></th>
2293
  <td>
2294
  <input name="sb_instagram_num_comments" type="text" disabled size="4" />
2295
+ <span class="sbi_note"><?php esc_html_e( 'Max number of latest comments.', 'instagram-feed' ); ?></span>
2296
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2297
+ <p class="sbi_tooltip"><?php esc_html_e( 'This is the maximum number of comments that will be shown in the lightbox. If there are more comments available than the number set, only the latest comments will be shown', 'instagram-feed' ); ?></p>
2298
  </td>
2299
  </tr>
2300
 
2304
 
2305
 
2306
  <hr id="loadmore" />
2307
+ <h3 id="sbi_button_heading"><?php esc_html_e( "'Load More' Button", 'instagram-feed' ); ?></h3>
2308
+ <table class="form-table" aria-describedby="sbi_button_heading">
2309
  <tbody>
2310
+ <tr>
2311
+ <th scope="row"><label><?php esc_html_e( "Show the 'Load More' button", 'instagram-feed' ); ?></label><code class="sbi_shortcode"> showbutton
2312
  Eg: showbutton=false</code></th>
2313
  <td>
2314
+ <input type="checkbox" name="sb_instagram_show_btn" id="sb_instagram_show_btn"
2315
+ <?php
2316
+ if ( $sb_instagram_show_btn ) {
2317
+ echo 'checked="checked"';}
2318
+ ?>
2319
+ />
2320
  </td>
2321
  </tr>
2322
+ <tr>
2323
+ <th scope="row"><label><?php esc_html_e( 'Button Background Color', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> buttoncolor
2324
  Eg: buttoncolor=8224e3</code></th>
2325
  <td>
2326
  <input name="sb_instagram_btn_background" type="text" value="<?php echo esc_attr( $sb_instagram_btn_background ); ?>" class="sbi_colorpick" />
2327
  </td>
2328
  </tr>
2329
+ <tr>
2330
+ <th scope="row"><label><?php esc_html_e( 'Button Text Color', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> buttontextcolor
2331
  Eg: buttontextcolor=eeee22</code></th>
2332
  <td>
2333
  <input name="sb_instagram_btn_text_color" type="text" value="<?php echo esc_attr( $sb_instagram_btn_text_color ); ?>" class="sbi_colorpick" />
2334
  </td>
2335
  </tr>
2336
+ <tr>
2337
+ <th scope="row"><label><?php esc_html_e( 'Button Text', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> buttontext
2338
  Eg: buttontext="Show more.."</code></th>
2339
  <td>
2340
  <input name="sb_instagram_btn_text" type="text" value="<?php echo esc_attr( wp_unslash( $sb_instagram_btn_text ) ); ?>" size="20" />
2346
  <?php submit_button(); ?>
2347
 
2348
  <hr id="follow" />
2349
+ <h3 id="sbi_follow_heading"><?php esc_html_e( "'Follow' Button", 'instagram-feed' ); ?></h3>
2350
+ <table class="form-table" aria-describedby="sbi_follow_heading">
2351
  <tbody>
2352
+ <tr>
2353
+ <th scope="row"><label><?php esc_html_e( 'Show the Follow button', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> showfollow
2354
  Eg: showfollow=true</code></th>
2355
  <td>
2356
+ <input type="checkbox" name="sb_instagram_show_follow_btn" id="sb_instagram_show_follow_btn"
2357
+ <?php
2358
+ if ( $sb_instagram_show_follow_btn ) {
2359
+ echo 'checked="checked"';}
2360
+ ?>
2361
+ />
2362
  </td>
2363
  </tr>
2364
 
2365
+ <tr>
2366
+ <th scope="row"><label><?php esc_html_e( 'Button Background Color', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> followcolor
2367
  Eg: followcolor=28a1bf</code></th>
2368
  <td>
2369
  <input name="sb_instagram_folow_btn_background" type="text" value="<?php echo esc_attr( $sb_instagram_folow_btn_background ); ?>" class="sbi_colorpick" />
2370
  </td>
2371
  </tr>
2372
+ <tr>
2373
+ <th scope="row"><label><?php esc_html_e( 'Button Text Color', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> followtextcolor
2374
  Eg: followtextcolor=000</code></th>
2375
  <td>
2376
  <input name="sb_instagram_follow_btn_text_color" type="text" value="<?php echo esc_attr( $sb_instagram_follow_btn_text_color ); ?>" class="sbi_colorpick" />
2377
  </td>
2378
  </tr>
2379
+ <tr>
2380
+ <th scope="row"><label><?php esc_html_e( 'Button Text', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> followtext
2381
  Eg: followtext="Follow me"</code></th>
2382
  <td>
2383
  <input name="sb_instagram_follow_btn_text" type="text" value="<?php echo esc_attr( wp_unslash( $sb_instagram_follow_btn_text ) ); ?>" size="30" />
2387
  </table>
2388
 
2389
  <hr id="filtering" />
2390
+ <h3 id="sbi-filter-heading"><?php esc_html_e( 'Post Filtering', 'instagram-feed' ); ?></h3>
2391
 
2392
  <p style="padding-bottom: 18px;">
2393
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=filtering" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Post Filtering options', 'instagram-feed' ); ?></a><br />
2394
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
2395
  </p>
2396
 
2397
  <div class="sbi-pro-options" style="margin-top: -15px;">
2398
 
2399
  <table class="form-table" aria-describedby="sbi-filter-heading">
2400
  <tbody>
2401
+ <tr class="sbi_pro">
2402
+ <th scope="row"><label><?php esc_html_e( 'Remove photos containing these words or hashtags', 'instagram-feed' ); ?></label></th>
2403
  <td>
2404
  <div class="sb_instagram_apply_labels">
2405
+ <p><?php esc_html_e( 'Apply to:', 'instagram-feed' ); ?></p>
2406
+ <input class="sb_instagram_incex_one_all" type="radio" value="all" disabled /><label><?php esc_html_e( 'All feeds', 'instagram-feed' ); ?></label>
2407
+ <input class="sb_instagram_incex_one_all" type="radio" value="one" disabled /><label><?php esc_html_e( 'One feed', 'instagram-feed' ); ?></label>
2408
  </div>
2409
 
2410
  <input disabled name="sb_instagram_exclude_words" id="sb_instagram_exclude_words" type="text" style="width: 70%;" value="" />
2411
  <br />
2412
+ <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Separate words/hashtags using commas', 'instagram-feed' ); ?></span>
2413
+ &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2414
+ <p class="sbi_tooltip"><?php esc_html_e( 'You can use this setting to remove photos which contain certain words or hashtags in the caption. Separate multiple words or hashtags using commas.', 'instagram-feed' ); ?></p>
2415
  </td>
2416
  </tr>
2417
 
2418
+ <tr class="sbi_pro">
2419
+ <th scope="row"><label><?php esc_html_e( 'Show photos containing these words or hashtags', 'instagram-feed' ); ?></label></th>
2420
  <td>
2421
  <div class="sb_instagram_apply_labels">
2422
+ <p><?php esc_html_e( 'Apply to:', 'instagram-feed' ); ?></p>
2423
+ <input class="sb_instagram_incex_one_all" type="radio" value="all" disabled /><label><?php esc_html_e( 'All feeds', 'instagram-feed' ); ?></label>
2424
+ <input class="sb_instagram_incex_one_all" type="radio" value="one" disabled /><label><?php esc_html_e( 'One feed', 'instagram-feed' ); ?></label>
2425
  </div>
2426
 
2427
  <input disabled name="sb_instagram_include_words" id="sb_instagram_include_words" type="text" style="width: 70%;" value="" />
2428
  <br />
2429
+ <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Separate words/hashtags using commas', 'instagram-feed' ); ?></span>
2430
+ &nbsp;<a class="sbi_tooltip_link sbi_pro" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2431
+ <p class="sbi_tooltip"><?php esc_html_e( 'You can use this setting to only show photos which contain certain words or hashtags in the caption. For example, adding "sheep, cow, dog" will show any photos which contain either the word sheep, cow, or dog. Separate multiple words or hashtags using commas.', 'instagram-feed' ); ?></p>
2432
  </td>
2433
  </tr>
2434
  </tbody>
2437
 
2438
 
2439
  <hr id="moderation" />
2440
+ <h3 id="sbi-moderation-heading"><?php esc_html_e( 'Moderation', 'instagram-feed' ); ?></h3>
2441
 
2442
  <p style="padding-bottom: 18px;">
2443
+ <a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=moderation" target="_blank"><?php esc_html_e( 'Upgrade to Pro to enable Moderation options', 'instagram-feed' ); ?></a><br />
2444
+ <a href="javascript:void(0);" class="button button-secondary sbi-show-pro"><strong>+</strong> <?php esc_html_e( 'Show Pro Options', 'instagram-feed' ); ?></a>
2445
  </p>
2446
 
2447
  <div class="sbi-pro-options" style="margin-top: -15px;">
2448
  <table class="form-table" aria-describedby="sbi-moderation-heading">
2449
  <tbody>
2450
+ <tr class="sbi_pro">
2451
+ <th scope="row"><label><?php esc_html_e( 'Moderation Type', 'instagram-feed' ); ?></label></th>
2452
  <td>
2453
+ <input class="sb_instagram_moderation_mode" checked="checked" disabled type="radio" value="visual" style="margin-top: 0;" /><label><?php esc_html_e( 'Visual', 'instagram-feed' ); ?></label>
2454
+ <input class="sb_instagram_moderation_mode" disabled type="radio" value="manual" style="margin-top: 0; margin-left: 10px;"/><label><?php esc_html_e( 'Manual', 'instagram-feed' ); ?></label>
2455
 
2456
+ <p class="sbi_tooltip" style="display: block;"><?php echo wp_kses_post( "<strong>Visual Moderation Mode</strong><br />This adds a button to each feed that will allow you to hide posts, block users, and create white lists from the front end using a visual interface. Visit <a href='https://smashballoon.com/guide-to-moderation-mode/?utm_campaign=instagram-free&utm_source=settings&utm_medium=moderationmode' target='_blank'>this page</a> for details", 'instagram-feed' ); ?></p>
2457
 
2458
  </td>
2459
  </tr>
2460
 
2461
+ <tr class="sbi_pro">
2462
+ <th scope="row"><label><?php esc_html_e( 'Only show posts by these users', 'instagram-feed' ); ?></label></th>
2463
  <td>
2464
  <input type="text" style="width: 70%;" disabled /><br />
2465
+ <span class="sbi_note" style="margin-left: 0;"><?php esc_html_e( 'Separate usernames using commas', 'instagram-feed' ); ?></span>
2466
 
2467
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2468
+ <p class="sbi_tooltip"><?php esc_html_e( 'You can use this setting to show photos only from certain users in your feed. Just enter the usernames here which you want to show. Separate multiple usernames using commas.', 'instagram-feed' ); ?></p>
2469
  </td>
2470
  </tr>
2471
+ <tr class="sbi_pro">
2472
+ <th scope="row"><label><?php esc_html_e( 'White lists', 'instagram-feed' ); ?></label></th>
2473
  <td>
2474
  <div class="sbi_white_list_names_wrapper">
2475
+ <?php esc_html_e( 'No white lists currently created', 'instagram-feed' ); ?>
2476
  </div>
2477
 
2478
  <input disabled class="button-secondary" type="submit" value="<?php esc_attr_e( 'Clear White Lists', 'instagram-feed' ); ?>" />
2479
+ &nbsp;<a class="sbi_tooltip_link" href="JavaScript:void(0);" style="display: inline-block; margin-top: 5px;"><?php esc_html_e( 'What is this?', 'instagram-feed' ); ?></a>
2480
+ <p class="sbi_tooltip"><?php esc_html_e( 'This will remove all of the white lists from the database', 'instagram-feed' ); ?></p>
2481
  </td>
2482
  </tr>
2483
 
2485
  </table>
2486
  </div>
2487
 
2488
+ <hr id="gdpr" />
2489
+ <h3 id="sbi-gdpr-heading"><?php esc_html_e( 'GDPR', 'instagram-feed' ); ?></h3>
2490
 
2491
+ <table class="form-table" aria-describedby="sbi-gdpr-heading">
2492
+ <tbody>
2493
+ <tr>
2494
+ <th scope="row" class="bump-left"><label class="bump-left"><?php esc_html_e( 'Enable GDPR settings', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> gdpr
2495
+ Eg: gdpr=yes</code></th>
2496
+ <td>
2497
 
2498
  <?php
2499
  $select_options = array(
2500
  array(
2501
  'label' => __( 'Automatic', 'instagram-feed' ),
2502
+ 'value' => 'auto',
2503
  ),
2504
  array(
2505
  'label' => __( 'Yes', 'instagram-feed' ),
2506
+ 'value' => 'yes',
2507
  ),
2508
  array(
2509
  'label' => __( 'No', 'instagram-feed' ),
2510
+ 'value' => 'no',
2511
+ ),
2512
  )
2513
  ?>
2514
  <?php
2515
  $gdpr_list = "<ul class='sbi-list'>
2516
+ <li>" . __( 'Only local images (not from Instagram\'s CDN) will be displayed in the feed.', 'instagram-feed' ) . '</li>
2517
+ <li>' . __( 'Placeholder blank images will be displayed until images are available.', 'instagram-feed' ) . '</li>
2518
+ </ul>';
2519
  ?>
2520
+ <div>
2521
+ <select name="gdpr" id="sbi_gdpr_setting">
2522
+ <?php
2523
+ foreach ( $select_options as $select_option ) :
2524
  $selected = $select_option['value'] === $gdpr ? ' selected' : '';
2525
  ?>
2526
+ <option value="<?php echo esc_attr( $select_option['value'] ); ?>"<?php echo esc_attr( $selected ); ?> ><?php echo esc_html( $select_option['label'] ); ?></option>
2527
  <?php endforeach; ?>
2528
+ </select>
2529
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2530
+ <div class="sbi_tooltip gdpr_tooltip">
2531
 
2532
+ <p><span><?php esc_html_e( 'Yes', 'instagram-feed' ); ?>:</span> <?php esc_html_e( "Enabling this setting prevents all images and videos from being loaded directly from Instagram's servers (CDN) to prevent any requests to external websites in your browser. To accommodate this, some features of the plugin will be disabled or limited.", 'instagram-feed' ); ?> <a href="JavaScript:void(0);" class="sbi_show_gdpr_list"><?php esc_html_e( 'What will be limited?', 'instagram-feed' ); ?></a></p>
2533
 
2534
+ <?php echo "<div class='sbi_gdpr_list'>" . wp_kses_post( $gdpr_list ) . '</div>'; ?>
2535
 
2536
 
2537
+ <p><span><?php esc_html_e( 'No', 'instagram-feed' ); ?>:</span> <?php esc_html_e( 'The plugin will still make some requests to load and display images and videos directly from Instagram.', 'instagram-feed' ); ?></p>
2538
 
2539
 
2540
+ <p><span><?php esc_html_e( 'Automatic', 'instagram-feed' ); ?>:</span> <?php echo wp_kses_post( sprintf( __( 'The plugin will only load images and videos directly from Instagram if consent has been given by one of these integrated %s', 'instagram-feed' ), '<a href="https://smashballoon.com/doc/gdpr-plugin-list/?instagram" target="_blank" rel="noopener">' . __( 'GDPR cookie plugins', 'instagram-feed' ) . '</a>' ) ); ?></p>
2541
 
2542
+ <p><?php echo wp_kses_post( sprintf( __( '%s to learn more about GDPR compliance in the Instagram Feed plugin.', 'instagram-feed' ), '<a href="https://smashballoon.com/doc/instagram-feed-gdpr-compliance/?instagram" target="_blank" rel="noopener">' . __( 'Click here', 'instagram-feed' ) . '</a>' ) ); ?></p>
2543
+ </div>
2544
+ </div>
2545
 
2546
+ <?php
2547
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2548
+ if ( ! SB_Instagram_GDPR_Integrations::gdpr_tests_successful( isset( $_GET['retest'] ) ) ) :
2549
  $errors = SB_Instagram_GDPR_Integrations::gdpr_tests_error_message();
2550
  ?>
2551
+ <div class="sb_instagram_box sbi_gdpr_error">
2552
+ <div class="sb_instagram_box_setting">
2553
+ <p>
2554
+ <strong><?php esc_html_e( 'Error:', 'instagram-feed' ); ?></strong> <?php esc_html_e( 'Due to a configuration issue on your web server, the GDPR setting is unable to be enabled.', 'instagram-feed' ); ?></p>
2555
+ <p>
2556
+ <?php echo wp_kses_post( $errors ); ?>
2557
+ </p>
2558
+ </div>
2559
+ </div>
2560
+ <?php else : ?>
2561
+
2562
+ <div class="sbi_gdpr_auto">
2563
+ <?php
2564
+ if ( SB_Instagram_GDPR_Integrations::gdpr_plugins_active() ) :
2565
  $active_plugin = SB_Instagram_GDPR_Integrations::gdpr_plugins_active();
2566
  ?>
2567
+ <div class="sbi_gdpr_plugin_active">
2568
+ <div class="sbi_active">
2569
+ <p>
2570
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-check-circle fa-w-16 fa-2x"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z" class=""></path></svg>
2571
+ <strong><?php echo wp_kses_post( sprintf( __( '%s detected', 'instagram-feed' ), $active_plugin ) ); ?></strong>
2572
+ <br />
2573
  <?php esc_html_e( 'Some Instagram Feed features will be limited for visitors to ensure GDPR compliance until they give consent.', 'instagram-feed' ); ?>
2574
+ <a href="JavaScript:void(0);" class="sbi_show_gdpr_list"><?php esc_html_e( 'What will be limited?', 'instagram-feed' ); ?></a>
2575
+ </p>
2576
+ <?php echo "<div class='sbi_gdpr_list'>" . wp_kses_post( $gdpr_list ) . '</div>'; ?>
2577
+ </div>
2578
+
2579
+ </div>
2580
+ <?php else : ?>
2581
+ <div class="sb_instagram_box">
2582
+ <div class="sb_instagram_box_setting">
2583
+ <p><?php echo wp_kses_post( sprintf( __( 'No GDPR consent plugin detected. Install a compatible %1$sGDPR consent plugin%2$s, or manually enable the setting above to display a GDPR compliant version of the feed to all visitors.', 'instagram-feed' ), '<a href="https://smashballoon.com/doc/gdpr-plugin-list/?instagram" target="_blank" rel="noopener">', '</a>' ) ); ?></p>
2584
+ </div>
2585
+ </div>
2586
  <?php endif; ?>
2587
+ </div>
2588
 
2589
+ <div class="sb_instagram_box sbi_gdpr_yes">
2590
+ <div class="sb_instagram_box_setting">
2591
+ <p><?php esc_html_e( 'No requests will be made to third-party websites. To accommodate this, some features of the plugin will be limited:', 'instagram-feed' ); ?></p>
2592
+ <?php echo wp_kses_post( $gdpr_list ); ?>
2593
+ </div>
2594
+ </div>
2595
 
2596
+ <div class="sb_instagram_box sbi_gdpr_no">
2597
+ <div class="sb_instagram_box_setting">
2598
+ <p><?php esc_html_e( 'The plugin will function as normal and load images directly from Instagram.', 'instagram-feed' ); ?></p>
2599
+ </div>
2600
+ </div>
2601
 
2602
  <?php endif; ?>
2603
+ </td>
2604
+ </tr>
2605
 
2606
+ </tbody>
2607
+ </table>
2608
 
2609
  <hr id="customcss" />
2610
+ <h3 id="sbi-misc-heading"><?php esc_html_e( 'Misc', 'instagram-feed' ); ?></h3>
2611
 
2612
  <table class="form-table" aria-describedby="sbi-misc-heading">
2613
  <tbody>
2614
+ <tr>
2615
  <th scope="row" style="padding-bottom: 0;">
2616
+ <?php echo wp_kses_post( __( '<strong style="font-size: 15px;">Custom CSS</strong><br />Enter your own custom CSS in the box below', 'instagram-feed' ) ); ?>
2617
  </th>
2618
  </tr>
2619
+ <tr>
2620
  <td>
2621
+ <textarea name="sb_instagram_custom_css" id="sb_instagram_custom_css" style="width: 70%;" rows="7"><?php echo esc_textarea( wp_unslash( $sb_instagram_custom_css ) ); ?></textarea>
2622
  </td>
2623
  </tr>
2624
+ <tr id="customjs">
2625
  <td style="padding-bottom: 0;">
2626
+ <?php echo wp_kses_post( __( '<strong style="font-size: 15px;">Custom JavaScript</strong><br />Enter your own custom JavaScript/jQuery in the box below', 'instagram-feed' ) ); ?>
2627
  </td>
2628
  </tr>
2629
+ <tr>
2630
  <td>
2631
+ <textarea name="sb_instagram_custom_js" id="sb_instagram_custom_js" style="width: 70%;" rows="7"><?php echo esc_textarea( wp_unslash( $sb_instagram_custom_js ) ); ?></textarea>
2632
  </td>
2633
  </tr>
2634
  </tbody>
2636
  <table class="form-table" aria-describedby="sbi-misc-heading">
2637
  <tbody>
2638
 
2639
+ <tr>
2640
+ <th scope="row"><label for="sb_instagram_ajax_theme" class="bump-left"><?php esc_html_e( 'Are you using an Ajax powered theme?', 'instagram-feed' ); ?></label></th>
2641
+ <td>
2642
+ <input name="sb_instagram_ajax_theme" type="checkbox" id="sb_instagram_ajax_theme"
2643
+ <?php
2644
+ if ( $sb_instagram_ajax_theme ) {
2645
+ echo 'checked';}
2646
+ ?>
2647
+ />
2648
+ <label for="sb_instagram_ajax_theme"><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></label>
2649
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2650
+ <p class="sbi_tooltip"><?php esc_html_e( "When navigating your site, if your theme uses Ajax to load content into your pages (meaning your page doesn't refresh) then check this setting. If you're not sure then please check with the theme author.", 'instagram-feed' ); ?></p>
2651
+ </td>
2652
+ </tr>
2653
+
2654
+ <tr>
2655
+ <th scope="row" class="bump-left"><label class="bump-left"><?php esc_html_e( 'Image Resizing', 'instagram-feed' ); ?></label></th>
2656
+ <td>
2657
+ <input name="sb_instagram_disable_resize" type="checkbox" id="sb_instagram_disable_resize"
2658
+ <?php
2659
+ if ( $sb_instagram_disable_resize ) {
2660
+ echo 'checked';}
2661
+ ?>
2662
+ />
2663
+ <label for="sb_instagram_disable_resize"><?php esc_html_e( 'Disable Local Image Storing and Resizing', 'instagram-feed' ); ?></label><br><br>
2664
+ <input name="sb_instagram_favor_local" type="checkbox" id="sb_instagram_favor_local"
2665
+ <?php
2666
+ if ( $sb_instagram_favor_local ) {
2667
+ echo 'checked';}
2668
+ ?>
2669
+ />
2670
+ <label for="sb_instagram_favor_local"><?php esc_html_e( 'Favor Local Images', 'instagram-feed' ); ?></label><br><br>
2671
+
2672
+ <input id="sbi_reset_resized" class="button-secondary" type="submit" value="<?php esc_attr_e( 'Reset Resized Images' ); ?>" style="vertical-align: middle;"/>
2673
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2674
+ <p class="sbi_tooltip"><?php esc_html_e( 'The plugin creates and stores resized versions of images in order to serve a more optimized resolution size in the feed. Click this button to clear all data related to resized images. Enable the setting to favor local images to always use a local, resized image if one is available.', 'instagram-feed' ); ?></p>
2675
+ </td>
2676
+ </tr>
2677
+
2678
+ <tr>
2679
+ <th scope="row"><label><?php esc_html_e( 'API request size', 'instagram-feed' ); ?></label><code class="sbi_shortcode"> minnum
2680
+ Eg: minnum=25</code></th>
2681
+ <td>
2682
+ <input name="sb_instagram_minnum" type="number" min="0" max="100" value="<?php echo esc_attr( $sb_instagram_minnum ); ?>" />
2683
+ <span class="sbi_note"><?php esc_html_e( 'Leave at "0" for default', 'instagram-feed' ); ?></span>
2684
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2685
+ <p class="sbi_tooltip"><?php esc_html_e( 'If your feed contains a lot of IG TV posts or your feed is not displaying any posts despite there being posts available on Instagram.com, try increasing this number to 25 or more.', 'instagram-feed' ); ?></p>
2686
+ </td>
2687
+ </tr>
2688
+
2689
+ <tr>
2690
+ <th scope="row"><label><?php esc_html_e( 'Enqueue JS file in head', 'instagram-feed' ); ?></label></th>
2691
+ <td>
2692
+ <input type="checkbox" name="enqueue_js_in_head" id="sb_instagram_enqueue_js_in_head"
2693
+ <?php
2694
+ if ( $enqueue_js_in_head ) {
2695
+ echo 'checked="checked"';}
2696
+ ?>
2697
+ />
2698
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2699
+ <p class="sbi_tooltip"><?php esc_html_e( "Check this box if you'd like to enqueue the JavaScript file for the plugin in the head instead of the footer.", 'instagram-feed' ); ?></p>
2700
+ </td>
2701
+ </tr>
2702
+
2703
+ <tr>
2704
+ <th scope="row"><label><?php esc_html_e( 'Enqueue CSS file with shortcode', 'instagram-feed' ); ?></label></th>
2705
+ <td>
2706
+ <input type="checkbox" name="enqueue_css_in_shortcode" id="sb_instagram_enqueue_css_in_shortcode"
2707
+ <?php
2708
+ if ( $enqueue_css_in_shortcode ) {
2709
+ echo 'checked="checked"';}
2710
+ ?>
2711
+ />
2712
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2713
+ <p class="sbi_tooltip"><?php esc_html_e( "Check this box if you'd like to only include the CSS file for the plugin when the feed is on the page.", 'instagram-feed' ); ?></p>
2714
+ </td>
2715
+ </tr>
2716
+
2717
+ <tr>
2718
+ <th scope="row"><label><?php esc_html_e( 'Disable JS Image Loading', 'instagram-feed' ); ?></label></th>
2719
  <td>
2720
+ <input type="checkbox" name="disable_js_image_loading" id="sb_instagram_disable_js_image_loading"
2721
+ <?php
2722
+ if ( $disable_js_image_loading ) {
2723
+ echo 'checked="checked"';}
2724
+ ?>
2725
+ />
2726
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2727
+ <p class="sbi_tooltip"><?php esc_html_e( 'Check this box to have images loaded server side instead of with JS.', 'instagram-feed' ); ?></p>
2728
  </td>
2729
  </tr>
2730
 
2731
+ <tr>
2732
+ <th scope="row"><label><?php esc_html_e( 'Enable Backup Caching', 'instagram-feed' ); ?></label></th>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2733
  <td class="sbi-customize-tab-opt">
2734
+ <input name="sb_instagram_backup" type="checkbox" id="sb_instagram_backup"
2735
+ <?php
2736
+ if ( $sb_instagram_backup ) {
2737
+ echo 'checked';}
2738
+ ?>
2739
+ />
2740
  <input id="sbi_clear_backups" class="button-secondary" type="submit" style="position: relative; top: -4px;" value="<?php esc_attr_e( 'Clear Backup Cache', 'instagram-feed' ); ?>" />
2741
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2742
+ <p class="sbi_tooltip"><?php esc_html_e( 'Every feed will save a duplicate version of itself in the database to be used if the normal cache is not available.', 'instagram-feed' ); ?></p>
2743
  </td>
2744
  </tr>
2745
 
2746
+ <tr>
2747
+ <th scope="row" class="bump-left">
2748
+ <label class="bump-left"><?php esc_html_e( 'Load initial posts with AJAX', 'instagram-feed' ); ?></label>
2749
+ </th>
2750
+ <td>
2751
+ <input name="sb_ajax_initial" type="checkbox" id="sb_ajax_initial"
2752
+ <?php
2753
+ if ( $sb_ajax_initial ) {
2754
+ echo 'checked';}
2755
+ ?>
2756
+ />
2757
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2758
+ <p class="sbi_tooltip"><?php esc_html_e( 'Initial posts will be loaded using AJAX instead of added to the page directly. If you use page caching, this will allow the feed to update according to the "Check for new posts every" setting on the "Configure" tab.', 'instagram-feed' ); ?></p>
2759
+ </td>
2760
+ </tr>
2761
 
2762
  <tr>
2763
+ <th scope="row" class="bump-left">
2764
+ <label for="sb_instagram_cron" class="bump-left"><?php esc_html_e( 'Force cache to clear on interval', 'instagram-feed' ); ?></label>
2765
  </th>
2766
  <td>
2767
  <select name="sb_instagram_cron">
2768
+ <option value="unset"
2769
+ <?php
2770
+ if ( $sb_instagram_cron === 'unset' ) {
2771
+ echo 'selected="selected"';}
2772
+ ?>
2773
+ > - </option>
2774
+ <option value="yes"
2775
+ <?php
2776
+ if ( $sb_instagram_cron === 'yes' ) {
2777
+ echo 'selected="selected"';}
2778
+ ?>
2779
+ ><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></option>
2780
+ <option value="no"
2781
+ <?php
2782
+ if ( $sb_instagram_cron === 'no' ) {
2783
+ echo 'selected="selected"';}
2784
+ ?>
2785
+ ><?php esc_html_e( 'No', 'instagram-feed' ); ?></option>
2786
  </select>
2787
 
2788
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2789
+ <p class="sbi_tooltip"><?php esc_html_e( "If you're experiencing an issue with the plugin not auto-updating then you can set this to 'Yes' to run a scheduled event behind the scenes which forces the plugin cache to clear on a regular basis and retrieve new data from Instagram.", 'instagram-feed' ); ?></p>
2790
  </td>
2791
  </tr>
2792
  </tbody>
2793
  </table>
2794
  <table class="form-table" aria-describedby="sbi-misc-heading">
2795
  <tbody>
2796
+ <tr>
2797
+ <th scope="row" class="bump-left"><label class="bump-left"><?php esc_html_e( 'Enable Custom Templates', 'instagram-feed' ); ?></label></th>
2798
+ <td>
2799
+ <input name="sb_instagram_custom_template" type="checkbox" id="sb_instagram_custom_template"
2800
+ <?php
2801
+ if ( $sb_instagram_custom_template ) {
2802
+ echo 'checked';}
2803
+ ?>
2804
+ />
2805
+ <label for="sb_instagram_custom_template"><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></label>
2806
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2807
+ <p class="sbi_tooltip"><?php echo wp_kses_post( __( "The default HTML for the feed can be replaced with custom templates added to your theme's folder. Enable this setting to use these templates. See <a href=\"https://smashballoon.com/guide-to-creating-custom-templates/\" target=\"_blank\">this guide</a>", 'instagram-feed' ) ); ?></p>
2808
+ </td>
2809
+ </tr>
2810
+ <tr>
2811
+ <th scope="row" class="bump-left"><label class="bump-left"><?php esc_html_e( 'Disable Admin Error Notice', 'instagram-feed' ); ?></label></th>
2812
+ <td>
2813
+ <input name="sb_instagram_disable_admin_notice" type="checkbox" id="sb_instagram_disable_admin_notice"
2814
+ <?php
2815
+ if ( $sb_instagram_disable_admin_notice ) {
2816
+ echo 'checked';}
2817
+ ?>
2818
+ />
2819
+ <label for="sb_instagram_disable_admin_notice"><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></label>
2820
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2821
+ <p class="sbi_tooltip"><?php esc_html_e( 'This will permanently disable the feed error notice that displays in the bottom right corner for admins on the front end of your site.', 'instagram-feed' ); ?></p>
2822
+ </td>
2823
+ </tr>
2824
+ <tr>
2825
+ <th scope="row" class="bump-left"><label class="bump-left"><?php esc_html_e( 'Feed Issue Email Report', 'instagram-feed' ); ?></label></th>
2826
+ <td>
2827
+ <input name="sb_instagram_enable_email_report" type="checkbox" id="sb_instagram_enable_email_report"
2828
+ <?php
2829
+ if ( $sb_instagram_enable_email_report ) {
2830
+ echo 'checked';}
2831
+ ?>
2832
+ />
2833
+ <label for="sb_instagram_enable_email_report"><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></label>
2834
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2835
+ <p class="sbi_tooltip"><?php esc_html_e( "Instagram Feed will send a weekly notification email using your site's wp_mail() function if one or more of your feeds is not updating or is not displaying. If you're not receiving the emails in your inbox, you may need to configure an SMTP service using another plugin like WP Mail SMTP.", 'instagram-feed' ); ?></p>
2836
+
2837
+ <div class="sb_instagram_box" style="display: block;">
2838
+ <div class="sb_instagram_box_setting">
2839
+ <label><?php esc_html_e( 'Schedule Weekly on', 'instagram-feed' ); ?></label><br>
2840
  <?php
2841
  $schedule_options = array(
2842
  array(
2843
+ 'val' => 'monday',
2844
+ 'label' => __( 'Monday', 'instagram-feed' ),
2845
  ),
2846
  array(
2847
+ 'val' => 'tuesday',
2848
+ 'label' => __( 'Tuesday', 'instagram-feed' ),
2849
  ),
2850
  array(
2851
+ 'val' => 'wednesday',
2852
+ 'label' => __( 'Wednesday', 'instagram-feed' ),
2853
  ),
2854
  array(
2855
+ 'val' => 'thursday',
2856
+ 'label' => __( 'Thursday', 'instagram-feed' ),
2857
  ),
2858
  array(
2859
+ 'val' => 'friday',
2860
+ 'label' => __( 'Friday', 'instagram-feed' ),
2861
  ),
2862
  array(
2863
+ 'val' => 'saturday',
2864
+ 'label' => __( 'Saturday', 'instagram-feed' ),
2865
  ),
2866
  array(
2867
+ 'val' => 'sunday',
2868
+ 'label' => __( 'Sunday', 'instagram-feed' ),
2869
  ),
2870
  );
2871
 
2872
+ if ( isset( $_GET['flag'] ) ) {
2873
  echo '<span id="sbi-goto"></span>';
2874
  }
2875
  ?>
2876
+ <select name="sb_instagram_email_notification" id="sb_instagram_email_notification">
2877
  <?php foreach ( $schedule_options as $schedule_option ) : ?>
2878
+ <option value="<?php echo esc_attr( $schedule_option['val'] ); ?>"
2879
+ <?php
2880
+ if ( $schedule_option['val'] === $sb_instagram_email_notification ) {
2881
+ echo 'selected';}
2882
+ ?>
2883
+ ><?php echo esc_html( $schedule_option['label'] ); ?></option>
2884
  <?php endforeach; ?>
2885
+ </select>
2886
+ </div>
2887
+ <div class="sb_instagram_box_setting">
2888
+ <label><?php esc_html_e( 'Email Recipients', 'instagram-feed' ); ?></label><br><input class="regular-text" type="text" name="sb_instagram_email_notification_addresses" value="<?php echo esc_attr( $sb_instagram_email_notification_addresses ); ?>"><span class="sbi_note"><?php esc_html_e( 'separate multiple emails with commas', 'instagram-feed' ); ?></span>
2889
+ <br><br><?php esc_html_e( 'Emails not working?', 'instagram-feed' ); ?> <a href="https://smashballoon.com/email-report-is-not-in-my-inbox/" target="_blank"><?php esc_html_e( 'See our related FAQ', 'instagram-feed' ); ?></a>
2890
+ </div>
2891
+ </div>
2892
+
2893
+ </td>
2894
+ </tr>
2895
  <?php
2896
  $usage_tracking = get_option( 'sbi_usage_tracking', false );
2897
  if ( $usage_tracking !== false ) :
2898
 
2899
+ if ( isset( $_POST['sb_instagram_enable_email_report'] ) ) {
2900
+ $usage_tracking['enabled'] = false;
2901
+ if ( isset( $_POST['sbi_usage_tracking_enable'] ) ) {
2902
+ $usage_tracking['enabled'] = true;
2903
+ }
2904
+ update_option( 'sbi_usage_tracking', $usage_tracking, false );
2905
  }
2906
+ $sbi_usage_tracking_enable = isset( $usage_tracking['enabled'] ) ? $usage_tracking['enabled'] : true;
 
 
2907
 
2908
+ // only show this setting after they have opted in or opted out using the admin notice
2909
+ ?>
2910
+ <tr>
2911
+
2912
+ <th scope="row" class="bump-left"><label class="bump-left"><?php esc_html_e( 'Enable Usage Tracking', 'instagram-feed' ); ?></label></th>
2913
+ <td>
2914
+ <input name="sbi_usage_tracking_enable" type="checkbox" id="sbi_usage_tracking_enable"
2915
+ <?php
2916
+ if ( $sbi_usage_tracking_enable ) {
2917
+ echo 'checked';}
2918
+ ?>
2919
+ />
2920
+ <label for="sbi_usage_tracking_enable"><?php esc_html_e( 'Yes', 'instagram-feed' ); ?></label>
2921
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);"><?php esc_html_e( 'What is usage tracking?', 'instagram-feed' ); ?></a>
2922
+ <p class="sbi_tooltip"><?php esc_html_e( 'Instagram Feed will record information and statistics about your site in order for the team at Smash Balloon to learn more about how our plugins are used. The plugin will never collect any sensitive information like access tokens, email addresses, or user information.', 'instagram-feed' ); ?></p>
2923
+ </td>
2924
+ </tr>
2925
+ <?php endif; ?>
2926
+
2927
+ <tr>
2928
+ <th scope="row"><label><?php esc_html_e( 'Manage Data', 'instagram-feed' ); ?></label></th>
2929
+ <td class="sbi-customize-tab-opt">
2930
+ <input id="sbi_clear_platform_data" class="button-secondary" type="submit" value="<?php esc_attr_e( 'Delete all Platform Data' ); ?>" />
2931
+ <a class="sbi_tooltip_link" href="JavaScript:void(0);" style="position: relative; top: 5px;"><?php esc_html_e( 'What does this mean?', 'instagram-feed' ); ?></a>
2932
+ <p class="sbi_tooltip"><?php esc_html_e( 'Warning: Clicking this button will permanently delete all Instagram data, including all connected accounts, cached posts, and stored images.', 'instagram-feed' ); ?></p>
2933
+ </td>
2934
+ </tr>
2935
+
2936
+ </tbody>
2937
  </table>
2938
 
2939
  <?php submit_button(); ?>
2940
 
2941
  </form>
2942
 
2943
+ <p><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>&nbsp; <?php echo wp_kses_post( __( 'Next Step: <a href="?page=sb-instagram-feed&tab=display">Display your Feed</a>', 'instagram-feed' ) ); ?></p>
2944
 
2945
+ <p><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <?php echo wp_kses_post( __( 'Need help setting up the plugin? Check out our <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=settings&utm_medium=display" target="_blank">setup directions</a>', 'instagram-feed' ) ); ?></p>
2946
 
2947
 
2948
  <?php } //End Customize tab ?>
2949
 
2950
 
2951
 
2952
+ <?php if ( $sbi_active_tab === 'display' ) { //Start Display tab ?>
2953
 
2954
+ <h3><?php esc_html_e( 'Display your Feed', 'instagram-feed' ); ?></h3>
2955
+ <p><?php esc_html_e( "Copy and paste the following shortcode directly into the page, post or widget where you'd like the feed to show up:", 'instagram-feed' ); ?></p>
2956
+ <input type="text" value="[instagram-feed]" size="16" readonly="readonly" style="text-align: center;" onclick="this.focus();this.select()" title="<?php esc_html_e( 'To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac).', 'instagram-feed' ); ?>" />
2957
 
2958
  <h3 style="padding-top: 10px;"><?php esc_html_e( 'Multiple Feeds', 'instagram-feed' ); ?></h3>
2959
+ <p><?php esc_html_e( "If you'd like to display multiple feeds then you can set different settings directly in the shortcode like so:", 'instagram-feed' ); ?>
2960
  <code>[instagram-feed num=9 cols=3]</code></p>
2961
  <p><?php esc_html_e( 'You can display as many different feeds as you like, on either the same page or on different pages, by just using the shortcode options below. For example:', 'instagram-feed' ); ?><br />
2962
  <code>[instagram-feed]</code><br />
2963
  <code>[instagram-feed num=4 cols=4 showfollow=false]</code><br />
2964
  </p>
2965
+ <p><?php esc_html_e( 'See the table below for a full list of available shortcode options:', 'instagram-feed' ); ?></p>
2966
 
2967
+ <p id="sbi-proonly-heading"><span class="sbi_table_key"></span><?php esc_html_e( 'Pro version only', 'instagram-feed' ); ?></p>
2968
 
2969
  <table class="sbi_shortcode_table" aria-describedby="sbi-proonly-heading">
2970
  <tbody>
2971
+ <tr>
2972
+ <th scope="row"><?php esc_html_e( 'Shortcode option', 'instagram-feed' ); ?></th>
2973
+ <th scope="row"><?php esc_html_e( 'Description', 'instagram-feed' ); ?></th>
2974
+ <th scope="row"><?php esc_html_e( 'Example', 'instagram-feed' ); ?></th>
2975
  </tr>
2976
 
2977
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Configure Options', 'instagram-feed' ); ?></td></tr>
2978
  <tr class="sbi_pro">
2979
  <td>type</td>
2980
+ <td><?php echo wp_kses_post( __( 'Display photos from a User ID (user)<br />Display posts from a Hashtag (hashtag)', 'instagram-feed' ) ); ?><br /><?php esc_html_e( 'Display photos that the account was tagged in (tagged)', 'instagram-feed' ); ?></td>
2981
  <td><code>[instagram-feed type=user]</code><br /><code>[instagram-feed type=hashtag]</code><br /><code>[instagram-feed type=tagged]</code></td>
2982
  </tr>
2983
  <tr>
2984
  <td>user</td>
2985
+ <td><?php esc_html_e( 'Your Instagram User Name. This must be from a connected account on the "Configure" tab.', 'instagram-feed' ); ?></td>
2986
  <td><code>[instagram-feed user="smashballoon"]</code></td>
2987
  </tr>
2988
  <tr class="sbi_pro">
2989
  <td>hashtag</td>
2990
+ <td><?php esc_html_e( 'Any hashtag. Separate multiple hashtags by commas.', 'instagram-feed' ); ?></td>
2991
  <td><code>[instagram-feed hashtag="#awesome"]</code></td>
2992
  </tr>
2993
+ <tr class="sbi_pro">
2994
+ <td>tagged</td>
2995
+ <td><?php esc_html_e( 'Your Instagram User Name. Separate multiple users by commas.', 'instagram-feed' ); ?></td>
2996
+ <td><code>[instagram-feed tagged="smashballoon"]</code></td>
2997
+ </tr>
2998
 
2999
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Customize Options', 'instagram-feed' ); ?></td></tr>
3000
  <tr>
3001
  <td>width</td>
3002
+ <td><?php esc_html_e( 'The width of your feed. Any number.', 'instagram-feed' ); ?></td>
3003
  <td><code>[instagram-feed width=50]</code></td>
3004
  </tr>
3005
  <tr>
3006
  <td>widthunit</td>
3007
+ <td><?php esc_html_e( "The unit of the width. 'px' or '%'", 'instagram-feed' ); ?></td>
3008
  <td><code>[instagram-feed widthunit=%]</code></td>
3009
  </tr>
3010
  <tr>
3011
  <td>height</td>
3012
+ <td><?php esc_html_e( 'The height of your feed. Any number.', 'instagram-feed' ); ?></td>
3013
  <td><code>[instagram-feed height=250]</code></td>
3014
  </tr>
3015
  <tr>
3016
  <td>heightunit</td>
3017
+ <td><?php esc_html_e( "The unit of the height. 'px' or '%'", 'instagram-feed' ); ?></td>
3018
  <td><code>[instagram-feed heightunit=px]</code></td>
3019
  </tr>
3020
  <tr>
3021
  <td>background</td>
3022
+ <td><?php esc_html_e( 'The background color of the feed. Any hex color code.', 'instagram-feed' ); ?></td>
3023
  <td><code>[instagram-feed background=#ffff00]</code></td>
3024
  </tr>
3025
  <tr>
3026
  <td>class</td>
3027
+ <td><?php esc_html_e( 'Add a CSS class to the feed container', 'instagram-feed' ); ?></td>
3028
  <td><code>[instagram-feed class=feedOne]</code></td>
3029
  </tr>
3030
 
3031
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Layout Options', 'instagram-feed' ); ?></td></tr>
3032
  <tr class="sbi_pro">
3033
  <td>layout</td>
3034
+ <td><?php esc_html_e( 'How posts are arranged visually in the feed. There are four layouts: Grid, Carousel Slider, Masonry Grid, or Highlight Grid. Options:', 'instagram-feed' ); ?> 'grid', 'carousel', 'masonry', or 'highlight'</td>
3035
  <td><code>[instagram-feed layout=grid]</code></td>
3036
  </tr>
3037
  <tr>
3038
  <td>num</td>
3039
+ <td><?php esc_html_e( 'The number of photos to display initially. Maximum is 33.', 'instagram-feed' ); ?></td>
3040
  <td><code>[instagram-feed num=10]</code></td>
3041
  </tr>
3042
  <tr class="sbi_pro">
3043
  <td>nummobile</td>
3044
+ <td><?php esc_html_e( 'The number of photos to display initially for mobile screens (smaller than 480 pixels).', 'instagram-feed' ); ?></td>
3045
  <td><code>[instagram-feed nummobile=6]</code></td>
3046
  </tr>
3047
  <tr>
3048
  <td>cols</td>
3049
+ <td><?php esc_html_e( 'The number of columns in your feed. 1 - 10.', 'instagram-feed' ); ?></td>
3050
  <td><code>[instagram-feed cols=5]</code></td>
3051
  </tr>
3052
  <tr class="sbi_pro">
3053
  <td>colsmobile</td>
3054
+ <td><?php esc_html_e( 'The number of columns in your feed for mobile screens (smaller than 480 pixels).', 'instagram-feed' ); ?></td>
3055
  <td><code>[instagram-feed colsmobile=2]</code></td>
3056
  </tr>
3057
  <tr>
3058
  <td>imagepadding</td>
3059
+ <td><?php esc_html_e( 'The spacing around your photos', 'instagram-feed' ); ?></td>
3060
  <td><code>[instagram-feed imagepadding=10]</code></td>
3061
  </tr>
3062
  <tr>
3063
  <td>imagepaddingunit</td>
3064
+ <td><?php esc_html_e( "The unit of the padding. 'px' or '%'", 'instagram-feed' ); ?></td>
3065
  <td><code>[instagram-feed imagepaddingunit=px]</code></td>
3066
  </tr>
3067
 
3068
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Carousel Options', 'instagram-feed' ); ?></td></tr>
3069
  <tr class="sbi_pro">
3070
  <td>carouselrows</td>
3071
+ <td><?php esc_html_e( 'Choose 1 or 2 rows of posts in the carousel', 'instagram-feed' ); ?></td>
3072
  <td><code>[instagram-feed carouselrows=1]</code></td>
3073
  </tr>
3074
  <tr class="sbi_pro">
3075
  <td>carouselloop</td>
3076
+ <td><?php esc_html_e( 'Infinitely loop through posts or rewind', 'instagram-feed' ); ?></td>
3077
  <td><code>[instagram-feed carouselloop=rewind]</code></td>
3078
  </tr>
3079
  <tr class="sbi_pro">
3080
  <td>carouselarrows</td>
3081
+ <td><?php esc_html_e( 'Display directional arrows on the carousel', 'instagram-feed' ); ?></td>
3082
  <td><code>[instagram-feed carouselarrows=true]</code></td>
3083
  </tr>
3084
  <tr class="sbi_pro">
3085
  <td>carouselpag</td>
3086
+ <td><?php esc_html_e( 'Display pagination links below the carousel', 'instagram-feed' ); ?></td>
3087
  <td><code>[instagram-feed carouselpag=true]</code></td>
3088
  </tr>
3089
  <tr class="sbi_pro">
3090
  <td>carouselautoplay</td>
3091
+ <td><?php esc_html_e( 'Make the carousel autoplay', 'instagram-feed' ); ?></td>
3092
  <td><code>[instagram-feed carouselautoplay=true]</code></td>
3093
  </tr>
3094
  <tr class="sbi_pro">
3095
  <td>carouseltime</td>
3096
+ <td><?php esc_html_e( 'The interval time between slides for autoplay. Time in miliseconds.', 'instagram-feed' ); ?></td>
3097
  <td><code>[instagram-feed carouseltime=8000]</code></td>
3098
  </tr>
3099
 
3100
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Highlight Options', 'instagram-feed' ); ?></td></tr>
3101
  <tr class="sbi_pro">
3102
  <td>highlighttype</td>
3103
+ <td><?php esc_html_e( 'Choose from 3 different ways of highlighting posts including by pattern, hashtag, post id or. Options:', 'instagram-feed' ); ?> 'pattern', 'hashtag', 'id'.</td>
3104
  <td><code>[instagram-feed highlighttype=hashtag]</code></td>
3105
  </tr>
3106
  <tr class="sbi_pro">
3107
  <td>highlightpattern</td>
3108
+ <td><?php esc_html_e( 'How often a post is highlighted.', 'instagram-feed' ); ?></td>
3109
  <td><code>[instagram-feed highlightpattern=7]</code></td>
3110
  </tr>
3111
  <tr class="sbi_pro">
3112
  <td>highlightoffset</td>
3113
+ <td><?php esc_html_e( 'When to start the highlight pattern.', 'instagram-feed' ); ?></td>
3114
  <td><code>[instagram-feed highlightoffset=3]</code></td>
3115
  </tr>
3116
  <tr class="sbi_pro">
3117
  <td>highlighthashtag</td>
3118
+ <td><?php esc_html_e( 'Highlight posts with these hashtags.', 'instagram-feed' ); ?></td>
3119
  <td><code>[instagram-feed highlighthashtag=best]</code></td>
3120
  </tr>
3121
 
3123
 
3124
 
3125
 
3126
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Photos Options', 'instagram-feed' ); ?></td></tr>
3127
  <tr>
3128
  <td>sortby</td>
3129
+ <td><?php esc_html_e( 'Sort the posts by Newest to Oldest (none) or Random (random)', 'instagram-feed' ); ?></td>
3130
  <td><code>[instagram-feed sortby=random]</code></td>
3131
  </tr>
3132
  <tr>
3133
  <td>imageres</td>
3134
+ <td><?php esc_html_e( 'The resolution/size of the photos including full, medium, thumbnail, and auto (based on size of image on page). Options:', 'instagram-feed' ); ?> 'auto', full', 'medium' or 'thumb'.</td>
3135
  <td><code>[instagram-feed imageres=full]</code></td>
3136
  </tr>
3137
  <tr class="sbi_pro">
3138
  <td>media</td>
3139
+ <td><?php esc_html_e( 'Display all media, only photos, or only videos', 'instagram-feed' ); ?></td>
3140
  <td><code>[instagram-feed media=photos]</code></td>
3141
  </tr>
3142
  <tr class="sbi_pro">
3143
  <td>disablelightbox</td>
3144
+ <td><?php esc_html_e( 'Whether to disable the photo Lightbox. It is enabled by default.', 'instagram-feed' ); ?></td>
3145
  <td><code>[instagram-feed disablelightbox=true]</code></td>
3146
  </tr>
3147
  <tr>
3148
  <td>disablemobile</td>
3149
+ <td><?php esc_html_e( 'Disable the mobile layout. Options:', 'instagram-feed' ); ?> 'true' or 'false'.</td>
3150
  <td><code>[instagram-feed disablemobile=true]</code></td>
3151
  </tr>
3152
  <tr class="sbi_pro">
3153
  <td>captionlinks</td>
3154
+ <td><?php esc_html_e( "Whether to use urls in captions for the photo's link instead of linking to instagram.com.", 'instagram-feed' ); ?></td>
3155
  <td><code>[instagram-feed captionlinks=true]</code></td>
3156
  </tr>
3157
 
3158
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Lightbox Comments Options', 'instagram-feed' ); ?></td></tr>
3159
  <tr class="sbi_pro">
3160
  <td>lightboxcomments</td>
3161
+ <td><?php esc_html_e( 'Whether to show comments in the lightbox for this feed.', 'instagram-feed' ); ?></td>
3162
  <td><code>[instagram-feed lightboxcomments=true]</code></td>
3163
  </tr>
3164
  <tr class="sbi_pro">
3165
  <td>numcomments</td>
3166
+ <td><?php esc_html_e( 'Number of comments to show starting from the most recent.', 'instagram-feed' ); ?></td>
3167
  <td><code>[instagram-feed numcomments=10]</code></td>
3168
  </tr>
3169
 
3170
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Photos Hover Style Options', 'instagram-feed' ); ?></td></tr>
3171
  <tr class="sbi_pro">
3172
  <td>hovercolor</td>
3173
+ <td><?php esc_html_e( 'The background color when hovering over a photo. Any hex color code.', 'instagram-feed' ); ?></td>
3174
  <td><code>[instagram-feed hovercolor=#ff0000]</code></td>
3175
  </tr>
3176
  <tr class="sbi_pro">
3177
  <td>hovertextcolor</td>
3178
+ <td><?php esc_html_e( 'The text/icon color when hovering over a photo. Any hex color code.', 'instagram-feed' ); ?></td>
3179
  <td><code>[instagram-feed hovertextcolor=#fff]</code></td>
3180
  </tr>
3181
  <tr class="sbi_pro">
3182
  <td>hoverdisplay</td>
3183
+ <td><?php esc_html_e( 'The info to display when hovering over the photo such as the user name, post date, Instagram icon, location, caption, and like counts. Options:', 'instagram-feed' ); ?><br />username, date, instagram, location, caption, likes</td>
3184
  <td><code>[instagram-feed hoverdisplay="date, location, likes"]</code></td>
3185
  </tr>
3186
 
3187
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Header Options', 'instagram-feed' ); ?></td></tr>
3188
  <tr>
3189
  <td>showheader</td>
3190
+ <td><?php esc_html_e( 'Whether to show the feed Header. Options:', 'instagram-feed' ); ?> 'true' or 'false'.</td>
3191
  <td><code>[instagram-feed showheader=false]</code></td>
3192
  </tr>
3193
  <tr>
3194
  <td>showbio</td>
3195
+ <td><?php esc_html_e( 'Display the bio in the header. Options:', 'instagram-feed' ); ?> 'true' or 'false'</td>
3196
  <td><code>[instagram-feed showbio=true]</code></td>
3197
  </tr>
3198
+ <tr>
3199
+ <td>custombio</td>
3200
+ <td><?php esc_html_e( 'Display a custom bio in the header', 'instagram-feed' ); ?></td>
3201
+ <td><code>[instagram-feed custombio="My custom bio."]</code></td>
3202
+ </tr>
3203
+ <tr>
3204
+ <td>customavatar</td>
3205
+ <td><?php esc_html_e( 'Display a custom avatar in the header. Enter the full URL of an image file.', 'instagram-feed' ); ?></td>
3206
+ <td><code>[instagram-feed customavatar="https://example.com/avatar.jpg"]</code></td>
3207
+ </tr>
3208
  <tr>
3209
  <td>headersize</td>
3210
+ <td><?php esc_html_e( 'Size of the header including small, medium and large. Options:', 'instagram-feed' ); ?> small, medium, or large.</td>
3211
  <td><code>[instagram-feed headersize=medium]</code></td>
3212
  </tr>
3213
  <tr>
3214
  <td>headercolor</td>
3215
+ <td><?php esc_html_e( 'The color of the Header text. Any hex color code.', 'instagram-feed' ); ?></td>
3216
  <td><code>[instagram-feed headercolor=#333]</code></td>
3217
  </tr>
3218
 
3219
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( "'Load More' Button Options", 'instagram-feed' ); ?></td></tr>
3220
  <tr>
3221
  <td>showbutton</td>
3222
+ <td><?php esc_html_e( "Whether to show the 'Load More' button. Options:", 'instagram-feed' ); ?> 'true' or 'false'.</td>
3223
  <td><code>[instagram-feed showbutton=false]</code></td>
3224
  </tr>
3225
  <tr>
3226
  <td>buttoncolor</td>
3227
+ <td><?php esc_html_e( 'The background color of the button. Any hex color code.', 'instagram-feed' ); ?></td>
3228
  <td><code>[instagram-feed buttoncolor=#000]</code></td>
3229
  </tr>
3230
  <tr>
3231
  <td>buttontextcolor</td>
3232
+ <td><?php esc_html_e( 'The text color of the button. Any hex color code.', 'instagram-feed' ); ?></td>
3233
  <td><code>[instagram-feed buttontextcolor=#fff]</code></td>
3234
  </tr>
3235
  <tr>
3236
  <td>buttontext</td>
3237
+ <td><?php esc_html_e( 'The text used for the button.', 'instagram-feed' ); ?></td>
3238
  <td><code>[instagram-feed buttontext="Load More Photos"]</code></td>
3239
  </tr>
3240
 
3241
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( "'Follow on Instagram' Button Options", 'instagram-feed' ); ?></td></tr>
3242
  <tr>
3243
  <td>showfollow</td>
3244
+ <td><?php esc_html_e( "Whether to show the 'Follow on Instagram' button. Options:", 'instagram-feed' ); ?> 'true' or 'false'.</td>
3245
  <td><code>[instagram-feed showfollow=false]</code></td>
3246
  </tr>
3247
  <tr>
3248
  <td>followcolor</td>
3249
+ <td><?php esc_html_e( 'The background color of the button. Any hex color code.', 'instagram-feed' ); ?></td>
3250
  <td><code>[instagram-feed followcolor=#ff0000]</code></td>
3251
  </tr>
3252
  <tr>
3253
  <td>followtextcolor</td>
3254
+ <td><?php esc_html_e( 'The text color of the button. Any hex color code.', 'instagram-feed' ); ?></td>
3255
  <td><code>[instagram-feed followtextcolor=#fff]</code></td>
3256
  </tr>
3257
  <tr>
3258
  <td>followtext</td>
3259
+ <td><?php esc_html_e( 'The text used for the button.', 'instagram-feed' ); ?></td>
3260
  <td><code>[instagram-feed followtext="Follow me"]</code></td>
3261
  </tr>
3262
 
3263
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Caption Options', 'instagram-feed' ); ?></td></tr>
3264
  <tr class="sbi_pro">
3265
  <td>showcaption</td>
3266
+ <td><?php esc_html_e( 'Whether to show the photo caption. Options:', 'instagram-feed' ); ?> 'true' or 'false'.</td>
3267
  <td><code>[instagram-feed showcaption=false]</code></td>
3268
  </tr>
3269
  <tr class="sbi_pro">
3270
  <td>captionlength</td>
3271
+ <td><?php esc_html_e( 'The number of characters of the caption to display', 'instagram-feed' ); ?></td>
3272
  <td><code>[instagram-feed captionlength=50]</code></td>
3273
  </tr>
3274
  <tr class="sbi_pro">
3275
  <td>captioncolor</td>
3276
+ <td><?php esc_html_e( 'The text color of the caption. Any hex color code.', 'instagram-feed' ); ?></td>
3277
  <td><code>[instagram-feed captioncolor=#000]</code></td>
3278
  </tr>
3279
  <tr class="sbi_pro">
3280
  <td>captionsize</td>
3281
+ <td><?php esc_html_e( 'The size of the caption text. Any number.', 'instagram-feed' ); ?></td>
3282
  <td><code>[instagram-feed captionsize=24]</code></td>
3283
  </tr>
3284
 
3285
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Likes &amp; Comments Options', 'instagram-feed' ); ?></td></tr>
3286
  <tr class="sbi_pro">
3287
  <td>showlikes</td>
3288
+ <td><?php esc_html_e( 'Whether to show the Likes &amp; Comments. Options:', 'instagram-feed' ); ?> 'true' or 'false'.</td>
3289
  <td><code>[instagram-feed showlikes=false]</code></td>
3290
  </tr>
3291
  <tr class="sbi_pro">
3292
  <td>likescolor</td>
3293
+ <td><?php esc_html_e( 'The color of the Likes &amp; Comments. Any hex color code.', 'instagram-feed' ); ?></td>
3294
  <td><code>[instagram-feed likescolor=#FF0000]</code></td>
3295
  </tr>
3296
  <tr class="sbi_pro">
3297
  <td>likessize</td>
3298
+ <td><?php esc_html_e( 'The size of the Likes &amp; Comments. Any number.', 'instagram-feed' ); ?></td>
3299
  <td><code>[instagram-feed likessize=14]</code></td>
3300
  </tr>
3301
 
3302
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Post Filtering Options', 'instagram-feed' ); ?></td></tr>
3303
  <tr class="sbi_pro">
3304
  <td>excludewords</td>
3305
+ <td><?php esc_html_e( 'Remove posts which contain certain words or hashtags in the caption.', 'instagram-feed' ); ?></td>
3306
  <td><code>[instagram-feed excludewords="bad, words"]</code></td>
3307
  </tr>
3308
  <tr class="sbi_pro">
3309
  <td>includewords</td>
3310
+ <td><?php esc_html_e( 'Only display posts which contain certain words or hashtags in the caption.', 'instagram-feed' ); ?></td>
3311
  <td><code>[instagram-feed includewords="sunshine"]</code></td>
3312
  </tr>
3313
 
3314
+ <tr class="sbi_table_header"><td colspan=3><?php esc_html_e( 'Auto Load More on Scroll', 'instagram-feed' ); ?></td></tr>
3315
  <tr class="sbi_pro">
3316
  <td>autoscroll</td>
3317
+ <td><?php esc_html_e( 'Load more posts automatically as the user scrolls down the page.', 'instagram-feed' ); ?></td>
3318
  <td><code>[instagram-feed autoscroll=true]</code></td>
3319
  </tr>
3320
  <tr class="sbi_pro">
3321
  <td>autoscrolldistance</td>
3322
+ <td><?php esc_html_e( 'Distance before the end of feed or page that triggers the loading of more posts.', 'instagram-feed' ); ?></td>
3323
  <td><code>[instagram-feed autoscrolldistance=200]</code></td>
3324
  </tr>
3325
 
3326
  </tbody>
3327
  </table>
3328
 
3329
+ <p><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <?php echo wp_kses_post( __( 'Need help setting up the plugin? Check out our <a href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=display&utm_medium=supportsetup" target="_blank">setup directions</a>', 'instagram-feed' ) ); ?></p>
3330
 
3331
  <?php } //End Display tab ?>
3332
 
3333
 
3334
+ <?php if ( $sbi_active_tab === 'support' ) { //Start Support tab ?>
3335
 
3336
  <div class="sbi_support">
3337
 
3338
+ <h3 style="padding-bottom: 10px;"><?php esc_html_e( 'Need help?', 'instagram-feed' ); ?></h3>
3339
 
3340
  <p>
3341
+ <span class="sbi-support-title"><i class="fa fa-life-ring" aria-hidden="true"></i>&nbsp; <a
3342
+ href="https://smashballoon.com/instagram-feed/free/?utm_campaign=instagram-free&utm_source=settings&utm_medium=general"
3343
+ target="_blank"><?php esc_html_e( 'Setup Directions', 'instagram-feed' ); ?></a></span>
3344
  <?php esc_html_e( 'A step-by-step guide on how to setup and use the plugin.', 'instagram-feed' ); ?>
3345
  </p>
3346
 
3347
  <p>
3348
+ <span class="sbi-support-title"><i class="fa fa-youtube-play" aria-hidden="true"></i>&nbsp; <a
3349
+ href="https://www.youtube.com/embed/q6ZXVU4g970" target="_blank" rel="noopener noreferrer"
3350
+ id="sbi-play-support-video"><?php esc_html_e( 'Watch a Video', 'instagram-feed' ); ?></a></span>
3351
+ <?php echo wp_kses_post( __( "Watch a short video demonstrating how to set up, customize and use the plugin.<br /><strong>Please note</strong> that the video shows the set up and use of the <strong><a href='https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=settings&utm_medium=general' target='_blank'>Pro version</a></strong> of the plugin, but the process is the same for this free version. The only difference is some of the features available.", 'instagram-feed' ) ); ?>
3352
 
3353
  <iframe id="sbi-support-video"
3354
+ src="//www.youtube.com/embed/q6ZXVU4g970?theme=light&amp;showinfo=0&amp;controls=2" width="960"
3355
+ height="540" frameborder="0" allowfullscreen="allowfullscreen" title="<?php esc_attr_e( 'Watch a Video', 'instagram-feed' ); ?>"></iframe>
3356
  </p>
3357
 
3358
  <p>
3359
+ <span class="sbi-support-title"><i class="fa fa-question-circle" aria-hidden="true"></i>&nbsp; <a
3360
+ href="https://smashballoon.com/instagram-feed/support/faq/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqs"
3361
+ target="_blank"><?php esc_html_e( 'FAQs and Docs', 'instagram-feed' ); ?></a></span>
3362
  <?php esc_html_e( 'View our expansive library of FAQs and documentation to help solve your problem as quickly as possible.', 'instagram-feed' ); ?>
3363
  </p>
3364
 
3366
 
3367
  <ul>
3368
  <li><strong><?php esc_html_e( 'FAQs', 'instagram-feed' ); ?></strong></li>
3369
+ <li>&bull;&nbsp; <?php echo wp_kses_post( __( '<a href="https://smashballoon.com/my-photos-wont-load/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqsnophotos" target="_blank">My Instagram Feed Won\'t Load</a>', 'instagram-feed' ) ); ?></li>
3370
+ <li>&bull;&nbsp; <?php echo wp_kses_post( __( '<a href="https://smashballoon.com/my-instagram-access-token-keep-expiring/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqsexpiring" target="_blank">My Access Token Keeps Expiring</a>', 'instagram-feed' ) ); ?></li>
3371
  <li style="margin-top: 8px; font-size: 12px;"><a href="https://smashballoon.com/instagram-feed/support/faq/?utm_campaign=instagram-free&utm_source=support&utm_medium=faqs" target="_blank"><?php esc_html_e( 'See All', 'instagram-feed' ); ?><i class="fa fa-chevron-right" aria-hidden="true"></i></a></li>
3372
  </ul>
3373
 
3374
  <ul>
3375
+ <li><strong><?php esc_html_e( 'Documentation', 'instagram-feed' ); ?></strong></li>
3376
+ <li>&bull;&nbsp; <?php echo wp_kses_post( __( '<a href="https://smashballoon.com/instagram-feed/free?utm_campaign=instagram-free&utm_source=support&utm_medium=installation" target="_blank">Installation and Configuration</a>', 'instagram-feed' ) ); ?></li>
3377
+ <li>&bull;&nbsp; <?php echo wp_kses_post( __( '<a href="https://smashballoon.com/display-multiple-instagram-feeds/?utm_campaign=instagram-free&utm_source=support&utm_medium=multiple" target="_blank">Displaying multiple feeds</a>', 'instagram-feed' ) ); ?></li>
3378
+ <li>&bull;&nbsp; <?php echo wp_kses_post( __( '<a href="https://smashballoon.com/instagram-feed-faq/customization/?utm_campaign=instagram-free&utm_source=support&utm_medium=customizing" target="_blank">Customizing your Feed</a>', 'instagram-feed' ) ); ?></li>
3379
  </ul>
3380
  </div>
3381
 
3382
  <p>
3383
+ <span class="sbi-support-title"><i class="fa fa-envelope" aria-hidden="true"></i>&nbsp; <a
3384
+ href="https://smashballoon.com/instagram-feed/support/?utm_campaign=instagram-free&utm_source=support&utm_medium=contact"
3385
+ target="_blank"><?php esc_html_e( 'Request Support', 'instagram-feed' ); ?></a></span>
3386
+ <?php echo wp_kses_post( __( 'Still need help? Submit a ticket and one of our support experts will get back to you as soon as possible.<br /><strong>Important:</strong> Please include your <strong>System Info</strong> below with all support requests.', 'instagram-feed' ) ); ?>
3387
  </p>
3388
  </div>
3389
 
3390
  <hr />
3391
 
3392
+ <h3><?php echo wp_kses_post( __( 'System Info &nbsp; <i style="color: #666; font-size: 11px; font-weight: normal;">Click the text below to select all</i>', 'instagram-feed' ) ); ?></h3>
3393
 
3394
 
3395
 
3396
 
3397
+ <?php $sbi_options = get_option( 'sb_instagram_settings' ); ?>
3398
  <textarea readonly="readonly" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac)." style="width: 100%; max-width: 960px; height: 500px; white-space: pre; font-family: Menlo,Monaco,monospace;">
3399
  ## SITE/SERVER INFO: ##
3400
+ Site URL: <?php echo esc_html( site_url() ) . "\n"; ?>
3401
+ Home URL: <?php echo esc_html( home_url() ) . "\n"; ?>
3402
+ WordPress Version: <?php echo esc_html( get_bloginfo( 'version' ) ) . "\n"; ?>
3403
+ PHP Version: <?php echo esc_html( PHP_VERSION ) . "\n"; ?>
3404
+ Web Server Info: <?php echo esc_html( $_SERVER['SERVER_SOFTWARE'] ) . "\n"; ?>
3405
 
3406
  ## ACTIVE PLUGINS: ##
3407
  <?php
3408
+ $plugins = get_plugins();
3409
  $active_plugins = get_option( 'active_plugins', array() );
3410
 
3411
  foreach ( $plugins as $plugin_path => $plugin ) {
3412
  // If the plugin isn't active, don't show it.
3413
+ if ( ! in_array( $plugin_path, $active_plugins, true ) ) {
3414
  continue;
3415
+ }
3416
 
3417
+ echo esc_html( $plugin['Name'] ) . ': ' . esc_html( $plugin['Version'] ) . "\n";
3418
  }
3419
  ?>
3420
 
3422
  sb_instagram_plugin_type => Instagram Feed Free
3423
  <?php
3424
  global $wpdb;
3425
+ foreach ( $sbi_options as $key => $val ) {
3426
  if ( $key !== 'connected_accounts' ) {
3427
  if ( is_array( $val ) ) {
3428
  foreach ( $val as $item ) {
3429
  if ( is_array( $item ) ) {
3430
  foreach ( $item as $key2 => $val2 ) {
3431
+ echo esc_html( $key2 ) . ' => ' . esc_html( $val2 ) . "\n";
3432
  }
3433
  } else {
3434
+ echo esc_html( $key ) . ' => ' . esc_html( $item ) . "\n";
3435
  }
3436
  }
3437
  } else {
3438
+ echo esc_html( $key ) . ' => ' . esc_html( $val ) . "\n";
3439
  }
3440
  }
 
3441
  }
3442
  ?>
3443
 
3444
+ ## CONNECTED ACCOUNTS: ##
3445
+ <?php
3446
+ echo "\n";
3447
+ $con_accounts = isset( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
3448
  $business_accounts = array();
3449
+ $basic_accounts = array();
3450
+ $manager = new SB_Instagram_Data_Manager();
3451
  if ( ! empty( $con_accounts ) ) {
3452
+ foreach ( $con_accounts as $account ) {
3453
+ $type = isset( $account['type'] ) ? $account['type'] : 'personal';
3454
+ $original_access_token = ! empty( $account['access_token'] ) ? $account['access_token'] : '';
3455
+ $account['access_token'] = ! empty( $original_access_token ) ? $manager->remote_encrypt( $original_access_token ) : '';
3456
+ if ( isset( $account['page_access_token'] ) ) {
3457
+ unset( $account['page_access_token'] );
3458
+ }
3459
+ echo '*' . esc_html( $account['user_id'] ) . '*' . "\n";
3460
+ var_export( $account );
3461
+ echo "\n";
3462
+ $account['access_token'] = $original_access_token;
3463
+ if ( $type === 'business' ) {
3464
+ $business_accounts[] = $account;
3465
+ } elseif ( $type === 'basic' ) {
3466
+ $basic_accounts[] = $account;
3467
+ }
3468
+ }
3469
  }
3470
  ?>
3471
 
3472
  ## API RESPONSE: ##
3473
  <?php
3474
+ $first_con_basic_account = isset( $basic_accounts[0] ) ? $basic_accounts[0] : array();
3475
  $first_con_business_account = isset( $business_accounts[0] ) ? $business_accounts[0] : array();
3476
 
3477
  if ( ! empty( $first_con_basic_account ) ) {
3481
  $connection->connect();
3482
  if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
3483
  foreach ( $connection->get_data() as $key => $item ) {
3484
+ if ( is_array( $item ) ) {
3485
  foreach ( $item as $key2 => $item2 ) {
3486
+ echo esc_html( $key2 ) . ' => ' . esc_html( $item2 ) . "\n";
3487
  }
3488
  } else {
3489
+ echo esc_html( $key ) . ' => ' . esc_html( $item ) . "\n";
3490
  }
3491
  }
3492
  } else {
3494
  $response = $connection->get_wp_error();
3495
  if ( isset( $response ) && isset( $response->errors ) ) {
3496
  foreach ( $response->errors as $key => $item ) {
3497
+ echo esc_html( $key ) . ' => ' . esc_html( $item[0] ) . "\n";
3498
  }
3499
  }
3500
  } else {
3514
  $connection->connect();
3515
  if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
3516
  foreach ( $connection->get_data() as $key => $item ) {
3517
+ if ( is_array( $item ) ) {
3518
  foreach ( $item as $key2 => $item2 ) {
3519
+ echo esc_html( $key2 ) . ' => ' . esc_html( $item2 ) . "\n";
3520
  }
3521
  } else {
3522
+ echo esc_html( $key ) . ' => ' . esc_html( $item ) . "\n";
3523
  }
3524
  }
3525
  } else {
3527
  $response = $connection->get_wp_error();
3528
  if ( isset( $response ) && isset( $response->errors ) ) {
3529
  foreach ( $response->errors as $key => $item ) {
3530
+ echo esc_html( $key ) . ' => ' . esc_html( $item[0] ) . "\n";
3531
  }
3532
  }
3533
  } else {
3537
  }
3538
  } else {
3539
  echo 'no connected business accounts';
3540
+ }
3541
+ ?>
3542
 
3543
  ## Cron Events: ##
3544
  <?php
3548
  foreach ( $data as $key2 => $val ) {
3549
  if ( strpos( $key2, 'sbi' ) !== false || strpos( $key2, 'sb_instagram' ) !== false ) {
3550
  $is_target = true;
3551
+ echo esc_html( $key2 );
3552
  echo "\n";
3553
  }
3554
  }
3555
+ if ( $is_target ) {
3556
+ echo esc_html( date( 'Y-m-d H:i:s', $key ) );
3557
  echo "\n";
3558
+ echo esc_html( 'Next Scheduled: ' . ( (int) $key - time() ) / 60 . ' minutes' );
3559
  echo "\n\n";
3560
  }
3561
  }
3562
  ?>
3563
  ## Cron Cache Report: ##
3564
+ <?php
3565
+ $cron_report = get_option( 'sbi_cron_report', array() );
3566
  if ( ! empty( $cron_report ) ) {
3567
  var_export( $cron_report );
3568
  }
3570
  ?>
3571
 
3572
  ## Access Token Refresh: ##
3573
+ <?php
3574
+ $cron_report = get_option( 'sbi_refresh_report', array() );
3575
  if ( ! empty( $cron_report ) ) {
3576
  var_export( $cron_report );
3577
  }
3579
  ?>
3580
 
3581
  ## Resizing: ##
3582
+ <?php
3583
+ $upload = wp_upload_dir();
3584
  $upload_dir = $upload['basedir'];
3585
  $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
3586
  if ( file_exists( $upload_dir ) ) {
3595
  echo "\n";
3596
  echo "\n";
3597
 
3598
+ $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE );
3599
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
3600
 
3601
+ if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) !== $feeds_posts_table_name ) {
3602
  echo 'no feeds posts table';
3603
  echo "\n";
3604
 
3611
  foreach ( $last_result as $column ) {
3612
 
3613
  foreach ( $column as $key => $value ) {
3614
+ echo esc_html( $key ) . ': ' . esc_html( $value ) . "\n";
3615
+
3616
  }
3617
  }
 
3618
  } else {
3619
  echo 'feeds posts has no rows';
3620
  echo "\n";
3622
  }
3623
  echo "\n";
3624
 
3625
+ if ( $wpdb->get_var( "show tables like '$table_name'" ) !== $table_name ) {
3626
  echo 'no posts table';
3627
  echo "\n";
3628
 
3637
  }
3638
 
3639
  foreach ( $column as $key => $value ) {
3640
+ echo esc_html( $key ) . ': ' . esc_html( $value ) . "\n";
3641
+
3642
  }
3643
  }
 
3644
  } else {
3645
  echo 'feeds posts has no rows';
3646
  echo "\n";
3654
  $errors = $sb_instagram_posts_manager->get_errors();
3655
  if ( ! empty( $errors['resizing'] ) ) :
3656
  echo '* Resizing *' . "\n";
3657
+ echo esc_html( $errors['resizing'] ) . "\n";
3658
  endif;
3659
  if ( ! empty( $errors['database_create'] ) ) :
3660
  echo '* Database Create *' . "\n";
3661
+ echo esc_html( $errors['database_create'] ) . "\n";
3662
  endif;
3663
  if ( ! empty( $errors['upload_dir'] ) ) :
3664
  echo '* Uploads Directory *' . "\n";
3665
+ echo esc_html( $errors['upload_dir'] ) . "\n";
3666
  endif;
3667
  if ( ! empty( $errors['connection'] ) ) :
3668
  echo '* API/WP_HTTP Request *' . "\n";
3675
  $error_log = $sb_instagram_posts_manager->get_error_log();
3676
  if ( ! empty( $error_log ) ) :
3677
  foreach ( $error_log as $error ) :
3678
+ echo esc_html( $error ) . "\n";
3679
  endforeach;
3680
  endif;
3681
  ?>
3685
  $actions = $sb_instagram_posts_manager->get_action_log();
3686
  if ( ! empty( $actions ) ) :
3687
  foreach ( $actions as $action ) :
3688
+ echo esc_html( $action ) . "\n";
3689
  endforeach;
3690
  endif;
3691
+ ?>
 
 
 
 
3692
 
3693
  ## Location Summary: ##
3694
  <?php
3695
+ $locator_summary = SB_Instagram_Feed_Locator::summary();
3696
  $condensed_shortcode_atts = array( 'type', 'user', 'hashtag', 'tagged', 'num', 'cols', 'layout', 'whitelist', 'includewords' );
3697
 
3698
+ if ( ! empty( $locator_summary ) ) {
3699
 
3700
  foreach ( $locator_summary as $locator_section ) {
3701
  if ( ! empty( $locator_section['results'] ) ) {
3706
  $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array();
3707
  foreach ( $shortcode_atts as $key => $value ) {
3708
  if ( in_array( $key, $condensed_shortcode_atts, true ) ) {
3709
+ $condensed_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"';
3710
  }
3711
  }
3712
  $condensed_shortcode_string .= ']';
3713
+ echo esc_url( get_the_permalink( $result['post_id'] ) ) . ' ' . esc_html( $condensed_shortcode_string ) . "\n";
3714
  }
 
3715
  }
3716
  }
3717
+ }
3718
+ ?>
3719
 
3720
  ## GDPR: ##
3721
  <?php
3722
  if ( ! SB_Instagram_GDPR_Integrations::gdpr_tests_successful() ) :
3723
  $errors = SB_Instagram_GDPR_Integrations::gdpr_tests_error_message();
3724
+ ?>
3725
+ <?php echo wp_kses_post( $errors ); ?>
3726
  <?php endif; ?>
3727
 
3728
  ## oEmbed: ##
3729
  <?php
3730
  $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
3731
+ foreach ( $oembed_token_settings as $key => $value ) {
3732
+ echo esc_html( $key ) . ': ' . esc_html( $value ) . "\n";
3733
  }
3734
 
3735
+ $single = new SB_Instagram_Single( 'https://www.instagram.com/p/CCq1D_cMYMF/' );
3736
+ $post = $single->fetch();
3737
  $message = '';
3738
  if ( isset( $post['thumbnail_url'] ) ) {
3739
  $message = 'success';
3740
  } else {
3741
+ $error = $single->get_error();
3742
 
3743
+ if ( ! empty( $error ) ) {
3744
+ $message = $error;
3745
+ }
3746
  }
3747
+ echo 'oEmbed request test: ' . esc_html( $message );
3748
 
3749
  ?>
3750
  </textarea>
3751
+ <div><input id="sbi_reset_log" class="button-secondary" type="submit" value="<?php esc_attr_e( 'Reset Error Log' ); ?>" style="vertical-align: middle;"/></div>
3752
 
3753
  <?php
3754
  } //End Support tab
3755
 
3756
+ if ( $sbi_active_tab === 'more' ) { //Start More Social Feeds tab
3757
 
3758
+ add_user_meta( get_current_user_id(), 'seen_more_plugins_page_1', 'true', true ); //Iterate when adding a new plugin
 
 
3759
  ?>
3760
 
3761
  <div class="sbi_more_plugins" id="sbi-admin-about">
3762
 
3763
  <div class="sbi-more-plugins-intro">
3764
+ <h3><?php echo wp_kses_post( __( "Here's some more <span>free</span> plugins you might like!", 'instagram-feed' ) ); ?></h3>
3765
  <p><?php esc_html_e( "As you're already using one of our free plugins we thought we'd suggest some others you might like to. Check out our other free plugins below:", 'instagram-feed' ); ?></p>
3766
  </div>
3767
 
3768
+ <?php
3769
+ function get_am_plugins() {
3770
+
3771
+ $images_url = SBI_PLUGIN_URL . 'img/about/';
3772
+
3773
+ return array(
3774
+ 'instagram-feed/instagram-feed.php' => array(
3775
+ 'icon' => $images_url . 'plugin-if.png',
3776
+ 'name' => esc_html__( 'Instagram Feed', 'custom-facebook-feed' ),
3777
+ 'desc' => esc_html__( 'Instagram Feed is a clean and beautiful way to add your Instagram posts to your website. Grab your visitors attention and keep them engaged with your site longer.', 'custom-facebook-feed' ),
3778
+ 'url' => 'https://downloads.wordpress.org/plugin/instagram-feed.zip',
3779
+ 'pro' => array(
3780
+ 'plug' => 'instagram-feed-pro/instagram-feed.php',
3781
  'icon' => $images_url . 'plugin-if.png',
3782
+ 'name' => esc_html__( 'Instagram Feed Pro', 'custom-facebook-feed' ),
3783
  'desc' => esc_html__( 'Instagram Feed is a clean and beautiful way to add your Instagram posts to your website. Grab your visitors attention and keep them engaged with your site longer.', 'custom-facebook-feed' ),
3784
+ 'url' => 'https://smashballoon.com/instagram-feed/?utm_campaign=facebook-free&utm_source=cross&utm_medium=sbiinstaller',
3785
+ 'act' => 'go-to-url',
 
 
 
 
 
 
 
3786
  ),
3787
+ ),
3788
+ 'custom-facebook-feed/custom-facebook-feed.php' => array(
3789
+ 'icon' => $images_url . 'plugin-fb.png',
3790
+ 'name' => esc_html__( 'Custom Facebook Feed', 'instagram-feed' ),
3791
+ 'desc' => esc_html__( 'Custom Facebook Feed makes displaying your Facebook posts easy. Keep your site visitors informed and increase engagement with your Facebook page by displaying a feed on your website.', 'instagram-feed' ),
3792
+ 'url' => 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip',
3793
+ 'pro' => array(
3794
+ 'plug' => 'custom-facebook-feed-pro/custom-facebook-feed.php',
3795
  'icon' => $images_url . 'plugin-fb.png',
3796
+ 'name' => esc_html__( 'Custom Facebook Feed Pro', 'instagram-feed' ),
3797
  'desc' => esc_html__( 'Custom Facebook Feed makes displaying your Facebook posts easy. Keep your site visitors informed and increase engagement with your Facebook page by displaying a feed on your website.', 'instagram-feed' ),
3798
+ 'url' => 'https://smashballoon.com/custom-facebook-feed/?utm_campaign=instagram-free&utm_source=cross&utm_medium=cffinstaller',
3799
+ 'act' => 'go-to-url',
 
 
 
 
 
 
 
3800
  ),
3801
+ ),
3802
+
3803
+ 'custom-twitter-feeds/custom-twitter-feed.php' => array(
3804
+ 'icon' => $images_url . 'plugin-tw.jpg',
3805
+ 'name' => esc_html__( 'Custom Twitter Feeds', 'instagram-feed' ),
3806
+ 'desc' => esc_html__( 'Custom Twitter Feeds is a highly customizable way to display tweets from your Twitter account. Promote your latest content and update your site content automatically.', 'instagram-feed' ),
3807
+ 'url' => 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip',
3808
+ 'pro' => array(
3809
+ 'plug' => 'custom-twitter-feeds-pro/custom-twitter-feed.php',
3810
  'icon' => $images_url . 'plugin-tw.jpg',
3811
+ 'name' => esc_html__( 'Custom Twitter Feeds Pro', 'instagram-feed' ),
3812
  'desc' => esc_html__( 'Custom Twitter Feeds is a highly customizable way to display tweets from your Twitter account. Promote your latest content and update your site content automatically.', 'instagram-feed' ),
3813
+ 'url' => 'https://smashballoon.com/custom-twitter-feeds/?utm_campaign=instagram-free&utm_source=cross&utm_medium=ctfinstaller',
3814
+ 'act' => 'go-to-url',
 
 
 
 
 
 
 
3815
  ),
3816
+ ),
3817
+
3818
+ 'feeds-for-youtube/youtube-feed.php' => array(
3819
+ 'icon' => $images_url . 'plugin-yt.png',
3820
+ 'name' => esc_html__( 'Feeds for YouTube', 'instagram-feed' ),
3821
+ 'desc' => esc_html__( 'Feeds for YouTube is a simple yet powerful way to display videos from YouTube on your website. Increase engagement with your channel while keeping visitors on your website.', 'instagram-feed' ),
3822
+ 'url' => 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip',
3823
+ 'pro' => array(
3824
+ 'plug' => 'youtube-feed-pro/youtube-feed.php',
3825
  'icon' => $images_url . 'plugin-yt.png',
3826
+ 'name' => esc_html__( 'Feeds for YouTube Pro', 'instagram-feed' ),
3827
  'desc' => esc_html__( 'Feeds for YouTube is a simple yet powerful way to display videos from YouTube on your website. Increase engagement with your channel while keeping visitors on your website.', 'instagram-feed' ),
3828
+ 'url' => 'https://smashballoon.com/youtube-feed/?utm_campaign=instagram-free&utm_source=cross&utm_medium=sbyinstaller',
3829
+ 'act' => 'go-to-url',
 
 
 
 
 
 
 
3830
  ),
3831
+ ),
3832
+ );
 
 
 
3833
 
3834
+ }
 
 
 
3835
 
3836
+ function output_about_addons() {
 
 
3837
 
3838
+ if ( version_compare( PHP_VERSION, '5.3.0' ) <= 0
3839
+ || version_compare( get_bloginfo( 'version' ), '4.6', '<' ) ) {
3840
+ return;
3841
+ }
 
3842
 
3843
+ $all_plugins = get_plugins();
3844
+ $am_plugins = get_am_plugins();
3845
+ $has_all_plugins = true;
3846
 
3847
+ ?>
3848
+ <div id="sbi-admin-addons">
3849
+ <div class="addons-container">
3850
+ <?php
3851
+ foreach ( $am_plugins as $plugin => $details ) :
3852
+
3853
+ $free_only = true;
3854
+ $plugin_data = get_the_plugin_data( $plugin, $details, $all_plugins, $free_only );
3855
+ $plugin_slug = strtolower( str_replace( ' ', '_', $plugin_data['details']['name'] ) );
3856
+
3857
+ //Only show the plugin if both free/pro versions aren't already active
3858
+ isset( $plugin_data['details']['plug'] ) ? $pro_plugin_source = $plugin_data['details']['plug'] : $pro_plugin_source = '';
3859
+ if ( ! is_plugin_active( $plugin ) && ! is_plugin_active( $pro_plugin_source ) ) {
3860
+ $has_all_plugins = false;
3861
+ ?>
3862
+ <div class="addon-container" id="install_<?php echo esc_attr( $plugin_slug ); ?>">
3863
+ <div class="addon-item">
3864
+ <div class="details sbi-clear">
3865
+ <img alt="<?php echo esc_attr( $plugin_data['details']['name'] ); ?>" src="<?php echo esc_url( $plugin_data['details']['icon'] ); ?>">
3866
+ <h5 class="addon-name">
3867
+ <?php echo esc_html( $plugin_data['details']['name'] ); ?>
3868
+ </h5>
3869
+ <p class="addon-desc">
3870
+ <?php echo wp_kses_post( $plugin_data['details']['desc'] ); ?>
3871
+ </p>
3872
+ </div>
3873
+ <div class="actions sbi-clear">
3874
+ <div class="status">
3875
+ <strong>
3876
+ <?php
3877
+ esc_html_e( 'Price:', 'instagram-feed' );
3878
+ echo ' <span style="color: green;">';
3879
+ esc_html_e( 'Free', 'instagram-feed' );
3880
+ echo '</span>';
3881
+ ?>
3882
+ </strong>
3883
  </div>
3884
+ <div class="action-button">
3885
+ <button class="<?php echo esc_attr( $plugin_data['action_class'] ); ?>" data-plugin="<?php echo esc_attr( $plugin_data['plugin_src'] ); ?>" data-type="plugin">
3886
+ <?php echo wp_kses_post( $plugin_data['action_text'] ); ?>
3887
+ </button>
 
 
 
 
 
 
 
 
 
 
3888
  </div>
3889
  </div>
3890
  </div>
3891
+ </div>
3892
 
3893
+ <?php } ?>
3894
 
3895
+ <?php
3896
+ endforeach;
3897
 
3898
+ if ( $has_all_plugins ) {
3899
+ ?>
3900
 
3901
+ <style type="text/css">.sbi-more-plugins-intro{display:none;}</style>
3902
+ <h2><?php esc_html_e( 'You already have all of our free plugins. Awesome!', 'instagram-feed' ); ?></h2>
3903
 
3904
+ <p><?php esc_html_e( 'Thank you so much for using our plugins. We appreciate you trusting us to power your social media feeds.', 'instagram-feed' ); ?></p>
3905
+ <p><?php esc_html_e( 'If you want to support us in our mission to make bringing social media content to your website both easy and reliable, then consider upgrading to one of our Pro plugins.', 'instagram-feed' ); ?></p>
3906
 
3907
+ <div class="sbi-cols-4">
3908
+ <?php //Show a list of Pro plugins which aren't currently active ?>
3909
+ <?php
3910
+ foreach ( $am_plugins as $plugin => $details ) :
3911
 
3912
+ $plugin_data = get_the_plugin_data( $plugin, $details, $all_plugins );
3913
+ $plugin_slug = strtolower( str_replace( ' ', '_', $plugin_data['details']['name'] ) );
3914
 
3915
+ isset( $plugin_data['details']['plug'] ) ? $pro_plugin_source = $plugin_data['details']['plug'] : $pro_plugin_source = '';
3916
+ if ( ! is_plugin_active( $pro_plugin_source ) ) {
3917
  ?>
3918
 
3919
+ <div class="addon-container" id="install_<?php echo esc_attr( $plugin_slug ); ?>">
3920
+ <div class="addon-item">
3921
+ <div class="details sbi-clear">
3922
+ <img alt="<?php echo esc_attr( $plugin_data['details']['name'] ); ?>" src="<?php echo esc_url( $plugin_data['details']['icon'] ); ?>">
3923
+ <h5 class="addon-name">
3924
+ <?php echo esc_html( $plugin_data['details']['name'] ); ?>
3925
+ </h5>
3926
+ <p class="addon-desc">
3927
+ <?php echo wp_kses_post( $plugin_data['details']['desc'] ); ?>
3928
+ </p>
3929
+ </div>
3930
+ <div class="actions sbi-clear">
3931
+ <div class="action-button">
3932
+ <a href="<?php echo esc_attr( $details['pro']['url'] ); ?>" target="_blank" class="status-go-to-url button button-primary">
3933
+ <?php esc_html_e( 'Upgrade to Pro', 'instagram-feed' ); ?>
3934
+ </a>
 
3935
  </div>
3936
  </div>
3937
  </div>
3938
+ </div>
3939
 
3940
+ <?php } ?>
3941
 
3942
+ <?php endforeach; ?>
3943
+ </div>
3944
 
3945
+ <?php } ?>
3946
 
 
3947
  </div>
3948
+ </div>
3949
+ <?php
3950
+ }
3951
 
3952
+ function get_the_plugin_data( $plugin, $details, $all_plugins, $free_only = false ) {
3953
 
3954
+ $have_pro = ( ! empty( $details['pro'] ) && ! empty( $details['pro']['plug'] ) );
3955
+ $show_pro = false;
3956
 
3957
+ $plugin_data = array();
3958
 
3959
+ if ( $free_only ) {
3960
+ $have_pro = false;
3961
+ }
3962
 
3963
+ if ( $have_pro ) {
3964
+ if ( array_key_exists( $plugin, $all_plugins ) ) {
3965
+ if ( is_plugin_active( $plugin ) ) {
 
 
 
 
3966
  $show_pro = true;
3967
  }
 
 
 
 
3968
  }
3969
+ if ( array_key_exists( $details['pro']['plug'], $all_plugins ) ) {
3970
+ $show_pro = true;
3971
+ }
3972
+ if ( $show_pro ) {
3973
+ $plugin = $details['pro']['plug'];
3974
+ $details = $details['pro'];
3975
+ }
3976
+ }
3977
 
3978
+ if ( $free_only ) {
3979
+ $show_pro = false;
3980
+ }
3981
 
3982
+ if ( array_key_exists( $plugin, $all_plugins ) ) {
3983
+ if ( is_plugin_active( $plugin ) ) {
3984
+ // Status text/status.
3985
+ $plugin_data['status_class'] = 'status-active';
3986
+ $plugin_data['status_text'] = esc_html__( 'Active', 'instagram-feed' );
3987
+ // Button text/status.
3988
+ $plugin_data['action_class'] = $plugin_data['status_class'] . ' button button-secondary disabled';
3989
+ $plugin_data['action_text'] = esc_html__( 'Activated', 'instagram-feed' );
3990
+ $plugin_data['plugin_src'] = esc_attr( $plugin );
 
 
 
 
 
 
 
 
 
3991
  } else {
 
3992
  // Status text/status.
3993
+ $plugin_data['status_class'] = 'status-inactive';
3994
+ $plugin_data['status_text'] = esc_html__( 'Inactive', 'instagram-feed' );
 
 
 
3995
  // Button text/status.
3996
+ $plugin_data['action_class'] = $plugin_data['status_class'] . ' button button-secondary';
3997
+ $plugin_data['action_text'] = esc_html__( 'Activate', 'instagram-feed' );
3998
+ $plugin_data['plugin_src'] = esc_attr( $plugin );
3999
  }
4000
+ } else {
4001
+ // Doesn't exist, install.
4002
+ // Status text/status.
4003
+ $plugin_data['status_class'] = 'status-download';
4004
+ if ( isset( $details['act'] ) && 'go-to-url' === $details['act'] ) {
4005
+ $plugin_data['status_class'] = 'status-go-to-url';
4006
+ }
4007
+ $plugin_data['status_text'] = esc_html__( 'Not Installed', 'instagram-feed' );
4008
+ // Button text/status.
4009
+ $plugin_data['action_class'] = $plugin_data['status_class'] . ' button button-primary';
4010
+ $plugin_data['action_text'] = esc_html__( 'Install Plugin', 'instagram-feed' );
4011
+ $plugin_data['plugin_src'] = esc_url( $details['url'] );
4012
  }
4013
 
4014
+ $plugin_data['details'] = $details;
4015
 
4016
+ return $plugin_data;
4017
+ }
 
 
 
4018
 
4019
+ output_about_addons();
 
4020
 
4021
+ ?>
4022
+ <style>.sbi_quickstart, .sbi-pro-notice, .sbi_plugins_promo, .sbi_share_plugin{ display: none !Important; }</style>
4023
+ </div>
4024
 
4025
+ <?php
4026
+ } //End More tab
4027
+ ?>
4028
 
4029
  <div class="sbi_quickstart">
4030
+ <h3><i class="fa fa-rocket" aria-hidden="true"></i>&nbsp; <?php esc_html_e( 'Display your feed', 'instagram-feed' ); ?></h3>
4031
+ <p><?php esc_html_e( 'Copy and paste this shortcode directly into the page, post or widget where you\'d like to display the feed:', 'instagram-feed' ); ?> <input type="text" value="[instagram-feed]" size="15" readonly="readonly" style="text-align: center;" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac)."></p>
4032
+ <p><?php echo wp_kses_post( __( 'Find out how to display <a href="?page=sb-instagram-feed&amp;tab=display">multiple feeds</a>.', 'instagram-feed' ) ); ?></p>
4033
  </div>
4034
 
4035
  <a href="https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=footer&utm_medium=ad" target="_blank" class="sbi-pro-notice">
4036
+ <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/instagram-pro-promo.png?2019' ); ?>" alt="<?php esc_attr_e( 'Instagram Feed Pro', 'instagram-feed' ); ?>">
4037
  </a>
4038
 
4039
+ <p class="sbi_plugins_promo dashicons-before dashicons-admin-plugins"> <?php echo wp_kses_post( __( 'Check out our other free plugins: <a href="https://wordpress.org/plugins/custom-facebook-feed/" target="_blank" rel="noopener noreferrer">Facebook</a>, <a href="https://wordpress.org/plugins/custom-twitter-feeds/" target="_blank" rel="noopener noreferrer">Twitter</a>, and <a href="https://wordpress.org/plugins/feeds-for-youtube/" target="_blank" rel="noopener noreferrer">YouTube</a>.', 'instagram-feed' ) ); ?></p>
4040
 
4041
  <div class="sbi_share_plugin">
4042
+ <h3><?php esc_html_e( 'Like the plugin? Help spread the word!', 'instagram-feed' ); ?></h3>
4043
 
4044
  <button id="sbi_admin_show_share_links" class="button secondary" style="margin-bottom: 1px;"><i class="fa fa-share-alt" aria-hidden="true"></i>&nbsp;&nbsp;Share the plugin</button> <div id="sbi_admin_share_links"></div>
4045
  </div>
4046
 
4047
  </div> <!-- end #sbi_admin -->
4048
 
4049
+ <?php
4050
+ } //End Settings page
inc/admin/templates/locator-summary.php CHANGED
@@ -13,88 +13,94 @@ if ( ! defined( 'ABSPATH' ) ) {
13
  $database_settings = sbi_get_database_settings();
14
  ?>
15
  <div class="sbi-feed-locator-summary-wrap">
16
- <h3><?php esc_html_e( 'Feed Finder Summary', 'instagram-feed' ); ?></h3>
17
- <p><?php esc_html_e( 'The table below shows a record of all feeds found on your site. A feed may not show up here immediately after being created.', 'instagram-feed' ); ?></p>
18
  <?php
19
- if ( ! empty( $locator_summary ) ) : ?>
 
20
 
21
- <?php foreach ( $locator_summary as $locator_section ) :
22
- if ( ! empty( $locator_section['results'] ) ) : ?>
23
- <div class="sbi-single-location">
24
- <h4><?php echo esc_html( $locator_section['label'] ); ?></h4>
25
- <table class="widefat striped" aria-describedby="sbi-locator-desc">
26
- <thead>
27
- <tr>
28
- <th scope="row"><?php esc_html_e( 'Type', 'instagram-feed' ); ?></th>
29
- <th scope="row"><?php esc_html_e( 'Sources', 'instagram-feed' ); ?></th>
30
- <th scope="row"><?php esc_html_e( 'Shortcode', 'instagram-feed' ); ?></th>
31
- <th scope="row"><?php esc_html_e( 'Location', 'instagram-feed' ); ?></th>
32
- </tr>
33
- </thead>
34
- <tbody>
 
 
35
 
36
  <?php
37
 
38
- $atts_for_page = array();
39
- foreach ($locator_section['results'] as $result) :
40
- $should_add = true;
41
- if (!empty($atts_for_page[$result['post_id']])) {
42
- foreach ($atts_for_page[$result['post_id']] as $existing_atts) {
43
- if ($existing_atts === $result['shortcode_atts']) {
44
- $should_add = false;
45
- }
46
- }
47
- }
48
- if ($should_add) {
49
- $atts_for_page[$result['post_id']][] = $result['shortcode_atts'];
50
 
51
- $shortcode_atts = json_decode( $result['shortcode_atts'], true );
52
- $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array();
53
 
54
- if ( class_exists( 'SB_Instagram_Settings_Pro' ) ) {
55
- $settings_obj = new SB_Instagram_Settings_Pro( $shortcode_atts, $database_settings );
56
- } else {
57
- $settings_obj = new SB_Instagram_Settings( $shortcode_atts, $database_settings );
58
- }
59
- $settings = $settings_obj->get_settings();
60
- $settings_obj->set_feed_type_and_terms();
61
- $display_terms = $settings_obj->feed_type_and_terms_display();
62
- $comma_separated = implode(', ', $display_terms );
63
- $display = $comma_separated;
64
- if ( strlen( $comma_separated ) > 31 ) {
65
- $display = '<span class="sbi-condensed-wrap">' . esc_html( substr( $comma_separated, 0, 30 ) ) . '<a class="sbi-locator-more" href="JavaScript:void(0);">...</a></span>';
66
- $comma_separated = '<span class="sbi-full-wrap">' . esc_html( $comma_separated ) . '</span>';
67
- } else {
68
- $comma_separated = '';
69
- }
70
- $type = isset( $settings['type'] ) ? $settings['type'] : 'user';
71
- $full_shortcode_string = '[instagram-feed';
72
- foreach ( $shortcode_atts as $key => $value ) {
73
- $full_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"';
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
- $full_shortcode_string .= ']';
76
- ?>
77
- <tr>
78
- <td><?php echo esc_html( $type ); ?></td>
79
- <td><?php echo $display . $comma_separated; ?></td>
80
- <td>
81
- <span class="sbi-condensed-wrap"><a class="sbi-locator-more" href="JavaScript:void(0);"><?php esc_html_e( 'Show', 'instagram-feed' ); ?></a></span>
82
- <span class="sbi-full-wrap"><?php echo esc_html( $full_shortcode_string ); ?></span>
83
- </td>
84
- <td><a href="<?php echo esc_url( get_the_permalink( $result['post_id'] ) ); ?>" target="_blank" rel="noopener"><?php echo esc_html( get_the_title( $result['post_id'] ) ); ?></a></td>
85
- </tr>
86
- <?php
87
- }
88
- endforeach; ?>
89
 
90
 
91
- </tbody>
92
- </table>
93
- </div>
94
 
95
- <?php endif;
 
96
  endforeach;
97
- else: ?>
98
- <p><?php esc_html_e( 'Locations of your feeds are currently being detected. You\'ll see more information posted here soon!', 'instagram-feed' ); ?></p>
 
99
  <?php endif; ?>
100
- </div>
13
  $database_settings = sbi_get_database_settings();
14
  ?>
15
  <div class="sbi-feed-locator-summary-wrap">
16
+ <h3><?php esc_html_e( 'Feed Finder Summary', 'instagram-feed' ); ?></h3>
17
+ <p><?php esc_html_e( 'The table below shows a record of all feeds found on your site. A feed may not show up here immediately after being created.', 'instagram-feed' ); ?></p>
18
  <?php
19
+ if ( ! empty( $locator_summary ) ) :
20
+ ?>
21
 
22
+ <?php
23
+ foreach ( $locator_summary as $locator_section ) :
24
+ if ( ! empty( $locator_section['results'] ) ) :
25
+ ?>
26
+ <div class="sbi-single-location">
27
+ <h4><?php echo esc_html( $locator_section['label'] ); ?></h4>
28
+ <table class="widefat striped" aria-describedby="sbi-locator-desc">
29
+ <thead>
30
+ <tr>
31
+ <th scope="row"><?php esc_html_e( 'Type', 'instagram-feed' ); ?></th>
32
+ <th scope="row"><?php esc_html_e( 'Sources', 'instagram-feed' ); ?></th>
33
+ <th scope="row"><?php esc_html_e( 'Shortcode', 'instagram-feed' ); ?></th>
34
+ <th scope="row"><?php esc_html_e( 'Location', 'instagram-feed' ); ?></th>
35
+ </tr>
36
+ </thead>
37
+ <tbody>
38
 
39
  <?php
40
 
41
+ $atts_for_page = array();
42
+ foreach ( $locator_section['results'] as $result ) :
43
+ $should_add = true;
44
+ if ( ! empty( $atts_for_page[ $result['post_id'] ] ) ) {
45
+ foreach ( $atts_for_page[ $result['post_id'] ] as $existing_atts ) {
46
+ if ( $existing_atts === $result['shortcode_atts'] ) {
47
+ $should_add = false;
48
+ }
49
+ }
50
+ }
51
+ if ( $should_add ) {
52
+ $atts_for_page[ $result['post_id'] ][] = $result['shortcode_atts'];
53
 
54
+ $shortcode_atts = json_decode( $result['shortcode_atts'], true );
55
+ $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array();
56
 
57
+ if ( class_exists( 'SB_Instagram_Settings_Pro' ) ) {
58
+ $settings_obj = new SB_Instagram_Settings_Pro( $shortcode_atts, $database_settings );
59
+ } else {
60
+ $settings_obj = new SB_Instagram_Settings( $shortcode_atts, $database_settings );
61
+ }
62
+ $settings = $settings_obj->get_settings();
63
+ $settings_obj->set_feed_type_and_terms();
64
+ $display_terms = $settings_obj->feed_type_and_terms_display();
65
+ $comma_separated = implode( ', ', $display_terms );
66
+ $display = $comma_separated;
67
+ if ( strlen( $comma_separated ) > 31 ) {
68
+ $display = '<span class="sbi-condensed-wrap">' . esc_html( substr( $comma_separated, 0, 30 ) ) . '<a class="sbi-locator-more" href="JavaScript:void(0);">...</a></span>';
69
+ $comma_separated = '<span class="sbi-full-wrap">' . esc_html( $comma_separated ) . '</span>';
70
+ } else {
71
+ $comma_separated = '';
72
+ }
73
+ $type = isset( $settings['type'] ) ? $settings['type'] : 'user';
74
+ $full_shortcode_string = '[instagram-feed';
75
+ foreach ( $shortcode_atts as $key => $value ) {
76
+ $full_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"';
77
+ }
78
+ $full_shortcode_string .= ']';
79
+ ?>
80
+ <tr>
81
+ <td><?php echo esc_html( $type ); ?></td>
82
+ <td><?php echo wp_kses_post( $display . $comma_separated ); ?></td>
83
+ <td>
84
+ <span class="sbi-condensed-wrap"><a class="sbi-locator-more" href="JavaScript:void(0);"><?php esc_html_e( 'Show', 'instagram-feed' ); ?></a></span>
85
+ <span class="sbi-full-wrap"><?php echo esc_html( $full_shortcode_string ); ?></span>
86
+ </td>
87
+ <td><a href="<?php echo esc_url( get_the_permalink( $result['post_id'] ) ); ?>" target="_blank" rel="noopener"><?php echo esc_html( get_the_title( $result['post_id'] ) ); ?></a></td>
88
+ </tr>
89
+ <?php
90
  }
91
+ endforeach;
92
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
 
95
+ </tbody>
96
+ </table>
97
+ </div>
98
 
99
+ <?php
100
+ endif;
101
  endforeach;
102
+ else :
103
+ ?>
104
+ <p><?php esc_html_e( 'Locations of your feeds are currently being detected. You\'ll see more information posted here soon!', 'instagram-feed' ); ?></p>
105
  <?php endif; ?>
106
+ </div>
inc/class-sb-instagram-api-connect.php CHANGED
@@ -65,7 +65,7 @@ class SB_Instagram_API_Connect
65
  if ( $this->is_wp_error() ) {
66
  return array();
67
  }
68
- if (!empty($this->response['data'])) {
69
  return $this->response['data'];
70
  } else {
71
  return $this->response;
@@ -82,7 +82,10 @@ class SB_Instagram_API_Connect
82
  */
83
  public function get_wp_error() {
84
  if ( $this->is_wp_error() ) {
85
- return array( 'response' => $this->response, 'url' => $this->url );
 
 
 
86
  } else {
87
  return false;
88
  }
@@ -98,7 +101,7 @@ class SB_Instagram_API_Connect
98
  *
99
  * @since 2.2.2/5.3.3
100
  */
101
- public function type_allows_after_paging( $type ) {
102
  return false;
103
  }
104
 
@@ -111,13 +114,13 @@ class SB_Instagram_API_Connect
111
  *
112
  * @since 2.0/5.0
113
  */
114
- public function get_next_page( $type = '' ) {
115
  if ( ! empty( $this->response['pagination']['next_url'] ) ) {
116
  return $this->response['pagination']['next_url'];
117
  } elseif ( ! empty( $this->response['paging']['next'] ) ) {
118
  return $this->response['paging']['next'];
119
  } else {
120
- if ( $this->type_allows_after_paging( $type ) ) {
121
  if ( isset( $this->response['paging']['cursors']['after'] ) ) {
122
  return $this->response['paging']['cursors']['after'];
123
  }
@@ -169,7 +172,7 @@ class SB_Instagram_API_Connect
169
  $response = $this->response;
170
  }
171
 
172
- return (isset( $response['error'] ));
173
  }
174
 
175
  /**
@@ -179,9 +182,9 @@ class SB_Instagram_API_Connect
179
  */
180
  public function connect() {
181
  $args = array(
182
- 'timeout' => 20
183
  );
184
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
185
  $args['sslverify'] = false;
186
  }
187
  $response = wp_remote_get( $this->url, $args );
@@ -204,7 +207,7 @@ class SB_Instagram_API_Connect
204
  *
205
  * @since 2.0/5.0
206
  */
207
- public static function handle_instagram_error( $response, $error_connected_account, $request_type ) {
208
  global $sb_instagram_posts_manager;
209
  delete_option( 'sbi_dismiss_critical_notice' );
210
 
@@ -245,8 +248,8 @@ class SB_Instagram_API_Connect
245
  * @since 2.2/5.3 added endpoints for the basic display API
246
  */
247
  protected function set_url( $connected_account, $endpoint_slug, $params ) {
248
- $account_type = isset( $connected_account['type'] ) ? $connected_account['type'] : 'personal';
249
- $num = ! empty( $params['num'] ) ? (int)$params['num'] : 33;
250
 
251
  if ( $account_type === 'basic' ) {
252
  if ( $endpoint_slug === 'access_token' ) {
@@ -255,25 +258,25 @@ class SB_Instagram_API_Connect
255
  $url = 'https://graph.instagram.com/me?fields=id,username,media_count&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
256
  } else {
257
  $num = min( $num, 200 );
258
- $url = 'https://graph.instagram.com/' . sbi_maybe_clean( $connected_account['user_id'] ) . '/media?fields=media_url,thumbnail_url,caption,id,media_type,timestamp,username,comments_count,like_count,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit='.$num.'&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
259
  }
260
  } elseif ( $account_type === 'personal' ) {
261
  if ( $endpoint_slug === 'header' ) {
262
  $url = 'https://api.instagram.com/v1/users/' . $connected_account['user_id'] . '?access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
263
  } else {
264
  $num = $num > 20 ? min( $num, 33 ) : 20; // minimum set at 20 due to IG TV bug
265
- $url = 'https://api.instagram.com/v1/users/' . $connected_account['user_id'] . '/media/recent?count='.$num.'&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
266
  }
267
  } else {
268
- if ( $endpoint_slug === 'header' ) {
269
  $url = 'https://graph.facebook.com/' . $connected_account['user_id'] . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
270
  } else {
271
  $num = min( $num, 200 );
272
- $url = 'https://graph.facebook.com/v10.0/' . $connected_account['user_id'] . '/media?fields=media_url,media_product_type,video_title,thumbnail_url,caption,id,media_type,timestamp,username,comments_count,like_count,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit='.$num.'&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
273
  }
274
  }
275
 
276
  $this->set_url_from_args( $url );
277
  }
278
 
279
- }
65
  if ( $this->is_wp_error() ) {
66
  return array();
67
  }
68
+ if ( ! empty( $this->response['data'] ) ) {
69
  return $this->response['data'];
70
  } else {
71
  return $this->response;
82
  */
83
  public function get_wp_error() {
84
  if ( $this->is_wp_error() ) {
85
+ return array(
86
+ 'response' => $this->response,
87
+ 'url' => $this->url,
88
+ );
89
  } else {
90
  return false;
91
  }
101
  *
102
  * @since 2.2.2/5.3.3
103
  */
104
+ public function type_allows_after_paging( ) {
105
  return false;
106
  }
107
 
114
  *
115
  * @since 2.0/5.0
116
  */
117
+ public function get_next_page( ) {
118
  if ( ! empty( $this->response['pagination']['next_url'] ) ) {
119
  return $this->response['pagination']['next_url'];
120
  } elseif ( ! empty( $this->response['paging']['next'] ) ) {
121
  return $this->response['paging']['next'];
122
  } else {
123
+ if ( $this->type_allows_after_paging( ) ) {
124
  if ( isset( $this->response['paging']['cursors']['after'] ) ) {
125
  return $this->response['paging']['cursors']['after'];
126
  }
172
  $response = $this->response;
173
  }
174
 
175
+ return ( isset( $response['error'] ) );
176
  }
177
 
178
  /**
182
  */
183
  public function connect() {
184
  $args = array(
185
+ 'timeout' => 20,
186
  );
187
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
188
  $args['sslverify'] = false;
189
  }
190
  $response = wp_remote_get( $this->url, $args );
207
  *
208
  * @since 2.0/5.0
209
  */
210
+ public static function handle_instagram_error( $response, $error_connected_account ) {
211
  global $sb_instagram_posts_manager;
212
  delete_option( 'sbi_dismiss_critical_notice' );
213
 
248
  * @since 2.2/5.3 added endpoints for the basic display API
249
  */
250
  protected function set_url( $connected_account, $endpoint_slug, $params ) {
251
+ $account_type = ! empty( $connected_account['type'] ) ? $connected_account['type'] : 'personal';
252
+ $num = ! empty( $params['num'] ) ? (int) $params['num'] : 33;
253
 
254
  if ( $account_type === 'basic' ) {
255
  if ( $endpoint_slug === 'access_token' ) {
258
  $url = 'https://graph.instagram.com/me?fields=id,username,media_count&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
259
  } else {
260
  $num = min( $num, 200 );
261
+ $url = 'https://graph.instagram.com/' . sbi_maybe_clean( $connected_account['user_id'] ) . '/media?fields=media_url,thumbnail_url,caption,id,media_type,timestamp,username,comments_count,like_count,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit=' . $num . '&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
262
  }
263
  } elseif ( $account_type === 'personal' ) {
264
  if ( $endpoint_slug === 'header' ) {
265
  $url = 'https://api.instagram.com/v1/users/' . $connected_account['user_id'] . '?access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
266
  } else {
267
  $num = $num > 20 ? min( $num, 33 ) : 20; // minimum set at 20 due to IG TV bug
268
+ $url = 'https://api.instagram.com/v1/users/' . $connected_account['user_id'] . '/media/recent?count=' . $num . '&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
269
  }
270
  } else {
271
+ if ( 'header' === $endpoint_slug ) {
272
  $url = 'https://graph.facebook.com/' . $connected_account['user_id'] . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
273
  } else {
274
  $num = min( $num, 200 );
275
+ $url = 'https://graph.facebook.com/v10.0/' . $connected_account['user_id'] . '/media?fields=media_url,media_product_type,video_title,thumbnail_url,caption,id,media_type,timestamp,username,comments_count,like_count,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit=' . $num . '&access_token=' . sbi_maybe_clean( $connected_account['access_token'] );
276
  }
277
  }
278
 
279
  $this->set_url_from_args( $url );
280
  }
281
 
282
+ }
inc/class-sb-instagram-connected-account.php CHANGED
@@ -21,16 +21,11 @@ class SB_Instagram_Connected_Account {
21
  */
22
  public $account;
23
 
24
- /**
25
- * @since 5.12.4
26
- */
27
- const ALGORITHM = 'AES-256-CBC';
28
-
29
  public function __construct( $search_term_or_account, $search_type = 'user' ) {
30
  if ( is_array( $search_term_or_account ) ) {
31
  $this->account = $search_term_or_account;
32
  } else {
33
- $this->account = SB_Instagram_Connected_Account::lookup( $search_term_or_account, $search_type );
34
  }
35
  }
36
 
@@ -55,48 +50,43 @@ class SB_Instagram_Connected_Account {
55
  * @since 5.10
56
  */
57
  public static function lookup( $search_term, $search_type = 'user' ) {
58
- $options = sbi_get_database_settings();
59
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
60
 
61
  if ( is_array( $search_term ) ) {
62
  return false;
63
  }
64
 
65
- if ( $search_type === 'business' ) {
66
- if ( $search_term === '' ) {
67
- $business_accounts = array();
68
  $access_tokens_found = array();
69
  foreach ( $connected_accounts as $connected_account ) {
70
- if ( isset( $connected_account['type'] )
71
- && $connected_account['type'] === 'business'
72
- && ! in_array( $connected_account['access_token'], $access_tokens_found, true ) ) {
73
- $business_accounts[] = $connected_account;
74
  $access_tokens_found[] = $connected_account['access_token'];
75
  }
76
  }
77
  return $business_accounts;
78
  } else {
79
  foreach ( $connected_accounts as $connected_account ) {
80
- if ( isset( $connected_account['type'] )
81
- && $connected_account['type'] === 'business' ) {
82
  return $connected_account;
83
  }
84
  }
85
-
86
-
87
  }
88
-
89
  } else {
90
  if ( isset( $connected_accounts[ $search_term ] ) ) {
91
  return $connected_accounts[ $search_term ];
92
  } else {
93
  foreach ( $connected_accounts as $connected_account ) {
94
- if ( strpos( $connected_account['access_token'], '.' ) === false ) {
95
- if ( strtolower( $connected_account['username'] ) === trim( strtolower( $search_term ) ) ) {
96
- return $connected_account;
97
- } elseif ( $connected_account['access_token'] === trim( strtolower( $search_term ) ) ) {
98
  return $connected_account;
99
- }
 
100
  }
101
  }
102
  }
@@ -119,7 +109,7 @@ class SB_Instagram_Connected_Account {
119
  */
120
  public static function create_local_avatar( $username, $profile_picture ) {
121
  $options = sbi_get_database_settings();
122
- if ( !$options['sb_instagram_disable_resize'] ) {
123
  if ( sbi_create_local_avatar( $username, $profile_picture ) ) {
124
  return true;
125
  }
@@ -171,7 +161,7 @@ class SB_Instagram_Connected_Account {
171
  */
172
  public static function encrypt_connected_account_tokens( $connected_account ) {
173
  if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) {
174
- $encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] );
175
  $connected_account['access_token'] = $encrypted_access_token;
176
 
177
  if ( isset( $connected_account['page_access_token'] ) ) {
@@ -196,15 +186,15 @@ class SB_Instagram_Connected_Account {
196
  * @since 5.12.4
197
  */
198
  public static function encrypt_all_access_tokens() {
199
- $options = sbi_get_database_settings();
200
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
201
 
202
  $updated = array();
203
  foreach ( $connected_accounts as $key => $connected_account ) {
204
  $updated[ $key ] = $connected_account;
205
 
206
  if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) {
207
- $encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] );
208
  $updated[ $key ]['access_token'] = $encrypted_access_token;
209
 
210
  if ( isset( $connected_account['page_access_token'] ) ) {
@@ -225,8 +215,8 @@ class SB_Instagram_Connected_Account {
225
  }
226
 
227
  public static function get_all_connected_accounts() {
228
- $options = sbi_get_database_settings();
229
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
230
 
231
  return $connected_accounts;
232
  }
@@ -240,4 +230,4 @@ class SB_Instagram_Connected_Account {
240
 
241
  return $connected_accounts;
242
  }
243
- }
21
  */
22
  public $account;
23
 
 
 
 
 
 
24
  public function __construct( $search_term_or_account, $search_type = 'user' ) {
25
  if ( is_array( $search_term_or_account ) ) {
26
  $this->account = $search_term_or_account;
27
  } else {
28
+ $this->account = self::lookup( $search_term_or_account, $search_type );
29
  }
30
  }
31
 
50
  * @since 5.10
51
  */
52
  public static function lookup( $search_term, $search_type = 'user' ) {
53
+ $options = sbi_get_database_settings();
54
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
55
 
56
  if ( is_array( $search_term ) ) {
57
  return false;
58
  }
59
 
60
+ if ( 'business' === $search_type ) {
61
+ if ( empty( $search_term ) ) {
62
+ $business_accounts = array();
63
  $access_tokens_found = array();
64
  foreach ( $connected_accounts as $connected_account ) {
65
+ if ( isset( $connected_account['type'] ) && 'business' === $connected_account['type'] && ! in_array( $connected_account['access_token'], $access_tokens_found, true ) ) {
66
+ $business_accounts[] = $connected_account;
 
 
67
  $access_tokens_found[] = $connected_account['access_token'];
68
  }
69
  }
70
  return $business_accounts;
71
  } else {
72
  foreach ( $connected_accounts as $connected_account ) {
73
+ if ( isset( $connected_account['type'] ) && 'business' === $connected_account['type'] ) {
 
74
  return $connected_account;
75
  }
76
  }
 
 
77
  }
 
78
  } else {
79
  if ( isset( $connected_accounts[ $search_term ] ) ) {
80
  return $connected_accounts[ $search_term ];
81
  } else {
82
  foreach ( $connected_accounts as $connected_account ) {
83
+ if (
84
+ strpos( $connected_account['access_token'], '.' ) === false &&
85
+ ( strtolower( $connected_account['username'] ) === trim( strtolower( $search_term ) ) || $connected_account['access_token'] === trim( strtolower( $search_term ) ) )
86
+ ) {
87
  return $connected_account;
88
+ } elseif ( $connected_account['access_token'] === trim( strtolower( $search_term ) ) ) {
89
+ return $connected_account;
90
  }
91
  }
92
  }
109
  */
110
  public static function create_local_avatar( $username, $profile_picture ) {
111
  $options = sbi_get_database_settings();
112
+ if ( ! $options['sb_instagram_disable_resize'] ) {
113
  if ( sbi_create_local_avatar( $username, $profile_picture ) ) {
114
  return true;
115
  }
161
  */
162
  public static function encrypt_connected_account_tokens( $connected_account ) {
163
  if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) {
164
+ $encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] );
165
  $connected_account['access_token'] = $encrypted_access_token;
166
 
167
  if ( isset( $connected_account['page_access_token'] ) ) {
186
  * @since 5.12.4
187
  */
188
  public static function encrypt_all_access_tokens() {
189
+ $options = sbi_get_database_settings();
190
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
191
 
192
  $updated = array();
193
  foreach ( $connected_accounts as $key => $connected_account ) {
194
  $updated[ $key ] = $connected_account;
195
 
196
  if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) {
197
+ $encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] );
198
  $updated[ $key ]['access_token'] = $encrypted_access_token;
199
 
200
  if ( isset( $connected_account['page_access_token'] ) ) {
215
  }
216
 
217
  public static function get_all_connected_accounts() {
218
+ $options = sbi_get_database_settings();
219
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
220
 
221
  return $connected_accounts;
222
  }
230
 
231
  return $connected_accounts;
232
  }
233
+ }
inc/class-sb-instagram-cron-updater.php CHANGED
@@ -15,8 +15,8 @@ if ( ! defined( 'ABSPATH' ) ) {
15
  die( '-1' );
16
  }
17
 
18
- class SB_Instagram_Cron_Updater
19
- {
20
  /**
21
  * Find and loop through all feed cache transients and update the post and
22
  * header caches
@@ -26,60 +26,56 @@ class SB_Instagram_Cron_Updater
26
  * @since 2.0/5.0
27
  */
28
  public static function do_feed_updates() {
29
- $feed_caches = SB_Instagram_Cron_Updater::get_feed_cache_option_names();
30
- shuffle( $feed_caches );
31
  $settings = sbi_get_database_settings();
32
 
33
  // this is outputted in system info
34
  $report = array(
35
  'notes' => array(
36
- 'time_ran' => date( 'Y-m-d H:i:s' ),
37
- 'num_found_transients' => count( $feed_caches )
38
- )
39
  );
40
 
41
  foreach ( $feed_caches as $feed_cache ) {
42
 
43
- $feed_id = str_replace( '_transient_', '', $feed_cache['option_name'] );
44
  $report[ $feed_id ] = array();
45
 
46
  $transient = get_transient( $feed_id );
47
 
48
  if ( $transient ) {
49
- $feed_data = json_decode( $transient, true );
50
 
51
  // shortcode attributes are saved in order to recreate the feed is needed
52
- $atts = isset( $feed_data['atts'] ) ? $feed_data['atts'] : false;
53
- $last_retrieve = isset( $feed_data['last_retrieve'] ) ? (int)$feed_data['last_retrieve'] : 0;
54
  // the last approximate time the feed was requested to be displayed on a page is recorded
55
  // in order to stop updating feeds not in use.
56
- $last_requested = isset( $feed_data['last_requested'] ) ? (int)$feed_data['last_requested'] : false;
57
  $report[ $feed_id ]['last_retrieve'] = date( 'Y-m-d H:i:s', $last_retrieve );
58
  if ( $atts !== false ) {
59
 
60
- if ( ! $last_requested || $last_requested > (time() - 60*60*24*30) ) {
61
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $settings );
62
 
63
  if ( empty( $settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
64
  $report[ $feed_id ]['did_update'] = 'no - no connected account';
65
  } else {
66
- SB_Instagram_Cron_Updater::do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts );
67
 
68
  $report[ $feed_id ]['did_update'] = 'yes';
69
  }
70
  } else {
71
  $report[ $feed_id ]['did_update'] = 'no - not recently requested';
72
  }
73
-
74
-
75
  } else {
76
  $report[ $feed_id ]['did_update'] = 'no - missing atts';
77
  }
78
-
79
  } else {
80
  $report[ $feed_id ]['did_update'] = 'no - no transient found';
81
  }
82
-
83
  }
84
 
85
  update_option( 'sbi_cron_report', $report, false );
@@ -92,8 +88,7 @@ class SB_Instagram_Cron_Updater
92
  *
93
  * Overwritten in the Pro version
94
  *
95
- * @param array $instagram_feed_settings associative array generated from
96
- * the sb_instagram_settings class
97
  * @param array $feed_data post, header, shortcode settings, and other info
98
  * associated with the feed that is saved in the cache
99
  * @param array $atts shortcode settings
@@ -107,8 +102,8 @@ class SB_Instagram_Cron_Updater
107
  public static function do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts, $include_resize = true ) {
108
  $instagram_feed_settings->set_feed_type_and_terms();
109
  $instagram_feed_settings->set_transient_name();
110
- $transient_name = $instagram_feed_settings->get_transient_name();
111
- $settings = $instagram_feed_settings->get_settings();
112
  $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
113
 
114
  $instagram_feed = new SB_Instagram_Feed( $transient_name );
@@ -118,9 +113,9 @@ class SB_Instagram_Cron_Updater
118
  }
119
 
120
  $to_cache = array(
121
- 'atts' => $atts,
122
  'last_requested' => $feed_data['last_requested'],
123
- 'last_retrieve' => time()
124
  );
125
 
126
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
@@ -136,11 +131,19 @@ class SB_Instagram_Cron_Updater
136
  $post_data = array_slice( $post_data, 0, $settings['num'] );
137
 
138
  $image_sizes = array(
139
- 'personal' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ),
140
- 'business' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 )
 
 
 
 
 
 
 
 
141
  );
142
 
143
- $post_set = new SB_Instagram_Post_Set( $post_data, $transient_name, NULL, $image_sizes );
144
 
145
  $post_set->maybe_save_update_and_resize_images_for_posts();
146
  }
@@ -163,11 +166,14 @@ class SB_Instagram_Cron_Updater
163
  return $feed_caches;
164
  }
165
 
166
- $results = $wpdb->get_results( "
 
167
  SELECT option_name
168
  FROM $wpdb->options
169
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
170
- AND `option_name` NOT LIKE ('%\_transient\_sbi\_header%');", ARRAY_A );
 
 
171
 
172
  if ( isset( $results[0] ) ) {
173
  $feed_caches = $results;
@@ -192,15 +198,15 @@ class SB_Instagram_Cron_Updater
192
 
193
  if ( $sbi_cache_cron_interval === '12hours' || $sbi_cache_cron_interval === '24hours' ) {
194
  $relative_time_now = time() + sbi_get_utc_offset();
195
- $base_day = strtotime( date( 'Y-m-d', $relative_time_now ) );
196
- $add_time = $sbi_cache_cron_am_pm === 'pm' ? (int)$sbi_cache_cron_time + 12 : (int)$sbi_cache_cron_time;
197
- $utc_start_time = $base_day + (($add_time * 60 * 60) - sbi_get_utc_offset());
198
 
199
  if ( $utc_start_time < time() ) {
200
  if ( $sbi_cache_cron_interval === '12hours' ) {
201
- $utc_start_time += 60*60*12;
202
  } else {
203
- $utc_start_time += 60*60*24;
204
  }
205
  }
206
 
@@ -209,7 +215,6 @@ class SB_Instagram_Cron_Updater
209
  } else {
210
  wp_schedule_event( $utc_start_time, 'daily', 'sbi_feed_update' );
211
  }
212
-
213
  } else {
214
 
215
  if ( $sbi_cache_cron_interval === '30mins' ) {
@@ -221,4 +226,4 @@ class SB_Instagram_Cron_Updater
221
 
222
  }
223
 
224
- }
15
  die( '-1' );
16
  }
17
 
18
+ class SB_Instagram_Cron_Updater {
19
+
20
  /**
21
  * Find and loop through all feed cache transients and update the post and
22
  * header caches
26
  * @since 2.0/5.0
27
  */
28
  public static function do_feed_updates() {
29
+ $feed_caches = self::get_feed_cache_option_names();
30
+ shuffle( $feed_caches );
31
  $settings = sbi_get_database_settings();
32
 
33
  // this is outputted in system info
34
  $report = array(
35
  'notes' => array(
36
+ 'time_ran' => date( 'Y-m-d H:i:s' ),
37
+ 'num_found_transients' => count( $feed_caches ),
38
+ ),
39
  );
40
 
41
  foreach ( $feed_caches as $feed_cache ) {
42
 
43
+ $feed_id = str_replace( '_transient_', '', $feed_cache['option_name'] );
44
  $report[ $feed_id ] = array();
45
 
46
  $transient = get_transient( $feed_id );
47
 
48
  if ( $transient ) {
49
+ $feed_data = json_decode( $transient, true );
50
 
51
  // shortcode attributes are saved in order to recreate the feed is needed
52
+ $atts = isset( $feed_data['atts'] ) ? $feed_data['atts'] : false;
53
+ $last_retrieve = isset( $feed_data['last_retrieve'] ) ? (int) $feed_data['last_retrieve'] : 0;
54
  // the last approximate time the feed was requested to be displayed on a page is recorded
55
  // in order to stop updating feeds not in use.
56
+ $last_requested = isset( $feed_data['last_requested'] ) ? (int) $feed_data['last_requested'] : false;
57
  $report[ $feed_id ]['last_retrieve'] = date( 'Y-m-d H:i:s', $last_retrieve );
58
  if ( $atts !== false ) {
59
 
60
+ if ( ! $last_requested || $last_requested > ( time() - 60 * 60 * 24 * 30 ) ) {
61
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $settings );
62
 
63
  if ( empty( $settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
64
  $report[ $feed_id ]['did_update'] = 'no - no connected account';
65
  } else {
66
+ self::do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts );
67
 
68
  $report[ $feed_id ]['did_update'] = 'yes';
69
  }
70
  } else {
71
  $report[ $feed_id ]['did_update'] = 'no - not recently requested';
72
  }
 
 
73
  } else {
74
  $report[ $feed_id ]['did_update'] = 'no - missing atts';
75
  }
 
76
  } else {
77
  $report[ $feed_id ]['did_update'] = 'no - no transient found';
78
  }
 
79
  }
80
 
81
  update_option( 'sbi_cron_report', $report, false );
88
  *
89
  * Overwritten in the Pro version
90
  *
91
+ * @param object|SB_Instagram_Settings $instagram_feed_settings
 
92
  * @param array $feed_data post, header, shortcode settings, and other info
93
  * associated with the feed that is saved in the cache
94
  * @param array $atts shortcode settings
102
  public static function do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts, $include_resize = true ) {
103
  $instagram_feed_settings->set_feed_type_and_terms();
104
  $instagram_feed_settings->set_transient_name();
105
+ $transient_name = $instagram_feed_settings->get_transient_name();
106
+ $settings = $instagram_feed_settings->get_settings();
107
  $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
108
 
109
  $instagram_feed = new SB_Instagram_Feed( $transient_name );
113
  }
114
 
115
  $to_cache = array(
116
+ 'atts' => $atts,
117
  'last_requested' => $feed_data['last_requested'],
118
+ 'last_retrieve' => time(),
119
  );
120
 
121
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
131
  $post_data = array_slice( $post_data, 0, $settings['num'] );
132
 
133
  $image_sizes = array(
134
+ 'personal' => array(
135
+ 'full' => 640,
136
+ 'low' => 320,
137
+ 'thumb' => 150,
138
+ ),
139
+ 'business' => array(
140
+ 'full' => 640,
141
+ 'low' => 320,
142
+ 'thumb' => 150,
143
+ ),
144
  );
145
 
146
+ $post_set = new SB_Instagram_Post_Set( $post_data, $transient_name, null, $image_sizes );
147
 
148
  $post_set->maybe_save_update_and_resize_images_for_posts();
149
  }
166
  return $feed_caches;
167
  }
168
 
169
+ $results = $wpdb->get_results(
170
+ "
171
  SELECT option_name
172
  FROM $wpdb->options
173
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
174
+ AND `option_name` NOT LIKE ('%\_transient\_sbi\_header%');",
175
+ ARRAY_A
176
+ );
177
 
178
  if ( isset( $results[0] ) ) {
179
  $feed_caches = $results;
198
 
199
  if ( $sbi_cache_cron_interval === '12hours' || $sbi_cache_cron_interval === '24hours' ) {
200
  $relative_time_now = time() + sbi_get_utc_offset();
201
+ $base_day = strtotime( date( 'Y-m-d', $relative_time_now ) );
202
+ $add_time = $sbi_cache_cron_am_pm === 'pm' ? (int) $sbi_cache_cron_time + 12 : (int) $sbi_cache_cron_time;
203
+ $utc_start_time = $base_day + ( ( $add_time * 60 * 60 ) - sbi_get_utc_offset() );
204
 
205
  if ( $utc_start_time < time() ) {
206
  if ( $sbi_cache_cron_interval === '12hours' ) {
207
+ $utc_start_time += 60 * 60 * 12;
208
  } else {
209
+ $utc_start_time += 60 * 60 * 24;
210
  }
211
  }
212
 
215
  } else {
216
  wp_schedule_event( $utc_start_time, 'daily', 'sbi_feed_update' );
217
  }
 
218
  } else {
219
 
220
  if ( $sbi_cache_cron_interval === '30mins' ) {
226
 
227
  }
228
 
229
+ }
inc/class-sb-instagram-data-manager.php CHANGED
@@ -80,7 +80,7 @@ class SB_Instagram_Data_Manager {
80
 
81
  $data_was_deleted = false;
82
 
83
- if ( $statuses['last_used'] < sbi_get_current_time() - (21 * DAY_IN_SECONDS) ) {
84
  global $sb_instagram_posts_manager;
85
 
86
  $this->delete_caches();
@@ -92,7 +92,7 @@ class SB_Instagram_Data_Manager {
92
  $data_was_deleted = true;
93
  }
94
 
95
- if ( $statuses['last_used'] < sbi_get_current_time() - (90 * DAY_IN_SECONDS) ) {
96
  SB_Instagram_Connected_Account::update_connected_accounts( array() );
97
  global $sb_instagram_posts_manager;
98
 
@@ -126,15 +126,17 @@ class SB_Instagram_Data_Manager {
126
  */
127
  public function delete_non_hashtag_sbi_instagram_posts( $username ) {
128
  global $wpdb;
129
- $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
130
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
131
 
132
  $non_hashtag_posts = $wpdb->get_results(
133
  "SELECT p.id, p.media_id FROM $table_name as p
134
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
135
- WHERE f.hashtag = '';", ARRAY_A );
 
 
136
 
137
- $upload = wp_upload_dir();
138
  $file_suffixes = array( 'thumb', 'low', 'full' );
139
 
140
  foreach ( $non_hashtag_posts as $post ) {
@@ -153,8 +155,10 @@ class SB_Instagram_Data_Manager {
153
 
154
  $non_hashtag_posts_deleted = $wpdb->query(
155
  "DELETE p, f FROM $table_name as p
156
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
157
- WHERE f.hashtag = '';", ARRAY_A );
 
 
158
 
159
  }
160
 
@@ -165,14 +169,15 @@ class SB_Instagram_Data_Manager {
165
  */
166
  public function update_json_non_hashtag_sbi_instagram_posts() {
167
  global $wpdb;
168
- $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
169
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
170
 
171
  $updated = $wpdb->query(
172
  "UPDATE $table_name as p
173
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
174
  SET p.json_data = ''
175
- WHERE f.hashtag = '';" );
 
176
 
177
  }
178
 
@@ -193,16 +198,18 @@ class SB_Instagram_Data_Manager {
193
  $this->update_statuses( $statuses );
194
 
195
  global $wpdb;
196
- $encryption = new SB_Instagram_Data_Encryption();
197
- $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
198
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
199
-
200
  $plaintext_posts = $wpdb->get_results(
201
  "SELECT * FROM $table_name as p
202
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
203
  WHERE p.json_data LIKE '%{%'
204
  ORDER BY p.time_stamp DESC
205
- LIMIT 50;", ARRAY_A );
 
 
206
 
207
  if ( empty( $plaintext_posts ) ) {
208
  $statuses['num_db_updates'] = 31;
@@ -211,11 +218,16 @@ class SB_Instagram_Data_Manager {
211
 
212
  foreach ( $plaintext_posts as $post ) {
213
  $json_data = $encryption->encrypt( $post['json_data'] );
214
- $updated = $wpdb->query( $wpdb->prepare(
215
- "UPDATE $table_name as p
216
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
 
217
  SET p.json_data = %s
218
- WHERE p.id = %d;", $json_data, $post['id'] ) );
 
 
 
 
219
  }
220
  }
221
 
@@ -239,58 +251,76 @@ class SB_Instagram_Data_Manager {
239
  public function delete_caches( $include_backup = true ) {
240
  /* Backup Caches */
241
  global $wpdb;
242
- $table_name = $wpdb->prefix . "options";
243
 
244
  if ( $include_backup ) {
245
- $wpdb->query( "
 
246
  DELETE
247
  FROM $table_name
248
  WHERE `option_name` LIKE ('%!sbi\_%')
249
- " );
250
- $wpdb->query( "
 
 
251
  DELETE
252
  FROM $table_name
253
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
254
- " );
255
- $wpdb->query( "
 
 
256
  DELETE
257
  FROM $table_name
258
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
259
- " );
 
260
  }
261
 
262
  /* Regular Caches */
263
  //Delete all transients
264
- $wpdb->query( "
 
265
  DELETE
266
  FROM $table_name
267
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
268
- " );
269
- $wpdb->query( "
 
 
270
  DELETE
271
  FROM $table_name
272
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
273
- " );
274
- $wpdb->query( "
 
 
275
  DELETE
276
  FROM $table_name
277
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
278
- " );
279
- $wpdb->query( "
 
 
280
  DELETE
281
  FROM $table_name
282
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
283
- " );
284
- $wpdb->query( "
 
 
285
  DELETE
286
  FROM $table_name
287
  WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
288
- " );
289
- $wpdb->query( "
 
 
290
  DELETE
291
  FROM $table_name
292
  WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
293
- " );
 
294
 
295
  delete_option( 'sbi_single_cache' );
296
  }
@@ -305,13 +335,16 @@ class SB_Instagram_Data_Manager {
305
  public function update_db_for_dpa() {
306
  global $wpdb;
307
  $encryption = new SB_Instagram_Data_Encryption();
308
- $table_name = $wpdb->prefix . "options";
309
 
310
- $permanent_caches = $wpdb->get_results("
 
311
  SELECT *
312
- FROM $table_name
313
  WHERE option_name LIKE ('%!sbi\_%')
314
- ", ARRAY_A );
 
 
315
 
316
  if ( count( $permanent_caches ) < 10 ) {
317
  foreach ( $permanent_caches as $permanent_cache ) {
@@ -324,7 +357,7 @@ class SB_Instagram_Data_Manager {
324
 
325
  $this->delete_caches( false );
326
  } else {
327
- $this->delete_caches( true );
328
  }
329
 
330
  SB_Instagram_Connected_Account::encrypt_all_access_tokens();
@@ -351,7 +384,7 @@ class SB_Instagram_Data_Manager {
351
  $ids = get_option( 'sbi_hashtag_ids', array() );
352
  if ( ! is_array( $ids ) ) {
353
  $encryption = new SB_Instagram_Data_Encryption();
354
- $ids = json_decode( $encryption->decrypt( $ids ), true );
355
  }
356
 
357
  update_option( 'sbi_hashtag_ids', $encryption->encrypt( sbi_json_encode( $ids ) ), false );
@@ -380,7 +413,7 @@ class SB_Instagram_Data_Manager {
380
  * @since 2.9.4/5.12.4
381
  */
382
  public function update_statuses( $statuses ) {
383
- $sbi_statuses_option = get_option( 'sbi_statuses', array() );
384
  $sbi_statuses_option['data_manager'] = $statuses;
385
 
386
  update_option( 'sbi_statuses', $sbi_statuses_option );
@@ -397,13 +430,13 @@ class SB_Instagram_Data_Manager {
397
  */
398
  public function remote_encrypt( $encrypted_value ) {
399
  $local_encrypt = new SB_Instagram_Data_Encryption();
400
- $raw_value = $local_encrypt->decrypt( $encrypted_value );
401
  if ( $this->key_salt === null ) {
402
- $url = 'https://secure.smashballoon.com/';
403
  $args = array(
404
- 'timeout' => 20
405
  );
406
- if ( version_compare( get_bloginfo( 'version' ), '3.7' , '<' ) ) {
407
  $args['sslverify'] = false;
408
  }
409
  $response = wp_remote_get( $url, $args );
@@ -413,12 +446,12 @@ class SB_Instagram_Data_Manager {
413
  }
414
  }
415
 
416
- $key = substr( $this->key_salt, 0, 64 );
417
  $salt = substr( $this->key_salt, 64, 64 );
418
 
419
  $args = array(
420
- 'key' => $key,
421
- 'salt' => $salt
422
  );
423
 
424
  $remote_encrypt = new SB_Instagram_Data_Encryption( $args );
@@ -432,7 +465,7 @@ class SB_Instagram_Data_Manager {
432
  * @since 2.9.4/5.12.4
433
  */
434
  public function reset() {
435
- $sbi_statuses_option = get_option( 'sbi_statuses', array() );
436
  $sbi_statuses_option['data_manager'] = $this->defaults();
437
 
438
  update_option( 'sbi_statuses', $sbi_statuses_option );
@@ -448,8 +481,8 @@ class SB_Instagram_Data_Manager {
448
  */
449
  public function defaults() {
450
  return array(
451
- 'last_used' => sbi_get_current_time() - DAY_IN_SECONDS,
452
- 'num_db_updates' => 0
453
  );
454
  }
455
- }
80
 
81
  $data_was_deleted = false;
82
 
83
+ if ( $statuses['last_used'] < sbi_get_current_time() - ( 21 * DAY_IN_SECONDS ) ) {
84
  global $sb_instagram_posts_manager;
85
 
86
  $this->delete_caches();
92
  $data_was_deleted = true;
93
  }
94
 
95
+ if ( $statuses['last_used'] < sbi_get_current_time() - ( 90 * DAY_IN_SECONDS ) ) {
96
  SB_Instagram_Connected_Account::update_connected_accounts( array() );
97
  global $sb_instagram_posts_manager;
98
 
126
  */
127
  public function delete_non_hashtag_sbi_instagram_posts( $username ) {
128
  global $wpdb;
129
+ $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
130
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
131
 
132
  $non_hashtag_posts = $wpdb->get_results(
133
  "SELECT p.id, p.media_id FROM $table_name as p
134
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
135
+ WHERE f.hashtag = '';",
136
+ ARRAY_A
137
+ );
138
 
139
+ $upload = wp_upload_dir();
140
  $file_suffixes = array( 'thumb', 'low', 'full' );
141
 
142
  foreach ( $non_hashtag_posts as $post ) {
155
 
156
  $non_hashtag_posts_deleted = $wpdb->query(
157
  "DELETE p, f FROM $table_name as p
158
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
159
+ WHERE f.hashtag = '';",
160
+ ARRAY_A
161
+ );
162
 
163
  }
164
 
169
  */
170
  public function update_json_non_hashtag_sbi_instagram_posts() {
171
  global $wpdb;
172
+ $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
173
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
174
 
175
  $updated = $wpdb->query(
176
  "UPDATE $table_name as p
177
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
178
  SET p.json_data = ''
179
+ WHERE f.hashtag = '';"
180
+ );
181
 
182
  }
183
 
198
  $this->update_statuses( $statuses );
199
 
200
  global $wpdb;
201
+ $encryption = new SB_Instagram_Data_Encryption();
202
+ $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
203
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
204
+
205
  $plaintext_posts = $wpdb->get_results(
206
  "SELECT * FROM $table_name as p
207
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
208
  WHERE p.json_data LIKE '%{%'
209
  ORDER BY p.time_stamp DESC
210
+ LIMIT 50;",
211
+ ARRAY_A
212
+ );
213
 
214
  if ( empty( $plaintext_posts ) ) {
215
  $statuses['num_db_updates'] = 31;
218
 
219
  foreach ( $plaintext_posts as $post ) {
220
  $json_data = $encryption->encrypt( $post['json_data'] );
221
+ $updated = $wpdb->query(
222
+ $wpdb->prepare(
223
+ "UPDATE $table_name as p
224
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
225
  SET p.json_data = %s
226
+ WHERE p.id = %d;",
227
+ $json_data,
228
+ $post['id']
229
+ )
230
+ );
231
  }
232
  }
233
 
251
  public function delete_caches( $include_backup = true ) {
252
  /* Backup Caches */
253
  global $wpdb;
254
+ $table_name = $wpdb->prefix . 'options';
255
 
256
  if ( $include_backup ) {
257
+ $wpdb->query(
258
+ "
259
  DELETE
260
  FROM $table_name
261
  WHERE `option_name` LIKE ('%!sbi\_%')
262
+ "
263
+ );
264
+ $wpdb->query(
265
+ "
266
  DELETE
267
  FROM $table_name
268
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
269
+ "
270
+ );
271
+ $wpdb->query(
272
+ "
273
  DELETE
274
  FROM $table_name
275
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
276
+ "
277
+ );
278
  }
279
 
280
  /* Regular Caches */
281
  //Delete all transients
282
+ $wpdb->query(
283
+ "
284
  DELETE
285
  FROM $table_name
286
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
287
+ "
288
+ );
289
+ $wpdb->query(
290
+ "
291
  DELETE
292
  FROM $table_name
293
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
294
+ "
295
+ );
296
+ $wpdb->query(
297
+ "
298
  DELETE
299
  FROM $table_name
300
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
301
+ "
302
+ );
303
+ $wpdb->query(
304
+ "
305
  DELETE
306
  FROM $table_name
307
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
308
+ "
309
+ );
310
+ $wpdb->query(
311
+ "
312
  DELETE
313
  FROM $table_name
314
  WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
315
+ "
316
+ );
317
+ $wpdb->query(
318
+ "
319
  DELETE
320
  FROM $table_name
321
  WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
322
+ "
323
+ );
324
 
325
  delete_option( 'sbi_single_cache' );
326
  }
335
  public function update_db_for_dpa() {
336
  global $wpdb;
337
  $encryption = new SB_Instagram_Data_Encryption();
338
+ $table_name = $wpdb->prefix . 'options';
339
 
340
+ $permanent_caches = $wpdb->get_results(
341
+ "
342
  SELECT *
343
+ FROM $wpdb->options
344
  WHERE option_name LIKE ('%!sbi\_%')
345
+ ",
346
+ ARRAY_A
347
+ );
348
 
349
  if ( count( $permanent_caches ) < 10 ) {
350
  foreach ( $permanent_caches as $permanent_cache ) {
357
 
358
  $this->delete_caches( false );
359
  } else {
360
+ $this->delete_caches();
361
  }
362
 
363
  SB_Instagram_Connected_Account::encrypt_all_access_tokens();
384
  $ids = get_option( 'sbi_hashtag_ids', array() );
385
  if ( ! is_array( $ids ) ) {
386
  $encryption = new SB_Instagram_Data_Encryption();
387
+ $ids = json_decode( $encryption->decrypt( $ids ), true );
388
  }
389
 
390
  update_option( 'sbi_hashtag_ids', $encryption->encrypt( sbi_json_encode( $ids ) ), false );
413
  * @since 2.9.4/5.12.4
414
  */
415
  public function update_statuses( $statuses ) {
416
+ $sbi_statuses_option = get_option( 'sbi_statuses', array() );
417
  $sbi_statuses_option['data_manager'] = $statuses;
418
 
419
  update_option( 'sbi_statuses', $sbi_statuses_option );
430
  */
431
  public function remote_encrypt( $encrypted_value ) {
432
  $local_encrypt = new SB_Instagram_Data_Encryption();
433
+ $raw_value = $local_encrypt->decrypt( $encrypted_value );
434
  if ( $this->key_salt === null ) {
435
+ $url = 'https://secure.smashballoon.com/';
436
  $args = array(
437
+ 'timeout' => 20,
438
  );
439
+ if ( version_compare( get_bloginfo( 'version' ), '3.7', '<' ) ) {
440
  $args['sslverify'] = false;
441
  }
442
  $response = wp_remote_get( $url, $args );
446
  }
447
  }
448
 
449
+ $key = substr( $this->key_salt, 0, 64 );
450
  $salt = substr( $this->key_salt, 64, 64 );
451
 
452
  $args = array(
453
+ 'key' => $key,
454
+ 'salt' => $salt,
455
  );
456
 
457
  $remote_encrypt = new SB_Instagram_Data_Encryption( $args );
465
  * @since 2.9.4/5.12.4
466
  */
467
  public function reset() {
468
+ $sbi_statuses_option = get_option( 'sbi_statuses', array() );
469
  $sbi_statuses_option['data_manager'] = $this->defaults();
470
 
471
  update_option( 'sbi_statuses', $sbi_statuses_option );
481
  */
482
  public function defaults() {
483
  return array(
484
+ 'last_used' => sbi_get_current_time() - DAY_IN_SECONDS,
485
+ 'num_db_updates' => 0,
486
  );
487
  }
488
+ }
inc/class-sb-instagram-display-elements.php CHANGED
@@ -12,8 +12,60 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  die( '-1' );
13
  }
14
 
15
- class SB_Instagram_Display_Elements
16
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  /**
18
  * Images are hidden initially with the new/transition classes
19
  * except if the js image loading is disabled using the plugin
@@ -28,7 +80,7 @@ class SB_Instagram_Display_Elements
28
  */
29
  public static function get_item_classes( $settings, $post = false ) {
30
  $classes = '';
31
- if ( !$settings['disable_js_image_loading'] ) {
32
  $classes .= ' sbi_new sbi_transition';
33
  } else {
34
  $classes .= ' sbi_new sbi_no_js sbi_no_resraise sbi_js_load_disabled';
@@ -71,24 +123,21 @@ class SB_Instagram_Display_Elements
71
  * @since 2.0/5.0
72
  */
73
  public static function get_optimum_media_url( $post, $settings, $resized_images = array() ) {
74
- $media_url = '';
75
- $optimum_res = $settings['imageres'];
76
  $account_type = isset( $post['images'] ) ? 'personal' : 'business';
77
 
78
  // only use the placeholder if it will be replaced using JS
79
- if ( !$settings['disable_js_image_loading'] ) {
80
  return trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png';
81
  } elseif ( $settings['imageres'] === 'auto' ) {
82
- $optimum_res = 'full';
83
  $settings['imageres'] = 'full';
84
  } else {
85
  if ( ! empty( $resized_images ) ) {
86
  $resolution = $settings['imageres'];
87
- $post_id = SB_Instagram_Parse::get_post_id( $post );
88
- if ( isset( $resized_images[ $post_id ] )
89
- && $resized_images[ $post_id ]['id'] !== 'error'
90
- && $resized_images[ $post_id ]['id'] !== 'pending'
91
- && $resized_images[ $post_id ]['id'] !== 'video' ) {
92
  if ( $resolution === 'thumb' ) {
93
  if ( isset( $resized_images[ $post_id ]['sizes']['low'] ) ) {
94
  $suffix = 'low';
@@ -122,13 +171,13 @@ class SB_Instagram_Display_Elements
122
 
123
  if ( $account_type === 'personal' ) {
124
  switch ( $optimum_res ) {
125
- case 'thumb' :
126
  $media_url = $post['images']['thumbnail']['url'];
127
  break;
128
- case 'medium' :
129
  $media_url = $post['images']['low_resolution']['url'];
130
  break;
131
- default :
132
  $media_url = $post['images']['standard_resolution']['url'];
133
  }
134
  } else {
@@ -136,9 +185,9 @@ class SB_Instagram_Display_Elements
136
 
137
  // use resized images if exists
138
  if ( $optimum_res === 'full' && isset( $resized_images[ $post_id ]['id'] )
139
- && $resized_images[ $post_id ]['id'] !== 'pending'
140
- && $resized_images[ $post_id ]['id'] !== 'video'
141
- && $resized_images[ $post_id ]['id'] !== 'error' ) {
142
  $media_url = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'full.jpg';
143
  } else {
144
  if ( SB_Instagram_GDPR_Integrations::doing_gdpr( $settings ) ) {
@@ -146,14 +195,14 @@ class SB_Instagram_Display_Elements
146
  }
147
  $media_type = $post['media_type'];
148
  if ( $media_type === 'CAROUSEL_ALBUM'
149
- || $media_type === 'VIDEO'
150
- || $media_type === 'OEMBED' ) {
151
  if ( isset( $post['thumbnail_url'] ) ) {
152
  return $post['thumbnail_url'];
153
  } elseif ( $media_type === 'CAROUSEL_ALBUM' && isset( $post['media_url'] ) ) {
154
  return $post['media_url'];
155
  } elseif ( isset( $post['children'] ) ) {
156
- $i = 0;
157
  $full_size = '';
158
  foreach ( $post['children']['data'] as $carousel_item ) {
159
  if ( $carousel_item['media_type'] === 'IMAGE' && empty( $full_size ) ) {
@@ -175,7 +224,7 @@ class SB_Instagram_Display_Elements
175
  }
176
  //attempt to get
177
  $permalink = SB_Instagram_Parse::fix_permalink( SB_Instagram_Parse::get_permalink( $post ) );
178
- $single = new SB_Instagram_Single( $permalink );
179
  $single->init();
180
  $post = $single->get_post();
181
 
@@ -195,7 +244,6 @@ class SB_Instagram_Display_Elements
195
  return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png';
196
  }
197
  }
198
-
199
  }
200
 
201
  return $media_url;
@@ -216,10 +264,10 @@ class SB_Instagram_Display_Elements
216
  * @since 2.1.1/5.2.1 added support for resized images
217
  */
218
  public static function get_sbi_photo_style_element( $post, $settings, $resized_images = array() ) {
219
- if ( !$settings['disable_js_image_loading'] ) {
220
  return '';
221
  } else {
222
- $full_res_image = SB_Instagram_Display_Elements::get_optimum_media_url( $post, $settings, $resized_images );
223
  /*
224
  * By setting the height to "0" the bottom padding can be used
225
  * as a percent to square the images. Since it needs to be a percent
@@ -227,10 +275,10 @@ class SB_Instagram_Display_Elements
227
  */
228
  $padding_bottom = '100%';
229
  if ( $settings['imagepaddingunit'] === '%' ) {
230
- $padding_bottom = 100 - ($settings['imagepadding'] * 2) . '%';
231
  } else {
232
- $padding_percent = $settings['imagepadding'] > 0 ? 100 - ($settings['cols'] / 2 * $settings['imagepadding'] / 5) : 100;
233
- $padding_bottom = $padding_percent . '%';
234
  }
235
  return ' style="background-image: url(&quot;' . esc_url( $full_res_image ) . '&quot;); background-size: cover; background-position: center center; background-repeat: no-repeat; opacity: 1;height: 0;padding-bottom: ' . esc_attr( $padding_bottom ) . ';"';
236
  }
@@ -248,21 +296,21 @@ class SB_Instagram_Display_Elements
248
 
249
  $styles = '';
250
  if ( ! empty( $settings['imagepadding'] )
251
- || ! empty( $settings['background'] )
252
- || ! empty( $settings['width'] )
253
- || ! empty( $settings['height'] ) ) {
254
  $styles = ' style="';
255
  if ( ! empty( $settings['imagepadding'] ) ) {
256
- $styles .= 'padding-bottom: ' . ((int)$settings['imagepadding'] * 2) . esc_attr( $settings['imagepaddingunit'] ) . ';';
257
  }
258
  if ( ! empty( $settings['background'] ) ) {
259
- $styles .= 'background-color: rgb(' . esc_attr( sbi_hextorgb( $settings['background'] ) ). ');';
260
  }
261
  if ( ! empty( $settings['width'] ) ) {
262
- $styles .= 'width: ' . (int)$settings['width'] . esc_attr( $settings['widthunit'] ) . ';';
263
  }
264
  if ( ! empty( $settings['height'] ) ) {
265
- $styles .= 'height: ' . (int)$settings['height'] . esc_attr( $settings['heightunit'] ) . ';';
266
  }
267
  $styles .= '"';
268
  }
@@ -277,8 +325,8 @@ class SB_Instagram_Display_Elements
277
  * @return string
278
  */
279
  public static function get_sbi_images_style( $settings ) {
280
- if ( ! empty ( $settings['imagepadding'] ) ) {
281
- return 'style="padding: '.(int)$settings['imagepadding'] . esc_attr( $settings['imagepaddingunit'] ) . ';"';
282
  }
283
  return '';
284
  }
@@ -293,7 +341,7 @@ class SB_Instagram_Display_Elements
293
  */
294
  public static function get_header_text_color_styles( $settings ) {
295
  if ( ! empty( $settings['headercolor'] ) ) {
296
- return 'style="color: rgb(' . esc_attr( sbi_hextorgb( $settings['headercolor'] ) ). ');"';
297
  }
298
  return '';
299
  }
@@ -308,7 +356,7 @@ class SB_Instagram_Display_Elements
308
  * @since 2.0.1/5.0
309
  */
310
  public static function get_header_size_class( $settings ) {
311
- $header_size_class = in_array( strtolower( $settings['headersize'] ), array( 'medium', 'large' ) ) ? ' sbi_'.strtolower( $settings['headersize'] ) : '';
312
  return $header_size_class;
313
  }
314
 
@@ -328,7 +376,7 @@ class SB_Instagram_Display_Elements
328
  $styles .= 'background: rgb(' . esc_attr( sbi_hextorgb( $settings['followcolor'] ) ) . ');';
329
  }
330
  if ( ! empty( $settings['followtextcolor'] ) ) {
331
- $styles .= 'color: rgb(' . esc_attr( sbi_hextorgb( $settings['followtextcolor'] ) ). ');';
332
  }
333
  $styles .= '"';
334
  }
@@ -350,7 +398,7 @@ class SB_Instagram_Display_Elements
350
  $styles .= 'background: rgb(' . esc_attr( sbi_hextorgb( $settings['buttoncolor'] ) ) . ');';
351
  }
352
  if ( ! empty( $settings['buttontextcolor'] ) ) {
353
- $styles .= 'color: rgb(' . esc_attr( sbi_hextorgb( $settings['buttontextcolor'] ) ). ');';
354
  }
355
  $styles .= '"';
356
  }
@@ -376,7 +424,6 @@ class SB_Instagram_Display_Elements
376
  } else {
377
  return '<i class="fa fa-clone sbi_carousel_icon" aria-hidden="true"></i>';
378
  }
379
-
380
  } elseif ( $type === 'video' ) {
381
  if ( $icon_type === 'svg' ) {
382
  return '<svg style="color: rgba(255,255,255,1)" class="svg-inline--fa fa-play fa-w-14 sbi_playbtn" aria-label="Play" aria-hidden="true" data-fa-processed="" data-prefix="fa" data-icon="play" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"></path></svg>';
@@ -404,4 +451,4 @@ class SB_Instagram_Display_Elements
404
  }
405
  }
406
 
407
- }
12
  die( '-1' );
13
  }
14
 
15
+ class SB_Instagram_Display_Elements {
16
+
17
+ public static function print_style( $content ) {
18
+ if ( empty( $content ) ) {
19
+ return;
20
+ }
21
+ $strip_style_content = trim( str_replace( 'style=', '', trim( $content ) ), '"' );
22
+
23
+ echo ' style="' . esc_attr( $strip_style_content ) . '"';
24
+ }
25
+
26
+ public static function print_icon( $icon_slug ) {
27
+
28
+ if ( sbi_is_pro_version() ) {
29
+ $icon_html = SB_Instagram_Display_Elements_Pro::get_icon( $icon_slug, 'svg' );
30
+ } else {
31
+ $icon_html = SB_Instagram_Display_Elements::get_icon( $icon_slug, 'svg' );
32
+ }
33
+
34
+ $allowed = array(
35
+ 'svg' => array(
36
+ 'id' => array(),
37
+ 'class' => array(),
38
+ 'aria-hidden' => array(),
39
+ 'data-fa-processed' => array(),
40
+ 'aria-label' => array(),
41
+ 'data-prefix' => array(),
42
+ 'data-icon' => array(),
43
+ 'role' => array(),
44
+ 'viewBox' => array(),
45
+ 'style' => array(),
46
+ ),
47
+ 'path' => array(
48
+ 'id' => array(),
49
+ 'class' => array(),
50
+ 'fill' => array(),
51
+ 'd' => array(),
52
+ 'style' => array(),
53
+ ),
54
+ 'g' => array(
55
+ 'id' => array(),
56
+ 'class' => array(),
57
+ 'g' => array(),
58
+ ),
59
+ 'title' => array(
60
+ 'id' => array(),
61
+ 'class' => array(),
62
+ 'title' => array(),
63
+ ),
64
+ );
65
+
66
+ echo wp_kses( $icon_html, $allowed );
67
+ }
68
+
69
  /**
70
  * Images are hidden initially with the new/transition classes
71
  * except if the js image loading is disabled using the plugin
80
  */
81
  public static function get_item_classes( $settings, $post = false ) {
82
  $classes = '';
83
+ if ( ! $settings['disable_js_image_loading'] ) {
84
  $classes .= ' sbi_new sbi_transition';
85
  } else {
86
  $classes .= ' sbi_new sbi_no_js sbi_no_resraise sbi_js_load_disabled';
123
  * @since 2.0/5.0
124
  */
125
  public static function get_optimum_media_url( $post, $settings, $resized_images = array() ) {
126
+ $media_url = '';
127
+ $optimum_res = $settings['imageres'];
128
  $account_type = isset( $post['images'] ) ? 'personal' : 'business';
129
 
130
  // only use the placeholder if it will be replaced using JS
131
+ if ( ! $settings['disable_js_image_loading'] ) {
132
  return trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png';
133
  } elseif ( $settings['imageres'] === 'auto' ) {
134
+ $optimum_res = 'full';
135
  $settings['imageres'] = 'full';
136
  } else {
137
  if ( ! empty( $resized_images ) ) {
138
  $resolution = $settings['imageres'];
139
+ $post_id = SB_Instagram_Parse::get_post_id( $post );
140
+ if ( isset( $resized_images[ $post_id ] ) && $resized_images[ $post_id ]['id'] !== 'error' && $resized_images[ $post_id ]['id'] !== 'pending' && $resized_images[ $post_id ]['id'] !== 'video' ) {
 
 
 
141
  if ( $resolution === 'thumb' ) {
142
  if ( isset( $resized_images[ $post_id ]['sizes']['low'] ) ) {
143
  $suffix = 'low';
171
 
172
  if ( $account_type === 'personal' ) {
173
  switch ( $optimum_res ) {
174
+ case 'thumb':
175
  $media_url = $post['images']['thumbnail']['url'];
176
  break;
177
+ case 'medium':
178
  $media_url = $post['images']['low_resolution']['url'];
179
  break;
180
+ default:
181
  $media_url = $post['images']['standard_resolution']['url'];
182
  }
183
  } else {
185
 
186
  // use resized images if exists
187
  if ( $optimum_res === 'full' && isset( $resized_images[ $post_id ]['id'] )
188
+ && $resized_images[ $post_id ]['id'] !== 'pending'
189
+ && $resized_images[ $post_id ]['id'] !== 'video'
190
+ && $resized_images[ $post_id ]['id'] !== 'error' ) {
191
  $media_url = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'full.jpg';
192
  } else {
193
  if ( SB_Instagram_GDPR_Integrations::doing_gdpr( $settings ) ) {
195
  }
196
  $media_type = $post['media_type'];
197
  if ( $media_type === 'CAROUSEL_ALBUM'
198
+ || $media_type === 'VIDEO'
199
+ || $media_type === 'OEMBED' ) {
200
  if ( isset( $post['thumbnail_url'] ) ) {
201
  return $post['thumbnail_url'];
202
  } elseif ( $media_type === 'CAROUSEL_ALBUM' && isset( $post['media_url'] ) ) {
203
  return $post['media_url'];
204
  } elseif ( isset( $post['children'] ) ) {
205
+ $i = 0;
206
  $full_size = '';
207
  foreach ( $post['children']['data'] as $carousel_item ) {
208
  if ( $carousel_item['media_type'] === 'IMAGE' && empty( $full_size ) ) {
224
  }
225
  //attempt to get
226
  $permalink = SB_Instagram_Parse::fix_permalink( SB_Instagram_Parse::get_permalink( $post ) );
227
+ $single = new SB_Instagram_Single( $permalink );
228
  $single->init();
229
  $post = $single->get_post();
230
 
244
  return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png';
245
  }
246
  }
 
247
  }
248
 
249
  return $media_url;
264
  * @since 2.1.1/5.2.1 added support for resized images
265
  */
266
  public static function get_sbi_photo_style_element( $post, $settings, $resized_images = array() ) {
267
+ if ( ! $settings['disable_js_image_loading'] ) {
268
  return '';
269
  } else {
270
+ $full_res_image = self::get_optimum_media_url( $post, $settings, $resized_images );
271
  /*
272
  * By setting the height to "0" the bottom padding can be used
273
  * as a percent to square the images. Since it needs to be a percent
275
  */
276
  $padding_bottom = '100%';
277
  if ( $settings['imagepaddingunit'] === '%' ) {
278
+ $padding_bottom = 100 - ( $settings['imagepadding'] * 2 ) . '%';
279
  } else {
280
+ $padding_percent = $settings['imagepadding'] > 0 ? 100 - ( $settings['cols'] / 2 * $settings['imagepadding'] / 5 ) : 100;
281
+ $padding_bottom = $padding_percent . '%';
282
  }
283
  return ' style="background-image: url(&quot;' . esc_url( $full_res_image ) . '&quot;); background-size: cover; background-position: center center; background-repeat: no-repeat; opacity: 1;height: 0;padding-bottom: ' . esc_attr( $padding_bottom ) . ';"';
284
  }
296
 
297
  $styles = '';
298
  if ( ! empty( $settings['imagepadding'] )
299
+ || ! empty( $settings['background'] )
300
+ || ! empty( $settings['width'] )
301
+ || ! empty( $settings['height'] ) ) {
302
  $styles = ' style="';
303
  if ( ! empty( $settings['imagepadding'] ) ) {
304
+ $styles .= 'padding-bottom: ' . ( (int) $settings['imagepadding'] * 2 ) . esc_attr( $settings['imagepaddingunit'] ) . ';';
305
  }
306
  if ( ! empty( $settings['background'] ) ) {
307
+ $styles .= 'background-color: rgb(' . esc_attr( sbi_hextorgb( $settings['background'] ) ) . ');';
308
  }
309
  if ( ! empty( $settings['width'] ) ) {
310
+ $styles .= 'width: ' . (int) $settings['width'] . esc_attr( $settings['widthunit'] ) . ';';
311
  }
312
  if ( ! empty( $settings['height'] ) ) {
313
+ $styles .= 'height: ' . (int) $settings['height'] . esc_attr( $settings['heightunit'] ) . ';';
314
  }
315
  $styles .= '"';
316
  }
325
  * @return string
326
  */
327
  public static function get_sbi_images_style( $settings ) {
328
+ if ( ! empty( $settings['imagepadding'] ) ) {
329
+ return 'style="padding: ' . (int) $settings['imagepadding'] . esc_attr( $settings['imagepaddingunit'] ) . ';"';
330
  }
331
  return '';
332
  }
341
  */
342
  public static function get_header_text_color_styles( $settings ) {
343
  if ( ! empty( $settings['headercolor'] ) ) {
344
+ return 'style="color: rgb(' . esc_attr( sbi_hextorgb( $settings['headercolor'] ) ) . ');"';
345
  }
346
  return '';
347
  }
356
  * @since 2.0.1/5.0
357
  */
358
  public static function get_header_size_class( $settings ) {
359
+ $header_size_class = in_array( strtolower( $settings['headersize'] ), array( 'medium', 'large' ), true ) ? ' sbi_' . strtolower( $settings['headersize'] ) : '';
360
  return $header_size_class;
361
  }
362
 
376
  $styles .= 'background: rgb(' . esc_attr( sbi_hextorgb( $settings['followcolor'] ) ) . ');';
377
  }
378
  if ( ! empty( $settings['followtextcolor'] ) ) {
379
+ $styles .= 'color: rgb(' . esc_attr( sbi_hextorgb( $settings['followtextcolor'] ) ) . ');';
380
  }
381
  $styles .= '"';
382
  }
398
  $styles .= 'background: rgb(' . esc_attr( sbi_hextorgb( $settings['buttoncolor'] ) ) . ');';
399
  }
400
  if ( ! empty( $settings['buttontextcolor'] ) ) {
401
+ $styles .= 'color: rgb(' . esc_attr( sbi_hextorgb( $settings['buttontextcolor'] ) ) . ');';
402
  }
403
  $styles .= '"';
404
  }
424
  } else {
425
  return '<i class="fa fa-clone sbi_carousel_icon" aria-hidden="true"></i>';
426
  }
 
427
  } elseif ( $type === 'video' ) {
428
  if ( $icon_type === 'svg' ) {
429
  return '<svg style="color: rgba(255,255,255,1)" class="svg-inline--fa fa-play fa-w-14 sbi_playbtn" aria-label="Play" aria-hidden="true" data-fa-processed="" data-prefix="fa" data-icon="play" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"></path></svg>';
451
  }
452
  }
453
 
454
+ }
inc/class-sb-instagram-education.php CHANGED
@@ -6,7 +6,10 @@
6
  */
7
  class SB_Instagram_Education {
8
 
9
- var $plugin_version;
 
 
 
10
 
11
  /**
12
  * Constructor.
@@ -36,49 +39,49 @@ class SB_Instagram_Education {
36
 
37
  $free_messages = array(
38
  array(
39
- 'title' => esc_html__( 'Get the Most out of Hashtags', 'instagram-feed' ),
40
  'content' => esc_html__( 'You can use hashtags on Instagram for so many things; targeted promotions, engaging with your audience, running contests, or just for categorizing posts. Learn more about how you can display Instagram hashtag feeds on your website using the Instagram Feed Pro plugin.', 'instagram-feed' ),
41
- 'more' => 'https://smashballoon.com/instagram-feed/features/#hashtag',
42
- 'item' => 1,
43
  ),
44
  array(
45
- 'title' => esc_html__( 'Keep Visitors on Your Site', 'instagram-feed' ),
46
  'content' => esc_html__( "You've done the hard work of getting a visitor onto your site, now keep them there by displaying your Instagram content inside a pop-up lightbox, rather than sending your visitors away to Instagram. Learn more about the Instagram Feed Pro lightbox feature.", 'instagram-feed' ),
47
- 'more' => 'https://smashballoon.com/instagram-feed/features/#popuplightbox',
48
- 'item' => 2,
49
  ),
50
  array(
51
- 'title' => esc_html__( 'Highlight Your Posts and Create Carousels', 'instagram-feed' ),
52
- 'content' => esc_html__( "Feature specific Instagram posts in your feeds by using the Highlight layout to feature specific posts, either by using their ID or a hashtag in their caption. Also create rotating carousels of your photos and videos to best utilize the space on your site. These layouts and more are available in our Pro version.", 'instagram-feed' ),
53
- 'more' => 'https://smashballoon.com/instagram-feed/features/#highlight',
54
- 'item' => 3,
55
  ),
56
  array(
57
- 'title' => esc_html__( 'Moderate your Feed Content', 'instagram-feed' ),
58
- 'content' => esc_html__( "Control exactly which posts show up in your feed by using the Visual Moderation Mode feature to pick and choose what to display. Remove specific posts or create a whitelist of approved content using Instagram Feed Pro.", 'instagram-feed' ),
59
- 'more' => 'https://smashballoon.com/instagram-feed/features/#moderation',
60
- 'item' => 4,
61
  ),
62
  );
63
 
64
  $pro_messages = array(
65
  array(
66
- 'title' => esc_html__( 'Automated YouTube Live Streaming', 'instagram-feed' ),
67
  'content' => esc_html__( 'You can automatically feed live YouTube videos to your website using our Feeds For YouTube Pro plugin. It takes all the hassle out of publishing live videos to your site by automating the process.', 'instagram-feed' ),
68
- 'more' => 'https://smashballoon.com/youtube-feed/',
69
- 'item' => 1,
70
  ),
71
  array(
72
- 'title' => esc_html__( 'Display Facebook Pages and Groups', 'instagram-feed' ),
73
  'content' => esc_html__( 'Have a Facebook Page or Group? Easily embed a feed of posts into your website, delivering fresh content automatically to your site from Facebook. Posts, Photos, Events, Videos, Albums, Reviews, and more!', 'instagram-feed' ),
74
- 'more' => 'https://smashballoon.com/custom-facebook-feed/',
75
- 'item' => 2,
76
  ),
77
  array(
78
- 'title' => esc_html__( 'Adding Social Proof with Twitter Feeds', 'instagram-feed' ),
79
  'content' => esc_html__( 'Twitter testimonials are one of the best ways to add verifiable social proof to your website. They add credibility to your brand, product, or service by displaying reviews from real people to your site, helping to convert more visitors into customers. Our free Custom Twitter Feeds plugin makes displaying Tweets on your website a breeze.', 'instagram-feed' ),
80
- 'more' => 'https://wordpress.org/plugins/custom-twitter-feeds/',
81
- 'item' => 3,
82
  ),
83
  );
84
 
@@ -111,15 +114,15 @@ class SB_Instagram_Education {
111
  */
112
  public function dyk_display() {
113
 
114
- $dyk_message = $this->dyk_message_rnd();
115
 
116
  if ( ! empty( $dyk_message['more'] ) ) {
117
  //utm_source=plugin-pro&utm_campaign=
118
  $dyk_message['more'] = add_query_arg(
119
  array(
120
  'utm_source' => 'issueemail',
121
- 'utm_campaign' => 'instagram-'.$this->plugin_version,
122
- 'utm_medium' => $dyk_message['item'],
123
  ),
124
  $dyk_message['more']
125
  );
6
  */
7
  class SB_Instagram_Education {
8
 
9
+ /**
10
+ * @var string
11
+ */
12
+ public $plugin_version;
13
 
14
  /**
15
  * Constructor.
39
 
40
  $free_messages = array(
41
  array(
42
+ 'title' => esc_html__( 'Get the Most out of Hashtags', 'instagram-feed' ),
43
  'content' => esc_html__( 'You can use hashtags on Instagram for so many things; targeted promotions, engaging with your audience, running contests, or just for categorizing posts. Learn more about how you can display Instagram hashtag feeds on your website using the Instagram Feed Pro plugin.', 'instagram-feed' ),
44
+ 'more' => 'https://smashballoon.com/instagram-feed/features/#hashtag',
45
+ 'item' => 1,
46
  ),
47
  array(
48
+ 'title' => esc_html__( 'Keep Visitors on Your Site', 'instagram-feed' ),
49
  'content' => esc_html__( "You've done the hard work of getting a visitor onto your site, now keep them there by displaying your Instagram content inside a pop-up lightbox, rather than sending your visitors away to Instagram. Learn more about the Instagram Feed Pro lightbox feature.", 'instagram-feed' ),
50
+ 'more' => 'https://smashballoon.com/instagram-feed/features/#popuplightbox',
51
+ 'item' => 2,
52
  ),
53
  array(
54
+ 'title' => esc_html__( 'Highlight Your Posts and Create Carousels', 'instagram-feed' ),
55
+ 'content' => esc_html__( 'Feature specific Instagram posts in your feeds by using the Highlight layout to feature specific posts, either by using their ID or a hashtag in their caption. Also create rotating carousels of your photos and videos to best utilize the space on your site. These layouts and more are available in our Pro version.', 'instagram-feed' ),
56
+ 'more' => 'https://smashballoon.com/instagram-feed/features/#highlight',
57
+ 'item' => 3,
58
  ),
59
  array(
60
+ 'title' => esc_html__( 'Moderate your Feed Content', 'instagram-feed' ),
61
+ 'content' => esc_html__( 'Control exactly which posts show up in your feed by using the Visual Moderation Mode feature to pick and choose what to display. Remove specific posts or create a whitelist of approved content using Instagram Feed Pro.', 'instagram-feed' ),
62
+ 'more' => 'https://smashballoon.com/instagram-feed/features/#moderation',
63
+ 'item' => 4,
64
  ),
65
  );
66
 
67
  $pro_messages = array(
68
  array(
69
+ 'title' => esc_html__( 'Automated YouTube Live Streaming', 'instagram-feed' ),
70
  'content' => esc_html__( 'You can automatically feed live YouTube videos to your website using our Feeds For YouTube Pro plugin. It takes all the hassle out of publishing live videos to your site by automating the process.', 'instagram-feed' ),
71
+ 'more' => 'https://smashballoon.com/youtube-feed/',
72
+ 'item' => 1,
73
  ),
74
  array(
75
+ 'title' => esc_html__( 'Display Facebook Pages and Groups', 'instagram-feed' ),
76
  'content' => esc_html__( 'Have a Facebook Page or Group? Easily embed a feed of posts into your website, delivering fresh content automatically to your site from Facebook. Posts, Photos, Events, Videos, Albums, Reviews, and more!', 'instagram-feed' ),
77
+ 'more' => 'https://smashballoon.com/custom-facebook-feed/',
78
+ 'item' => 2,
79
  ),
80
  array(
81
+ 'title' => esc_html__( 'Adding Social Proof with Twitter Feeds', 'instagram-feed' ),
82
  'content' => esc_html__( 'Twitter testimonials are one of the best ways to add verifiable social proof to your website. They add credibility to your brand, product, or service by displaying reviews from real people to your site, helping to convert more visitors into customers. Our free Custom Twitter Feeds plugin makes displaying Tweets on your website a breeze.', 'instagram-feed' ),
83
+ 'more' => 'https://wordpress.org/plugins/custom-twitter-feeds/',
84
+ 'item' => 3,
85
  ),
86
  );
87
 
114
  */
115
  public function dyk_display() {
116
 
117
+ $dyk_message = $this->dyk_message_rnd();
118
 
119
  if ( ! empty( $dyk_message['more'] ) ) {
120
  //utm_source=plugin-pro&utm_campaign=
121
  $dyk_message['more'] = add_query_arg(
122
  array(
123
  'utm_source' => 'issueemail',
124
+ 'utm_campaign' => 'instagram-' . $this->plugin_version,
125
+ 'utm_medium' => $dyk_message['item'],
126
  ),
127
  $dyk_message['more']
128
  );
inc/class-sb-instagram-feed-locator.php CHANGED
@@ -11,12 +11,16 @@ if ( ! defined( 'ABSPATH' ) ) {
11
  die( '-1' );
12
  }
13
 
14
- class SB_Instagram_Feed_Locator
15
- {
16
- private $feed_details;
17
 
18
- private $expiration_time;
 
 
 
19
 
 
 
 
20
  private $matching_entries;
21
 
22
  public function __construct( $feed_details ) {
@@ -35,8 +39,6 @@ class SB_Instagram_Feed_Locator
35
  $this->feed_details = $feed_details;
36
 
37
  $this->matching_entries = array();
38
-
39
- $this->expiration_time = time() - 2 * WEEK_IN_SECONDS;
40
  }
41
 
42
  /**
@@ -51,11 +53,18 @@ class SB_Instagram_Feed_Locator
51
  global $wpdb;
52
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
53
 
54
- $results = $wpdb->get_results( $wpdb->prepare("
 
 
55
  SELECT *
56
  FROM $feed_locator_table_name
57
  WHERE post_id = %d
58
- AND feed_id = %s", $this->feed_details['location']['post_id'], $this->feed_details['feed_id'] ),ARRAY_A );
 
 
 
 
 
59
 
60
  return $results;
61
  }
@@ -69,44 +78,57 @@ class SB_Instagram_Feed_Locator
69
  global $wpdb;
70
 
71
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
72
- $two_minutes_ago = date( 'Y-m-d H:i:s', time() - 120 );
73
 
74
- $results_recent_entries = $wpdb->get_results( $wpdb->prepare("
 
 
75
  SELECT COUNT(*) AS num_entries
76
- FROM $feed_locator_table_name
77
  WHERE last_update > %s;
78
- ", $two_minutes_ago ), ARRAY_A );
 
 
 
 
79
 
80
  // Only allow 5 new entries within 5 minutes
81
- if ( isset( $results_recent_entries[0]['num_entries'] ) && (int)$results_recent_entries[0]['num_entries'] > 5 ) {
82
  return;
83
  }
84
 
85
  // Only allow 1000 total entries
86
- $results_total_entries = $wpdb->get_results( "
 
87
  SELECT COUNT(*) AS num_entries
88
- FROM $feed_locator_table_name", ARRAY_A );
89
- if ( isset( $results_total_entries[0]['num_entries'] ) && (int)$results_total_entries[0]['num_entries'] > 1000 ) {
 
 
90
  $this->delete_oldest_entry();
91
  }
92
 
93
- $affected = $wpdb->query( $wpdb->prepare( "INSERT INTO $feed_locator_table_name
 
 
94
  (feed_id,
95
  post_id,
96
  html_location,
97
  shortcode_atts,
98
- last_update)
99
  VALUES (
100
  %s,
101
  %d,
102
  %s,
103
  %s,
104
  %s);",
105
- $this->feed_details['feed_id'],
106
- $this->feed_details['location']['post_id'],
107
- $this->feed_details['location']['html'],
108
- sbi_json_encode( $this->feed_details['atts'] ),
109
- date( 'Y-m-d H:i:s' ) ) );
 
 
110
  }
111
 
112
  public function delete_oldest_entry() {
@@ -115,9 +137,10 @@ class SB_Instagram_Feed_Locator
115
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
116
 
117
  $affected = $wpdb->query(
118
- "DELETE FROM $feed_locator_table_name
119
- ORDER BY last_update ASC
120
- LIMIT 1;" );
 
121
 
122
  }
123
 
@@ -135,10 +158,17 @@ class SB_Instagram_Feed_Locator
135
 
136
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
137
 
138
- $query = $wpdb->query( $wpdb->prepare( "
 
 
139
  UPDATE $feed_locator_table_name
140
  SET last_update = %s, html_location = %s
141
- WHERE id = %d;", date( 'Y-m-d H:i:s' ), $location, $id ) );
 
 
 
 
 
142
  }
143
 
144
  /**
@@ -158,13 +188,13 @@ class SB_Instagram_Feed_Locator
158
  if ( empty( $this->matching_entries ) ) {
159
  $this->insert_entry();
160
  } else {
161
- $matching_indices = array();
162
- $matched_location = false;
163
  $non_unknown_match = false;
164
- $unknown_match = false;
165
 
166
  foreach ( $this->matching_entries as $index => $matching_entry ) {
167
- $details_atts = is_array( $this->feed_details['atts'] ) ? $this->feed_details['atts'] : array();
168
  $matching_atts = json_decode( $matching_entry['shortcode_atts'], true );
169
  if ( ! is_array( $matching_atts ) ) {
170
  $matching_atts = array();
@@ -187,20 +217,18 @@ class SB_Instagram_Feed_Locator
187
  if ( false === $matched_location ) {
188
  // if there is no matched location, there is only one feed on the page, and the feed being checked has an unknown location, update the known location
189
  if ( count( $matching_indices ) === 1
190
- && $this->feed_details['location']['html'] === 'unknown'
191
- && false !== $non_unknown_match ) {
192
  $this->update_entry( $this->matching_entries[ $non_unknown_match ]['id'], $this->matching_entries[ $non_unknown_match ]['html_location'] );
193
  } else {
194
  if ( $this->feed_details['location']['html'] !== 'unknown'
195
- && false !== $unknown_match ) {
196
  $this->update_entry( $this->matching_entries[ $unknown_match ]['id'], $this->feed_details['location']['html'] );
197
  } else {
198
  $this->insert_entry();
199
  }
200
-
201
  }
202
  }
203
-
204
  }
205
  }
206
 
@@ -227,12 +255,16 @@ class SB_Instagram_Feed_Locator
227
  global $wpdb;
228
 
229
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
230
- $two_weeks_ago = date( 'Y-m-d H:i:s', time() - 2 * WEEK_IN_SECONDS );
231
 
232
- $affected = $wpdb->query( $wpdb->prepare(
233
- "DELETE FROM $feed_locator_table_name WHERE last_update < %s;", $two_weeks_ago ) );
 
 
 
 
234
 
235
- $sbi_statuses_option = get_option( 'sbi_statuses', array() );
236
  $sbi_statuses_option['feed_locator']['last_check'] = time();
237
  if ( ! isset( $sbi_statuses_option['feed_locator']['initialized'] ) ) {
238
  $sbi_statuses_option['feed_locator']['initialized'] = time();
@@ -255,7 +287,7 @@ class SB_Instagram_Feed_Locator
255
  public static function should_do_locating() {
256
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
257
  if ( isset( $sbi_statuses_option['feed_locator']['initialized'] )
258
- && $sbi_statuses_option['feed_locator']['initialized'] < (time() - 300) ) {
259
  $should_do_locating = rand( 1, 10 ) === 10;
260
  } else {
261
  $should_do_locating = rand( 1, 30 ) === 30;
@@ -280,13 +312,13 @@ class SB_Instagram_Feed_Locator
280
  public static function should_do_ajax_locating( $feed_id, $post_id ) {
281
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
282
  if ( isset( $sbi_statuses_option['feed_locator']['initialized'] )
283
- && $sbi_statuses_option['feed_locator']['initialized'] < (time() - 300) ) {
284
  $should_do_locating = rand( 1, 10 ) === 10;
285
  } else {
286
  $should_do_locating = rand( 1, 30 ) === 30;
287
  }
288
  if ( $should_do_locating ) {
289
- $should_do_locating = SB_Instagram_Feed_Locator::entries_need_locating( $feed_id, $post_id );
290
  }
291
 
292
  $should_do_locating = apply_filters( 'sbi_should_do_ajax_locating', $should_do_locating );
@@ -314,14 +346,22 @@ class SB_Instagram_Feed_Locator
314
 
315
  $one_day_ago = date( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS );
316
 
317
- $results = $wpdb->get_results( $wpdb->prepare("
 
 
318
  SELECT id
319
  FROM $feed_locator_table_name
320
  WHERE html_location = 'unknown'
321
  AND last_update < %s
322
  AND feed_id = %s
323
  AND post_id = %d
324
- LIMIT 1;", $one_day_ago, $feed_id, $post_id ),ARRAY_A );
 
 
 
 
 
 
325
 
326
  return isset( $results[0] );
327
  }
@@ -337,8 +377,8 @@ class SB_Instagram_Feed_Locator
337
 
338
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
339
 
340
- if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) != $feed_locator_table_name ) {
341
- $sql = "CREATE TABLE " . $feed_locator_table_name . " (
342
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
343
  feed_id VARCHAR(50) DEFAULT '' NOT NULL,
344
  post_id BIGINT(20) UNSIGNED NOT NULL,
@@ -348,12 +388,12 @@ class SB_Instagram_Feed_Locator
348
  );";
349
  $wpdb->query( $sql );
350
  }
351
- $error = $wpdb->last_error;
352
- $query = $wpdb->last_query;
353
  $had_error = false;
354
- if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) != $feed_locator_table_name ) {
355
  $had_error = true;
356
- $sb_instagram_posts_manager->add_error( 'database_create', '<strong>' . __( 'There was an error when trying to create the database tables used to locate feeds.', 'instagram-feed' ) .'</strong><br>' . $error . '<br><code>' . $query . '</code>' );
357
  }
358
 
359
  if ( ! $had_error ) {
@@ -375,26 +415,32 @@ class SB_Instagram_Feed_Locator
375
  global $wpdb;
376
 
377
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
378
- $results_content = $wpdb->get_results( "
 
379
  SELECT COUNT(*) AS num_entries
380
- FROM $feed_locator_table_name
381
  WHERE html_location = 'content'
382
- ", ARRAY_A );
 
 
383
 
384
- $results_other = $wpdb->get_results( "
 
385
  SELECT COUNT(*) AS num_entries
386
- FROM $feed_locator_table_name
387
  WHERE html_location != 'content'
388
  AND html_location != 'unknown'
389
  GROUP BY feed_id
390
- ", ARRAY_A );
 
 
391
 
392
  $total = 0;
393
  if ( isset( $results_content[0]['num_entries'] ) ) {
394
- $total += (int)$results_content[0]['num_entries'];
395
  }
396
  if ( isset( $results_other[0]['num_entries'] ) ) {
397
- $total += (int)$results_other[0]['num_entries'];
398
  }
399
 
400
  return $total;
@@ -414,37 +460,40 @@ class SB_Instagram_Feed_Locator
414
 
415
  $locations = array(
416
  array(
417
- 'label' => __( 'Content', 'instagram-feed' ),
418
- 'html_locations' => array( 'content', 'unknown' )
419
  ),
420
  array(
421
- 'label' => __( 'Header', 'instagram-feed' ),
422
  'html_locations' => array( 'header' ),
423
- 'group_by' => 'feed_id'
424
  ),
425
  array(
426
- 'label' => __( 'Sidebar', 'instagram-feed' ),
427
  'html_locations' => array( 'sidebar' ),
428
- 'group_by' => 'feed_id'
429
  ),
430
  array(
431
- 'label' => __( 'Footer', 'instagram-feed' ),
432
  'html_locations' => array( 'footer' ),
433
- 'group_by' => 'feed_id'
434
- )
435
  );
436
 
437
  $one_result_found = false;
438
 
439
  foreach ( $locations as $key => $location ) {
440
- $in = implode( "', '", $location['html_locations'] );
441
- $group_by = isset( $location['group_by'] ) ? "GROUP BY " . $location['group_by'] : "";
442
- $results = $wpdb->get_results("
 
443
  SELECT *
444
  FROM $feed_locator_table_name
445
  WHERE html_location IN ('$in')
446
  $group_by
447
- ORDER BY last_update ASC",ARRAY_A );
 
 
448
 
449
  if ( isset( $results[0] ) ) {
450
  $one_result_found = true;
@@ -459,4 +508,4 @@ class SB_Instagram_Feed_Locator
459
 
460
  return $locations;
461
  }
462
- }
11
  die( '-1' );
12
  }
13
 
14
+ class SB_Instagram_Feed_Locator {
 
 
15
 
16
+ /**
17
+ * @var array
18
+ */
19
+ private $feed_details;
20
 
21
+ /**
22
+ * @var array
23
+ */
24
  private $matching_entries;
25
 
26
  public function __construct( $feed_details ) {
39
  $this->feed_details = $feed_details;
40
 
41
  $this->matching_entries = array();
 
 
42
  }
43
 
44
  /**
53
  global $wpdb;
54
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
55
 
56
+ $results = $wpdb->get_results(
57
+ $wpdb->prepare(
58
+ "
59
  SELECT *
60
  FROM $feed_locator_table_name
61
  WHERE post_id = %d
62
+ AND feed_id = %s",
63
+ $this->feed_details['location']['post_id'],
64
+ $this->feed_details['feed_id']
65
+ ),
66
+ ARRAY_A
67
+ );
68
 
69
  return $results;
70
  }
78
  global $wpdb;
79
 
80
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
81
+ $two_minutes_ago = date( 'Y-m-d H:i:s', time() - 120 );
82
 
83
+ $results_recent_entries = $wpdb->get_results(
84
+ $wpdb->prepare(
85
+ "
86
  SELECT COUNT(*) AS num_entries
87
+ FROM $feed_locator_table_name
88
  WHERE last_update > %s;
89
+ ",
90
+ $two_minutes_ago
91
+ ),
92
+ ARRAY_A
93
+ );
94
 
95
  // Only allow 5 new entries within 5 minutes
96
+ if ( isset( $results_recent_entries[0]['num_entries'] ) && (int) $results_recent_entries[0]['num_entries'] > 5 ) {
97
  return;
98
  }
99
 
100
  // Only allow 1000 total entries
101
+ $results_total_entries = $wpdb->get_results(
102
+ "
103
  SELECT COUNT(*) AS num_entries
104
+ FROM $feed_locator_table_name",
105
+ ARRAY_A
106
+ );
107
+ if ( isset( $results_total_entries[0]['num_entries'] ) && (int) $results_total_entries[0]['num_entries'] > 1000 ) {
108
  $this->delete_oldest_entry();
109
  }
110
 
111
+ $affected = $wpdb->query(
112
+ $wpdb->prepare(
113
+ "INSERT INTO $feed_locator_table_name
114
  (feed_id,
115
  post_id,
116
  html_location,
117
  shortcode_atts,
118
+ last_update)
119
  VALUES (
120
  %s,
121
  %d,
122
  %s,
123
  %s,
124
  %s);",
125
+ $this->feed_details['feed_id'],
126
+ $this->feed_details['location']['post_id'],
127
+ $this->feed_details['location']['html'],
128
+ sbi_json_encode( $this->feed_details['atts'] ),
129
+ date( 'Y-m-d H:i:s' )
130
+ )
131
+ );
132
  }
133
 
134
  public function delete_oldest_entry() {
137
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
138
 
139
  $affected = $wpdb->query(
140
+ "DELETE FROM $feed_locator_table_name
141
+ ORDER BY last_update ASC
142
+ LIMIT 1;"
143
+ );
144
 
145
  }
146
 
158
 
159
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
160
 
161
+ $query = $wpdb->query(
162
+ $wpdb->prepare(
163
+ "
164
  UPDATE $feed_locator_table_name
165
  SET last_update = %s, html_location = %s
166
+ WHERE id = %d;",
167
+ date( 'Y-m-d H:i:s' ),
168
+ $location,
169
+ $id
170
+ )
171
+ );
172
  }
173
 
174
  /**
188
  if ( empty( $this->matching_entries ) ) {
189
  $this->insert_entry();
190
  } else {
191
+ $matching_indices = array();
192
+ $matched_location = false;
193
  $non_unknown_match = false;
194
+ $unknown_match = false;
195
 
196
  foreach ( $this->matching_entries as $index => $matching_entry ) {
197
+ $details_atts = is_array( $this->feed_details['atts'] ) ? $this->feed_details['atts'] : array();
198
  $matching_atts = json_decode( $matching_entry['shortcode_atts'], true );
199
  if ( ! is_array( $matching_atts ) ) {
200
  $matching_atts = array();
217
  if ( false === $matched_location ) {
218
  // if there is no matched location, there is only one feed on the page, and the feed being checked has an unknown location, update the known location
219
  if ( count( $matching_indices ) === 1
220
+ && $this->feed_details['location']['html'] === 'unknown'
221
+ && false !== $non_unknown_match ) {
222
  $this->update_entry( $this->matching_entries[ $non_unknown_match ]['id'], $this->matching_entries[ $non_unknown_match ]['html_location'] );
223
  } else {
224
  if ( $this->feed_details['location']['html'] !== 'unknown'
225
+ && false !== $unknown_match ) {
226
  $this->update_entry( $this->matching_entries[ $unknown_match ]['id'], $this->feed_details['location']['html'] );
227
  } else {
228
  $this->insert_entry();
229
  }
 
230
  }
231
  }
 
232
  }
233
  }
234
 
255
  global $wpdb;
256
 
257
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
258
+ $two_weeks_ago = date( 'Y-m-d H:i:s', time() - 2 * WEEK_IN_SECONDS );
259
 
260
+ $affected = $wpdb->query(
261
+ $wpdb->prepare(
262
+ "DELETE FROM $feed_locator_table_name WHERE last_update < %s;",
263
+ $two_weeks_ago
264
+ )
265
+ );
266
 
267
+ $sbi_statuses_option = get_option( 'sbi_statuses', array() );
268
  $sbi_statuses_option['feed_locator']['last_check'] = time();
269
  if ( ! isset( $sbi_statuses_option['feed_locator']['initialized'] ) ) {
270
  $sbi_statuses_option['feed_locator']['initialized'] = time();
287
  public static function should_do_locating() {
288
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
289
  if ( isset( $sbi_statuses_option['feed_locator']['initialized'] )
290
+ && $sbi_statuses_option['feed_locator']['initialized'] < ( time() - 300 ) ) {
291
  $should_do_locating = rand( 1, 10 ) === 10;
292
  } else {
293
  $should_do_locating = rand( 1, 30 ) === 30;
312
  public static function should_do_ajax_locating( $feed_id, $post_id ) {
313
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
314
  if ( isset( $sbi_statuses_option['feed_locator']['initialized'] )
315
+ && $sbi_statuses_option['feed_locator']['initialized'] < ( time() - 300 ) ) {
316
  $should_do_locating = rand( 1, 10 ) === 10;
317
  } else {
318
  $should_do_locating = rand( 1, 30 ) === 30;
319
  }
320
  if ( $should_do_locating ) {
321
+ $should_do_locating = self::entries_need_locating( $feed_id, $post_id );
322
  }
323
 
324
  $should_do_locating = apply_filters( 'sbi_should_do_ajax_locating', $should_do_locating );
346
 
347
  $one_day_ago = date( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS );
348
 
349
+ $results = $wpdb->get_results(
350
+ $wpdb->prepare(
351
+ "
352
  SELECT id
353
  FROM $feed_locator_table_name
354
  WHERE html_location = 'unknown'
355
  AND last_update < %s
356
  AND feed_id = %s
357
  AND post_id = %d
358
+ LIMIT 1;",
359
+ $one_day_ago,
360
+ $feed_id,
361
+ $post_id
362
+ ),
363
+ ARRAY_A
364
+ );
365
 
366
  return isset( $results[0] );
367
  }
377
 
378
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
379
 
380
+ if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) !== $feed_locator_table_name ) {
381
+ $sql = 'CREATE TABLE ' . $feed_locator_table_name . " (
382
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
383
  feed_id VARCHAR(50) DEFAULT '' NOT NULL,
384
  post_id BIGINT(20) UNSIGNED NOT NULL,
388
  );";
389
  $wpdb->query( $sql );
390
  }
391
+ $error = $wpdb->last_error;
392
+ $query = $wpdb->last_query;
393
  $had_error = false;
394
+ if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) !== $feed_locator_table_name ) {
395
  $had_error = true;
396
+ $sb_instagram_posts_manager->add_error( 'database_create', '<strong>' . __( 'There was an error when trying to create the database tables used to locate feeds.', 'instagram-feed' ) . '</strong><br>' . $error . '<br><code>' . $query . '</code>' );
397
  }
398
 
399
  if ( ! $had_error ) {
415
  global $wpdb;
416
 
417
  $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR );
418
+ $results_content = $wpdb->get_results(
419
+ "
420
  SELECT COUNT(*) AS num_entries
421
+ FROM $feed_locator_table_name
422
  WHERE html_location = 'content'
423
+ ",
424
+ ARRAY_A
425
+ );
426
 
427
+ $results_other = $wpdb->get_results(
428
+ "
429
  SELECT COUNT(*) AS num_entries
430
+ FROM $feed_locator_table_name
431
  WHERE html_location != 'content'
432
  AND html_location != 'unknown'
433
  GROUP BY feed_id
434
+ ",
435
+ ARRAY_A
436
+ );
437
 
438
  $total = 0;
439
  if ( isset( $results_content[0]['num_entries'] ) ) {
440
+ $total += (int) $results_content[0]['num_entries'];
441
  }
442
  if ( isset( $results_other[0]['num_entries'] ) ) {
443
+ $total += (int) $results_other[0]['num_entries'];
444
  }
445
 
446
  return $total;
460
 
461
  $locations = array(
462
  array(
463
+ 'label' => __( 'Content', 'instagram-feed' ),
464
+ 'html_locations' => array( 'content', 'unknown' ),
465
  ),
466
  array(
467
+ 'label' => __( 'Header', 'instagram-feed' ),
468
  'html_locations' => array( 'header' ),
469
+ 'group_by' => 'feed_id',
470
  ),
471
  array(
472
+ 'label' => __( 'Sidebar', 'instagram-feed' ),
473
  'html_locations' => array( 'sidebar' ),
474
+ 'group_by' => 'feed_id',
475
  ),
476
  array(
477
+ 'label' => __( 'Footer', 'instagram-feed' ),
478
  'html_locations' => array( 'footer' ),
479
+ 'group_by' => 'feed_id',
480
+ ),
481
  );
482
 
483
  $one_result_found = false;
484
 
485
  foreach ( $locations as $key => $location ) {
486
+ $in = implode( "', '", $location['html_locations'] );
487
+ $group_by = isset( $location['group_by'] ) ? 'GROUP BY ' . $location['group_by'] : '';
488
+ $results = $wpdb->get_results(
489
+ "
490
  SELECT *
491
  FROM $feed_locator_table_name
492
  WHERE html_location IN ('$in')
493
  $group_by
494
+ ORDER BY last_update ASC",
495
+ ARRAY_A
496
+ );
497
 
498
  if ( isset( $results[0] ) ) {
499
  $one_result_found = true;
508
 
509
  return $locations;
510
  }
511
+ }
inc/class-sb-instagram-feed.php CHANGED
@@ -13,8 +13,8 @@ if ( ! defined( 'ABSPATH' ) ) {
13
  die( '-1' );
14
  }
15
 
16
- class SB_Instagram_Feed
17
- {
18
  /**
19
  * @var string
20
  */
@@ -60,11 +60,6 @@ class SB_Instagram_Feed
60
  */
61
  private $last_retrieve;
62
 
63
- /**
64
- * @var bool
65
- */
66
- private $should_paginate;
67
-
68
  /**
69
  * @var int
70
  */
@@ -128,24 +123,23 @@ class SB_Instagram_Feed
128
  */
129
  public function __construct( $transient_name ) {
130
  $this->regular_feed_transient_name = $transient_name;
131
- $this->backup_feed_transient_name = SBI_BACKUP_PREFIX . $transient_name;
132
 
133
- $sbi_header_transient_name = str_replace( 'sbi_', 'sbi_header_', $transient_name );
134
- $sbi_header_transient_name = substr($sbi_header_transient_name, 0, 44);
135
- $this->header_transient_name = $sbi_header_transient_name;
136
  $this->backup_header_transient_name = SBI_BACKUP_PREFIX . $sbi_header_transient_name;
137
 
138
- $this->post_data = array();
139
- $this->next_pages = array();
140
  $this->cached_feed_error = array();
141
- $this->pages_created = 0;
142
- $this->should_paginate = true;
143
 
144
  // this is a count of how many api calls have been made for each feed
145
  // type and term.
146
  // By default the limit is 10
147
- $this->num_api_calls = 0;
148
- $this->max_api_calls = apply_filters( 'sbi_max_concurrent_api_calls', 10 );
149
  $this->should_use_backup = false;
150
 
151
  // used for errors and the sbi_debug report
@@ -278,8 +272,8 @@ class SB_Instagram_Feed
278
  * @since 2.0/5.0
279
  */
280
  public function need_header( $settings, $feed_types_and_terms ) {
281
- $showheader = ($settings['showheader'] === 'on' || $settings['showheader'] === 'true' || $settings['showheader'] === true);
282
- return ($showheader && isset( $feed_types_and_terms['users'] ));
283
  }
284
 
285
  /**
@@ -318,7 +312,7 @@ class SB_Instagram_Feed
318
  *
319
  * @since 2.0/5.0
320
  */
321
- public function set_post_data_from_cache( $atts = array() ) {
322
  $transient_data = get_transient( $this->regular_feed_transient_name );
323
 
324
  $decrypted = $this->encryption->decrypt( $transient_data );
@@ -326,21 +320,21 @@ class SB_Instagram_Feed
326
  $transient_data = $decrypted ? json_decode( $decrypted, true ) : json_decode( $transient_data, true );
327
 
328
  if ( $transient_data ) {
329
- $post_data = isset( $transient_data['data'] ) ? $transient_data['data'] : array();
330
- $this->post_data = $post_data;
331
- $this->next_pages = isset( $transient_data['pagination'] ) ? $transient_data['pagination'] : array();
332
  $this->pages_created = isset( $transient_data['pages_created'] ) ? $transient_data['pages_created'] : 0;
333
 
334
  if ( isset( $transient_data['atts'] ) ) {
335
  $this->transient_atts = $transient_data['atts'];
336
- $this->last_retrieve = $transient_data['last_retrieve'];
337
  }
338
 
339
  if ( isset( $transient_data['errors'] ) ) {
340
  $this->cached_feed_error = $transient_data['errors'];
341
  }
342
 
343
- $this->add_report( 'pages created: ' . $this->pages_created .', next pages exist: ' . ! empty( $this->next_pages ) );
344
  }
345
  }
346
 
@@ -357,13 +351,13 @@ class SB_Instagram_Feed
357
  if ( $backup_data ) {
358
  $backup_data = json_decode( $backup_data, true );
359
 
360
- $post_data = isset( $backup_data['data'] ) ? $backup_data['data'] : array();
361
- $this->post_data = $post_data;
362
  $this->next_pages = isset( $backup_data['pagination'] ) ? $backup_data['pagination'] : array();
363
 
364
  if ( isset( $backup_data['atts'] ) ) {
365
  $this->transient_atts = $backup_data['atts'];
366
- $this->last_retrieve = $backup_data['last_retrieve'];
367
  }
368
 
369
  $this->maybe_set_header_data_from_backup();
@@ -387,7 +381,7 @@ class SB_Instagram_Feed
387
 
388
  if ( ! empty( $backup_header_data ) ) {
389
  $backup_header_data = json_decode( $backup_header_data, true );
390
- $this->header_data = $backup_header_data;
391
 
392
  return true;
393
  } else {
@@ -434,7 +428,7 @@ class SB_Instagram_Feed
434
  }
435
 
436
  $images_transient_name = str_replace( 'sbi_', 'sbi_i_', $transient_name );
437
- $cache = $offset === 0 ? get_transient( $images_transient_name ) : false;
438
 
439
  if ( $cache ) {
440
  $encryption = new SB_Instagram_Data_Encryption();
@@ -450,25 +444,28 @@ class SB_Instagram_Feed
450
 
451
  $offset = max( 0, $offset );
452
 
453
- $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
454
  $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
455
 
456
  $feed_id_array = explode( '#', $transient_name );
457
- $feed_id = $feed_id_array[0];
458
 
459
  if ( is_array( $num_or_array_of_ids ) ) {
460
  $ids = $num_or_array_of_ids;
461
 
462
  $id_string = "'" . implode( "','", $ids ) . "'";
463
- $results = $wpdb->get_results( "
 
464
  SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes
465
- FROM $posts_table_name AS p
466
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
467
  WHERE p.instagram_id IN($id_string)
468
- AND p.images_done = 1", ARRAY_A );
 
 
469
 
470
  $return = array();
471
- if ( !empty( $results ) && is_array( $results ) ) {
472
 
473
  foreach ( $results as $result ) {
474
  $sizes = maybe_unserialize( $result['sizes'] );
@@ -476,28 +473,34 @@ class SB_Instagram_Feed
476
  $sizes = array( 'full' => 640 );
477
  }
478
  $return[ $result['instagram_id'] ] = array(
479
- 'id' => $result['media_id'],
480
  'ratio' => $result['aspect_ratio'],
481
- 'sizes' => $sizes
482
  );
483
  }
484
-
485
  }
486
-
487
  } else {
488
  $num = $num_or_array_of_ids;
489
 
490
- $results = $wpdb->get_results( $wpdb->prepare( "
 
 
491
  SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes
492
- FROM $posts_table_name AS p
493
- INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
494
  WHERE f.feed_id = %s
495
  AND p.images_done = 1
496
  ORDER BY p.time_stamp
497
- DESC LIMIT %d, %d", $feed_id, $offset, (int)$num ), ARRAY_A );
 
 
 
 
 
 
498
 
499
  $return = array();
500
- if ( !empty( $results ) && is_array( $results ) ) {
501
 
502
  foreach ( $results as $result ) {
503
  $sizes = maybe_unserialize( $result['sizes'] );
@@ -505,14 +508,12 @@ class SB_Instagram_Feed
505
  $sizes = array( 'full' => 640 );
506
  }
507
  $return[ $result['instagram_id'] ] = array(
508
- 'id' => $result['media_id'],
509
  'ratio' => $result['aspect_ratio'],
510
- 'sizes' => $sizes
511
  );
512
  }
513
-
514
  }
515
-
516
  }
517
 
518
  if ( $offset === 0 && $should_cache ) {
@@ -544,11 +545,16 @@ class SB_Instagram_Feed
544
 
545
  global $wpdb;
546
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
547
- $id_string = "'" . implode( "','", $array_of_ids ) . "'";
548
 
549
- $query = $wpdb->query( $wpdb->prepare( "UPDATE $table_name
 
 
550
  SET last_requested = %s
551
- WHERE instagram_id IN ({$id_string});", date( 'Y-m-d H:i:s' ) ) );
 
 
 
552
  }
553
 
554
  /**
@@ -560,7 +566,7 @@ class SB_Instagram_Feed
560
  * @since 2.0/5.0
561
  */
562
  public function need_to_start_cron_job() {
563
- return (( ! empty( $this->post_data ) && ! isset( $this->transient_atts )) || (empty( $this->post_data ) && empty( $this->cached_feed_error )));
564
  }
565
 
566
  /**
@@ -575,18 +581,18 @@ class SB_Instagram_Feed
575
  * @since 2.0/5.0
576
  */
577
  public function need_posts( $num, $offset = 0, $page = 0 ) {
578
- $num_existing_posts = is_array( $this->post_data ) ? count( $this->post_data ) : 0;
579
- $num_needed_for_page = (int)$num + (int)$offset;
580
- $this->add_report( 'pages created ' .$this->pages_created . ' page on' . $page );
581
 
582
  if ( $this->pages_created < $page ) {
583
  $this->add_report( 'need another page' );
584
  return true;
585
  }
586
 
587
- ($num_existing_posts < $num_needed_for_page) ? $this->add_report( 'need more posts ' . $num_existing_posts . ' ' . $num_needed_for_page ) : $this->add_report( 'have enough posts' );
588
 
589
- return ($num_existing_posts < $num_needed_for_page);
590
  }
591
 
592
  /**
@@ -599,12 +605,12 @@ class SB_Instagram_Feed
599
  * @since 2.0/5.0
600
  */
601
  public function can_get_more_posts() {
602
- $one_type_and_term_has_more_ages = $this->next_pages !== false;
603
  $max_concurrent_api_calls_not_met = $this->num_api_calls < $this->max_api_calls;
604
  $max_concurrent_api_calls_not_met ? $this->add_report( 'max conccurrent requests not met' ) : $this->add_report( 'max concurrent met' );
605
  $one_type_and_term_has_more_ages ? $this->add_report( 'more pages available' ) : $this->add_report( 'no next page' );
606
 
607
- return ($one_type_and_term_has_more_ages && $max_concurrent_api_calls_not_met);
608
  }
609
 
610
  /**
@@ -627,7 +633,7 @@ class SB_Instagram_Feed
627
  $this->pages_created ++;
628
 
629
  $new_post_sets = array();
630
- $next_pages = $this->next_pages;
631
  global $sb_instagram_posts_manager;
632
 
633
  /**
@@ -638,16 +644,16 @@ class SB_Instagram_Feed
638
  *
639
  * @since 2.0/5.0
640
  */
641
- $num = apply_filters( 'sbi_num_in_request', $settings['minnum'], $settings );
642
- $num = max( $num, (int)$settings['apinum'] );
643
  $params = array(
644
- 'num' => $num
645
  );
646
 
647
  $one_successful_connection = false;
648
- $one_post_found = false;
649
- $next_page_found = false;
650
- $one_api_request_delayed = false;
651
 
652
  foreach ( $feed_types_and_terms as $type => $terms ) {
653
  if ( is_array( $terms ) && count( $terms ) > 5 ) {
@@ -659,18 +665,18 @@ class SB_Instagram_Feed
659
  $params['num'] = 13;
660
  }
661
 
662
- $term = $term_and_params['term'];
663
  $params = array_merge( $params, $term_and_params['params'] );
664
  if ( ! isset( $term_and_params['error'] )
665
- && (! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== false) ) {
666
  $connected_account_for_term = isset( $connected_accounts_for_feed[ $term ] ) ? $connected_accounts_for_feed[ $term ] : array();
667
- $account_type = isset( $connected_account_for_term['type'] ) ? $connected_account_for_term['type'] : 'personal';
668
 
669
  // basic account access tokens need to be refreshed every 60 days
670
  // normally done using WP Cron but can be done here as a fail safe
671
  if ( $account_type === 'basic' ) {
672
  if ( SB_Instagram_Token_Refresher::refresh_time_has_passed_threshold( $connected_account_for_term )
673
- && SB_Instagram_Token_Refresher::minimum_time_interval_since_last_attempt_has_passed( $connected_account_for_term ) ) {
674
  $refresher = new SB_Instagram_Token_Refresher( $connected_account_for_term );
675
  $refresher->attempt_token_refresh();
676
  if ( $refresher->get_last_error_code() === 10 ) {
@@ -680,7 +686,6 @@ class SB_Instagram_Feed
680
  $this->add_report( 'trying to refresh token ' . $term . '_' . $type );
681
  }
682
  }
683
-
684
  }
685
 
686
  if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
@@ -689,7 +694,7 @@ class SB_Instagram_Feed
689
  $connection = $this->make_api_connection( $next_page_term );
690
  } else {
691
  $params['cursor'] = $next_page_term;
692
- $connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
693
  }
694
  } else {
695
  $connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
@@ -710,7 +715,7 @@ class SB_Instagram_Feed
710
 
711
  $data = $connection->get_data();
712
 
713
- if ( !$connected_account_for_term['is_valid'] ) {
714
  $this->add_report( 'clearing invalid token' );
715
  $this->clear_expired_access_token_notice( $connected_account_for_term );
716
  }
@@ -718,15 +723,15 @@ class SB_Instagram_Feed
718
  if ( isset( $data[0]['id'] ) ) {
719
  $one_post_found = true;
720
 
721
- $post_set = $this->filter_posts( $data, $settings );
722
  $post_set['term'] = $this->get_account_term( $term_and_params );
723
- $new_post_sets[] = $post_set;
724
  }
725
 
726
- $next_page = $connection->get_next_page( $type );
727
  if ( ! empty( $next_page ) ) {
728
  $next_pages[ $term . '_' . $type ] = $next_page;
729
- $next_page_found = true;
730
  } else {
731
  $next_pages[ $term . '_' . $type ] = false;
732
  }
@@ -742,21 +747,21 @@ class SB_Instagram_Feed
742
  if ( strpos( $next_page_term, 'https://' ) !== false ) {
743
  $additional_connection = $this->make_api_connection( $next_page_term );
744
  } else {
745
- $params['cursor'] = $next_page_term;
746
  $additional_connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
747
  }
748
  $additional_connection->connect();
749
  }
750
 
751
  if ( isset( $additional_connection )
752
- && ! $additional_connection->is_wp_error()
753
- && ! $additional_connection->is_instagram_error() ) {
754
  $additional_data = $additional_connection->get_data();
755
 
756
  if ( isset( $additional_data[0]['id'] ) ) {
757
  $one_post_found = true;
758
 
759
- $post_set = $this->filter_posts( $additional_data, $settings );
760
  $post_set['term'] = $this->get_account_term( $term_and_params );
761
  $new_post_sets[] = $post_set;
762
 
@@ -764,7 +769,7 @@ class SB_Instagram_Feed
764
 
765
  }
766
 
767
- $next_page = $additional_connection->get_next_page( $type );
768
  if ( ! empty( $next_page ) ) {
769
  $next_pages[ $term . '_' . $type ] = $next_page;
770
  $next_page_found = true;
@@ -776,23 +781,23 @@ class SB_Instagram_Feed
776
  }
777
  } else {
778
 
779
- if ( $this->can_try_another_request( $type, $connected_accounts_for_feed[ $term ] ) ) {
780
  $this->add_report( 'trying other accounts' );
781
- $i = 0;
782
  $attempted = array( $connected_accounts_for_feed[ $term ]['access_token'] );
783
- $success = false;
784
  $different = true;
785
- $error = false;
786
 
787
  while ( $different
788
- && ! $success
789
- && $this->can_try_another_request( $type, $connected_accounts_for_feed[ $term ], $i ) ) {
790
- $different = $this->get_different_connected_account( $type, $attempted );
791
  $this->add_report( 'trying the account ' . $different['user_id'] );
792
 
793
  if ( $different ) {
794
- $connected_accounts_for_feed[ $term ] = $this->get_different_connected_account( $type, $attempted );
795
- $attempted[] = $connected_accounts_for_feed[ $term ]['user_id'];
796
 
797
  if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
798
  $new_connection = $this->make_api_connection( $next_pages[ $term . '_' . $type ] );
@@ -804,21 +809,22 @@ class SB_Instagram_Feed
804
  if ( ! $new_connection->is_wp_error() && ! $new_connection->is_instagram_error() ) {
805
 
806
  $one_successful_connection = true;
807
- $success = true;
808
  $sb_instagram_posts_manager->maybe_remove_display_error( 'hashtag_limit' );
809
 
810
  $data = $new_connection->get_data();
811
  if ( isset( $data[0]['id'] ) ) {
812
- $one_post_found = true;
813
- $post_set = $this->filter_posts( $data, $settings );
 
814
  $post_set['term'] = $this->get_account_term( $term_and_params );
815
 
816
  $new_post_sets[] = $post_set;
817
  }
818
- $next_page = $new_connection->get_next_page( $type );
819
  if ( ! empty( $next_page ) ) {
820
  $next_pages[ $term . '_' . $type ] = $next_page;
821
- $next_page_found = true;
822
  } else {
823
  $next_pages[ $term . '_' . $type ] = false;
824
  }
@@ -840,7 +846,7 @@ class SB_Instagram_Feed
840
  if ( $connection->is_wp_error() ) {
841
  SB_Instagram_API_Connect::handle_wp_remote_get_error( $error );
842
  } else {
843
- SB_Instagram_API_Connect::handle_instagram_error( $error, $connected_accounts_for_feed[ $term ], $type );
844
  }
845
  $next_pages[ $term . '_' . $type ] = false;
846
 
@@ -849,18 +855,17 @@ class SB_Instagram_Feed
849
  if ( $connection->is_wp_error() ) {
850
  SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() );
851
  } else {
852
- SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $term ], $type );
853
  }
854
 
855
  $next_pages[ $term . '_' . $type ] = false;
856
  }
857
  }
858
  }
859
-
860
  }
861
  }
862
 
863
- if ( ! $one_successful_connection || ($one_api_request_delayed && empty( $new_post_sets )) ) {
864
  $this->should_use_backup = true;
865
  }
866
  $posts = $this->merge_posts( $new_post_sets, $settings );
@@ -907,6 +912,17 @@ class SB_Instagram_Feed
907
  */
908
  public function set_remote_header_data( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) {
909
  $first_user = $this->get_first_user( $feed_types_and_terms );
 
 
 
 
 
 
 
 
 
 
 
910
  $this->header_data = false;
911
  global $sb_instagram_posts_manager;
912
 
@@ -923,24 +939,24 @@ class SB_Instagram_Feed
923
  $sb_instagram_posts_manager->remove_error( 'connection', $connected_accounts_for_feed[ $first_user ] );
924
 
925
  if ( isset( $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) && $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) {
926
- $upload = wp_upload_dir();
927
  $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
928
 
929
- $full_file_name = $resized_url . $this->header_data['username'] . '.jpg';
930
  $this->header_data['local_avatar'] = $full_file_name;
931
  } else {
932
- if ( !$sb_instagram_posts_manager->image_resizing_disabled( $feed_types_and_terms ) && ! isset( $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) ) {
933
  if ( sbi_store_local_avatar( $connected_accounts_for_feed[ $first_user ] ) ) {
934
- $upload = wp_upload_dir();
935
  $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
936
 
937
- $full_file_name = $resized_url . $this->header_data['username'] . '.jpg';
938
  $this->header_data['local_avatar'] = $full_file_name;
939
  }
940
  }
941
  }
942
  if ( empty( $this->header_data['bio'] )
943
- && isset( $connected_accounts_for_feed[ $first_user ]['bio'] ) ) {
944
 
945
  $this->header_data['bio'] = sbi_decode_emoji( $connected_accounts_for_feed[ $first_user ]['bio'] );
946
  }
@@ -950,7 +966,7 @@ class SB_Instagram_Feed
950
  if ( $connection->is_wp_error() ) {
951
  SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() );
952
  } else {
953
- SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $first_user ], 'header' );
954
  }
955
  }
956
  }
@@ -972,9 +988,9 @@ class SB_Instagram_Feed
972
  $this->trim_posts_to_max();
973
 
974
  $to_cache = array(
975
- 'data' => $this->post_data,
976
- 'pagination' => $this->next_pages,
977
- 'pages_created' => $this->pages_created
978
  );
979
 
980
  global $sb_instagram_posts_manager;
@@ -996,7 +1012,6 @@ class SB_Instagram_Feed
996
  }
997
  update_option( $this->backup_feed_transient_name, $encrypted, false );
998
  }
999
-
1000
  } else {
1001
  $this->add_report( 'no data not caching' );
1002
  }
@@ -1015,17 +1030,17 @@ class SB_Instagram_Feed
1015
  */
1016
  public function set_cron_cache( $to_cache, $cache_time, $save_backup = true ) {
1017
  if ( ! empty( $this->post_data )
1018
- || ! empty( $this->next_pages )
1019
- || ! empty( $to_cache['data'] )
1020
- || $this->should_cache_error() ) {
1021
  $this->remove_duplicate_posts();
1022
  $this->trim_posts_to_max();
1023
 
1024
- $to_cache['data'] = isset( $to_cache['data'] ) ? $to_cache['data'] : $this->post_data;
1025
- $to_cache['pagination'] = isset( $to_cache['next_pages'] ) ? $to_cache['next_pages'] : $this->next_pages;
1026
- $to_cache['atts'] = isset( $to_cache['atts'] ) ? $to_cache['atts'] : $this->transient_atts;
1027
  $to_cache['last_requested'] = isset( $to_cache['last_requested'] ) ? $to_cache['last_requested'] : time();
1028
- $to_cache['last_retrieve'] = isset( $to_cache['last_retrieve'] ) ? $to_cache['last_retrieve'] : $this->last_retrieve;
1029
 
1030
  global $sb_instagram_posts_manager;
1031
 
@@ -1042,8 +1057,8 @@ class SB_Instagram_Feed
1042
 
1043
  if ( $save_backup ) {
1044
  if ( ! empty( $this->post_data )
1045
- || ! empty( $this->next_pages )
1046
- || ! empty( $to_cache['data'] ) ) {
1047
  if ( isset( $to_cache['errors'] ) ) {
1048
  unset( $to_cache['errors'] );
1049
  }
@@ -1087,7 +1102,7 @@ class SB_Instagram_Feed
1087
  * @since 2.0/5.0
1088
  */
1089
  public function should_update_last_requested() {
1090
- return (rand( 1, 20 ) === 20);
1091
  }
1092
 
1093
  /**
@@ -1104,12 +1119,12 @@ class SB_Instagram_Feed
1104
  if ( $settings['minnum'] < 1 ) {
1105
  return false;
1106
  }
1107
- $posts_available = count( $this->post_data ) - ($offset + $settings['num']);
1108
- $show_loadmore_button_by_settings = ($settings['showbutton'] == 'on' || $settings['showbutton'] == 'true' || $settings['showbutton'] == true ) && $settings['showbutton'] !== 'false';
1109
 
1110
  if ( $show_loadmore_button_by_settings ) {
1111
  // used for permanent and whitelist feeds
1112
- if ( $this->feed_is_complete( $settings, $offset ) ) {
1113
  $this->add_report( 'no pagination, feed complete' );
1114
  return false;
1115
  }
@@ -1126,10 +1141,8 @@ class SB_Instagram_Feed
1126
  }
1127
  }
1128
  }
1129
-
1130
  }
1131
 
1132
-
1133
  $this->add_report( 'no pagination, no posts available' );
1134
 
1135
  return false;
@@ -1155,12 +1168,12 @@ class SB_Instagram_Feed
1155
  global $sb_instagram_posts_manager;
1156
 
1157
  if ( empty( $this->post_data ) && ! empty( $connected_accounts_for_feed ) && $settings['minnum'] > 0 ) {
1158
- $this->handle_no_posts_found( $settings, $feed_types_and_terms );
1159
  }
1160
- $posts = array_slice( $this->post_data, 0, $settings['minnum'] );
1161
  $header_data = ! empty( $this->header_data ) ? $this->header_data : false;
1162
 
1163
- $first_user = ! empty( $feed_types_and_terms['users'][0] ) ? $feed_types_and_terms['users'][0]['term'] : false;
1164
  $first_username = false;
1165
  if ( $first_user ) {
1166
  $first_username = isset( $connected_accounts_for_feed[ $first_user ]['username'] ) ? $connected_accounts_for_feed[ $first_user ]['username'] : $first_user;
@@ -1171,11 +1184,11 @@ class SB_Instagram_Feed
1171
  }
1172
  $use_pagination = $this->should_use_pagination( $settings, 0 );
1173
 
1174
- $feed_id = $this->regular_feed_transient_name;
1175
  $shortcode_atts = ! empty( $atts ) ? sbi_json_encode( $atts ) : '{}';
1176
 
1177
  $settings['header_outside'] = false;
1178
- $settings['header_inside'] = false;
1179
  if ( $header_data && $settings['showheader'] ) {
1180
  $settings['header_inside'] = true;
1181
  }
@@ -1183,7 +1196,7 @@ class SB_Instagram_Feed
1183
  $other_atts = '';
1184
 
1185
  $classes = array();
1186
- if ( empty( $settings['widthresp'] ) || $settings['widthresp'] == 'on' || $settings['widthresp'] == 'true' || $settings['widthresp'] === true ) {
1187
  if ( $settings['widthresp'] !== 'false' ) {
1188
  $classes[] = 'sbi_width_resp';
1189
  }
@@ -1192,11 +1205,11 @@ class SB_Instagram_Feed
1192
  $classes[] = esc_attr( $settings['class'] );
1193
  }
1194
  if ( ! empty( $settings['height'] )
1195
- && (((int)$settings['height'] < 100 && $settings['heightunit'] === '%') || $settings['heightunit'] === 'px') ) {
1196
  $classes[] = 'sbi_fixed_height';
1197
  }
1198
  if ( ! empty( $settings['disablemobile'] )
1199
- && ($settings['disablemobile'] == 'on' || $settings['disablemobile'] == 'true' || $settings['disablemobile'] == true) ) {
1200
  if ( $settings['disablemobile'] !== 'false' ) {
1201
  $classes[] = 'sbi_disable_mobile';
1202
  }
@@ -1210,7 +1223,7 @@ class SB_Instagram_Feed
1210
  $other_atts .= ' data-postid="' . esc_attr( get_the_ID() ) . '"';
1211
  $other_atts .= ' data-locatornonce="' . esc_attr( wp_create_nonce( 'sbi-locator-nonce-' . get_the_ID() . '-' . $this->regular_feed_transient_name ) ) . '"';
1212
 
1213
- $other_atts = $this->add_other_atts( $other_atts, $settings );
1214
 
1215
  $flags = array();
1216
 
@@ -1233,10 +1246,11 @@ class SB_Instagram_Feed
1233
  }
1234
  }
1235
  if ( ! $settings['isgutenberg']
1236
- && SB_Instagram_Feed_Locator::should_do_ajax_locating( $this->regular_feed_transient_name, get_the_ID() ) ) {
1237
  $this->add_report( 'doing feed locating' );
1238
  $flags[] = 'locator';
1239
  }
 
1240
  if ( isset( $_GET['sbi_debug'] ) ) {
1241
  $flags[] = 'debug';
1242
  }
@@ -1244,7 +1258,7 @@ class SB_Instagram_Feed
1244
  $flags = apply_filters( 'sbi_flags', $flags, $settings );
1245
 
1246
  if ( ! empty( $flags ) ) {
1247
- $other_atts .= ' data-sbi-flags="' . implode(',', $flags ) . '"';
1248
  }
1249
 
1250
  ob_start();
@@ -1273,12 +1287,12 @@ class SB_Instagram_Feed
1273
  *
1274
  * @since 2.0/5.0
1275
  */
1276
- public function get_the_items_html( $settings, $offset, $feed_types_and_terms, $connected_accounts_for_feed ) {
1277
  if ( empty( $this->post_data ) ) {
1278
  ob_start();
1279
  $html = ob_get_contents();
1280
- ob_get_clean(); ?>
1281
- <p><?php esc_html_e( 'No posts found.', 'instagram-feed' ); ?></p>
1282
  <?php
1283
  $html = ob_get_contents();
1284
  ob_get_clean();
@@ -1302,7 +1316,7 @@ class SB_Instagram_Feed
1302
  *
1303
  * @return object
1304
  */
1305
- public function make_api_connection( $connected_account_or_page, $type = NULL, $params = NULL ) {
1306
  return new SB_Instagram_API_Connect( $connected_account_or_page, $type, $params );
1307
  }
1308
 
@@ -1321,18 +1335,18 @@ class SB_Instagram_Feed
1321
  }
1322
  $sbi_options = sbi_get_database_settings();
1323
  $font_method = 'svg';
1324
- $upload = wp_upload_dir();
1325
  $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
1326
 
1327
  $js_options = array(
1328
  'font_method' => $font_method,
1329
  'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png',
1330
- 'resized_url' => $resized_url
1331
  );
1332
 
1333
  $encoded_options = sbi_json_encode( $js_options );
1334
 
1335
- $js_option_html = '<script type="text/javascript">var sb_instagram_js_options = ' . $encoded_options . ';</script>';
1336
  $js_option_html .= "<script type='text/javascript' src='" . trailingslashit( SBI_PLUGIN_URL ) . 'js/sbi-scripts.min.js?ver=' . SBIVER . "'></script>";
1337
 
1338
  return $js_option_html;
@@ -1388,7 +1402,7 @@ class SB_Instagram_Feed
1388
  *
1389
  * @return string
1390
  */
1391
- protected function add_other_atts( $other_atts, $settings ) {
1392
  return $other_atts;
1393
  }
1394
 
@@ -1403,41 +1417,39 @@ class SB_Instagram_Feed
1403
  *
1404
  * @since 2.0/5.0
1405
  */
1406
- protected function filter_posts( $post_set, $settings = array() ) {
1407
- // array_unique( $post_set, SORT_REGULAR);
1408
-
1409
  return $post_set;
1410
  }
1411
 
1412
- protected function handle_no_posts_found( $settings = array(), $feed_types_and_terms = array() ) {
1413
  global $sb_instagram_posts_manager;
1414
 
1415
  $error_message_return = array(
1416
- 'error_message' => __( 'Error: No posts found.', 'instagram-feed' ),
1417
- 'admin_only' => __( 'Make sure this account has posts available on instagram.com.', 'instagram-feed' ),
1418
  'frontend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
1419
- 'backend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>'
1420
  );
1421
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
1422
  }
1423
 
1424
  protected function remove_duplicate_posts() {
1425
- $posts = $this->post_data;
1426
- $ids_in_feed = array();
1427
  $non_duplicate_posts = array();
1428
- $removed = array();
1429
 
1430
  foreach ( $posts as $post ) {
1431
  $post_id = SB_Instagram_Parse::get_post_id( $post );
1432
  if ( ! in_array( $post_id, $ids_in_feed, true ) ) {
1433
- $ids_in_feed[] = $post_id;
1434
  $non_duplicate_posts[] = $post;
1435
  } else {
1436
  $removed[] = $post_id;
1437
  }
1438
  }
1439
 
1440
- $this->add_report( 'removed duplicates: ' . implode(', ', $removed ) );
1441
  $this->set_post_data( $non_duplicate_posts );
1442
  }
1443
 
@@ -1452,7 +1464,7 @@ class SB_Instagram_Feed
1452
  }
1453
 
1454
  $max = apply_filters( 'sbi_max_cache_size', 500 );
1455
- $this->set_post_data( array_slice( $this->post_data , 0, $max ) );
1456
 
1457
  }
1458
 
@@ -1469,7 +1481,7 @@ class SB_Instagram_Feed
1469
  *
1470
  * @since 2.0/5.0
1471
  */
1472
- protected function feed_is_complete( $settings, $offset = 0 ) {
1473
  return false;
1474
  }
1475
 
@@ -1480,7 +1492,7 @@ class SB_Instagram_Feed
1480
  */
1481
  private function clear_expired_access_token_notice( $connected_account_for_term ) {
1482
  $sbi_options = get_option( 'sb_instagram_settings' );
1483
- $ca_to_save = isset( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
1484
 
1485
  if ( ! empty( $ca_to_save ) && ! empty( $connected_account_for_term ) ) {
1486
 
@@ -1509,13 +1521,13 @@ class SB_Instagram_Feed
1509
  */
1510
  private function posts_loop( $posts, $settings, $offset = 0 ) {
1511
 
1512
- $image_ids = array();
1513
- $post_index = $offset;
1514
- $icon_type = 'svg';
1515
  $resized_images = $this->get_resized_images();
1516
 
1517
  foreach ( $posts as $post ) {
1518
- $image_ids[] = SB_Instagram_Parse::get_post_id( $post );
1519
  $account_type = SB_Instagram_Parse::get_account_type( $post );
1520
  include sbi_get_feed_template_part( 'item', $settings );
1521
  $post_index++;
@@ -1551,12 +1563,12 @@ class SB_Instagram_Feed
1551
 
1552
  $merged_posts = array();
1553
  if ( $settings['sortby'] === 'alternate'
1554
- || $settings['sortby'] === 'api' && isset( $post_sets[1] ) ) {
1555
  // don't bother merging posts if there is only one post set
1556
  if ( isset( $post_sets[1] ) ) {
1557
- $min_cycles = $settings['sortby'] === 'api' ? min( 200 / count( $post_sets ) + 5, 50 ) : max( 1, (int)$settings['minnum'] );
1558
- $terms = array();
1559
- for( $i = 0; $i <= $min_cycles; $i++ ) {
1560
  $ii = 0;
1561
  foreach ( $post_sets as $post_set ) {
1562
  if ( isset( $post_sets[ $ii ]['term'] ) ) {
@@ -1576,7 +1588,7 @@ class SB_Instagram_Feed
1576
  }
1577
  if ( isset( $post_set[ $i ] ) && isset( $post_set[ $i ]['id'] ) ) {
1578
  $post_set[ $i ]['term'] = $terms[ $ii ];
1579
- $merged_posts[] = $post_set[ $i ];
1580
  }
1581
  $ii++;
1582
  }
@@ -1631,7 +1643,7 @@ class SB_Instagram_Feed
1631
  if ( isset( $post_sets[1] ) ) {
1632
 
1633
  $terms = array();
1634
- $ii = 0;
1635
  foreach ( $post_sets as $post_set ) {
1636
  if ( isset( $post_set[0]['id'] ) ) {
1637
  if ( isset( $post_sets[ $ii ]['term'] ) ) {
@@ -1691,7 +1703,7 @@ class SB_Instagram_Feed
1691
  'alternate',
1692
  'api',
1693
  'random',
1694
- 'likes'
1695
  );
1696
 
1697
  if ( ! in_array( $settings['sortby'], $merge_befores, true ) ) {
@@ -1726,16 +1738,16 @@ class SB_Instagram_Feed
1726
  $return_post_set = $post_set;
1727
  } elseif ( $settings['sortby'] === 'random' ) {
1728
  /*
1729
- * randomly selects posts in a random order. Cache saves posts
1730
- * in this random order so paginating does not cause some posts to show up
1731
- * twice or not at all
1732
- */
1733
- usort($post_set, 'sbi_rand_sort' );
1734
  $return_post_set = $post_set;
1735
 
1736
  } else {
1737
  // compares posted on dates of posts
1738
- usort($post_set, 'sbi_date_sort' );
1739
  $return_post_set = $post_set;
1740
  }
1741
 
@@ -1764,7 +1776,7 @@ class SB_Instagram_Feed
1764
  *
1765
  * @since 2.0/5.1.1
1766
  */
1767
- protected function can_try_another_request( $type, $connected_account_with_error, $attempts = 0 ) {
1768
  return false;
1769
  }
1770
 
@@ -1780,8 +1792,8 @@ class SB_Instagram_Feed
1780
  *
1781
  * @since 2.0/5.1.1
1782
  */
1783
- protected function get_different_connected_account( $type, $attempted_connected_accounts ) {
1784
  return false;
1785
  }
1786
 
1787
- }
13
  die( '-1' );
14
  }
15
 
16
+ class SB_Instagram_Feed {
17
+
18
  /**
19
  * @var string
20
  */
60
  */
61
  private $last_retrieve;
62
 
 
 
 
 
 
63
  /**
64
  * @var int
65
  */
123
  */
124
  public function __construct( $transient_name ) {
125
  $this->regular_feed_transient_name = $transient_name;
126
+ $this->backup_feed_transient_name = SBI_BACKUP_PREFIX . $transient_name;
127
 
128
+ $sbi_header_transient_name = str_replace( 'sbi_', 'sbi_header_', $transient_name );
129
+ $sbi_header_transient_name = substr( $sbi_header_transient_name, 0, 44 );
130
+ $this->header_transient_name = $sbi_header_transient_name;
131
  $this->backup_header_transient_name = SBI_BACKUP_PREFIX . $sbi_header_transient_name;
132
 
133
+ $this->post_data = array();
134
+ $this->next_pages = array();
135
  $this->cached_feed_error = array();
136
+ $this->pages_created = 0;
 
137
 
138
  // this is a count of how many api calls have been made for each feed
139
  // type and term.
140
  // By default the limit is 10
141
+ $this->num_api_calls = 0;
142
+ $this->max_api_calls = apply_filters( 'sbi_max_concurrent_api_calls', 10 );
143
  $this->should_use_backup = false;
144
 
145
  // used for errors and the sbi_debug report
272
  * @since 2.0/5.0
273
  */
274
  public function need_header( $settings, $feed_types_and_terms ) {
275
+ $showheader = ( $settings['showheader'] === 'on' || $settings['showheader'] === 'true' || $settings['showheader'] === true );
276
+ return ( $showheader && isset( $feed_types_and_terms['users'] ) );
277
  }
278
 
279
  /**
312
  *
313
  * @since 2.0/5.0
314
  */
315
+ public function set_post_data_from_cache() {
316
  $transient_data = get_transient( $this->regular_feed_transient_name );
317
 
318
  $decrypted = $this->encryption->decrypt( $transient_data );
320
  $transient_data = $decrypted ? json_decode( $decrypted, true ) : json_decode( $transient_data, true );
321
 
322
  if ( $transient_data ) {
323
+ $post_data = isset( $transient_data['data'] ) ? $transient_data['data'] : array();
324
+ $this->post_data = $post_data;
325
+ $this->next_pages = isset( $transient_data['pagination'] ) ? $transient_data['pagination'] : array();
326
  $this->pages_created = isset( $transient_data['pages_created'] ) ? $transient_data['pages_created'] : 0;
327
 
328
  if ( isset( $transient_data['atts'] ) ) {
329
  $this->transient_atts = $transient_data['atts'];
330
+ $this->last_retrieve = $transient_data['last_retrieve'];
331
  }
332
 
333
  if ( isset( $transient_data['errors'] ) ) {
334
  $this->cached_feed_error = $transient_data['errors'];
335
  }
336
 
337
+ $this->add_report( 'pages created: ' . $this->pages_created . ', next pages exist: ' . ! empty( $this->next_pages ) );
338
  }
339
  }
340
 
351
  if ( $backup_data ) {
352
  $backup_data = json_decode( $backup_data, true );
353
 
354
+ $post_data = isset( $backup_data['data'] ) ? $backup_data['data'] : array();
355
+ $this->post_data = $post_data;
356
  $this->next_pages = isset( $backup_data['pagination'] ) ? $backup_data['pagination'] : array();
357
 
358
  if ( isset( $backup_data['atts'] ) ) {
359
  $this->transient_atts = $backup_data['atts'];
360
+ $this->last_retrieve = $backup_data['last_retrieve'];
361
  }
362
 
363
  $this->maybe_set_header_data_from_backup();
381
 
382
  if ( ! empty( $backup_header_data ) ) {
383
  $backup_header_data = json_decode( $backup_header_data, true );
384
+ $this->header_data = $backup_header_data;
385
 
386
  return true;
387
  } else {
428
  }
429
 
430
  $images_transient_name = str_replace( 'sbi_', 'sbi_i_', $transient_name );
431
+ $cache = $offset === 0 ? get_transient( $images_transient_name ) : false;
432
 
433
  if ( $cache ) {
434
  $encryption = new SB_Instagram_Data_Encryption();
444
 
445
  $offset = max( 0, $offset );
446
 
447
+ $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
448
  $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
449
 
450
  $feed_id_array = explode( '#', $transient_name );
451
+ $feed_id = $feed_id_array[0];
452
 
453
  if ( is_array( $num_or_array_of_ids ) ) {
454
  $ids = $num_or_array_of_ids;
455
 
456
  $id_string = "'" . implode( "','", $ids ) . "'";
457
+ $results = $wpdb->get_results(
458
+ "
459
  SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes
460
+ FROM $posts_table_name AS p
461
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
462
  WHERE p.instagram_id IN($id_string)
463
+ AND p.images_done = 1",
464
+ ARRAY_A
465
+ );
466
 
467
  $return = array();
468
+ if ( ! empty( $results ) && is_array( $results ) ) {
469
 
470
  foreach ( $results as $result ) {
471
  $sizes = maybe_unserialize( $result['sizes'] );
473
  $sizes = array( 'full' => 640 );
474
  }
475
  $return[ $result['instagram_id'] ] = array(
476
+ 'id' => $result['media_id'],
477
  'ratio' => $result['aspect_ratio'],
478
+ 'sizes' => $sizes,
479
  );
480
  }
 
481
  }
 
482
  } else {
483
  $num = $num_or_array_of_ids;
484
 
485
+ $results = $wpdb->get_results(
486
+ $wpdb->prepare(
487
+ "
488
  SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes
489
+ FROM $posts_table_name AS p
490
+ INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
491
  WHERE f.feed_id = %s
492
  AND p.images_done = 1
493
  ORDER BY p.time_stamp
494
+ DESC LIMIT %d, %d",
495
+ $feed_id,
496
+ $offset,
497
+ (int) $num
498
+ ),
499
+ ARRAY_A
500
+ );
501
 
502
  $return = array();
503
+ if ( ! empty( $results ) && is_array( $results ) ) {
504
 
505
  foreach ( $results as $result ) {
506
  $sizes = maybe_unserialize( $result['sizes'] );
508
  $sizes = array( 'full' => 640 );
509
  }
510
  $return[ $result['instagram_id'] ] = array(
511
+ 'id' => $result['media_id'],
512
  'ratio' => $result['aspect_ratio'],
513
+ 'sizes' => $sizes,
514
  );
515
  }
 
516
  }
 
517
  }
518
 
519
  if ( $offset === 0 && $should_cache ) {
545
 
546
  global $wpdb;
547
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
548
+ $id_string = "'" . implode( "','", $array_of_ids ) . "'";
549
 
550
+ $query = $wpdb->query(
551
+ $wpdb->prepare(
552
+ "UPDATE $table_name
553
  SET last_requested = %s
554
+ WHERE instagram_id IN ({$id_string});",
555
+ date( 'Y-m-d H:i:s' )
556
+ )
557
+ );
558
  }
559
 
560
  /**
566
  * @since 2.0/5.0
567
  */
568
  public function need_to_start_cron_job() {
569
+ return ( ( ! empty( $this->post_data ) && ! isset( $this->transient_atts ) ) || ( empty( $this->post_data ) && empty( $this->cached_feed_error ) ) );
570
  }
571
 
572
  /**
581
  * @since 2.0/5.0
582
  */
583
  public function need_posts( $num, $offset = 0, $page = 0 ) {
584
+ $num_existing_posts = is_array( $this->post_data ) ? count( $this->post_data ) : 0;
585
+ $num_needed_for_page = (int) $num + (int) $offset;
586
+ $this->add_report( 'pages created ' . $this->pages_created . ' page on' . $page );
587
 
588
  if ( $this->pages_created < $page ) {
589
  $this->add_report( 'need another page' );
590
  return true;
591
  }
592
 
593
+ ( $num_existing_posts < $num_needed_for_page ) ? $this->add_report( 'need more posts ' . $num_existing_posts . ' ' . $num_needed_for_page ) : $this->add_report( 'have enough posts' );
594
 
595
+ return ( $num_existing_posts < $num_needed_for_page );
596
  }
597
 
598
  /**
605
  * @since 2.0/5.0
606
  */
607
  public function can_get_more_posts() {
608
+ $one_type_and_term_has_more_ages = $this->next_pages !== false;
609
  $max_concurrent_api_calls_not_met = $this->num_api_calls < $this->max_api_calls;
610
  $max_concurrent_api_calls_not_met ? $this->add_report( 'max conccurrent requests not met' ) : $this->add_report( 'max concurrent met' );
611
  $one_type_and_term_has_more_ages ? $this->add_report( 'more pages available' ) : $this->add_report( 'no next page' );
612
 
613
+ return ( $one_type_and_term_has_more_ages && $max_concurrent_api_calls_not_met );
614
  }
615
 
616
  /**
633
  $this->pages_created ++;
634
 
635
  $new_post_sets = array();
636
+ $next_pages = $this->next_pages;
637
  global $sb_instagram_posts_manager;
638
 
639
  /**
644
  *
645
  * @since 2.0/5.0
646
  */
647
+ $num = apply_filters( 'sbi_num_in_request', $settings['minnum'], $settings );
648
+ $num = max( $num, (int) $settings['apinum'] );
649
  $params = array(
650
+ 'num' => $num,
651
  );
652
 
653
  $one_successful_connection = false;
654
+ $one_post_found = false;
655
+ $next_page_found = false;
656
+ $one_api_request_delayed = false;
657
 
658
  foreach ( $feed_types_and_terms as $type => $terms ) {
659
  if ( is_array( $terms ) && count( $terms ) > 5 ) {
665
  $params['num'] = 13;
666
  }
667
 
668
+ $term = $term_and_params['term'];
669
  $params = array_merge( $params, $term_and_params['params'] );
670
  if ( ! isset( $term_and_params['error'] )
671
+ && ( ! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== false ) ) {
672
  $connected_account_for_term = isset( $connected_accounts_for_feed[ $term ] ) ? $connected_accounts_for_feed[ $term ] : array();
673
+ $account_type = isset( $connected_account_for_term['type'] ) ? $connected_account_for_term['type'] : 'personal';
674
 
675
  // basic account access tokens need to be refreshed every 60 days
676
  // normally done using WP Cron but can be done here as a fail safe
677
  if ( $account_type === 'basic' ) {
678
  if ( SB_Instagram_Token_Refresher::refresh_time_has_passed_threshold( $connected_account_for_term )
679
+ && SB_Instagram_Token_Refresher::minimum_time_interval_since_last_attempt_has_passed( $connected_account_for_term ) ) {
680
  $refresher = new SB_Instagram_Token_Refresher( $connected_account_for_term );
681
  $refresher->attempt_token_refresh();
682
  if ( $refresher->get_last_error_code() === 10 ) {
686
  $this->add_report( 'trying to refresh token ' . $term . '_' . $type );
687
  }
688
  }
 
689
  }
690
 
691
  if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
694
  $connection = $this->make_api_connection( $next_page_term );
695
  } else {
696
  $params['cursor'] = $next_page_term;
697
+ $connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
698
  }
699
  } else {
700
  $connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
715
 
716
  $data = $connection->get_data();
717
 
718
+ if ( ! $connected_account_for_term['is_valid'] ) {
719
  $this->add_report( 'clearing invalid token' );
720
  $this->clear_expired_access_token_notice( $connected_account_for_term );
721
  }
723
  if ( isset( $data[0]['id'] ) ) {
724
  $one_post_found = true;
725
 
726
+ $post_set = $this->filter_posts( $data );
727
  $post_set['term'] = $this->get_account_term( $term_and_params );
728
+ $new_post_sets[] = $post_set;
729
  }
730
 
731
+ $next_page = $connection->get_next_page();
732
  if ( ! empty( $next_page ) ) {
733
  $next_pages[ $term . '_' . $type ] = $next_page;
734
+ $next_page_found = true;
735
  } else {
736
  $next_pages[ $term . '_' . $type ] = false;
737
  }
747
  if ( strpos( $next_page_term, 'https://' ) !== false ) {
748
  $additional_connection = $this->make_api_connection( $next_page_term );
749
  } else {
750
+ $params['cursor'] = $next_page_term;
751
  $additional_connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
752
  }
753
  $additional_connection->connect();
754
  }
755
 
756
  if ( isset( $additional_connection )
757
+ && ! $additional_connection->is_wp_error()
758
+ && ! $additional_connection->is_instagram_error() ) {
759
  $additional_data = $additional_connection->get_data();
760
 
761
  if ( isset( $additional_data[0]['id'] ) ) {
762
  $one_post_found = true;
763
 
764
+ $post_set = $this->filter_posts( $additional_data );
765
  $post_set['term'] = $this->get_account_term( $term_and_params );
766
  $new_post_sets[] = $post_set;
767
 
769
 
770
  }
771
 
772
+ $next_page = $additional_connection->get_next_page();
773
  if ( ! empty( $next_page ) ) {
774
  $next_pages[ $term . '_' . $type ] = $next_page;
775
  $next_page_found = true;
781
  }
782
  } else {
783
 
784
+ if ( $this->can_try_another_request() ) {
785
  $this->add_report( 'trying other accounts' );
786
+ $i = 0;
787
  $attempted = array( $connected_accounts_for_feed[ $term ]['access_token'] );
788
+ $success = false;
789
  $different = true;
790
+ $error = false;
791
 
792
  while ( $different
793
+ && ! $success
794
+ && $this->can_try_another_request() ) {
795
+ $different = $this->get_different_connected_account();
796
  $this->add_report( 'trying the account ' . $different['user_id'] );
797
 
798
  if ( $different ) {
799
+ $connected_accounts_for_feed[ $term ] = $this->get_different_connected_account();
800
+ $attempted[] = $connected_accounts_for_feed[ $term ]['user_id'];
801
 
802
  if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
803
  $new_connection = $this->make_api_connection( $next_pages[ $term . '_' . $type ] );
809
  if ( ! $new_connection->is_wp_error() && ! $new_connection->is_instagram_error() ) {
810
 
811
  $one_successful_connection = true;
812
+ $success = true;
813
  $sb_instagram_posts_manager->maybe_remove_display_error( 'hashtag_limit' );
814
 
815
  $data = $new_connection->get_data();
816
  if ( isset( $data[0]['id'] ) ) {
817
+
818
+ $one_post_found = true;
819
+ $post_set = $this->filter_posts( $data );
820
  $post_set['term'] = $this->get_account_term( $term_and_params );
821
 
822
  $new_post_sets[] = $post_set;
823
  }
824
+ $next_page = $new_connection->get_next_page();
825
  if ( ! empty( $next_page ) ) {
826
  $next_pages[ $term . '_' . $type ] = $next_page;
827
+ $next_page_found = true;
828
  } else {
829
  $next_pages[ $term . '_' . $type ] = false;
830
  }
846
  if ( $connection->is_wp_error() ) {
847
  SB_Instagram_API_Connect::handle_wp_remote_get_error( $error );
848
  } else {
849
+ SB_Instagram_API_Connect::handle_instagram_error( $error, $connected_accounts_for_feed[ $term ] );
850
  }
851
  $next_pages[ $term . '_' . $type ] = false;
852
 
855
  if ( $connection->is_wp_error() ) {
856
  SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() );
857
  } else {
858
+ SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $term ] );
859
  }
860
 
861
  $next_pages[ $term . '_' . $type ] = false;
862
  }
863
  }
864
  }
 
865
  }
866
  }
867
 
868
+ if ( ! $one_successful_connection || ( $one_api_request_delayed && empty( $new_post_sets ) ) ) {
869
  $this->should_use_backup = true;
870
  }
871
  $posts = $this->merge_posts( $new_post_sets, $settings );
912
  */
913
  public function set_remote_header_data( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) {
914
  $first_user = $this->get_first_user( $feed_types_and_terms );
915
+
916
+ if ( ! empty( $settings['headersource'] ) ) {
917
+ foreach ( $connected_accounts_for_feed as $connected_account ) {
918
+ if ( $connected_account['username'] === $settings['headersource'] ) {
919
+ $first_user = $connected_account['user_id'];
920
+ } elseif ( $connected_account['user_id'] === $settings['headersource'] ) {
921
+ $first_user = $connected_account['user_id'];
922
+ }
923
+ }
924
+ }
925
+
926
  $this->header_data = false;
927
  global $sb_instagram_posts_manager;
928
 
939
  $sb_instagram_posts_manager->remove_error( 'connection', $connected_accounts_for_feed[ $first_user ] );
940
 
941
  if ( isset( $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) && $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) {
942
+ $upload = wp_upload_dir();
943
  $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
944
 
945
+ $full_file_name = $resized_url . $this->header_data['username'] . '.jpg';
946
  $this->header_data['local_avatar'] = $full_file_name;
947
  } else {
948
+ if ( ! $sb_instagram_posts_manager->image_resizing_disabled( $feed_types_and_terms ) && ! isset( $connected_accounts_for_feed[ $first_user ]['local_avatar'] ) ) {
949
  if ( sbi_store_local_avatar( $connected_accounts_for_feed[ $first_user ] ) ) {
950
+ $upload = wp_upload_dir();
951
  $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
952
 
953
+ $full_file_name = $resized_url . $this->header_data['username'] . '.jpg';
954
  $this->header_data['local_avatar'] = $full_file_name;
955
  }
956
  }
957
  }
958
  if ( empty( $this->header_data['bio'] )
959
+ && isset( $connected_accounts_for_feed[ $first_user ]['bio'] ) ) {
960
 
961
  $this->header_data['bio'] = sbi_decode_emoji( $connected_accounts_for_feed[ $first_user ]['bio'] );
962
  }
966
  if ( $connection->is_wp_error() ) {
967
  SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() );
968
  } else {
969
+ SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $first_user ] );
970
  }
971
  }
972
  }
988
  $this->trim_posts_to_max();
989
 
990
  $to_cache = array(
991
+ 'data' => $this->post_data,
992
+ 'pagination' => $this->next_pages,
993
+ 'pages_created' => $this->pages_created,
994
  );
995
 
996
  global $sb_instagram_posts_manager;
1012
  }
1013
  update_option( $this->backup_feed_transient_name, $encrypted, false );
1014
  }
 
1015
  } else {
1016
  $this->add_report( 'no data not caching' );
1017
  }
1030
  */
1031
  public function set_cron_cache( $to_cache, $cache_time, $save_backup = true ) {
1032
  if ( ! empty( $this->post_data )
1033
+ || ! empty( $this->next_pages )
1034
+ || ! empty( $to_cache['data'] )
1035
+ || $this->should_cache_error() ) {
1036
  $this->remove_duplicate_posts();
1037
  $this->trim_posts_to_max();
1038
 
1039
+ $to_cache['data'] = isset( $to_cache['data'] ) ? $to_cache['data'] : $this->post_data;
1040
+ $to_cache['pagination'] = isset( $to_cache['next_pages'] ) ? $to_cache['next_pages'] : $this->next_pages;
1041
+ $to_cache['atts'] = isset( $to_cache['atts'] ) ? $to_cache['atts'] : $this->transient_atts;
1042
  $to_cache['last_requested'] = isset( $to_cache['last_requested'] ) ? $to_cache['last_requested'] : time();
1043
+ $to_cache['last_retrieve'] = isset( $to_cache['last_retrieve'] ) ? $to_cache['last_retrieve'] : $this->last_retrieve;
1044
 
1045
  global $sb_instagram_posts_manager;
1046
 
1057
 
1058
  if ( $save_backup ) {
1059
  if ( ! empty( $this->post_data )
1060
+ || ! empty( $this->next_pages )
1061
+ || ! empty( $to_cache['data'] ) ) {
1062
  if ( isset( $to_cache['errors'] ) ) {
1063
  unset( $to_cache['errors'] );
1064
  }
1102
  * @since 2.0/5.0
1103
  */
1104
  public function should_update_last_requested() {
1105
+ return ( rand( 1, 20 ) === 20 );
1106
  }
1107
 
1108
  /**
1119
  if ( $settings['minnum'] < 1 ) {
1120
  return false;
1121
  }
1122
+ $posts_available = count( $this->post_data ) - ( $offset + $settings['num'] );
1123
+ $show_loadmore_button_by_settings = ( $settings['showbutton'] === 'on' || $settings['showbutton'] === 'true' || $settings['showbutton'] === true ) && $settings['showbutton'] !== 'false';
1124
 
1125
  if ( $show_loadmore_button_by_settings ) {
1126
  // used for permanent and whitelist feeds
1127
+ if ( $this->feed_is_complete() ) {
1128
  $this->add_report( 'no pagination, feed complete' );
1129
  return false;
1130
  }
1141
  }
1142
  }
1143
  }
 
1144
  }
1145
 
 
1146
  $this->add_report( 'no pagination, no posts available' );
1147
 
1148
  return false;
1168
  global $sb_instagram_posts_manager;
1169
 
1170
  if ( empty( $this->post_data ) && ! empty( $connected_accounts_for_feed ) && $settings['minnum'] > 0 ) {
1171
+ $this->handle_no_posts_found();
1172
  }
1173
+ $posts = array_slice( $this->post_data, 0, $settings['minnum'] );
1174
  $header_data = ! empty( $this->header_data ) ? $this->header_data : false;
1175
 
1176
+ $first_user = ! empty( $feed_types_and_terms['users'][0] ) ? $feed_types_and_terms['users'][0]['term'] : false;
1177
  $first_username = false;
1178
  if ( $first_user ) {
1179
  $first_username = isset( $connected_accounts_for_feed[ $first_user ]['username'] ) ? $connected_accounts_for_feed[ $first_user ]['username'] : $first_user;
1184
  }
1185
  $use_pagination = $this->should_use_pagination( $settings, 0 );
1186
 
1187
+ $feed_id = $this->regular_feed_transient_name;
1188
  $shortcode_atts = ! empty( $atts ) ? sbi_json_encode( $atts ) : '{}';
1189
 
1190
  $settings['header_outside'] = false;
1191
+ $settings['header_inside'] = false;
1192
  if ( $header_data && $settings['showheader'] ) {
1193
  $settings['header_inside'] = true;
1194
  }
1196
  $other_atts = '';
1197
 
1198
  $classes = array();
1199
+ if ( empty( $settings['widthresp'] ) || $settings['widthresp'] === 'on' || $settings['widthresp'] === 'true' || $settings['widthresp'] === true ) {
1200
  if ( $settings['widthresp'] !== 'false' ) {
1201
  $classes[] = 'sbi_width_resp';
1202
  }
1205
  $classes[] = esc_attr( $settings['class'] );
1206
  }
1207
  if ( ! empty( $settings['height'] )
1208
+ && ( ( (int) $settings['height'] < 100 && $settings['heightunit'] === '%' ) || $settings['heightunit'] === 'px' ) ) {
1209
  $classes[] = 'sbi_fixed_height';
1210
  }
1211
  if ( ! empty( $settings['disablemobile'] )
1212
+ && ( $settings['disablemobile'] === 'on' || $settings['disablemobile'] === 'true' || $settings['disablemobile'] === true ) ) {
1213
  if ( $settings['disablemobile'] !== 'false' ) {
1214
  $classes[] = 'sbi_disable_mobile';
1215
  }
1223
  $other_atts .= ' data-postid="' . esc_attr( get_the_ID() ) . '"';
1224
  $other_atts .= ' data-locatornonce="' . esc_attr( wp_create_nonce( 'sbi-locator-nonce-' . get_the_ID() . '-' . $this->regular_feed_transient_name ) ) . '"';
1225
 
1226
+ $other_atts = $this->add_other_atts( $other_atts );
1227
 
1228
  $flags = array();
1229
 
1246
  }
1247
  }
1248
  if ( ! $settings['isgutenberg']
1249
+ && SB_Instagram_Feed_Locator::should_do_ajax_locating( $this->regular_feed_transient_name, get_the_ID() ) ) {
1250
  $this->add_report( 'doing feed locating' );
1251
  $flags[] = 'locator';
1252
  }
1253
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1254
  if ( isset( $_GET['sbi_debug'] ) ) {
1255
  $flags[] = 'debug';
1256
  }
1258
  $flags = apply_filters( 'sbi_flags', $flags, $settings );
1259
 
1260
  if ( ! empty( $flags ) ) {
1261
+ $other_atts .= ' data-sbi-flags="' . implode( ',', $flags ) . '"';
1262
  }
1263
 
1264
  ob_start();
1287
  *
1288
  * @since 2.0/5.0
1289
  */
1290
+ public function get_the_items_html( $settings, $offset ) {
1291
  if ( empty( $this->post_data ) ) {
1292
  ob_start();
1293
  $html = ob_get_contents();
1294
+ ob_get_clean(); ?>
1295
+ <p><?php esc_html_e( 'No posts found.', 'instagram-feed' ); ?></p>
1296
  <?php
1297
  $html = ob_get_contents();
1298
  ob_get_clean();
1316
  *
1317
  * @return object
1318
  */
1319
+ public function make_api_connection( $connected_account_or_page, $type = null, $params = null ) {
1320
  return new SB_Instagram_API_Connect( $connected_account_or_page, $type, $params );
1321
  }
1322
 
1335
  }
1336
  $sbi_options = sbi_get_database_settings();
1337
  $font_method = 'svg';
1338
+ $upload = wp_upload_dir();
1339
  $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
1340
 
1341
  $js_options = array(
1342
  'font_method' => $font_method,
1343
  'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png',
1344
+ 'resized_url' => $resized_url,
1345
  );
1346
 
1347
  $encoded_options = sbi_json_encode( $js_options );
1348
 
1349
+ $js_option_html = '<script type="text/javascript">var sb_instagram_js_options = ' . $encoded_options . ';</script>';
1350
  $js_option_html .= "<script type='text/javascript' src='" . trailingslashit( SBI_PLUGIN_URL ) . 'js/sbi-scripts.min.js?ver=' . SBIVER . "'></script>";
1351
 
1352
  return $js_option_html;
1402
  *
1403
  * @return string
1404
  */
1405
+ protected function add_other_atts( $other_atts ) {
1406
  return $other_atts;
1407
  }
1408
 
1417
  *
1418
  * @since 2.0/5.0
1419
  */
1420
+ protected function filter_posts( $post_set ) {
 
 
1421
  return $post_set;
1422
  }
1423
 
1424
+ protected function handle_no_posts_found() {
1425
  global $sb_instagram_posts_manager;
1426
 
1427
  $error_message_return = array(
1428
+ 'error_message' => __( 'Error: No posts found.', 'instagram-feed' ),
1429
+ 'admin_only' => __( 'Make sure this account has posts available on instagram.com.', 'instagram-feed' ),
1430
  'frontend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
1431
+ 'backend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
1432
  );
1433
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
1434
  }
1435
 
1436
  protected function remove_duplicate_posts() {
1437
+ $posts = $this->post_data;
1438
+ $ids_in_feed = array();
1439
  $non_duplicate_posts = array();
1440
+ $removed = array();
1441
 
1442
  foreach ( $posts as $post ) {
1443
  $post_id = SB_Instagram_Parse::get_post_id( $post );
1444
  if ( ! in_array( $post_id, $ids_in_feed, true ) ) {
1445
+ $ids_in_feed[] = $post_id;
1446
  $non_duplicate_posts[] = $post;
1447
  } else {
1448
  $removed[] = $post_id;
1449
  }
1450
  }
1451
 
1452
+ $this->add_report( 'removed duplicates: ' . implode( ', ', $removed ) );
1453
  $this->set_post_data( $non_duplicate_posts );
1454
  }
1455
 
1464
  }
1465
 
1466
  $max = apply_filters( 'sbi_max_cache_size', 500 );
1467
+ $this->set_post_data( array_slice( $this->post_data, 0, $max ) );
1468
 
1469
  }
1470
 
1481
  *
1482
  * @since 2.0/5.0
1483
  */
1484
+ protected function feed_is_complete() {
1485
  return false;
1486
  }
1487
 
1492
  */
1493
  private function clear_expired_access_token_notice( $connected_account_for_term ) {
1494
  $sbi_options = get_option( 'sb_instagram_settings' );
1495
+ $ca_to_save = isset( $sbi_options['connected_accounts'] ) ? $sbi_options['connected_accounts'] : array();
1496
 
1497
  if ( ! empty( $ca_to_save ) && ! empty( $connected_account_for_term ) ) {
1498
 
1521
  */
1522
  private function posts_loop( $posts, $settings, $offset = 0 ) {
1523
 
1524
+ $image_ids = array();
1525
+ $post_index = $offset;
1526
+ $icon_type = 'svg';
1527
  $resized_images = $this->get_resized_images();
1528
 
1529
  foreach ( $posts as $post ) {
1530
+ $image_ids[] = SB_Instagram_Parse::get_post_id( $post );
1531
  $account_type = SB_Instagram_Parse::get_account_type( $post );
1532
  include sbi_get_feed_template_part( 'item', $settings );
1533
  $post_index++;
1563
 
1564
  $merged_posts = array();
1565
  if ( $settings['sortby'] === 'alternate'
1566
+ || $settings['sortby'] === 'api' && isset( $post_sets[1] ) ) {
1567
  // don't bother merging posts if there is only one post set
1568
  if ( isset( $post_sets[1] ) ) {
1569
+ $min_cycles = $settings['sortby'] === 'api' ? min( 200 / count( $post_sets ) + 5, 50 ) : max( 1, (int) $settings['minnum'] );
1570
+ $terms = array();
1571
+ for ( $i = 0; $i <= $min_cycles; $i++ ) {
1572
  $ii = 0;
1573
  foreach ( $post_sets as $post_set ) {
1574
  if ( isset( $post_sets[ $ii ]['term'] ) ) {
1588
  }
1589
  if ( isset( $post_set[ $i ] ) && isset( $post_set[ $i ]['id'] ) ) {
1590
  $post_set[ $i ]['term'] = $terms[ $ii ];
1591
+ $merged_posts[] = $post_set[ $i ];
1592
  }
1593
  $ii++;
1594
  }
1643
  if ( isset( $post_sets[1] ) ) {
1644
 
1645
  $terms = array();
1646
+ $ii = 0;
1647
  foreach ( $post_sets as $post_set ) {
1648
  if ( isset( $post_set[0]['id'] ) ) {
1649
  if ( isset( $post_sets[ $ii ]['term'] ) ) {
1703
  'alternate',
1704
  'api',
1705
  'random',
1706
+ 'likes',
1707
  );
1708
 
1709
  if ( ! in_array( $settings['sortby'], $merge_befores, true ) ) {
1738
  $return_post_set = $post_set;
1739
  } elseif ( $settings['sortby'] === 'random' ) {
1740
  /*
1741
+ * randomly selects posts in a random order. Cache saves posts
1742
+ * in this random order so paginating does not cause some posts to show up
1743
+ * twice or not at all
1744
+ */
1745
+ usort( $post_set, 'sbi_rand_sort' );
1746
  $return_post_set = $post_set;
1747
 
1748
  } else {
1749
  // compares posted on dates of posts
1750
+ usort( $post_set, 'sbi_date_sort' );
1751
  $return_post_set = $post_set;
1752
  }
1753
 
1776
  *
1777
  * @since 2.0/5.1.1
1778
  */
1779
+ protected function can_try_another_request() {
1780
  return false;
1781
  }
1782
 
1792
  *
1793
  * @since 2.0/5.1.1
1794
  */
1795
+ protected function get_different_connected_account() {
1796
  return false;
1797
  }
1798
 
1799
+ }
inc/class-sb-instagram-gdpr-integrations.php CHANGED
@@ -32,10 +32,10 @@ class SB_Instagram_GDPR_Integrations {
32
  */
33
  public static function undo_script_blocking( $blocking ) {
34
  $settings = sbi_get_database_settings();
35
- if ( ! SB_Instagram_GDPR_Integrations::doing_gdpr( $settings ) ) {
36
  return $blocking;
37
  }
38
- unset($blocking['instagram-feed']);
39
  return $blocking;
40
  }
41
 
@@ -58,7 +58,7 @@ class SB_Instagram_GDPR_Integrations {
58
  if ( class_exists( 'COMPLIANZ' ) ) {
59
  return 'Complianz by Really Simple Plugins';
60
  }
61
- if ( function_exists('BorlabsCookieHelper') ) {
62
  return 'Borlabs Cookie by Borlabs';
63
  }
64
 
@@ -81,7 +81,7 @@ class SB_Instagram_GDPR_Integrations {
81
  if ( $gdpr === 'yes' ) {
82
  return true;
83
  }
84
- return (SB_Instagram_GDPR_Integrations::gdpr_plugins_active() !== false);
85
  }
86
 
87
  public static function blocking_cdn( $settings ) {
@@ -95,7 +95,7 @@ class SB_Instagram_GDPR_Integrations {
95
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
96
 
97
  if ( $sbi_statuses_option['gdpr']['from_update_success'] ) {
98
- return (SB_Instagram_GDPR_Integrations::gdpr_plugins_active() !== false);
99
  }
100
  return false;
101
  }
@@ -149,14 +149,14 @@ class SB_Instagram_GDPR_Integrations {
149
  }
150
 
151
  global $wpdb;
152
- $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE );
153
  $sbi_statuses_option['gdpr']['tables'] = true;
154
- if ( $wpdb->get_var( "show tables like '$table_name'" ) != $table_name ) {
155
  $sbi_statuses_option['gdpr']['tables'] = false;
156
  }
157
 
158
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
159
- if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) != $feeds_posts_table_name ) {
160
  $sbi_statuses_option['gdpr']['tables'] = false;
161
  }
162
 
@@ -169,8 +169,8 @@ class SB_Instagram_GDPR_Integrations {
169
  }
170
 
171
  if ( ! $sbi_statuses_option['gdpr']['upload_dir']
172
- || ! $sbi_statuses_option['gdpr']['tables']
173
- || ! $sbi_statuses_option['gdpr']['image_editor'] ) {
174
  return false;
175
  }
176
 
@@ -182,18 +182,19 @@ class SB_Instagram_GDPR_Integrations {
182
 
183
  $errors = array();
184
  if ( ! $sbi_statuses_option['gdpr']['upload_dir'] ) {
185
- $errors[] = __( 'A folder for storing resized images was not successfully created.' );
186
  }
187
  if ( ! $sbi_statuses_option['gdpr']['tables'] ) {
188
  $errors[] = __( 'Tables used for storing information about resized images were not successfully created.' );
189
  }
190
  if ( ! $sbi_statuses_option['gdpr']['image_editor'] ) {
191
- $errors[] = sprintf( __( 'An image editor is not available on your server. Instagram Feed is unable to create local resized images. See %sthis FAQ%s for more information' ), '<a href="https://smashballoon.com/doc/the-images-in-my-feed-are-missing-or-showing-errors/" target="_blank" rel="noopener noreferrer">','</a>' );
192
  }
193
 
 
194
  if ( isset( $_GET['tab'] ) && $_GET['tab'] !== 'support' ) {
195
- $tab = sbi_is_pro_version() ? 'customize-advanced' : 'customize';
196
- $errors[] = '<a href="?page=sb-instagram-feed&amp;tab='.$tab.'&amp;retest=1" class="button button-secondary">' . __( 'Retest', 'instagram-feed' ) . '</a>';
197
  }
198
 
199
  return implode( '<br>', $errors );
@@ -206,4 +207,4 @@ class SB_Instagram_GDPR_Integrations {
206
  return $return;
207
  }
208
 
209
- }
32
  */
33
  public static function undo_script_blocking( $blocking ) {
34
  $settings = sbi_get_database_settings();
35
+ if ( ! self::doing_gdpr( $settings ) ) {
36
  return $blocking;
37
  }
38
+ unset( $blocking['instagram-feed'] );
39
  return $blocking;
40
  }
41
 
58
  if ( class_exists( 'COMPLIANZ' ) ) {
59
  return 'Complianz by Really Simple Plugins';
60
  }
61
+ if ( function_exists( 'BorlabsCookieHelper' ) ) {
62
  return 'Borlabs Cookie by Borlabs';
63
  }
64
 
81
  if ( $gdpr === 'yes' ) {
82
  return true;
83
  }
84
+ return ( self::gdpr_plugins_active() !== false );
85
  }
86
 
87
  public static function blocking_cdn( $settings ) {
95
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
96
 
97
  if ( $sbi_statuses_option['gdpr']['from_update_success'] ) {
98
+ return ( self::gdpr_plugins_active() !== false );
99
  }
100
  return false;
101
  }
149
  }
150
 
151
  global $wpdb;
152
+ $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE );
153
  $sbi_statuses_option['gdpr']['tables'] = true;
154
+ if ( $wpdb->get_var( "show tables like '$table_name'" ) !== $table_name ) {
155
  $sbi_statuses_option['gdpr']['tables'] = false;
156
  }
157
 
158
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
159
+ if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) !== $feeds_posts_table_name ) {
160
  $sbi_statuses_option['gdpr']['tables'] = false;
161
  }
162
 
169
  }
170
 
171
  if ( ! $sbi_statuses_option['gdpr']['upload_dir']
172
+ || ! $sbi_statuses_option['gdpr']['tables']
173
+ || ! $sbi_statuses_option['gdpr']['image_editor'] ) {
174
  return false;
175
  }
176
 
182
 
183
  $errors = array();
184
  if ( ! $sbi_statuses_option['gdpr']['upload_dir'] ) {
185
+ $errors[] = __( 'A folder for storing resized images was not successfully created.' );
186
  }
187
  if ( ! $sbi_statuses_option['gdpr']['tables'] ) {
188
  $errors[] = __( 'Tables used for storing information about resized images were not successfully created.' );
189
  }
190
  if ( ! $sbi_statuses_option['gdpr']['image_editor'] ) {
191
+ $errors[] = sprintf( __( 'An image editor is not available on your server. Instagram Feed is unable to create local resized images. See %1$sthis FAQ%2$s for more information' ), '<a href="https://smashballoon.com/doc/the-images-in-my-feed-are-missing-or-showing-errors/" target="_blank" rel="noopener noreferrer">', '</a>' );
192
  }
193
 
194
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
195
  if ( isset( $_GET['tab'] ) && $_GET['tab'] !== 'support' ) {
196
+ $tab = sbi_is_pro_version() ? 'customize-advanced' : 'customize';
197
+ $errors[] = '<a href="?page=sb-instagram-feed&amp;tab=' . esc_attr( $tab ) . '&amp;retest=1" class="button button-secondary">' . __( 'Retest', 'instagram-feed' ) . '</a>';
198
  }
199
 
200
  return implode( '<br>', $errors );
207
  return $return;
208
  }
209
 
210
+ }
inc/class-sb-instagram-oembed.php CHANGED
@@ -12,8 +12,8 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  die( '-1' );
13
  }
14
 
15
- class SB_Instagram_Oembed
16
- {
17
  /**
18
  * SB_Instagram_Oembed constructor.
19
  *
@@ -23,15 +23,15 @@ class SB_Instagram_Oembed
23
  * @since 2.5/5.8
24
  */
25
  public function __construct() {
26
- if ( SB_Instagram_Oembed::can_do_oembed() ) {
27
- if ( SB_Instagram_Oembed::can_check_for_old_oembeds() ) {
28
  add_action( 'the_post', array( 'SB_Instagram_Oembed', 'check_page_for_old_oembeds' ) );
29
  }
30
  add_filter( 'oembed_providers', array( 'SB_Instagram_Oembed', 'oembed_providers' ), 10, 1 );
31
  add_filter( 'oembed_fetch_url', array( 'SB_Instagram_Oembed', 'oembed_set_fetch_url' ), 10, 3 );
32
  add_filter( 'oembed_result', array( 'SB_Instagram_Oembed', 'oembed_result' ), 10, 3 );
33
  }
34
- if ( SB_Instagram_Oembed::should_extend_ttl() ) {
35
  add_filter( 'oembed_ttl', array( 'SB_Instagram_Oembed', 'oembed_ttl' ), 10, 4 );
36
  }
37
  }
@@ -51,7 +51,7 @@ class SB_Instagram_Oembed
51
  return false;
52
  }
53
 
54
- $access_token = SB_Instagram_Oembed::last_access_token();
55
  if ( ! $access_token ) {
56
  return false;
57
  }
@@ -75,7 +75,7 @@ class SB_Instagram_Oembed
75
  return false;
76
  }
77
 
78
- $will_expire = SB_Instagram_Oembed::oembed_access_token_will_expire();
79
  if ( $will_expire ) {
80
  return true;
81
  }
@@ -110,7 +110,7 @@ class SB_Instagram_Oembed
110
  * @since 2.5/5.8
111
  */
112
  public static function oembed_providers( $providers ) {
113
- $oembed_url = SB_Instagram_Oembed::oembed_url();
114
  if ( $oembed_url ) {
115
  $providers['#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i'] = array( $oembed_url, true );
116
  // for WP 4.9
@@ -132,12 +132,18 @@ class SB_Instagram_Oembed
132
  *
133
  * @since 2.5/5.8
134
  */
135
- public static function oembed_set_fetch_url( $provider, $url, $args ) {
136
  $access_token = SB_Instagram_Oembed::last_access_token();
 
137
  if ( ! $access_token ) {
138
  return $provider;
139
  }
140
 
 
 
 
 
 
141
  if ( strpos( $provider, 'instagram_oembed' ) !== false ) {
142
  if ( strpos( $url, '?' ) !== false ) {
143
  $exploded = explode( '?', $url );
@@ -145,6 +151,7 @@ class SB_Instagram_Oembed
145
  $provider = str_replace( urlencode( '?' . $exploded[1] ), '', $provider );
146
  }
147
  }
 
148
  $provider = add_query_arg( 'access_token', $access_token, $provider );
149
  }
150
 
@@ -163,7 +170,7 @@ class SB_Instagram_Oembed
163
  *
164
  * @since 2.5/5.8
165
  */
166
- public static function oembed_result( $html, $url, $args ) {
167
  if ( preg_match( '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i', $url ) === 1 ) {
168
  if ( strpos( $html, 'class="instagram-media"' ) !== false ) {
169
  $html = '<div class="sbi-embed-wrap">' . str_replace( 'class="instagram-media"', 'class="instagram-media sbi-embed"', $html ) . '</div>';
@@ -185,7 +192,7 @@ class SB_Instagram_Oembed
185
  *
186
  * @since 2.5/5.8
187
  */
188
- public static function oembed_ttl( $ttl, $url, $attr, $post_ID ) {
189
  if ( preg_match( '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i', $url ) === 1 ) {
190
  $ttl = 30 * YEAR_IN_SECONDS;
191
  }
@@ -215,9 +222,8 @@ class SB_Instagram_Oembed
215
  */
216
  public static function last_access_token() {
217
  $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
218
- $will_expire = SB_Instagram_Oembed::oembed_access_token_will_expire();
219
- if ( ! empty( $oembed_token_settings['access_token'] )
220
- && (! $will_expire || $will_expire > time()) ) {
221
  $return = sbi_maybe_clean( $oembed_token_settings['access_token'] );
222
  return $return;
223
  } else {
@@ -231,7 +237,6 @@ class SB_Instagram_Oembed
231
  $oembed_token_settings['access_token'] = $connected_account['access_token'];
232
  }
233
  }
234
-
235
  }
236
  }
237
 
@@ -259,7 +264,7 @@ class SB_Instagram_Oembed
259
  */
260
  public static function oembed_access_token_will_expire() {
261
  $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
262
- $will_expire = isset( $oembed_token_settings['expiration_date'] ) && (int)$oembed_token_settings['expiration_date'] > 0 ? (int)$oembed_token_settings['expiration_date'] : false;
263
 
264
  return $will_expire;
265
  }
@@ -284,11 +289,11 @@ class SB_Instagram_Oembed
284
  return;
285
  }
286
 
287
- $done_checking = (int)get_post_meta( $post_ID, '_sbi_oembed_done_checking', true ) === 1;
288
 
289
  if ( ! $done_checking ) {
290
 
291
- $num_found = SB_Instagram_Oembed::delete_instagram_oembed_caches( $post_ID );
292
  if ( $num_found === 0 ) {
293
  update_post_meta( $post_ID, '_sbi_oembed_done_checking', 1 );
294
  }
@@ -315,7 +320,7 @@ class SB_Instagram_Oembed
315
  foreach ( $post_metas as $post_meta_key => $post_meta_value ) {
316
  if ( '_oembed_' === substr( $post_meta_key, 0, 8 ) ) {
317
  if ( strpos( $post_meta_value[0], 'class="instagram-media"' ) !== false
318
- && strpos( $post_meta_value[0], 'sbi-embed-wrap' ) === false ) {
319
  $total_found++;
320
  delete_post_meta( $post_ID, $post_meta_key );
321
  if ( '_oembed_time_' !== substr( $post_meta_key, 0, 13 ) ) {
@@ -335,11 +340,13 @@ class SB_Instagram_Oembed
335
  */
336
  public static function clear_checks() {
337
  global $wpdb;
338
- $table_name = esc_sql( $wpdb->prefix . "postmeta" );
339
- $result = $wpdb->query("
 
340
  DELETE
341
  FROM $table_name
342
- WHERE meta_key = '_sbi_oembed_done_checking';");
 
343
  }
344
  }
345
 
12
  die( '-1' );
13
  }
14
 
15
+ class SB_Instagram_Oembed {
16
+
17
  /**
18
  * SB_Instagram_Oembed constructor.
19
  *
23
  * @since 2.5/5.8
24
  */
25
  public function __construct() {
26
+ if ( self::can_do_oembed() ) {
27
+ if ( self::can_check_for_old_oembeds() ) {
28
  add_action( 'the_post', array( 'SB_Instagram_Oembed', 'check_page_for_old_oembeds' ) );
29
  }
30
  add_filter( 'oembed_providers', array( 'SB_Instagram_Oembed', 'oembed_providers' ), 10, 1 );
31
  add_filter( 'oembed_fetch_url', array( 'SB_Instagram_Oembed', 'oembed_set_fetch_url' ), 10, 3 );
32
  add_filter( 'oembed_result', array( 'SB_Instagram_Oembed', 'oembed_result' ), 10, 3 );
33
  }
34
+ if ( self::should_extend_ttl() ) {
35
  add_filter( 'oembed_ttl', array( 'SB_Instagram_Oembed', 'oembed_ttl' ), 10, 4 );
36
  }
37
  }
51
  return false;
52
  }
53
 
54
+ $access_token = self::last_access_token();
55
  if ( ! $access_token ) {
56
  return false;
57
  }
75
  return false;
76
  }
77
 
78
+ $will_expire = self::oembed_access_token_will_expire();
79
  if ( $will_expire ) {
80
  return true;
81
  }
110
  * @since 2.5/5.8
111
  */
112
  public static function oembed_providers( $providers ) {
113
+ $oembed_url = self::oembed_url();
114
  if ( $oembed_url ) {
115
  $providers['#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i'] = array( $oembed_url, true );
116
  // for WP 4.9
132
  *
133
  * @since 2.5/5.8
134
  */
135
+ public static function oembed_set_fetch_url( $provider, $url ) {
136
  $access_token = SB_Instagram_Oembed::last_access_token();
137
+
138
  if ( ! $access_token ) {
139
  return $provider;
140
  }
141
 
142
+ $encryption = new SB_Instagram_Data_Encryption();
143
+ if ( $access_token && $encryption->decrypt( $access_token ) ) {
144
+ $access_token = $encryption->decrypt( $access_token );
145
+ }
146
+
147
  if ( strpos( $provider, 'instagram_oembed' ) !== false ) {
148
  if ( strpos( $url, '?' ) !== false ) {
149
  $exploded = explode( '?', $url );
151
  $provider = str_replace( urlencode( '?' . $exploded[1] ), '', $provider );
152
  }
153
  }
154
+
155
  $provider = add_query_arg( 'access_token', $access_token, $provider );
156
  }
157
 
170
  *
171
  * @since 2.5/5.8
172
  */
173
+ public static function oembed_result( $html, $url ) {
174
  if ( preg_match( '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i', $url ) === 1 ) {
175
  if ( strpos( $html, 'class="instagram-media"' ) !== false ) {
176
  $html = '<div class="sbi-embed-wrap">' . str_replace( 'class="instagram-media"', 'class="instagram-media sbi-embed"', $html ) . '</div>';
192
  *
193
  * @since 2.5/5.8
194
  */
195
+ public static function oembed_ttl( $ttl, $url ) {
196
  if ( preg_match( '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i', $url ) === 1 ) {
197
  $ttl = 30 * YEAR_IN_SECONDS;
198
  }
222
  */
223
  public static function last_access_token() {
224
  $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
225
+ $will_expire = self::oembed_access_token_will_expire();
226
+ if ( ! empty( $oembed_token_settings['access_token'] ) && ( ! $will_expire || $will_expire > time() ) ) {
 
227
  $return = sbi_maybe_clean( $oembed_token_settings['access_token'] );
228
  return $return;
229
  } else {
237
  $oembed_token_settings['access_token'] = $connected_account['access_token'];
238
  }
239
  }
 
240
  }
241
  }
242
 
264
  */
265
  public static function oembed_access_token_will_expire() {
266
  $oembed_token_settings = get_option( 'sbi_oembed_token', array() );
267
+ $will_expire = isset( $oembed_token_settings['expiration_date'] ) && (int) $oembed_token_settings['expiration_date'] > 0 ? (int) $oembed_token_settings['expiration_date'] : false;
268
 
269
  return $will_expire;
270
  }
289
  return;
290
  }
291
 
292
+ $done_checking = (int) get_post_meta( $post_ID, '_sbi_oembed_done_checking', true ) === 1;
293
 
294
  if ( ! $done_checking ) {
295
 
296
+ $num_found = self::delete_instagram_oembed_caches( $post_ID );
297
  if ( $num_found === 0 ) {
298
  update_post_meta( $post_ID, '_sbi_oembed_done_checking', 1 );
299
  }
320
  foreach ( $post_metas as $post_meta_key => $post_meta_value ) {
321
  if ( '_oembed_' === substr( $post_meta_key, 0, 8 ) ) {
322
  if ( strpos( $post_meta_value[0], 'class="instagram-media"' ) !== false
323
+ && strpos( $post_meta_value[0], 'sbi-embed-wrap' ) === false ) {
324
  $total_found++;
325
  delete_post_meta( $post_ID, $post_meta_key );
326
  if ( '_oembed_time_' !== substr( $post_meta_key, 0, 13 ) ) {
340
  */
341
  public static function clear_checks() {
342
  global $wpdb;
343
+ $table_name = esc_sql( $wpdb->prefix . 'postmeta' );
344
+ $result = $wpdb->query(
345
+ "
346
  DELETE
347
  FROM $table_name
348
+ WHERE meta_key = '_sbi_oembed_done_checking';"
349
+ );
350
  }
351
  }
352
 
inc/class-sb-instagram-parse.php CHANGED
@@ -14,8 +14,8 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  die( '-1' );
15
  }
16
 
17
- class SB_Instagram_Parse
18
- {
19
  /**
20
  * @param $post array
21
  *
@@ -35,7 +35,7 @@ class SB_Instagram_Parse
35
  * @since 2.0/5.0
36
  */
37
  public static function get_account_type( $post ) {
38
- if (isset( $post['media_type'] ) ) {
39
  return 'business';
40
  } else {
41
  return 'personal';
@@ -53,10 +53,10 @@ class SB_Instagram_Parse
53
  $timestamp = 0;
54
  if ( isset( $post['created_time'] ) ) {
55
  $timestamp = $post['created_time'];
56
- } else if ( isset( $post['timestamp'] ) ) {
57
  // some date formatting functions have trouble with the "T", "+", and extra zeroes added by Instagram
58
- $remove_plus = trim( str_replace( array('T', '+', ' 0000' ), ' ', $post['timestamp'] ) );
59
- $timestamp = strtotime( $remove_plus );
60
  }
61
 
62
  return $timestamp;
@@ -74,7 +74,7 @@ class SB_Instagram_Parse
74
  return $post['type'];
75
  }
76
 
77
- return strtolower( str_replace( '_ALBUM','', $post['media_type'] ) );
78
  }
79
 
80
  /**
@@ -100,22 +100,22 @@ class SB_Instagram_Parse
100
  *
101
  * @since 2.0/5.0
102
  */
103
- public static function get_media_url( $post, $resolution = 'lightbox' ) {
104
  $account_type = isset( $post['images'] ) ? 'personal' : 'business';
105
- $media_type = isset( $post['media_type'] ) ? $post['media_type'] : 'none';
106
 
107
  if ( $account_type === 'personal' ) {
108
  return $post['images']['standard_resolution']['url'];
109
  } else {
110
  if ( $media_type === 'CAROUSEL_ALBUM'
111
- || $media_type === 'VIDEO'
112
- || $media_type === 'OEMBED' ) {
113
  if ( isset( $post['thumbnail_url'] ) ) {
114
  return $post['thumbnail_url'];
115
  } elseif ( $media_type === 'CAROUSEL_ALBUM' && isset( $post['media_url'] ) ) {
116
  return $post['media_url'];
117
  } elseif ( isset( $post['children'] ) ) {
118
- $i = 0;
119
  $full_size = '';
120
  foreach ( $post['children']['data'] as $carousel_item ) {
121
  if ( $carousel_item['media_type'] === 'IMAGE' && empty( $full_size ) ) {
@@ -128,8 +128,8 @@ class SB_Instagram_Parse
128
  } else {
129
  $media = trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png';
130
  //attempt to get
131
- $permalink = SB_Instagram_Parse::fix_permalink( SB_Instagram_Parse::get_permalink( $carousel_item ) );
132
- $single = new SB_Instagram_Single( $permalink );
133
  $single->init();
134
  $carousel_item_post = $single->get_post();
135
 
@@ -150,8 +150,8 @@ class SB_Instagram_Parse
150
  return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png';
151
  }
152
  //attempt to get
153
- $permalink = SB_Instagram_Parse::fix_permalink( SB_Instagram_Parse::get_permalink( $post ) );
154
- $single = new SB_Instagram_Single( $permalink );
155
  $single->init();
156
  $post = $single->get_post();
157
 
@@ -189,12 +189,12 @@ class SB_Instagram_Parse
189
  * @since 2.1.3/5.2.3 added 'd' element as a default backup from the API
190
  */
191
  public static function get_media_src_set( $post, $resized_images = array() ) {
192
- $full_size = SB_Instagram_Parse::get_media_url( $post );
193
- $media_urls = array(
194
- 'd' => SB_Instagram_Parse::get_media_url( $post ),
195
  '150' => '',
196
  '320' => '',
197
- '640' => ''
198
  );
199
  $account_type = isset( $post['images'] ) ? 'personal' : 'business';
200
 
@@ -203,7 +203,7 @@ class SB_Instagram_Parse
203
  $media_urls['320'] = $post['images']['low_resolution']['url'];
204
  $media_urls['640'] = $post['images']['standard_resolution']['url'];
205
  } else {
206
- $post_id = SB_Instagram_Parse::get_post_id( $post );
207
 
208
  $media_urls['640'] = $full_size;
209
  $media_urls['150'] = $full_size;
@@ -211,9 +211,9 @@ class SB_Instagram_Parse
211
 
212
  // use resized images if exists
213
  if ( isset( $resized_images[ $post_id ]['id'] )
214
- && $resized_images[ $post_id ]['id'] !== 'pending'
215
- && $resized_images[ $post_id ]['id'] !== 'video'
216
- && $resized_images[ $post_id ]['id'] !== 'error' ) {
217
  if ( isset( $resized_images[ $post_id ]['sizes']['full'] ) ) {
218
  $media_urls['640'] = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'full.jpg';
219
  }
@@ -221,7 +221,6 @@ class SB_Instagram_Parse
221
  $media_urls['320'] = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'low.jpg';
222
  }
223
  }
224
-
225
  }
226
 
227
  return $media_urls;
@@ -246,10 +245,10 @@ class SB_Instagram_Parse
246
  $caption = $post['caption']['text'];
247
  }
248
 
249
- $video_title = SB_Instagram_Parse::get_video_title( $post );
250
 
251
  if ( ! empty( $video_title ) ) {
252
- $caption = $video_title .'. ' . $caption;
253
  }
254
 
255
  return $caption;
@@ -321,7 +320,7 @@ class SB_Instagram_Parse
321
  } elseif ( isset( $header_data['data']['full_name'] ) ) {
322
  return $header_data['data']['full_name'];
323
  }
324
- return SB_Instagram_Parse::get_username( $header_data );
325
  }
326
 
327
  /**
@@ -339,9 +338,9 @@ class SB_Instagram_Parse
339
  return $settings['custombio'];
340
  } elseif ( isset( $header_data['data']['bio'] ) ) {
341
  return $header_data['data']['bio'];
342
- } elseif ( isset( $header_data['bio'] ) ){
343
  return $header_data['bio'];
344
- } elseif ( isset( $header_data['biography'] ) ){
345
  return $header_data['biography'];
346
  }
347
  return '';
@@ -360,8 +359,8 @@ class SB_Instagram_Parse
360
  public static function fix_permalink( $permalink ) {
361
  if ( substr_count( $permalink, '/' ) > 5 ) {
362
  $permalink_array = explode( '/', $permalink );
363
- $perm_id = $permalink_array[ count( $permalink_array ) - 2 ];
364
- $permalink = 'https://www.instagram.com/p/' . $perm_id . '/';
365
  }
366
  return $permalink;
367
 
@@ -400,4 +399,4 @@ class SB_Instagram_Parse
400
 
401
  return 'feed';
402
  }
403
- }
14
  die( '-1' );
15
  }
16
 
17
+ class SB_Instagram_Parse {
18
+
19
  /**
20
  * @param $post array
21
  *
35
  * @since 2.0/5.0
36
  */
37
  public static function get_account_type( $post ) {
38
+ if ( isset( $post['media_type'] ) ) {
39
  return 'business';
40
  } else {
41
  return 'personal';
53
  $timestamp = 0;
54
  if ( isset( $post['created_time'] ) ) {
55
  $timestamp = $post['created_time'];
56
+ } elseif ( isset( $post['timestamp'] ) ) {
57
  // some date formatting functions have trouble with the "T", "+", and extra zeroes added by Instagram
58
+ $remove_plus = trim( str_replace( array( 'T', '+', ' 0000' ), ' ', $post['timestamp'] ) );
59
+ $timestamp = strtotime( $remove_plus );
60
  }
61
 
62
  return $timestamp;
74
  return $post['type'];
75
  }
76
 
77
+ return strtolower( str_replace( '_ALBUM', '', $post['media_type'] ) );
78
  }
79
 
80
  /**
100
  *
101
  * @since 2.0/5.0
102
  */
103
+ public static function get_media_url( $post ) {
104
  $account_type = isset( $post['images'] ) ? 'personal' : 'business';
105
+ $media_type = isset( $post['media_type'] ) ? $post['media_type'] : 'none';
106
 
107
  if ( $account_type === 'personal' ) {
108
  return $post['images']['standard_resolution']['url'];
109
  } else {
110
  if ( $media_type === 'CAROUSEL_ALBUM'
111
+ || $media_type === 'VIDEO'
112
+ || $media_type === 'OEMBED' ) {
113
  if ( isset( $post['thumbnail_url'] ) ) {
114
  return $post['thumbnail_url'];
115
  } elseif ( $media_type === 'CAROUSEL_ALBUM' && isset( $post['media_url'] ) ) {
116
  return $post['media_url'];
117
  } elseif ( isset( $post['children'] ) ) {
118
+ $i = 0;
119
  $full_size = '';
120
  foreach ( $post['children']['data'] as $carousel_item ) {
121
  if ( $carousel_item['media_type'] === 'IMAGE' && empty( $full_size ) ) {
128
  } else {
129
  $media = trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png';
130
  //attempt to get
131
+ $permalink = self::fix_permalink( self::get_permalink( $carousel_item ) );
132
+ $single = new SB_Instagram_Single( $permalink );
133
  $single->init();
134
  $carousel_item_post = $single->get_post();
135
 
150
  return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png';
151
  }
152
  //attempt to get
153
+ $permalink = self::fix_permalink( self::get_permalink( $post ) );
154
+ $single = new SB_Instagram_Single( $permalink );
155
  $single->init();
156
  $post = $single->get_post();
157
 
189
  * @since 2.1.3/5.2.3 added 'd' element as a default backup from the API
190
  */
191
  public static function get_media_src_set( $post, $resized_images = array() ) {
192
+ $full_size = self::get_media_url( $post );
193
+ $media_urls = array(
194
+ 'd' => self::get_media_url( $post ),
195
  '150' => '',
196
  '320' => '',
197
+ '640' => '',
198
  );
199
  $account_type = isset( $post['images'] ) ? 'personal' : 'business';
200
 
203
  $media_urls['320'] = $post['images']['low_resolution']['url'];
204
  $media_urls['640'] = $post['images']['standard_resolution']['url'];
205
  } else {
206
+ $post_id = self::get_post_id( $post );
207
 
208
  $media_urls['640'] = $full_size;
209
  $media_urls['150'] = $full_size;
211
 
212
  // use resized images if exists
213
  if ( isset( $resized_images[ $post_id ]['id'] )
214
+ && $resized_images[ $post_id ]['id'] !== 'pending'
215
+ && $resized_images[ $post_id ]['id'] !== 'video'
216
+ && $resized_images[ $post_id ]['id'] !== 'error' ) {
217
  if ( isset( $resized_images[ $post_id ]['sizes']['full'] ) ) {
218
  $media_urls['640'] = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'full.jpg';
219
  }
221
  $media_urls['320'] = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'low.jpg';
222
  }
223
  }
 
224
  }
225
 
226
  return $media_urls;
245
  $caption = $post['caption']['text'];
246
  }
247
 
248
+ $video_title = self::get_video_title( $post );
249
 
250
  if ( ! empty( $video_title ) ) {
251
+ $caption = $video_title . '. ' . $caption;
252
  }
253
 
254
  return $caption;
320
  } elseif ( isset( $header_data['data']['full_name'] ) ) {
321
  return $header_data['data']['full_name'];
322
  }
323
+ return self::get_username( $header_data );
324
  }
325
 
326
  /**
338
  return $settings['custombio'];
339
  } elseif ( isset( $header_data['data']['bio'] ) ) {
340
  return $header_data['data']['bio'];
341
+ } elseif ( isset( $header_data['bio'] ) ) {
342
  return $header_data['bio'];
343
+ } elseif ( isset( $header_data['biography'] ) ) {
344
  return $header_data['biography'];
345
  }
346
  return '';
359
  public static function fix_permalink( $permalink ) {
360
  if ( substr_count( $permalink, '/' ) > 5 ) {
361
  $permalink_array = explode( '/', $permalink );
362
+ $perm_id = $permalink_array[ count( $permalink_array ) - 2 ];
363
+ $permalink = 'https://www.instagram.com/p/' . $perm_id . '/';
364
  }
365
  return $permalink;
366
 
399
 
400
  return 'feed';
401
  }
402
+ }
inc/class-sb-instagram-post-set.php CHANGED
@@ -62,13 +62,24 @@ class SB_Instagram_Post_Set {
62
  *
63
  * @since 2.0/4.0
64
  */
65
- public function __construct( $post_data, $transient_name = false, $fill_in_timestamp = NULL, $image_sizes = array( 'personal' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ), 'business' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ) ), $upload_dir = NULL, $upload_url = NULL ) {
 
 
 
 
 
 
 
 
 
 
 
66
  $this->post_data = $post_data;
67
 
68
  $this->image_sizes = $image_sizes;
69
 
70
  if ( ! isset( $upload_dir ) || ! isset( $upload_url ) ) {
71
- $upload = wp_upload_dir();
72
  $upload_dir = $upload['basedir'];
73
  $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
74
 
@@ -116,12 +127,12 @@ class SB_Instagram_Post_Set {
116
  public function maybe_save_update_and_resize_images_for_posts() {
117
  global $sb_instagram_posts_manager;
118
 
119
- $posts_iterated_through = 0;
120
- $number_resized = 0;
121
- $number_updated = 0;
122
  $resized_image_data_for_set = array();
123
- $resizing_disabled = $sb_instagram_posts_manager->image_resizing_disabled( $this->transient_name ) || $sb_instagram_posts_manager->max_resizing_per_time_period_reached();
124
- $is_top_post_feed = (substr( $this->transient_name, 4, 1 ) === '+');
125
 
126
  foreach ( $this->post_data as $single_instagram_post_data ) {
127
 
@@ -142,22 +153,22 @@ class SB_Instagram_Post_Set {
142
  }
143
 
144
  if ( ! $resizing_disabled ) {
145
- if ( (! $single_post->exists_in_posts_table() || ! $single_post->images_done_resizing()) && $number_resized < 30 ) {
146
 
147
  if ( $sb_instagram_posts_manager->max_total_records_reached() ) {
148
  $sb_instagram_posts_manager->delete_least_used_image();
149
  }
150
 
151
  if ( ! $single_post->images_done_resizing() && $single_post->exists_in_posts_table() ) {
152
- $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url );
153
  } else {
154
  if ( $is_top_post_feed ) {
155
  if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - (120 * $posts_iterated_through) - 1 ) ) ) {
156
- $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url );
157
  }
158
  } else {
159
  if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->fill_in_timestamp ) - (120 * $posts_iterated_through) ) ) ) {
160
- $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url );
161
  }
162
  }
163
  }
@@ -165,7 +176,7 @@ class SB_Instagram_Post_Set {
165
  $number_resized++;
166
  } else {
167
  if ( $is_top_post_feed ) {
168
- $single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - (120 * $posts_iterated_through) ) );
169
  } else {
170
  $single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url );
171
  }
@@ -185,4 +196,4 @@ class SB_Instagram_Post_Set {
185
  $this->resized_image_data_for_set = $resized_image_data_for_set;
186
  }
187
 
188
- }
62
  *
63
  * @since 2.0/4.0
64
  */
65
+ public function __construct( $post_data, $transient_name = false, $fill_in_timestamp = null, $image_sizes = array(
66
+ 'personal' => array(
67
+ 'full' => 640,
68
+ 'low' => 320,
69
+ 'thumb' => 150,
70
+ ),
71
+ 'business' => array(
72
+ 'full' => 640,
73
+ 'low' => 320,
74
+ 'thumb' => 150,
75
+ ),
76
+ ), $upload_dir = null, $upload_url = null ) {
77
  $this->post_data = $post_data;
78
 
79
  $this->image_sizes = $image_sizes;
80
 
81
  if ( ! isset( $upload_dir ) || ! isset( $upload_url ) ) {
82
+ $upload = wp_upload_dir();
83
  $upload_dir = $upload['basedir'];
84
  $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
85
 
127
  public function maybe_save_update_and_resize_images_for_posts() {
128
  global $sb_instagram_posts_manager;
129
 
130
+ $posts_iterated_through = 0;
131
+ $number_resized = 0;
132
+ $number_updated = 0;
133
  $resized_image_data_for_set = array();
134
+ $resizing_disabled = $sb_instagram_posts_manager->image_resizing_disabled( $this->transient_name ) || $sb_instagram_posts_manager->max_resizing_per_time_period_reached();
135
+ $is_top_post_feed = ( substr( $this->transient_name, 4, 1 ) === '+' );
136
 
137
  foreach ( $this->post_data as $single_instagram_post_data ) {
138
 
153
  }
154
 
155
  if ( ! $resizing_disabled ) {
156
+ if ( ( ! $single_post->exists_in_posts_table() || ! $single_post->images_done_resizing() ) && $number_resized < 30 ) {
157
 
158
  if ( $sb_instagram_posts_manager->max_total_records_reached() ) {
159
  $sb_instagram_posts_manager->delete_least_used_image();
160
  }
161
 
162
  if ( ! $single_post->images_done_resizing() && $single_post->exists_in_posts_table() ) {
163
+ $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir );
164
  } else {
165
  if ( $is_top_post_feed ) {
166
  if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - (120 * $posts_iterated_through) - 1 ) ) ) {
167
+ $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir );
168
  }
169
  } else {
170
  if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->fill_in_timestamp ) - (120 * $posts_iterated_through) ) ) ) {
171
+ $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir );
172
  }
173
  }
174
  }
176
  $number_resized++;
177
  } else {
178
  if ( $is_top_post_feed ) {
179
+ $single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - ( 120 * $posts_iterated_through ) ) );
180
  } else {
181
  $single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url );
182
  }
196
  $this->resized_image_data_for_set = $resized_image_data_for_set;
197
  }
198
 
199
+ }
inc/class-sb-instagram-post.php CHANGED
@@ -14,8 +14,8 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  die( '-1' );
15
  }
16
 
17
- class SB_Instagram_Post
18
- {
19
  /**
20
  * @var string
21
  */
@@ -69,10 +69,10 @@ class SB_Instagram_Post
69
 
70
  $feed_id_match = $wpdb->get_results( $wpdb->prepare( "SELECT id, media_id, top_time_stamp, images_done FROM $table_name WHERE instagram_id = %s LIMIT 1", $instagram_post_id ), ARRAY_A );
71
 
72
- $this->db_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['id'] : '';
73
- $this->media_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['media_id'] : '';
74
  $this->top_time_stamp = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['top_time_stamp'] ) ? $feed_id_match[0]['top_time_stamp'] : '';
75
- $this->images_done = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['images_done'] ) ? $feed_id_match[0]['images_done'] === '1' : 0;
76
 
77
  $this->instagram_post_id = $instagram_post_id;
78
 
@@ -148,7 +148,7 @@ class SB_Instagram_Post
148
  *
149
  * @since 2.0/4.0
150
  */
151
- public function save_in_db( $transient_name = false, $timestamp_override = NULL ) {
152
  global $wpdb;
153
 
154
  $parsed_data = $this->get_parsed_post_data();
@@ -164,19 +164,21 @@ class SB_Instagram_Post
164
  "'pending'",
165
  "'pending'",
166
  0,
167
- "'".date( 'Y-m-d H:i:s' )."'"
168
  );
169
 
170
- $entry_string = implode( ',',$entry_data );
171
- $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
172
 
173
  $timestamp_column = 'time_stamp';
174
- if ( substr( $transient_name, 4, 1 ) === '+') {
175
  $timestamp_column = 'top_time_stamp';
176
  }
177
 
178
- $error = $wpdb->query( "INSERT INTO $table_name
179
- (created_on,instagram_id,time_stamp,top_time_stamp,json_data,media_id,sizes,images_done,last_requested) VALUES ($entry_string);" );
 
 
180
 
181
  if ( $error !== false ) {
182
  $this->db_id = $wpdb->insert_id;
@@ -205,7 +207,7 @@ class SB_Instagram_Post
205
  * accommodate personal accounts and possible
206
  * custom sizes in the future
207
  */
208
- public function resize_and_save_image( $image_sizes, $upload_dir, $upload_url ) {
209
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
210
 
211
  if ( isset( $this->instagram_api_data['id'] ) ) {
@@ -214,14 +216,14 @@ class SB_Instagram_Post
214
  $image_sizes_to_make = isset( $image_sizes[ $account_type ] ) ? $image_sizes[ $account_type ] : array();
215
  // if it's a personal account or a weird url, the post id is used, otherwise the last part of the image url is used
216
  if ( $account_type === 'business' ) {
217
- $new_file_name = explode( '?', SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' ) );
218
  if ( strlen( basename( $new_file_name[0], '.jpg' ) ) > 10 ) {
219
- $new_file_name = basename( $new_file_name[0], '.jpg' );
220
  } else {
221
- $new_file_name = $this->instagram_api_data['id'];
222
  }
223
  } else {
224
- $new_file_name = $this->instagram_api_data['id'];
225
  }
226
 
227
  // the process is considered a success if one image is successfully resized
@@ -229,21 +231,20 @@ class SB_Instagram_Post
229
 
230
  foreach ( $image_sizes_to_make as $res_setting => $image_size ) {
231
  if ( $account_type === 'business' ) {
232
- $file_name = SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' );
233
  } else {
234
- $file_name = isset( $image_source_set[ $image_size ] ) ? $image_source_set[ $image_size ] : SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' );
235
  }
236
  if ( strpos( $file_name, 'placeholder' ) !== false ) {
237
  $file_name = '';
238
  }
239
  if ( ! empty( $file_name ) ) {
240
 
241
- $sizes = array(
242
  'height' => 1,
243
- 'width' => 1
244
  );
245
 
246
-
247
  $suffix = $res_setting;
248
 
249
  $this_image_file_name = $new_file_name . $suffix . '.jpg';
@@ -254,7 +255,7 @@ class SB_Instagram_Post
254
  if ( is_wp_error( $image_editor ) ) {
255
 
256
  // Gives us access to the download_url() and wp_handle_sideload() functions.
257
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
258
 
259
  $timeout_seconds = 5;
260
 
@@ -264,13 +265,13 @@ class SB_Instagram_Post
264
  $image_editor = wp_get_image_editor( $temp_file );
265
 
266
  global $sb_instagram_posts_manager;
267
- $details = __( 'Using backup editor method.', 'instagram-feed' ) . ' ' . $file_name;
268
  $sb_instagram_posts_manager->add_error( 'image_editor', $details );
269
  }
270
 
271
  // not uncommon for the image editor to not work using it this way
272
  if ( ! is_wp_error( $image_editor ) ) {
273
- $image_editor->set_quality(80);
274
 
275
  $sizes = $image_editor->get_size();
276
 
@@ -282,7 +283,7 @@ class SB_Instagram_Post
282
 
283
  if ( ! $saved_image ) {
284
  global $sb_instagram_posts_manager;
285
- $details = __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name;
286
  $sb_instagram_posts_manager->add_error( 'image_editor', $details );
287
 
288
  } else {
@@ -303,33 +304,33 @@ class SB_Instagram_Post
303
  global $sb_instagram_posts_manager;
304
  $sb_instagram_posts_manager->add_error( 'image_editor', $message );
305
  }
306
-
307
  }
308
-
309
-
310
  }
311
 
312
  if ( $one_successful_image_resize ) {
313
  $aspect_ratio = round( $sizes['width'] / $sizes['height'], 2 );
314
 
315
- $this->update_sbi_instagram_posts( array(
316
- 'media_id' => $new_file_name,
317
- 'sizes' => maybe_serialize( $image_sizes_to_make ),
318
- 'aspect_ratio' => $aspect_ratio,
319
- 'images_done' => 1
320
- ) );
 
 
321
 
322
  $this->add_resized_image_to_obj_array( 'id', $new_file_name );
323
  } else {
324
  // an error status means that image resizing won't be attempted again for this post
325
- $this->update_sbi_instagram_posts( array(
326
- 'media_id' => 'error',
327
- 'sizes' => maybe_serialize( $image_sizes_to_make ),
328
- 'aspect_ratio' => 1,
329
- 'images_done' => 1
330
- ) );
 
 
331
  }
332
-
333
  }
334
  }
335
 
@@ -345,14 +346,21 @@ class SB_Instagram_Post
345
  global $wpdb;
346
 
347
  $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
348
- $stored = $wpdb->get_results( $wpdb->prepare( "SELECT media_id, aspect_ratio FROM $posts_table_name
349
- WHERE instagram_id = %s
350
- LIMIT 1", $this->instagram_post_id ), ARRAY_A );
 
 
 
 
 
 
 
351
 
352
  if ( isset( $stored[0] ) ) {
353
- $return = array(
354
- 'id' => $stored[0]['media_id'],
355
- 'ratio' => $stored[0]['aspect_ratio']
356
  );
357
  $this->resized_image_array = $return;
358
  return $return;
@@ -379,14 +387,14 @@ class SB_Instagram_Post
379
  *
380
  * @since 2.0/4.0
381
  */
382
- public function update_db_data( $update_last_requested = true, $transient_name = false, $image_sizes = array(), $upload_dir = '', $upload_url ='', $timestamp_for_update = false ) {
383
 
384
  if ( empty( $this->db_id ) ) {
385
  return false;
386
  }
387
 
388
  $to_update = array(
389
- 'json_data' => $this->encryption->encrypt( sbi_json_encode( $this->instagram_api_data ) )
390
  );
391
 
392
  if ( $update_last_requested ) {
@@ -402,7 +410,7 @@ class SB_Instagram_Post
402
  }
403
 
404
  if ( $this->media_id === 'pending' ) {
405
- $this->resize_and_save_image( $image_sizes, $upload_dir, $upload_url );
406
  } else {
407
  $this->update_sbi_instagram_posts( $to_update );
408
  }
@@ -424,9 +432,15 @@ class SB_Instagram_Post
424
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
425
 
426
  foreach ( $to_update as $column => $value ) {
427
- $query = $wpdb->query( $wpdb->prepare( "UPDATE $table_name
 
 
428
  SET $column = %s
429
- WHERE id = %d;", $value, $this->db_id ) );
 
 
 
 
430
 
431
  if ( $query === false ) {
432
  global $sb_instagram_posts_manager;
@@ -451,10 +465,10 @@ class SB_Instagram_Post
451
  */
452
  public function exists_in_feeds_posts_table( $transient_name ) {
453
  global $wpdb;
454
- $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
455
  $feed_id_array = explode( '#', $transient_name );
456
- $feed_id = $feed_id_array[0];
457
- $results = $wpdb->get_results( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE instagram_id = %s AND feed_id = %s LIMIT 1", $this->instagram_post_id, $feed_id ), ARRAY_A );
458
 
459
  if ( isset( $results[0]['feed_id'] ) ) {
460
  return true;
@@ -472,7 +486,7 @@ class SB_Instagram_Post
472
  *
473
  * @param string $transient_name
474
  *
475
- * @return int
476
  *
477
  * @since 2.0/4.0
478
  */
@@ -481,7 +495,7 @@ class SB_Instagram_Post
481
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
482
  // the number is removed from the transient name for backwards compatibilty.
483
  $feed_id_array = explode( '#', $transient_name );
484
- $feed_id = $feed_id_array[0];
485
 
486
  if ( ! empty( $this->db_id ) ) {
487
  $entry_data = array(
@@ -492,14 +506,18 @@ class SB_Instagram_Post
492
 
493
  if ( ! empty( $this->instagram_api_data['term'] ) ) {
494
  $entry_data[] = "'" . esc_sql( strtolower( str_replace( '#', '', $this->instagram_api_data['term'] ) ) ) . "'";
495
- $entry_string = implode( ',',$entry_data );
496
 
497
- $error = $wpdb->query( "INSERT INTO $table_name
498
- (id,instagram_id,feed_id,hashtag) VALUES ($entry_string);" );
 
 
499
  } else {
500
- $entry_string = implode( ',',$entry_data );
501
- $error = $wpdb->query( "INSERT INTO $table_name
502
- (id,instagram_id,feed_id) VALUES ($entry_string);" );
 
 
503
  }
504
  } else {
505
  global $sb_instagram_posts_manager;
@@ -508,7 +526,6 @@ class SB_Instagram_Post
508
  return false;
509
  }
510
 
511
-
512
  if ( $error !== false ) {
513
  return $wpdb->insert_id;
514
  } else {
@@ -517,6 +534,7 @@ class SB_Instagram_Post
517
  $query = $wpdb->last_query;
518
  $sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . $error . '<br><code>' . $query . '</code>' );
519
  }
 
520
  }
521
 
522
  /**
@@ -531,37 +549,37 @@ class SB_Instagram_Post
531
  private function get_parsed_post_data( $all = true ) {
532
 
533
  $instagram_post_id = isset( $this->instagram_api_data['id'] ) ? $this->instagram_api_data['id'] : '';
534
- $comments_count = isset( $this->instagram_api_data['comments_count'] ) ? $this->instagram_api_data['comments_count'] : '';
535
- $like_count = isset( $this->instagram_api_data['like_count'] ) ? $this->instagram_api_data['like_count'] : '';
536
 
537
  $parsed_data = array(
538
  'comments_count' => $comments_count,
539
- 'like_count' => $like_count
540
  );
541
 
542
  if ( $all ) {
543
- $caption = isset( $this->instagram_api_data['caption'] ) ? $this->instagram_api_data['caption'] : '';
544
- $media_url = isset( $this->instagram_api_data['media_url'] ) ? $this->instagram_api_data['media_url'] : '';
545
  $media_type = isset( $this->instagram_api_data['media_type'] ) ? $this->instagram_api_data['media_type'] : '';
546
 
547
  $timestamp = '';
548
  if ( isset( $this->instagram_api_data['timestamp'] ) ) {
549
  $timestamp_parts = explode( ' ', $this->instagram_api_data['timestamp'] );
550
- $timestamp = str_replace( 'T', ' ', $timestamp_parts[0] );
551
  }
552
 
553
- $username = isset( $this->instagram_api_data['username'] ) ? $this->instagram_api_data['username'] : '';
554
  $permalink = isset( $this->instagram_api_data['permalink'] ) ? $this->instagram_api_data['permalink'] : '';
555
- $children = isset( $this->instagram_api_data['children'] ) ? sbi_json_encode( $this->instagram_api_data['children'] ) : '';
556
 
557
- $parsed_data['caption'] = $caption;
558
- $parsed_data['media_url'] = $media_url;
559
- $parsed_data['id'] = $instagram_post_id;
560
  $parsed_data['media_type'] = $media_type;
561
- $parsed_data['timestamp'] = $timestamp;
562
- $parsed_data['username'] = $username;
563
- $parsed_data['permalink'] = $permalink;
564
- $parsed_data['children'] = $children;
565
  }
566
 
567
  return $parsed_data;
@@ -585,19 +603,21 @@ class SB_Instagram_Post
585
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
586
  // the number is removed from the transient name for backwards compatibilty.
587
  $feed_id_array = explode( '#', $feed_id );
588
- $feed_id = str_replace( '+', '', $feed_id_array[0] );
589
 
590
  $feed_id_match = $wpdb->get_col( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE feed_id = %s AND instagram_id = %s", $feed_id, $this->instagram_post_id ) );
591
 
592
  if ( ! isset( $feed_id_match[0] ) ) {
593
- $entry_data = array(
594
  $this->db_id,
595
  "'" . esc_sql( $this->instagram_post_id ) . "'",
596
- "'" . esc_sql( $feed_id ) . "'"
 
 
 
 
 
597
  );
598
- $entry_string = implode( ',',$entry_data );
599
- $error = $wpdb->query( "INSERT INTO $table_name
600
- (id,instagram_id,feed_id) VALUES ($entry_string);" );
601
  }
602
  }
603
- }
14
  die( '-1' );
15
  }
16
 
17
+ class SB_Instagram_Post {
18
+
19
  /**
20
  * @var string
21
  */
69
 
70
  $feed_id_match = $wpdb->get_results( $wpdb->prepare( "SELECT id, media_id, top_time_stamp, images_done FROM $table_name WHERE instagram_id = %s LIMIT 1", $instagram_post_id ), ARRAY_A );
71
 
72
+ $this->db_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['id'] : '';
73
+ $this->media_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['media_id'] : '';
74
  $this->top_time_stamp = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['top_time_stamp'] ) ? $feed_id_match[0]['top_time_stamp'] : '';
75
+ $this->images_done = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['images_done'] ) ? $feed_id_match[0]['images_done'] === '1' : 0;
76
 
77
  $this->instagram_post_id = $instagram_post_id;
78
 
148
  *
149
  * @since 2.0/4.0
150
  */
151
+ public function save_in_db( $transient_name = false, $timestamp_override = null ) {
152
  global $wpdb;
153
 
154
  $parsed_data = $this->get_parsed_post_data();
164
  "'pending'",
165
  "'pending'",
166
  0,
167
+ "'" . date( 'Y-m-d H:i:s' ) . "'",
168
  );
169
 
170
+ $entry_string = implode( ',', $entry_data );
171
+ $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
172
 
173
  $timestamp_column = 'time_stamp';
174
+ if ( substr( $transient_name, 4, 1 ) === '+' ) {
175
  $timestamp_column = 'top_time_stamp';
176
  }
177
 
178
+ $error = $wpdb->query(
179
+ "INSERT INTO $table_name
180
+ (created_on,instagram_id,time_stamp,top_time_stamp,json_data,media_id,sizes,images_done,last_requested) VALUES ($entry_string);"
181
+ );
182
 
183
  if ( $error !== false ) {
184
  $this->db_id = $wpdb->insert_id;
207
  * accommodate personal accounts and possible
208
  * custom sizes in the future
209
  */
210
+ public function resize_and_save_image( $image_sizes, $upload_dir ) {
211
  $sbi_statuses_option = get_option( 'sbi_statuses', array() );
212
 
213
  if ( isset( $this->instagram_api_data['id'] ) ) {
216
  $image_sizes_to_make = isset( $image_sizes[ $account_type ] ) ? $image_sizes[ $account_type ] : array();
217
  // if it's a personal account or a weird url, the post id is used, otherwise the last part of the image url is used
218
  if ( $account_type === 'business' ) {
219
+ $new_file_name = explode( '?', SB_Instagram_Parse::get_media_url( $this->instagram_api_data ) );
220
  if ( strlen( basename( $new_file_name[0], '.jpg' ) ) > 10 ) {
221
+ $new_file_name = basename( $new_file_name[0], '.jpg' );
222
  } else {
223
+ $new_file_name = $this->instagram_api_data['id'];
224
  }
225
  } else {
226
+ $new_file_name = $this->instagram_api_data['id'];
227
  }
228
 
229
  // the process is considered a success if one image is successfully resized
231
 
232
  foreach ( $image_sizes_to_make as $res_setting => $image_size ) {
233
  if ( $account_type === 'business' ) {
234
+ $file_name = SB_Instagram_Parse::get_media_url( $this->instagram_api_data );
235
  } else {
236
+ $file_name = isset( $image_source_set[ $image_size ] ) ? $image_source_set[ $image_size ] : SB_Instagram_Parse::get_media_url( $this->instagram_api_data );
237
  }
238
  if ( strpos( $file_name, 'placeholder' ) !== false ) {
239
  $file_name = '';
240
  }
241
  if ( ! empty( $file_name ) ) {
242
 
243
+ $sizes = array(
244
  'height' => 1,
245
+ 'width' => 1,
246
  );
247
 
 
248
  $suffix = $res_setting;
249
 
250
  $this_image_file_name = $new_file_name . $suffix . '.jpg';
255
  if ( is_wp_error( $image_editor ) ) {
256
 
257
  // Gives us access to the download_url() and wp_handle_sideload() functions.
258
+ require_once ABSPATH . 'wp-admin/includes/file.php';
259
 
260
  $timeout_seconds = 5;
261
 
265
  $image_editor = wp_get_image_editor( $temp_file );
266
 
267
  global $sb_instagram_posts_manager;
268
+ $details = __( 'Using backup editor method.', 'instagram-feed' ) . ' ' . $file_name;
269
  $sb_instagram_posts_manager->add_error( 'image_editor', $details );
270
  }
271
 
272
  // not uncommon for the image editor to not work using it this way
273
  if ( ! is_wp_error( $image_editor ) ) {
274
+ $image_editor->set_quality( 80 );
275
 
276
  $sizes = $image_editor->get_size();
277
 
283
 
284
  if ( ! $saved_image ) {
285
  global $sb_instagram_posts_manager;
286
+ $details = __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name;
287
  $sb_instagram_posts_manager->add_error( 'image_editor', $details );
288
 
289
  } else {
304
  global $sb_instagram_posts_manager;
305
  $sb_instagram_posts_manager->add_error( 'image_editor', $message );
306
  }
 
307
  }
 
 
308
  }
309
 
310
  if ( $one_successful_image_resize ) {
311
  $aspect_ratio = round( $sizes['width'] / $sizes['height'], 2 );
312
 
313
+ $this->update_sbi_instagram_posts(
314
+ array(
315
+ 'media_id' => $new_file_name,
316
+ 'sizes' => maybe_serialize( $image_sizes_to_make ),
317
+ 'aspect_ratio' => $aspect_ratio,
318
+ 'images_done' => 1,
319
+ )
320
+ );
321
 
322
  $this->add_resized_image_to_obj_array( 'id', $new_file_name );
323
  } else {
324
  // an error status means that image resizing won't be attempted again for this post
325
+ $this->update_sbi_instagram_posts(
326
+ array(
327
+ 'media_id' => 'error',
328
+ 'sizes' => maybe_serialize( $image_sizes_to_make ),
329
+ 'aspect_ratio' => 1,
330
+ 'images_done' => 1,
331
+ )
332
+ );
333
  }
 
334
  }
335
  }
336
 
346
  global $wpdb;
347
 
348
  $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
349
+
350
+ $stored = $wpdb->get_results(
351
+ $wpdb->prepare(
352
+ "SELECT media_id, aspect_ratio FROM $posts_table_name
353
+ WHERE instagram_id = %s
354
+ LIMIT 1",
355
+ $this->instagram_post_id
356
+ ),
357
+ ARRAY_A
358
+ );
359
 
360
  if ( isset( $stored[0] ) ) {
361
+ $return = array(
362
+ 'id' => $stored[0]['media_id'],
363
+ 'ratio' => $stored[0]['aspect_ratio'],
364
  );
365
  $this->resized_image_array = $return;
366
  return $return;
387
  *
388
  * @since 2.0/4.0
389
  */
390
+ public function update_db_data( $update_last_requested = true, $transient_name = false, $image_sizes = array(), $upload_dir = '', $upload_url = '', $timestamp_for_update = false ) {
391
 
392
  if ( empty( $this->db_id ) ) {
393
  return false;
394
  }
395
 
396
  $to_update = array(
397
+ 'json_data' => $this->encryption->encrypt( sbi_json_encode( $this->instagram_api_data ) ),
398
  );
399
 
400
  if ( $update_last_requested ) {
410
  }
411
 
412
  if ( $this->media_id === 'pending' ) {
413
+ $this->resize_and_save_image( $image_sizes, $upload_dir );
414
  } else {
415
  $this->update_sbi_instagram_posts( $to_update );
416
  }
432
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
433
 
434
  foreach ( $to_update as $column => $value ) {
435
+ $query = $wpdb->query(
436
+ $wpdb->prepare(
437
+ "UPDATE $table_name
438
  SET $column = %s
439
+ WHERE id = %d;",
440
+ $value,
441
+ $this->db_id
442
+ )
443
+ );
444
 
445
  if ( $query === false ) {
446
  global $sb_instagram_posts_manager;
465
  */
466
  public function exists_in_feeds_posts_table( $transient_name ) {
467
  global $wpdb;
468
+ $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
469
  $feed_id_array = explode( '#', $transient_name );
470
+ $feed_id = $feed_id_array[0];
471
+ $results = $wpdb->get_results( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE instagram_id = %s AND feed_id = %s LIMIT 1", $this->instagram_post_id, $feed_id ), ARRAY_A );
472
 
473
  if ( isset( $results[0]['feed_id'] ) ) {
474
  return true;
486
  *
487
  * @param string $transient_name
488
  *
489
+ * @return int|bool
490
  *
491
  * @since 2.0/4.0
492
  */
495
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
496
  // the number is removed from the transient name for backwards compatibilty.
497
  $feed_id_array = explode( '#', $transient_name );
498
+ $feed_id = $feed_id_array[0];
499
 
500
  if ( ! empty( $this->db_id ) ) {
501
  $entry_data = array(
506
 
507
  if ( ! empty( $this->instagram_api_data['term'] ) ) {
508
  $entry_data[] = "'" . esc_sql( strtolower( str_replace( '#', '', $this->instagram_api_data['term'] ) ) ) . "'";
509
+ $entry_string = implode( ',', $entry_data );
510
 
511
+ $error = $wpdb->query(
512
+ "INSERT INTO $table_name
513
+ (id,instagram_id,feed_id,hashtag) VALUES ($entry_string);"
514
+ );
515
  } else {
516
+ $entry_string = implode( ',', $entry_data );
517
+ $error = $wpdb->query(
518
+ "INSERT INTO $table_name
519
+ (id,instagram_id,feed_id) VALUES ($entry_string);"
520
+ );
521
  }
522
  } else {
523
  global $sb_instagram_posts_manager;
526
  return false;
527
  }
528
 
 
529
  if ( $error !== false ) {
530
  return $wpdb->insert_id;
531
  } else {
534
  $query = $wpdb->last_query;
535
  $sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . $error . '<br><code>' . $query . '</code>' );
536
  }
537
+ return false;
538
  }
539
 
540
  /**
549
  private function get_parsed_post_data( $all = true ) {
550
 
551
  $instagram_post_id = isset( $this->instagram_api_data['id'] ) ? $this->instagram_api_data['id'] : '';
552
+ $comments_count = isset( $this->instagram_api_data['comments_count'] ) ? $this->instagram_api_data['comments_count'] : '';
553
+ $like_count = isset( $this->instagram_api_data['like_count'] ) ? $this->instagram_api_data['like_count'] : '';
554
 
555
  $parsed_data = array(
556
  'comments_count' => $comments_count,
557
+ 'like_count' => $like_count,
558
  );
559
 
560
  if ( $all ) {
561
+ $caption = isset( $this->instagram_api_data['caption'] ) ? $this->instagram_api_data['caption'] : '';
562
+ $media_url = isset( $this->instagram_api_data['media_url'] ) ? $this->instagram_api_data['media_url'] : '';
563
  $media_type = isset( $this->instagram_api_data['media_type'] ) ? $this->instagram_api_data['media_type'] : '';
564
 
565
  $timestamp = '';
566
  if ( isset( $this->instagram_api_data['timestamp'] ) ) {
567
  $timestamp_parts = explode( ' ', $this->instagram_api_data['timestamp'] );
568
+ $timestamp = str_replace( 'T', ' ', $timestamp_parts[0] );
569
  }
570
 
571
+ $username = isset( $this->instagram_api_data['username'] ) ? $this->instagram_api_data['username'] : '';
572
  $permalink = isset( $this->instagram_api_data['permalink'] ) ? $this->instagram_api_data['permalink'] : '';
573
+ $children = isset( $this->instagram_api_data['children'] ) ? sbi_json_encode( $this->instagram_api_data['children'] ) : '';
574
 
575
+ $parsed_data['caption'] = $caption;
576
+ $parsed_data['media_url'] = $media_url;
577
+ $parsed_data['id'] = $instagram_post_id;
578
  $parsed_data['media_type'] = $media_type;
579
+ $parsed_data['timestamp'] = $timestamp;
580
+ $parsed_data['username'] = $username;
581
+ $parsed_data['permalink'] = $permalink;
582
+ $parsed_data['children'] = $children;
583
  }
584
 
585
  return $parsed_data;
603
  $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
604
  // the number is removed from the transient name for backwards compatibilty.
605
  $feed_id_array = explode( '#', $feed_id );
606
+ $feed_id = str_replace( '+', '', $feed_id_array[0] );
607
 
608
  $feed_id_match = $wpdb->get_col( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE feed_id = %s AND instagram_id = %s", $feed_id, $this->instagram_post_id ) );
609
 
610
  if ( ! isset( $feed_id_match[0] ) ) {
611
+ $entry_data = array(
612
  $this->db_id,
613
  "'" . esc_sql( $this->instagram_post_id ) . "'",
614
+ "'" . esc_sql( $feed_id ) . "'",
615
+ );
616
+ $entry_string = implode( ',', $entry_data );
617
+ $error = $wpdb->query(
618
+ "INSERT INTO $table_name
619
+ (id,instagram_id,feed_id) VALUES ($entry_string);"
620
  );
 
 
 
621
  }
622
  }
623
+ }
inc/class-sb-instagram-posts-manager.php CHANGED
@@ -12,8 +12,8 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  die( '-1' );
13
  }
14
 
15
- class SB_Instagram_Posts_Manager
16
- {
17
  /**
18
  * @var mixed|void
19
  */
@@ -44,18 +44,18 @@ class SB_Instagram_Posts_Manager
44
  */
45
  public function __construct() {
46
  $this->sbi_options = get_option( 'sb_instagram_settings' );
47
- $this->errors = get_option( 'sb_instagram_errors', array() );
48
  if ( ! isset( $this->errors['connection'] ) ) {
49
  $this->errors = array(
50
- 'connection' => array(),
51
- 'hashtag' => array(),
52
- 'resizing' => array(),
53
  'database_create' => array(),
54
- 'upload_dir' => array(),
55
- 'accounts' => array(),
56
- 'error_log' => array(),
57
- 'action_log' => array(),
58
- 'revoked' => array()
59
  );
60
  }
61
 
@@ -83,7 +83,7 @@ class SB_Instagram_Posts_Manager
83
  }
84
 
85
  if ( isset( $details['error']['code'] )
86
- && (int)$details['error']['code'] === 18 ) {
87
  $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 15;
88
  }
89
  }
@@ -114,16 +114,15 @@ class SB_Instagram_Posts_Manager
114
 
115
  // is it connection? or what type?
116
  if ( $type === 'api'
117
- || $type === 'wp_remote_get' ) {
118
  $connection_details = array(
119
- 'error_id' => ''
120
  );
121
 
122
  $connection_details['critical'] = false;
123
  if ( isset( $details['error']['code'] ) ) {
124
  $connection_details['error_id'] = $details['error']['code'];
125
 
126
-
127
  if ( $this->is_critical_error( $details ) ) {
128
  $connection_details['critical'] = true;
129
  }
@@ -145,7 +144,7 @@ class SB_Instagram_Posts_Manager
145
  $connection_details['post_id'] = get_the_ID();
146
  }
147
  $connection_details['error_message'] = $this->generate_error_message( $details, $connected_account );
148
- $log_item .= $connection_details['error_message']['admin_only'];
149
  $this->maybe_set_display_error( 'connection', $connection_details );
150
  $this->errors['connection'] = $connection_details;
151
  }
@@ -153,10 +152,10 @@ class SB_Instagram_Posts_Manager
153
  if ( $type === 'hashtag' ) {
154
  $hashtag_details = array(
155
  'error_id' => '',
156
- 'hashtag' => isset( $details['hashtag'] ) ? $details['hashtag'] : ''
157
  );
158
  if ( isset( $details['error']['code'] ) ) {
159
- if ( (int)$details['error']['code'] === 24 ) {
160
  $hashtag_details['clear_time'] = time() + 60 * 5;
161
  }
162
  }
@@ -172,15 +171,15 @@ class SB_Instagram_Posts_Manager
172
  $hashtag_details['post_id'] = get_the_ID();
173
  }
174
  $hashtag_details['error_message'] = $this->generate_error_message( $details, $connected_account );
175
- $log_item .= $hashtag_details['error_message']['admin_only'];
176
  $this->maybe_set_display_error( 'hashtag', $hashtag_details );
177
 
178
  $found = false;
179
  if ( isset( $details['hashtag'] ) ) {
180
  foreach ( $this->errors['hashtag'] as $hashtag_error_item ) {
181
  if ( isset( $hashtag_error_item['hashtag'] )
182
- && strtolower( $hashtag_error_item['hashtag'] ) === strtolower( $details['hashtag'] )
183
- && $hashtag_error_item['error_id'] === $details['error_id'] ) {
184
  $found = true;
185
  }
186
  }
@@ -192,20 +191,20 @@ class SB_Instagram_Posts_Manager
192
  }
193
 
194
  if ( $type === 'image_editor'
195
- || $type === 'storage' ) {
196
 
197
  $this->errors['resizing'] = $details;
198
- $log_item .= $details;
199
  }
200
 
201
  if ( $type === 'database_create' ) {
202
  $this->errors['database_create'] = $details;
203
- $log_item .= $details;
204
  }
205
 
206
  if ( $type === 'upload_dir' ) {
207
  $this->errors['upload_dir'] = $details;
208
- $log_item .= $details;
209
  }
210
 
211
  $current_log = $this->errors['error_log'];
@@ -213,7 +212,7 @@ class SB_Instagram_Posts_Manager
213
  reset( $current_log );
214
  unset( $current_log[ key( $current_log ) ] );
215
  }
216
- $current_log[] = $log_item;
217
  $this->errors['error_log'] = $current_log;
218
  update_option( 'sb_instagram_errors', $this->errors, false );
219
  }
@@ -268,7 +267,7 @@ class SB_Instagram_Posts_Manager
268
  * @since 2.7/5.10
269
  */
270
  public function is_critical_error( $details ) {
271
- $error_code = (int)$details['error']['code'];
272
 
273
  $critical_codes = array(
274
  803, // ID doesn't exist
@@ -290,8 +289,8 @@ class SB_Instagram_Posts_Manager
290
  * @since 2.7/5.10
291
  */
292
  public function is_app_permission_related( $details ) {
293
- $error_code = (int)$details['error']['code'];
294
- $error_subcode = isset( $details['error']['error_subcode'] ) ? (int)$details['error']['error_subcode'] : 0;
295
 
296
  $critical_codes = array(
297
  190, // access token or permissions
@@ -324,25 +323,25 @@ class SB_Instagram_Posts_Manager
324
  public function generate_error_message( $response, $connected_account = array( 'username' => '' ) ) {
325
 
326
  $error_message_return = array(
327
- 'error_message' => '',
328
- 'admin_only' => '',
329
  'frontend_directions' => '',
330
- 'backend_directions' => '',
331
- 'time' => time()
332
  );
333
- $hash = isset( $response['error']['code'] ) ? '#' . (int)$response['error']['code'] : '';
334
 
335
  if ( isset( $response['response'] ) && is_wp_error( $response['response'] ) ) {
336
  $error_message_return['error_message'] = __( 'HTTP Error. Unable to connect to the Instagram API.', 'instagram-feed' ) . ' ' . __( 'Feed will not update.', 'instagram-feed' );
337
- $error_message_return['admin_only'] = sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] );
338
 
339
- $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/'.$hash.'" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
340
 
341
  if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) {
342
  $num = count( $response['response']->errors );
343
- $i = 1;
344
  foreach ( $response['response']->errors as $key => $item ) {
345
- $error_message_return['admin_only'] .= ' '.$key . ' - ' . $item[0];
346
  if ( $i < $num ) {
347
  $error_message_return['admin_only'] .= ',';
348
  }
@@ -352,34 +351,34 @@ class SB_Instagram_Posts_Manager
352
 
353
  return $error_message_return;
354
  }
355
- $hash = '#' . (int)$response['error']['code'];
356
  $link = admin_url( '?page=sb-instagram-feed' );
357
 
358
  if ( isset( $response['error']['message'] ) ) {
359
- if ( (int)$response['error']['code'] === 100 ) {
360
- $error_message_return['error_message'] = __( 'Error: Access Token is not valid or has expired.', 'instagram-feed' ) . ' ' . __( 'Feed will not update.', 'instagram-feed' );
361
- $error_message_return['admin_only'] = sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message'];
362
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
363
- } elseif ( (int)$response['error']['code'] === 18 ) {
364
- $error_message_return['error_message'] = __( 'Error: Hashtag limit of 30 unique hashtags per week has been reached.', 'instagram-feed' );
365
- $error_message_return['admin_only'] = __( 'If you need to display more than 30 hashtag feeds on your site, consider connecting an additional business account from a separate Instagram Identity and Facebook page. Connecting an additional Instagram business account from the same Facebook page will not raise the limit.', 'instagram-feed' );
366
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
367
- } elseif ( (int)$response['error']['code'] === 10 ) {
368
- $error_message_return['error_message'] = sprintf( __( 'Error: Connected account for the user %s does not have permission to use this feed type.', 'instagram-feed' ), $connected_account['username'] );
369
- $error_message_return['admin_only'] = __( 'Try using the big blue button on the "Configure" tab to reconnect the account and update its permissions.', 'instagram-feed' );
370
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
371
- } elseif ( (int)$response['error']['code'] === 24 ) {
372
- $error_message_return['error_message'] = __( 'Error: Cannot retrieve posts for this hashtag.', 'instagram-feed' );
373
- $error_message_return['admin_only'] = $response['error']['error_user_msg'];
374
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
375
  } else {
376
- $error_message_return['error_message'] = __( 'There has been a problem with your Instagram Feed.', 'instagram-feed' );
377
- $error_message_return['admin_only'] = sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message'];
378
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
379
  }
380
  } else {
381
  $error_message_return['error_message'] = __( 'An unknown error has occurred.', 'instagram-feed' );
382
- $error_message_return['admin_only'] = json_encode( $response );
383
  }
384
  return $error_message_return;
385
  }
@@ -432,14 +431,14 @@ class SB_Instagram_Posts_Manager
432
  */
433
  public function delete_least_used_image() {
434
  global $wpdb;
435
- $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
436
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
437
 
438
  $max = isset( $this->limit ) && $this->limit > 1 ? $this->limit : 1;
439
 
440
  $oldest_posts = $wpdb->get_results( "SELECT id, media_id FROM $table_name ORDER BY last_requested ASC LIMIT $max", ARRAY_A );
441
 
442
- $upload = wp_upload_dir();
443
  $file_suffixes = array( 'thumb', 'low', 'full' );
444
 
445
  foreach ( $oldest_posts as $post ) {
@@ -470,11 +469,11 @@ class SB_Instagram_Posts_Manager
470
 
471
  $num_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );
472
 
473
- if ( !isset( $this->limit ) && (int)$num_records > SBI_MAX_RECORDS ) {
474
- $this->limit = (int)$num_records - SBI_MAX_RECORDS;
475
  }
476
 
477
- return ((int)$num_records > SBI_MAX_RECORDS);
478
  }
479
 
480
  /**
@@ -493,7 +492,7 @@ class SB_Instagram_Posts_Manager
493
 
494
  $num_new_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE created_on > '$fifteen_minutes_ago'" );
495
 
496
- return ((int)$num_new_records > 100);
497
  }
498
 
499
  /**
@@ -502,7 +501,7 @@ class SB_Instagram_Posts_Manager
502
  * @since 2.0/4.0
503
  */
504
  public function image_resizing_disabled( $data = false ) {
505
- $options = sbi_get_database_settings();
506
  $disable_resizing = isset( $options['sb_instagram_disable_resize'] ) ? $options['sb_instagram_disable_resize'] === 'on' || $options['sb_instagram_disable_resize'] === true : false;
507
  $disable_resizing = apply_filters( 'sbi_image_resizing_disabled', $disable_resizing, $data );
508
 
@@ -524,14 +523,14 @@ class SB_Instagram_Posts_Manager
524
  public function does_resizing_tables_exist() {
525
  global $wpdb;
526
 
527
- $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
528
- $resizing_key = "sbi_resizing_exists";
529
 
530
  $sbi_resizing_cache = wp_cache_get( $resizing_key );
531
 
532
  if ( false === $sbi_resizing_cache ) {
533
 
534
- if ( $wpdb->get_var( "show tables like '$table_name'" ) == $table_name ) {
535
  wp_cache_set( $resizing_key, true );
536
  } else {
537
  wp_cache_set( $resizing_key, false );
@@ -554,15 +553,15 @@ class SB_Instagram_Posts_Manager
554
 
555
  $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
556
 
557
- $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . '*' ); // get all file names
558
  foreach ( $image_files as $file ) { // iterate files
559
  if ( is_file( $file ) ) {
560
  unlink( $file );
561
  }
562
  }
563
 
564
- $options = get_option( 'sb_instagram_settings', array() );
565
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
566
 
567
  foreach ( $connected_accounts as $account_id => $data ) {
568
  if ( isset( $data['local_avatar'] ) ) {
@@ -580,21 +579,25 @@ class SB_Instagram_Posts_Manager
580
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
581
  $wpdb->query( "DROP TABLE IF EXISTS $feeds_posts_table_name" );
582
 
583
- $table_name = $wpdb->prefix . "options";
584
 
585
- $wpdb->query( "
 
586
  DELETE
587
  FROM $table_name
588
  WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
589
- " );
590
- $wpdb->query( "
 
 
591
  DELETE
592
  FROM $table_name
593
  WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
594
- " );
 
595
  delete_option( 'sbi_hashtag_ids' );
596
 
597
- $upload = wp_upload_dir();
598
  $upload_dir = $upload['basedir'];
599
  $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
600
  if ( ! file_exists( $upload_dir ) ) {
@@ -659,7 +662,7 @@ class SB_Instagram_Posts_Manager
659
 
660
  if ( ! empty( $this->errors[ $type ] ) ) {
661
  $this->errors[ $type ] = array();
662
- $this->add_action_log( 'Cleared ' . $type .' error.' );
663
  $update = true;
664
  }
665
 
@@ -676,8 +679,8 @@ class SB_Instagram_Posts_Manager
676
  }
677
 
678
  if ( ! empty( $this->errors['revoked'] ) ) {
679
- if (($key = array_search($connected_account['user_id'], $this->errors['revoked'])) !== false) {
680
- unset($this->errors['revoked'][$key]);
681
  }
682
  }
683
 
@@ -712,7 +715,7 @@ class SB_Instagram_Posts_Manager
712
  unset( $this->errors['accounts'][ $account_id ] );
713
  } else {
714
  foreach ( $error_types as $error_type => $details ) {
715
- if ( (string)$account_id === (string)$clearing_account_id ) {
716
  if ( $error_type === $clearing_error_type || $clearing_error_type === 'all' ) {
717
  unset( $this->errors['accounts'][ $account_id ][ $error_type ] );
718
  $cleared = true;
@@ -741,7 +744,6 @@ class SB_Instagram_Posts_Manager
741
  unset( $this->errors['accounts'][ $account_id ] );
742
  }
743
  }
744
-
745
  }
746
 
747
  if ( $update ) {
@@ -769,7 +771,7 @@ class SB_Instagram_Posts_Manager
769
  */
770
  public function reset_api_errors() {
771
  $this->errors['connection'] = array();
772
- $this->errors['accounts'] = array();
773
 
774
  update_option( 'sb_instagram_errors', $this->errors, false );
775
  sb_instagram_cron_clear_cache();
@@ -817,7 +819,7 @@ class SB_Instagram_Posts_Manager
817
  $error_messages[] = $this->display_error['configuration'];
818
  }
819
  if ( ! empty( $this->display_error['hashtag'][0] ) ) {
820
- $error_24 = array();
821
  $error_24_message = array();
822
  foreach ( $this->display_error['hashtag'] as $hashtag_error ) {
823
  if ( $hashtag_error['error_id'] === 24 ) {
@@ -825,7 +827,7 @@ class SB_Instagram_Posts_Manager
825
  $error_24[] = $hashtag_error['hashtag'];
826
  }
827
  if ( empty( $error_24_message ) ) {
828
- $error_24_message = $hashtag_error['error_message'];
829
  $error_24_message['admin_only'] = str_replace( $hashtag_error['hashtag'], '###', $error_24_message['admin_only'] );
830
  }
831
  } else {
@@ -833,15 +835,14 @@ class SB_Instagram_Posts_Manager
833
  }
834
  }
835
  if ( ! empty( $error_24_message ) ) {
836
- $hashtag_string = count( $error_24 ) > 1 ? implode( '", "', $error_24 ) : $error_24[0];
837
  $error_24_message['admin_only'] = str_replace( '###', $hashtag_string, $error_24_message['admin_only'] );
838
- $error_messages[] = $error_24_message;
839
  }
840
-
841
  }
842
  if ( ! empty( $this->display_error['hashtag_limit'] ) ) {
843
  $response = array(
844
- 'error' => $this->display_error['hashtag_limit']['error']
845
  );
846
 
847
  $error_messages[] = $this->generate_error_message( $response );
@@ -920,16 +921,16 @@ class SB_Instagram_Posts_Manager
920
 
921
  $to_save = array();
922
  $changed = false;
923
- $return = false;
924
 
925
  foreach ( $this->errors['hashtag'] as $hashtag_error ) {
926
  if ( ! empty( $hashtag_error['hashtag'] )
927
- && strtolower( $hashtag_error['hashtag'] ) === strtolower( $hashtag ) ) {
928
  if ( ! empty( $hashtag_error['clear_time'] ) ) {
929
 
930
- if ( $hashtag_error['clear_time'] < time() ) {
931
  $changed = true;
932
- $return = false;
933
  // clear the error, return false
934
  } else {
935
  $to_save[] = $hashtag_error;
@@ -939,7 +940,7 @@ class SB_Instagram_Posts_Manager
939
  }
940
  } else {
941
  if ( ! empty( $hashtag_error['clear_time'] ) ) {
942
- if ( $hashtag_error['clear_time'] < time() ) {
943
  $changed = true;
944
  } else {
945
  $to_save[] = $hashtag_error;
@@ -948,7 +949,6 @@ class SB_Instagram_Posts_Manager
948
  $to_save[] = $hashtag_error;
949
  }
950
  }
951
-
952
  }
953
 
954
  if ( $changed ) {
@@ -973,31 +973,31 @@ class SB_Instagram_Posts_Manager
973
  $error_message = '';
974
 
975
  $error_message_array = $errors['connection']['error_message'];
976
- $error_message .= '<strong>' . $error_message_array['error_message'] . '</strong><br>';
977
- $error_message .= $error_message_array['admin_only'] . '<br><br>';
978
  if ( ! empty( $error_message_array['backend_directions'] ) ) {
979
  $error_message .= $error_message_array['backend_directions'];
980
  } else {
981
- $hash = isset( $errors['connection']['error_id'] ) ? '#' . (int)$errors['connection']['error_id'] : '';
982
- $error_message .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/'.$hash.'" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
983
  }
984
  } else {
985
- $options = sbi_get_database_settings();
986
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
987
  foreach ( $connected_accounts as $connected_account ) {
988
  if ( isset( $connected_account['private'] )
989
- && sbi_private_account_near_expiration( $connected_account ) ) {
990
- $link_1 = '<a href="https://help.instagram.com/116024195217477/In">';
991
- $link_2 = '</a>';
992
  $error_message_array = array(
993
- 'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ),
994
- 'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %smake your Instagram account public%s.', 'instagram-feed' ), $link_1, $link_2 ),
995
  'frontend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/#10">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
996
- 'backend_directions' => ''
997
  );
998
  }
999
 
1000
- if ( isset( $this->errors['accounts'][ $connected_account['user_id' ] ]['api'] ) ) {
1001
  if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api']['error'] ) ) {
1002
  if ( $this->is_critical_error( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] ) ) {
1003
  $error_message_array = $this->generate_error_message( $this->errors['accounts'][ $connected_account['user_id'] ]['api'], $connected_account );
@@ -1006,14 +1006,13 @@ class SB_Instagram_Posts_Manager
1006
  }
1007
 
1008
  if ( ! isset( $error_message ) && isset( $error_message_array ) ) {
1009
- $error_message = $error_message_array['admin_only'] . '<br><br>';
1010
  if ( ! empty( $error_message_array['backend_directions'] ) ) {
1011
  $error_message .= $error_message_array['backend_directions'];
1012
  } else {
1013
  $error_message .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
1014
  }
1015
  }
1016
-
1017
  }
1018
  }
1019
  if ( isset( $error_message ) ) {
@@ -1042,13 +1041,12 @@ class SB_Instagram_Posts_Manager
1042
  */
1043
  public function clear_api_request_delays() {
1044
  if ( empty( $this->errors['accounts'] )
1045
- && empty( $this->errors['hashtag'] ) ) {
1046
  return;
1047
  }
1048
 
1049
-
1050
  $changed = false;
1051
- foreach( $this->errors['accounts'] as $account_id => $account_error ) {
1052
  if ( ! empty( $account_error['api']['clear_time'] ) ) {
1053
  $this->errors['accounts'][ $account_id ]['api']['clear_time'] = 0;
1054
  }
@@ -1059,7 +1057,7 @@ class SB_Instagram_Posts_Manager
1059
  if ( ! empty( $hashtag_error['hashtag'] ) ) {
1060
  if ( ! empty( $hashtag_error['clear_time'] ) ) {
1061
  $this->errors['hashtag'][ $key ]['clear_time'] = 0;
1062
- $changed = true;
1063
  }
1064
  }
1065
  }
@@ -1084,15 +1082,15 @@ class SB_Instagram_Posts_Manager
1084
 
1085
  if ( $this->errors['accounts'][ $account_id ]['api']['clear_time'] < time() ) {
1086
  $is_delay = false;
1087
- return apply_filters( 'sbi_is_api_delay', $is_delay );
1088
  } else {
1089
  $is_delay = true;
1090
- return apply_filters( 'sbi_is_api_delay', $is_delay );
1091
  }
1092
  }
1093
  }
1094
 
1095
- return apply_filters( 'sbi_is_api_delay', $is_delay );
1096
  }
1097
 
1098
  /**
@@ -1104,15 +1102,15 @@ class SB_Instagram_Posts_Manager
1104
  if ( isset( $this->errors['connection']['critical'] ) ) {
1105
  return true;
1106
  } else {
1107
- $options = sbi_get_database_settings();
1108
- $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
1109
  foreach ( $connected_accounts as $connected_account ) {
1110
  if ( isset( $connected_account['private'] )
1111
- && sbi_private_account_near_expiration( $connected_account ) ) {
1112
  return true;
1113
  }
1114
 
1115
- if ( isset( $this->errors['accounts'][ $connected_account['user_id' ] ]['api'] ) ) {
1116
  if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api']['error'] ) ) {
1117
  return $this->is_critical_error( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] );
1118
  }
@@ -1146,15 +1144,15 @@ class SB_Instagram_Posts_Manager
1146
  public function delete_platform_data( $to_delete_connected_account ) {
1147
 
1148
  $are_other_business_accounts = false;
1149
- $all_connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts();
1150
 
1151
  $to_update = array();
1152
  foreach ( $all_connected_accounts as $connected_account ) {
1153
- if ( (int)$connected_account['user_id'] !== (int)$to_delete_connected_account['user_id'] ) {
1154
  $to_update[ $connected_account['user_id'] ] = $connected_account;
1155
 
1156
  if ( isset( $connected_account['type'] )
1157
- && $connected_account['type'] === 'business' ) {
1158
  $are_other_business_accounts = true;
1159
  }
1160
  }
@@ -1175,4 +1173,4 @@ class SB_Instagram_Posts_Manager
1175
  }
1176
 
1177
 
1178
- }
12
  die( '-1' );
13
  }
14
 
15
+ class SB_Instagram_Posts_Manager {
16
+
17
  /**
18
  * @var mixed|void
19
  */
44
  */
45
  public function __construct() {
46
  $this->sbi_options = get_option( 'sb_instagram_settings' );
47
+ $this->errors = get_option( 'sb_instagram_errors', array() );
48
  if ( ! isset( $this->errors['connection'] ) ) {
49
  $this->errors = array(
50
+ 'connection' => array(),
51
+ 'hashtag' => array(),
52
+ 'resizing' => array(),
53
  'database_create' => array(),
54
+ 'upload_dir' => array(),
55
+ 'accounts' => array(),
56
+ 'error_log' => array(),
57
+ 'action_log' => array(),
58
+ 'revoked' => array(),
59
  );
60
  }
61
 
83
  }
84
 
85
  if ( isset( $details['error']['code'] )
86
+ && (int) $details['error']['code'] === 18 ) {
87
  $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 15;
88
  }
89
  }
114
 
115
  // is it connection? or what type?
116
  if ( $type === 'api'
117
+ || $type === 'wp_remote_get' ) {
118
  $connection_details = array(
119
+ 'error_id' => '',
120
  );
121
 
122
  $connection_details['critical'] = false;
123
  if ( isset( $details['error']['code'] ) ) {
124
  $connection_details['error_id'] = $details['error']['code'];
125
 
 
126
  if ( $this->is_critical_error( $details ) ) {
127
  $connection_details['critical'] = true;
128
  }
144
  $connection_details['post_id'] = get_the_ID();
145
  }
146
  $connection_details['error_message'] = $this->generate_error_message( $details, $connected_account );
147
+ $log_item .= $connection_details['error_message']['admin_only'];
148
  $this->maybe_set_display_error( 'connection', $connection_details );
149
  $this->errors['connection'] = $connection_details;
150
  }
152
  if ( $type === 'hashtag' ) {
153
  $hashtag_details = array(
154
  'error_id' => '',
155
+ 'hashtag' => isset( $details['hashtag'] ) ? $details['hashtag'] : '',
156
  );
157
  if ( isset( $details['error']['code'] ) ) {
158
+ if ( (int) $details['error']['code'] === 24 ) {
159
  $hashtag_details['clear_time'] = time() + 60 * 5;
160
  }
161
  }
171
  $hashtag_details['post_id'] = get_the_ID();
172
  }
173
  $hashtag_details['error_message'] = $this->generate_error_message( $details, $connected_account );
174
+ $log_item .= $hashtag_details['error_message']['admin_only'];
175
  $this->maybe_set_display_error( 'hashtag', $hashtag_details );
176
 
177
  $found = false;
178
  if ( isset( $details['hashtag'] ) ) {
179
  foreach ( $this->errors['hashtag'] as $hashtag_error_item ) {
180
  if ( isset( $hashtag_error_item['hashtag'] )
181
+ && strtolower( $hashtag_error_item['hashtag'] ) === strtolower( $details['hashtag'] )
182
+ && $hashtag_error_item['error_id'] === $details['error_id'] ) {
183
  $found = true;
184
  }
185
  }
191
  }
192
 
193
  if ( $type === 'image_editor'
194
+ || $type === 'storage' ) {
195
 
196
  $this->errors['resizing'] = $details;
197
+ $log_item .= $details;
198
  }
199
 
200
  if ( $type === 'database_create' ) {
201
  $this->errors['database_create'] = $details;
202
+ $log_item .= $details;
203
  }
204
 
205
  if ( $type === 'upload_dir' ) {
206
  $this->errors['upload_dir'] = $details;
207
+ $log_item .= $details;
208
  }
209
 
210
  $current_log = $this->errors['error_log'];
212
  reset( $current_log );
213
  unset( $current_log[ key( $current_log ) ] );
214
  }
215
+ $current_log[] = $log_item;
216
  $this->errors['error_log'] = $current_log;
217
  update_option( 'sb_instagram_errors', $this->errors, false );
218
  }
267
  * @since 2.7/5.10
268
  */
269
  public function is_critical_error( $details ) {
270
+ $error_code = (int) $details['error']['code'];
271
 
272
  $critical_codes = array(
273
  803, // ID doesn't exist
289
  * @since 2.7/5.10
290
  */
291
  public function is_app_permission_related( $details ) {
292
+ $error_code = (int) $details['error']['code'];
293
+ $error_subcode = isset( $details['error']['error_subcode'] ) ? (int) $details['error']['error_subcode'] : 0;
294
 
295
  $critical_codes = array(
296
  190, // access token or permissions
323
  public function generate_error_message( $response, $connected_account = array( 'username' => '' ) ) {
324
 
325
  $error_message_return = array(
326
+ 'error_message' => '',
327
+ 'admin_only' => '',
328
  'frontend_directions' => '',
329
+ 'backend_directions' => '',
330
+ 'time' => time(),
331
  );
332
+ $hash = isset( $response['error']['code'] ) ? '#' . (int) $response['error']['code'] : '';
333
 
334
  if ( isset( $response['response'] ) && is_wp_error( $response['response'] ) ) {
335
  $error_message_return['error_message'] = __( 'HTTP Error. Unable to connect to the Instagram API.', 'instagram-feed' ) . ' ' . __( 'Feed will not update.', 'instagram-feed' );
336
+ $error_message_return['admin_only'] = sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] );
337
 
338
+ $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
339
 
340
  if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) {
341
  $num = count( $response['response']->errors );
342
+ $i = 1;
343
  foreach ( $response['response']->errors as $key => $item ) {
344
+ $error_message_return['admin_only'] .= ' ' . $key . ' - ' . $item[0];
345
  if ( $i < $num ) {
346
  $error_message_return['admin_only'] .= ',';
347
  }
351
 
352
  return $error_message_return;
353
  }
354
+ $hash = '#' . (int) $response['error']['code'];
355
  $link = admin_url( '?page=sb-instagram-feed' );
356
 
357
  if ( isset( $response['error']['message'] ) ) {
358
+ if ( (int) $response['error']['code'] === 100 ) {
359
+ $error_message_return['error_message'] = __( 'Error: Access Token is not valid or has expired.', 'instagram-feed' ) . ' ' . __( 'Feed will not update.', 'instagram-feed' );
360
+ $error_message_return['admin_only'] = sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message'];
361
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
362
+ } elseif ( (int) $response['error']['code'] === 18 ) {
363
+ $error_message_return['error_message'] = __( 'Error: Hashtag limit of 30 unique hashtags per week has been reached.', 'instagram-feed' );
364
+ $error_message_return['admin_only'] = __( 'If you need to display more than 30 hashtag feeds on your site, consider connecting an additional business account from a separate Instagram Identity and Facebook page. Connecting an additional Instagram business account from the same Facebook page will not raise the limit.', 'instagram-feed' );
365
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
366
+ } elseif ( (int) $response['error']['code'] === 10 ) {
367
+ $error_message_return['error_message'] = sprintf( __( 'Error: Connected account for the user %s does not have permission to use this feed type.', 'instagram-feed' ), $connected_account['username'] );
368
+ $error_message_return['admin_only'] = __( 'Try using the big blue button on the "Configure" tab to reconnect the account and update its permissions.', 'instagram-feed' );
369
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
370
+ } elseif ( (int) $response['error']['code'] === 24 ) {
371
+ $error_message_return['error_message'] = __( 'Error: Cannot retrieve posts for this hashtag.', 'instagram-feed' );
372
+ $error_message_return['admin_only'] = $response['error']['error_user_msg'];
373
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
374
  } else {
375
+ $error_message_return['error_message'] = __( 'There has been a problem with your Instagram Feed.', 'instagram-feed' );
376
+ $error_message_return['admin_only'] = sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message'];
377
  $error_message_return['frontend_directions'] = '<a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a>';
378
  }
379
  } else {
380
  $error_message_return['error_message'] = __( 'An unknown error has occurred.', 'instagram-feed' );
381
+ $error_message_return['admin_only'] = sbi_json_encode( $response );
382
  }
383
  return $error_message_return;
384
  }
431
  */
432
  public function delete_least_used_image() {
433
  global $wpdb;
434
+ $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
435
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
436
 
437
  $max = isset( $this->limit ) && $this->limit > 1 ? $this->limit : 1;
438
 
439
  $oldest_posts = $wpdb->get_results( "SELECT id, media_id FROM $table_name ORDER BY last_requested ASC LIMIT $max", ARRAY_A );
440
 
441
+ $upload = wp_upload_dir();
442
  $file_suffixes = array( 'thumb', 'low', 'full' );
443
 
444
  foreach ( $oldest_posts as $post ) {
469
 
470
  $num_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );
471
 
472
+ if ( ! isset( $this->limit ) && (int) $num_records > SBI_MAX_RECORDS ) {
473
+ $this->limit = (int) $num_records - SBI_MAX_RECORDS;
474
  }
475
 
476
+ return ( (int) $num_records > SBI_MAX_RECORDS );
477
  }
478
 
479
  /**
492
 
493
  $num_new_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE created_on > '$fifteen_minutes_ago'" );
494
 
495
+ return ( (int) $num_new_records > 100 );
496
  }
497
 
498
  /**
501
  * @since 2.0/4.0
502
  */
503
  public function image_resizing_disabled( $data = false ) {
504
+ $options = sbi_get_database_settings();
505
  $disable_resizing = isset( $options['sb_instagram_disable_resize'] ) ? $options['sb_instagram_disable_resize'] === 'on' || $options['sb_instagram_disable_resize'] === true : false;
506
  $disable_resizing = apply_filters( 'sbi_image_resizing_disabled', $disable_resizing, $data );
507
 
523
  public function does_resizing_tables_exist() {
524
  global $wpdb;
525
 
526
+ $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
527
+ $resizing_key = 'sbi_resizing_exists';
528
 
529
  $sbi_resizing_cache = wp_cache_get( $resizing_key );
530
 
531
  if ( false === $sbi_resizing_cache ) {
532
 
533
+ if ( $wpdb->get_var( "show tables like '$table_name'" ) === $table_name ) {
534
  wp_cache_set( $resizing_key, true );
535
  } else {
536
  wp_cache_set( $resizing_key, false );
553
 
554
  $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
555
 
556
+ $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . '*' ); // get all file names
557
  foreach ( $image_files as $file ) { // iterate files
558
  if ( is_file( $file ) ) {
559
  unlink( $file );
560
  }
561
  }
562
 
563
+ $options = get_option( 'sb_instagram_settings', array() );
564
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
565
 
566
  foreach ( $connected_accounts as $account_id => $data ) {
567
  if ( isset( $data['local_avatar'] ) ) {
579
  $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS );
580
  $wpdb->query( "DROP TABLE IF EXISTS $feeds_posts_table_name" );
581
 
582
+ $table_name = $wpdb->prefix . 'options';
583
 
584
+ $wpdb->query(
585
+ "
586
  DELETE
587
  FROM $table_name
588
  WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
589
+ "
590
+ );
591
+ $wpdb->query(
592
+ "
593
  DELETE
594
  FROM $table_name
595
  WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
596
+ "
597
+ );
598
  delete_option( 'sbi_hashtag_ids' );
599
 
600
+ $upload = wp_upload_dir();
601
  $upload_dir = $upload['basedir'];
602
  $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
603
  if ( ! file_exists( $upload_dir ) ) {
662
 
663
  if ( ! empty( $this->errors[ $type ] ) ) {
664
  $this->errors[ $type ] = array();
665
+ $this->add_action_log( 'Cleared ' . $type . ' error.' );
666
  $update = true;
667
  }
668
 
679
  }
680
 
681
  if ( ! empty( $this->errors['revoked'] ) ) {
682
+ if ( ( $key = array_search( $connected_account['user_id'], $this->errors['revoked'], true ) ) !== false ) {
683
+ unset( $this->errors['revoked'][ $key ] );
684
  }
685
  }
686
 
715
  unset( $this->errors['accounts'][ $account_id ] );
716
  } else {
717
  foreach ( $error_types as $error_type => $details ) {
718
+ if ( (string) $account_id === (string) $clearing_account_id ) {
719
  if ( $error_type === $clearing_error_type || $clearing_error_type === 'all' ) {
720
  unset( $this->errors['accounts'][ $account_id ][ $error_type ] );
721
  $cleared = true;
744
  unset( $this->errors['accounts'][ $account_id ] );
745
  }
746
  }
 
747
  }
748
 
749
  if ( $update ) {
771
  */
772
  public function reset_api_errors() {
773
  $this->errors['connection'] = array();
774
+ $this->errors['accounts'] = array();
775
 
776
  update_option( 'sb_instagram_errors', $this->errors, false );
777
  sb_instagram_cron_clear_cache();
819
  $error_messages[] = $this->display_error['configuration'];
820
  }
821
  if ( ! empty( $this->display_error['hashtag'][0] ) ) {
822
+ $error_24 = array();
823
  $error_24_message = array();
824
  foreach ( $this->display_error['hashtag'] as $hashtag_error ) {
825
  if ( $hashtag_error['error_id'] === 24 ) {
827
  $error_24[] = $hashtag_error['hashtag'];
828
  }
829
  if ( empty( $error_24_message ) ) {
830
+ $error_24_message = $hashtag_error['error_message'];
831
  $error_24_message['admin_only'] = str_replace( $hashtag_error['hashtag'], '###', $error_24_message['admin_only'] );
832
  }
833
  } else {
835
  }
836
  }
837
  if ( ! empty( $error_24_message ) ) {
838
+ $hashtag_string = count( $error_24 ) > 1 ? implode( '", "', $error_24 ) : $error_24[0];
839
  $error_24_message['admin_only'] = str_replace( '###', $hashtag_string, $error_24_message['admin_only'] );
840
+ $error_messages[] = $error_24_message;
841
  }
 
842
  }
843
  if ( ! empty( $this->display_error['hashtag_limit'] ) ) {
844
  $response = array(
845
+ 'error' => $this->display_error['hashtag_limit']['error'],
846
  );
847
 
848
  $error_messages[] = $this->generate_error_message( $response );
921
 
922
  $to_save = array();
923
  $changed = false;
924
+ $return = false;
925
 
926
  foreach ( $this->errors['hashtag'] as $hashtag_error ) {
927
  if ( ! empty( $hashtag_error['hashtag'] )
928
+ && strtolower( $hashtag_error['hashtag'] ) === strtolower( $hashtag ) ) {
929
  if ( ! empty( $hashtag_error['clear_time'] ) ) {
930
 
931
+ if ( $hashtag_error['clear_time'] < time() ) {
932
  $changed = true;
933
+ $return = false;
934
  // clear the error, return false
935
  } else {
936
  $to_save[] = $hashtag_error;
940
  }
941
  } else {
942
  if ( ! empty( $hashtag_error['clear_time'] ) ) {
943
+ if ( $hashtag_error['clear_time'] < time() ) {
944
  $changed = true;
945
  } else {
946
  $to_save[] = $hashtag_error;
949
  $to_save[] = $hashtag_error;
950
  }
951
  }
 
952
  }
953
 
954
  if ( $changed ) {
973
  $error_message = '';
974
 
975
  $error_message_array = $errors['connection']['error_message'];
976
+ $error_message .= '<strong>' . $error_message_array['error_message'] . '</strong><br>';
977
+ $error_message .= $error_message_array['admin_only'] . '<br><br>';
978
  if ( ! empty( $error_message_array['backend_directions'] ) ) {
979
  $error_message .= $error_message_array['backend_directions'];
980
  } else {
981
+ $hash = isset( $errors['connection']['error_id'] ) ? '#' . (int) $errors['connection']['error_id'] : '';
982
+ $error_message .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/' . $hash . '" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
983
  }
984
  } else {
985
+ $options = sbi_get_database_settings();
986
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
987
  foreach ( $connected_accounts as $connected_account ) {
988
  if ( isset( $connected_account['private'] )
989
+ && sbi_private_account_near_expiration( $connected_account ) ) {
990
+ $link_1 = '<a href="https://help.instagram.com/116024195217477/In">';
991
+ $link_2 = '</a>';
992
  $error_message_array = array(
993
+ 'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ),
994
+ 'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %1$smake your Instagram account public%2$s.', 'instagram-feed' ), $link_1, $link_2 ),
995
  'frontend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/#10">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
996
+ 'backend_directions' => '',
997
  );
998
  }
999
 
1000
+ if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] ) ) {
1001
  if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api']['error'] ) ) {
1002
  if ( $this->is_critical_error( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] ) ) {
1003
  $error_message_array = $this->generate_error_message( $this->errors['accounts'][ $connected_account['user_id'] ]['api'], $connected_account );
1006
  }
1007
 
1008
  if ( ! isset( $error_message ) && isset( $error_message_array ) ) {
1009
+ $error_message = $error_message_array['admin_only'] . '<br><br>';
1010
  if ( ! empty( $error_message_array['backend_directions'] ) ) {
1011
  $error_message .= $error_message_array['backend_directions'];
1012
  } else {
1013
  $error_message .= '<p class="sbi-error-directions"><a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '</a></p>';
1014
  }
1015
  }
 
1016
  }
1017
  }
1018
  if ( isset( $error_message ) ) {
1041
  */
1042
  public function clear_api_request_delays() {
1043
  if ( empty( $this->errors['accounts'] )
1044
+ && empty( $this->errors['hashtag'] ) ) {
1045
  return;
1046
  }
1047
 
 
1048
  $changed = false;
1049
+ foreach ( $this->errors['accounts'] as $account_id => $account_error ) {
1050
  if ( ! empty( $account_error['api']['clear_time'] ) ) {
1051
  $this->errors['accounts'][ $account_id ]['api']['clear_time'] = 0;
1052
  }
1057
  if ( ! empty( $hashtag_error['hashtag'] ) ) {
1058
  if ( ! empty( $hashtag_error['clear_time'] ) ) {
1059
  $this->errors['hashtag'][ $key ]['clear_time'] = 0;
1060
+ $changed = true;
1061
  }
1062
  }
1063
  }
1082
 
1083
  if ( $this->errors['accounts'][ $account_id ]['api']['clear_time'] < time() ) {
1084
  $is_delay = false;
1085
+ return apply_filters( 'sbi_is_api_delay', $is_delay );
1086
  } else {
1087
  $is_delay = true;
1088
+ return apply_filters( 'sbi_is_api_delay', $is_delay );
1089
  }
1090
  }
1091
  }
1092
 
1093
+ return apply_filters( 'sbi_is_api_delay', $is_delay );
1094
  }
1095
 
1096
  /**
1102
  if ( isset( $this->errors['connection']['critical'] ) ) {
1103
  return true;
1104
  } else {
1105
+ $options = sbi_get_database_settings();
1106
+ $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
1107
  foreach ( $connected_accounts as $connected_account ) {
1108
  if ( isset( $connected_account['private'] )
1109
+ && sbi_private_account_near_expiration( $connected_account ) ) {
1110
  return true;
1111
  }
1112
 
1113
+ if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] ) ) {
1114
  if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api']['error'] ) ) {
1115
  return $this->is_critical_error( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] );
1116
  }
1144
  public function delete_platform_data( $to_delete_connected_account ) {
1145
 
1146
  $are_other_business_accounts = false;
1147
+ $all_connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts();
1148
 
1149
  $to_update = array();
1150
  foreach ( $all_connected_accounts as $connected_account ) {
1151
+ if ( (int) $connected_account['user_id'] !== (int) $to_delete_connected_account['user_id'] ) {
1152
  $to_update[ $connected_account['user_id'] ] = $connected_account;
1153
 
1154
  if ( isset( $connected_account['type'] )
1155
+ && $connected_account['type'] === 'business' ) {
1156
  $are_other_business_accounts = true;
1157
  }
1158
  }
1173
  }
1174
 
1175
 
1176
+ }
inc/class-sb-instagram-settings.php CHANGED
@@ -60,7 +60,7 @@ class SB_Instagram_Settings {
60
  * @param array $db settings from the wp_options table
61
  */
62
  public function __construct( $atts, $db ) {
63
- $this->feed_type_and_terms = array();
64
  $this->connected_accounts_in_feed = array();
65
 
66
  $this->atts = $atts;
@@ -79,7 +79,7 @@ class SB_Instagram_Settings {
79
  'sortby' => isset( $db['sb_instagram_sort'] ) ? $db['sb_instagram_sort'] : '',
80
  'num' => isset( $db['sb_instagram_num'] ) ? $db['sb_instagram_num'] : '',
81
  'apinum' => isset( $db['sb_instagram_minnum'] ) ? $db['sb_instagram_minnum'] : '',
82
- 'nummobile' => isset($db[ 'sb_instagram_nummobile' ]) ? $db[ 'sb_instagram_nummobile' ] : '',
83
  'cols' => isset( $db['sb_instagram_cols'] ) ? $db['sb_instagram_cols'] : '',
84
  'disablemobile' => isset( $db['sb_instagram_disable_mobile'] ) ? $db['sb_instagram_disable_mobile'] : '',
85
  'imagepadding' => isset( $db['sb_instagram_image_padding'] ) ? $db['sb_instagram_image_padding'] : '',
@@ -97,28 +97,31 @@ class SB_Instagram_Settings {
97
  'showheader' => isset( $db['sb_instagram_show_header'] ) ? $db['sb_instagram_show_header'] : '',
98
  'headersize' => isset( $db['sb_instagram_header_size'] ) ? $db['sb_instagram_header_size'] : '',
99
  'showbio' => isset( $db['sb_instagram_show_bio'] ) ? $db['sb_instagram_show_bio'] : '',
100
- 'custombio' => isset($db[ 'sb_instagram_custom_bio' ]) ? $db[ 'sb_instagram_custom_bio' ] : '',
101
- 'customavatar' => isset($db[ 'sb_instagram_custom_avatar' ]) ? $db[ 'sb_instagram_custom_avatar' ] : '',
102
  'headercolor' => isset( $db['sb_instagram_header_color'] ) ? $db['sb_instagram_header_color'] : '',
103
  'class' => '',
104
  'ajaxtheme' => isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] : '',
105
  'cachetime' => isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : '',
106
  'media' => isset( $db['sb_instagram_media_type'] ) ? $db['sb_instagram_media_type'] : '',
107
- 'headeroutside' => isset($db[ 'sb_instagram_outside_scrollable' ]) ? $db[ 'sb_instagram_outside_scrollable' ] : '',
108
  'accesstoken' => '',
109
  'user' => isset( $db['sb_instagram_user'] ) ? $db['sb_instagram_user'] : false,
110
  'feedid' => isset( $db['sb_instagram_feed_id'] ) ? $db['sb_instagram_feed_id'] : false,
111
  'resizeprocess' => isset( $db['sb_instagram_resizeprocess'] ) ? $db['sb_instagram_resizeprocess'] : 'background',
112
- 'customtemplates' => isset( $db['custom_template'] ) ? $db['custom_template'] : '',
113
- 'gdpr' => isset( $db['gdpr'] ) ? $db['gdpr'] : 'auto',
114
- 'altresize' => isset( $db['altresize'] ) ? $db['altresize'] : true,
115
- ), $atts );
 
 
116
 
117
- $this->settings['customtemplates'] = $this->settings['customtemplates'] === 'true' || $this->settings['customtemplates'] === 'on';
 
118
  if ( isset( $_GET['sbi_debug'] ) ) {
119
  $this->settings['customtemplates'] = false;
120
  }
121
- $this->settings['minnum'] = max( (int)$this->settings['num'], (int)$this->settings['nummobile'] );
122
  $this->settings['showbio'] = $this->settings['showbio'] === 'true' || $this->settings['showbio'] === 'on' || $this->settings['showbio'] === true;
123
  if ( isset( $atts['showbio'] ) && $atts['showbio'] === 'false' ) {
124
  $this->settings['showbio'] = false;
@@ -128,36 +131,30 @@ class SB_Instagram_Settings {
128
  } elseif ( isset( $atts['showheader'] ) && $atts['showheader'] === 'true' ) {
129
  $this->settings['showheader'] = true;
130
  }
131
- $this->settings['disable_resize'] = isset( $db['sb_instagram_disable_resize'] ) && ($db['sb_instagram_disable_resize'] === 'on');
132
- $this->settings['favor_local'] = ! isset( $db['sb_instagram_favor_local'] ) || ($db['sb_instagram_favor_local'] === 'on') || ($db['sb_instagram_favor_local'] === true);
133
- $this->settings['backup_cache_enabled'] = ! isset( $db['sb_instagram_backup'] ) || ($db['sb_instagram_backup'] === 'on') || $db['sb_instagram_backup'] === true;
134
- $this->settings['headeroutside'] = ($this->settings['headeroutside'] === true || $this->settings['headeroutside'] === 'on' || $this->settings['headeroutside'] === 'true');
135
- $this->settings['disable_js_image_loading'] = isset( $db['disable_js_image_loading'] ) && ($db['disable_js_image_loading'] === 'on');
136
- $this->settings['ajax_post_load'] = isset( $db['sb_ajax_initial'] ) && ($db['sb_ajax_initial'] === 'on');
137
 
138
  switch ( $db['sbi_cache_cron_interval'] ) {
139
- case '30mins' :
140
- $this->settings['sbi_cache_cron_interval'] = 60*30;
141
  break;
142
- case '1hour' :
143
- $this->settings['sbi_cache_cron_interval'] = 60*60;
144
  break;
145
- default :
146
- $this->settings['sbi_cache_cron_interval'] = 60*60*12;
147
  }
148
 
149
- $this->settings['sb_instagram_cache_time'] = isset( $this->db['sb_instagram_cache_time'] ) ? $this->db['sb_instagram_cache_time'] : 1;
150
  $this->settings['sb_instagram_cache_time_unit'] = isset( $this->db['sb_instagram_cache_time_unit'] ) ? $this->db['sb_instagram_cache_time_unit'] : 'hours';
151
 
152
- /*global $sb_instagram_posts_manager;
153
-
154
- if ( $sb_instagram_posts_manager->are_current_api_request_delays() ) {
155
- $this->settings['alwaysUseBackup'] = true;
156
- }*/
157
-
158
  $this->settings['isgutenberg'] = SB_Instagram_Blocks::is_gb_editor();
159
  if ( $this->settings['isgutenberg'] ) {
160
- $this->settings['ajax_post_load'] = false;
161
  $this->settings['disable_js_image_loading'] = true;
162
  }
163
 
@@ -175,12 +172,12 @@ class SB_Instagram_Settings {
175
  foreach ( $this->feed_type_and_terms as $feed_type => $type_terms ) {
176
  foreach ( $type_terms as $term ) {
177
  if ( $feed_type === 'users'
178
- || $feed_type === 'tagged' ) {
179
  if ( ! in_array( $this->connected_accounts_in_feed[ $term['term'] ]['username'], $return, true ) ) {
180
  $return[] = $this->connected_accounts_in_feed[ $term['term'] ]['username'];
181
  }
182
  } elseif ( $feed_type === 'hashtags_recent'
183
- || $feed_type === 'hashtags_top' ) {
184
  if ( ! in_array( $term['hashtag_name'], $return, true ) ) {
185
  $return[] = $term['hashtag_name'];
186
  }
@@ -254,7 +251,7 @@ class SB_Instagram_Settings {
254
  'enqueue_js_in_head',
255
  'sb_instagram_disable_awesome',
256
  'sb_ajax_initial',
257
- 'use_custom'
258
  );
259
 
260
  return $public;
@@ -319,7 +316,7 @@ class SB_Instagram_Settings {
319
 
320
  if ( isset( $feed_type_and_terms['users'] ) ) {
321
  foreach ( $feed_type_and_terms['users'] as $term_and_params ) {
322
- $user = $term_and_params['term'];
323
  $connected_account = isset( $this->connected_accounts_in_feed[ $user ] ) ? $this->connected_accounts_in_feed[ $user ] : array();
324
  if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) {
325
  $sbi_transient_name .= $connected_account['username'];
@@ -373,16 +370,16 @@ class SB_Instagram_Settings {
373
  $set = false;
374
  foreach ( $this->connected_accounts as $connected_account ) {
375
  if ( ! $set && strpos( $connected_account['access_token'], '.' ) === false ) {
376
- $set = true;
377
- $this->settings['user'] = $connected_account['username'];
378
  $this->connected_accounts_in_feed = array( $connected_account['user_id'] => $connected_account );
379
- $feed_type_and_terms = array(
380
- 'users'=> array(
381
  array(
382
- 'term' => $connected_account['user_id'],
383
- 'params' => array()
384
- )
385
- )
386
  );
387
  if ( $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) {
388
  $feed_type_and_terms['users'][0]['error'] = true;
@@ -393,11 +390,11 @@ class SB_Instagram_Settings {
393
  return;
394
  } else {
395
  $connected_accounts_in_feed = array();
396
- $feed_type_and_terms = array(
397
- 'users' => array()
398
  );
399
- $usernames_included = array();
400
- $usernames_not_connected = array();
401
  foreach ( $users as $user_id_or_name ) {
402
  $connected_account = SB_Instagram_Connected_Account::lookup( $user_id_or_name );
403
 
@@ -406,27 +403,26 @@ class SB_Instagram_Settings {
406
  if ( ! $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) {
407
  $feed_type_and_terms['users'][] = array(
408
  'term' => $connected_account['user_id'],
409
- 'params' => array()
410
  );
411
  } else {
412
  $feed_type_and_terms['users'][] = array(
413
  'term' => $connected_account['user_id'],
414
  'params' => array(),
415
- 'error' => true
416
  );
417
  }
418
  $connected_accounts_in_feed[ $connected_account['user_id'] ] = $connected_account;
419
- $usernames_included[] = $connected_account['username'];
420
  }
421
  } else {
422
  $feed_type_and_terms['users'][] = array(
423
  'term' => $user_id_or_name,
424
  'params' => array(),
425
- 'error' => true
426
  );
427
- $usernames_not_connected[] = $user_id_or_name;
428
  }
429
-
430
  }
431
 
432
  if ( ! empty( $usernames_not_connected ) ) {
@@ -437,13 +433,13 @@ class SB_Instagram_Settings {
437
  $user = implode( ', ', $usernames_not_connected );
438
  }
439
 
440
- $settings_link = '<a href="'.get_admin_url().'?page=sb-instagram-feed" target="_blank">' . __( 'plugin Settings page', 'instagram-feed' ) . '</a>';
441
 
442
  $error_message_return = array(
443
- 'error_message' => sprintf( __( 'Error: There is no connected account for the user %s.', 'instagram-feed' ), $user ),
444
- 'admin_only' => sprintf( __( 'A connected account related to the user is required to display user feeds. Please connect an account for this user on the %s.', 'instagram-feed' ), $settings_link ),
445
  'frontend_directions' => '',
446
- 'backend_directions' => ''
447
  );
448
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
449
  }
@@ -469,13 +465,13 @@ class SB_Instagram_Settings {
469
  global $sb_instagram_posts_manager;
470
 
471
  $is_using_access_token_in_shortcode = ! empty( $this->atts['accesstoken'] );
472
- $settings_link = '<a href="'.get_admin_url().'?page=sb-instagram-feed" target="_blank">' . __( 'plugin Settings page', 'instagram-feed' ) . '</a>';
473
  if ( $is_using_access_token_in_shortcode ) {
474
  $error_message_return = array(
475
- 'error_message' => __( 'Error: Cannot add access token directly to the shortcode.', 'instagram-feed' ),
476
- 'admin_only' => sprintf( __( 'Due to recent Instagram platform changes, it\'s no longer possible to create a feed by adding the access token to the shortcode. Remove the access token from the shortcode and connect an account on the %s instead.', 'instagram-feed' ), $settings_link ),
477
  'frontend_directions' => '',
478
- 'backend_directions' => ''
479
  );
480
 
481
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
@@ -484,40 +480,40 @@ class SB_Instagram_Settings {
484
  }
485
 
486
  if ( empty( $this->settings['id'] )
487
- && empty( $this->settings['user'] )
488
- && ! empty ( $this->connected_accounts ) ) {
489
 
490
  $this->set_user_feed();
491
  } else {
492
  $user_array = array();
493
  if ( ! empty( $this->settings['user'] ) ) {
494
- $user_array = is_array( $this->settings['user'] ) ? $this->settings['user'] : explode( ',', str_replace( ' ', '', $this->settings['user'] ) );
495
  } elseif ( ! empty( $this->settings['id'] ) ) {
496
- $user_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
497
  }
498
 
499
  $this->set_user_feed( $user_array );
500
  }
501
  if ( empty( $this->feed_type_and_terms['users'] ) ) {
502
  $error_message_return = array(
503
- 'error_message' => __( 'Error: No users set.', 'instagram-feed' ),
504
- 'admin_only' => __( 'Please visit the plugin\'s settings page to select a user account or add one to the shortcode - user="username".', 'instagram-feed' ),
505
  'frontend_directions' => '',
506
- 'backend_directions' => ''
507
  );
508
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
509
  }
510
 
511
  foreach ( $this->connected_accounts_in_feed as $connected_account_in_feed ) {
512
  if ( isset( $connected_account_in_feed['private'] )
513
- && sbi_private_account_near_expiration( $connected_account_in_feed ) ) {
514
- $link_1 = '<a href="https://help.instagram.com/116024195217477/In">';
515
- $link_2 = '</a>';
516
  $error_message_return = array(
517
- 'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ),
518
- 'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %smake your Instagram account public%s.', 'instagram-feed' ), $link_1, $link_2 ),
519
  'frontend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/#10">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
520
- 'backend_directions' => ''
521
  );
522
 
523
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
@@ -535,161 +531,163 @@ class SB_Instagram_Settings {
535
  return SBI_CRON_UPDATE_CACHE_TIME;
536
  } else {
537
  //If the caching time doesn't exist in the database then set it to be 1 hour
538
- $cache_time = isset( $this->settings['sb_instagram_cache_time'] ) ? (int)$this->settings['sb_instagram_cache_time'] : 1;
539
  $cache_time_unit = isset( $this->settings['sb_instagram_cache_time_unit'] ) ? $this->settings['sb_instagram_cache_time_unit'] : 'hours';
540
 
541
  //Calculate the cache time in seconds
542
- if ( $cache_time_unit == 'minutes' ) $cache_time_unit = 60;
543
- if ( $cache_time_unit == 'hours' ) $cache_time_unit = 60*60;
544
- if ( $cache_time_unit == 'days' ) $cache_time_unit = 60*60*24;
545
-
546
- $cache_time_return = min( $cache_time * $cache_time_unit, DAY_IN_SECONDS );
 
 
 
 
547
 
548
- return $cache_time_return;
549
  }
550
  }
551
 
552
  public static function default_settings() {
553
  $defaults = array(
554
- 'sb_instagram_at' => '',
555
- 'sb_instagram_type' => 'user',
556
- 'sb_instagram_order' => 'top',
557
- 'sb_instagram_user_id' => '',
558
- 'sb_instagram_tagged_ids' => '',
559
- 'sb_instagram_hashtag' => '',
560
- 'sb_instagram_type_self_likes' => '',
561
- 'sb_instagram_location' => '',
562
- 'sb_instagram_coordinates' => '',
563
- 'sb_instagram_preserve_settings' => '',
564
- 'sb_instagram_ajax_theme' => false,
565
- 'enqueue_js_in_head' => false,
566
- 'disable_js_image_loading' => false,
567
- 'sb_instagram_disable_resize' => false,
568
- 'sb_instagram_favor_local' => true,
569
- 'sb_instagram_cache_time' => '1',
570
- 'sb_instagram_cache_time_unit' => 'hours',
571
- 'sbi_caching_type' => 'background',
572
- 'sbi_cache_cron_interval' => '12hours',
573
- 'sbi_cache_cron_time' => '1',
574
- 'sbi_cache_cron_am_pm' => 'am',
575
-
576
- 'sb_instagram_width' => '100',
577
- 'sb_instagram_width_unit' => '%',
578
- 'sb_instagram_feed_width_resp' => false,
579
- 'sb_instagram_height' => '',
580
- 'sb_instagram_num' => '20',
581
- 'sb_instagram_nummobile' => '',
582
- 'sb_instagram_height_unit' => '',
583
- 'sb_instagram_cols' => '4',
584
- 'sb_instagram_colsmobile' => 'auto',
585
- 'sb_instagram_image_padding' => '5',
586
- 'sb_instagram_image_padding_unit' => 'px',
587
 
588
  //Layout Type
589
- 'sb_instagram_layout_type' => 'grid',
590
- 'sb_instagram_highlight_type' => 'pattern',
591
- 'sb_instagram_highlight_offset' => 0,
592
- 'sb_instagram_highlight_factor' => 6,
593
- 'sb_instagram_highlight_ids' => '',
594
- 'sb_instagram_highlight_hashtag' => '',
595
 
596
  //Hover style
597
- 'sb_hover_background' => '',
598
- 'sb_hover_text' => '',
599
- 'sbi_hover_inc_username' => true,
600
- 'sbi_hover_inc_icon' => true,
601
- 'sbi_hover_inc_date' => true,
602
- 'sbi_hover_inc_instagram' => true,
603
- 'sbi_hover_inc_location' => false,
604
- 'sbi_hover_inc_caption' => false,
605
- 'sbi_hover_inc_likes' => false,
606
- // 'sb_instagram_hover_text_size' => '',
607
-
608
- 'sb_instagram_sort' => 'none',
609
- 'sb_instagram_disable_lightbox' => false,
610
- 'sb_instagram_captionlinks' => false,
611
- 'sb_instagram_background' => '',
612
- 'sb_instagram_show_btn' => true,
613
- 'sb_instagram_btn_background' => '',
614
- 'sb_instagram_btn_text_color' => '',
615
- 'sb_instagram_btn_text' => __( 'Load More', 'instagram-feed' ),
616
- 'sb_instagram_image_res' => 'auto',
617
- 'sb_instagram_media_type' => 'all',
618
- 'sb_instagram_moderation_mode' => 'manual',
619
- 'sb_instagram_hide_photos' => '',
620
- 'sb_instagram_block_users' => '',
621
- 'sb_instagram_ex_apply_to' => 'all',
622
- 'sb_instagram_inc_apply_to' => 'all',
623
- 'sb_instagram_show_users' => '',
624
- 'sb_instagram_exclude_words' => '',
625
- 'sb_instagram_include_words' => '',
626
 
627
  //Text
628
- 'sb_instagram_show_caption' => true,
629
- 'sb_instagram_caption_length' => '50',
630
- 'sb_instagram_caption_color' => '',
631
- 'sb_instagram_caption_size' => '13',
632
 
633
  //lightbox comments
634
- 'sb_instagram_lightbox_comments' => true,
635
- 'sb_instagram_num_comments' => '20',
636
 
637
  //Meta
638
- 'sb_instagram_show_meta' => true,
639
- 'sb_instagram_meta_color' => '',
640
- 'sb_instagram_meta_size' => '13',
641
  //Header
642
- 'sb_instagram_show_header' => true,
643
- 'sb_instagram_header_color' => '',
644
- 'sb_instagram_header_style' => 'standard',
645
- 'sb_instagram_show_followers' => true,
646
- 'sb_instagram_show_bio' => true,
647
- 'sb_instagram_custom_bio' => '',
648
- 'sb_instagram_custom_avatar' => '',
649
- 'sb_instagram_header_primary_color' => '517fa4',
650
- 'sb_instagram_header_secondary_color' => 'eeeeee',
651
- 'sb_instagram_header_size' => 'small',
652
- 'sb_instagram_outside_scrollable' => false,
653
- 'sb_instagram_stories' => true,
654
- 'sb_instagram_stories_time' => 5000,
655
 
656
  //Follow button
657
- 'sb_instagram_show_follow_btn' => true,
658
- 'sb_instagram_folow_btn_background' => '',
659
- 'sb_instagram_follow_btn_text_color' => '',
660
- 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
661
 
662
  //Autoscroll
663
- 'sb_instagram_autoscroll' => false,
664
- 'sb_instagram_autoscrolldistance' => 200,
665
 
666
  //Misc
667
- 'sb_instagram_custom_css' => '',
668
- 'sb_instagram_custom_js' => '',
669
- 'sb_instagram_requests_max' => '5',
670
- 'sb_instagram_minnum' => '0',
671
- 'sb_instagram_cron' => 'unset',
672
- 'sb_instagram_disable_font' => false,
673
- 'sb_instagram_backup' => true,
674
- 'sb_ajax_initial' => false,
675
- 'enqueue_css_in_shortcode' => false,
676
- 'sb_instagram_disable_mob_swipe' => false,
677
- 'sbi_br_adjust' => true,
678
- 'sb_instagram_media_vine' => false,
679
- 'custom_template' => false,
680
- 'disable_admin_notice' => false,
681
- 'enable_email_report' => 'on',
682
- 'email_notification' => 'monday',
683
- 'email_notification_addresses' => get_option( 'admin_email' ),
684
 
685
  //Carousel
686
- 'sb_instagram_carousel' => false,
687
- 'sb_instagram_carousel_rows' => 1,
688
- 'sb_instagram_carousel_loop' => 'rewind',
689
- 'sb_instagram_carousel_arrows' => false,
690
- 'sb_instagram_carousel_pag' => true,
691
- 'sb_instagram_carousel_autoplay' => false,
692
- 'sb_instagram_carousel_interval' => '5000'
693
 
694
  );
695
 
@@ -703,143 +701,259 @@ class SB_Instagram_Settings {
703
  */
704
  public static function get_allowed_atts() {
705
  $allowed_atts = array(
706
- 'id' => array(
707
- 'method' => 'alpha_numeric_and_comma',
708
- 'allowed_vals' => 'any'
709
  ),
710
- 'width' => array(
711
  'method' => 'page_load_only',
712
  ),
713
- 'widthunit'=> array(
714
  'method' => 'page_load_only',
715
  ),
716
- 'widthresp' => array(
717
  'method' => 'page_load_only',
718
  ),
719
- 'height' => array(
720
  'method' => 'page_load_only',
721
  ),
722
- 'heightunit' => array(
723
  'method' => 'page_load_only',
724
  ),
725
- 'sortby' => array(
726
- 'method' => 'enum',
727
- 'allowed_vals' => array( 'none', 'random', 'likes' )
728
  ),
729
- 'num' => array(
730
- 'method' => 'intval',
731
- 'allowed_vals' => 500
732
  ),
733
- 'nummobile' => array(
734
- 'method' => 'intval',
735
- 'allowed_vals' => 500
736
  ),
737
- 'apinum' => array(
738
- 'method' => 'intval',
739
- 'allowed_vals' => 100
740
  ),
741
- 'cols' => array(
742
- 'method' => 'intval',
743
- 'allowed_vals' => 15
744
  ),
745
- 'disablemobile' => array(
746
  'method' => 'page_load_only',
747
  ),
748
- 'imagepadding' => array(
749
  'method' => 'page_load_only',
750
  ),
751
  'imagepaddingunit' => array(
752
  'method' => 'page_load_only',
753
  ),
754
- 'background' => array(
755
  'method' => 'page_load_only',
756
  ),
757
- 'showbutton' => array(
758
  'method' => 'page_load_only',
759
  ),
760
- 'buttoncolor' => array(
761
  'method' => 'page_load_only',
762
  ),
763
- 'buttontextcolor' => array(
764
  'method' => 'page_load_only',
765
  ),
766
- 'buttontext' => array(
767
  'method' => 'page_load_only',
768
  ),
769
- 'imageres' => array(
770
- 'method' => 'enum',
771
- 'allowed_vals' => array( 'auto', 'thumb', 'low', 'full' )
772
  ),
773
- 'showfollow' => array(
774
  'method' => 'page_load_only',
775
  ),
776
- 'followcolor' => array(
777
  'method' => 'page_load_only',
778
  ),
779
- 'followtextcolor' => array(
780
  'method' => 'page_load_only',
781
  ),
782
- 'followtext' => array(
783
  'method' => 'page_load_only',
784
  ),
785
- 'showheader' => array(
786
  'method' => 'page_load_only',
787
  ),
788
- 'headersize' => array(
789
  'method' => 'page_load_only',
790
  ),
791
- 'showbio' => array(
792
  'method' => 'page_load_only',
793
  ),
794
- 'custombio' => array(
795
  'method' => 'page_load_only',
796
  ),
797
- 'customavatar' => array(
798
  'method' => 'page_load_only',
799
  ),
800
- 'headercolor' => array(
801
  'method' => 'page_load_only',
802
  ),
803
- 'class' => array(
804
  'method' => 'page_load_only',
805
  ),
806
- 'ajaxtheme' => array(
807
  'method' => 'page_load_only',
808
  ),
809
- 'cachetime' => array(
810
  'method' => 'page_load_only',
811
  ),
812
- 'media' => array(
813
  'method' => 'page_load_only',
814
  ),
815
- 'headeroutside' => array(
816
  'method' => 'page_load_only',
817
  ),
818
- 'user' => array(
819
- 'method' => 'feedid_chars',
820
- 'allowed_vals' => 'any'
 
 
 
 
821
  ),
822
- 'feedid' => array(
823
- 'method' => 'feedid_chars',
824
- 'allowed_vals' => 'any'
825
  ),
826
- 'resizeprocess' => array(
827
- 'method' => 'enum',
828
- 'allowed_vals' => array( 'page', 'background' )
829
  ),
830
- 'customtemplates' => array(
831
- 'method' => 'string_true',
832
- 'allowed_vals' => 'any'
833
  ),
834
- 'gdpr' => array(
835
- 'method' => 'enum',
836
- 'allowed_vals' => array( 'auto', 'yes', 'no' )
837
- )
838
  );
839
 
840
  return $allowed_atts;
841
  }
842
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
  /**
844
  * Compares given array with an allow list of
845
  * setting keys and how they should be sanitized
@@ -851,122 +965,22 @@ class SB_Instagram_Settings {
851
  public static function sanitize_raw_atts( $atts ) {
852
  $sanitized_atts = array();
853
 
854
- $allowed_atts = SB_Instagram_Settings::get_allowed_atts();
855
 
856
  foreach ( $atts as $key => $value ) {
857
- $value = (string)$value;
858
 
859
  if ( isset( $allowed_atts[ $key ] ) && strlen( $value ) < 500 ) {
860
  $sanitization_method = $allowed_atts[ $key ]['method'];
 
 
861
 
862
- switch ( $sanitization_method ) {
863
- case 'enum' :
864
- if ( in_array( $value, $allowed_atts[ $key ]['allowed_vals'], true ) ) {
865
- $sanitized_atts[ $key ] = sanitize_text_field( $value );
866
- }
867
- break;
868
- case 'enum_array' :
869
- $values_array = explode( ',', str_replace( ' ', '', $value ) );
870
- $filtered = array();
871
- foreach ( $values_array as $single_value ) {
872
- if ( in_array( $single_value, $allowed_atts[ $key ]['allowed_vals'], true ) ) {
873
- $filtered[] = $single_value;
874
- }
875
- }
876
- $sanitized_atts[ $key ] = implode( ',', $filtered );
877
- break;
878
- case 'alpha_numeric_and_comma' :
879
- $value = str_replace( ' ', '', $value );
880
- $sanitized_atts[ $key ] = preg_replace( "/[^A-Za-z0-9_,]/", '', $value );
881
- break;
882
- case 'feedid_chars' :
883
- $value = str_replace( ' ', '', $value );
884
- $feedid_chars_with_expected = preg_replace( "/[^A-Za-z0-9#_\-\/?.,]/", '', str_replace('%','', urlencode( $value ) ) );
885
- if ( $feedid_chars_with_expected !== str_replace('%','', urlencode( $value ) ) ) {
886
- $sanitized_atts[ $key ] = '';
887
- } else {
888
- $sanitized_atts[ $key ] = sanitize_text_field( $value );
889
- }
890
- break;
891
- case 'user_chars' :
892
- $value = str_replace( ' ', '', $value );
893
- $sanitized_atts[ $key ] = preg_replace( "/[^A-Za-z0-9_,]/", '', $value );
894
- break;
895
- case 'hashtag_chars' :
896
- $value = str_replace( ' ', '', $value );
897
- $hashtag_with_expected = preg_replace( "/[^A-Za-z0-9#_\-\/?.,]/", '', str_replace('%','', urlencode( $value ) ) );
898
- if ( $hashtag_with_expected !== str_replace('%','', urlencode( $value ) ) ) {
899
- $sanitized_atts[ $key ] = '';
900
- } else {
901
- $sanitized_atts[ $key ] = sanitize_text_field( $value );
902
- }
903
- break;
904
- case 'intval' :
905
- $value = intval( $value );
906
-
907
- if ( $value < (int)$allowed_atts[ $key ]['allowed_vals'] ) {
908
- $sanitized_atts[ $key ] = $value;
909
- }
910
-
911
- break;
912
- case 'floatval' :
913
- $value = floatval( $value );
914
-
915
- if ( $allowed_atts[ $key ]['allowed_vals'] === 'any' ) {
916
- $sanitized_atts[ $key ] = $value;
917
- } elseif ( $value < (float)$allowed_atts[ $key ]['allowed_vals'] ) {
918
- $sanitized_atts[ $key ] = $value;
919
- }
920
-
921
- if ( floor( $value ) === $value ) {
922
- $sanitized_atts[ $key ] = (int)$value;
923
- }
924
-
925
- break;
926
- case 'string_true' :
927
- $value = floatval( $value );
928
-
929
- if ( $value === 'true' || $value === 'on' || $value === true ) {
930
- $sanitized_atts[ $key ] = 'true';
931
- } else {
932
- $sanitized_atts[ $key ] = 'false';
933
- }
934
-
935
- break;
936
- case 'color' :
937
- if ( strpos( $value, 'rgb' ) === false ) {
938
- $sanitized_atts[ $key ] = sanitize_hex_color( $value );
939
- } else {
940
- $sanitized_atts[ $key ] = preg_replace( "/[^rgba0-9.,()]/", '', $value );
941
- }
942
-
943
- break;
944
- case 'pxsize' :
945
- if ( strpos( $value, 'inherit' ) !== false ) {
946
- $sanitized_atts[ $key ] = 'inherit';
947
- } else {
948
- $sanitized_atts[ $key ] = preg_replace( "/[^0-9]/", '', $value );
949
- }
950
-
951
- break;
952
- case 'numeric_and_comma' :
953
- $sanitized_atts[ $key ] = preg_replace( "/[^0-9,]/", '', $value );
954
-
955
- break;
956
- case 'inc_ex' :
957
- $values_array = explode( ',', str_replace( ' ', '', $value ) );
958
- $filtered = array();
959
- foreach ( $values_array as $single_value ) {
960
- if ( strlen( $single_value ) < $allowed_atts[ $key ]['allowed_vals'] ) {
961
- $filtered[] = $single_value;
962
- }
963
- }
964
- $sanitized_atts[ $key ] = implode( ',', $filtered );
965
- break;
966
  }
967
  }
968
  }
969
 
970
  return $sanitized_atts;
971
  }
972
- }
60
  * @param array $db settings from the wp_options table
61
  */
62
  public function __construct( $atts, $db ) {
63
+ $this->feed_type_and_terms = array();
64
  $this->connected_accounts_in_feed = array();
65
 
66
  $this->atts = $atts;
79
  'sortby' => isset( $db['sb_instagram_sort'] ) ? $db['sb_instagram_sort'] : '',
80
  'num' => isset( $db['sb_instagram_num'] ) ? $db['sb_instagram_num'] : '',
81
  'apinum' => isset( $db['sb_instagram_minnum'] ) ? $db['sb_instagram_minnum'] : '',
82
+ 'nummobile' => isset( $db['sb_instagram_nummobile'] ) ? $db['sb_instagram_nummobile'] : '',
83
  'cols' => isset( $db['sb_instagram_cols'] ) ? $db['sb_instagram_cols'] : '',
84
  'disablemobile' => isset( $db['sb_instagram_disable_mobile'] ) ? $db['sb_instagram_disable_mobile'] : '',
85
  'imagepadding' => isset( $db['sb_instagram_image_padding'] ) ? $db['sb_instagram_image_padding'] : '',
97
  'showheader' => isset( $db['sb_instagram_show_header'] ) ? $db['sb_instagram_show_header'] : '',
98
  'headersize' => isset( $db['sb_instagram_header_size'] ) ? $db['sb_instagram_header_size'] : '',
99
  'showbio' => isset( $db['sb_instagram_show_bio'] ) ? $db['sb_instagram_show_bio'] : '',
100
+ 'custombio' => isset( $db['sb_instagram_custom_bio'] ) ? $db['sb_instagram_custom_bio'] : '',
101
+ 'customavatar' => isset( $db['sb_instagram_custom_avatar'] ) ? $db['sb_instagram_custom_avatar'] : '',
102
  'headercolor' => isset( $db['sb_instagram_header_color'] ) ? $db['sb_instagram_header_color'] : '',
103
  'class' => '',
104
  'ajaxtheme' => isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] : '',
105
  'cachetime' => isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : '',
106
  'media' => isset( $db['sb_instagram_media_type'] ) ? $db['sb_instagram_media_type'] : '',
107
+ 'headeroutside' => isset( $db['sb_instagram_outside_scrollable'] ) ? $db['sb_instagram_outside_scrollable'] : '',
108
  'accesstoken' => '',
109
  'user' => isset( $db['sb_instagram_user'] ) ? $db['sb_instagram_user'] : false,
110
  'feedid' => isset( $db['sb_instagram_feed_id'] ) ? $db['sb_instagram_feed_id'] : false,
111
  'resizeprocess' => isset( $db['sb_instagram_resizeprocess'] ) ? $db['sb_instagram_resizeprocess'] : 'background',
112
+ 'customtemplates' => isset( $db['custom_template'] ) ? $db['custom_template'] : '',
113
+ 'gdpr' => isset( $db['gdpr'] ) ? $db['gdpr'] : 'auto',
114
+ 'altresize' => isset( $db['altresize'] ) ? $db['altresize'] : true,
115
+ ),
116
+ $atts
117
+ );
118
 
119
+ $this->settings['customtemplates'] = $this->settings['customtemplates'] === 'true' || $this->settings['customtemplates'] === 'on' || $this->settings['customtemplates'] === true;
120
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
121
  if ( isset( $_GET['sbi_debug'] ) ) {
122
  $this->settings['customtemplates'] = false;
123
  }
124
+ $this->settings['minnum'] = max( (int) $this->settings['num'], (int) $this->settings['nummobile'] );
125
  $this->settings['showbio'] = $this->settings['showbio'] === 'true' || $this->settings['showbio'] === 'on' || $this->settings['showbio'] === true;
126
  if ( isset( $atts['showbio'] ) && $atts['showbio'] === 'false' ) {
127
  $this->settings['showbio'] = false;
131
  } elseif ( isset( $atts['showheader'] ) && $atts['showheader'] === 'true' ) {
132
  $this->settings['showheader'] = true;
133
  }
134
+ $this->settings['disable_resize'] = isset( $db['sb_instagram_disable_resize'] ) && ( $db['sb_instagram_disable_resize'] === 'on' || $db['sb_instagram_disable_resize'] === true );
135
+ $this->settings['favor_local'] = ! isset( $db['sb_instagram_favor_local'] ) || ( $db['sb_instagram_favor_local'] === 'on' ) || ( $db['sb_instagram_favor_local'] === true );
136
+ $this->settings['backup_cache_enabled'] = ! isset( $db['sb_instagram_backup'] ) || ( $db['sb_instagram_backup'] === 'on' ) || $db['sb_instagram_backup'] === true;
137
+ $this->settings['headeroutside'] = ( $this->settings['headeroutside'] === true || $this->settings['headeroutside'] === 'on' || $this->settings['headeroutside'] === 'true' );
138
+ $this->settings['disable_js_image_loading'] = isset( $db['disable_js_image_loading'] ) && ( $db['disable_js_image_loading'] === 'on' || $db['disable_js_image_loading'] === true );
139
+ $this->settings['ajax_post_load'] = isset( $db['sb_ajax_initial'] ) && ( $db['sb_ajax_initial'] === 'on' || $db['sb_ajax_initial'] === true );
140
 
141
  switch ( $db['sbi_cache_cron_interval'] ) {
142
+ case '30mins':
143
+ $this->settings['sbi_cache_cron_interval'] = 60 * 30;
144
  break;
145
+ case '1hour':
146
+ $this->settings['sbi_cache_cron_interval'] = 60 * 60;
147
  break;
148
+ default:
149
+ $this->settings['sbi_cache_cron_interval'] = 60 * 60 * 12;
150
  }
151
 
152
+ $this->settings['sb_instagram_cache_time'] = isset( $this->db['sb_instagram_cache_time'] ) ? $this->db['sb_instagram_cache_time'] : 1;
153
  $this->settings['sb_instagram_cache_time_unit'] = isset( $this->db['sb_instagram_cache_time_unit'] ) ? $this->db['sb_instagram_cache_time_unit'] : 'hours';
154
 
 
 
 
 
 
 
155
  $this->settings['isgutenberg'] = SB_Instagram_Blocks::is_gb_editor();
156
  if ( $this->settings['isgutenberg'] ) {
157
+ $this->settings['ajax_post_load'] = false;
158
  $this->settings['disable_js_image_loading'] = true;
159
  }
160
 
172
  foreach ( $this->feed_type_and_terms as $feed_type => $type_terms ) {
173
  foreach ( $type_terms as $term ) {
174
  if ( $feed_type === 'users'
175
+ || $feed_type === 'tagged' ) {
176
  if ( ! in_array( $this->connected_accounts_in_feed[ $term['term'] ]['username'], $return, true ) ) {
177
  $return[] = $this->connected_accounts_in_feed[ $term['term'] ]['username'];
178
  }
179
  } elseif ( $feed_type === 'hashtags_recent'
180
+ || $feed_type === 'hashtags_top' ) {
181
  if ( ! in_array( $term['hashtag_name'], $return, true ) ) {
182
  $return[] = $term['hashtag_name'];
183
  }
251
  'enqueue_js_in_head',
252
  'sb_instagram_disable_awesome',
253
  'sb_ajax_initial',
254
+ 'use_custom',
255
  );
256
 
257
  return $public;
316
 
317
  if ( isset( $feed_type_and_terms['users'] ) ) {
318
  foreach ( $feed_type_and_terms['users'] as $term_and_params ) {
319
+ $user = $term_and_params['term'];
320
  $connected_account = isset( $this->connected_accounts_in_feed[ $user ] ) ? $this->connected_accounts_in_feed[ $user ] : array();
321
  if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) {
322
  $sbi_transient_name .= $connected_account['username'];
370
  $set = false;
371
  foreach ( $this->connected_accounts as $connected_account ) {
372
  if ( ! $set && strpos( $connected_account['access_token'], '.' ) === false ) {
373
+ $set = true;
374
+ $this->settings['user'] = $connected_account['username'];
375
  $this->connected_accounts_in_feed = array( $connected_account['user_id'] => $connected_account );
376
+ $feed_type_and_terms = array(
377
+ 'users' => array(
378
  array(
379
+ 'term' => $connected_account['user_id'],
380
+ 'params' => array(),
381
+ ),
382
+ ),
383
  );
384
  if ( $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) {
385
  $feed_type_and_terms['users'][0]['error'] = true;
390
  return;
391
  } else {
392
  $connected_accounts_in_feed = array();
393
+ $feed_type_and_terms = array(
394
+ 'users' => array(),
395
  );
396
+ $usernames_included = array();
397
+ $usernames_not_connected = array();
398
  foreach ( $users as $user_id_or_name ) {
399
  $connected_account = SB_Instagram_Connected_Account::lookup( $user_id_or_name );
400
 
403
  if ( ! $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) {
404
  $feed_type_and_terms['users'][] = array(
405
  'term' => $connected_account['user_id'],
406
+ 'params' => array(),
407
  );
408
  } else {
409
  $feed_type_and_terms['users'][] = array(
410
  'term' => $connected_account['user_id'],
411
  'params' => array(),
412
+ 'error' => true,
413
  );
414
  }
415
  $connected_accounts_in_feed[ $connected_account['user_id'] ] = $connected_account;
416
+ $usernames_included[] = $connected_account['username'];
417
  }
418
  } else {
419
  $feed_type_and_terms['users'][] = array(
420
  'term' => $user_id_or_name,
421
  'params' => array(),
422
+ 'error' => true,
423
  );
424
+ $usernames_not_connected[] = $user_id_or_name;
425
  }
 
426
  }
427
 
428
  if ( ! empty( $usernames_not_connected ) ) {
433
  $user = implode( ', ', $usernames_not_connected );
434
  }
435
 
436
+ $settings_link = '<a href="' . get_admin_url() . '?page=sb-instagram-feed" target="_blank">' . __( 'plugin Settings page', 'instagram-feed' ) . '</a>';
437
 
438
  $error_message_return = array(
439
+ 'error_message' => sprintf( __( 'Error: There is no connected account for the user %s.', 'instagram-feed' ), $user ),
440
+ 'admin_only' => sprintf( __( 'A connected account related to the user is required to display user feeds. Please connect an account for this user on the %s.', 'instagram-feed' ), $settings_link ),
441
  'frontend_directions' => '',
442
+ 'backend_directions' => '',
443
  );
444
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
445
  }
465
  global $sb_instagram_posts_manager;
466
 
467
  $is_using_access_token_in_shortcode = ! empty( $this->atts['accesstoken'] );
468
+ $settings_link = '<a href="' . get_admin_url() . '?page=sb-instagram-feed" target="_blank">' . __( 'plugin Settings page', 'instagram-feed' ) . '</a>';
469
  if ( $is_using_access_token_in_shortcode ) {
470
  $error_message_return = array(
471
+ 'error_message' => __( 'Error: Cannot add access token directly to the shortcode.', 'instagram-feed' ),
472
+ 'admin_only' => sprintf( __( 'Due to recent Instagram platform changes, it\'s no longer possible to create a feed by adding the access token to the shortcode. Remove the access token from the shortcode and connect an account on the %s instead.', 'instagram-feed' ), $settings_link ),
473
  'frontend_directions' => '',
474
+ 'backend_directions' => '',
475
  );
476
 
477
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
480
  }
481
 
482
  if ( empty( $this->settings['id'] )
483
+ && empty( $this->settings['user'] )
484
+ && ! empty( $this->connected_accounts ) ) {
485
 
486
  $this->set_user_feed();
487
  } else {
488
  $user_array = array();
489
  if ( ! empty( $this->settings['user'] ) ) {
490
+ $user_array = is_array( $this->settings['user'] ) ? $this->settings['user'] : explode( ',', str_replace( ' ', '', $this->settings['user'] ) );
491
  } elseif ( ! empty( $this->settings['id'] ) ) {
492
+ $user_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
493
  }
494
 
495
  $this->set_user_feed( $user_array );
496
  }
497
  if ( empty( $this->feed_type_and_terms['users'] ) ) {
498
  $error_message_return = array(
499
+ 'error_message' => __( 'Error: No users set.', 'instagram-feed' ),
500
+ 'admin_only' => __( 'Please visit the plugin\'s settings page to select a user account or add one to the shortcode - user="username".', 'instagram-feed' ),
501
  'frontend_directions' => '',
502
+ 'backend_directions' => '',
503
  );
504
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
505
  }
506
 
507
  foreach ( $this->connected_accounts_in_feed as $connected_account_in_feed ) {
508
  if ( isset( $connected_account_in_feed['private'] )
509
+ && sbi_private_account_near_expiration( $connected_account_in_feed ) ) {
510
+ $link_1 = '<a href="https://help.instagram.com/116024195217477/In">';
511
+ $link_2 = '</a>';
512
  $error_message_return = array(
513
+ 'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ),
514
+ 'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %1$smake your Instagram account public%2$s.', 'instagram-feed' ), $link_1, $link_2 ),
515
  'frontend_directions' => '<a href="https://smashballoon.com/instagram-feed/docs/errors/#10">' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '</a>',
516
+ 'backend_directions' => '',
517
  );
518
 
519
  $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
531
  return SBI_CRON_UPDATE_CACHE_TIME;
532
  } else {
533
  //If the caching time doesn't exist in the database then set it to be 1 hour
534
+ $cache_time = isset( $this->settings['sb_instagram_cache_time'] ) ? (int) $this->settings['sb_instagram_cache_time'] : 1;
535
  $cache_time_unit = isset( $this->settings['sb_instagram_cache_time_unit'] ) ? $this->settings['sb_instagram_cache_time_unit'] : 'hours';
536
 
537
  //Calculate the cache time in seconds
538
+ if ( $cache_time_unit === 'minutes' ) {
539
+ $cache_time_unit = 60;
540
+ }
541
+ if ( $cache_time_unit === 'hours' ) {
542
+ $cache_time_unit = 60 * 60;
543
+ }
544
+ if ( $cache_time_unit === 'days' ) {
545
+ $cache_time_unit = 60 * 60 * 24;
546
+ }
547
 
548
+ return min( $cache_time * $cache_time_unit, DAY_IN_SECONDS );
549
  }
550
  }
551
 
552
  public static function default_settings() {
553
  $defaults = array(
554
+ 'sb_instagram_at' => '',
555
+ 'sb_instagram_type' => 'user',
556
+ 'sb_instagram_order' => 'top',
557
+ 'sb_instagram_user_id' => '',
558
+ 'sb_instagram_tagged_ids' => '',
559
+ 'sb_instagram_hashtag' => '',
560
+ 'sb_instagram_type_self_likes' => '',
561
+ 'sb_instagram_location' => '',
562
+ 'sb_instagram_coordinates' => '',
563
+ 'sb_instagram_preserve_settings' => '',
564
+ 'sb_instagram_ajax_theme' => false,
565
+ 'enqueue_js_in_head' => false,
566
+ 'disable_js_image_loading' => false,
567
+ 'sb_instagram_disable_resize' => false,
568
+ 'sb_instagram_favor_local' => true,
569
+ 'sb_instagram_cache_time' => '1',
570
+ 'sb_instagram_cache_time_unit' => 'hours',
571
+ 'sbi_caching_type' => 'background',
572
+ 'sbi_cache_cron_interval' => '12hours',
573
+ 'sbi_cache_cron_time' => '1',
574
+ 'sbi_cache_cron_am_pm' => 'am',
575
+
576
+ 'sb_instagram_width' => '100',
577
+ 'sb_instagram_width_unit' => '%',
578
+ 'sb_instagram_feed_width_resp' => false,
579
+ 'sb_instagram_height' => '',
580
+ 'sb_instagram_num' => '20',
581
+ 'sb_instagram_nummobile' => '',
582
+ 'sb_instagram_height_unit' => '',
583
+ 'sb_instagram_cols' => '4',
584
+ 'sb_instagram_colsmobile' => 'auto',
585
+ 'sb_instagram_image_padding' => '5',
586
+ 'sb_instagram_image_padding_unit' => 'px',
587
 
588
  //Layout Type
589
+ 'sb_instagram_layout_type' => 'grid',
590
+ 'sb_instagram_highlight_type' => 'pattern',
591
+ 'sb_instagram_highlight_offset' => 0,
592
+ 'sb_instagram_highlight_factor' => 6,
593
+ 'sb_instagram_highlight_ids' => '',
594
+ 'sb_instagram_highlight_hashtag' => '',
595
 
596
  //Hover style
597
+ 'sb_hover_background' => '',
598
+ 'sb_hover_text' => '',
599
+ 'sbi_hover_inc_username' => true,
600
+ 'sbi_hover_inc_icon' => true,
601
+ 'sbi_hover_inc_date' => true,
602
+ 'sbi_hover_inc_instagram' => true,
603
+ 'sbi_hover_inc_location' => false,
604
+ 'sbi_hover_inc_caption' => false,
605
+ 'sbi_hover_inc_likes' => false,
606
+ 'sb_instagram_sort' => 'none',
607
+ 'sb_instagram_disable_lightbox' => false,
608
+ 'sb_instagram_captionlinks' => false,
609
+ 'sb_instagram_background' => '',
610
+ 'sb_instagram_show_btn' => true,
611
+ 'sb_instagram_btn_background' => '',
612
+ 'sb_instagram_btn_text_color' => '',
613
+ 'sb_instagram_btn_text' => __( 'Load More', 'instagram-feed' ),
614
+ 'sb_instagram_image_res' => 'auto',
615
+ 'sb_instagram_media_type' => 'all',
616
+ 'sb_instagram_moderation_mode' => 'manual',
617
+ 'sb_instagram_hide_photos' => '',
618
+ 'sb_instagram_block_users' => '',
619
+ 'sb_instagram_ex_apply_to' => 'all',
620
+ 'sb_instagram_inc_apply_to' => 'all',
621
+ 'sb_instagram_show_users' => '',
622
+ 'sb_instagram_exclude_words' => '',
623
+ 'sb_instagram_include_words' => '',
 
 
624
 
625
  //Text
626
+ 'sb_instagram_show_caption' => true,
627
+ 'sb_instagram_caption_length' => '50',
628
+ 'sb_instagram_caption_color' => '',
629
+ 'sb_instagram_caption_size' => '13',
630
 
631
  //lightbox comments
632
+ 'sb_instagram_lightbox_comments' => true,
633
+ 'sb_instagram_num_comments' => '20',
634
 
635
  //Meta
636
+ 'sb_instagram_show_meta' => true,
637
+ 'sb_instagram_meta_color' => '',
638
+ 'sb_instagram_meta_size' => '13',
639
  //Header
640
+ 'sb_instagram_show_header' => true,
641
+ 'sb_instagram_header_color' => '',
642
+ 'sb_instagram_header_style' => 'standard',
643
+ 'sb_instagram_show_followers' => true,
644
+ 'sb_instagram_show_bio' => true,
645
+ 'sb_instagram_custom_bio' => '',
646
+ 'sb_instagram_custom_avatar' => '',
647
+ 'sb_instagram_header_primary_color' => '517fa4',
648
+ 'sb_instagram_header_secondary_color' => 'eeeeee',
649
+ 'sb_instagram_header_size' => 'small',
650
+ 'sb_instagram_outside_scrollable' => false,
651
+ 'sb_instagram_stories' => true,
652
+ 'sb_instagram_stories_time' => 5000,
653
 
654
  //Follow button
655
+ 'sb_instagram_show_follow_btn' => true,
656
+ 'sb_instagram_folow_btn_background' => '',
657
+ 'sb_instagram_follow_btn_text_color' => '',
658
+ 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
659
 
660
  //Autoscroll
661
+ 'sb_instagram_autoscroll' => false,
662
+ 'sb_instagram_autoscrolldistance' => 200,
663
 
664
  //Misc
665
+ 'sb_instagram_custom_css' => '',
666
+ 'sb_instagram_custom_js' => '',
667
+ 'sb_instagram_requests_max' => '5',
668
+ 'sb_instagram_minnum' => '0',
669
+ 'sb_instagram_cron' => 'unset',
670
+ 'sb_instagram_disable_font' => false,
671
+ 'sb_instagram_backup' => true,
672
+ 'sb_ajax_initial' => false,
673
+ 'enqueue_css_in_shortcode' => false,
674
+ 'sb_instagram_disable_mob_swipe' => false,
675
+ 'sbi_br_adjust' => true,
676
+ 'sb_instagram_media_vine' => false,
677
+ 'custom_template' => false,
678
+ 'disable_admin_notice' => false,
679
+ 'enable_email_report' => true,
680
+ 'email_notification' => 'monday',
681
+ 'email_notification_addresses' => get_option( 'admin_email' ),
682
 
683
  //Carousel
684
+ 'sb_instagram_carousel' => false,
685
+ 'sb_instagram_carousel_rows' => 1,
686
+ 'sb_instagram_carousel_loop' => 'rewind',
687
+ 'sb_instagram_carousel_arrows' => false,
688
+ 'sb_instagram_carousel_pag' => true,
689
+ 'sb_instagram_carousel_autoplay' => false,
690
+ 'sb_instagram_carousel_interval' => '5000',
691
 
692
  );
693
 
701
  */
702
  public static function get_allowed_atts() {
703
  $allowed_atts = array(
704
+ 'id' => array(
705
+ 'method' => 'alpha_numeric_and_comma',
706
+ 'allowed_vals' => 'any',
707
  ),
708
+ 'width' => array(
709
  'method' => 'page_load_only',
710
  ),
711
+ 'widthunit' => array(
712
  'method' => 'page_load_only',
713
  ),
714
+ 'widthresp' => array(
715
  'method' => 'page_load_only',
716
  ),
717
+ 'height' => array(
718
  'method' => 'page_load_only',
719
  ),
720
+ 'heightunit' => array(
721
  'method' => 'page_load_only',
722
  ),
723
+ 'sortby' => array(
724
+ 'method' => 'enum',
725
+ 'allowed_vals' => array( 'none', 'random', 'likes' ),
726
  ),
727
+ 'num' => array(
728
+ 'method' => 'intval',
729
+ 'allowed_vals' => 500,
730
  ),
731
+ 'nummobile' => array(
732
+ 'method' => 'intval',
733
+ 'allowed_vals' => 500,
734
  ),
735
+ 'apinum' => array(
736
+ 'method' => 'intval',
737
+ 'allowed_vals' => 100,
738
  ),
739
+ 'cols' => array(
740
+ 'method' => 'intval',
741
+ 'allowed_vals' => 15,
742
  ),
743
+ 'disablemobile' => array(
744
  'method' => 'page_load_only',
745
  ),
746
+ 'imagepadding' => array(
747
  'method' => 'page_load_only',
748
  ),
749
  'imagepaddingunit' => array(
750
  'method' => 'page_load_only',
751
  ),
752
+ 'background' => array(
753
  'method' => 'page_load_only',
754
  ),
755
+ 'showbutton' => array(
756
  'method' => 'page_load_only',
757
  ),
758
+ 'buttoncolor' => array(
759
  'method' => 'page_load_only',
760
  ),
761
+ 'buttontextcolor' => array(
762
  'method' => 'page_load_only',
763
  ),
764
+ 'buttontext' => array(
765
  'method' => 'page_load_only',
766
  ),
767
+ 'imageres' => array(
768
+ 'method' => 'enum',
769
+ 'allowed_vals' => array( 'auto', 'thumb', 'low', 'full' ),
770
  ),
771
+ 'showfollow' => array(
772
  'method' => 'page_load_only',
773
  ),
774
+ 'followcolor' => array(
775
  'method' => 'page_load_only',
776
  ),
777
+ 'followtextcolor' => array(
778
  'method' => 'page_load_only',
779
  ),
780
+ 'followtext' => array(
781
  'method' => 'page_load_only',
782
  ),
783
+ 'showheader' => array(
784
  'method' => 'page_load_only',
785
  ),
786
+ 'headersize' => array(
787
  'method' => 'page_load_only',
788
  ),
789
+ 'showbio' => array(
790
  'method' => 'page_load_only',
791
  ),
792
+ 'custombio' => array(
793
  'method' => 'page_load_only',
794
  ),
795
+ 'customavatar' => array(
796
  'method' => 'page_load_only',
797
  ),
798
+ 'headercolor' => array(
799
  'method' => 'page_load_only',
800
  ),
801
+ 'class' => array(
802
  'method' => 'page_load_only',
803
  ),
804
+ 'ajaxtheme' => array(
805
  'method' => 'page_load_only',
806
  ),
807
+ 'cachetime' => array(
808
  'method' => 'page_load_only',
809
  ),
810
+ 'media' => array(
811
  'method' => 'page_load_only',
812
  ),
813
+ 'headeroutside' => array(
814
  'method' => 'page_load_only',
815
  ),
816
+ 'user' => array(
817
+ 'method' => 'feedid_chars',
818
+ 'allowed_vals' => 'any',
819
+ ),
820
+ 'feedid' => array(
821
+ 'method' => 'feedid_chars',
822
+ 'allowed_vals' => 'any',
823
  ),
824
+ 'resizeprocess' => array(
825
+ 'method' => 'enum',
826
+ 'allowed_vals' => array( 'page', 'background' ),
827
  ),
828
+ 'customtemplates' => array(
829
+ 'method' => 'string_true',
830
+ 'allowed_vals' => 'any',
831
  ),
832
+ 'gdpr' => array(
833
+ 'method' => 'enum',
834
+ 'allowed_vals' => array( 'auto', 'yes', 'no' ),
835
  ),
 
 
 
 
836
  );
837
 
838
  return $allowed_atts;
839
  }
840
 
841
+ /**
842
+ * @param $value
843
+ * @param $sanitization_method
844
+ * @param $allowed_vals
845
+ *
846
+ * @return array|float|int|string|string[]|void|null
847
+ */
848
+ public static function sanitize_setting( $value, $sanitization_method, $allowed_vals ) {
849
+ $sanitized_value = null;
850
+ switch ( $sanitization_method ) {
851
+ case 'enum':
852
+ if ( in_array( $value, $allowed_vals, true ) ) {
853
+ $sanitized_value = sanitize_text_field( $value );
854
+ }
855
+ break;
856
+ case 'enum_array':
857
+ $values_array = explode( ',', str_replace( ' ', '', $value ) );
858
+ $filtered = array();
859
+ foreach ( $values_array as $single_value ) {
860
+ if ( in_array( $single_value, $allowed_vals, true ) ) {
861
+ $filtered[] = $single_value;
862
+ }
863
+ }
864
+ $sanitized_value = implode( ',', $filtered );
865
+ break;
866
+ case 'alpha_numeric_and_comma':
867
+ $value = str_replace( ' ', '', $value );
868
+ $sanitized_value = preg_replace( '/[^A-Za-z0-9_,]/', '', $value );
869
+ break;
870
+ case 'feedid_chars':
871
+ $value = str_replace( ' ', '', $value );
872
+ $feedid_chars_with_expected = preg_replace( '/[^A-Za-z0-9#_\-\/?.,]/', '', str_replace( '%', '', urlencode( $value ) ) );
873
+ if ( $feedid_chars_with_expected !== str_replace( '%', '', urlencode( $value ) ) ) {
874
+ $sanitized_value = '';
875
+ } else {
876
+ $sanitized_value = sanitize_text_field( $value );
877
+ }
878
+ break;
879
+ case 'user_chars':
880
+ $value = str_replace( ' ', '', $value );
881
+ $sanitized_value = preg_replace( '/[^A-Za-z0-9_,]/', '', $value );
882
+ break;
883
+ case 'hashtag_chars':
884
+ $value = str_replace( ' ', '', $value );
885
+ $hashtag_with_expected = preg_replace( '/[^A-Za-z0-9#_\-\/?.,]/', '', str_replace( '%', '', urlencode( $value ) ) );
886
+ if ( $hashtag_with_expected !== str_replace( '%', '', urlencode( $value ) ) ) {
887
+ $sanitized_value = '';
888
+ } else {
889
+ $sanitized_value = sanitize_text_field( $value );
890
+ }
891
+ break;
892
+ case 'intval':
893
+ $value = intval( $value );
894
+
895
+ if ( $value < (int) $allowed_vals ) {
896
+ $sanitized_value = $value;
897
+ }
898
+
899
+ break;
900
+ case 'floatval':
901
+ $value = floatval( $value );
902
+
903
+ if ( $allowed_vals === 'any' || $value < (float) $allowed_vals ) {
904
+ $sanitized_value = $value;
905
+ }
906
+
907
+ if ( floor( $value ) === $value ) {
908
+ $sanitized_value = (int) $value;
909
+ }
910
+
911
+ break;
912
+ case 'string_true':
913
+ $value = floatval( $value );
914
+
915
+ if ( $value === 'true' || $value === 'on' || $value === true ) {
916
+ $sanitized_value = 'true';
917
+ } else {
918
+ $sanitized_value = 'false';
919
+ }
920
+
921
+ break;
922
+ case 'color':
923
+ if ( strpos( $value, 'rgb' ) === false ) {
924
+ $sanitized_value = sanitize_hex_color( $value );
925
+ } else {
926
+ $sanitized_value = preg_replace( '/[^rgba0-9.,()]/', '', $value );
927
+ }
928
+
929
+ break;
930
+ case 'pxsize':
931
+ if ( strpos( $value, 'inherit' ) !== false ) {
932
+ $sanitized_value = 'inherit';
933
+ } else {
934
+ $sanitized_value = preg_replace( '/[^0-9]/', '', $value );
935
+ }
936
+
937
+ break;
938
+ case 'numeric_and_comma':
939
+ $sanitized_value = preg_replace( '/[^0-9,]/', '', $value );
940
+
941
+ break;
942
+ case 'inc_ex':
943
+ $values_array = explode( ',', str_replace( ' ', '', $value ) );
944
+ $filtered = array();
945
+ foreach ( $values_array as $single_value ) {
946
+ if ( strlen( $single_value ) < $allowed_vals ) {
947
+ $filtered[] = $single_value;
948
+ }
949
+ }
950
+ $sanitized_value = implode( ',', $filtered );
951
+ break;
952
+ }
953
+
954
+ return $sanitized_value;
955
+ }
956
+
957
  /**
958
  * Compares given array with an allow list of
959
  * setting keys and how they should be sanitized
965
  public static function sanitize_raw_atts( $atts ) {
966
  $sanitized_atts = array();
967
 
968
+ $allowed_atts = self::get_allowed_atts();
969
 
970
  foreach ( $atts as $key => $value ) {
971
+ $value = (string) $value;
972
 
973
  if ( isset( $allowed_atts[ $key ] ) && strlen( $value ) < 500 ) {
974
  $sanitization_method = $allowed_atts[ $key ]['method'];
975
+ $allowed_vals = ! empty( $allowed_atts[ $key ]['allowed_vals'] ) ? $allowed_atts[ $key ]['allowed_vals'] : '';
976
+ $sanitized_val = self::sanitize_setting( $value, $sanitization_method, $allowed_vals );
977
 
978
+ if ( ! is_null( $sanitized_val ) ) {
979
+ $sanitized_atts[ $key ] = $sanitized_val;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
980
  }
981
  }
982
  }
983
 
984
  return $sanitized_atts;
985
  }
986
+ }
inc/class-sb-instagram-single.php CHANGED
@@ -11,8 +11,8 @@ if ( ! defined( 'ABSPATH' ) ) {
11
  die( '-1' );
12
  }
13
 
14
- class SB_Instagram_Single
15
- {
16
  /**
17
  * @var string
18
  */
@@ -47,14 +47,14 @@ class SB_Instagram_Single
47
  */
48
  public function __construct( $permalink_or_permalink_id ) {
49
  if ( strpos( $permalink_or_permalink_id, 'http' ) !== false ) {
50
- $this->permalink = $permalink_or_permalink_id;
51
  $exploded_permalink = explode( '/', $permalink_or_permalink_id );
52
- $permalink_id = $exploded_permalink[4];
53
 
54
  $this->permalink_id = $permalink_id;
55
  } else {
56
  $this->permalink_id = $permalink_or_permalink_id;
57
- $this->permalink = 'https://www.instagram.com/p/' . $this->permalink_id;
58
  }
59
  $this->error = false;
60
 
@@ -71,22 +71,20 @@ class SB_Instagram_Single
71
  $this->post = $this->maybe_saved_data();
72
 
73
  if ( empty( $this->post )
74
- || ! $this->was_recently_updated() ) {
75
 
76
  if ( ! $this->should_delay_oembed_request() ) {
77
 
78
  $data = $this->fetch();
79
  if ( ! empty( $data ) ) {
80
- $data = $this->parse_and_restructure( $data );
81
  $this->post = $data;
82
  $this->update_last_update_timestamp();
83
  $this->update_single_cache();
84
  } elseif ( $data === false ) {
85
  $this->add_oembed_request_delay();
86
  }
87
-
88
  }
89
-
90
  }
91
  }
92
 
@@ -116,7 +114,7 @@ class SB_Instagram_Single
116
  return false;
117
  }
118
 
119
- return (time() - 21 * DAY_IN_SECONDS) < $this->post['last_update'];
120
  }
121
 
122
 
@@ -140,9 +138,13 @@ class SB_Instagram_Single
140
 
141
  $url = SB_Instagram_Oembed::oembed_url();
142
 
143
- $fetch_url = add_query_arg( array(
144
- 'url' => $this->permalink,
145
- 'access_token' => $access_token ), $url );
 
 
 
 
146
 
147
  $result = wp_remote_get( esc_url_raw( $fetch_url ) );
148
 
@@ -153,7 +155,7 @@ class SB_Instagram_Single
153
  if ( $data && isset( $data['error'] ) ) {
154
  $this->add_oembed_request_delay();
155
  $this->error = sprintf( __( 'API error %s:', 'instagram-feed' ), $data['error']['code'] ) . ' ' . $data['error']['message'];
156
- $data = false;
157
  }
158
  } else {
159
  $error = '';
@@ -176,7 +178,7 @@ class SB_Instagram_Single
176
  * @since 2.5.3/5.8.3
177
  */
178
  public function should_delay_oembed_request() {
179
- return (get_transient( 'sbi_delay_oembeds_' . $this->permalink_id ) !== false);
180
  }
181
 
182
  /**
@@ -209,7 +211,7 @@ class SB_Instagram_Single
209
  if ( ! is_array( $stored_option ) ) {
210
  $stored_option = json_decode( $this->encryption->decrypt( $stored_option ), true );
211
  }
212
- $new = array( $this->permalink_id => $this->post );
213
  $stored_option = array_merge( $new, $stored_option );
214
  // only latest 400 posts
215
  $stored_option = array_slice( $stored_option, 0, 400 );
@@ -232,8 +234,8 @@ class SB_Instagram_Single
232
 
233
  $return = array(
234
  'thumbnail_url' => '',
235
- 'id'=> $this->permalink_id,
236
- 'media_type' => 'OEMBED'
237
  );
238
 
239
  if ( ! empty( $data['thumbnail_url'] ) ) {
@@ -263,24 +265,27 @@ class SB_Instagram_Single
263
  } else {
264
  $settings = get_option( 'sb_instagram_settings', array() );
265
 
266
- $resize_disabled = isset( $settings['sb_instagram_disable_resize'] ) && $settings['sb_instagram_disable_resize'] === 'on';
267
 
268
  if ( ! $resize_disabled ) {
269
  global $wpdb;
270
 
271
  $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
272
 
273
- $results = $wpdb->get_col( $wpdb->prepare(
274
- "SELECT json_data FROM $posts_table_name
 
275
  WHERE instagram_id = %s
276
- LIMIT 1", $this->permalink_id ) );
 
 
 
277
  if ( isset( $results[0] ) ) {
278
  $data = json_decode( $this->encryption->decrypt( $results[0] ), true );
279
  }
280
-
281
  }
282
  }
283
 
284
  return $data;
285
  }
286
- }
11
  die( '-1' );
12
  }
13
 
14
+ class SB_Instagram_Single {
15
+
16
  /**
17
  * @var string
18
  */
47
  */
48
  public function __construct( $permalink_or_permalink_id ) {
49
  if ( strpos( $permalink_or_permalink_id, 'http' ) !== false ) {
50
+ $this->permalink = $permalink_or_permalink_id;
51
  $exploded_permalink = explode( '/', $permalink_or_permalink_id );
52
+ $permalink_id = $exploded_permalink[4];
53
 
54
  $this->permalink_id = $permalink_id;
55
  } else {
56
  $this->permalink_id = $permalink_or_permalink_id;
57
+ $this->permalink = 'https://www.instagram.com/p/' . $this->permalink_id;
58
  }
59
  $this->error = false;
60
 
71
  $this->post = $this->maybe_saved_data();
72
 
73
  if ( empty( $this->post )
74
+ || ! $this->was_recently_updated() ) {
75
 
76
  if ( ! $this->should_delay_oembed_request() ) {
77
 
78
  $data = $this->fetch();
79
  if ( ! empty( $data ) ) {
80
+ $data = $this->parse_and_restructure( $data );
81
  $this->post = $data;
82
  $this->update_last_update_timestamp();
83
  $this->update_single_cache();
84
  } elseif ( $data === false ) {
85
  $this->add_oembed_request_delay();
86
  }
 
87
  }
 
88
  }
89
  }
90
 
114
  return false;
115
  }
116
 
117
+ return ( time() - 21 * DAY_IN_SECONDS ) < $this->post['last_update'];
118
  }
119
 
120
 
138
 
139
  $url = SB_Instagram_Oembed::oembed_url();
140
 
141
+ $fetch_url = add_query_arg(
142
+ array(
143
+ 'url' => $this->permalink,
144
+ 'access_token' => $access_token,
145
+ ),
146
+ $url
147
+ );
148
 
149
  $result = wp_remote_get( esc_url_raw( $fetch_url ) );
150
 
155
  if ( $data && isset( $data['error'] ) ) {
156
  $this->add_oembed_request_delay();
157
  $this->error = sprintf( __( 'API error %s:', 'instagram-feed' ), $data['error']['code'] ) . ' ' . $data['error']['message'];
158
+ $data = false;
159
  }
160
  } else {
161
  $error = '';
178
  * @since 2.5.3/5.8.3
179
  */
180
  public function should_delay_oembed_request() {
181
+ return ( get_transient( 'sbi_delay_oembeds_' . $this->permalink_id ) !== false );
182
  }
183
 
184
  /**
211
  if ( ! is_array( $stored_option ) ) {
212
  $stored_option = json_decode( $this->encryption->decrypt( $stored_option ), true );
213
  }
214
+ $new = array( $this->permalink_id => $this->post );
215
  $stored_option = array_merge( $new, $stored_option );
216
  // only latest 400 posts
217
  $stored_option = array_slice( $stored_option, 0, 400 );
234
 
235
  $return = array(
236
  'thumbnail_url' => '',
237
+ 'id' => $this->permalink_id,
238
+ 'media_type' => 'OEMBED',
239
  );
240
 
241
  if ( ! empty( $data['thumbnail_url'] ) ) {
265
  } else {
266
  $settings = get_option( 'sb_instagram_settings', array() );
267
 
268
+ $resize_disabled = isset( $settings['sb_instagram_disable_resize'] ) && $settings['sb_instagram_disable_resize'];
269
 
270
  if ( ! $resize_disabled ) {
271
  global $wpdb;
272
 
273
  $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
274
 
275
+ $results = $wpdb->get_col(
276
+ $wpdb->prepare(
277
+ "SELECT json_data FROM $posts_table_name
278
  WHERE instagram_id = %s
279
+ LIMIT 1",
280
+ $this->permalink_id
281
+ )
282
+ );
283
  if ( isset( $results[0] ) ) {
284
  $data = json_decode( $this->encryption->decrypt( $results[0] ), true );
285
  }
 
286
  }
287
  }
288
 
289
  return $data;
290
  }
291
+ }
inc/class-sb-instagram-token-refresher.php CHANGED
@@ -12,8 +12,8 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  die( '-1' );
13
  }
14
 
15
- class SB_Instagram_Token_Refresher
16
- {
17
 
18
  /**
19
  * @var array
@@ -25,9 +25,9 @@ class SB_Instagram_Token_Refresher
25
  */
26
  private $report;
27
 
28
- public function __construct( $connected_account ) {
29
  $this->connected_account = $connected_account;
30
- $this->report = array();
31
  }
32
 
33
  public function get_report() {
@@ -46,7 +46,7 @@ class SB_Instagram_Token_Refresher
46
  */
47
  public static function refresh_time_has_passed_threshold( $connected_account ) {
48
  $expiration_timestamp = isset( $connected_account['expires_timestamp'] ) ? $connected_account['expires_timestamp'] : time();
49
- $current_time = sbi_get_current_timestamp();
50
 
51
  $refresh_threshold = $expiration_timestamp - SBI_REFRESH_THRESHOLD_OFFSET;
52
 
@@ -67,7 +67,7 @@ class SB_Instagram_Token_Refresher
67
  * @return bool
68
  */
69
  public static function minimum_time_interval_since_last_attempt_has_passed( $connected_account ) {
70
- $last_attempt = isset( $connected_account['last_refresh_attempt'] ) ? (int)$connected_account['last_refresh_attempt'] : 0;
71
  $current_time = sbi_get_current_timestamp();
72
  if ( $current_time > $last_attempt + SBI_MINIMUM_INTERVAL ) {
73
  return true;
@@ -83,17 +83,16 @@ class SB_Instagram_Token_Refresher
83
  * @return bool
84
  */
85
  public function should_attempt_refresh() {
86
- if ( SB_Instagram_Token_Refresher::refresh_time_has_passed_threshold( $this->connected_account ) ) {
87
 
88
- if ( SB_Instagram_Token_Refresher::minimum_time_interval_since_last_attempt_has_passed( $this->connected_account ) ) {
89
  $this->report['should_do_update'] = true;
90
- $this->report['reason'] = '';
91
  return true;
92
  } else {
93
  $this->report['should_do_update'] = false;
94
- $this->report['reason'] = 'has not been enough time since last attempt';
95
  }
96
-
97
  } else {
98
  $this->report['should_do_update'] = false;
99
  $this->report['reason'] = 'token expiration date not close enough';
@@ -125,12 +124,12 @@ class SB_Instagram_Token_Refresher
125
  return true;
126
  } else {
127
  $this->report['did_update'] = false;
128
- $this->report['reason'] = 'successful connection but no data returned';
129
  }
130
  } else {
131
  $this->report['did_update'] = false;
132
- $this->report['reason'] = 'could not connect to Instagram';
133
- $this->report['error_log'] = $connection;
134
  }
135
 
136
  return false;
@@ -141,7 +140,7 @@ class SB_Instagram_Token_Refresher
141
  * the access token for a connected account and saves it in the database.
142
  */
143
  public function update_last_attempt_timestamp() {
144
- $options = get_option( 'sb_instagram_settings', array() );
145
  $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
146
 
147
  $connected_accounts[ $this->connected_account['user_id'] ]['last_refresh_attempt'] = time();
@@ -176,19 +175,19 @@ class SB_Instagram_Token_Refresher
176
  * @param $token_data
177
  */
178
  private function add_renewal_data( $token_data ) {
179
- $options = get_option( 'sb_instagram_settings', array() );
180
  $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
181
 
182
- $expires_in = $token_data['expires_in'];
183
  $expires_timestamp = sbi_get_current_timestamp() + $expires_in;
184
 
185
  $connected_accounts[ $this->connected_account['user_id'] ]['expires_timestamp'] = $expires_timestamp;
186
- $connected_accounts[ $this->connected_account['user_id'] ]['access_token'] = $token_data['access_token'];
187
- $connected_accounts[ $this->connected_account['user_id'] ] = SB_Instagram_Connected_Account::encrypt_connected_account_tokens( $connected_accounts[ $this->connected_account['user_id'] ] );
188
 
189
  $options['connected_accounts'] = $connected_accounts;
190
 
191
  update_option( 'sb_instagram_settings', $options );
192
  }
193
 
194
- }
12
  die( '-1' );
13
  }
14
 
15
+ class SB_Instagram_Token_Refresher {
16
+
17
 
18
  /**
19
  * @var array
25
  */
26
  private $report;
27
 
28
+ public function __construct( $connected_account ) {
29
  $this->connected_account = $connected_account;
30
+ $this->report = array();
31
  }
32
 
33
  public function get_report() {
46
  */
47
  public static function refresh_time_has_passed_threshold( $connected_account ) {
48
  $expiration_timestamp = isset( $connected_account['expires_timestamp'] ) ? $connected_account['expires_timestamp'] : time();
49
+ $current_time = sbi_get_current_timestamp();
50
 
51
  $refresh_threshold = $expiration_timestamp - SBI_REFRESH_THRESHOLD_OFFSET;
52
 
67
  * @return bool
68
  */
69
  public static function minimum_time_interval_since_last_attempt_has_passed( $connected_account ) {
70
+ $last_attempt = isset( $connected_account['last_refresh_attempt'] ) ? (int) $connected_account['last_refresh_attempt'] : 0;
71
  $current_time = sbi_get_current_timestamp();
72
  if ( $current_time > $last_attempt + SBI_MINIMUM_INTERVAL ) {
73
  return true;
83
  * @return bool
84
  */
85
  public function should_attempt_refresh() {
86
+ if ( self::refresh_time_has_passed_threshold( $this->connected_account ) ) {
87
 
88
+ if ( self::minimum_time_interval_since_last_attempt_has_passed( $this->connected_account ) ) {
89
  $this->report['should_do_update'] = true;
90
+ $this->report['reason'] = '';
91
  return true;
92
  } else {
93
  $this->report['should_do_update'] = false;
94
+ $this->report['reason'] = 'has not been enough time since last attempt';
95
  }
 
96
  } else {
97
  $this->report['should_do_update'] = false;
98
  $this->report['reason'] = 'token expiration date not close enough';
124
  return true;
125
  } else {
126
  $this->report['did_update'] = false;
127
+ $this->report['reason'] = 'successful connection but no data returned';
128
  }
129
  } else {
130
  $this->report['did_update'] = false;
131
+ $this->report['reason'] = 'could not connect to Instagram';
132
+ $this->report['error_log'] = $connection;
133
  }
134
 
135
  return false;
140
  * the access token for a connected account and saves it in the database.
141
  */
142
  public function update_last_attempt_timestamp() {
143
+ $options = get_option( 'sb_instagram_settings', array() );
144
  $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
145
 
146
  $connected_accounts[ $this->connected_account['user_id'] ]['last_refresh_attempt'] = time();
175
  * @param $token_data
176
  */
177
  private function add_renewal_data( $token_data ) {
178
+ $options = get_option( 'sb_instagram_settings', array() );
179
  $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
180
 
181
+ $expires_in = $token_data['expires_in'];
182
  $expires_timestamp = sbi_get_current_timestamp() + $expires_in;
183
 
184
  $connected_accounts[ $this->connected_account['user_id'] ]['expires_timestamp'] = $expires_timestamp;
185
+ $connected_accounts[ $this->connected_account['user_id'] ]['access_token'] = $token_data['access_token'];
186
+ $connected_accounts[ $this->connected_account['user_id'] ] = SB_Instagram_Connected_Account::encrypt_connected_account_tokens( $connected_accounts[ $this->connected_account['user_id'] ] );
187
 
188
  $options['connected_accounts'] = $connected_accounts;
189
 
190
  update_option( 'sb_instagram_settings', $options );
191
  }
192
 
193
+ }
inc/email.php CHANGED
@@ -18,22 +18,22 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  <title><?php echo esc_html( $title ); ?></title>
19
  </head>
20
  <body>
21
- <table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" style="border-collapse:collapse;border-spacing:0px;vertical-align:top;min-width:100%;box-sizing:border-box;background-color:rgb(233,234,236);color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;padding:0px;margin:0px;text-align:left;font-size:14px;line-height:140%;height:100%;width:100%"><tbody><tr style="padding:0px;vertical-align:top;text-align:left">
22
- <td align="center" valign="top" style="vertical-align:top;color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;padding:0px;margin:0px;font-size:14px;line-height:140%;text-align:center;border-collapse:collapse">
23
- <table border="0" cellpadding="0" cellspacing="0" style="border-collapse:collapse;border-spacing:0px;padding:0px;vertical-align:top;width:600px;margin:0px auto;text-align:inherit">
24
  <tbody><tr style="padding:0px;vertical-align:top;text-align:left">
25
- <td align="center" valign="middle" style="vertical-align:top;color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;font-size:14px;line-height:140%;text-align:center;padding:30px 30px 22px;border-collapse:collapse">
26
  <?php if ( ! empty( $header_image ) ) : ?>
27
  <img src="<?php echo esc_url( $header_image ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" />
28
  <?php endif; ?>
29
  </td>
30
  </tr>
31
  <tr style="padding:0px;vertical-align:top;text-align:left">
32
- <td align="left" valign="top" style="vertical-align:top;color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;text-align:left;font-size:14px;line-height:140%;background-color:rgb(255,255,255);padding:60px 75px 45px;border-width:3px 1px 1px;border-style:solid;border-color:rgb(227, 71, 22) rgb(221,221,221) rgb(221,221,221);border-collapse:collapse">
33
 
34
  <table style="border-collapse:collapse;border-spacing:0px;padding:0px;vertical-align:top;text-align:left;width:100%"><tbody><tr style="padding:0px;vertical-align:top;text-align:left">
35
  <td style="vertical-align:top;font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;padding:0px;margin:0px;text-align:left;font-size:14px;line-height:140%;color:rgb(119,119,119);border-collapse:collapse">
36
- <?php echo $message_content; ?>
37
 
38
  <table class="summary-info-table" style="border-collapse: collapse; border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 38px 0 0 0; Margin: 38px 0 0 0; font-size: 15px; border: 1px solid #dddddd; border-radius: 6px; display: block;">
39
  <tbody><tr style="padding: 0; vertical-align: top; text-align: left;">
@@ -76,7 +76,7 @@ if ( ! defined( 'ABSPATH' ) ) {
76
  </td>
77
  </tr>
78
  <tr style="padding:0px;vertical-align:top;text-align:left">
79
- <td align="center" valign="top" style="vertical-align:top;font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;line-height:140%;padding:30px;color:rgb(114,119,124);font-size:12px;text-align:center;border-collapse:collapse">
80
  <?php
81
  /* translators: %s - link to a site. */
82
  esc_html_e( 'This is a courtesy email sent from the Smash Balloon Instagram Feed plugin on your website to alert you when there is an issue with one of your Instagram feeds.', 'instagram-feed' );
@@ -84,7 +84,7 @@ if ( ! defined( 'ABSPATH' ) ) {
84
  </td>
85
  </tr>
86
  <tr style="padding:0px;vertical-align:top;text-align:left">
87
- <td align="center" valign="top" style="vertical-align:top;font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;line-height:140%;padding:30px;color:rgb(114,119,124);font-size:12px;text-align:center;border-collapse:collapse">
88
  <?php
89
  printf( esc_html__( 'Sent from %s', 'instagram-feed' ), '<a href="' . esc_url( home_url() ) . '">' . esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) ) . '</a>' );
90
  ?>
18
  <title><?php echo esc_html( $title ); ?></title>
19
  </head>
20
  <body>
21
+ <table border="0" style="border-collapse:collapse;border-spacing:0px;vertical-align:top;min-width:100%;box-sizing:border-box;background-color:rgb(233,234,236);color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;padding:0px;margin:0px;text-align:left;font-size:14px;line-height:140%;height:100%;width:100%"><tbody><tr style="padding:0px;vertical-align:top;text-align:left">
22
+ <td style="vertical-align:top;color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;padding:0px;margin:0px;font-size:14px;line-height:140%;text-align:center;border-collapse:collapse">
23
+ <table border="0" style="border-collapse:collapse;border-spacing:0px;padding:0px;vertical-align:top;width:600px;margin:0px auto;text-align:inherit">
24
  <tbody><tr style="padding:0px;vertical-align:top;text-align:left">
25
+ <td style="vertical-align:top;color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;font-size:14px;line-height:140%;text-align:center;padding:30px 30px 22px;border-collapse:collapse">
26
  <?php if ( ! empty( $header_image ) ) : ?>
27
  <img src="<?php echo esc_url( $header_image ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" />
28
  <?php endif; ?>
29
  </td>
30
  </tr>
31
  <tr style="padding:0px;vertical-align:top;text-align:left">
32
+ <td style="vertical-align:top;color:rgb(68,68,68);font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;text-align:left;font-size:14px;line-height:140%;background-color:rgb(255,255,255);padding:60px 75px 45px;border-width:3px 1px 1px;border-style:solid;border-color:rgb(227, 71, 22) rgb(221,221,221) rgb(221,221,221);border-collapse:collapse">
33
 
34
  <table style="border-collapse:collapse;border-spacing:0px;padding:0px;vertical-align:top;text-align:left;width:100%"><tbody><tr style="padding:0px;vertical-align:top;text-align:left">
35
  <td style="vertical-align:top;font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;padding:0px;margin:0px;text-align:left;font-size:14px;line-height:140%;color:rgb(119,119,119);border-collapse:collapse">
36
+ <?php echo wp_kses_post( $message_content ); ?>
37
 
38
  <table class="summary-info-table" style="border-collapse: collapse; border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 38px 0 0 0; Margin: 38px 0 0 0; font-size: 15px; border: 1px solid #dddddd; border-radius: 6px; display: block;">
39
  <tbody><tr style="padding: 0; vertical-align: top; text-align: left;">
76
  </td>
77
  </tr>
78
  <tr style="padding:0px;vertical-align:top;text-align:left">
79
+ <td style="vertical-align:top;font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;line-height:140%;padding:30px;color:rgb(114,119,124);font-size:12px;text-align:center;border-collapse:collapse">
80
  <?php
81
  /* translators: %s - link to a site. */
82
  esc_html_e( 'This is a courtesy email sent from the Smash Balloon Instagram Feed plugin on your website to alert you when there is an issue with one of your Instagram feeds.', 'instagram-feed' );
84
  </td>
85
  </tr>
86
  <tr style="padding:0px;vertical-align:top;text-align:left">
87
+ <td style="vertical-align:top;font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;font-weight:normal;margin:0px;line-height:140%;padding:30px;color:rgb(114,119,124);font-size:12px;text-align:center;border-collapse:collapse">
88
  <?php
89
  printf( esc_html__( 'Sent from %s', 'instagram-feed' ), '<a href="' . esc_url( home_url() ) . '">' . esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) ) . '</a>' );
90
  ?>
inc/if-functions.php CHANGED
@@ -13,7 +13,9 @@
13
  * - Enqueueing CSS and JS files for the feed
14
  *
15
  */
16
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
 
17
 
18
  add_filter( 'widget_text', 'do_shortcode' );
19
 
@@ -22,28 +24,29 @@ add_filter( 'widget_text', 'do_shortcode' );
22
  * Can be safely added directly to templates using
23
  * 'echo do_shortcode( "[instagram-feed]" );'
24
  */
25
- add_shortcode('instagram-feed', 'display_instagram');
26
  function display_instagram( $atts = array() ) {
27
 
28
  $database_settings = sbi_get_database_settings();
29
 
30
- if ( $database_settings['sb_instagram_ajax_theme'] !== 'on' && $database_settings['sb_instagram_ajax_theme'] !== 'true' ) {
31
  wp_enqueue_script( 'sb_instagram_scripts' );
32
  }
33
 
34
- if ( $database_settings['enqueue_css_in_shortcode'] === 'on' || $database_settings['enqueue_css_in_shortcode'] === 'true' ) {
35
  wp_enqueue_style( 'sb_instagram_styles' );
36
  }
37
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
38
 
39
- if ( empty( $database_settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
40
- $style = current_user_can( 'manage_instagram_feed_options' ) ? ' style="display: block;"' : '';
 
41
  ob_start(); ?>
42
- <div id="sbi_mod_error" <?php echo $style; ?>>
43
- <span><?php esc_html_e('This error message is only visible to WordPress admins', 'instagram-feed' ); ?></span><br />
44
- <p><strong><?php esc_html_e( 'Error: No connected account.', 'instagram-feed' ); ?></strong>
45
- <p><?php esc_html_e( 'Please go to the Instagram Feed settings page to connect an account.', 'instagram-feed' ); ?></p>
46
- </div>
47
  <?php
48
  $html = ob_get_contents();
49
  ob_get_clean();
@@ -52,8 +55,8 @@ function display_instagram( $atts = array() ) {
52
 
53
  $instagram_feed_settings->set_feed_type_and_terms();
54
  $instagram_feed_settings->set_transient_name();
55
- $transient_name = $instagram_feed_settings->get_transient_name();
56
- $settings = $instagram_feed_settings->get_settings();
57
  $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
58
 
59
  $instagram_feed = new SB_Instagram_Feed( $transient_name );
@@ -68,9 +71,9 @@ function display_instagram( $atts = array() ) {
68
  if ( $instagram_feed->need_to_start_cron_job() ) {
69
  $instagram_feed->add_report( 'setting up feed for cron cache' );
70
  $to_cache = array(
71
- 'atts' => $atts,
72
- 'last_requested' => time(),
73
- );
74
 
75
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() );
76
 
@@ -86,18 +89,16 @@ function display_instagram( $atts = array() ) {
86
 
87
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
88
  }
89
-
90
- } elseif ( $instagram_feed->regular_cache_exists() ) {
91
  $instagram_feed->add_report( 'page load caching used and regular cache exists' );
92
  $instagram_feed->set_post_data_from_cache();
93
 
94
- if ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
95
- while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
96
  $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
97
  }
98
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
99
  }
100
-
101
  } else {
102
  $instagram_feed->add_report( 'no feed cache found' );
103
 
@@ -108,7 +109,6 @@ function display_instagram( $atts = array() ) {
108
  if ( ! $instagram_feed->should_use_backup() ) {
109
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
110
  }
111
-
112
  }
113
 
114
  if ( $instagram_feed->should_use_backup() ) {
@@ -117,7 +117,6 @@ function display_instagram( $atts = array() ) {
117
  $instagram_feed->maybe_set_header_data_from_backup();
118
  }
119
 
120
-
121
  // if need a header
122
  if ( $instagram_feed->need_header( $settings, $feed_type_and_terms ) ) {
123
  if ( $instagram_feed->should_use_backup() && $settings['minnum'] > 0 ) {
@@ -147,7 +146,7 @@ function display_instagram( $atts = array() ) {
147
  $post_set = new SB_Instagram_Post_Set( $post_data, $transient_name );
148
 
149
  $post_set->maybe_save_update_and_resize_images_for_posts();
150
- }
151
 
152
  if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
153
  global $sb_instagram_posts_manager;
@@ -183,7 +182,7 @@ function sbi_add_resized_image_data( $instagram_feed, $feed_id ) {
183
  }
184
  }
185
  ?>
186
- <span class="sbi_resized_image_data" data-feed-id="<?php echo esc_attr( $feed_id ); ?>" data-resized="<?php echo esc_attr( sbi_json_encode( SB_Instagram_Feed::get_resized_images_source_set( $instagram_feed->get_image_ids_post_set(), 0, $feed_id ) ) ); ?>">
187
  </span>
188
  <?php
189
  }
@@ -194,12 +193,14 @@ add_action( 'sbi_before_feed_end', 'sbi_add_resized_image_data', 10, 2 );
194
  * Resembles "display_instagram"
195
  */
196
  function sbi_get_next_post_set() {
 
197
  if ( ! isset( $_POST['feed_id'] ) || strpos( $_POST['feed_id'], 'sbi' ) === false ) {
198
- die( 'invalid feed ID');
199
  }
200
 
201
  $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
202
 
 
203
  $atts_raw = isset( $_POST['atts'] ) ? json_decode( stripslashes( $_POST['atts'] ), true ) : array();
204
  if ( is_array( $atts_raw ) ) {
205
  $atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw );
@@ -208,10 +209,10 @@ function sbi_get_next_post_set() {
208
  }
209
  $atts = $atts_raw; // now sanitized
210
 
211
- $offset = isset( $_POST['offset'] ) ? (int)$_POST['offset'] : 0;
212
- $page = isset( $_POST['page'] ) ? (int)$_POST['page'] : 1;
213
 
214
- $database_settings = sbi_get_database_settings();
215
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
216
 
217
  if ( empty( $database_settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
@@ -228,22 +229,22 @@ function sbi_get_next_post_set() {
228
 
229
  $settings = $instagram_feed_settings->get_settings();
230
 
231
- $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( wp_unslash( $_POST['location'] ) ) : 'unknown';
232
- $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
233
  $feed_details = array(
234
- 'feed_id' => $transient_name,
235
- 'atts' => $atts,
236
  'location' => array(
237
  'post_id' => $post_id,
238
- 'html' => $location
239
- )
240
  );
241
 
242
  $can_do_background_tasks = false;
243
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
244
  $nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : '';
245
  if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) {
246
- $can_do_background_tasks = true;
247
  }
248
  } else {
249
  $can_do_background_tasks = true;
@@ -271,8 +272,8 @@ function sbi_get_next_post_set() {
271
  $normal_method = true;
272
  if ( $instagram_feed->need_to_start_cron_job() ) {
273
  $instagram_feed->add_report( 'needed to start cron job' );
274
- $to_cache = array(
275
- 'atts' => $atts,
276
  'last_requested' => time(),
277
  );
278
  $normal_method = false;
@@ -290,21 +291,18 @@ function sbi_get_next_post_set() {
290
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() );
291
  }
292
  }
293
-
294
  } elseif ( $instagram_feed->regular_cache_exists() ) {
295
  $instagram_feed->add_report( 'regular cache exists' );
296
  $instagram_feed->set_post_data_from_cache();
297
 
298
- if ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
299
- while ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
300
  $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
301
  }
302
 
303
  $instagram_feed->add_report( 'adding to cache' );
304
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
305
  }
306
-
307
-
308
  } else {
309
  $instagram_feed->add_report( 'no feed cache found' );
310
 
@@ -319,7 +317,6 @@ function sbi_get_next_post_set() {
319
  $instagram_feed->add_report( 'transient gone, adding to cache' );
320
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
321
  }
322
-
323
  }
324
 
325
  if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
@@ -340,7 +337,7 @@ function sbi_get_next_post_set() {
340
  $feed_status = array( 'shouldPaginate' => $instagram_feed->should_use_pagination( $settings, $offset ) );
341
 
342
  $return = array(
343
- 'html' => $instagram_feed->get_the_items_html( $settings, $offset, $instagram_feed_settings->get_feed_type_and_terms(), $instagram_feed_settings->get_connected_accounts_in_feed() ),
344
  'feedStatus' => $feed_status,
345
  'report' => $instagram_feed->get_report(),
346
  'resizedImages' => SB_Instagram_Feed::get_resized_images_source_set( $instagram_feed->get_image_ids_post_set(), 1, $feed_id )
@@ -360,19 +357,21 @@ add_action( 'wp_ajax_nopriv_sbi_load_more_clicked', 'sbi_get_next_post_set' );
360
  * @return string
361
  */
362
  function sbi_process_submitted_resize_ids() {
 
363
  if ( ! isset( $_POST['feed_id'] ) || strpos( $_POST['feed_id'], 'sbi' ) === false ) {
364
- die( 'invalid feed ID');
365
  }
366
 
367
- $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
368
  $images_need_resizing_raw = isset( $_POST['needs_resizing'] ) ? wp_unslash( $_POST['needs_resizing'] ) : array();
369
  if ( is_array( $images_need_resizing_raw ) ) {
370
- array_map( 'sanitize_text_field', $images_need_resizing_raw );
371
  } else {
372
  $images_need_resizing_raw = array();
373
  }
374
  $images_need_resizing = $images_need_resizing_raw;
375
 
 
376
  $atts_raw = isset( $_POST['atts'] ) ? json_decode( wp_unslash( $_POST['atts'] ), true ) : array();
377
  if ( is_array( $atts_raw ) ) {
378
  $atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw );
@@ -381,10 +380,10 @@ function sbi_process_submitted_resize_ids() {
381
  }
382
  $atts = $atts_raw; // now sanitized
383
 
384
- $offset = isset( $_POST['offset'] ) ? (int)$_POST['offset'] : 0;
385
  $cache_all = isset( $_POST['cache_all'] ) ? $_POST['cache_all'] === 'true' : false;
386
 
387
- $database_settings = sbi_get_database_settings();
388
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
389
 
390
  if ( empty( $database_settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
@@ -401,15 +400,15 @@ function sbi_process_submitted_resize_ids() {
401
 
402
  $settings = $instagram_feed_settings->get_settings();
403
 
404
- $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( wp_unslash( $_POST['location'] ) ) : 'unknown';
405
- $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
406
  $feed_details = array(
407
- 'feed_id' => $transient_name,
408
- 'atts' => $atts,
409
  'location' => array(
410
  'post_id' => $post_id,
411
- 'html' => $location
412
- )
413
  );
414
 
415
  $can_do_background_tasks = false;
@@ -430,7 +429,7 @@ function sbi_process_submitted_resize_ids() {
430
  $settings['cache_all'] = true;
431
  }
432
 
433
- sbi_resize_posts_by_id( $images_need_resizing, $transient_name, $settings );
434
  sbi_delete_image_cache( $transient_name );
435
 
436
  global $sb_instagram_posts_manager;
@@ -440,15 +439,15 @@ function sbi_process_submitted_resize_ids() {
440
  die();
441
  }
442
 
443
-
444
  die( 'resizing success' );
445
  }
446
  add_action( 'wp_ajax_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' );
447
  add_action( 'wp_ajax_nopriv_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' );
448
 
449
  function sbi_do_locator() {
 
450
  if ( ! isset( $_POST['feed_id'] ) || strpos( $_POST['feed_id'], 'sbi' ) === false ) {
451
- die( 'invalid feed ID');
452
  }
453
 
454
  $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
@@ -461,22 +460,22 @@ function sbi_do_locator() {
461
  }
462
  $atts = $atts_raw; // now sanitized
463
 
464
- $database_settings = sbi_get_database_settings();
465
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
466
 
467
  $instagram_feed_settings->set_feed_type_and_terms();
468
  $instagram_feed_settings->set_transient_name();
469
  $transient_name = $instagram_feed_settings->get_transient_name();
470
 
471
- $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown';
472
- $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
473
  $feed_details = array(
474
- 'feed_id' => $feed_id,
475
- 'atts' => $atts,
476
  'location' => array(
477
  'post_id' => $post_id,
478
- 'html' => $location
479
- )
480
  );
481
 
482
  $can_do_background_tasks = false;
@@ -515,26 +514,27 @@ function sbi_do_background_tasks( $feed_details ) {
515
  * @param object $instagram_feed
516
  * @param string $feed_id
517
  */
518
- function sbi_error_report( $instagram_feed, $feed_id ) {
519
  global $sb_instagram_posts_manager;
520
 
521
- $style = sbi_current_user_can( 'manage_instagram_feed_options' ) ? ' style="display: block;"' : '';
522
-
523
  $error_messages = $sb_instagram_posts_manager->get_frontend_errors( $instagram_feed );
524
 
525
- if ( ! empty( $error_messages ) ) {?>
526
- <div id="sbi_mod_error"<?php echo $style; ?>>
527
- <span><?php esc_html_e('This error message is only visible to WordPress admins', 'instagram-feed' ); ?></span><br />
528
- <?php foreach ( $error_messages as $error_message ) {
 
 
529
 
530
- echo '<div><strong>' . esc_html( $error_message['error_message'] ) . '</strong>';
531
  if ( sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
532
- echo '<br>' . $error_message['admin_only'];
533
- echo '<br>' . $error_message['frontend_directions'];
534
  }
535
  echo '</div>';
536
- } ?>
537
- </div>
 
538
  <?php
539
  }
540
 
@@ -568,59 +568,73 @@ function sbi_doing_openssl() {
568
  * @param string $feed_id
569
  */
570
  function sbi_debug_report( $instagram_feed, $feed_id ) {
 
 
 
 
571
 
572
- if ( ! isset( $_GET['sbi_debug'] ) ) {
573
- return;
574
- }
575
-
576
- ?>
577
- <p>Status</p>
578
- <ul>
579
- <li>Time: <?php echo date( "Y-m-d H:i:s", time() ); ?></li>
580
- <?php foreach ( $instagram_feed->get_report() as $item ) : ?>
581
- <li><?php echo esc_html( $item ); ?></li>
582
- <?php endforeach; ?>
583
 
584
  </ul>
585
 
586
- <?php
587
  $database_settings = sbi_get_database_settings();
588
 
589
  $public_settings_keys = SB_Instagram_Settings::get_public_db_settings_keys();
590
- ?>
591
- <p>Settings</p>
592
- <ul>
593
- <?php foreach ( $public_settings_keys as $key ) : if ( isset( $database_settings[ $key ] ) ) : ?>
594
- <li>
595
- <small><?php echo esc_html( $key ); ?>:</small>
596
- <?php if ( ! is_array( $database_settings[ $key ] ) ) :
597
- echo $database_settings[ $key ];
598
- else : ?>
 
 
 
 
 
599
  <pre>
600
- <?php var_export( $database_settings[ $key ] ); ?>
601
  </pre>
602
- <?php endif; ?>
603
- </li>
604
 
605
- <?php endif; endforeach; ?>
606
- </ul>
607
- <p>GDPR</p>
608
- <ul>
 
 
 
609
  <?php
610
- $statuses = SB_Instagram_GDPR_Integrations::statuses();
611
- foreach ( $statuses as $status_key => $value) : ?>
612
- <li>
613
- <small><?php echo esc_html( $status_key ); ?>:</small>
614
- <?php if ( $value == 1 ) { echo 'success'; } else { echo 'failed'; } ?>
615
- </li>
 
 
 
 
 
 
616
 
617
  <?php endforeach; ?>
618
- <li>
619
- <small>Enabled:</small>
620
- <?php echo SB_Instagram_GDPR_Integrations::doing_gdpr( $database_settings ); ?>
621
- </li>
622
- </ul>
623
- <?php
624
  }
625
  add_action( 'sbi_before_feed_end', 'sbi_debug_report', 11, 2 );
626
 
@@ -632,7 +646,7 @@ add_action( 'sbi_before_feed_end', 'sbi_debug_report', 11, 2 );
632
  * @param array $settings
633
  * @param int $offset
634
  */
635
- function sbi_resize_posts_by_id( $ids, $transient_name, $settings, $offset = 0 ) {
636
  $instagram_feed = new SB_Instagram_Feed( $transient_name );
637
 
638
  if ( $instagram_feed->regular_cache_exists() ) {
@@ -641,22 +655,18 @@ function sbi_resize_posts_by_id( $ids, $transient_name, $settings, $offset = 0 )
641
 
642
  $cached_post_data = $instagram_feed->get_post_data();
643
 
644
- $num_ids = count( $ids );
645
  $found_posts = array();
646
- $i = 0;
647
- while ( count( $found_posts) < $num_ids && isset( $cached_post_data[ $i ] ) ) {
648
- if ( ! empty( $cached_post_data[ $i ]['id'] ) && in_array( $cached_post_data[ $i ]['id'], $ids, true ) ) {
649
- $found_posts[] = $cached_post_data[ $i ];
650
- }
651
- $i++;
652
- }
653
 
654
  $fill_in_timestamp = date( 'Y-m-d H:i:s', time() + 120 );
655
 
656
- if ( $offset !== 0 ) {
657
- $fill_in_timestamp = date( 'Y-m-d H:i:s', strtotime( $instagram_feed->get_earliest_time_stamp() ) - 120 );
658
- }
659
-
660
  $post_set = new SB_Instagram_Post_Set( $found_posts, $transient_name, $fill_in_timestamp );
661
 
662
  $post_set->maybe_save_update_and_resize_images_for_posts();
@@ -664,7 +674,7 @@ function sbi_resize_posts_by_id( $ids, $transient_name, $settings, $offset = 0 )
664
  }
665
 
666
  function sbi_store_local_avatar( $connected_account ) {
667
- $sbi_settings = get_option( 'sb_instagram_settings', array() );
668
  $connected_accounts = $sbi_settings['connected_accounts'];
669
  if ( sbi_create_local_avatar( $connected_account['username'], $connected_account['profile_picture'] ) ) {
670
  $connected_accounts[ $connected_account['user_id'] ]['local_avatar'] = true;
@@ -672,7 +682,6 @@ function sbi_store_local_avatar( $connected_account ) {
672
  $connected_accounts[ $connected_account['user_id'] ]['local_avatar'] = false;
673
  }
674
 
675
-
676
  $sbi_settings['connected_accounts'] = $connected_accounts;
677
 
678
  update_option( 'sb_instagram_settings', $sbi_settings );
@@ -686,7 +695,7 @@ function sbi_create_local_avatar( $username, $file_name ) {
686
  if ( ! is_wp_error( $image_editor ) ) {
687
  $upload = wp_upload_dir();
688
 
689
- $full_file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg';
690
 
691
  $saved_image = $image_editor->save( $full_file_name );
692
 
@@ -717,53 +726,53 @@ function sbi_create_local_avatar( $username, $file_name ) {
717
  * @return array
718
  */
719
  function sbi_get_database_settings() {
720
- $defaults = array(
721
- 'sb_instagram_at' => '',
722
- 'sb_instagram_user_id' => '',
723
- 'sb_instagram_preserve_settings' => '',
724
- 'sb_instagram_ajax_theme' => false,
725
- 'sb_instagram_disable_resize' => false,
726
- 'sb_instagram_cache_time' => 1,
727
- 'sb_instagram_cache_time_unit' => 'hours',
728
- 'sbi_caching_type' => 'page',
729
- 'sbi_cache_cron_interval' => '12hours',
730
- 'sbi_cache_cron_time' => '1',
731
- 'sbi_cache_cron_am_pm' => 'am',
732
- 'sb_instagram_width' => '100',
733
- 'sb_instagram_width_unit' => '%',
734
- 'sb_instagram_feed_width_resp' => false,
735
- 'sb_instagram_height' => '',
736
- 'sb_instagram_num' => '20',
737
- 'sb_instagram_height_unit' => '',
738
- 'sb_instagram_cols' => '4',
739
- 'sb_instagram_disable_mobile' => false,
740
- 'sb_instagram_image_padding' => '5',
741
- 'sb_instagram_image_padding_unit' => 'px',
742
- 'sb_instagram_sort' => 'none',
743
- 'sb_instagram_background' => '',
744
- 'sb_instagram_show_btn' => true,
745
- 'sb_instagram_btn_background' => '',
746
- 'sb_instagram_btn_text_color' => '',
747
- 'sb_instagram_btn_text' => __( 'Load More...', 'instagram-feed' ),
748
- 'sb_instagram_image_res' => 'auto',
749
  //Header
750
- 'sb_instagram_show_header' => true,
751
- 'sb_instagram_header_size' => 'small',
752
- 'sb_instagram_header_color' => '',
753
  //Follow button
754
- 'sb_instagram_show_follow_btn' => true,
755
- 'sb_instagram_folow_btn_background' => '',
756
  'sb_instagram_follow_btn_text_color' => '',
757
- 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
758
  //Misc
759
- 'sb_instagram_custom_css' => '',
760
- 'sb_instagram_custom_js' => '',
761
- 'sb_instagram_cron' => 'no',
762
- 'sb_instagram_backup' => true,
763
- 'sb_ajax_initial' => false,
764
- 'enqueue_css_in_shortcode' => false,
765
- 'sb_instagram_disable_mob_swipe' => false,
766
- 'sb_instagram_disable_awesome' => false
767
  );
768
  $sbi_settings = get_option( 'sb_instagram_settings', array() );
769
 
@@ -779,26 +788,26 @@ function sbi_get_feed_template_part( $part, $settings = array() ) {
779
  $file = '';
780
 
781
  $using_custom_templates_in_theme = apply_filters( 'sbi_use_theme_templates', $settings['customtemplates'] );
782
- $generic_path = trailingslashit( SBI_PLUGIN_DIR ) . 'templates/';
783
 
784
  if ( $using_custom_templates_in_theme ) {
785
  $custom_header_template = locate_template( 'sbi/header.php', false, false );
786
- $custom_item_template = locate_template( 'sbi/item.php', false, false );
787
  $custom_footer_template = locate_template( 'sbi/footer.php', false, false );
788
- $custom_feed_template = locate_template( 'sbi/feed.php', false, false );
789
  } else {
790
  $custom_header_template = false;
791
- $custom_item_template = false;
792
  $custom_footer_template = false;
793
- $custom_feed_template = false;
794
  }
795
 
796
  if ( $part === 'header' ) {
797
- if ( $custom_header_template ) {
798
- $file = $custom_header_template;
799
- } else {
800
- $file = $generic_path . 'header.php';
801
- }
802
  } elseif ( $part === 'item' ) {
803
  if ( $custom_item_template ) {
804
  $file = $custom_item_template;
@@ -826,13 +835,13 @@ function sbi_get_feed_template_part( $part, $settings = array() ) {
826
  * Triggered by a cron event to update feeds
827
  */
828
  function sbi_cron_updater() {
829
- $sbi_settings = sbi_get_database_settings();
830
 
831
- if ( $sbi_settings['sbi_caching_type'] === 'background' ) {
832
- $cron_updater = new SB_Instagram_Cron_Updater();
833
 
834
- $cron_updater->do_feed_updates();
835
- }
836
 
837
  }
838
  add_action( 'sbi_feed_update', 'sbi_cron_updater' );
@@ -849,13 +858,13 @@ function sbi_maybe_clean( $maybe_dirty ) {
849
  if ( $decrypted ) {
850
  $maybe_dirty = $decrypted;
851
  }
852
- if ( substr_count ( $maybe_dirty , '.' ) < 3 ) {
853
  return str_replace( '634hgdf83hjdj2', '', $maybe_dirty );
854
  }
855
 
856
- $parts = explode( '.', trim( $maybe_dirty ) );
857
  $last_part = $parts[2] . $parts[3];
858
- $cleaned = $parts[0] . '.' . base64_decode( $parts[1] ) . '.' . base64_decode( $last_part );
859
 
860
  return $cleaned;
861
  }
@@ -866,12 +875,12 @@ function sbi_maybe_clean( $maybe_dirty ) {
866
  * @return string
867
  */
868
  function sbi_get_parts( $whole ) {
869
- if ( substr_count ( $whole , '.' ) !== 2 ) {
870
  return $whole;
871
  }
872
 
873
- $parts = explode( '.', trim( $whole ) );
874
- $return = $parts[0] . '.' . base64_encode( $parts[1] ). '.' . base64_encode( $parts[2] );
875
 
876
  return substr( $return, 0, 40 ) . '.' . substr( $return, 40, 100 );
877
  }
@@ -889,32 +898,29 @@ function sbi_date_sort( $a, $b ) {
889
  if ( isset( $time_stamp_a ) ) {
890
  return $time_stamp_b - $time_stamp_a;
891
  } else {
892
- return rand ( -1, 1 );
893
  }
894
  }
895
 
896
  function sbi_code_check( $code ) {
897
- if ( strpos( $code, '634hgdf83hjdj2') !== false ) {
898
  return true;
899
  }
900
  return false;
901
  }
902
 
903
  function sbi_fixer( $code ) {
904
- if ( strpos( $code, '634hgdf83hjdj2') !== false ) {
905
  return $code;
906
  } else {
907
- return substr_replace( $code , '634hgdf83hjdj2', 15, 0 );
908
  }
909
  }
910
 
911
  /**
912
- * @param $a
913
- * @param $b
914
- *
915
  * @return false|int
916
  */
917
- function sbi_rand_sort( $a, $b ) {
918
  return rand ( -1, 1 );
919
  }
920
 
@@ -955,13 +961,13 @@ function sbi_hextorgb( $hex ) {
955
  $hex = str_replace( '#', '', $hex );
956
 
957
  if ( strlen( $hex ) === 3 ) {
958
- $r = hexdec( substr( $hex,0,1 ).substr( $hex,0,1 ) );
959
- $g = hexdec( substr( $hex,1,1 ).substr( $hex,1,1 ) );
960
- $b = hexdec( substr( $hex,2,1 ).substr( $hex,2,1 ) );
961
  } else {
962
- $r = hexdec( substr( $hex,0,2 ) );
963
- $g = hexdec( substr( $hex,2,2 ) );
964
- $b = hexdec( substr( $hex,4,2 ) );
965
  }
966
  $rgb = array( $r, $g, $b );
967
 
@@ -980,7 +986,7 @@ function sbi_is_url( $input ) {
980
  */
981
  function sbi_sanitize_emoji( $string ) {
982
  $encoded = array(
983
- 'jsonencoded' => $string
984
  );
985
  return sbi_json_encode( $encoded );
986
  }
@@ -998,6 +1004,18 @@ function sbi_decode_emoji( $string ) {
998
  return $string;
999
  }
1000
 
 
 
 
 
 
 
 
 
 
 
 
 
1001
  /**
1002
  * @return int
1003
  */
@@ -1033,15 +1051,15 @@ function sbi_is_after_deprecation_deadline() {
1033
  }
1034
 
1035
  function sbi_json_encode( $thing ) {
1036
- if ( function_exists( 'wp_json_encode' ) ) {
1037
- return wp_json_encode( $thing );
1038
- } else {
1039
- return json_encode( $thing );
1040
- }
1041
  }
1042
 
1043
  function sbi_private_account_near_expiration( $connected_account ) {
1044
- $expires_in = max( 0, floor( ($connected_account['expires_timestamp'] - time()) / DAY_IN_SECONDS ) );
1045
  return $expires_in < 10;
1046
  }
1047
 
@@ -1069,37 +1087,49 @@ function sbi_update_connected_account( $account_id, $to_update ) {
1069
  function sb_instagram_cron_clear_cache() {
1070
  //Delete all transients
1071
  global $wpdb;
1072
- $table_name = $wpdb->prefix . "options";
1073
- $wpdb->query( "
 
1074
  DELETE
1075
  FROM $table_name
1076
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
1077
- " );
1078
- $wpdb->query( "
 
 
1079
  DELETE
1080
  FROM $table_name
1081
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
1082
- " );
1083
- $wpdb->query( "
 
 
1084
  DELETE
1085
  FROM $table_name
1086
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
1087
- " );
1088
- $wpdb->query( "
 
 
1089
  DELETE
1090
  FROM $table_name
1091
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
1092
- " );
1093
- $wpdb->query( "
 
 
1094
  DELETE
1095
  FROM $table_name
1096
  WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
1097
- " );
1098
- $wpdb->query( "
 
 
1099
  DELETE
1100
  FROM $table_name
1101
  WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
1102
- " );
 
1103
 
1104
  sb_instagram_clear_page_caches();
1105
  }
@@ -1110,12 +1140,12 @@ function sb_instagram_cron_clear_cache() {
1110
  */
1111
  function sb_instagram_clear_page_caches() {
1112
 
1113
- $clear_page_caches = apply_filters( 'sbi_clear_page_caches', true );
1114
- if ( ! $clear_page_caches ) {
1115
- return;
1116
- }
1117
 
1118
- if ( isset( $GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ){
1119
  /* Clear WP fastest cache*/
1120
  $GLOBALS['wp_fastest_cache']->deleteCache();
1121
  }
@@ -1124,8 +1154,8 @@ function sb_instagram_clear_page_caches() {
1124
  wp_cache_clear_cache();
1125
  }
1126
 
1127
- if ( class_exists('W3_Plugin_TotalCacheAdmin') ) {
1128
- $plugin_totalcacheadmin = & w3_instance('W3_Plugin_TotalCacheAdmin');
1129
 
1130
  $plugin_totalcacheadmin->flush_all();
1131
  }
@@ -1142,7 +1172,7 @@ function sb_instagram_clear_page_caches() {
1142
  // Litespeed Cache
1143
  if ( method_exists( 'LiteSpeed_Cache_API', 'purge' ) ) {
1144
  LiteSpeed_Cache_API::purge( 'esi.instagram-feed' );
1145
- }
1146
  }
1147
 
1148
  /**
@@ -1156,14 +1186,15 @@ function sb_instagram_scripts_enqueue() {
1156
  $sb_instagram_settings = get_option( 'sb_instagram_settings' );
1157
 
1158
  $js_file = 'js/sbi-scripts.min.js';
 
1159
  if ( isset( $_GET['sbi_debug'] ) ) {
1160
  $js_file = 'js/sbi-scripts.js';
1161
  }
1162
 
1163
  if ( isset( $sb_instagram_settings['enqueue_js_in_head'] ) && $sb_instagram_settings['enqueue_js_in_head'] ) {
1164
- wp_enqueue_script( 'sb_instagram_scripts', trailingslashit( SBI_PLUGIN_URL ) . $js_file, array('jquery'), SBIVER, false );
1165
  } else {
1166
- wp_register_script( 'sb_instagram_scripts', trailingslashit( SBI_PLUGIN_URL ) . $js_file, array('jquery'), SBIVER, true );
1167
  }
1168
 
1169
  if ( isset( $sb_instagram_settings['enqueue_css_in_shortcode'] ) && $sb_instagram_settings['enqueue_css_in_shortcode'] ) {
@@ -1172,14 +1203,13 @@ function sb_instagram_scripts_enqueue() {
1172
  wp_enqueue_style( 'sb_instagram_styles', trailingslashit( SBI_PLUGIN_URL ) . 'css/sbi-styles.min.css', array(), SBIVER );
1173
  }
1174
 
1175
-
1176
  $data = array(
1177
  'font_method' => 'svg',
1178
  'resized_url' => sbi_get_resized_uploads_url(),
1179
  'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png',
1180
- );
1181
  //Pass option to JS file
1182
- wp_localize_script('sb_instagram_scripts', 'sb_instagram_js_options', $data );
1183
 
1184
  if ( SB_Instagram_Blocks::is_gb_editor() ) {
1185
  wp_enqueue_style( 'sb_instagram_styles' );
@@ -1192,27 +1222,27 @@ add_action( 'wp_enqueue_scripts', 'sb_instagram_scripts_enqueue', 2 );
1192
  * Adds the ajax url and custom JavaScript to the page
1193
  */
1194
  function sb_instagram_custom_js() {
1195
- $options = get_option('sb_instagram_settings');
1196
- isset($options[ 'sb_instagram_custom_js' ]) ? $sb_instagram_custom_js = trim($options['sb_instagram_custom_js']) : $sb_instagram_custom_js = '';
1197
 
1198
  echo '<!-- Instagram Feed JS -->';
1199
  echo "\r\n";
1200
  echo '<script type="text/javascript">';
1201
  echo "\r\n";
1202
- echo 'var sbiajaxurl = "' . admin_url('admin-ajax.php') . '";';
1203
 
1204
- if ( !empty( $sb_instagram_custom_js ) ) {
1205
  echo "\r\n";
1206
- echo "jQuery( document ).ready(function($) {";
1207
  echo "\r\n";
1208
- echo "window.sbi_custom_js = function(){";
1209
  echo "\r\n";
1210
- echo stripslashes($sb_instagram_custom_js);
1211
  echo "\r\n";
1212
- echo "}";
1213
  echo "\r\n";
1214
- echo "});";
1215
- }
1216
 
1217
  echo "\r\n";
1218
  echo '</script>';
@@ -1223,30 +1253,46 @@ add_action( 'wp_footer', 'sb_instagram_custom_js' );
1223
  //Custom CSS
1224
  add_action( 'wp_head', 'sb_instagram_custom_css' );
1225
  function sb_instagram_custom_css() {
1226
- $options = get_option('sb_instagram_settings');
1227
 
1228
- isset($options[ 'sb_instagram_custom_css' ]) ? $sb_instagram_custom_css = trim($options['sb_instagram_custom_css']) : $sb_instagram_custom_css = '';
 
 
 
 
1229
 
1230
  //Show CSS if an admin (so can see Hide Photos link), if including Custom CSS or if hiding some photos
1231
- ( current_user_can( 'edit_posts' ) || !empty($sb_instagram_custom_css) ) ? $sbi_show_css = true : $sbi_show_css = false;
1232
 
1233
- if( $sbi_show_css ) echo '<!-- Instagram Feed CSS -->';
1234
- if( $sbi_show_css ) echo "\r\n";
1235
- if( $sbi_show_css ) echo '<style type="text/css">';
 
 
 
 
 
 
1236
 
1237
- if( !empty($sb_instagram_custom_css) ){
1238
  echo "\r\n";
1239
- echo stripslashes($sb_instagram_custom_css);
1240
  }
1241
 
1242
- if( current_user_can( 'edit_posts' ) ){
1243
  echo "\r\n";
1244
- echo "#sbi_mod_link, #sbi_mod_error{ display: block !important; width: 100%; float: left; box-sizing: border-box; }";
1245
  }
1246
 
1247
- if( $sbi_show_css ) echo "\r\n";
1248
- if( $sbi_show_css ) echo '</style>';
1249
- if( $sbi_show_css ) echo "\r\n";
 
 
 
 
 
 
1250
  }
1251
 
1252
  /**
@@ -1259,14 +1305,14 @@ function sb_instagram_custom_css() {
1259
  * @return int
1260
  */
1261
  function sbi_raise_num_in_request( $num, $settings ) {
1262
- if ( $settings['sortby'] === 'random' ) {
1263
- if ( $num > 5 ) {
1264
- return min( $num * 4, 100 );
1265
- } else {
1266
- return 20;
1267
- }
1268
- }
1269
- return $num;
1270
  }
1271
  add_filter( 'sbi_num_in_request', 'sbi_raise_num_in_request', 5, 2 );
1272
 
@@ -1285,10 +1331,9 @@ function sbi_critical_error_notice() {
1285
  }
1286
 
1287
  global $sb_instagram_posts_manager;
1288
- if ( ! $sb_instagram_posts_manager->are_critical_errors() ) {
1289
- return;
1290
- }
1291
-
1292
 
1293
  // Don't show if already dismissed.
1294
  if ( get_option( 'sbi_dismiss_critical_notice', false ) ) {
@@ -1296,143 +1341,143 @@ function sbi_critical_error_notice() {
1296
  }
1297
 
1298
  $db_settings = sbi_get_database_settings();
1299
- if ( isset( $db_settings['disable_admin_notice'] ) && $db_settings['disable_admin_notice'] === 'on' ) {
1300
  return;
1301
  }
1302
 
1303
  ?>
1304
- <div class="sbi-critical-notice sbi-critical-notice-hide">
1305
- <div class="sbi-critical-notice-icon">
1306
- <img src="<?php echo SBI_PLUGIN_URL . 'img/insta-logo.png'; ?>" width="45" alt="Instagram Feed icon" />
1307
- </div>
1308
- <div class="sbi-critical-notice-text">
1309
- <h3><?php esc_html_e( 'Instagram Feed Critical Issue', 'instagram-feed' ); ?></h3>
1310
- <p>
1311
  <?php
1312
  $doc_url = admin_url() . '?page=sb-instagram-feed&amp;tab=configure';
1313
  // Translators: %s is the link to the article where more details about critical are listed.
1314
  printf( esc_html__( 'An issue is preventing your Instagram Feeds from updating. %1$sResolve this issue%2$s.', 'instagram-feed' ), '<a href="' . esc_url( $doc_url ) . '" target="_blank">', '</a>' );
1315
  ?>
1316
- </p>
1317
- </div>
1318
- <div class="sbi-critical-notice-close">&times;</div>
1319
- </div>
1320
- <style type="text/css">
1321
- .sbi-critical-notice {
1322
- position: fixed;
1323
- bottom: 20px;
1324
- right: 15px;
1325
- font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
1326
- background: #fff;
1327
- box-shadow: 0 0 10px 0 #dedede;
1328
- padding: 10px 10px;
1329
- display: flex;
1330
- align-items: center;
1331
- justify-content: center;
1332
- width: 325px;
1333
- max-width: calc( 100% - 30px );
1334
- border-radius: 6px;
1335
- transition: bottom 700ms ease;
1336
- z-index: 10000;
1337
- }
1338
-
1339
- .sbi-critical-notice h3 {
1340
- font-size: 13px;
1341
- color: #222;
1342
- font-weight: 700;
1343
- margin: 0 0 4px;
1344
- padding: 0;
1345
- line-height: 1;
1346
- border: none;
1347
- }
1348
-
1349
- .sbi-critical-notice p {
1350
- font-size: 12px;
1351
- color: #7f7f7f;
1352
- font-weight: 400;
1353
- margin: 0;
1354
- padding: 0;
1355
- line-height: 1.2;
1356
- border: none;
1357
- }
1358
-
1359
- .sbi-critical-notice p a {
1360
- color: #7f7f7f;
1361
- font-size: 12px;
1362
- line-height: 1.2;
1363
- margin: 0;
1364
- padding: 0;
1365
- text-decoration: underline;
1366
- font-weight: 400;
1367
- }
1368
-
1369
- .sbi-critical-notice p a:hover {
1370
- color: #666;
1371
- }
1372
-
1373
- .sbi-critical-notice-icon img {
1374
- height: auto;
1375
- display: block;
1376
- margin: 0;
1377
- }
1378
-
1379
- .sbi-critical-notice-icon {
1380
- padding: 0;
1381
- border-radius: 4px;
1382
- flex-grow: 0;
1383
- flex-shrink: 0;
1384
- margin-right: 12px;
1385
- overflow: hidden;
1386
- }
1387
-
1388
- .sbi-critical-notice-close {
1389
- padding: 10px;
1390
- margin: -12px -9px 0 0;
1391
- border: none;
1392
- box-shadow: none;
1393
- border-radius: 0;
1394
- color: #7f7f7f;
1395
- background: transparent;
1396
- line-height: 1;
1397
- align-self: flex-start;
1398
- cursor: pointer;
1399
- font-weight: 400;
1400
- }
1401
- .sbi-critical-notice-close:hover,
1402
- .sbi-critical-notice-close:focus{
1403
- color: #111;
1404
- }
1405
-
1406
- .sbi-critical-notice.sbi-critical-notice-hide {
1407
- bottom: -200px;
1408
- }
1409
- </style>
1410
  <?php
1411
 
1412
  if ( ! wp_script_is( 'jquery', 'queue' ) ) {
1413
  wp_enqueue_script( 'jquery' );
1414
  }
1415
  ?>
1416
- <script>
1417
- if ( 'undefined' !== typeof jQuery ) {
1418
- jQuery( document ).ready( function ( $ ) {
1419
- /* Don't show the notice if we don't have a way to hide it (no js, no jQuery). */
1420
- $( document.querySelector( '.sbi-critical-notice' ) ).removeClass( 'sbi-critical-notice-hide' );
1421
- $( document.querySelector( '.sbi-critical-notice-close' ) ).on( 'click', function ( e ) {
1422
- e.preventDefault();
1423
- $( this ).closest( '.sbi-critical-notice' ).addClass( 'sbi-critical-notice-hide' );
1424
- $.ajax( {
1425
- url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
1426
- method: 'POST',
1427
- data: {
1428
- action: 'sbi_dismiss_critical_notice',
1429
- nonce: '<?php echo esc_js( wp_create_nonce( 'sbi-critical-notice' ) ); ?>',
1430
- }
1431
- } );
1432
- } );
1433
- } );
1434
- }
1435
- </script>
1436
  <?php
1437
  }
1438
 
@@ -1456,22 +1501,22 @@ add_action( 'wp_ajax_sbi_dismiss_critical_notice', 'sbi_dismiss_critical_notice'
1456
  function sbi_schedule_report_email() {
1457
  $options = get_option( 'sb_instagram_settings', array() );
1458
 
1459
- $input = isset( $options[ 'email_notification' ] ) ? $options[ 'email_notification' ] : 'monday';
1460
  $timestamp = strtotime( 'next ' . $input );
1461
- $timestamp = $timestamp + (3600 * 24 * 7);
1462
 
1463
- $six_am_local = $timestamp + sbi_get_utc_offset() + (6*60*60);
1464
 
1465
  wp_schedule_event( $six_am_local, 'sbiweekly', 'sb_instagram_feed_issue_email' );
1466
  }
1467
 
1468
  function sbi_send_report_email() {
1469
- $options = get_option('sb_instagram_settings' );
1470
 
1471
  $to_string = ! empty( $options['email_notification_addresses'] ) ? str_replace( ' ', '', $options['email_notification_addresses'] ) : get_option( 'admin_email', '' );
1472
 
1473
  $to_array_raw = explode( ',', $to_string );
1474
- $to_array = array();
1475
 
1476
  foreach ( $to_array_raw as $email ) {
1477
  if ( is_email( $email ) ) {
@@ -1482,44 +1527,44 @@ function sbi_send_report_email() {
1482
  if ( empty( $to_array ) ) {
1483
  return false;
1484
  }
1485
- $from_name = esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) );
1486
- $email_from = $from_name . ' <' . get_option( 'admin_email', $to_array[0] ) . '>';
1487
- $header_from = "From: " . $email_from;
1488
 
1489
  $headers = array( 'Content-Type: text/html; charset=utf-8', $header_from );
1490
 
1491
  $header_image = SBI_PLUGIN_URL . 'img/balloon-120.png';
1492
 
1493
- $link = admin_url( '?page=sb-instagram-feed');
1494
  //&tab=customize-advanced
1495
- $footer_link = admin_url('admin.php?page=sb-instagram-feed&tab=customize-advanced&flag=emails');
1496
 
1497
  $is_expiration_notice = false;
1498
 
1499
  if ( isset( $options['connected_accounts'] ) ) {
1500
  foreach ( $options['connected_accounts'] as $account ) {
1501
  if ( $account['type'] === 'basic'
1502
- && isset( $account['private'] )
1503
- && sbi_private_account_near_expiration( $account ) ) {
1504
  $is_expiration_notice = true;
1505
  }
1506
  }
1507
  }
1508
 
1509
  if ( ! $is_expiration_notice ) {
1510
- $title = sprintf( __( 'Instagram Feed Report for %s', 'instagram-feed' ), str_replace( array( 'http://', 'https://' ), '', home_url() ) );
1511
- $bold = __( 'There\'s an Issue with an Instagram Feed on Your Website', 'instagram-feed' );
1512
- $details = '<p>' . __( 'An Instagram feed on your website is currently unable to connect to Instagram to retrieve new posts. Don\'t worry, your feed is still being displayed using a cached version, but is no longer able to display new posts.', 'instagram-feed' ) . '</p>';
1513
- $details .= '<p>' . sprintf( __( 'This is caused by an issue with your Instagram account connecting to the Instagram API. For information on the exact issue and directions on how to resolve it, please visit the %sInstagram Feed settings page%s on your website.', 'instagram-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' ). '</p>';
1514
  } else {
1515
- $title = __( 'Your Private Instagram Feed Account Needs to be Reauthenticated', 'instagram-feed' );
1516
- $bold = __( 'Access Token Refresh Needed', 'instagram-feed' );
1517
- $details = '<p>' . __( 'As your Instagram account is set to be "Private", Instagram requires that you reauthenticate your account every 60 days. This a courtesy email to let you know that you need to take action to allow the Instagram feed on your website to continue updating. If you don\'t refresh your account, then a backup cache will be displayed instead.', 'instagram-feed' ) . '</p>';
1518
- $details .= '<p>' . sprintf( __( 'To prevent your account expiring every 60 days %sswitch your account to be public%s. For more information and to refresh your account, click here to visit the %sInstagram Feed settings page%s on your website.', 'instagram-feed' ), '<a href="https://help.instagram.com/116024195217477/In">', '</a>', '<a href="' . esc_url( $link ) . '">', '</a>' ). '</p>';
1519
  }
1520
  $message_content = '<h6 style="padding:0;word-wrap:normal;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;font-weight:bold;line-height:130%;font-size: 16px;color:#444444;text-align:inherit;margin:0 0 20px 0;Margin:0 0 20px 0;">' . $bold . '</h6>' . $details;
1521
  include_once SBI_PLUGIN_DIR . 'inc/class-sb-instagram-education.php';
1522
- $educator = new SB_Instagram_Education();
1523
  $dyk_message = $educator->dyk_display();
1524
  ob_start();
1525
  include SBI_PLUGIN_DIR . 'inc/email.php';
@@ -1536,7 +1581,7 @@ function sbi_maybe_send_feed_issue_email() {
1536
  if ( ! $sb_instagram_posts_manager->are_critical_errors() ) {
1537
  return;
1538
  }
1539
- $options = get_option('sb_instagram_settings' );
1540
 
1541
  if ( isset( $options['enable_email_report'] ) && empty( $options['enable_email_report'] ) ) {
1542
  return;
@@ -1556,4 +1601,4 @@ function sbi_get_option( $option_name, $default ) {
1556
 
1557
  function sbi_is_pro_version() {
1558
  return defined( 'SBI_STORE_URL' );
1559
- }
13
  * - Enqueueing CSS and JS files for the feed
14
  *
15
  */
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit; // Exit if accessed directly
18
+ }
19
 
20
  add_filter( 'widget_text', 'do_shortcode' );
21
 
24
  * Can be safely added directly to templates using
25
  * 'echo do_shortcode( "[instagram-feed]" );'
26
  */
27
+ add_shortcode( 'instagram-feed', 'display_instagram' );
28
  function display_instagram( $atts = array() ) {
29
 
30
  $database_settings = sbi_get_database_settings();
31
 
32
+ if ( $database_settings['sb_instagram_ajax_theme'] !== 'on' && $database_settings['sb_instagram_ajax_theme'] !== 'true' && $database_settings['sb_instagram_ajax_theme'] !== true ) {
33
  wp_enqueue_script( 'sb_instagram_scripts' );
34
  }
35
 
36
+ if ( $database_settings['enqueue_css_in_shortcode'] === 'on' || $database_settings['enqueue_css_in_shortcode'] === 'true' || $database_settings['enqueue_css_in_shortcode'] === true ) {
37
  wp_enqueue_style( 'sb_instagram_styles' );
38
  }
39
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
40
 
41
+ if ( current_user_can( 'manage_instagram_feed_options' )
42
+ && empty( $database_settings['connected_accounts'] )
43
+ && empty( $atts['accesstoken'] ) ) {
44
  ob_start(); ?>
45
+ <div id="sbi_mod_error">
46
+ <span><?php esc_html_e( 'This error message is only visible to WordPress admins', 'instagram-feed' ); ?></span><br />
47
+ <p><strong><?php esc_html_e( 'Error: No connected account.', 'instagram-feed' ); ?></strong>
48
+ <p><?php esc_html_e( 'Please go to the Instagram Feed settings page to connect an account.', 'instagram-feed' ); ?></p>
49
+ </div>
50
  <?php
51
  $html = ob_get_contents();
52
  ob_get_clean();
55
 
56
  $instagram_feed_settings->set_feed_type_and_terms();
57
  $instagram_feed_settings->set_transient_name();
58
+ $transient_name = $instagram_feed_settings->get_transient_name();
59
+ $settings = $instagram_feed_settings->get_settings();
60
  $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
61
 
62
  $instagram_feed = new SB_Instagram_Feed( $transient_name );
71
  if ( $instagram_feed->need_to_start_cron_job() ) {
72
  $instagram_feed->add_report( 'setting up feed for cron cache' );
73
  $to_cache = array(
74
+ 'atts' => $atts,
75
+ 'last_requested' => time(),
76
+ );
77
 
78
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() );
79
 
89
 
90
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
91
  }
92
+ } elseif ( $instagram_feed->regular_cache_exists() ) {
 
93
  $instagram_feed->add_report( 'page load caching used and regular cache exists' );
94
  $instagram_feed->set_post_data_from_cache();
95
 
96
+ if ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
97
+ while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
98
  $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
99
  }
100
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
101
  }
 
102
  } else {
103
  $instagram_feed->add_report( 'no feed cache found' );
104
 
109
  if ( ! $instagram_feed->should_use_backup() ) {
110
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
111
  }
 
112
  }
113
 
114
  if ( $instagram_feed->should_use_backup() ) {
117
  $instagram_feed->maybe_set_header_data_from_backup();
118
  }
119
 
 
120
  // if need a header
121
  if ( $instagram_feed->need_header( $settings, $feed_type_and_terms ) ) {
122
  if ( $instagram_feed->should_use_backup() && $settings['minnum'] > 0 ) {
146
  $post_set = new SB_Instagram_Post_Set( $post_data, $transient_name );
147
 
148
  $post_set->maybe_save_update_and_resize_images_for_posts();
149
+ }
150
 
151
  if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
152
  global $sb_instagram_posts_manager;
182
  }
183
  }
184
  ?>
185
+ <span class="sbi_resized_image_data" data-feed-id="<?php echo esc_attr( $feed_id ); ?>" data-resized="<?php echo esc_attr( sbi_json_encode( SB_Instagram_Feed::get_resized_images_source_set( $instagram_feed->get_image_ids_post_set(), 0, $feed_id ) ) ); ?>">
186
  </span>
187
  <?php
188
  }
193
  * Resembles "display_instagram"
194
  */
195
  function sbi_get_next_post_set() {
196
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
197
  if ( ! isset( $_POST['feed_id'] ) || strpos( $_POST['feed_id'], 'sbi' ) === false ) {
198
+ die( 'invalid feed ID' );
199
  }
200
 
201
  $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
202
 
203
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
204
  $atts_raw = isset( $_POST['atts'] ) ? json_decode( stripslashes( $_POST['atts'] ), true ) : array();
205
  if ( is_array( $atts_raw ) ) {
206
  $atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw );
209
  }
210
  $atts = $atts_raw; // now sanitized
211
 
212
+ $offset = isset( $_POST['offset'] ) ? (int) $_POST['offset'] : 0;
213
+ $page = isset( $_POST['page'] ) ? (int) $_POST['page'] : 1;
214
 
215
+ $database_settings = sbi_get_database_settings();
216
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
217
 
218
  if ( empty( $database_settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
229
 
230
  $settings = $instagram_feed_settings->get_settings();
231
 
232
+ $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( wp_unslash( $_POST['location'] ) ) : 'unknown';
233
+ $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int) $_POST['post_id'] : 'unknown';
234
  $feed_details = array(
235
+ 'feed_id' => $transient_name,
236
+ 'atts' => $atts,
237
  'location' => array(
238
  'post_id' => $post_id,
239
+ 'html' => $location,
240
+ ),
241
  );
242
 
243
  $can_do_background_tasks = false;
244
  if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
245
  $nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : '';
246
  if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) {
247
+ $can_do_background_tasks = true;
248
  }
249
  } else {
250
  $can_do_background_tasks = true;
272
  $normal_method = true;
273
  if ( $instagram_feed->need_to_start_cron_job() ) {
274
  $instagram_feed->add_report( 'needed to start cron job' );
275
+ $to_cache = array(
276
+ 'atts' => $atts,
277
  'last_requested' => time(),
278
  );
279
  $normal_method = false;
291
  $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() );
292
  }
293
  }
 
294
  } elseif ( $instagram_feed->regular_cache_exists() ) {
295
  $instagram_feed->add_report( 'regular cache exists' );
296
  $instagram_feed->set_post_data_from_cache();
297
 
298
+ if ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
299
+ while ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
300
  $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
301
  }
302
 
303
  $instagram_feed->add_report( 'adding to cache' );
304
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
305
  }
 
 
306
  } else {
307
  $instagram_feed->add_report( 'no feed cache found' );
308
 
317
  $instagram_feed->add_report( 'transient gone, adding to cache' );
318
  $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
319
  }
 
320
  }
321
 
322
  if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
337
  $feed_status = array( 'shouldPaginate' => $instagram_feed->should_use_pagination( $settings, $offset ) );
338
 
339
  $return = array(
340
+ 'html' => $instagram_feed->get_the_items_html( $settings, $offset ),
341
  'feedStatus' => $feed_status,
342
  'report' => $instagram_feed->get_report(),
343
  'resizedImages' => SB_Instagram_Feed::get_resized_images_source_set( $instagram_feed->get_image_ids_post_set(), 1, $feed_id )
357
  * @return string
358
  */
359
  function sbi_process_submitted_resize_ids() {
360
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
361
  if ( ! isset( $_POST['feed_id'] ) || strpos( $_POST['feed_id'], 'sbi' ) === false ) {
362
+ die( 'invalid feed ID' );
363
  }
364
 
365
+ $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
366
  $images_need_resizing_raw = isset( $_POST['needs_resizing'] ) ? wp_unslash( $_POST['needs_resizing'] ) : array();
367
  if ( is_array( $images_need_resizing_raw ) ) {
368
+ array_map( 'sbi_sanitize_instagram_ids', $images_need_resizing_raw );
369
  } else {
370
  $images_need_resizing_raw = array();
371
  }
372
  $images_need_resizing = $images_need_resizing_raw;
373
 
374
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
375
  $atts_raw = isset( $_POST['atts'] ) ? json_decode( wp_unslash( $_POST['atts'] ), true ) : array();
376
  if ( is_array( $atts_raw ) ) {
377
  $atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw );
380
  }
381
  $atts = $atts_raw; // now sanitized
382
 
383
+ $offset = isset( $_POST['offset'] ) ? (int) $_POST['offset'] : 0;
384
  $cache_all = isset( $_POST['cache_all'] ) ? $_POST['cache_all'] === 'true' : false;
385
 
386
+ $database_settings = sbi_get_database_settings();
387
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
388
 
389
  if ( empty( $database_settings['connected_accounts'] ) && empty( $atts['accesstoken'] ) ) {
400
 
401
  $settings = $instagram_feed_settings->get_settings();
402
 
403
+ $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( wp_unslash( $_POST['location'] ) ) : 'unknown';
404
+ $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int) $_POST['post_id'] : 'unknown';
405
  $feed_details = array(
406
+ 'feed_id' => $transient_name,
407
+ 'atts' => $atts,
408
  'location' => array(
409
  'post_id' => $post_id,
410
+ 'html' => $location,
411
+ ),
412
  );
413
 
414
  $can_do_background_tasks = false;
429
  $settings['cache_all'] = true;
430
  }
431
 
432
+ sbi_resize_posts_by_id( $images_need_resizing, $transient_name );
433
  sbi_delete_image_cache( $transient_name );
434
 
435
  global $sb_instagram_posts_manager;
439
  die();
440
  }
441
 
 
442
  die( 'resizing success' );
443
  }
444
  add_action( 'wp_ajax_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' );
445
  add_action( 'wp_ajax_nopriv_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' );
446
 
447
  function sbi_do_locator() {
448
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
449
  if ( ! isset( $_POST['feed_id'] ) || strpos( $_POST['feed_id'], 'sbi' ) === false ) {
450
+ die( 'invalid feed ID' );
451
  }
452
 
453
  $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
460
  }
461
  $atts = $atts_raw; // now sanitized
462
 
463
+ $database_settings = sbi_get_database_settings();
464
  $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
465
 
466
  $instagram_feed_settings->set_feed_type_and_terms();
467
  $instagram_feed_settings->set_transient_name();
468
  $transient_name = $instagram_feed_settings->get_transient_name();
469
 
470
+ $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown';
471
+ $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int) $_POST['post_id'] : 'unknown';
472
  $feed_details = array(
473
+ 'feed_id' => $feed_id,
474
+ 'atts' => $atts,
475
  'location' => array(
476
  'post_id' => $post_id,
477
+ 'html' => $location,
478
+ ),
479
  );
480
 
481
  $can_do_background_tasks = false;
514
  * @param object $instagram_feed
515
  * @param string $feed_id
516
  */
517
+ function sbi_error_report( $instagram_feed ) {
518
  global $sb_instagram_posts_manager;
519
 
 
 
520
  $error_messages = $sb_instagram_posts_manager->get_frontend_errors( $instagram_feed );
521
 
522
+ if ( sbi_current_user_can( 'manage_instagram_feed_options' ) && ! empty( $error_messages ) ) {
523
+ ?>
524
+ <div id="sbi_mod_error">
525
+ <span><?php esc_html_e( 'This error message is only visible to WordPress admins', 'instagram-feed' ); ?></span><br />
526
+ <?php
527
+ foreach ( $error_messages as $error_message ) {
528
 
529
+ echo '<div><strong>' . esc_html( $error_message['error_message'] ) . '</strong>';
530
  if ( sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
531
+ echo '<br>' . wp_kses_post( $error_message['admin_only'] );
532
+ echo '<br>' . wp_kses_post( $error_message['frontend_directions'] );
533
  }
534
  echo '</div>';
535
+ }
536
+ ?>
537
+ </div>
538
  <?php
539
  }
540
 
568
  * @param string $feed_id
569
  */
570
  function sbi_debug_report( $instagram_feed, $feed_id ) {
571
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
572
+ if ( ! isset( $_GET['sbi_debug'] ) ) {
573
+ return;
574
+ }
575
 
576
+ ?>
577
+ <p>Status</p>
578
+ <ul>
579
+ <li>Time: <?php echo esc_html( date( 'Y-m-d H:i:s', time() ) ); ?></li>
580
+ <?php foreach ( $instagram_feed->get_report() as $item ) : ?>
581
+ <li><?php echo esc_html( $item ); ?></li>
582
+ <?php endforeach; ?>
 
 
 
 
583
 
584
  </ul>
585
 
586
+ <?php
587
  $database_settings = sbi_get_database_settings();
588
 
589
  $public_settings_keys = SB_Instagram_Settings::get_public_db_settings_keys();
590
+ ?>
591
+ <p>Settings</p>
592
+ <ul>
593
+ <?php
594
+ foreach ( $public_settings_keys as $key ) :
595
+ if ( isset( $database_settings[ $key ] ) ) :
596
+ ?>
597
+ <li>
598
+ <small><?php echo esc_html( $key ); ?>:</small>
599
+ <?php
600
+ if ( ! is_array( $database_settings[ $key ] ) ) :
601
+ echo esc_html( $database_settings[ $key ] );
602
+ else :
603
+ ?>
604
  <pre>
605
+ <?php var_export( $database_settings[ $key ] ); ?>
606
  </pre>
607
+ <?php endif; ?>
608
+ </li>
609
 
610
+ <?php
611
+ endif;
612
+ endforeach;
613
+ ?>
614
+ </ul>
615
+ <p>GDPR</p>
616
+ <ul>
617
  <?php
618
+ $statuses = SB_Instagram_GDPR_Integrations::statuses();
619
+ foreach ( $statuses as $status_key => $value ) :
620
+ ?>
621
+ <li>
622
+ <small><?php echo esc_html( $status_key ); ?>:</small>
623
+ <?php
624
+ if ( $value === 1 ) {
625
+ echo 'success';
626
+ } else {
627
+ echo 'failed'; }
628
+ ?>
629
+ </li>
630
 
631
  <?php endforeach; ?>
632
+ <li>
633
+ <small>Enabled:</small>
634
+ <?php echo esc_html( SB_Instagram_GDPR_Integrations::doing_gdpr( $database_settings ) ); ?>
635
+ </li>
636
+ </ul>
637
+ <?php
638
  }
639
  add_action( 'sbi_before_feed_end', 'sbi_debug_report', 11, 2 );
640
 
646
  * @param array $settings
647
  * @param int $offset
648
  */
649
+ function sbi_resize_posts_by_id( $ids, $transient_name, $offset = 0 ) {
650
  $instagram_feed = new SB_Instagram_Feed( $transient_name );
651
 
652
  if ( $instagram_feed->regular_cache_exists() ) {
655
 
656
  $cached_post_data = $instagram_feed->get_post_data();
657
 
658
+ $num_ids = count( $ids );
659
  $found_posts = array();
660
+ $i = 0;
661
+ while ( count( $found_posts ) < $num_ids && isset( $cached_post_data[ $i ] ) ) {
662
+ if ( ! empty( $cached_post_data[ $i ]['id'] ) && in_array( $cached_post_data[ $i ]['id'], $ids, true ) ) {
663
+ $found_posts[] = $cached_post_data[ $i ];
664
+ }
665
+ $i++;
666
+ }
667
 
668
  $fill_in_timestamp = date( 'Y-m-d H:i:s', time() + 120 );
669
 
 
 
 
 
670
  $post_set = new SB_Instagram_Post_Set( $found_posts, $transient_name, $fill_in_timestamp );
671
 
672
  $post_set->maybe_save_update_and_resize_images_for_posts();
674
  }
675
 
676
  function sbi_store_local_avatar( $connected_account ) {
677
+ $sbi_settings = get_option( 'sb_instagram_settings', array() );
678
  $connected_accounts = $sbi_settings['connected_accounts'];
679
  if ( sbi_create_local_avatar( $connected_account['username'], $connected_account['profile_picture'] ) ) {
680
  $connected_accounts[ $connected_account['user_id'] ]['local_avatar'] = true;
682
  $connected_accounts[ $connected_account['user_id'] ]['local_avatar'] = false;
683
  }
684
 
 
685
  $sbi_settings['connected_accounts'] = $connected_accounts;
686
 
687
  update_option( 'sb_instagram_settings', $sbi_settings );
695
  if ( ! is_wp_error( $image_editor ) ) {
696
  $upload = wp_upload_dir();
697
 
698
+ $full_file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg';
699
 
700
  $saved_image = $image_editor->save( $full_file_name );
701
 
726
  * @return array
727
  */
728
  function sbi_get_database_settings() {
729
+ $defaults = array(
730
+ 'sb_instagram_at' => '',
731
+ 'sb_instagram_user_id' => '',
732
+ 'sb_instagram_preserve_settings' => '',
733
+ 'sb_instagram_ajax_theme' => false,
734
+ 'sb_instagram_disable_resize' => false,
735
+ 'sb_instagram_cache_time' => 1,
736
+ 'sb_instagram_cache_time_unit' => 'hours',
737
+ 'sbi_caching_type' => 'page',
738
+ 'sbi_cache_cron_interval' => '12hours',
739
+ 'sbi_cache_cron_time' => '1',
740
+ 'sbi_cache_cron_am_pm' => 'am',
741
+ 'sb_instagram_width' => '100',
742
+ 'sb_instagram_width_unit' => '%',
743
+ 'sb_instagram_feed_width_resp' => false,
744
+ 'sb_instagram_height' => '',
745
+ 'sb_instagram_num' => '20',
746
+ 'sb_instagram_height_unit' => '',
747
+ 'sb_instagram_cols' => '4',
748
+ 'sb_instagram_disable_mobile' => false,
749
+ 'sb_instagram_image_padding' => '5',
750
+ 'sb_instagram_image_padding_unit' => 'px',
751
+ 'sb_instagram_sort' => 'none',
752
+ 'sb_instagram_background' => '',
753
+ 'sb_instagram_show_btn' => true,
754
+ 'sb_instagram_btn_background' => '',
755
+ 'sb_instagram_btn_text_color' => '',
756
+ 'sb_instagram_btn_text' => __( 'Load More...', 'instagram-feed' ),
757
+ 'sb_instagram_image_res' => 'auto',
758
  //Header
759
+ 'sb_instagram_show_header' => true,
760
+ 'sb_instagram_header_size' => 'small',
761
+ 'sb_instagram_header_color' => '',
762
  //Follow button
763
+ 'sb_instagram_show_follow_btn' => true,
764
+ 'sb_instagram_folow_btn_background' => '',
765
  'sb_instagram_follow_btn_text_color' => '',
766
+ 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
767
  //Misc
768
+ 'sb_instagram_custom_css' => '',
769
+ 'sb_instagram_custom_js' => '',
770
+ 'sb_instagram_cron' => 'no',
771
+ 'sb_instagram_backup' => true,
772
+ 'sb_ajax_initial' => false,
773
+ 'enqueue_css_in_shortcode' => false,
774
+ 'sb_instagram_disable_mob_swipe' => false,
775
+ 'sb_instagram_disable_awesome' => false,
776
  );
777
  $sbi_settings = get_option( 'sb_instagram_settings', array() );
778
 
788
  $file = '';
789
 
790
  $using_custom_templates_in_theme = apply_filters( 'sbi_use_theme_templates', $settings['customtemplates'] );
791
+ $generic_path = trailingslashit( SBI_PLUGIN_DIR ) . 'templates/';
792
 
793
  if ( $using_custom_templates_in_theme ) {
794
  $custom_header_template = locate_template( 'sbi/header.php', false, false );
795
+ $custom_item_template = locate_template( 'sbi/item.php', false, false );
796
  $custom_footer_template = locate_template( 'sbi/footer.php', false, false );
797
+ $custom_feed_template = locate_template( 'sbi/feed.php', false, false );
798
  } else {
799
  $custom_header_template = false;
800
+ $custom_item_template = false;
801
  $custom_footer_template = false;
802
+ $custom_feed_template = false;
803
  }
804
 
805
  if ( $part === 'header' ) {
806
+ if ( $custom_header_template ) {
807
+ $file = $custom_header_template;
808
+ } else {
809
+ $file = $generic_path . 'header.php';
810
+ }
811
  } elseif ( $part === 'item' ) {
812
  if ( $custom_item_template ) {
813
  $file = $custom_item_template;
835
  * Triggered by a cron event to update feeds
836
  */
837
  function sbi_cron_updater() {
838
+ $sbi_settings = sbi_get_database_settings();
839
 
840
+ if ( $sbi_settings['sbi_caching_type'] === 'background' ) {
841
+ $cron_updater = new SB_Instagram_Cron_Updater();
842
 
843
+ $cron_updater->do_feed_updates();
844
+ }
845
 
846
  }
847
  add_action( 'sbi_feed_update', 'sbi_cron_updater' );
858
  if ( $decrypted ) {
859
  $maybe_dirty = $decrypted;
860
  }
861
+ if ( substr_count( $maybe_dirty, '.' ) < 3 ) {
862
  return str_replace( '634hgdf83hjdj2', '', $maybe_dirty );
863
  }
864
 
865
+ $parts = explode( '.', trim( $maybe_dirty ) );
866
  $last_part = $parts[2] . $parts[3];
867
+ $cleaned = $parts[0] . '.' . base64_decode( $parts[1] ) . '.' . base64_decode( $last_part );
868
 
869
  return $cleaned;
870
  }
875
  * @return string
876
  */
877
  function sbi_get_parts( $whole ) {
878
+ if ( substr_count( $whole, '.' ) !== 2 ) {
879
  return $whole;
880
  }
881
 
882
+ $parts = explode( '.', trim( $whole ) );
883
+ $return = $parts[0] . '.' . base64_encode( $parts[1] ) . '.' . base64_encode( $parts[2] );
884
 
885
  return substr( $return, 0, 40 ) . '.' . substr( $return, 40, 100 );
886
  }
898
  if ( isset( $time_stamp_a ) ) {
899
  return $time_stamp_b - $time_stamp_a;
900
  } else {
901
+ return rand( -1, 1 );
902
  }
903
  }
904
 
905
  function sbi_code_check( $code ) {
906
+ if ( strpos( $code, '634hgdf83hjdj2' ) !== false ) {
907
  return true;
908
  }
909
  return false;
910
  }
911
 
912
  function sbi_fixer( $code ) {
913
+ if ( strpos( $code, '634hgdf83hjdj2' ) !== false ) {
914
  return $code;
915
  } else {
916
+ return substr_replace( $code, '634hgdf83hjdj2', 15, 0 );
917
  }
918
  }
919
 
920
  /**
 
 
 
921
  * @return false|int
922
  */
923
+ function sbi_rand_sort() {
924
  return rand ( -1, 1 );
925
  }
926
 
961
  $hex = str_replace( '#', '', $hex );
962
 
963
  if ( strlen( $hex ) === 3 ) {
964
+ $r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
965
+ $g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
966
+ $b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
967
  } else {
968
+ $r = hexdec( substr( $hex, 0, 2 ) );
969
+ $g = hexdec( substr( $hex, 2, 2 ) );
970
+ $b = hexdec( substr( $hex, 4, 2 ) );
971
  }
972
  $rgb = array( $r, $g, $b );
973
 
986
  */
987
  function sbi_sanitize_emoji( $string ) {
988
  $encoded = array(
989
+ 'jsonencoded' => $string,
990
  );
991
  return sbi_json_encode( $encoded );
992
  }
1004
  return $string;
1005
  }
1006
 
1007
+ function sbi_sanitize_instagram_ids( $raw_id ) {
1008
+ return preg_replace( '/[^0-9_]/', '', $raw_id );
1009
+ }
1010
+
1011
+ function sbi_sanitize_alphanumeric_and_equals( $value ) {
1012
+ return preg_replace( '/[^A-Za-z0-9=]/', '', $value );
1013
+ }
1014
+
1015
+ function sbi_sanitize_username( $value ) {
1016
+ return preg_replace( '/[^A-Za-z0-9_.]/', '', $value );
1017
+ }
1018
+
1019
  /**
1020
  * @return int
1021
  */
1051
  }
1052
 
1053
  function sbi_json_encode( $thing ) {
1054
+ if ( function_exists( 'wp_json_encode' ) ) {
1055
+ return wp_json_encode( $thing );
1056
+ } else {
1057
+ return json_encode( $thing );
1058
+ }
1059
  }
1060
 
1061
  function sbi_private_account_near_expiration( $connected_account ) {
1062
+ $expires_in = max( 0, floor( ( $connected_account['expires_timestamp'] - time() ) / DAY_IN_SECONDS ) );
1063
  return $expires_in < 10;
1064
  }
1065
 
1087
  function sb_instagram_cron_clear_cache() {
1088
  //Delete all transients
1089
  global $wpdb;
1090
+ $table_name = $wpdb->prefix . 'options';
1091
+ $wpdb->query(
1092
+ "
1093
  DELETE
1094
  FROM $table_name
1095
  WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
1096
+ "
1097
+ );
1098
+ $wpdb->query(
1099
+ "
1100
  DELETE
1101
  FROM $table_name
1102
  WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')
1103
+ "
1104
+ );
1105
+ $wpdb->query(
1106
+ "
1107
  DELETE
1108
  FROM $table_name
1109
  WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')
1110
+ "
1111
+ );
1112
+ $wpdb->query(
1113
+ "
1114
  DELETE
1115
  FROM $table_name
1116
  WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')
1117
+ "
1118
+ );
1119
+ $wpdb->query(
1120
+ "
1121
  DELETE
1122
  FROM $table_name
1123
  WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')
1124
+ "
1125
+ );
1126
+ $wpdb->query(
1127
+ "
1128
  DELETE
1129
  FROM $table_name
1130
  WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')
1131
+ "
1132
+ );
1133
 
1134
  sb_instagram_clear_page_caches();
1135
  }
1140
  */
1141
  function sb_instagram_clear_page_caches() {
1142
 
1143
+ $clear_page_caches = apply_filters( 'sbi_clear_page_caches', true );
1144
+ if ( ! $clear_page_caches ) {
1145
+ return;
1146
+ }
1147
 
1148
+ if ( isset( $GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) {
1149
  /* Clear WP fastest cache*/
1150
  $GLOBALS['wp_fastest_cache']->deleteCache();
1151
  }
1154
  wp_cache_clear_cache();
1155
  }
1156
 
1157
+ if ( class_exists( 'W3_Plugin_TotalCacheAdmin' ) ) {
1158
+ $plugin_totalcacheadmin = & w3_instance( 'W3_Plugin_TotalCacheAdmin' );
1159
 
1160
  $plugin_totalcacheadmin->flush_all();
1161
  }
1172
  // Litespeed Cache
1173
  if ( method_exists( 'LiteSpeed_Cache_API', 'purge' ) ) {
1174
  LiteSpeed_Cache_API::purge( 'esi.instagram-feed' );
1175
+ }
1176
  }
1177
 
1178
  /**
1186
  $sb_instagram_settings = get_option( 'sb_instagram_settings' );
1187
 
1188
  $js_file = 'js/sbi-scripts.min.js';
1189
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1190
  if ( isset( $_GET['sbi_debug'] ) ) {
1191
  $js_file = 'js/sbi-scripts.js';
1192
  }
1193
 
1194
  if ( isset( $sb_instagram_settings['enqueue_js_in_head'] ) && $sb_instagram_settings['enqueue_js_in_head'] ) {
1195
+ wp_enqueue_script( 'sb_instagram_scripts', trailingslashit( SBI_PLUGIN_URL ) . $js_file, array( 'jquery' ), SBIVER, false );
1196
  } else {
1197
+ wp_register_script( 'sb_instagram_scripts', trailingslashit( SBI_PLUGIN_URL ) . $js_file, array( 'jquery' ), SBIVER, true );
1198
  }
1199
 
1200
  if ( isset( $sb_instagram_settings['enqueue_css_in_shortcode'] ) && $sb_instagram_settings['enqueue_css_in_shortcode'] ) {
1203
  wp_enqueue_style( 'sb_instagram_styles', trailingslashit( SBI_PLUGIN_URL ) . 'css/sbi-styles.min.css', array(), SBIVER );
1204
  }
1205
 
 
1206
  $data = array(
1207
  'font_method' => 'svg',
1208
  'resized_url' => sbi_get_resized_uploads_url(),
1209
  'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png',
1210
+ );
1211
  //Pass option to JS file
1212
+ wp_localize_script( 'sb_instagram_scripts', 'sb_instagram_js_options', $data );
1213
 
1214
  if ( SB_Instagram_Blocks::is_gb_editor() ) {
1215
  wp_enqueue_style( 'sb_instagram_styles' );
1222
  * Adds the ajax url and custom JavaScript to the page
1223
  */
1224
  function sb_instagram_custom_js() {
1225
+ $options = get_option( 'sb_instagram_settings' );
1226
+ isset( $options['sb_instagram_custom_js'] ) ? $sb_instagram_custom_js = trim( $options['sb_instagram_custom_js'] ) : $sb_instagram_custom_js = '';
1227
 
1228
  echo '<!-- Instagram Feed JS -->';
1229
  echo "\r\n";
1230
  echo '<script type="text/javascript">';
1231
  echo "\r\n";
1232
+ echo 'var sbiajaxurl = "' . admin_url( 'admin-ajax.php' ) . '";';
1233
 
1234
+ if ( ! empty( $sb_instagram_custom_js ) ) {
1235
  echo "\r\n";
1236
+ echo 'jQuery( document ).ready(function($) {';
1237
  echo "\r\n";
1238
+ echo 'window.sbi_custom_js = function(){';
1239
  echo "\r\n";
1240
+ echo stripslashes( $sb_instagram_custom_js );
1241
  echo "\r\n";
1242
+ echo '}';
1243
  echo "\r\n";
1244
+ echo '});';
1245
+ }
1246
 
1247
  echo "\r\n";
1248
  echo '</script>';
1253
  //Custom CSS
1254
  add_action( 'wp_head', 'sb_instagram_custom_css' );
1255
  function sb_instagram_custom_css() {
1256
+ $options = get_option( 'sb_instagram_settings' );
1257
 
1258
+ if ( preg_match( '#</?\w+#', $options['sb_instagram_custom_css'] ) ) {
1259
+ $sb_instagram_custom_css = '';
1260
+ } else {
1261
+ $sb_instagram_custom_css = $options['sb_instagram_custom_css'];
1262
+ }
1263
 
1264
  //Show CSS if an admin (so can see Hide Photos link), if including Custom CSS or if hiding some photos
1265
+ ( current_user_can( 'edit_posts' ) || ! empty( $sb_instagram_custom_css ) ) ? $sbi_show_css = true : $sbi_show_css = false;
1266
 
1267
+ if ( $sbi_show_css ) {
1268
+ echo '<!-- Instagram Feed CSS -->';
1269
+ }
1270
+ if ( $sbi_show_css ) {
1271
+ echo "\r\n";
1272
+ }
1273
+ if ( $sbi_show_css ) {
1274
+ echo '<style type="text/css">';
1275
+ }
1276
 
1277
+ if ( ! empty( $sb_instagram_custom_css ) ) {
1278
  echo "\r\n";
1279
+ echo stripslashes( $sb_instagram_custom_css );
1280
  }
1281
 
1282
+ if ( sbi_current_user_can( 'edit_posts' ) ) {
1283
  echo "\r\n";
1284
+ echo '#sbi_mod_link, #sbi_mod_error{ display: block !important; width: 100%; float: left; box-sizing: border-box; }';
1285
  }
1286
 
1287
+ if ( $sbi_show_css ) {
1288
+ echo "\r\n";
1289
+ }
1290
+ if ( $sbi_show_css ) {
1291
+ echo '</style>';
1292
+ }
1293
+ if ( $sbi_show_css ) {
1294
+ echo "\r\n";
1295
+ }
1296
  }
1297
 
1298
  /**
1305
  * @return int
1306
  */
1307
  function sbi_raise_num_in_request( $num, $settings ) {
1308
+ if ( $settings['sortby'] === 'random' ) {
1309
+ if ( $num > 5 ) {
1310
+ return min( $num * 4, 100 );
1311
+ } else {
1312
+ return 20;
1313
+ }
1314
+ }
1315
+ return $num;
1316
  }
1317
  add_filter( 'sbi_num_in_request', 'sbi_raise_num_in_request', 5, 2 );
1318
 
1331
  }
1332
 
1333
  global $sb_instagram_posts_manager;
1334
+ if ( ! $sb_instagram_posts_manager->are_critical_errors() ) {
1335
+ return;
1336
+ }
 
1337
 
1338
  // Don't show if already dismissed.
1339
  if ( get_option( 'sbi_dismiss_critical_notice', false ) ) {
1341
  }
1342
 
1343
  $db_settings = sbi_get_database_settings();
1344
+ if ( isset( $db_settings['disable_admin_notice'] ) && ($db_settings['disable_admin_notice'] === 'on' || $db_settings['disable_admin_notice'] === true) ) {
1345
  return;
1346
  }
1347
 
1348
  ?>
1349
+ <div class="sbi-critical-notice sbi-critical-notice-hide">
1350
+ <div class="sbi-critical-notice-icon">
1351
+ <img src="<?php echo esc_url( SBI_PLUGIN_URL . 'img/insta-logo.png' ); ?>" width="45" alt="Instagram Feed icon" />
1352
+ </div>
1353
+ <div class="sbi-critical-notice-text">
1354
+ <h3><?php esc_html_e( 'Instagram Feed Critical Issue', 'instagram-feed' ); ?></h3>
1355
+ <p>
1356
  <?php
1357
  $doc_url = admin_url() . '?page=sb-instagram-feed&amp;tab=configure';
1358
  // Translators: %s is the link to the article where more details about critical are listed.
1359
  printf( esc_html__( 'An issue is preventing your Instagram Feeds from updating. %1$sResolve this issue%2$s.', 'instagram-feed' ), '<a href="' . esc_url( $doc_url ) . '" target="_blank">', '</a>' );
1360
  ?>
1361
+ </p>
1362
+ </div>
1363
+ <div class="sbi-critical-notice-close">&times;</div>
1364
+ </div>
1365
+ <style type="text/css">
1366
+ .sbi-critical-notice {
1367
+ position: fixed;
1368
+ bottom: 20px;
1369
+ right: 15px;
1370
+ font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
1371
+ background: #fff;
1372
+ box-shadow: 0 0 10px 0 #dedede;
1373
+ padding: 10px 10px;
1374
+ display: flex;
1375
+ align-items: center;
1376
+ justify-content: center;
1377
+ width: 325px;
1378
+ max-width: calc( 100% - 30px );
1379
+ border-radius: 6px;
1380
+ transition: bottom 700ms ease;
1381
+ z-index: 10000;
1382
+ }
1383
+
1384
+ .sbi-critical-notice h3 {
1385
+ font-size: 13px;
1386
+ color: #222;
1387
+ font-weight: 700;
1388
+ margin: 0 0 4px;
1389
+ padding: 0;
1390
+ line-height: 1;
1391
+ border: none;
1392
+ }
1393
+
1394
+ .sbi-critical-notice p {
1395
+ font-size: 12px;
1396
+ color: #7f7f7f;
1397
+ font-weight: 400;
1398
+ margin: 0;
1399
+ padding: 0;
1400
+ line-height: 1.2;
1401
+ border: none;
1402
+ }
1403
+
1404
+ .sbi-critical-notice p a {
1405
+ color: #7f7f7f;
1406
+ font-size: 12px;
1407
+ line-height: 1.2;
1408
+ margin: 0;
1409
+ padding: 0;
1410
+ text-decoration: underline;
1411
+ font-weight: 400;
1412
+ }
1413
+
1414
+ .sbi-critical-notice p a:hover {
1415
+ color: #666;
1416
+ }
1417
+
1418
+ .sbi-critical-notice-icon img {
1419
+ height: auto;
1420
+ display: block;
1421
+ margin: 0;
1422
+ }
1423
+
1424
+ .sbi-critical-notice-icon {
1425
+ padding: 0;
1426
+ border-radius: 4px;
1427
+ flex-grow: 0;
1428
+ flex-shrink: 0;
1429
+ margin-right: 12px;
1430
+ overflow: hidden;
1431
+ }
1432
+
1433
+ .sbi-critical-notice-close {
1434
+ padding: 10px;
1435
+ margin: -12px -9px 0 0;
1436
+ border: none;
1437
+ box-shadow: none;
1438
+ border-radius: 0;
1439
+ color: #7f7f7f;
1440
+ background: transparent;
1441
+ line-height: 1;
1442
+ align-self: flex-start;
1443
+ cursor: pointer;
1444
+ font-weight: 400;
1445
+ }
1446
+ .sbi-critical-notice-close:hover,
1447
+ .sbi-critical-notice-close:focus{
1448
+ color: #111;
1449
+ }
1450
+
1451
+ .sbi-critical-notice.sbi-critical-notice-hide {
1452
+ bottom: -200px;
1453
+ }
1454
+ </style>
1455
  <?php
1456
 
1457
  if ( ! wp_script_is( 'jquery', 'queue' ) ) {
1458
  wp_enqueue_script( 'jquery' );
1459
  }
1460
  ?>
1461
+ <script>
1462
+ if ( 'undefined' !== typeof jQuery ) {
1463
+ jQuery( document ).ready( function ( $ ) {
1464
+ /* Don't show the notice if we don't have a way to hide it (no js, no jQuery). */
1465
+ $( document.querySelector( '.sbi-critical-notice' ) ).removeClass( 'sbi-critical-notice-hide' );
1466
+ $( document.querySelector( '.sbi-critical-notice-close' ) ).on( 'click', function ( e ) {
1467
+ e.preventDefault();
1468
+ $( this ).closest( '.sbi-critical-notice' ).addClass( 'sbi-critical-notice-hide' );
1469
+ $.ajax( {
1470
+ url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
1471
+ method: 'POST',
1472
+ data: {
1473
+ action: 'sbi_dismiss_critical_notice',
1474
+ nonce: '<?php echo esc_js( wp_create_nonce( 'sbi-critical-notice' ) ); ?>',
1475
+ }
1476
+ } );
1477
+ } );
1478
+ } );
1479
+ }
1480
+ </script>
1481
  <?php
1482
  }
1483
 
1501
  function sbi_schedule_report_email() {
1502
  $options = get_option( 'sb_instagram_settings', array() );
1503
 
1504
+ $input = isset( $options['email_notification'] ) ? $options['email_notification'] : 'monday';
1505
  $timestamp = strtotime( 'next ' . $input );
1506
+ $timestamp = $timestamp + ( 3600 * 24 * 7 );
1507
 
1508
+ $six_am_local = $timestamp + sbi_get_utc_offset() + ( 6 * 60 * 60 );
1509
 
1510
  wp_schedule_event( $six_am_local, 'sbiweekly', 'sb_instagram_feed_issue_email' );
1511
  }
1512
 
1513
  function sbi_send_report_email() {
1514
+ $options = get_option( 'sb_instagram_settings' );
1515
 
1516
  $to_string = ! empty( $options['email_notification_addresses'] ) ? str_replace( ' ', '', $options['email_notification_addresses'] ) : get_option( 'admin_email', '' );
1517
 
1518
  $to_array_raw = explode( ',', $to_string );
1519
+ $to_array = array();
1520
 
1521
  foreach ( $to_array_raw as $email ) {
1522
  if ( is_email( $email ) ) {
1527
  if ( empty( $to_array ) ) {
1528
  return false;
1529
  }
1530
+ $from_name = esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) );
1531
+ $email_from = $from_name . ' <' . get_option( 'admin_email', $to_array[0] ) . '>';
1532
+ $header_from = 'From: ' . $email_from;
1533
 
1534
  $headers = array( 'Content-Type: text/html; charset=utf-8', $header_from );
1535
 
1536
  $header_image = SBI_PLUGIN_URL . 'img/balloon-120.png';
1537
 
1538
+ $link = admin_url( '?page=sb-instagram-feed' );
1539
  //&tab=customize-advanced
1540
+ $footer_link = admin_url( 'admin.php?page=sb-instagram-feed&tab=customize-advanced&flag=emails' );
1541
 
1542
  $is_expiration_notice = false;
1543
 
1544
  if ( isset( $options['connected_accounts'] ) ) {
1545
  foreach ( $options['connected_accounts'] as $account ) {
1546
  if ( $account['type'] === 'basic'
1547
+ && isset( $account['private'] )
1548
+ && sbi_private_account_near_expiration( $account ) ) {
1549
  $is_expiration_notice = true;
1550
  }
1551
  }
1552
  }
1553
 
1554
  if ( ! $is_expiration_notice ) {
1555
+ $title = sprintf( __( 'Instagram Feed Report for %s', 'instagram-feed' ), str_replace( array( 'http://', 'https://' ), '', home_url() ) );
1556
+ $bold = __( 'There\'s an Issue with an Instagram Feed on Your Website', 'instagram-feed' );
1557
+ $details = '<p>' . __( 'An Instagram feed on your website is currently unable to connect to Instagram to retrieve new posts. Don\'t worry, your feed is still being displayed using a cached version, but is no longer able to display new posts.', 'instagram-feed' ) . '</p>';
1558
+ $details .= '<p>' . sprintf( __( 'This is caused by an issue with your Instagram account connecting to the Instagram API. For information on the exact issue and directions on how to resolve it, please visit the %1$sInstagram Feed settings page%2$s on your website.', 'instagram-feed' ), '<a href="' . esc_url( $link ) . '">', '</a>' ) . '</p>';
1559
  } else {
1560
+ $title = __( 'Your Private Instagram Feed Account Needs to be Reauthenticated', 'instagram-feed' );
1561
+ $bold = __( 'Access Token Refresh Needed', 'instagram-feed' );
1562
+ $details = '<p>' . __( 'As your Instagram account is set to be "Private", Instagram requires that you reauthenticate your account every 60 days. This a courtesy email to let you know that you need to take action to allow the Instagram feed on your website to continue updating. If you don\'t refresh your account, then a backup cache will be displayed instead.', 'instagram-feed' ) . '</p>';
1563
+ $details .= '<p>' . sprintf( __( 'To prevent your account expiring every 60 days %1$sswitch your account to be public%2$s. For more information and to refresh your account, click here to visit the %3$sInstagram Feed settings page%4$s on your website.', 'instagram-feed' ), '<a href="https://help.instagram.com/116024195217477/In">', '</a>', '<a href="' . esc_url( $link ) . '">', '</a>' ) . '</p>';
1564
  }
1565
  $message_content = '<h6 style="padding:0;word-wrap:normal;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;font-weight:bold;line-height:130%;font-size: 16px;color:#444444;text-align:inherit;margin:0 0 20px 0;Margin:0 0 20px 0;">' . $bold . '</h6>' . $details;
1566
  include_once SBI_PLUGIN_DIR . 'inc/class-sb-instagram-education.php';
1567
+ $educator = new SB_Instagram_Education();
1568
  $dyk_message = $educator->dyk_display();
1569
  ob_start();
1570
  include SBI_PLUGIN_DIR . 'inc/email.php';
1581
  if ( ! $sb_instagram_posts_manager->are_critical_errors() ) {
1582
  return;
1583
  }
1584
+ $options = get_option( 'sb_instagram_settings' );
1585
 
1586
  if ( isset( $options['enable_email_report'] ) && empty( $options['enable_email_report'] ) ) {
1587
  return;
1601
 
1602
  function sbi_is_pro_version() {
1603
  return defined( 'SBI_STORE_URL' );
1604
+ }
instagram-feed.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Smash Balloon Instagram Feed
4
  Plugin URI: https://smashballoon.com/instagram-feed
5
  Description: Display beautifully clean, customizable, and responsive Instagram feeds.
6
- Version: 2.9.6
7
  Author: Smash Balloon
8
  Author URI: https://smashballoon.com/
9
  License: GPLv2 or later
@@ -23,7 +23,7 @@ along with this program; if not, write to the Free Software
23
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
  */
25
  if ( ! defined( 'SBIVER' ) ) {
26
- define( 'SBIVER', '2.9.6' );
27
  }
28
  // Db version.
29
  if ( ! defined( 'SBI_DBVERSION' ) ) {
@@ -52,9 +52,11 @@ if ( ! defined( 'SBI_MINIMUM_INTERVAL' ) ) {
52
  define( 'SBI_MINIMUM_INTERVAL', 600 );
53
  }
54
 
55
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
 
56
  if ( function_exists( 'sb_instagram_feed_init' ) ) {
57
- wp_die( "Please deactivate Custom Feeds for Instagram Pro before activating this version.<br /><br />Back to the WordPress <a href='".get_admin_url(null, 'plugins.php')."'>Plugins page</a>." );
58
  } else {
59
  /**
60
  * Define constants and load plugin files
@@ -367,7 +369,7 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
367
  $charset_collate = $wpdb->get_charset_collate();
368
  $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE );
369
 
370
- if ( $wpdb->get_var( "show tables like '$table_name'" ) != $table_name ) {
371
  $sql = "CREATE TABLE " . $table_name . " (
372
  id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
373
  created_on DATETIME,
@@ -603,8 +605,6 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
603
  update_option( 'sbi_db_version', SBI_DBVERSION );
604
  }
605
 
606
- //$manager = new SB_Instagram_Data_Manager();
607
- //$manager->reset(); die();
608
  if ( (float) $db_ver < 1.91 ) {
609
  $manager = new SB_Instagram_Data_Manager();
610
  $manager->update_db_for_dpa();
@@ -763,7 +763,7 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
763
  *
764
  * @since 2.0
765
  */
766
- function sbi_on_create_blog( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
767
  if ( is_plugin_active_for_network( 'instagram-feed/instagram-feed.php' ) ) {
768
  switch_to_blog( $blog_id );
769
  sbi_create_database_table();
3
  Plugin Name: Smash Balloon Instagram Feed
4
  Plugin URI: https://smashballoon.com/instagram-feed
5
  Description: Display beautifully clean, customizable, and responsive Instagram feeds.
6
+ Version: 2.9.7
7
  Author: Smash Balloon
8
  Author URI: https://smashballoon.com/
9
  License: GPLv2 or later
23
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
  */
25
  if ( ! defined( 'SBIVER' ) ) {
26
+ define( 'SBIVER', '2.9.7' );
27
  }
28
  // Db version.
29
  if ( ! defined( 'SBI_DBVERSION' ) ) {
52
  define( 'SBI_MINIMUM_INTERVAL', 600 );
53
  }
54
 
55
+ if ( ! defined( 'ABSPATH' ) ){
56
+ exit;
57
+ } // Exit if accessed directly
58
  if ( function_exists( 'sb_instagram_feed_init' ) ) {
59
+ wp_die( "Please deactivate Custom Feeds for Instagram Pro before activating this version.<br /><br />Back to the WordPress <a href='".esc_url( get_admin_url(null, 'plugins.php') )."'>Plugins page</a>." );
60
  } else {
61
  /**
62
  * Define constants and load plugin files
369
  $charset_collate = $wpdb->get_charset_collate();
370
  $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE );
371
 
372
+ if ( $wpdb->get_var( "show tables like '$table_name'" ) !== $table_name ) {
373
  $sql = "CREATE TABLE " . $table_name . " (
374
  id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
375
  created_on DATETIME,
605
  update_option( 'sbi_db_version', SBI_DBVERSION );
606
  }
607
 
 
 
608
  if ( (float) $db_ver < 1.91 ) {
609
  $manager = new SB_Instagram_Data_Manager();
610
  $manager->update_db_for_dpa();
763
  *
764
  * @since 2.0
765
  */
766
+ function sbi_on_create_blog( $blog_id ) {
767
  if ( is_plugin_active_for_network( 'instagram-feed/instagram-feed.php' ) ) {
768
  switch_to_blog( $blog_id );
769
  sbi_create_database_table();
js/sb-blocks.js CHANGED
@@ -58,7 +58,6 @@
58
  })
59
  }
60
  function afterRender() {
61
- var executed = false;
62
  // no way to run a script after AJAX call to get feed so we just try to execute it on a few intervals
63
  setTimeout(function() { if (typeof sbi_init !== 'undefined') {sbi_init();}},1000);
64
  setTimeout(function() { if (typeof sbi_init !== 'undefined') {sbi_init();}},2000);
58
  })
59
  }
60
  function afterRender() {
 
61
  // no way to run a script after AJAX call to get feed so we just try to execute it on a few intervals
62
  setTimeout(function() { if (typeof sbi_init !== 'undefined') {sbi_init();}},1000);
63
  setTimeout(function() { if (typeof sbi_init !== 'undefined') {sbi_init();}},2000);
js/sb-instagram-2-2.js CHANGED
@@ -132,9 +132,7 @@ if(!sbi_js_exists) {
132
  function sbiAddVisibilityListener() {
133
  /* Detect when element becomes visible. Used for when the feed is initially hidden, in a tab for example. https://github.com/shaunbowe/jquery.visibilityChanged */
134
  !function (i) {
135
- var n = {
136
- callback: function () {
137
- }, runOnLoad: !0, frequency: 100, sbiPreviousVisibility: null
138
  }, c = {};
139
  c.sbiCheckVisibility = function (i, n) {
140
  if (jQuery.contains(document, i[0])) {
@@ -297,12 +295,8 @@ if(!sbi_js_exists) {
297
  $(this.el).find('.sbi_item').each(function() {
298
  feed.lazyLoadCheck($(this));
299
  });
300
- },
301
- initLayout: function() {
302
-
303
  },
304
  afterInitialImagesLoaded: function() {
305
- this.initLayout();
306
  this.loadMoreButtonInit();
307
  this.hideExtraImagesForWidth();
308
  this.beforeNewImagesRevealed();
@@ -339,8 +333,7 @@ if(!sbi_js_exists) {
339
  this.setImageSizeClass();
340
  },
341
  revealNewImages: function() {
342
- var $self = $(this.el),
343
- feed = this;
344
 
345
  $self.find('.sbi-screenreader').each(function() {
346
  $(this).find('img').remove();
@@ -488,7 +481,7 @@ if(!sbi_js_exists) {
488
  locator_nonce: locatorNonce
489
  };
490
  var onSuccess = function(data) {
491
-
492
  };
493
  sbiAjax(submitData,onSuccess);
494
  }
@@ -553,8 +546,7 @@ if(!sbi_js_exists) {
553
  sbiAjax(submitData, onSuccess);
554
  },
555
  appendNewPosts: function (newPostsHtml) {
556
- var $self = $(this.el),
557
- feed = this;
558
  if ($self.find('#sbi_images .sbi_item').length) {
559
  $self.find('#sbi_images .sbi_item').last().after(newPostsHtml);
560
  } else {
@@ -577,8 +569,8 @@ if(!sbi_js_exists) {
577
  //Figure out what the width should be using the number of cols
578
  //Figure out what the width should be using the number of cols
579
  var imagesPadding = $self.find('#sbi_images').innerWidth() - $self.find('#sbi_images').width(),
580
- imagepadding = imagesPadding / 2;
581
- sbi_photo_width_manual = ( $self.find('#sbi_images').width() / sbi_num_cols ) - imagesPadding;
582
  //If the width is less than it should be then set it manually
583
  //if( sbi_photo_width <= (sbi_photo_width_manual) ) sbi_photo_width = sbi_photo_width_manual;
584
 
@@ -930,8 +922,7 @@ if(!sbi_js_exists) {
930
  }
931
  },
932
  applyImageLiquid: function () {
933
- var $self = $(this.el),
934
- feed = this;
935
  sbiAddImgLiquid();
936
  if (typeof $self.find(".sbi_photo").sbi_imgLiquid == 'function') {
937
  $self.find(".sbi_photo").sbi_imgLiquid({fill: true});
@@ -954,9 +945,8 @@ if(!sbi_js_exists) {
954
  var $self = $(this.el),
955
  cols = this.settings.cols,
956
  colsmobile = this.settings.colsmobile,
957
- returnCols = cols;
958
-
959
- sbiWindowWidth = window.innerWidth;
960
 
961
  if ($self.hasClass('sbi_mob_col_auto')) {
962
  if (sbiWindowWidth < 640 && (parseInt(cols) > 2 && parseInt(cols) < 7)) returnCols = 2;
132
  function sbiAddVisibilityListener() {
133
  /* Detect when element becomes visible. Used for when the feed is initially hidden, in a tab for example. https://github.com/shaunbowe/jquery.visibilityChanged */
134
  !function (i) {
135
+ var n = {runOnLoad: !0, frequency: 100, sbiPreviousVisibility: null
 
 
136
  }, c = {};
137
  c.sbiCheckVisibility = function (i, n) {
138
  if (jQuery.contains(document, i[0])) {
295
  $(this.el).find('.sbi_item').each(function() {
296
  feed.lazyLoadCheck($(this));
297
  });
 
 
 
298
  },
299
  afterInitialImagesLoaded: function() {
 
300
  this.loadMoreButtonInit();
301
  this.hideExtraImagesForWidth();
302
  this.beforeNewImagesRevealed();
333
  this.setImageSizeClass();
334
  },
335
  revealNewImages: function() {
336
+ var $self = $(this.el);
 
337
 
338
  $self.find('.sbi-screenreader').each(function() {
339
  $(this).find('img').remove();
481
  locator_nonce: locatorNonce
482
  };
483
  var onSuccess = function(data) {
484
+ console.log('done.');
485
  };
486
  sbiAjax(submitData,onSuccess);
487
  }
546
  sbiAjax(submitData, onSuccess);
547
  },
548
  appendNewPosts: function (newPostsHtml) {
549
+ var $self = $(this.el);
 
550
  if ($self.find('#sbi_images .sbi_item').length) {
551
  $self.find('#sbi_images .sbi_item').last().after(newPostsHtml);
552
  } else {
569
  //Figure out what the width should be using the number of cols
570
  //Figure out what the width should be using the number of cols
571
  var imagesPadding = $self.find('#sbi_images').innerWidth() - $self.find('#sbi_images').width(),
572
+ imagepadding = imagesPadding / 2,
573
+ sbi_photo_width_manual = ( $self.find('#sbi_images').width() / sbi_num_cols ) - imagesPadding;
574
  //If the width is less than it should be then set it manually
575
  //if( sbi_photo_width <= (sbi_photo_width_manual) ) sbi_photo_width = sbi_photo_width_manual;
576
 
922
  }
923
  },
924
  applyImageLiquid: function () {
925
+ var $self = $(this.el);
 
926
  sbiAddImgLiquid();
927
  if (typeof $self.find(".sbi_photo").sbi_imgLiquid == 'function') {
928
  $self.find(".sbi_photo").sbi_imgLiquid({fill: true});
945
  var $self = $(this.el),
946
  cols = this.settings.cols,
947
  colsmobile = this.settings.colsmobile,
948
+ returnCols = cols,
949
+ sbiWindowWidth = window.innerWidth;
 
950
 
951
  if ($self.hasClass('sbi_mob_col_auto')) {
952
  if (sbiWindowWidth < 640 && (parseInt(cols) > 2 && parseInt(cols) < 7)) returnCols = 2;
js/sb-instagram-admin-2-2.js CHANGED
@@ -1,1186 +1,1401 @@
1
- jQuery(document).ready(function($) {
 
2
 
3
  //Close the modal if clicking anywhere outside it
4
- jQuery('body').on('click', '.sb_cross_install_modal', function(e){
5
- if (e.target !== this) return;
6
- jQuery('.sb_cross_install_modal').remove();
7
- });
 
 
 
 
 
 
8
 
9
- jQuery('#sbi_no_js_warning').remove();
10
  /* NEW API CODE */
11
- $('.sbi_admin_btn, .sbi_reconnect').on('click',function(event) {
 
 
12
  event.preventDefault();
13
 
14
- var today = new Date(),
15
- march = new Date('June 1, 2020 00:00:00'),
16
- oldApiURL = $(this).attr('data-old-api'),
17
- oldApiLink = '';
18
  if (today.getTime() < march.getTime()) {
19
- oldApiLink = 'To connect using the legacy API, <a href="'+oldApiURL+'">click here</a> (expires on June 1, 2020).';
20
  }
21
 
22
- var personalBasicApiURL = $('#sbi_config .sbi_admin_btn').attr('data-personal-basic-api'),
23
- newApiURL = $('#sbi_config .sbi_admin_btn').attr('data-new-api');
24
 
25
  var modalHTML = '<div class="sbi-source-popup sbi-popup-inside sbi_config_modal"><div class="sbi-source-redirect sbi-fs"><div class="sbi-source-redirect-ld sbi-fs"><div></div></div> <div class="sbi-source-redirect-info sbi-fs"><strong class="sbi-fs">Redirecting to connect.smashballoon.com</strong> <p class="sbi-fs">You will be redirected to our app so you can connect your account in 5 seconds</p></div></div></div>';
26
- $('#sbi_config').append('<div id="sbi_config_info" class="sb_get_token">' +
27
- modalHTML +
28
- '</div>');
29
-
30
- setTimeout(function() {
 
 
 
31
  window.location.href = newApiURL;
32
- },3000);
33
- });
34
-
35
- if ($('.sbi_config_modal .sbi-managed-pages').length) {
36
- $('#sbi_config').append($('#sbi_config_info'));
 
 
 
37
  }
38
 
39
- $('#sbi-select-all').on('change',function() {
40
- var status = $(this).is(':checked');
41
- $('.sbi-add-checkbox input').each(function() {
42
- $(this).prop('checked',status);
43
- });
44
- if($('.sbi-add-checkbox input:checked').length) {
45
- $('#sbi-connect-business-accounts').prop('disabled',false);
 
 
 
 
46
  } else {
47
- $('#sbi-connect-business-accounts').prop('disabled',true);
48
  }
49
- });
50
-
51
- $('.sbi-add-checkbox input').on('change',function() {
52
- if($('.sbi-add-checkbox input:checked').length) {
53
- $('#sbi-connect-business-accounts').prop('disabled',false);
 
 
 
54
  } else {
55
- $('#sbi-connect-business-accounts').prop('disabled',true);
56
  }
57
- });
 
58
 
59
- $('#sbi-connect-business-accounts').on('click',function(event) {
 
 
60
  event.preventDefault();
61
  var accounts = {};
62
- $('.sbi-add-checkbox input').each(function(index) {
63
- if ($(this).is(':checked')) {
64
- var jsonSubmit = JSON.parse($(this).val());
65
- jsonSubmit.access_token = $(this).closest('.sbi-managed-page').attr('data-token');
66
- jsonSubmit.page_access_token = $(this).closest('.sbi-managed-page').attr('data-page-token');
67
- accounts[index] = jsonSubmit;
 
68
  }
69
- });
 
70
 
71
- $('.sbi_connected_accounts_wrap,#sbi_config_info').fadeTo("slow" , 0.5);
72
- jQuery.ajax({
 
73
  url: sbiA.ajax_url,
74
  type: 'post',
75
  data: {
76
- action: 'sbi_connect_business_accounts',
77
- accounts: JSON.stringify(accounts),
78
- sbi_nonce: sbiA.sbi_nonce
79
  },
80
  success: function (data) {
81
- if (data.trim().indexOf('{') === 0) {
82
- var connectedAccounts = JSON.parse(data);
83
- $('.sbi_connected_accounts_wrap').fadeTo("slow" , 1);
84
- $('#sbi_config_info').remove();
85
- $.each(connectedAccounts,function(index,savedToken) {
86
- console.log(savedToken);
87
- sbiAfterUpdateToken(savedToken,false);
88
-
89
- });
90
- }
91
 
 
 
92
  }
93
- });
 
94
 
95
- });
 
96
 
97
- $('.sbi_modal_close').on('click', function(){
98
- if (jQuery('.sbi-need-to-connect').length) {
99
- $('#sbi_config_info').hide();
 
 
100
  } else {
101
- $('#sbi_config_info').remove();
102
  }
103
- });
 
104
  /* NEW API CODE */
105
  //Autofill the token and id
106
  var hash = window.location.hash,
107
- token = hash.substring(14),
108
- id = token.split('.')[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- if (token.length > 40 && $('.sbi_admin_btn').length) {
111
- $('.sbi_admin_btn').css('opacity','.5').after('<div class="spinner" style="visibility: visible; position: relative;float: left;margin-top: 15px;"></div>');
112
- jQuery.ajax({
113
- url: sbiA.ajax_url,
114
- type: 'post',
115
- data: {
116
- action: 'sbi_after_connection',
117
- access_token: token,
118
- },
119
- success: function (data) {
120
- if (data.indexOf('{') === 0) {
121
- var accountInfo = JSON.parse(data);
122
- if (typeof accountInfo.error_message === 'undefined') {
123
- accountInfo.token = token;
124
-
125
- $('.sbi_admin_btn').css('opacity','1');
126
- $('#sbi_config').find('.spinner').remove();
127
- if (!$('.sbi_connected_account ').length) {
128
- $('.sbi_no_accounts').remove();
129
- sbSaveToken(token,true);
130
- } else {
131
- var buttonText = 'Connect This Account';
132
- // if the account is connected, offer to update in case information has changed.
133
- if ($('#sbi_connected_account_'+id).length) {
134
- buttonText = 'Update This Account';
135
- }
136
- $('#sbi_config').append('<div id="sbi_config_info" class="sb_get_token">' +
137
- '<div class="sbi_config_modal">' +
138
- '<img class="sbi_ca_avatar" src="'+accountInfo.profile_picture+'" />' +
139
- '<div class="sbi_ca_username"><strong>'+accountInfo.username+'</strong></div>' +
140
- '<p class="sbi_submit"><input type="submit" name="sbi_submit" id="sbi_connect_account" class="button button-primary" value="'+buttonText+'">' +
141
- '<a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts">Switch Accounts</a></p>' +
142
- '<a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>' +
143
- '</div>' +
144
- '</div>');
145
-
146
- $('#sbi_connect_account').on('click',function(event) {
147
- event.preventDefault();
148
- $('#sbi_config_info').fadeOut(200);
149
- sbSaveToken(token,false);
150
- });
151
-
152
- sbiSwitchAccounts();
153
- }
154
- } else {
155
- $('.sbi_admin_btn').css('opacity','1');
156
- $('#sbi_config').find('.spinner').remove();
157
- var message = accountInfo.error_message;
158
-
159
- $('#sbi_config').append('<div id="sbi_config_info" class="sb_get_token">' +
160
- '<div class="sbi_config_modal">' +
161
- '<p>'+message+'</p>' +
162
- '<p class="sbi_submit"><a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts">Switch Accounts</a></p>' +
163
- '<a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>' +
164
- '</div>' +
165
- '</div>');
166
-
167
- sbiSwitchAccounts();
168
- }
169
 
170
- } else {
171
- $('.sbi_admin_btn').css('opacity','1');
172
- $('#sbi_config').find('.spinner').remove();
173
- var message = 'There was an error connecting your account';
174
-
175
- $('#sbi_config').append('<div id="sbi_config_info" class="sb_get_token">' +
176
- '<div class="sbi_config_modal">' +
177
- '<p>'+message+'</p>' +
178
- '<p class="sbi_submit"><a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts">Switch Accounts</a></p>' +
179
- '<a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>' +
180
- '</div>' +
181
- '</div>');
182
-
183
- sbiSwitchAccounts();
184
- }
 
185
 
 
186
  }
187
- });
 
 
188
 
189
- window.location.hash = '';
190
  }
191
  function sbiSwitchAccounts(){
192
- $('#sbi_switch_accounts').on('click', function(){
193
- //Log user out of Instagram by hitting the logout URL in an iframe
194
- $('body').append('<iframe style="display: none;" src="https://www.instagram.com/accounts/logout"></iframe>');
195
-
196
- $(this).text('Please wait...').after('<div class="spinner" style="visibility: visible; float: none; margin: -3px 0 0 3px;"></div>');
197
-
198
- //Wait a couple seconds for the logout to occur, then connect a new account
199
- setTimeout(function(){
200
- window.location.href = $('.sbi_admin_btn').attr('href');
201
- }, 2000);
202
- });
 
 
 
 
 
 
203
 
204
- $('.sbi_modal_close').on('click', function(){
205
- $('#sbi_config_info').remove();
206
- });
 
 
 
207
  }
208
- if ($('#sbi_switch_accounts').length) {
209
- $('.sbi_admin_btn').attr('href',$('#sbi_config .sbi_admin_btn').attr('data-personal-basic-api'));
210
- sbiSwitchAccounts();
211
  }
212
 
213
  function sbiAfterUpdateToken(savedToken,saveID){
214
- $('.sbi_no_accounts').remove();
215
- if (saveID) {
216
- sbSaveID(savedToken.user_id);
217
- $('.sbi_user_feed_ids_wrap').prepend(
218
- '<div id="sbi_user_feed_id_'+savedToken.user_id+'" class="sbi_user_feed_account_wrap">'+
219
- '<strong>'+savedToken.username+'</strong> <span>('+savedToken.user_id+')</span>' +
220
- '<input type="hidden" name="sb_instagram_user_id[]" value="'+savedToken.user_id+'">' +
221
- '</div>'
222
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
- if (typeof savedToken.old_user_id !== 'undefined' && $('#sbi_connected_account_'+savedToken.old_user_id).length) {
225
-
226
- if ($('#sbi_user_feed_id_'+savedToken.old_user_id).length) {
227
- $('.sbi_user_feed_ids_wrap').prepend(
228
- '<div id="sbi_user_feed_id_'+savedToken.user_id+'" class="sbi_user_feed_account_wrap">'+
229
- '<strong>'+savedToken.username+'</strong> <span>('+savedToken.user_id+')</span>' +
230
- '<input type="hidden" name="sb_instagram_user_id[]" value="'+savedToken.user_id+'">' +
231
- '</div>'
232
- );
233
- $('#sbi_user_feed_id_'+savedToken.old_user_id).remove();
234
 
235
- saveID = true;
236
- }
237
-
238
- $('#sbi_connected_account_'+savedToken.old_user_id).remove();
 
 
 
 
 
 
 
 
239
  }
240
- if ($('#sbi_connected_account_'+savedToken.user_id).length) {
241
- if (savedToken.is_valid) {
242
- $('#sbi_connected_account_'+savedToken.user_id).addClass('sbi_account_updated');
243
- } else {
244
- $('#sbi_connected_account_'+savedToken.user_id).addClass('sbi_account_invalid');
245
- }
246
- $('#sbi_connected_account_'+savedToken.user_id).attr('data-accesstoken',savedToken.access_token);
247
- if (typeof savedToken.use_tagged !== 'undefined' && savedToken.use_tagged == '1') {
248
- $('#sbi_connected_account_'+savedToken.user_id).attr('data-permissions','tagged');
249
- $('#sbi_connected_account_'+savedToken.user_id).find('.sbi_permissions_desc').text('All');
250
- }
251
 
252
- if (! $('#sbi_connected_account_'+savedToken.user_id + ' .sbi_ca_avatar').length) {
253
- if (savedToken.profile_picture !== '') {
254
- $('#sbi_connected_account_'+savedToken.user_id + ' .sbi_ca_username').prepend('<img class="sbi_ca_avatar" src="'+savedToken.profile_picture+'">');
255
- }
256
- }
257
- $('#sbi_connected_account_'+savedToken.user_id + ' .sbi_ca_username').find('span').text(sbiAccountType(savedToken.type,false));
258
 
259
- $('#sbi_connected_account_'+savedToken.user_id).find('.sbi_ca_accesstoken .sbi_ca_token').text(savedToken.access_token);
260
- $('#sbi_connected_account_'+savedToken.user_id).find('.sbi_tooltip code').text('[instagram-feed accesstoken="'+savedToken.access_token+'"]');
261
 
 
 
 
 
 
262
  } else {
263
- //Check which kind of account it is
264
- if(typeof savedToken.type !== 'undefined'){
265
- var accountType = savedToken.type;
266
- $('.sbi_hashtag_feed_issue').removeClass('sbi_hashtag_feed_issue').find('.sbi_hashtag_feed_issue_note').hide();
267
- } else {
268
- var accountType = 'personal';
269
- }
270
- var isPrivate = (typeof savedToken.private !== 'undefined');
271
 
272
- var avatarHTML = '';
273
- if (savedToken.profile_picture !== '') {
274
- avatarHTML = '<img class="sbi_ca_avatar" src="'+savedToken.profile_picture+'" />';
275
- }
276
 
277
- //Add the account HTML to the page
278
- var removeOrSaveHTML = saveID ? '<a href="JavaScript:void(0);" class="sbi_remove_from_user_feed button-primary"><i class="fa fa-minus-circle" aria-hidden="true"></i>Remove from Primary Feed</a>' : '<a href="JavaScript:void(0);" class="sbi_use_in_user_feed button-primary"><i class="fa fa-plus-circle" aria-hidden="true"></i>Add to Primary Feed</a>',
279
- statusClass = saveID ? 'sbi_account_active' : 'sbi_account_updated',
280
- html = '<div class="sbi_connected_account '+statusClass+' sbi-init-click-remove" id="sbi_connected_account_'+savedToken.user_id+'" data-accesstoken="'+savedToken.access_token+'" data-userid="'+savedToken.user_id+'" data-username="'+savedToken.username+'">'+
281
- '<div class="sbi_ca_info">'+
282
-
283
- '<div class="sbi_ca_delete">'+
284
- '<a href="JavaScript:void(0);" class="sbi_delete_account"><i class="fa fa-times"></i><span class="sbi_remove_text">Remove</span></a>'+
285
- '</div>'+
286
-
287
- '<div class="sbi_ca_username">'+
288
- avatarHTML+
289
- '<strong>'+savedToken.username+'<span>'+sbiAccountType(accountType,isPrivate)+'</span></strong>'+
290
- '</div>'+
291
-
292
- '<div class="sbi_ca_actions">'+
293
- removeOrSaveHTML +
294
- '<a class="sbi_ca_token_shortcode button-secondary" href="JavaScript:void(0);"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>Add to another Feed</a>'+
295
- '<a class="sbi_ca_show_token button-secondary" href="JavaScript:void(0);" title="Show access token and account info"><i class="fa fa-cog"></i></a>'+
296
- '</div>'+
297
-
298
- '<div class="sbi_ca_shortcode">'+
299
- '<p>Copy and paste this shortcode into your page or widget area:<br>'+
300
- '<code>[instagram-feed user="'+savedToken.username+'"]</code>'+
301
- '</p>'+
302
- '<p>To add multiple users in the same feed, simply separate them using commas:<br>'+
303
- '<code>[instagram-feed user="'+savedToken.username+', a_second_user, a_third_user"]</code>'+
304
- '<p>Click on the <a href="?page=sb-instagram-feed&tab=display" target="_blank">Display Your Feed</a> tab to learn more about shortcodes</p>'+
305
- '</div>'+
306
-
307
- '<div class="sbi_ca_accesstoken">' +
308
- '<span class="sbi_ca_token_label">User ID:</span><input type="text" class="sbi_ca_user_id" value="'+savedToken.user_id+'" readonly="readonly" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac)."><br>' +
309
- '<span class="sbi_ca_token_label">Permissions:</span><span class="sbi_permissions_desc">All</span>' +
310
- '</div>' +
311
-
312
- '</div>'+
313
- '</div>';
314
- $('.sbi_connected_accounts_wrap').prepend(html);
315
- var $clickRemove = $('.sbi-init-click-remove');
316
- sbiInitClickRemove($clickRemove.find('.sbi_delete_account'));
317
- if ($clickRemove.find('.sbi_remove_from_user_feed').length ) {
318
- $clickRemove.find('.sbi_remove_from_user_feed').off();
319
- sbiInitUserRemove($clickRemove.find('.sbi_remove_from_user_feed'));
320
- } else {
321
- $clickRemove.find('.sbi_use_in_user_feed').off();
322
- sbiInitUserAdd($clickRemove.find('.sbi_use_in_user_feed'));
323
- }
324
- $clickRemove.removeClass('sbi-init-click-remove');
325
  }
 
 
326
  }
327
 
328
  function sbSaveToken(token,saveID) {
329
- $('.sbi_connected_accounts_wrap').fadeTo("slow" , 0.5);
330
- jQuery.ajax({
331
- url: sbiA.ajax_url,
332
- type: 'post',
333
- data: {
334
- action: 'sbi_auto_save_tokens',
335
- access_token: token,
336
- just_tokens: true,
337
- sbi_nonce: sbiA.sbi_nonce
338
- },
339
- success: function (data) {
340
- var savedToken = JSON.parse(data);
341
- $('.sbi_connected_accounts_wrap').fadeTo("slow" , 1);
342
- sbiAfterUpdateToken(savedToken,saveID);
343
- }
344
- });
 
 
345
  }
346
 
347
  function sbiAccountType(accountType,isPrivate) {
348
- if (accountType === 'basic') {
349
- var returnText = 'personal';
350
- if (isPrivate) {
351
- returnText += ' (private)'
352
- }
353
- return returnText;
354
  }
355
- return accountType;
 
 
356
  }
357
 
358
  function sbSaveID(ID) {
359
- jQuery.ajax({
360
- url: sbiA.ajax_url,
361
- type: 'post',
362
- data: {
363
- action: 'sbi_auto_save_id',
364
- id: ID,
365
- just_tokens: true,
366
- sbi_nonce: sbiA.sbi_nonce
367
- },
368
- success: function (data) {
369
- }
370
- });
 
 
371
  }
372
 
373
  // connect accounts
374
  //sbi-bus-account-error
375
  if (window.location.hash && window.location.hash === '#test') {
376
- window.location.hash = '';
377
- $('#sbi-bus-account-error').html('<p style="margin-top: 5px;"><strong style="font-size: 16px">Couldn\'t connect an account with this access token</strong><br />' +
378
- 'Please check to make sure that the token you entered is correct.</p>')
 
 
379
  }
380
 
381
- $('.sbi_manually_connect_wrap').hide();
382
- $('.sbi_manually_connect').on('click',function(event) {
 
 
383
  event.preventDefault();
384
- if ( $('.sbi_manually_connect_wrap').is(':visible') ) {
385
- $('.sbi_manually_connect_wrap').slideUp(200);
386
  } else {
387
- $('.sbi_manually_connect_wrap').slideDown(200);
388
- $('#sb_manual_at').focus();
389
  }
390
- });
 
391
 
392
- $('#sb_manual_at').on('input',function() {
393
- sbiToggleManualAccountIDInput();
394
- });
395
- if ($('#sb_manual_at').length){
396
  sbiToggleManualAccountIDInput();
 
 
 
 
397
  }
398
 
399
  function sbiIsBusinessToken() {
400
- return ($('#sb_manual_at').val().trim().length > 125);
401
  }
402
 
403
  function sbiToggleManualAccountIDInput() {
404
- if (sbiIsBusinessToken()) {
405
- $('.sbi_manual_account_id_toggle').slideDown();
406
- $('.sbi_business_profile_tag').css('display', 'inline-block');
407
- } else {
408
- $('.sbi_manual_account_id_toggle').slideUp();
409
- }
410
  }
411
 
412
- var $body = $('body');
413
- $body.on('click', '.sbi_test_token, .sbi_ca_token_shortcode', function (event) {
 
 
 
414
  event.preventDefault();
415
- var $clicked = $(event.target),
416
- accessToken = $clicked.closest('.sbi_connected_account').attr('data-accesstoken'),
417
- action = false,
418
- atParts = accessToken.split('.'),
419
- username = $clicked.closest('.sbi_connected_account').attr('data-username'),
420
- accountID = $clicked.closest('.sbi_connected_account').attr('data-userid');
421
- if ($clicked.hasClass('sbi_ca_token_shortcode')) {
422
- jQuery(this).closest('.sbi_ca_info').find('.sbi_ca_shortcode').slideToggle(200);
423
  } //
424
 
425
- });
 
426
 
427
- $('.sbi_delete_account').each(function() {
428
- sbiInitClickRemove($(this));
429
- });
 
 
430
 
431
  function sbiInitClickRemove(el) {
432
- el.on('click',function(event) {
433
- event.preventDefault();
434
- if (!$(this).closest('.sbi_connected_accounts_wrap').hasClass('sbi-waiting')) {
435
- $(this).closest('.sbi_connected_accounts_wrap').addClass('sbi-waiting');
436
- var accessToken = $(this).closest('.sbi_connected_account').attr('data-accesstoken'),
437
- action = false,
438
- atParts = accessToken.split('.'),
439
- username = $(this).closest('.sbi_connected_account').attr('data-username'),
440
- accountID = $(this).closest('.sbi_connected_account').attr('data-userid');
441
-
442
- if (window.confirm("Delete this connected account?")) {
443
- action = 'sbi_delete_account';
444
- $('#sbi_user_feed_id_' + accountID).remove();
445
- $('#sbi_tagged_feed_id_' + accountID).remove();
446
- $('#sbi_connected_account_' + accountID).append('<div class="spinner" style="margin-top: -10px;visibility: visible;top: 50%;position: absolute;right: 50%;"></div>').find('.sbi_ca_info').css('opacity','.5');
447
-
448
- jQuery.ajax({
449
- url: sbiA.ajax_url,
450
- type: 'post',
451
- data: {
452
- action: action,
453
- account_id: accountID,
454
- sbi_nonce: sbiA.sbi_nonce
455
- },
456
- success: function (data) {
457
- $('.sbi-waiting').removeClass('sbi-waiting');
458
- $('#sbi_connected_account_' + accountID).fadeOut(300, function() { $(this).remove(); });
459
- }
460
- });
461
- } else {
462
- $('.sbi-waiting').removeClass('sbi-waiting');
463
  }
 
 
 
464
  }
 
465
 
466
- });
 
467
  }
468
 
469
- $('.sbi_remove_from_user_feed').each(function() {
470
- sbiInitUserRemove($(this));
471
- });
 
 
472
 
473
  function sbiInitUserRemove(el,targetClass) {
474
- el.on('click',function(event) {
475
- event.preventDefault();
476
- var targetClass = $('input[name=sb_instagram_type]:checked').val();
 
 
477
 
478
- var $clicked = $(this),
479
- accountID = $clicked.closest('.sbi_connected_account').attr('data-userid');
480
 
481
- $('#sbi_'+targetClass+'_feed_id_'+accountID).remove();
482
 
483
- sbiConAccountsAddRemoveUpdater();
484
- });
 
485
  }
486
 
487
-
488
-
489
- $('.sbi_use_in_user_feed').each(function() {
490
- sbiInitUserAdd($(this), 'user');
491
- });
492
 
493
  function sbiInitUserAdd(el,targetClass) {
494
- el.on('click',function(event) {
495
- var targetClass = $('input[name=sb_instagram_type]:checked').val();
496
- event.preventDefault();
497
- var $clicked = $(this),
498
- $closest = $clicked.closest('.sbi_connected_account'),
499
- username = $clicked.closest('.sbi_connected_account').attr('data-username'),
500
- accountID = $clicked.closest('.sbi_connected_account').attr('data-userid');
501
-
502
- var name = '<strong>'+accountID+'</strong>';
503
- if (username !== '') {
504
- name = '<strong>'+username+'</strong> <span>('+accountID+')</span>';
505
- }
506
- $('.sbi_'+targetClass+'_feed_ids_wrap').prepend(
507
- '<div id="sbi_'+targetClass+'_feed_id_'+accountID+'" class="sbi_'+targetClass+'_feed_account_wrap">'+
508
- name +
509
- '<input type="hidden" name="sb_instagram_'+targetClass+'_id[]" value="'+accountID+'">' +
510
- '</div>'
511
- );
512
- $('.sbi_no_accounts').hide();
513
- sbiConAccountsAddRemoveUpdater();
514
- });
 
 
 
515
  }
516
 
517
  function sbiConAccountsAddRemoveUpdater() {
518
- var targetClass = $('input[name=sb_instagram_type]:checked').val();
519
-
520
- var isSelected = [];
521
- $('.sbi_'+targetClass+'_feed_account_wrap').find('input').each(function() {
522
- isSelected.push($(this).val());
523
- });
524
-
525
- $('.sbi_connected_account').each(function() {
526
- var username = $(this).attr('data-username'),
527
- accountID = $(this).attr('data-userid'),
528
- type = $(this).attr('data-type'),
529
- permissions = $(this).attr('data-permissions'),
530
- $addRemoveButton = $(this).find('.sbi_ca_actions .button-primary').first();
531
- $(this).removeClass('sbi_account_updated');
532
- $addRemoveButton.prop('disabled',false);
533
-
534
- if (targetClass === 'tagged' && (type === 'personal' || permissions !== 'tagged')) {
535
- $addRemoveButton.show();
536
- if (type === 'personal') {
537
- $addRemoveButton.html('Tagged Feeds Not Supported');
538
- } else {
539
- $addRemoveButton.html('Reconnect Account');
540
- }
541
- $addRemoveButton.prop('disabled',true).addClass('sbi_remove_from_user_feed').removeClass('sbi_use_in_user_feed');
542
- $(this).removeClass('sbi_account_active');
543
- } else if (targetClass === 'hashtag') {
544
- $addRemoveButton.hide();
545
- $addRemoveButton.prop('disabled',true).addClass('sbi_remove_from_user_feed').removeClass('sbi_use_in_user_feed');
546
- $(this).removeClass('sbi_account_active');
547
  } else {
548
- $addRemoveButton.show();
549
- if (isSelected.indexOf(accountID) > -1) {
550
- $addRemoveButton.html('<i class="fa fa-minus-circle" aria-hidden="true" style="margin-right: 5px;"></i>Remove from Primary Feed');
551
- $addRemoveButton.addClass('sbi_remove_from_user_feed').removeClass('sbi_use_in_user_feed');
552
- $(this).addClass('sbi_account_active');
553
- } else {
554
- $addRemoveButton.html('<i class="fa fa-plus-circle" aria-hidden="true"></i>Add to Primary Feed');
555
- $addRemoveButton.removeClass('sbi_remove_from_user_feed');
556
- $addRemoveButton.addClass('sbi_use_in_user_feed');
557
- $(this).removeClass('sbi_account_active');
558
- }
559
  }
560
-
561
-
562
- if ($(this).find('.sbi_remove_from_user_feed').length ) {
563
- $(this).find('.sbi_remove_from_user_feed').off();
564
- sbiInitUserRemove($(this).find('.sbi_remove_from_user_feed'));
 
 
 
 
 
 
 
565
  } else {
566
- $(this).find('.sbi_use_in_user_feed').off();
567
- sbiInitUserAdd($(this).find('.sbi_use_in_user_feed'),'user');
 
 
568
  }
 
569
 
570
- });
571
- }sbiConAccountsAddRemoveUpdater();
572
-
573
- $('input[name=sb_instagram_type]').on('change',sbiConAccountsAddRemoveUpdater);
 
 
 
574
 
 
 
 
575
 
 
576
 
577
- $body.on('click', '.sbi_ca_show_token', function(event) {
578
- jQuery(this).closest('.sbi_ca_info').find('.sbi_ca_accesstoken').slideToggle(200);
579
- });
 
 
 
 
580
 
581
- $('#sbi_manual_submit').on('click',function(event) {
 
 
582
  event.preventDefault();
583
- var $self = $(this);
584
- var accessToken = $('#sb_manual_at').val(),
585
- error = false;
586
- if (sbiIsBusinessToken() && $('.sbi_manual_account_id_toggle').find('input').val().length < 3) {
587
- error = true;
588
- if (!$('.sbi_manually_connect_wrap').find('.sbi_user_id_error').length) {
589
- $('.sbi_manually_connect_wrap').show().prepend('<div class="sbi_user_id_error" style="display:block;">Please enter a valid User ID for this Business account.</div>');
590
- }
591
  } else {
592
- error = false;
593
  }
594
  if (accessToken.length < 15) {
595
- if (!$('.sbi_manually_connect_wrap').find('.sbi_user_id_error').length) {
596
- $('.sbi_manually_connect_wrap').show().prepend('<div class="sbi_user_id_error" style="display:block;">Please enter a valid access token</div>');
597
- }
598
- } else if (! error) {
599
- $(this).prop('disabled',true);
600
- $(this).closest('.sbi_manually_connect_wrap').fadeOut();
601
- $('.sbi_connected_accounts_wrap').fadeTo("slow" , 0.5).find('.sbi_user_id_error').remove();
602
-
603
- jQuery.ajax({
604
- url: sbiA.ajax_url,
605
- type: 'post',
606
- data: {
607
- action: 'sbi_test_token',
608
- access_token: accessToken,
609
- account_id : $('.sbi_manual_account_id_toggle').find('input').val().trim(),
610
- sbi_nonce: sbiA.sbi_nonce
611
- },
612
- success: function (data) {
613
- $('.sbi_connected_accounts_wrap').fadeTo("slow" , 1);
614
- $self.prop('disabled',false);
615
- if ( data.indexOf('{') > -1) {
616
- var savedToken = JSON.parse(data);
617
- if (typeof savedToken.url !== 'undefined') {
618
- window.location.href = savedToken.url;
619
- } else {
620
- $(this).closest('.sbi_manually_connect_wrap').fadeOut();
621
- $('#sb_manual_at, .sbi_manual_account_id_toggle input').val('');
622
- sbiAfterUpdateToken(savedToken,false);
623
- }
624
-
625
- } else {
626
- $('.sbi_manually_connect_wrap').show().prepend('<div class="sbi_user_id_error" style="display:block;">'+data+'</div>');
627
- }
628
-
629
  }
630
- });
 
 
 
631
  }
632
 
633
- });
 
634
 
635
- //sbi_reset_resized
636
- // clear resized
637
- var $sbiClearResizedButton = $('#sbi_reset_resized');
638
 
639
- $sbiClearResizedButton.on('click',function(event) {
 
 
640
  event.preventDefault();
641
 
642
- jQuery('#sbi-clear-cache-success').remove();
643
- jQuery(this).prop("disabled",true);
644
 
645
- $.ajax({
 
646
  url : sbiA.ajax_url,
647
  type : 'post',
648
  data : {
649
- action : 'sbi_reset_resized',
650
- sbi_nonce: sbiA.sbi_nonce
651
  },
652
  success : function(data) {
653
- $sbiClearResizedButton.prop('disabled',false);
654
- if(data=='1') {
655
- $sbiClearResizedButton.after('<i id="sbi-clear-cache-success" class="fa fa-check-circle sbi-success"></i>');
656
- } else {
657
- $sbiClearResizedButton.after('<span>error</span>');
658
- }
 
659
  }
660
- }); // ajax call
661
- }); // clear_comment_cache click
 
 
662
 
663
  //Caching options
664
- if( jQuery('#sbi_caching_type_page').is(':checked') ) {
665
- jQuery('.sbi-caching-cron-options').hide();
666
- jQuery('.sbi-caching-page-options').show();
667
  } else {
668
- jQuery('.sbi-caching-page-options').hide();
669
- jQuery('.sbi-caching-cron-options').show();
670
  }
671
 
672
- $('input[type=radio][name=sbi_caching_type]').on('change',function() {
 
 
673
  if (this.value == 'page') {
674
- jQuery('.sbi-caching-cron-options').slideUp();
675
- jQuery('.sbi-caching-page-options').slideDown();
 
 
 
676
  }
677
- else if (this.value == 'background') {
678
- jQuery('.sbi-caching-page-options').slideUp();
679
- jQuery('.sbi-caching-cron-options').slideDown();
680
- }
681
- });
682
 
683
  //Should we show the caching time settings?
684
- var sbi_cache_cron_interval = jQuery('#sbi_cache_cron_interval').val(),
685
- $sbi_caching_time_settings = jQuery('#sbi-caching-time-settings');
686
 
687
  //Should we show anything initially?
688
- if(sbi_cache_cron_interval == '30mins' || sbi_cache_cron_interval == '1hour') $sbi_caching_time_settings.hide();
 
 
689
 
690
- jQuery('#sbi_cache_cron_interval').on('change',function(){
691
- sbi_cache_cron_interval = jQuery('#sbi_cache_cron_interval').val();
 
 
692
 
693
- if(sbi_cache_cron_interval == '30mins' || sbi_cache_cron_interval == '1hour'){
694
- $sbi_caching_time_settings.hide();
695
  } else {
696
- $sbi_caching_time_settings.show();
697
  }
698
- });
699
- sbi_cache_cron_interval = jQuery('#sbi_cache_cron_interval').val();
 
700
 
701
- if(sbi_cache_cron_interval == '30mins' || sbi_cache_cron_interval == '1hour'){
702
- $sbi_caching_time_settings.hide();
703
  } else {
704
- $sbi_caching_time_settings.show();
705
  }
706
 
707
-
708
  //clear backup caches
709
- jQuery('#sbi_clear_backups').on('click',function(event) {
710
- jQuery('.sbi-success').remove();
 
 
711
  event.preventDefault();
712
- jQuery.ajax({
 
713
  url: sbiA.ajax_url,
714
  type: 'post',
715
  data: {
716
- action: 'sbi_clear_backups',
717
- access_token: token,
718
- sbi_nonce : sbiA.sbi_nonce,
719
- just_tokens: true
720
  },
721
  success: function (data) {
722
- jQuery('#sbi_clear_backups').after('<span class="sbi-success"><i class="fa fa-check-circle"></i></span>');
723
  }
724
- });
725
- });
 
 
726
 
727
  //sbi_reset_log
728
- var $sbiClearLog = $('#sbi_reset_log');
729
 
730
- $sbiClearLog.on('click',function(event) {
 
 
731
  event.preventDefault();
732
 
733
- jQuery('#sbi-clear-cache-success').remove();
734
- jQuery(this).prop("disabled",true);
735
 
736
- $.ajax({
 
737
  url : sbiA.ajax_url,
738
  type : 'post',
739
  data : {
740
- action : 'sbi_reset_log',
741
- sbi_nonce : sbiA.sbi_nonce,
742
  },
743
  success : function(data) {
744
- $sbiClearLog.prop('disabled',false);
745
- if(data=='1') {
746
- $sbiClearLog.after('<i id="sbi-clear-cache-success" class="fa fa-check-circle sbi-success"></i>');
747
- } else {
748
- $sbiClearLog.after('<span>error</span>');
749
- }
 
750
  }
751
- }); // ajax call
752
- }); // clear_comment_cache click
753
-
754
- $('.sb-opt-in').on('click',function(event) {
 
 
 
 
755
  event.preventDefault();
756
 
757
- var $btn = jQuery(this);
758
- $btn.prop( 'disabled', true ).addClass( 'loading' ).html('<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>');
759
 
760
- sbiSubmitOptIn(true);
761
- }); // clear_comment_cache click
 
762
 
763
- jQuery('#sbi-oembed-disable').on('click',function(e) {
 
 
764
  e.preventDefault();
765
- jQuery(this).addClass( 'loading' ).html('<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>');
766
- jQuery.ajax({
 
767
  url : sbiA.ajax_url,
768
  type: 'post',
769
  data: {
770
- action : 'sbi_oembed_disable',
771
- sbi_nonce : sbiA.sbi_nonce,
772
  },
773
  success: function (data) {
774
- jQuery('#sbi-oembed-disable').closest('p').html(data);
 
775
  }
776
- });
777
- });
778
-
779
- $('.sb-no-usage-opt-out').on('click',function(event) {
 
 
 
 
780
  event.preventDefault();
781
 
782
- var $btn = jQuery(this);
783
- $btn.prop( 'disabled', true ).addClass( 'loading' ).html('<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>');
784
 
785
- sbiSubmitOptIn(false);
786
- }); // clear_comment_cache click
 
787
 
788
  function sbiSubmitOptIn(choice) {
789
- $.ajax({
790
- url : sbiA.ajax_url,
791
- type : 'post',
792
- data : {
793
- action : 'sbi_usage_opt_in_or_out',
794
- opted_in: choice,
795
- sbi_nonce : sbiA.sbi_nonce,
796
- },
797
- success : function(data) {
798
- $('.sb-no-usage-opt-out').closest('.sbi-admin-notice').fadeOut();
799
- }
800
- }); // ajax call
 
 
801
  }
802
 
803
  //clear platform data
804
- jQuery('#sbi_clear_platform_data').on('click',function(event) {
805
- jQuery('.sbi-success').remove();
806
- var $self = jQuery(this);
 
 
807
  event.preventDefault();
808
- if (window.confirm("Warning: Clicking this button will permanently delete all Instagram data, including all connected accounts, cached posts, and stored images.")) {
809
- $self.prop('disabled',true);
810
- jQuery.ajax({
811
- url: sbiA.ajax_url,
812
- type: 'post',
813
- data: {
814
- action: 'sbi_delete_platform_data',
815
- sbi_nonce: sbiA.sbi_nonce
816
- },
817
- success: function (data) {
818
- $self.prop('disabled',false);
 
819
 
820
- jQuery('#sbi_clear_platform_data').after('<span class="sbi-success"><i class="fa fa-check-circle"></i></span>');
821
- }
822
- });
 
823
  }
824
 
825
- });
 
826
 
827
- jQuery('select[name=sb_instagram_cache_time_unit]').on('change',function() {
 
 
828
  var newMax = 24;
829
- if (jQuery(this).val() === 'minutes') {
830
- newMax = 1440;
831
  }
832
- jQuery('input[name=sb_instagram_cache_time]').prop('max', newMax);
833
- });
 
834
 
835
  //Tooltips
836
- jQuery('#sbi_admin').on('click', '.sbi_tooltip_link, .sbi_type_tooltip_link', function(){
837
- if( jQuery(this).hasClass('sbi_type_tooltip_link') ){
838
- jQuery(this).closest('.sbi_row').children('.sbi_tooltip').slideToggle();
 
 
 
839
  } else {
840
- $el = jQuery(this);
841
- if( jQuery(this).hasClass('sbi_tooltip_outside') ) $el = jQuery(this).parent();
842
- $el.siblings('.sbi_tooltip').slideToggle();
 
 
843
  }
844
- });
 
845
 
846
  //Shortcode labels
847
- jQuery('#sbi_admin label').on('click',function(){
848
- var $sbi_shortcode = jQuery(this).siblings('.sbi_shortcode');
849
- var $el = jQuery(this).parent();
850
-
851
- if($sbi_shortcode.is(':visible')){
852
- $el.removeClass('sbi_shortcode_visible');
853
- $el.find('.sbi_shortcode').css('display','none');
 
 
854
  } else {
855
- $el.addClass('sbi_shortcode_visible');
856
- $el.find('.sbi_shortcode').css('display','block');
857
  }
858
- });
859
-
860
- jQuery('#sbi_admin label').on('mouseenter mouseleave', function(e) {
861
- switch(e.type) {
862
- case 'mouseenter':
863
- if( jQuery(this).siblings('.sbi_shortcode').length > 0 ){
864
- jQuery(this).attr('title', 'Click for shortcode option').append('<code class="sbi_shortcode_symbol">[]</code>');
865
- }
866
- break;
867
- case 'mouseleave':
868
- jQuery(this).find('.sbi_shortcode_symbol').remove();
869
- break;
 
 
 
870
  }
871
- });
872
-
873
- jQuery('#sbi_admin .sbi_lock').on('mouseenter mouseleave', function(e) {
874
- switch(e.type) {
875
- case 'mouseenter':
876
- jQuery(this).siblings('.sbi_pro_tooltip').show();
877
- break;
878
- case 'mouseleave':
879
- jQuery('.sbi_pro_tooltip').hide();
880
- break;
 
 
 
881
  }
882
- });
883
-
 
884
  //Add the color picker
885
- if( jQuery('.sbi_colorpick').length > 0 ) jQuery('.sbi_colorpick').wpColorPicker();
 
 
886
 
887
  //Check User ID is numeric
888
- jQuery("#sb_instagram_user_id").on('change',function() {
 
 
889
 
890
- var sbi_user_id = jQuery('#sb_instagram_user_id').val(),
891
- $sbi_user_id_error = $(this).closest('td').find('.sbi_user_id_error'),
892
- $sbi_other_user_error = $(this).closest('td').find('.sbi_other_user_error');
893
 
894
- if (sbi_user_id.match(/[^0-9, _.-]/)) {
895
- $sbi_user_id_error.fadeIn();
896
  } else {
897
- $sbi_user_id_error.fadeOut();
898
  }
899
 
900
  //Check whether an ID from another account is being used
901
- sbi_check_other_user_id(sbi_user_id, $sbi_other_user_error);
902
 
903
- });
 
904
  function sbi_check_other_user_id(sbi_user_id, $sbi_other_user_error){
905
- if (jQuery('#sb_instagram_at').length && jQuery('#sb_instagram_at').val() !== '' && sbi_user_id.length) {
906
- if(jQuery('#sb_instagram_at').val().indexOf(sbi_user_id) == -1 ){
907
- $sbi_other_user_error.fadeIn();
908
- } else {
909
- $sbi_other_user_error.fadeOut();
910
- }
911
  }
 
912
  }
913
  //Check initially when settings load
914
- sbi_check_other_user_id( jQuery('#sb_instagram_user_id').val(), $('td').find('.sbi_other_user_error') );
915
 
916
  //Mobile width
917
- var sb_instagram_feed_width = jQuery('#sbi_admin #sb_instagram_width').val(),
918
- sb_instagram_width_unit = jQuery('#sbi_admin #sb_instagram_width_unit').val(),
919
- $sb_instagram_width_options = jQuery('#sbi_admin #sb_instagram_width_options');
920
 
921
  if (typeof sb_instagram_feed_width !== 'undefined') {
922
 
923
- //Show initially if a width is set
924
- if( (sb_instagram_feed_width.length > 1 && sb_instagram_width_unit == 'px') || (sb_instagram_feed_width !== '100' && sb_instagram_width_unit == '%') ) $sb_instagram_width_options.show();
925
-
926
- jQuery('#sbi_admin #sb_instagram_width, #sbi_admin #sb_instagram_width_unit').on('change',function(){
927
- sb_instagram_feed_width = jQuery('#sbi_admin #sb_instagram_width').val();
928
- sb_instagram_width_unit = jQuery('#sbi_admin #sb_instagram_width_unit').val();
929
-
930
- if( sb_instagram_feed_width.length < 2 || (sb_instagram_feed_width == '100' && sb_instagram_width_unit == '%') ) {
931
- $sb_instagram_width_options.slideUp();
932
- } else {
933
- $sb_instagram_width_options.slideDown();
934
- }
935
- });
 
 
 
 
 
936
 
937
  }
938
 
939
  //Scroll to hash for quick links
940
- jQuery('#sbi_admin a').on('click',function() {
941
- if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
942
- var target = jQuery(this.hash);
943
- target = target.length ? target : this.hash.slice(1);
944
- if (target.length) {
945
- jQuery('html,body').animate({
946
- scrollTop: target.offset().top
947
- }, 500);
948
- return false;
949
- }
 
 
 
 
 
950
  }
951
- });
 
952
 
953
  //Support tab show video
954
- jQuery('#sbi-play-support-video').on('click', function(e){
 
 
955
  e.preventDefault();
956
- jQuery('#sbi-support-video').show().attr('src', jQuery('#sbi-support-video').attr('src')+'&amp;autoplay=1' );
957
- });
 
958
 
959
- jQuery('#sbi_admin .sbi-show-pro').on('click', function(){
960
- jQuery(this).parent().next('.sbi-pro-options').toggle();
961
- });
 
 
 
962
 
963
  /* Pro 3.0 JS */
964
  function sbiUpdateLayoutTypeOptionsDisplay() {
965
- setTimeout(function(){
966
- jQuery('.sb_instagram_layout_settings').hide();
967
- jQuery('.sb_instagram_layout_settings.sbi_layout_type_'+jQuery('.sb_layout_type:checked').val()).show();
968
- }, 1);
 
 
 
969
  }
970
- jQuery('.sb_layout_type').on('change',sbiUpdateLayoutTypeOptionsDisplay);
971
 
972
- jQuery('.sbi_close_options').on('click', function(){
973
- jQuery('.sb_instagram_layout_settings').hide();
974
- });
 
 
 
975
 
976
  function sbiUpdateHighlightOptionsDisplay() {
977
- jQuery('.sb_instagram_highlight_sub_options').hide();
978
- var selected = jQuery('#sb_instagram_highlight_type').val();
979
 
980
- if (selected === 'pattern') {
981
- jQuery('.sb_instagram_highlight_pattern').show();
982
- } else if (selected === 'id') {
983
- jQuery('.sb_instagram_highlight_ids').show();
984
- } else {
985
- jQuery('.sb_instagram_highlight_hashtag').show();
986
- }
987
 
988
  }
989
  sbiUpdateHighlightOptionsDisplay();
990
- jQuery('#sb_instagram_highlight_type').on('change',sbiUpdateHighlightOptionsDisplay);
991
 
992
  //sb_instagram_enable_email_report
993
  function sbiToggleEmail() {
994
- if (jQuery('#sb_instagram_enable_email_report').is(':checked')) {
995
- jQuery('#sb_instagram_enable_email_report').closest('td').find('.sb_instagram_box').slideDown();
996
- } else {
997
- jQuery('#sb_instagram_enable_email_report').closest('td').find('.sb_instagram_box').slideUp();
998
- }
999
  }sbiToggleEmail();
1000
- jQuery('#sb_instagram_enable_email_report').on('change',sbiToggleEmail);
1001
- if (jQuery('#sbi-goto').length) {
1002
- jQuery('#sbi-goto').closest('tr').addClass('sbi-goto');
1003
- $('html, body').animate({
1004
- scrollTop: $('#sbi-goto').offset().top - 200
1005
- }, 500);
 
 
 
1006
  }
1007
 
1008
  //Open/close the expandable option sections
1009
- jQuery('.sbi-expandable-options').hide();
1010
- jQuery('.sbi-expand-button a').on('click', function(e){
 
 
1011
  e.preventDefault();
1012
- var $self = jQuery(this);
1013
- $self.parent().next('.sbi-expandable-options').toggle();
1014
- if( $self.text().indexOf('Show') !== -1 ){
1015
- $self.text( $self.text().replace('Show', 'Hide') );
1016
  } else {
1017
- $self.text( $self.text().replace('Hide', 'Show') );
1018
  }
1019
- });
 
1020
 
1021
  //Selecting a post layout
1022
- jQuery('.sbi_layout_cell').on('click',function(){
1023
- var $self = jQuery(this);
1024
- $('.sb_layout_type').trigger('change');
1025
- $self.addClass('sbi_layout_selected').find('.sb_layout_type').prop('checked',true);
1026
- $self.siblings().removeClass('sbi_layout_selected');
1027
- });
1028
-
1029
- setTimeout( function() {
1030
- jQuery('.notice-dismiss').on('click',function() {
1031
- if (jQuery(this).closest('.sbi-admin-notice').length) {
1032
-
1033
- if (jQuery(this).closest('.sbi-admin-notice').find('.sbi-admin-error').length) {
1034
-
1035
- var exemptErrorType = jQuery(this).closest('.sbi-admin-notice').find('.sbi-admin-error').attr('data-sbi-type');
1036
-
1037
- if (exemptErrorType === 'ajax') {
1038
- jQuery.ajax({
1039
- url: sbiA.ajax_url,
1040
- type: 'post',
1041
- data: {
1042
- action : 'sbi_on_ajax_test_trigger',
1043
- sbi_nonce: sbiA.sbi_nonce
1044
- },
1045
- success: function (data) {
1046
- }
1047
- });
 
 
 
 
 
 
1048
  }
 
1049
  }
 
1050
  }
1051
- });
1052
- },1500);
 
 
 
1053
 
1054
  //Load the admin share widgets
1055
- jQuery('#sbi_admin_show_share_links').on('click', function(){
1056
- jQuery(this).fadeOut();
1057
- if( jQuery('#sbi_admin_share_links iframe').length == 0 ) jQuery('#sbi_admin_share_links').html('<a href="https://twitter.com/share" class="twitter-share-button" data-url="https://wordpress.org/plugins/instagram-feed/" data-text="Display beautifully clean, customizable, and responsive Instagram feeds from multiple accounts" data-via="smashballoon" data-dnt="true">Tweet</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?"http":"https";if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document, "script", "twitter-wjs");</script> <style type="text/css"> #twitter-widget-0{float: left; width: 82px !important;}.IN-widget{margin-right: 20px;}</style> <div id="fb-root" style="display: none;"></div><script>(function(d, s, id){var js, fjs=d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js=d.createElement(s); js.id=id; js.src="//connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v2.0"; fjs.parentNode.insertBefore(js, fjs);}(document, "script", "facebook-jssdk"));</script> <div class="fb-like" data-href="https://wordpress.org/plugins/instagram-feed/" data-layout="button_count" data-action="like" data-show-faces="false" data-share="true" style="display: block; float: left; margin-right: 5px;"></div><script src="//platform.linkedin.com/in.js" type="text/javascript"> lang: en_US </script> <script type="IN/Share" data-url="https://wordpress.org/plugins/instagram-feed/"></script></div>');
 
 
 
 
1058
 
1059
- setTimeout(function(){
1060
- jQuery('#sbi_admin_share_links').addClass('sbi_show');
1061
- }, 500);
1062
- });
 
 
 
 
1063
 
1064
  // notices
1065
 
1066
- if (jQuery('#sbi-notice-bar').length) {
1067
- jQuery('#wpadminbar').after(jQuery('#sbi-notice-bar'));
1068
- jQuery('#wpcontent').css('padding-left', 0);
1069
- jQuery('#wpbody').css('padding-left', '20px');
1070
- jQuery('#sbi-notice-bar').show();
1071
  }
1072
 
1073
- jQuery('#sbi-notice-bar .dismiss').on('click',function(e) {
 
 
1074
  e.preventDefault();
1075
- jQuery('#sbi-notice-bar').remove();
1076
- jQuery.ajax({
 
1077
  url: sbiA.ajax_url,
1078
  type: 'post',
1079
  data: {
1080
- action : 'sbi_lite_dismiss',
1081
- sbi_nonce: sbiA.sbi_nonce
1082
  },
1083
  success: function (data) {
1084
  }
1085
- });
1086
- });
 
 
1087
  /* removing padding */
1088
- if (jQuery('#sbi-admin-about').length && ! jQuery('.sbi_more_plugins').length) {
1089
- jQuery('#wpcontent').css('padding', 0);
1090
  }
1091
 
1092
  /* Clear errors visit page */
1093
- jQuery('.sbi-error-directions a').addClass('button button-primary');
1094
- jQuery('.sbi-error-directions.sbi-reconnect a').on('click',function(){
 
 
1095
  event.preventDefault();
1096
- jQuery('.sbi_admin_btn').trigger('click');
1097
- });
1098
- jQuery('.sbi-clear-errors-visit-page').appendTo('.sbi-error-directions');
1099
- jQuery('.sbi-clear-errors-visit-page').on('click',function(event) {
 
 
 
1100
  event.preventDefault();
1101
- var $btn = jQuery(this);
1102
- $btn.prop( 'disabled', true ).addClass( 'loading' ).html('<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>');
1103
- $.ajax({
 
1104
  url : sbiA.ajax_url,
1105
  type : 'post',
1106
  data : {
1107
- action : 'sbi_reset_log'
 
1108
  },
1109
  success : function(data) {
1110
- window.location.href = $btn.attr('href');
1111
  },
1112
  error : function(data) {
1113
- window.location.href = $btn.attr('href');
1114
  }
1115
- }); // ajax call
1116
- })
 
 
1117
 
1118
  //Click event for other plugins in menu
1119
- $('.sbi_get_cff, .sbi_get_sbi, .sbi_get_ctf, .sbi_get_yt').parent().on('click', function(e){
 
 
1120
  e.preventDefault();
1121
 
1122
- jQuery('.sb_cross_install_modal').remove();
1123
 
1124
- $('#wpbody-content').prepend('<div class="sb_cross_install_modal"><div class="sb_cross_install_inner" id="sbi-admin-about"><div id="sbi-admin-addons"><div class="addons-container"><i class="fa fa-spinner fa-spin sbi-loader" aria-hidden="true"></i></div></div></div></div>');
1125
 
1126
- var $self = $(this).find('span'),
1127
- sb_get_plugin = 'custom_twitter_feeds';
1128
 
1129
- if( $self.hasClass('sbi_get_cff') ){
1130
- sb_get_plugin = 'custom_facebook_feed';
1131
- } else if( $self.hasClass('sbi_get_sbi') ){
1132
- sb_get_plugin = 'instagram_feed';
1133
- } else if( $self.hasClass('sbi_get_yt') ){
1134
- sb_get_plugin = 'feeds_for_youtube';
1135
  }
1136
 
1137
- $get_plugins_url = sbiA.ajax_url.replace('admin-ajax.php', '');
1138
 
1139
  //Get the quick install box from the about page
1140
- $('.sb_cross_install_modal .addons-container').load($get_plugins_url+'admin.php?page=sb-instagram-feed&tab=more #install_'+sb_get_plugin);
1141
- });
 
1142
 
1143
  //Add class to Pro menu item
1144
- $('.sbi_get_pro').parent().attr({'class':'sbi_get_pro_highlight', 'target':'_blank'});
1145
 
1146
- jQuery('.sbi-need-to-connect').on('click',function(e) {
 
 
1147
  e.preventDefault();
1148
 
1149
- jQuery('#sbi_config_info').show();
1150
- });
1151
-
1152
- jQuery('.sbi_show_gdpr_list').on('click', function(){
1153
-
1
+ jQuery( document ).ready(
2
+ function($) {
3
 
4
  //Close the modal if clicking anywhere outside it
5
+ jQuery( 'body' ).on(
6
+ 'click',
7
+ '.sb_cross_install_modal',
8
+ function(e){
9
+ if (e.target !== this) {
10
+ return;
11
+ }
12
+ jQuery( '.sb_cross_install_modal' ).remove();
13
+ }
14
+ );
15
 
16
+ jQuery( '#sbi_no_js_warning' ).remove();
17
  /* NEW API CODE */
18
+ $( '.sbi_admin_btn, .sbi_reconnect' ).on(
19
+ 'click',
20
+ function(event) {
21
  event.preventDefault();
22
 
23
+ var today = new Date(),
24
+ march = new Date( 'June 1, 2020 00:00:00' ),
25
+ oldApiURL = $( this ).attr( 'data-old-api' ),
26
+ oldApiLink = '';
27
  if (today.getTime() < march.getTime()) {
28
+ oldApiLink = 'To connect using the legacy API, <a href="' + oldApiURL + '">click here</a> (expires on June 1, 2020).';
29
  }
30
 
31
+ var personalBasicApiURL = $( '#sbi_config .sbi_admin_btn' ).attr( 'data-personal-basic-api' ),
32
+ newApiURL = $( '#sbi_config .sbi_admin_btn' ).attr( 'data-new-api' );
33
 
34
  var modalHTML = '<div class="sbi-source-popup sbi-popup-inside sbi_config_modal"><div class="sbi-source-redirect sbi-fs"><div class="sbi-source-redirect-ld sbi-fs"><div></div></div> <div class="sbi-source-redirect-info sbi-fs"><strong class="sbi-fs">Redirecting to connect.smashballoon.com</strong> <p class="sbi-fs">You will be redirected to our app so you can connect your account in 5 seconds</p></div></div></div>';
35
+ $( '#sbi_config' ).append(
36
+ '<div id="sbi_config_info" class="sb_get_token">' +
37
+ modalHTML +
38
+ '</div>'
39
+ );
40
+
41
+ setTimeout(
42
+ function() {
43
  window.location.href = newApiURL;
44
+ },
45
+ 3000
46
+ );
47
+ }
48
+ );
49
+
50
+ if ($( '.sbi_config_modal .sbi-managed-pages' ).length) {
51
+ $( '#sbi_config' ).append( $( '#sbi_config_info' ) );
52
  }
53
 
54
+ $( '#sbi-select-all' ).on(
55
+ 'change',
56
+ function() {
57
+ var status = $( this ).is( ':checked' );
58
+ $( '.sbi-add-checkbox input' ).each(
59
+ function() {
60
+ $( this ).prop( 'checked',status );
61
+ }
62
+ );
63
+ if ($( '.sbi-add-checkbox input:checked' ).length) {
64
+ $( '#sbi-connect-business-accounts' ).prop( 'disabled',false );
65
  } else {
66
+ $( '#sbi-connect-business-accounts' ).prop( 'disabled',true );
67
  }
68
+ }
69
+ );
70
+
71
+ $( '.sbi-add-checkbox input' ).on(
72
+ 'change',
73
+ function() {
74
+ if ($( '.sbi-add-checkbox input:checked' ).length) {
75
+ $( '#sbi-connect-business-accounts' ).prop( 'disabled',false );
76
  } else {
77
+ $( '#sbi-connect-business-accounts' ).prop( 'disabled',true );
78
  }
79
+ }
80
+ );
81
 
82
+ $( '#sbi-connect-business-accounts' ).on(
83
+ 'click',
84
+ function(event) {
85
  event.preventDefault();
86
  var accounts = {};
87
+ $( '.sbi-add-checkbox input' ).each(
88
+ function(index) {
89
+ if ($( this ).is( ':checked' )) {
90
+ var jsonSubmit = JSON.parse( $( this ).val() );
91
+ jsonSubmit.access_token = $( this ).closest( '.sbi-managed-page' ).attr( 'data-token' );
92
+ jsonSubmit.page_access_token = $( this ).closest( '.sbi-managed-page' ).attr( 'data-page-token' );
93
+ accounts[index] = jsonSubmit;
94
  }
95
+ }
96
+ );
97
 
98
+ $( '.sbi_connected_accounts_wrap,#sbi_config_info' ).fadeTo( "slow" , 0.5 );
99
+ jQuery.ajax(
100
+ {
101
  url: sbiA.ajax_url,
102
  type: 'post',
103
  data: {
104
+ action: 'sbi_connect_business_accounts',
105
+ accounts: JSON.stringify( accounts ),
106
+ sbi_nonce: sbiA.sbi_nonce
107
  },
108
  success: function (data) {
109
+ var connectedAccounts = typeof data.data !== 'undefined' ? data.data : data;
110
+ $( '.sbi_connected_accounts_wrap' ).fadeTo( "slow" , 1 );
111
+ $( '#sbi_config_info' ).remove();
112
+ $.each(
113
+ connectedAccounts,
114
+ function(index,savedToken) {
115
+ console.log( savedToken );
116
+ sbiAfterUpdateToken( savedToken,false );
 
 
117
 
118
+ }
119
+ );
120
  }
121
+ }
122
+ );
123
 
124
+ }
125
+ );
126
 
127
+ $( '.sbi_modal_close' ).on(
128
+ 'click',
129
+ function(){
130
+ if (jQuery( '.sbi-need-to-connect' ).length) {
131
+ $( '#sbi_config_info' ).hide();
132
  } else {
133
+ $( '#sbi_config_info' ).remove();
134
  }
135
+ }
136
+ );
137
  /* NEW API CODE */
138
  //Autofill the token and id
139
  var hash = window.location.hash,
140
+ token = hash.substring( 14 ),
141
+ id = token.split( '.' )[0];
142
+
143
+ if (token.length > 40 && $( '.sbi_admin_btn' ).length) {
144
+ $( '.sbi_admin_btn' ).css( 'opacity','.5' ).after( '<div class="spinner" style="visibility: visible; position: relative;float: left;margin-top: 15px;"></div>' );
145
+ jQuery.ajax(
146
+ {
147
+ url: sbiA.ajax_url,
148
+ type: 'post',
149
+ data: {
150
+ action: 'sbi_after_connection',
151
+ access_token: token,
152
+ },
153
+ success: function (data) {
154
+ var accountInfo = typeof data.data !== 'undefined' ? data.data : data;
155
+ if (typeof accountInfo.error_message === 'undefined') {
156
+ accountInfo.token = token;
157
+
158
+ $( '.sbi_admin_btn' ).css( 'opacity','1' );
159
+ $( '#sbi_config' ).find( '.spinner' ).remove();
160
+ if ( ! $( '.sbi_connected_account ' ).length) {
161
+ $( '.sbi_no_accounts' ).remove();
162
+ sbSaveToken( token,true );
163
+ } else {
164
+ var buttonText = 'Connect This Account';
165
+ // if the account is connected, offer to update in case information has changed.
166
+ if ($( '#sbi_connected_account_' + id ).length) {
167
+ buttonText = 'Update This Account';
168
+ }
169
+ $( '#sbi_config' ).append(
170
+ '<div id="sbi_config_info" class="sb_get_token">' +
171
+ '<div class="sbi_config_modal">' +
172
+ '<img class="sbi_ca_avatar" src="' + accountInfo.profile_picture + '" />' +
173
+ '<div class="sbi_ca_username"><strong>' + accountInfo.username + '</strong></div>' +
174
+ '<p class="sbi_submit"><input type="submit" name="sbi_submit" id="sbi_connect_account" class="button button-primary" value="' + buttonText + '">' +
175
+ '<a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts">Switch Accounts</a></p>' +
176
+ '<a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>' +
177
+ '</div>' +
178
+ '</div>'
179
+ );
180
 
181
+ $( '#sbi_connect_account' ).on(
182
+ 'click',
183
+ function(event) {
184
+ event.preventDefault();
185
+ $( '#sbi_config_info' ).fadeOut( 200 );
186
+ sbSaveToken( token,false );
187
+ }
188
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
+ sbiSwitchAccounts();
191
+ }
192
+ } else {
193
+ $( '.sbi_admin_btn' ).css( 'opacity','1' );
194
+ $( '#sbi_config' ).find( '.spinner' ).remove();
195
+ var message = accountInfo.error_message;
196
+
197
+ $( '#sbi_config' ).append(
198
+ '<div id="sbi_config_info" class="sb_get_token">' +
199
+ '<div class="sbi_config_modal">' +
200
+ '<p>' + message + '</p>' +
201
+ '<p class="sbi_submit"><a href="JavaScript:void(0);" class="button button-secondary" id="sbi_switch_accounts">Switch Accounts</a></p>' +
202
+ '<a href="JavaScript:void(0);"><i class="sbi_modal_close fa fa-times"></i></a>' +
203
+ '</div>' +
204
+ '</div>'
205
+ );
206
 
207
+ sbiSwitchAccounts();
208
  }
209
+ }
210
+ }
211
+ );
212
 
213
+ window.location.hash = '';
214
  }
215
  function sbiSwitchAccounts(){
216
+ $( '#sbi_switch_accounts' ).on(
217
+ 'click',
218
+ function(){
219
+ //Log user out of Instagram by hitting the logout URL in an iframe
220
+ $( 'body' ).append( '<iframe style="display: none;" src="https://www.instagram.com/accounts/logout"></iframe>' );
221
+
222
+ $( this ).text( 'Please wait...' ).after( '<div class="spinner" style="visibility: visible; float: none; margin: -3px 0 0 3px;"></div>' );
223
+
224
+ //Wait a couple seconds for the logout to occur, then connect a new account
225
+ setTimeout(
226
+ function(){
227
+ window.location.href = $( '.sbi_admin_btn' ).attr( 'href' );
228
+ },
229
+ 2000
230
+ );
231
+ }
232
+ );
233
 
234
+ $( '.sbi_modal_close' ).on(
235
+ 'click',
236
+ function(){
237
+ $( '#sbi_config_info' ).remove();
238
+ }
239
+ );
240
  }
241
+ if ($( '#sbi_switch_accounts' ).length) {
242
+ $( '.sbi_admin_btn' ).attr( 'href',$( '#sbi_config .sbi_admin_btn' ).attr( 'data-personal-basic-api' ) );
243
+ sbiSwitchAccounts();
244
  }
245
 
246
  function sbiAfterUpdateToken(savedToken,saveID){
247
+ $( '.sbi_no_accounts' ).remove();
248
+ if (saveID) {
249
+ sbSaveID( savedToken.user_id );
250
+ $( '.sbi_user_feed_ids_wrap' ).prepend(
251
+ '<div id="sbi_user_feed_id_' + savedToken.user_id + '" class="sbi_user_feed_account_wrap">' +
252
+ '<strong>' + savedToken.username + '</strong> <span>(' + savedToken.user_id + ')</span>' +
253
+ '<input type="hidden" name="sb_instagram_user_id[]" value="' + savedToken.user_id + '">' +
254
+ '</div>'
255
+ );
256
+ }
257
+ if (typeof savedToken.old_user_id !== 'undefined' && $( '#sbi_connected_account_' + savedToken.old_user_id ).length) {
258
+
259
+ if ($( '#sbi_user_feed_id_' + savedToken.old_user_id ).length) {
260
+ $( '.sbi_user_feed_ids_wrap' ).prepend(
261
+ '<div id="sbi_user_feed_id_' + savedToken.user_id + '" class="sbi_user_feed_account_wrap">' +
262
+ '<strong>' + savedToken.username + '</strong> <span>(' + savedToken.user_id + ')</span>' +
263
+ '<input type="hidden" name="sb_instagram_user_id[]" value="' + savedToken.user_id + '">' +
264
+ '</div>'
265
+ );
266
+ $( '#sbi_user_feed_id_' + savedToken.old_user_id ).remove();
267
+
268
+ saveID = true;
269
  }
 
 
 
 
 
 
 
 
 
 
270
 
271
+ $( '#sbi_connected_account_' + savedToken.old_user_id ).remove();
272
+ }
273
+ if ($( '#sbi_connected_account_' + savedToken.user_id ).length) {
274
+ if (savedToken.is_valid) {
275
+ $( '#sbi_connected_account_' + savedToken.user_id ).addClass( 'sbi_account_updated' );
276
+ } else {
277
+ $( '#sbi_connected_account_' + savedToken.user_id ).addClass( 'sbi_account_invalid' );
278
+ }
279
+ $( '#sbi_connected_account_' + savedToken.user_id ).attr( 'data-accesstoken',savedToken.access_token );
280
+ if (typeof savedToken.use_tagged !== 'undefined' && savedToken.use_tagged == '1') {
281
+ $( '#sbi_connected_account_' + savedToken.user_id ).attr( 'data-permissions','tagged' );
282
+ $( '#sbi_connected_account_' + savedToken.user_id ).find( '.sbi_permissions_desc' ).text( 'All' );
283
  }
 
 
 
 
 
 
 
 
 
 
 
284
 
285
+ if ( ! $( '#sbi_connected_account_' + savedToken.user_id + ' .sbi_ca_avatar' ).length) {
286
+ if (savedToken.profile_picture !== '') {
287
+ $( '#sbi_connected_account_' + savedToken.user_id + ' .sbi_ca_username' ).prepend( '<img class="sbi_ca_avatar" src="' + savedToken.profile_picture + '">' );
288
+ }
289
+ }
290
+ $( '#sbi_connected_account_' + savedToken.user_id + ' .sbi_ca_username' ).find( 'span' ).text( sbiAccountType( savedToken.type,false ) );
291
 
292
+ $( '#sbi_connected_account_' + savedToken.user_id ).find( '.sbi_ca_accesstoken .sbi_ca_token' ).text( savedToken.access_token );
293
+ $( '#sbi_connected_account_' + savedToken.user_id ).find( '.sbi_tooltip code' ).text( '[instagram-feed accesstoken="' + savedToken.access_token + '"]' );
294
 
295
+ } else {
296
+ //Check which kind of account it is
297
+ if (typeof savedToken.type !== 'undefined') {
298
+ var accountType = savedToken.type;
299
+ $( '.sbi_hashtag_feed_issue' ).removeClass( 'sbi_hashtag_feed_issue' ).find( '.sbi_hashtag_feed_issue_note' ).hide();
300
  } else {
301
+ var accountType = 'personal';
302
+ }
303
+ var isPrivate = (typeof savedToken.private !== 'undefined');
 
 
 
 
 
304
 
305
+ var avatarHTML = '';
306
+ if (savedToken.profile_picture !== '') {
307
+ avatarHTML = '<img class="sbi_ca_avatar" src="' + savedToken.profile_picture + '" />';
308
+ }
309
 
310
+ //Add the account HTML to the page
311
+ var removeOrSaveHTML = saveID ? '<a href="JavaScript:void(0);" class="sbi_remove_from_user_feed button-primary"><i class="fa fa-minus-circle" aria-hidden="true"></i>Remove from Primary Feed</a>' : '<a href="JavaScript:void(0);" class="sbi_use_in_user_feed button-primary"><i class="fa fa-plus-circle" aria-hidden="true"></i>Add to Primary Feed</a>',
312
+ statusClass = saveID ? 'sbi_account_active' : 'sbi_account_updated',
313
+ html = '<div class="sbi_connected_account ' + statusClass + ' sbi-init-click-remove" id="sbi_connected_account_' + savedToken.user_id + '" data-accesstoken="' + savedToken.access_token + '" data-userid="' + savedToken.user_id + '" data-username="' + savedToken.username + '">' +
314
+ '<div class="sbi_ca_info">' +
315
+
316
+ '<div class="sbi_ca_delete">' +
317
+ '<a href="JavaScript:void(0);" class="sbi_delete_account"><i class="fa fa-times"></i><span class="sbi_remove_text">Remove</span></a>' +
318
+ '</div>' +
319
+
320
+ '<div class="sbi_ca_username">' +
321
+ avatarHTML +
322
+ '<strong>' + savedToken.username + '<span>' + sbiAccountType( accountType,isPrivate ) + '</span></strong>' +
323
+ '</div>' +
324
+
325
+ '<div class="sbi_ca_actions">' +
326
+ removeOrSaveHTML +
327
+ '<a class="sbi_ca_token_shortcode button-secondary" href="JavaScript:void(0);"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>Add to another Feed</a>' +
328
+ '<a class="sbi_ca_show_token button-secondary" href="JavaScript:void(0);" title="Show access token and account info"><i class="fa fa-cog"></i></a>' +
329
+ '</div>' +
330
+
331
+ '<div class="sbi_ca_shortcode">' +
332
+ '<p>Copy and paste this shortcode into your page or widget area:<br>' +
333
+ '<code>[instagram-feed user="' + savedToken.username + '"]</code>' +
334
+ '</p>' +
335
+ '<p>To add multiple users in the same feed, simply separate them using commas:<br>' +
336
+ '<code>[instagram-feed user="' + savedToken.username + ', a_second_user, a_third_user"]</code>' +
337
+ '<p>Click on the <a href="?page=sb-instagram-feed&tab=display" target="_blank">Display Your Feed</a> tab to learn more about shortcodes</p>' +
338
+ '</div>' +
339
+
340
+ '<div class="sbi_ca_accesstoken">' +
341
+ '<span class="sbi_ca_token_label">User ID:</span><input type="text" class="sbi_ca_user_id" value="' + savedToken.user_id + '" readonly="readonly" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac)."><br>' +
342
+ '<span class="sbi_ca_token_label">Permissions:</span><span class="sbi_permissions_desc">All</span>' +
343
+ '</div>' +
344
+
345
+ '</div>' +
346
+ '</div>';
347
+ $( '.sbi_connected_accounts_wrap' ).prepend( html );
348
+ var $clickRemove = $( '.sbi-init-click-remove' );
349
+ sbiInitClickRemove( $clickRemove.find( '.sbi_delete_account' ) );
350
+ if ($clickRemove.find( '.sbi_remove_from_user_feed' ).length ) {
351
+ $clickRemove.find( '.sbi_remove_from_user_feed' ).off();
352
+ sbiInitUserRemove( $clickRemove.find( '.sbi_remove_from_user_feed' ) );
353
+ } else {
354
+ $clickRemove.find( '.sbi_use_in_user_feed' ).off();
355
+ sbiInitUserAdd( $clickRemove.find( '.sbi_use_in_user_feed' ) );
 
 
356
  }
357
+ $clickRemove.removeClass( 'sbi-init-click-remove' );
358
+ }
359
  }
360
 
361
  function sbSaveToken(token,saveID) {
362
+ $( '.sbi_connected_accounts_wrap' ).fadeTo( "slow" , 0.5 );
363
+ jQuery.ajax(
364
+ {
365
+ url: sbiA.ajax_url,
366
+ type: 'post',
367
+ data: {
368
+ action: 'sbi_auto_save_tokens',
369
+ access_token: token,
370
+ just_tokens: true,
371
+ sbi_nonce: sbiA.sbi_nonce
372
+ },
373
+ success: function (data) {
374
+ var savedToken = typeof data.data !== 'undefined' ? data.data : data;
375
+ $( '.sbi_connected_accounts_wrap' ).fadeTo( "slow" , 1 );
376
+ sbiAfterUpdateToken( savedToken,saveID );
377
+ }
378
+ }
379
+ );
380
  }
381
 
382
  function sbiAccountType(accountType,isPrivate) {
383
+ if (accountType === 'basic') {
384
+ var returnText = 'personal';
385
+ if (isPrivate) {
386
+ returnText += ' (private)'
 
 
387
  }
388
+ return returnText;
389
+ }
390
+ return accountType;
391
  }
392
 
393
  function sbSaveID(ID) {
394
+ jQuery.ajax(
395
+ {
396
+ url: sbiA.ajax_url,
397
+ type: 'post',
398
+ data: {
399
+ action: 'sbi_auto_save_id',
400
+ id: ID,
401
+ just_tokens: true,
402
+ sbi_nonce: sbiA.sbi_nonce
403
+ },
404
+ success: function (data) {
405
+ }
406
+ }
407
+ );
408
  }
409
 
410
  // connect accounts
411
  //sbi-bus-account-error
412
  if (window.location.hash && window.location.hash === '#test') {
413
+ window.location.hash = '';
414
+ $( '#sbi-bus-account-error' ).html(
415
+ '<p style="margin-top: 5px;"><strong style="font-size: 16px">Couldn\'t connect an account with this access token</strong><br />' +
416
+ 'Please check to make sure that the token you entered is correct.</p>'
417
+ )
418
  }
419
 
420
+ $( '.sbi_manually_connect_wrap' ).hide();
421
+ $( '.sbi_manually_connect' ).on(
422
+ 'click',
423
+ function(event) {
424
  event.preventDefault();
425
+ if ( $( '.sbi_manually_connect_wrap' ).is( ':visible' ) ) {
426
+ $( '.sbi_manually_connect_wrap' ).slideUp( 200 );
427
  } else {
428
+ $( '.sbi_manually_connect_wrap' ).slideDown( 200 );
429
+ $( '#sb_manual_at' ).focus();
430
  }
431
+ }
432
+ );
433
 
434
+ $( '#sb_manual_at' ).on(
435
+ 'input',
436
+ function() {
 
437
  sbiToggleManualAccountIDInput();
438
+ }
439
+ );
440
+ if ($( '#sb_manual_at' ).length) {
441
+ sbiToggleManualAccountIDInput();
442
  }
443
 
444
  function sbiIsBusinessToken() {
445
+ return ($( '#sb_manual_at' ).val().trim().length > 125);
446
  }
447
 
448
  function sbiToggleManualAccountIDInput() {
449
+ if (sbiIsBusinessToken()) {
450
+ $( '.sbi_manual_account_id_toggle' ).slideDown();
451
+ $( '.sbi_business_profile_tag' ).css( 'display', 'inline-block' );
452
+ } else {
453
+ $( '.sbi_manual_account_id_toggle' ).slideUp();
454
+ }
455
  }
456
 
457
+ var $body = $( 'body' );
458
+ $body.on(
459
+ 'click',
460
+ '.sbi_test_token, .sbi_ca_token_shortcode',
461
+ function (event) {
462
  event.preventDefault();
463
+ var $clicked = $( event.target ),
464
+ accessToken = $clicked.closest( '.sbi_connected_account' ).attr( 'data-accesstoken' ),
465
+ action = false,
466
+ atParts = accessToken.split( '.' ),
467
+ username = $clicked.closest( '.sbi_connected_account' ).attr( 'data-username' ),
468
+ accountID = $clicked.closest( '.sbi_connected_account' ).attr( 'data-userid' );
469
+ if ($clicked.hasClass( 'sbi_ca_token_shortcode' )) {
470
+ jQuery( this ).closest( '.sbi_ca_info' ).find( '.sbi_ca_shortcode' ).slideToggle( 200 );
471
  } //
472
 
473
+ }
474
+ );
475
 
476
+ $( '.sbi_delete_account' ).each(
477
+ function() {
478
+ sbiInitClickRemove( $( this ) );
479
+ }
480
+ );
481
 
482
  function sbiInitClickRemove(el) {
483
+ el.on(
484
+ 'click',
485
+ function(event) {
486
+ event.preventDefault();
487
+ if ( ! $( this ).closest( '.sbi_connected_accounts_wrap' ).hasClass( 'sbi-waiting' )) {
488
+ $( this ).closest( '.sbi_connected_accounts_wrap' ).addClass( 'sbi-waiting' );
489
+ var accessToken = $( this ).closest( '.sbi_connected_account' ).attr( 'data-accesstoken' ),
490
+ action = false,
491
+ atParts = accessToken.split( '.' ),
492
+ username = $( this ).closest( '.sbi_connected_account' ).attr( 'data-username' ),
493
+ accountID = $( this ).closest( '.sbi_connected_account' ).attr( 'data-userid' );
494
+
495
+ if (window.confirm( "Delete this connected account?" )) {
496
+ action = 'sbi_delete_account';
497
+ $( '#sbi_user_feed_id_' + accountID ).remove();
498
+ $( '#sbi_tagged_feed_id_' + accountID ).remove();
499
+ $( '#sbi_connected_account_' + accountID ).append( '<div class="spinner" style="margin-top: -10px;visibility: visible;top: 50%;position: absolute;right: 50%;"></div>' ).find( '.sbi_ca_info' ).css( 'opacity','.5' );
500
+
501
+ jQuery.ajax(
502
+ {
503
+ url: sbiA.ajax_url,
504
+ type: 'post',
505
+ data: {
506
+ action: action,
507
+ account_id: accountID,
508
+ sbi_nonce: sbiA.sbi_nonce
509
+ },
510
+ success: function (data) {
511
+ $( '.sbi-waiting' ).removeClass( 'sbi-waiting' );
512
+ $( '#sbi_connected_account_' + accountID ).fadeOut( 300, function() { $( this ).remove(); } );
513
+ }
514
  }
515
+ );
516
+ } else {
517
+ $( '.sbi-waiting' ).removeClass( 'sbi-waiting' );
518
  }
519
+ }
520
 
521
+ }
522
+ );
523
  }
524
 
525
+ $( '.sbi_remove_from_user_feed' ).each(
526
+ function() {
527
+ sbiInitUserRemove( $( this ) );
528
+ }
529
+ );
530
 
531
  function sbiInitUserRemove(el,targetClass) {
532
+ el.on(
533
+ 'click',
534
+ function(event) {
535
+ event.preventDefault();
536
+ var targetClass = $( 'input[name=sb_instagram_type]:checked' ).val();
537
 
538
+ var $clicked = $( this ),
539
+ accountID = $clicked.closest( '.sbi_connected_account' ).attr( 'data-userid' );
540
 
541
+ $( '#sbi_' + targetClass + '_feed_id_' + accountID ).remove();
542
 
543
+ sbiConAccountsAddRemoveUpdater();
544
+ }
545
+ );
546
  }
547
 
548
+ $( '.sbi_use_in_user_feed' ).each(
549
+ function() {
550
+ sbiInitUserAdd( $( this ), 'user' );
551
+ }
552
+ );
553
 
554
  function sbiInitUserAdd(el,targetClass) {
555
+ el.on(
556
+ 'click',
557
+ function(event) {
558
+ var targetClass = $( 'input[name=sb_instagram_type]:checked' ).val();
559
+ event.preventDefault();
560
+ var $clicked = $( this ),
561
+ $closest = $clicked.closest( '.sbi_connected_account' ),
562
+ username = $clicked.closest( '.sbi_connected_account' ).attr( 'data-username' ),
563
+ accountID = $clicked.closest( '.sbi_connected_account' ).attr( 'data-userid' );
564
+
565
+ var name = '<strong>' + accountID + '</strong>';
566
+ if (username !== '') {
567
+ name = '<strong>' + username + '</strong> <span>(' + accountID + ')</span>';
568
+ }
569
+ $( '.sbi_' + targetClass + '_feed_ids_wrap' ).prepend(
570
+ '<div id="sbi_' + targetClass + '_feed_id_' + accountID + '" class="sbi_' + targetClass + '_feed_account_wrap">' +
571
+ name +
572
+ '<input type="hidden" name="sb_instagram_' + targetClass + '_id[]" value="' + accountID + '">' +
573
+ '</div>'
574
+ );
575
+ $( '.sbi_no_accounts' ).hide();
576
+ sbiConAccountsAddRemoveUpdater();
577
+ }
578
+ );
579
  }
580
 
581
  function sbiConAccountsAddRemoveUpdater() {
582
+ var targetClass = $( 'input[name=sb_instagram_type]:checked' ).val();
583
+
584
+ var isSelected = [];
585
+ $( '.sbi_' + targetClass + '_feed_account_wrap' ).find( 'input' ).each(
586
+ function() {
587
+ isSelected.push( $( this ).val() );
588
+ }
589
+ );
590
+
591
+ $( '.sbi_connected_account' ).each(
592
+ function() {
593
+ var username = $( this ).attr( 'data-username' ),
594
+ accountID = $( this ).attr( 'data-userid' ),
595
+ type = $( this ).attr( 'data-type' ),
596
+ permissions = $( this ).attr( 'data-permissions' ),
597
+ $addRemoveButton = $( this ).find( '.sbi_ca_actions .button-primary' ).first();
598
+ $( this ).removeClass( 'sbi_account_updated' );
599
+ $addRemoveButton.prop( 'disabled',false );
600
+
601
+ if (targetClass === 'tagged' && (type === 'personal' || permissions !== 'tagged')) {
602
+ $addRemoveButton.show();
603
+ if (type === 'personal') {
604
+ $addRemoveButton.html( 'Tagged Feeds Not Supported' );
 
 
 
 
 
 
605
  } else {
606
+ $addRemoveButton.html( 'Reconnect Account' );
 
 
 
 
 
 
 
 
 
 
607
  }
608
+ $addRemoveButton.prop( 'disabled',true ).addClass( 'sbi_remove_from_user_feed' ).removeClass( 'sbi_use_in_user_feed' );
609
+ $( this ).removeClass( 'sbi_account_active' );
610
+ } else if (targetClass === 'hashtag') {
611
+ $addRemoveButton.hide();
612
+ $addRemoveButton.prop( 'disabled',true ).addClass( 'sbi_remove_from_user_feed' ).removeClass( 'sbi_use_in_user_feed' );
613
+ $( this ).removeClass( 'sbi_account_active' );
614
+ } else {
615
+ $addRemoveButton.show();
616
+ if (isSelected.indexOf( accountID ) > -1) {
617
+ $addRemoveButton.html( '<i class="fa fa-minus-circle" aria-hidden="true" style="margin-right: 5px;"></i>Remove from Primary Feed' );
618
+ $addRemoveButton.addClass( 'sbi_remove_from_user_feed' ).removeClass( 'sbi_use_in_user_feed' );
619
+ $( this ).addClass( 'sbi_account_active' );
620
  } else {
621
+ $addRemoveButton.html( '<i class="fa fa-plus-circle" aria-hidden="true"></i>Add to Primary Feed' );
622
+ $addRemoveButton.removeClass( 'sbi_remove_from_user_feed' );
623
+ $addRemoveButton.addClass( 'sbi_use_in_user_feed' );
624
+ $( this ).removeClass( 'sbi_account_active' );
625
  }
626
+ }
627
 
628
+ if ($( this ).find( '.sbi_remove_from_user_feed' ).length ) {
629
+ $( this ).find( '.sbi_remove_from_user_feed' ).off();
630
+ sbiInitUserRemove( $( this ).find( '.sbi_remove_from_user_feed' ) );
631
+ } else {
632
+ $( this ).find( '.sbi_use_in_user_feed' ).off();
633
+ sbiInitUserAdd( $( this ).find( '.sbi_use_in_user_feed' ),'user' );
634
+ }
635
 
636
+ }
637
+ );
638
+ }sbiConAccountsAddRemoveUpdater();
639
 
640
+ $( 'input[name=sb_instagram_type]' ).on( 'change',sbiConAccountsAddRemoveUpdater );
641
 
642
+ $body.on(
643
+ 'click',
644
+ '.sbi_ca_show_token',
645
+ function(event) {
646
+ jQuery( this ).closest( '.sbi_ca_info' ).find( '.sbi_ca_accesstoken' ).slideToggle( 200 );
647
+ }
648
+ );
649
 
650
+ $( '#sbi_manual_submit' ).on(
651
+ 'click',
652
+ function(event) {
653
  event.preventDefault();
654
+ var $self = $( this );
655
+ var accessToken = $( '#sb_manual_at' ).val(),
656
+ error = false;
657
+ if (sbiIsBusinessToken() && $( '.sbi_manual_account_id_toggle' ).find( 'input' ).val().length < 3) {
658
+ error = true;
659
+ if ( ! $( '.sbi_manually_connect_wrap' ).find( '.sbi_user_id_error' ).length) {
660
+ $( '.sbi_manually_connect_wrap' ).show().prepend( '<div class="sbi_user_id_error" style="display:block;">Please enter a valid User ID for this Business account.</div>' );
661
+ }
662
  } else {
663
+ error = false;
664
  }
665
  if (accessToken.length < 15) {
666
+ if ( ! $( '.sbi_manually_connect_wrap' ).find( '.sbi_user_id_error' ).length) {
667
+ $( '.sbi_manually_connect_wrap' ).show().prepend( '<div class="sbi_user_id_error" style="display:block;">Please enter a valid access token</div>' );
668
+ }
669
+ } else if ( ! error) {
670
+ $( this ).prop( 'disabled',true );
671
+ $( this ).closest( '.sbi_manually_connect_wrap' ).fadeOut();
672
+ $( '.sbi_connected_accounts_wrap' ).fadeTo( "slow" , 0.5 ).find( '.sbi_user_id_error' ).remove();
673
+
674
+ jQuery.ajax(
675
+ {
676
+ url: sbiA.ajax_url,
677
+ type: 'post',
678
+ data: {
679
+ action: 'sbi_test_token',
680
+ access_token: accessToken,
681
+ account_id : $( '.sbi_manual_account_id_toggle' ).find( 'input' ).val().trim(),
682
+ sbi_nonce: sbiA.sbi_nonce
683
+ },
684
+ success: function (data) {
685
+ var savedToken = typeof data.data !== 'undefined' ? data.data : data;
686
+ $( '.sbi_connected_accounts_wrap' ).fadeTo( "slow" , 1 );
687
+ $self.prop( 'disabled',false );
688
+
689
+ if ( typeof savedToken.error_message === 'undefined' ) {
690
+ if (typeof savedToken.url !== 'undefined') {
691
+ window.location.href = savedToken.url;
692
+ } else {
693
+ $( this ).closest( '.sbi_manually_connect_wrap' ).fadeOut();
694
+ $( '#sb_manual_at, .sbi_manual_account_id_toggle input' ).val( '' );
695
+ sbiAfterUpdateToken( savedToken,false );
696
+ }
697
+ } else {
698
+ $('.sbi_manually_connect_wrap').show().prepend('<div class="sbi_user_id_error" style="display:block;">' + savedToken.error_message + '</div>');
 
699
  }
700
+
701
+ }
702
+ }
703
+ );
704
  }
705
 
706
+ }
707
+ );
708
 
709
+ var $sbiClearResizedButton = $( '#sbi_reset_resized' );
 
 
710
 
711
+ $sbiClearResizedButton.on(
712
+ 'click',
713
+ function(event) {
714
  event.preventDefault();
715
 
716
+ jQuery( '#sbi-clear-cache-success' ).remove();
717
+ jQuery( this ).prop( "disabled",true );
718
 
719
+ $.ajax(
720
+ {
721
  url : sbiA.ajax_url,
722
  type : 'post',
723
  data : {
724
+ action : 'sbi_reset_resized',
725
+ sbi_nonce: sbiA.sbi_nonce
726
  },
727
  success : function(data) {
728
+ data = typeof data.data !== 'undefined' ? data.data : data;
729
+ $sbiClearResizedButton.prop( 'disabled',false );
730
+ if (data == '1') {
731
+ $sbiClearResizedButton.after( '<i id="sbi-clear-cache-success" class="fa fa-check-circle sbi-success"></i>' );
732
+ } else {
733
+ $sbiClearResizedButton.after( '<span>error</span>' );
734
+ }
735
  }
736
+ }
737
+ ); // ajax call
738
+ }
739
+ ); // clear_comment_cache click
740
 
741
  //Caching options
742
+ if ( jQuery( '#sbi_caching_type_page' ).is( ':checked' ) ) {
743
+ jQuery( '.sbi-caching-cron-options' ).hide();
744
+ jQuery( '.sbi-caching-page-options' ).show();
745
  } else {
746
+ jQuery( '.sbi-caching-page-options' ).hide();
747
+ jQuery( '.sbi-caching-cron-options' ).show();
748
  }
749
 
750
+ $( 'input[type=radio][name=sbi_caching_type]' ).on(
751
+ 'change',
752
+ function() {
753
  if (this.value == 'page') {
754
+ jQuery( '.sbi-caching-cron-options' ).slideUp();
755
+ jQuery( '.sbi-caching-page-options' ).slideDown();
756
+ } else if (this.value == 'background') {
757
+ jQuery( '.sbi-caching-page-options' ).slideUp();
758
+ jQuery( '.sbi-caching-cron-options' ).slideDown();
759
  }
760
+ }
761
+ );
 
 
 
762
 
763
  //Should we show the caching time settings?
764
+ var sbi_cache_cron_interval = jQuery( '#sbi_cache_cron_interval' ).val(),
765
+ $sbi_caching_time_settings = jQuery( '#sbi-caching-time-settings' );
766
 
767
  //Should we show anything initially?
768
+ if (sbi_cache_cron_interval == '30mins' || sbi_cache_cron_interval == '1hour') {
769
+ $sbi_caching_time_settings.hide();
770
+ }
771
 
772
+ jQuery( '#sbi_cache_cron_interval' ).on(
773
+ 'change',
774
+ function(){
775
+ sbi_cache_cron_interval = jQuery( '#sbi_cache_cron_interval' ).val();
776
 
777
+ if (sbi_cache_cron_interval == '30mins' || sbi_cache_cron_interval == '1hour') {
778
+ $sbi_caching_time_settings.hide();
779
  } else {
780
+ $sbi_caching_time_settings.show();
781
  }
782
+ }
783
+ );
784
+ sbi_cache_cron_interval = jQuery( '#sbi_cache_cron_interval' ).val();
785
 
786
+ if (sbi_cache_cron_interval == '30mins' || sbi_cache_cron_interval == '1hour') {
787
+ $sbi_caching_time_settings.hide();
788
  } else {
789
+ $sbi_caching_time_settings.show();
790
  }
791
 
 
792
  //clear backup caches
793
+ jQuery( '#sbi_clear_backups' ).on(
794
+ 'click',
795
+ function(event) {
796
+ jQuery( '.sbi-success' ).remove();
797
  event.preventDefault();
798
+ jQuery.ajax(
799
+ {
800
  url: sbiA.ajax_url,
801
  type: 'post',
802
  data: {
803
+ action: 'sbi_clear_backups',
804
+ access_token: token,
805
+ sbi_nonce : sbiA.sbi_nonce,
806
+ just_tokens: true
807
  },
808
  success: function (data) {
809
+ jQuery( '#sbi_clear_backups' ).after( '<span class="sbi-success"><i class="fa fa-check-circle"></i></span>' );
810
  }
811
+ }
812
+ );
813
+ }
814
+ );
815
 
816
  //sbi_reset_log
817
+ var $sbiClearLog = $( '#sbi_reset_log' );
818
 
819
+ $sbiClearLog.on(
820
+ 'click',
821
+ function(event) {
822
  event.preventDefault();
823
 
824
+ jQuery( '#sbi-clear-cache-success' ).remove();
825
+ jQuery( this ).prop( "disabled",true );
826
 
827
+ $.ajax(
828
+ {
829
  url : sbiA.ajax_url,
830
  type : 'post',
831
  data : {
832
+ action : 'sbi_reset_log',
833
+ sbi_nonce : sbiA.sbi_nonce,
834
  },
835
  success : function(data) {
836
+ $sbiClearLog.prop( 'disabled',false );
837
+ data = typeof data.data !== 'undefined' ? data.data : data;
838
+ if (data == '1') {
839
+ $sbiClearLog.after( '<i id="sbi-clear-cache-success" class="fa fa-check-circle sbi-success"></i>' );
840
+ } else {
841
+ $sbiClearLog.after( '<span>error</span>' );
842
+ }
843
  }
844
+ }
845
+ ); // ajax call
846
+ }
847
+ ); // clear_comment_cache click
848
+
849
+ $( '.sb-opt-in' ).on(
850
+ 'click',
851
+ function(event) {
852
  event.preventDefault();
853
 
854
+ var $btn = jQuery( this );
855
+ $btn.prop( 'disabled', true ).addClass( 'loading' ).html( '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>' );
856
 
857
+ sbiSubmitOptIn( true );
858
+ }
859
+ ); // clear_comment_cache click
860
 
861
+ jQuery( '#sbi-oembed-disable' ).on(
862
+ 'click',
863
+ function(e) {
864
  e.preventDefault();
865
+ jQuery( this ).addClass( 'loading' ).html( '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>' );
866
+ jQuery.ajax(
867
+ {
868
  url : sbiA.ajax_url,
869
  type: 'post',
870
  data: {
871
+ action : 'sbi_oembed_disable',
872
+ sbi_nonce : sbiA.sbi_nonce,
873
  },
874
  success: function (data) {
875
+ data = typeof data.data !== 'undefined' ? data.data : data;
876
+ jQuery( '#sbi-oembed-disable' ).closest( 'p' ).html( data );
877
  }
878
+ }
879
+ );
880
+ }
881
+ );
882
+
883
+ $( '.sb-no-usage-opt-out' ).on(
884
+ 'click',
885
+ function(event) {
886
  event.preventDefault();
887
 
888
+ var $btn = jQuery( this );
889
+ $btn.prop( 'disabled', true ).addClass( 'loading' ).html( '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>' );
890
 
891
+ sbiSubmitOptIn( false );
892
+ }
893
+ ); // clear_comment_cache click
894
 
895
  function sbiSubmitOptIn(choice) {
896
+ $.ajax(
897
+ {
898
+ url : sbiA.ajax_url,
899
+ type : 'post',
900
+ data : {
901
+ action : 'sbi_usage_opt_in_or_out',
902
+ opted_in: choice,
903
+ sbi_nonce : sbiA.sbi_nonce,
904
+ },
905
+ success : function(data) {
906
+ $( '.sb-no-usage-opt-out' ).closest( '.sbi-admin-notice' ).fadeOut();
907
+ }
908
+ }
909
+ ); // ajax call
910
  }
911
 
912
  //clear platform data
913
+ jQuery( '#sbi_clear_platform_data' ).on(
914
+ 'click',
915
+ function(event) {
916
+ jQuery( '.sbi-success' ).remove();
917
+ var $self = jQuery( this );
918
  event.preventDefault();
919
+ if (window.confirm( "Warning: Clicking this button will permanently delete all Instagram data, including all connected accounts, cached posts, and stored images." )) {
920
+ $self.prop( 'disabled',true );
921
+ jQuery.ajax(
922
+ {
923
+ url: sbiA.ajax_url,
924
+ type: 'post',
925
+ data: {
926
+ action: 'sbi_delete_platform_data',
927
+ sbi_nonce: sbiA.sbi_nonce
928
+ },
929
+ success: function (data) {
930
+ $self.prop( 'disabled',false );
931
 
932
+ jQuery( '#sbi_clear_platform_data' ).after( '<span class="sbi-success"><i class="fa fa-check-circle"></i></span>' );
933
+ }
934
+ }
935
+ );
936
  }
937
 
938
+ }
939
+ );
940
 
941
+ jQuery( 'select[name=sb_instagram_cache_time_unit]' ).on(
942
+ 'change',
943
+ function() {
944
  var newMax = 24;
945
+ if (jQuery( this ).val() === 'minutes') {
946
+ newMax = 1440;
947
  }
948
+ jQuery( 'input[name=sb_instagram_cache_time]' ).prop( 'max', newMax );
949
+ }
950
+ );
951
 
952
  //Tooltips
953
+ jQuery( '#sbi_admin' ).on(
954
+ 'click',
955
+ '.sbi_tooltip_link, .sbi_type_tooltip_link',
956
+ function(){
957
+ if ( jQuery( this ).hasClass( 'sbi_type_tooltip_link' ) ) {
958
+ jQuery( this ).closest( '.sbi_row' ).children( '.sbi_tooltip' ).slideToggle();
959
  } else {
960
+ $el = jQuery( this );
961
+ if ( jQuery( this ).hasClass( 'sbi_tooltip_outside' ) ) {
962
+ $el = jQuery( this ).parent();
963
+ }
964
+ $el.siblings( '.sbi_tooltip' ).slideToggle();
965
  }
966
+ }
967
+ );
968
 
969
  //Shortcode labels
970
+ jQuery( '#sbi_admin label' ).on(
971
+ 'click',
972
+ function(){
973
+ var $sbi_shortcode = jQuery( this ).siblings( '.sbi_shortcode' );
974
+ var $el = jQuery( this ).parent();
975
+
976
+ if ($sbi_shortcode.is( ':visible' )) {
977
+ $el.removeClass( 'sbi_shortcode_visible' );
978
+ $el.find( '.sbi_shortcode' ).css( 'display','none' );
979
  } else {
980
+ $el.addClass( 'sbi_shortcode_visible' );
981
+ $el.find( '.sbi_shortcode' ).css( 'display','block' );
982
  }
983
+ }
984
+ );
985
+
986
+ jQuery( '#sbi_admin label' ).on(
987
+ 'mouseenter mouseleave',
988
+ function(e) {
989
+ switch (e.type) {
990
+ case 'mouseenter':
991
+ if ( jQuery( this ).siblings( '.sbi_shortcode' ).length > 0 ) {
992
+ jQuery( this ).attr( 'title', 'Click for shortcode option' ).append( '<code class="sbi_shortcode_symbol">[]</code>' );
993
+ }
994
+ break;
995
+ case 'mouseleave':
996
+ jQuery( this ).find( '.sbi_shortcode_symbol' ).remove();
997
+ break;
998
  }
999
+ }
1000
+ );
1001
+
1002
+ jQuery( '#sbi_admin .sbi_lock' ).on(
1003
+ 'mouseenter mouseleave',
1004
+ function(e) {
1005
+ switch (e.type) {
1006
+ case 'mouseenter':
1007
+ jQuery( this ).siblings( '.sbi_pro_tooltip' ).show();
1008
+ break;
1009
+ case 'mouseleave':
1010
+ jQuery( '.sbi_pro_tooltip' ).hide();
1011
+ break;
1012
  }
1013
+ }
1014
+ );
1015
+
1016
  //Add the color picker
1017
+ if ( jQuery( '.sbi_colorpick' ).length > 0 ) {
1018
+ jQuery( '.sbi_colorpick' ).wpColorPicker();
1019
+ }
1020
 
1021
  //Check User ID is numeric
1022
+ jQuery( "#sb_instagram_user_id" ).on(
1023
+ 'change',
1024
+ function() {
1025
 
1026
+ var sbi_user_id = jQuery( '#sb_instagram_user_id' ).val(),
1027
+ $sbi_user_id_error = $( this ).closest( 'td' ).find( '.sbi_user_id_error' ),
1028
+ $sbi_other_user_error = $( this ).closest( 'td' ).find( '.sbi_other_user_error' );
1029
 
1030
+ if (sbi_user_id.match( /[^0-9, _.-]/ )) {
1031
+ $sbi_user_id_error.fadeIn();
1032
  } else {
1033
+ $sbi_user_id_error.fadeOut();
1034
  }
1035
 
1036
  //Check whether an ID from another account is being used
1037
+ sbi_check_other_user_id( sbi_user_id, $sbi_other_user_error );
1038
 
1039
+ }
1040
+ );
1041
  function sbi_check_other_user_id(sbi_user_id, $sbi_other_user_error){
1042
+ if (jQuery( '#sb_instagram_at' ).length && jQuery( '#sb_instagram_at' ).val() !== '' && sbi_user_id.length) {
1043
+ if (jQuery( '#sb_instagram_at' ).val().indexOf( sbi_user_id ) == -1 ) {
1044
+ $sbi_other_user_error.fadeIn();
1045
+ } else {
1046
+ $sbi_other_user_error.fadeOut();
 
1047
  }
1048
+ }
1049
  }
1050
  //Check initially when settings load
1051
+ sbi_check_other_user_id( jQuery( '#sb_instagram_user_id' ).val(), $( 'td' ).find( '.sbi_other_user_error' ) );
1052
 
1053
  //Mobile width
1054
+ var sb_instagram_feed_width = jQuery( '#sbi_admin #sb_instagram_width' ).val(),
1055
+ sb_instagram_width_unit = jQuery( '#sbi_admin #sb_instagram_width_unit' ).val(),
1056
+ $sb_instagram_width_options = jQuery( '#sbi_admin #sb_instagram_width_options' );
1057
 
1058
  if (typeof sb_instagram_feed_width !== 'undefined') {
1059
 
1060
+ //Show initially if a width is set
1061
+ if ( (sb_instagram_feed_width.length > 1 && sb_instagram_width_unit == 'px') || (sb_instagram_feed_width !== '100' && sb_instagram_width_unit == '%') ) {
1062
+ $sb_instagram_width_options.show();
1063
+ }
1064
+
1065
+ jQuery( '#sbi_admin #sb_instagram_width, #sbi_admin #sb_instagram_width_unit' ).on(
1066
+ 'change',
1067
+ function(){
1068
+ sb_instagram_feed_width = jQuery( '#sbi_admin #sb_instagram_width' ).val();
1069
+ sb_instagram_width_unit = jQuery( '#sbi_admin #sb_instagram_width_unit' ).val();
1070
+
1071
+ if ( sb_instagram_feed_width.length < 2 || (sb_instagram_feed_width == '100' && sb_instagram_width_unit == '%') ) {
1072
+ $sb_instagram_width_options.slideUp();
1073
+ } else {
1074
+ $sb_instagram_width_options.slideDown();
1075
+ }
1076
+ }
1077
+ );
1078
 
1079
  }
1080
 
1081
  //Scroll to hash for quick links
1082
+ jQuery( '#sbi_admin a' ).on(
1083
+ 'click',
1084
+ function() {
1085
+ if (location.pathname.replace( /^\//,'' ) == this.pathname.replace( /^\//,'' ) && location.hostname == this.hostname) {
1086
+ var target = jQuery( this.hash );
1087
+ target = target.length ? target : this.hash.slice( 1 );
1088
+ if (target.length) {
1089
+ jQuery( 'html,body' ).animate(
1090
+ {
1091
+ scrollTop: target.offset().top
1092
+ },
1093
+ 500
1094
+ );
1095
+ return false;
1096
+ }
1097
  }
1098
+ }
1099
+ );
1100
 
1101
  //Support tab show video
1102
+ jQuery( '#sbi-play-support-video' ).on(
1103
+ 'click',
1104
+ function(e){
1105
  e.preventDefault();
1106
+ jQuery( '#sbi-support-video' ).show().attr( 'src', jQuery( '#sbi-support-video' ).attr( 'src' ) + '&amp;autoplay=1' );
1107
+ }
1108
+ );
1109
 
1110
+ jQuery( '#sbi_admin .sbi-show-pro' ).on(
1111
+ 'click',
1112
+ function(){
1113
+ jQuery( this ).parent().next( '.sbi-pro-options' ).toggle();
1114
+ }
1115
+ );
1116
 
1117
  /* Pro 3.0 JS */
1118
  function sbiUpdateLayoutTypeOptionsDisplay() {
1119
+ setTimeout(
1120
+ function(){
1121
+ jQuery( '.sb_instagram_layout_settings' ).hide();
1122
+ jQuery( '.sb_instagram_layout_settings.sbi_layout_type_' + jQuery( '.sb_layout_type:checked' ).val() ).show();
1123
+ },
1124
+ 1
1125
+ );
1126
  }
1127
+ jQuery( '.sb_layout_type' ).on( 'change',sbiUpdateLayoutTypeOptionsDisplay );
1128
 
1129
+ jQuery( '.sbi_close_options' ).on(
1130
+ 'click',
1131
+ function(){
1132
+ jQuery( '.sb_instagram_layout_settings' ).hide();
1133
+ }
1134
+ );
1135
 
1136
  function sbiUpdateHighlightOptionsDisplay() {
1137
+ jQuery( '.sb_instagram_highlight_sub_options' ).hide();
1138
+ var selected = jQuery( '#sb_instagram_highlight_type' ).val();
1139
 
1140
+ if (selected === 'pattern') {
1141
+ jQuery( '.sb_instagram_highlight_pattern' ).show();
1142
+ } else if (selected === 'id') {
1143
+ jQuery( '.sb_instagram_highlight_ids' ).show();
1144
+ } else {
1145
+ jQuery( '.sb_instagram_highlight_hashtag' ).show();
1146
+ }
1147
 
1148
  }
1149
  sbiUpdateHighlightOptionsDisplay();
1150
+ jQuery( '#sb_instagram_highlight_type' ).on( 'change',sbiUpdateHighlightOptionsDisplay );
1151
 
1152
  //sb_instagram_enable_email_report
1153
  function sbiToggleEmail() {
1154
+ if (jQuery( '#sb_instagram_enable_email_report' ).is( ':checked' )) {
1155
+ jQuery( '#sb_instagram_enable_email_report' ).closest( 'td' ).find( '.sb_instagram_box' ).slideDown();
1156
+ } else {
1157
+ jQuery( '#sb_instagram_enable_email_report' ).closest( 'td' ).find( '.sb_instagram_box' ).slideUp();
1158
+ }
1159
  }sbiToggleEmail();
1160
+ jQuery( '#sb_instagram_enable_email_report' ).on( 'change',sbiToggleEmail );
1161
+ if (jQuery( '#sbi-goto' ).length) {
1162
+ jQuery( '#sbi-goto' ).closest( 'tr' ).addClass( 'sbi-goto' );
1163
+ $( 'html, body' ).animate(
1164
+ {
1165
+ scrollTop: $( '#sbi-goto' ).offset().top - 200
1166
+ },
1167
+ 500
1168
+ );
1169
  }
1170
 
1171
  //Open/close the expandable option sections
1172
+ jQuery( '.sbi-expandable-options' ).hide();
1173
+ jQuery( '.sbi-expand-button a' ).on(
1174
+ 'click',
1175
+ function(e){
1176
  e.preventDefault();
1177
+ var $self = jQuery( this );
1178
+ $self.parent().next( '.sbi-expandable-options' ).toggle();
1179
+ if ( $self.text().indexOf( 'Show' ) !== -1 ) {
1180
+ $self.text( $self.text().replace( 'Show', 'Hide' ) );
1181
  } else {
1182
+ $self.text( $self.text().replace( 'Hide', 'Show' ) );
1183
  }
1184
+ }
1185
+ );
1186
 
1187
  //Selecting a post layout
1188
+ jQuery( '.sbi_layout_cell' ).on(
1189
+ 'click',
1190
+ function(){
1191
+ var $self = jQuery( this );
1192
+ $( '.sb_layout_type' ).trigger( 'change' );
1193
+ $self.addClass( 'sbi_layout_selected' ).find( '.sb_layout_type' ).prop( 'checked',true );
1194
+ $self.siblings().removeClass( 'sbi_layout_selected' );
1195
+ }
1196
+ );
1197
+
1198
+ setTimeout(
1199
+ function() {
1200
+ jQuery( '.notice-dismiss' ).on(
1201
+ 'click',
1202
+ function() {
1203
+ if (jQuery( this ).closest( '.sbi-admin-notice' ).length) {
1204
+
1205
+ if (jQuery( this ).closest( '.sbi-admin-notice' ).find( '.sbi-admin-error' ).length) {
1206
+
1207
+ var exemptErrorType = jQuery( this ).closest( '.sbi-admin-notice' ).find( '.sbi-admin-error' ).attr( 'data-sbi-type' );
1208
+
1209
+ if (exemptErrorType === 'ajax') {
1210
+ jQuery.ajax(
1211
+ {
1212
+ url: sbiA.ajax_url,
1213
+ type: 'post',
1214
+ data: {
1215
+ action : 'sbi_on_ajax_test_trigger',
1216
+ sbi_nonce: sbiA.sbi_nonce
1217
+ },
1218
+ success: function (data) {
1219
+ }
1220
  }
1221
+ );
1222
  }
1223
+ }
1224
  }
1225
+ }
1226
+ );
1227
+ },
1228
+ 1500
1229
+ );
1230
 
1231
  //Load the admin share widgets
1232
+ jQuery( '#sbi_admin_show_share_links' ).on(
1233
+ 'click',
1234
+ function(){
1235
+ jQuery( this ).fadeOut();
1236
+ if ( jQuery( '#sbi_admin_share_links iframe' ).length == 0 ) {
1237
+ jQuery( '#sbi_admin_share_links' ).html( '<a href="https://twitter.com/share" class="twitter-share-button" data-url="https://wordpress.org/plugins/instagram-feed/" data-text="Display beautifully clean, customizable, and responsive Instagram feeds from multiple accounts" data-via="smashballoon" data-dnt="true">Tweet</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?"http":"https";if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document, "script", "twitter-wjs");</script> <style type="text/css"> #twitter-widget-0{float: left; width: 82px !important;}.IN-widget{margin-right: 20px;}</style> <div id="fb-root" style="display: none;"></div><script>(function(d, s, id){var js, fjs=d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js=d.createElement(s); js.id=id; js.src="//connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v2.0"; fjs.parentNode.insertBefore(js, fjs);}(document, "script", "facebook-jssdk"));</script> <div class="fb-like" data-href="https://wordpress.org/plugins/instagram-feed/" data-layout="button_count" data-action="like" data-show-faces="false" data-share="true" style="display: block; float: left; margin-right: 5px;"></div><script src="//platform.linkedin.com/in.js" type="text/javascript"> lang: en_US </script> <script type="IN/Share" data-url="https://wordpress.org/plugins/instagram-feed/"></script></div>' );
1238
+ }
1239
 
1240
+ setTimeout(
1241
+ function(){
1242
+ jQuery( '#sbi_admin_share_links' ).addClass( 'sbi_show' );
1243
+ },
1244
+ 500
1245
+ );
1246
+ }
1247
+ );
1248
 
1249
  // notices
1250
 
1251
+ if (jQuery( '#sbi-notice-bar' ).length) {
1252
+ jQuery( '#wpadminbar' ).after( jQuery( '#sbi-notice-bar' ) );
1253
+ jQuery( '#wpcontent' ).css( 'padding-left', 0 );
1254
+ jQuery( '#wpbody' ).css( 'padding-left', '20px' );
1255
+ jQuery( '#sbi-notice-bar' ).show();
1256
  }
1257
 
1258
+ jQuery( '#sbi-notice-bar .dismiss' ).on(
1259
+ 'click',
1260
+ function(e) {
1261
  e.preventDefault();
1262
+ jQuery( '#sbi-notice-bar' ).remove();
1263
+ jQuery.ajax(
1264
+ {
1265
  url: sbiA.ajax_url,
1266
  type: 'post',
1267
  data: {
1268
+ action : 'sbi_lite_dismiss',
1269
+ sbi_nonce: sbiA.sbi_nonce
1270
  },
1271
  success: function (data) {
1272
  }
1273
+ }
1274
+ );
1275
+ }
1276
+ );
1277
  /* removing padding */
1278
+ if (jQuery( '#sbi-admin-about' ).length && ! jQuery( '.sbi_more_plugins' ).length) {
1279
+ jQuery( '#wpcontent' ).css( 'padding', 0 );
1280
  }
1281
 
1282
  /* Clear errors visit page */
1283
+ jQuery( '.sbi-error-directions a' ).addClass( 'button button-primary' );
1284
+ jQuery( '.sbi-error-directions.sbi-reconnect a' ).on(
1285
+ 'click',
1286
+ function(){
1287
  event.preventDefault();
1288
+ jQuery( '.sbi_admin_btn' ).trigger( 'click' );
1289
+ }
1290
+ );
1291
+ jQuery( '.sbi-clear-errors-visit-page' ).appendTo( '.sbi-error-directions' );
1292
+ jQuery( '.sbi-clear-errors-visit-page' ).on(
1293
+ 'click',
1294
+ function(event) {
1295
  event.preventDefault();
1296
+ var $btn = jQuery( this );
1297
+ $btn.prop( 'disabled', true ).addClass( 'loading' ).html( '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>' );
1298
+ $.ajax(
1299
+ {
1300
  url : sbiA.ajax_url,
1301
  type : 'post',
1302
  data : {
1303
+ action : 'sbi_reset_log',
1304
+ sbi_nonce: sbiA.sbi_nonce
1305
  },
1306
  success : function(data) {
1307
+ window.location.href = $btn.attr( 'href' );
1308
  },
1309
  error : function(data) {
1310
+ window.location.href = $btn.attr( 'href' );
1311
  }
1312
+ }
1313
+ ); // ajax call
1314
+ }
1315
+ )
1316
 
1317
  //Click event for other plugins in menu
1318
+ $( '.sbi_get_cff, .sbi_get_sbi, .sbi_get_ctf, .sbi_get_yt' ).parent().on(
1319
+ 'click',
1320
+ function(e){
1321
  e.preventDefault();
1322
 
1323
+ jQuery( '.sb_cross_install_modal' ).remove();
1324
 
1325
+ $( '#wpbody-content' ).prepend( '<div class="sb_cross_install_modal"><div class="sb_cross_install_inner" id="sbi-admin-about"><div id="sbi-admin-addons"><div class="addons-container"><i class="fa fa-spinner fa-spin sbi-loader" aria-hidden="true"></i></div></div></div></div>' );
1326
 
1327
+ var $self = $( this ).find( 'span' ),
1328
+ sb_get_plugin = 'custom_twitter_feeds';
1329
 
1330
+ if ( $self.hasClass( 'sbi_get_cff' ) ) {
1331
+ sb_get_plugin = 'custom_facebook_feed';
1332
+ } else if ( $self.hasClass( 'sbi_get_sbi' ) ) {
1333
+ sb_get_plugin = 'instagram_feed';
1334
+ } else if ( $self.hasClass( 'sbi_get_yt' ) ) {
1335
+ sb_get_plugin = 'feeds_for_youtube';
1336
  }
1337
 
1338
+ $get_plugins_url = sbiA.ajax_url.replace( 'admin-ajax.php', '' );
1339
 
1340
  //Get the quick install box from the about page
1341
+ $( '.sb_cross_install_modal .addons-container' ).load( $get_plugins_url + 'admin.php?page=sb-instagram-feed&tab=more #install_' + sb_get_plugin );
1342
+ }
1343
+ );
1344
 
1345
  //Add class to Pro menu item
1346
+ $( '.sbi_get_pro' ).parent().attr( {'class':'sbi_get_pro_highlight', 'target':'_blank'} );
1347
 
1348
+ jQuery( '.sbi-need-to-connect' ).on(
1349
+ 'click',
1350
+ function(e) {
1351
  e.preventDefault();
1352