Instagram Feed - Version 2.5.1

Version Description

  • Tweak: Minor update to footer.php template.
  • Tweak: Added support for improved notices on the plugin settings page.
  • Fix: Added aria-hidden="true" attribute to loader icon for better accessibility.
Download this release

Release Info

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

Code changes from version 2.5 to 2.5.1

README.txt CHANGED
@@ -2,8 +2,8 @@
2
  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.5
6
- Stable tag: 2.5
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.5 =
335
  * New: Added support for Instagram oEmbeds. When you share a link to a Instagram post, WordPress automatically converts it into an embedded Instagram post for you (an "oEmbed"). However, on October 24, 2020, WordPress is discontinuing support for Instagram oEmbeds and so any existing or new embeds will no longer work. Don't worry though, we have your back! This update adds support for Instagram oEmbeds and so, after updating, the Instagram Feed plugin will automatically keep your oEmbeds working. It will also power any new oEmbeds you post going forward.
336
  * New: Install our other free social media plugins right from the Instagram Feed settings menu. Use our Facebook, YouTube, and Twitter plugins to add even more social content to your website and help further engage your viewers and increase your followers.
2
  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.5.1
6
+ Stable tag: 2.5.1
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.5.1 =
335
+ * Tweak: Minor update to footer.php template.
336
+ * Tweak: Added support for improved notices on the plugin settings page.
337
+ * Fix: Added aria-hidden="true" attribute to loader icon for better accessibility.
338
+
339
  = 2.5 =
340
  * New: Added support for Instagram oEmbeds. When you share a link to a Instagram post, WordPress automatically converts it into an embedded Instagram post for you (an "oEmbed"). However, on October 24, 2020, WordPress is discontinuing support for Instagram oEmbeds and so any existing or new embeds will no longer work. Don't worry though, we have your back! This update adds support for Instagram oEmbeds and so, after updating, the Instagram Feed plugin will automatically keep your oEmbeds working. It will also power any new oEmbeds you post going forward.
341
  * New: Install our other free social media plugins right from the Instagram Feed settings menu. Use our Facebook, YouTube, and Twitter plugins to add even more social content to your website and help further engage your viewers and increase your followers.
css/admin-notifications.css ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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;
8
+ padding: 15px 102px 15px 72px;
9
+ margin: 0 0 14px 0;
10
+ }
11
+
12
+ #sbi-notifications * {
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ #sbi-notifications .bell,
17
+ #sbi-notifications .thumb{
18
+ position: absolute;
19
+ top: 15px;
20
+ left: 15px;
21
+ width: 42px;
22
+ height: 48px;
23
+ }
24
+ #sbi-notifications .thumb img {
25
+ max-width: 100%;
26
+ }
27
+ #sbi-notifications .thumb .img-overlay {
28
+ top: 42px;
29
+ left: -6px;
30
+ width: 54px;
31
+ position: absolute;
32
+ background: #ca4a1f;
33
+ color: #fff;
34
+ padding: 2px 4px;
35
+ border-radius: 3px;
36
+ line-height: 1;
37
+ font-size: 11px;
38
+ font-weight: bold;
39
+ text-align: center;
40
+ }
41
+
42
+ #sbi-notifications .messages .message {
43
+ display: none;
44
+ }
45
+
46
+ #sbi-notifications .messages .message.current {
47
+ display: block;
48
+ }
49
+
50
+ #sbi-notifications .messages .message .title {
51
+ font-weight: bold;
52
+ font-size: 17px;
53
+ line-height: 20px;
54
+ margin: 0;
55
+ padding: 0;
56
+ color: #444;
57
+ }
58
+
59
+ #sbi-notifications .messages .message .content {
60
+ font-weight: normal;
61
+ font-size: 13px;
62
+ line-height: 20px;
63
+ margin: 6px 0 40px 0;
64
+ }
65
+
66
+ #sbi-notifications .messages .message .buttons {
67
+ margin: -30px 80px 0 0;
68
+ }
69
+
70
+ #sbi-notifications .messages .message .buttons a {
71
+ margin: 0 6px 0 0;
72
+ padding: 8px 10px;
73
+ line-height: 13px;
74
+ font-size: 13px;
75
+ min-height: unset;
76
+ }
77
+
78
+ #sbi-notifications .messages .message .buttons .button-secondary {
79
+ border: 1px solid #0071A1;
80
+ }
81
+
82
+ #sbi-notifications .dismiss {
83
+ position: absolute;
84
+ top: 15px;
85
+ right: 15px;
86
+ width: 16px;
87
+ height: 16px;
88
+ color: #72777C;
89
+ font-size: 16px;
90
+ cursor: pointer;
91
+ text-align: center;
92
+ vertical-align: middle;
93
+ line-height: 16px;
94
+ }
95
+
96
+ #sbi-notifications .dismiss:hover {
97
+ color: #dc3232;
98
+ }
99
+
100
+ #sbi-notifications .navigation {
101
+ position: absolute;
102
+ bottom: 15px;
103
+ right: 15px;
104
+ width: 63px;
105
+ height: 30px;
106
+ }
107
+
108
+ #sbi-notifications .navigation a {
109
+ display: block;
110
+ width: 30px;
111
+ height: 30px;
112
+ border: 1px solid #7E8993;
113
+ border-radius: 3px;
114
+ font-size: 8px;
115
+ text-align: center;
116
+ vertical-align: middle;
117
+ line-height: 30px;
118
+ cursor: pointer;
119
+ background-color: #ffffff;
120
+ color: #41454A;
121
+ }
122
+ #sbi-notifications .navigation svg {
123
+ width: 8px;
124
+ height: 8px;
125
+ }
126
+
127
+ #sbi-notifications .navigation a:hover {
128
+ background-color: #f1f1f1;
129
+ }
130
+
131
+ #sbi-notifications .navigation .prev {
132
+ float: left;
133
+ }
134
+
135
+ #sbi-notifications .navigation .next {
136
+ float: right;
137
+ }
138
+
139
+ #sbi-notifications .navigation .disabled {
140
+ border-color: #dddddd;
141
+ color: #A0A5AA;
142
+ cursor: default;
143
+ }
144
+
145
+ #sbi-notifications .navigation .disabled:hover {
146
+ background-color: #ffffff;
147
+ }
148
+
149
+ @media screen and (max-width: 768px) {
150
+ #sbi-notifications {
151
+ padding: 15px 15px 15px 72px;
152
+ }
153
+ #sbi-notifications .messages .message .title {
154
+ margin: 0 30px 0 0;
155
+ }
156
+ #sbi-notifications .messages .message .content {
157
+ font-size: 16px;
158
+ line-height: 24px;
159
+ }
160
+ #sbi-notifications .messages .message .buttons {
161
+ margin: -30px 80px 0 0;
162
+ }
163
+ #sbi-notifications .messages .message .buttons a {
164
+ margin: 0;
165
+ display: table;
166
+ }
167
+ #sbi-notifications .messages .message .buttons .button-secondary {
168
+ margin-top: 6px;
169
+ }
170
+ }
171
+
172
+ /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2Nzcy9hZG1pbi1ub3RpZmljYXRpb25zLmNzcyIsInNvdXJjZXMiOlsiYXNzZXRzL3Njc3MvYWRtaW4tbm90aWZpY2F0aW9ucy5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEFkbWluIG5vdGlmaWNhdGlvbiBzdHlsZXMuXG5cbiN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXG5cdHBvc2l0aW9uOiByZWxhdGl2ZTtcblx0YmFja2dyb3VuZDogI0ZGRkZGRiAwIDAgbm8tcmVwZWF0IHBhZGRpbmctYm94O1xuXHRib3gtc2hhZG93OiAwcHggNXB4IDE1cHggIzAwMDAwMDBEO1xuXHRib3JkZXItcmFkaXVzOiA2cHg7XG5cdG9wYWNpdHk6IDE7XG5cdG1pbi1oZWlnaHQ6IDQ4cHg7XG5cdHBhZGRpbmc6IDE1cHggMTAycHggMTVweCA3MnB4O1xuXHRtYXJnaW46IDAgMCAxNHB4IDA7XG5cblx0KiB7XG5cdFx0Ym94LXNpemluZzogYm9yZGVyLWJveDtcblx0fVxuXG5cdC5iZWxsIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdGxlZnQ6IDE1cHg7XG5cdFx0d2lkdGg6IDQycHg7XG5cdFx0aGVpZ2h0OiA0OHB4O1xuXHR9XG5cblx0Lm1lc3NhZ2VzIHtcblx0XHQubWVzc2FnZSB7XG5cdFx0XHRkaXNwbGF5OiBub25lO1xuXG5cdFx0XHQmLmN1cnJlbnQge1xuXHRcdFx0XHRkaXNwbGF5OiBibG9jaztcblx0XHRcdH1cblxuXHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IGJvbGQ7XG5cdFx0XHRcdGZvbnQtc2l6ZTogMTdweDtcblx0XHRcdFx0bGluZS1oZWlnaHQ6IDIwcHg7XG5cdFx0XHRcdG1hcmdpbjogMDtcblx0XHRcdFx0Y29sb3I6ICM0NDQ7XG5cdFx0XHR9XG5cblx0XHRcdC5jb250ZW50IHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IG5vcm1hbDtcblx0XHRcdFx0Zm9udC1zaXplOiAxM3B4O1xuXHRcdFx0XHRsaW5lLWhlaWdodDogMjBweDtcblx0XHRcdFx0bWFyZ2luOiA2cHggMCA0MHB4IDA7XG5cdFx0XHR9XG5cblx0XHRcdC5idXR0b25zIHtcblx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRhIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgNnB4IDAgMDtcblx0XHRcdFx0XHRwYWRkaW5nOiA4cHggMTBweDtcblx0XHRcdFx0XHRsaW5lLWhlaWdodDogMTNweDtcblx0XHRcdFx0XHRmb250LXNpemU6IDEzcHg7XG5cdFx0XHRcdFx0bWluLWhlaWdodDogdW5zZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9uLXNlY29uZGFyeSB7XG5cdFx0XHRcdFx0Ym9yZGVyOiAxcHggc29saWQgIzAwNzFBMTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC5kaXNtaXNzIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdHJpZ2h0OiAxNXB4O1xuXHRcdHdpZHRoOiAxNnB4O1xuXHRcdGhlaWdodDogMTZweDtcblx0XHRjb2xvcjogIzcyNzc3Qztcblx0XHRmb250LXNpemU6IDE2cHg7XG5cdFx0Y3Vyc29yOiBwb2ludGVyO1xuXHRcdHRleHQtYWxpZ246IGNlbnRlcjtcblx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdGxpbmUtaGVpZ2h0OiAxNnB4O1xuXG5cdFx0Jjpob3ZlciB7XG5cdFx0XHRjb2xvcjogI2RjMzIzMjtcblx0XHR9XG5cdH1cblxuXHQubmF2aWdhdGlvbiB7XG5cdFx0cG9zaXRpb246IGFic29sdXRlO1xuXHRcdGJvdHRvbTogMTVweDtcblx0XHRyaWdodDogMTVweDtcblx0XHR3aWR0aDogNjNweDtcblx0XHRoZWlnaHQ6IDMwcHg7XG5cblx0XHRhIHtcblx0XHRcdGRpc3BsYXk6IGJsb2NrO1xuXHRcdFx0d2lkdGg6IDMwcHg7XG5cdFx0XHRoZWlnaHQ6IDMwcHg7XG5cdFx0XHRib3JkZXI6IDFweCBzb2xpZCAjN0U4OTkzO1xuXHRcdFx0Ym9yZGVyLXJhZGl1czogM3B4O1xuXHRcdFx0Zm9udC1zaXplOiA4cHg7XG5cdFx0XHR0ZXh0LWFsaWduOiBjZW50ZXI7XG5cdFx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdFx0bGluZS1oZWlnaHQ6IDMwcHg7XG5cdFx0XHRjdXJzb3I6IHBvaW50ZXI7XG5cdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0Y29sb3I6ICM0MTQ1NEE7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZjFmMWYxO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC5wcmV2IHtcblx0XHRcdGZsb2F0OiBsZWZ0O1xuXHRcdH1cblxuXHRcdC5uZXh0IHtcblx0XHRcdGZsb2F0OiByaWdodDtcblx0XHR9XG5cblx0XHQuZGlzYWJsZWQge1xuXHRcdFx0Ym9yZGVyLWNvbG9yOiAjZGRkZGRkO1xuXHRcdFx0Y29sb3I6ICNBMEE1QUE7XG5cdFx0XHRjdXJzb3I6IGRlZmF1bHQ7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3NjhweCkge1xuXG5cdCN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXHRcdHBhZGRpbmc6IDE1cHggMTVweCAxNXB4IDcycHg7XG5cblx0XHQubWVzc2FnZXMge1xuXG5cdFx0XHQubWVzc2FnZSB7XG5cblx0XHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgMzBweCAwIDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuY29udGVudCB7XG5cdFx0XHRcdFx0Zm9udC1zaXplOiAxNnB4O1xuXHRcdFx0XHRcdGxpbmUtaGVpZ2h0OiAyNHB4XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9ucyB7XG5cdFx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRcdGEge1xuXHRcdFx0XHRcdFx0bWFyZ2luOiAwO1xuXHRcdFx0XHRcdFx0ZGlzcGxheTogdGFibGU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0LmJ1dHRvbi1zZWNvbmRhcnkge1xuXHRcdFx0XHRcdFx0bWFyZ2luLXRvcDogNnB4O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxBQUFBLHNCQUFzQixDQUFDO0VBRXRCLFFBQVEsRUFBRSxRQUFRO0VBQ2xCLFVBQVUsRUFBRSxpQ0FBaUM7RUFDN0MsVUFBVSxFQUFFLHNCQUFzQjtFQUNsQyxhQUFhLEVBQUUsR0FBRztFQUNsQixPQUFPLEVBQUUsQ0FBQztFQUNWLFVBQVUsRUFBRSxJQUFJO0VBQ2hCLE9BQU8sRUFBRSxvQkFBb0I7RUFDN0IsTUFBTSxFQUFFLFVBQVU7Q0FxSGxCOztBQTlIRCxBQVdDLHNCQVhxQixDQVdyQixDQUFDLENBQUM7RUFDRCxVQUFVLEVBQUUsVUFBVTtDQUN0Qjs7QUFiRixBQWVDLHNCQWZxQixDQWVyQixLQUFLLENBQUM7RUFDTCxRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULElBQUksRUFBRSxJQUFJO0VBQ1YsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtDQUNaOztBQXJCRixBQXdCRSxzQkF4Qm9CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQUFDO0VBQ1IsT0FBTyxFQUFFLElBQUk7Q0FvQ2I7O0FBN0RILEFBMkJHLHNCQTNCbUIsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLEFBR04sUUFBUSxDQUFDO0VBQ1QsT0FBTyxFQUFFLEtBQUs7Q0FDZDs7QUE3QkosQUErQkcsc0JBL0JtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FPUCxNQUFNLENBQUM7RUFDTixXQUFXLEVBQUUsSUFBSTtFQUNqQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxDQUFDO0VBQ1QsS0FBSyxFQUFFLElBQUk7Q0FDWDs7QUFyQ0osQUF1Q0csc0JBdkNtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FlUCxRQUFRLENBQUM7RUFDUixXQUFXLEVBQUUsTUFBTTtFQUNuQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxZQUFZO0NBQ3BCOztBQTVDSixBQThDRyxzQkE5Q21CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQXNCUCxRQUFRLENBQUM7RUFDUixNQUFNLEVBQUUsY0FBYztDQWF0Qjs7QUE1REosQUFpREksc0JBakRrQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FzQlAsUUFBUSxDQUdQLENBQUMsQ0FBQztFQUNELE1BQU0sRUFBRSxTQUFTO0VBQ2pCLE9BQU8sRUFBRSxRQUFRO0VBQ2pCLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLFNBQVMsRUFBRSxJQUFJO0VBQ2YsVUFBVSxFQUFFLEtBQUs7Q0FDakI7O0FBdkRMLEFBeURJLHNCQXpEa0IsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLENBc0JQLFFBQVEsQ0FXUCxpQkFBaUIsQ0FBQztFQUNqQixNQUFNLEVBQUUsaUJBQWlCO0NBQ3pCOztBQTNETCxBQWdFQyxzQkFoRXFCLENBZ0VyQixRQUFRLENBQUM7RUFDUixRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULEtBQUssRUFBRSxJQUFJO0VBQ1gsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtFQUNaLEtBQUssRUFBRSxPQUFPO0VBQ2QsU0FBUyxFQUFFLElBQUk7RUFDZixNQUFNLEVBQUUsT0FBTztFQUNmLFVBQVUsRUFBRSxNQUFNO0VBQ2xCLGNBQWMsRUFBRSxNQUFNO0VBQ3RCLFdBQVcsRUFBRSxJQUFJO0NBS2pCOztBQWhGRixBQTZFRSxzQkE3RW9CLENBZ0VyQixRQUFRLEFBYU4sTUFBTSxDQUFDO0VBQ1AsS0FBSyxFQUFFLE9BQU87Q0FDZDs7QUEvRUgsQUFrRkMsc0JBbEZxQixDQWtGckIsV0FBVyxDQUFDO0VBQ1gsUUFBUSxFQUFFLFFBQVE7RUFDbEIsTUFBTSxFQUFFLElBQUk7RUFDWixLQUFLLEVBQUUsSUFBSTtFQUNYLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7Q0FzQ1o7O0FBN0hGLEFBeUZFLHNCQXpGb0IsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLENBQUM7RUFDRCxPQUFPLEVBQUUsS0FBSztFQUNkLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7RUFDWixNQUFNLEVBQUUsaUJBQWlCO0VBQ3pCLGFBQWEsRUFBRSxHQUFHO0VBQ2xCLFNBQVMsRUFBRSxHQUFHO0VBQ2QsVUFBVSxFQUFFLE1BQU07RUFDbEIsY0FBYyxFQUFFLE1BQU07RUFDdEIsV0FBVyxFQUFFLElBQUk7RUFDakIsTUFBTSxFQUFFLE9BQU87RUFDZixnQkFBZ0IsRUFBRSxPQUFPO0VBQ3pCLEtBQUssRUFBRSxPQUFPO0NBS2Q7O0FBMUdILEFBdUdHLHNCQXZHbUIsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLEFBY0MsTUFBTSxDQUFDO0VBQ1AsZ0JBQWdCLEVBQUUsT0FBTztDQUN6Qjs7QUF6R0osQUE0R0Usc0JBNUdvQixDQWtGckIsV0FBVyxDQTBCVixLQUFLLENBQUM7RUFDTCxLQUFLLEVBQUUsSUFBSTtDQUNYOztBQTlHSCxBQWdIRSxzQkFoSG9CLENBa0ZyQixXQUFXLENBOEJWLEtBQUssQ0FBQztFQUNMLEtBQUssRUFBRSxLQUFLO0NBQ1o7O0FBbEhILEFBb0hFLHNCQXBIb0IsQ0FrRnJCLFdBQVcsQ0FrQ1YsU0FBUyxDQUFDO0VBQ1QsWUFBWSxFQUFFLE9BQU87RUFDckIsS0FBSyxFQUFFLE9BQU87RUFDZCxNQUFNLEVBQUUsT0FBTztDQUtmOztBQTVISCxBQXlIRyxzQkF6SG1CLENBa0ZyQixXQUFXLENBa0NWLFNBQVMsQUFLUCxNQUFNLENBQUM7RUFDUCxnQkFBZ0IsRUFBRSxPQUFPO0NBQ3pCOztBQUtKLE1BQU0sQ0FBQyxNQUFNLE1BQU0sU0FBUyxFQUFFLEtBQUs7RUFFbEMsQUFBQSxzQkFBc0IsQ0FBQztJQUN0QixPQUFPLEVBQUUsbUJBQW1CO0dBNkI1QjtFQTlCRCxBQU9HLHNCQVBtQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQUVQLE1BQU0sQ0FBQztJQUNOLE1BQU0sRUFBRSxVQUFVO0dBQ2xCO0VBVEosQUFXRyxzQkFYbUIsQ0FHckIsU0FBUyxDQUVSLFFBQVEsQ0FNUCxRQUFRLENBQUM7SUFDUixTQUFTLEVBQUUsSUFBSTtJQUNmLFdBQVcsRUFBRSxJQUNkO0dBQUM7RUFkSixBQWdCRyxzQkFoQm1CLENBR3JCLFNBQVMsQ0FFUixRQUFRLENBV1AsUUFBUSxDQUFDO0lBQ1IsTUFBTSxFQUFFLGNBQWM7R0FVdEI7RUEzQkosQUFtQkksc0JBbkJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FHUCxDQUFDLENBQUM7SUFDRCxNQUFNLEVBQUUsQ0FBQztJQUNULE9BQU8sRUFBRSxLQUFLO0dBQ2Q7RUF0QkwsQUF3Qkksc0JBeEJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FRUCxpQkFBaUIsQ0FBQztJQUNqQixVQUFVLEVBQUUsR0FBRztHQUNmIn0= */
css/sb-instagram-admin.css CHANGED
@@ -354,14 +354,14 @@
354
  -webkit-border-radius: 3px;
355
  border-radius: 3px;
356
  }
357
- #sbi_admin .sbi_notice a{
358
  color: #d85600;
359
  }
360
- #sbi_admin .sbi_notice a:hover,
361
- #sbi_admin .sbi_notice a:focus{
362
  color: #a34100;
363
  }
364
- #sbi_admin .sbi_notice p{
365
  margin: 0;
366
  padding: 5px 0;
367
  font-size: 13px;
@@ -426,72 +426,122 @@
426
  }
427
 
428
  /* Review notice */
429
- .sbi_review_notice{
430
- position: relative;
431
- overflow: hidden;
432
- max-width: 870px;
433
- margin-top: 10px;
434
- padding: 10px 10px 7px 10px;
435
 
436
- background: #E6F0E8;
437
- border: 1px solid #6AB074;
438
- color: #214F28;
439
- }
440
- .sbi_bfcm_sale_notice,
441
- .sbi_new_user_sale_notice{
442
- max-width: 672px;
443
  }
444
- .sbi_review_notice img{
 
 
445
  width: 74px;
446
- margin: 0 0 0 -100% !important;
447
 
448
- -moz-border-radius: 4px;
449
- -webkit-border-radius: 4px;
450
- border-radius: 4px;
451
  }
452
- .sbi_review_notice .sbi-notice-text{
453
- float: left;
454
- clear: none;
455
- width: 100%;
456
- padding: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  }
458
- .sbi_review_notice .sbi-links{
459
  margin-top: 4px !important;
460
  }
461
- .sbi_review_notice p{
462
- float: left;
463
- clear: both;
464
- width: auto;
465
  margin: 0 0 0 90px !important;
466
  padding: 2px 40px 2px 0;
467
  line-height: 1.4;
468
  }
469
- .sbi_review_notice a{
470
- display: inline-block;
471
- padding: 0 8px;
472
- color: #178529;
473
  }
474
- .sbi_review_notice a:hover,
475
- .sbi_review_notice a:focus{
476
- color: #0c7abf;
 
 
 
 
 
477
  }
478
  .sbi_review_notice .links{
479
- margin: 0 0 0 82px !important;
480
- padding: 4px 0 0 0;
481
- margin-top: 6px !important;
482
  }
483
- .sbi_review_notice .sbi_notice_close,
484
- .sbi_review_notice .sbi_bfcm_sale_notice_close,
485
- .sbi_review_notice .sbi_new_user_sale_notice_close {
486
- position: absolute;
487
- top: 0;
488
- right: 0;
489
- padding: 10px;
490
- line-height: 1;
 
 
 
 
491
  }
492
- .sbi_review_notice .sbi_notice_close:hover,
493
- .sbi_review_notice .sbi_notice_close:focus{
494
- color: #a34100;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  }
496
 
497
  /* Support page */
@@ -1420,30 +1470,16 @@
1420
  margin-top: -10px;
1421
  }
1422
 
1423
- .sbi_review_notice .sbi_offer_btn{
1424
- padding: 4px 12px 6px 12px;
1425
- background: green;
1426
- color: #fff;
1427
- border-radius: 4px;
1428
- display: inline-block;
1429
- text-decoration: none;
1430
- margin-left: 9px;
1431
- }
1432
- .sbi_review_notice .sbi_offer_btn:hover,
1433
- .sbi_review_notice .sbi_offer_btn:focus{
1434
- background: #049404;
1435
- color: #fff;
1436
- }
1437
- .sbi_review_notice .sbi_other_notice{
1438
  padding-top: 10px;
1439
  font-style: italic;
1440
  font-size: 12px;
1441
  }
1442
- .sbi_review_notice .sbi_other_notice a {
1443
  padding: 0;
1444
  }
1445
 
1446
- .sbi_review_notice .sbi_offer_btn {
1447
  padding: 4px 12px 6px 12px;
1448
  background: green;
1449
  color: #fff;
@@ -1451,8 +1487,9 @@
1451
  display: inline-block;
1452
  text-decoration: none;
1453
  margin-left: 0;
 
1454
  }
1455
- .sbi_review_notice .sbi_offer_btn:hover, .sbi_review_notice .sbi_offer_btn:focus {
1456
  background: #049404;
1457
  color: #fff;
1458
  }
354
  -webkit-border-radius: 3px;
355
  border-radius: 3px;
356
  }
357
+ #sbi_admin .sbi_nojs_notice a{
358
  color: #d85600;
359
  }
360
+ #sbi_admin .sbi_nojs_notice a:hover,
361
+ #sbi_admin .sbi_nojs_notice a:focus{
362
  color: #a34100;
363
  }
364
+ #sbi_admin .sbi_nojs_notice p{
365
  margin: 0;
366
  padding: 5px 0;
367
  font-size: 13px;
426
  }
427
 
428
  /* Review notice */
429
+ .sbi_notice{
430
+ position: relative;
431
+ overflow: hidden;
432
+ max-width: 865px;
433
+ margin-top: 10px;
434
+ padding: 10px 10px 7px 10px;
435
 
436
+ background: #E6F0E8;
437
+ border: 1px solid #6AB074;
438
+ color: #214F28;
 
 
 
 
439
  }
440
+ .sbi_notice .sbi_thumb{
441
+ position: relative;
442
+ display: inline-block;
443
  width: 74px;
444
+ margin: 0 0 0 -100% !important;
445
 
446
+ -moz-border-radius: 4px;
447
+ -webkit-border-radius: 4px;
448
+ border-radius: 4px;
449
  }
450
+ .sbi_notice .sbi_thumb .img-overlay {
451
+ position: absolute;
452
+ bottom: 4px;
453
+ padding: 6px 7px 6px 5px;
454
+ font-size: 13px;
455
+ font-weight: bold;
456
+ background: #fff;
457
+ background: rgba(255,255,255,0.85);
458
+ line-height: 1;
459
+ color: #333;
460
+ box-shadow: 1px -1px 3px 0 rgba(0,0,0,0.15);
461
+ }
462
+ .sbi_notice .sbi_thumb img {
463
+ max-width: 100%;
464
+ }
465
+ .sbi_notice .sbi-notice-text{
466
+ float: left;
467
+ clear: none;
468
+ width: 100%;
469
+ padding: 0;
470
  }
471
+ .sbi_notice .sbi-links{
472
  margin-top: 4px !important;
473
  }
474
+ .sbi_notice p{
475
+ float: left;
476
+ clear: both;
477
+ width: auto;
478
  margin: 0 0 0 90px !important;
479
  padding: 2px 40px 2px 0;
480
  line-height: 1.4;
481
  }
482
+ .sbi_notice a{
483
+ display: inline-block;
484
+ padding: 0 8px;
485
+ color: #178529;
486
  }
487
+ .sbi_notice a:hover,
488
+ .sbi_notice a:focus{
489
+ color: #0c7abf;
490
+ }
491
+ .sbi_notice .links{
492
+ margin: 0 0 0 90px !important;
493
+ padding: 4px 0 0 0;
494
+ margin-top: 1px !important;
495
  }
496
  .sbi_review_notice .links{
497
+ margin-left: 82px !important;
498
+ margin-top: 0 !important;
 
499
  }
500
+ .sbi_notice .sbi_notice_close,
501
+ .sbi_notice .sbi_bfcm_sale_notice_close,
502
+ .sbi_notice .sbi_new_user_sale_notice_close {
503
+ position: absolute;
504
+ top: 0;
505
+ right: 0;
506
+ padding: 10px;
507
+ line-height: 1;
508
+ }
509
+ .sbi_notice .sbi_notice_close:hover,
510
+ .sbi_notice .sbi_notice_close:focus{
511
+ color: #a34100;
512
  }
513
+ .sbi_notice strong span {
514
+ font-weight: 900;
515
+ }
516
+ /* Notice CTA btn */
517
+ .sbi_notice .sbi_offer_btn,
518
+ .sbi_notice .sbi_main_cta{
519
+ padding: 4px 12px 6px 12px;
520
+ background: green;
521
+ color: #fff;
522
+ border-radius: 4px;
523
+ display: inline-block;
524
+ text-decoration: none;
525
+ margin-left: 0;
526
+ margin-right: 4px;
527
+ }
528
+ .sbi_notice .sbi_offer_btn:hover,
529
+ .sbi_notice .sbi_offer_btn:focus,
530
+ .sbi_notice .sbi_main_cta:hover,
531
+ .sbi_notice .sbi_main_cta:focus{
532
+ background: #049404;
533
+ color: #fff;
534
+ }
535
+ .sbi_notice .sbi_other_notice{
536
+ padding-top: 10px;
537
+ font-style: italic;
538
+ font-size: 12px;
539
+ }
540
+ .sbi_notice .sbi_other_notice a{
541
+ padding: 0;
542
+ }
543
+ .sbi_notice .links > .sbi_main_cta:first-child {
544
+ margin-left: 8px;
545
  }
546
 
547
  /* Support page */
1470
  margin-top: -10px;
1471
  }
1472
 
1473
+ .sbi_notice .sbi_other_notice{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1474
  padding-top: 10px;
1475
  font-style: italic;
1476
  font-size: 12px;
1477
  }
1478
+ .sbi_notice .sbi_other_notice a {
1479
  padding: 0;
1480
  }
1481
 
1482
+ .sbi_notice .sbi_offer_btn {
1483
  padding: 4px 12px 6px 12px;
1484
  background: green;
1485
  color: #fff;
1487
  display: inline-block;
1488
  text-decoration: none;
1489
  margin-left: 0;
1490
+ margin-right: 8px;
1491
  }
1492
+ .sbi_notice .sbi_offer_btn:hover, .sbi_notice .sbi_offer_btn:focus {
1493
  background: #049404;
1494
  color: #fff;
1495
  }
img/sbi-icon-offer.png DELETED
Binary file
img/sbi-icon.png CHANGED
Binary file
inc/admin/actions.php CHANGED
@@ -1077,7 +1077,7 @@ function sbi_get_current_time() {
1077
  $current_time = time();
1078
 
1079
  // where to do tests
1080
- // $current_time = strtotime( 'November 25, 2022' ) + 1;
1081
 
1082
  return $current_time;
1083
  }
@@ -1085,197 +1085,9 @@ function sbi_get_current_time() {
1085
  // generates the html for the admin notices
1086
  function sbi_notices_html() {
1087
 
1088
- //Only show to admins
1089
- $current_screen = get_current_screen();
1090
- $is_plugins_page = isset( $current_screen->id ) && $current_screen->id === 'plugins';
1091
- $page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
1092
- //Only show to admins
1093
- if ( ! current_user_can( 'manage_options' ) ) {
1094
- return;
1095
- }
1096
-
1097
- $sbi_statuses_option = get_option( 'sbi_statuses', array() );
1098
- $current_time = sbi_get_current_time();
1099
- $sbi_bfcm_discount_code = 'happysmashgiving' . date('Y', $current_time );
1100
-
1101
- // rating notice logic
1102
- $sbi_rating_notice_option = get_option( 'sbi_rating_notice', false );
1103
- $sbi_rating_notice_waiting = get_transient( 'instagram_feed_rating_notice_waiting' );
1104
- $should_show_rating_notice = ($sbi_rating_notice_waiting !== 'waiting' && $sbi_rating_notice_option !== 'dismissed');
1105
-
1106
- // black friday cyber monday logic
1107
- $thanksgiving_this_year = sbi_get_future_date( 11, date('Y', $current_time ), 4, 4, 1 );
1108
- $one_week_before_black_friday_this_year = $thanksgiving_this_year - 7*24*60*60;
1109
- $one_day_after_cyber_monday_this_year = $thanksgiving_this_year + 5*24*60*60;
1110
- $has_been_two_days_since_rating_dismissal = isset( $sbi_statuses_option['rating_notice_dismissed'] ) ? ((int)$sbi_statuses_option['rating_notice_dismissed'] + 2*24*60*60) < $current_time : true;
1111
-
1112
- $could_show_bfcm_discount = ($current_time > $one_week_before_black_friday_this_year && $current_time < $one_day_after_cyber_monday_this_year);
1113
- $should_show_bfcm_discount = false;
1114
- if ( $could_show_bfcm_discount && $has_been_two_days_since_rating_dismissal ) {
1115
- global $current_user;
1116
- $user_id = $current_user->ID;
1117
-
1118
- $ignore_bfcm_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice' );
1119
- $ignore_bfcm_sale_notice_meta = isset( $ignore_bfcm_sale_notice_meta[0] ) ? $ignore_bfcm_sale_notice_meta[0] : '';
1120
-
1121
- /* Check that the user hasn't already clicked to ignore the message */
1122
- $should_show_bfcm_discount = ($ignore_bfcm_sale_notice_meta !== 'always' && $ignore_bfcm_sale_notice_meta !== date( 'Y', $current_time ));
1123
- }
1124
-
1125
- // new user discount logic
1126
- $in_new_user_month_range = true;
1127
- $should_show_new_user_discount = false;
1128
- $has_been_one_month_since_rating_dismissal = isset( $sbi_statuses_option['rating_notice_dismissed'] ) ? ((int)$sbi_statuses_option['rating_notice_dismissed'] + 30*24*60*60) < $current_time + 1: true;
1129
-
1130
- if ( isset( $sbi_statuses_option['first_install'] ) && $sbi_statuses_option['first_install'] === 'from_update' ) {
1131
- global $current_user;
1132
- $user_id = $current_user->ID;
1133
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
1134
- $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
1135
- if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
1136
- $should_show_new_user_discount = true;
1137
- }
1138
- } elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal ) {
1139
- global $current_user;
1140
- $user_id = $current_user->ID;
1141
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
1142
- $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
1143
-
1144
- if ( $ignore_new_user_sale_notice_meta !== 'always'
1145
- && isset( $sbi_statuses_option['first_install'] )
1146
- && $current_time > (int)$sbi_statuses_option['first_install'] + 60*60*24*30 ) {
1147
- $should_show_new_user_discount = true;
1148
- }
1149
- }
1150
-
1151
- if ( $should_show_rating_notice ) {
1152
- $other_notice_html = '';
1153
- $dismiss_url = add_query_arg( 'sbi_ignore_rating_notice_nag', '1' );
1154
- $later_url = add_query_arg( 'sbi_ignore_rating_notice_nag', 'later' );
1155
- if ( $should_show_bfcm_discount ) {
1156
- $other_notice_html = '<p class="sbi_other_notice">' . sprintf( __( 'PS. We currently have a %sBlack Friday deal%s for 60%% off the Pro version!', 'instagram-feed' ), '<a href="https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=rating&discount='.$sbi_bfcm_discount_code.'" target="_blank"><b style="font-weight: 700;">', '</b></a>' ) . '</a></p>';
1157
-
1158
- $dismiss_url = add_query_arg( array(
1159
- 'sbi_ignore_rating_notice_nag' => '1',
1160
- 'sbi_ignore_bfcm_sale_notice' => date( 'Y', $current_time )
1161
- )
1162
- );
1163
- $later_url = add_query_arg( array(
1164
- 'sbi_ignore_rating_notice_nag' => 'later',
1165
- 'sbi_ignore_bfcm_sale_notice' => date( 'Y', $current_time )
1166
- )
1167
- );
1168
- }
1169
-
1170
- echo "
1171
- <div class='sbi_notice sbi_review_notice'>
1172
- <img src='". SBI_PLUGIN_URL . 'img/sbi-icon.png' ."' alt='" . __( 'Instagram Feed', 'instagram-feed' ) . "'>
1173
- <div class='sbi-notice-text'>
1174
- <p style='padding-top: 4px;'>" . sprintf( __( "It's great to see that you've been using the %1sInstagram Feed%2s plugin for a while now. Hopefully you're happy with it!&nbsp; If so, would you consider leaving a positive review? It really helps to support the plugin and helps others to discover it too!", 'instagram-feed' ), '<strong style=\'font-weight: 700;\'>', '</strong>' ) . "</p>
1175
- <p class='links'";
1176
- if( $should_show_bfcm_discount ) echo " style='margin-top: 0 !important;'";
1177
- echo ">
1178
- <a class='sbi_notice_dismiss' href='https://wordpress.org/support/plugin/instagram-feed/reviews/' target='_blank'>" . __( 'Sure, I\'d love to!', 'instagram-feed' ) . "</a>
1179
- &middot;
1180
- <a class='sbi_notice_dismiss' href='" .esc_url( $dismiss_url ). "'>" . __( 'No thanks', 'instagram-feed' ) . "</a>
1181
- &middot;
1182
- <a class='sbi_notice_dismiss' href='" .esc_url( $dismiss_url ). "'>" . __( 'I\'ve already given a review', 'instagram-feed' ) . "</a>
1183
- &middot;
1184
- <a class='sbi_notice_dismiss' href='" .esc_url( $later_url ). "'>" . __( 'Ask Me Later', 'instagram-feed' ) . "</a>
1185
- </p>"
1186
- . $other_notice_html .
1187
- "</div>
1188
- <a class='sbi_notice_close' href='" .esc_url( $dismiss_url ). "'><i class='fa fa-close'></i></a>
1189
- </div>";
1190
-
1191
- } elseif ( $should_show_new_user_discount ) {
1192
- global $current_user;
1193
- $user_id = $current_user->ID;
1194
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
1195
- if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
1196
-
1197
- echo "
1198
- <div class='sbi_notice sbi_review_notice sbi_new_user_sale_notice'>
1199
- <img src='" . SBI_PLUGIN_URL . 'img/sbi-icon-offer.png' . "' alt='Instagram Feed'>
1200
- <div class='sbi-notice-text'>
1201
- <p><b style'font-weight: 700;'>" . sprintf( __( 'Exclusive offer!%1s We don\'t run promotions very often, but for a limited time we\'re offering %2s60%% off%3s our Pro version to all users of our free Instagram Feed plugin.', 'instagram-feed' ), '</b> ', '<b style="font-weight: 700;">', '</b>' ) . "</p>
1202
- <p class='sbi-links'>
1203
- <a class='sbi_notice_dismiss sbi_offer_btn' href='https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=newuser&discount=instagramthankyou' target='_blank'><b>" . __( 'Get this offer', 'instagram-feed' ) . "</b></a>
1204
- <a class='sbi_notice_dismiss' style='margin-left: 5px;' href='" . esc_url( add_query_arg( 'sbi_ignore_new_user_sale_notice', 'always' ) ) . "'>" . __( 'I\'m not interested', 'instagram-feed' ) . "</a>
1205
-
1206
- </p>
1207
- </div>
1208
- <a class='sbi_new_user_sale_notice_close' href='" . esc_url( add_query_arg( 'sbi_ignore_new_user_sale_notice', 'always' ) ) . "'><i class='fa fa-close'></i></a>
1209
- </div>
1210
- ";
1211
- }
1212
-
1213
- } elseif ( $should_show_bfcm_discount ) {
1214
-
1215
- echo "
1216
- <div class='sbi_notice sbi_review_notice sbi_bfcm_sale_notice'>
1217
- <img src='". SBI_PLUGIN_URL . 'img/sbi-icon-offer.png' ."' alt='Instagram Feed'>
1218
- <div class='sbi-notice-text'>
1219
- <p>" . sprintf( __( '%sBlack Friday/Cyber Monday Deal!%s Thank you for using our free Instagram Feed plugin. For a limited time, we\'re offering %s60%% off%s the Pro version for all of our users.', 'instagram-feed' ), '<b style="font-weight: 700;">', '</b>', '<b style="font-weight: 700;">', '</b>' ) . "</p>
1220
- <p class='sbi-links'>
1221
- <a class='sbi_notice_dismiss sbi_offer_btn' href='https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=notices&utm_medium=bfcm&discount=".$sbi_bfcm_discount_code."' target='_blank'>" . __( 'Get this offer!', 'instagram-feed' ) . "</a>
1222
- <a class='sbi_notice_dismiss' style='margin-left: 5px;' href='" .esc_url( add_query_arg( 'sbi_ignore_bfcm_sale_notice', date( 'Y', $current_time ) ) ). "'>" . __( 'I\'m not interested', 'instagram-feed' ) . "</a>
1223
- </p>
1224
- </div>
1225
- <a class='sbi_bfcm_sale_notice_close' href='" .esc_url( add_query_arg( 'sbi_ignore_bfcm_sale_notice', date( 'Y', $current_time ) ) ). "'><i class='fa fa-close'></i></a>
1226
- </div>
1227
- ";
1228
-
1229
- }
1230
-
1231
  }
1232
- add_action( 'admin_notices', 'sbi_notices_html', 8 ); // priority 12 for Twitter, priority 10 for Facebook
1233
-
1234
- function sbi_process_nags() {
1235
-
1236
- global $current_user;
1237
- $user_id = $current_user->ID;
1238
- $sbi_statuses_option = get_option( 'sbi_statuses', array() );
1239
-
1240
- if ( isset( $_GET['sbi_ignore_rating_notice_nag'] ) ) {
1241
- if ( (int)$_GET['sbi_ignore_rating_notice_nag'] === 1 ) {
1242
- update_option( 'sbi_rating_notice', 'dismissed', false );
1243
- $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
1244
- update_option( 'sbi_statuses', $sbi_statuses_option, false );
1245
-
1246
- } elseif ( $_GET['sbi_ignore_rating_notice_nag'] === 'later' ) {
1247
- set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
1248
- update_option( 'sbi_rating_notice', 'pending', false );
1249
- }
1250
- }
1251
-
1252
- if ( isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ) {
1253
- $response = sanitize_text_field( $_GET['sbi_ignore_new_user_sale_notice'] );
1254
- if ( $response === 'always' ) {
1255
- update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
1256
 
1257
- $current_month_number = (int)date('n', sbi_get_current_time() );
1258
- $not_early_in_the_year = ($current_month_number > 5);
1259
-
1260
- if ( $not_early_in_the_year ) {
1261
- update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
1262
- }
1263
-
1264
- }
1265
- }
1266
-
1267
- if ( isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ) {
1268
- $response = sanitize_text_field( $_GET['sbi_ignore_bfcm_sale_notice'] );
1269
- if ( $response === 'always' ) {
1270
- update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', 'always' );
1271
- } elseif ( $response === date( 'Y', sbi_get_current_time() ) ) {
1272
- update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
1273
- }
1274
- update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
1275
- }
1276
-
1277
- }
1278
- add_action( 'admin_init', 'sbi_process_nags' );
1279
 
1280
  function sbi_get_future_date( $month, $year, $week, $day, $direction ) {
1281
  if ( $direction > 0 ) {
1077
  $current_time = time();
1078
 
1079
  // where to do tests
1080
+ // $current_time = strtotime( 'November 25, 2020' ) + 1;
1081
 
1082
  return $current_time;
1083
  }
1085
  // generates the html for the admin notices
1086
  function sbi_notices_html() {
1087
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1088
  }
1089
+ //add_action( 'admin_notices', 'sbi_notices_html', 8 ); // priority 12 for Twitter, priority 10 for Facebook
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1091
 
1092
  function sbi_get_future_date( $month, $year, $week, $day, $direction ) {
1093
  if ( $direction > 0 ) {
inc/admin/class-sbi-new-user.php ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SBI_New_User.
4
+ *
5
+ * @since 2.6
6
+ */
7
+
8
+ // Exit if accessed directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ class SBI_New_User extends SBI_Notifications {
14
+
15
+ /**
16
+ * Source of notifications content.
17
+ *
18
+ * @since 2.6
19
+ *
20
+ * @var string
21
+ */
22
+ const SOURCE_URL = 'http://plugin.smashballoon.com/newuser.json';
23
+
24
+ /**
25
+ * @var string
26
+ */
27
+ const OPTION_NAME = 'sbi_newuser_notifications';
28
+
29
+ /**
30
+ * Register hooks.
31
+ *
32
+ * @since 2.6
33
+ */
34
+ public function hooks() {
35
+ add_action( 'admin_notices', array( $this, 'output' ), 8 );
36
+
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
+ }
47
+
48
+ /**
49
+ * Verify notification data before it is saved.
50
+ *
51
+ * @param array $notifications Array of notifications items to verify.
52
+ *
53
+ * @return array
54
+ *
55
+ * @since 2.6
56
+ */
57
+ public function verify( $notifications ) {
58
+ $data = array();
59
+
60
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
61
+ return $data;
62
+ }
63
+
64
+ $option = $this->get_option();
65
+
66
+ foreach ( $notifications as $key => $notification ) {
67
+
68
+ // The message should never be empty, if they are, ignore.
69
+ if ( empty( $notification['content'] ) ) {
70
+ continue;
71
+ }
72
+
73
+ // Ignore if notification has already been dismissed.
74
+ if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
75
+ continue;
76
+ }
77
+
78
+ $data[ $key ] = $notification;
79
+ }
80
+
81
+ return $data;
82
+ }
83
+
84
+ /**
85
+ * Verify saved notification data for active notifications.
86
+ *
87
+ * @since 2.6
88
+ *
89
+ * @param array $notifications Array of notifications items to verify.
90
+ *
91
+ * @return array
92
+ */
93
+ public function verify_active( $notifications ) {
94
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
95
+ return array();
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' ) {
117
+ $should_show_new_user_discount = true;
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
+ }
131
+
132
+ if ( isset( $notifications['review'] ) && $should_show_rating_notice ) {
133
+ return array( $notifications['review'] );
134
+ } elseif ( isset( $notifications['discount'] ) && $should_show_new_user_discount ) {
135
+ return array( $notifications['discount'] );
136
+ }
137
+
138
+ return array();
139
+ }
140
+
141
+ /**
142
+ * Get notification data.
143
+ *
144
+ * @since 2.6
145
+ *
146
+ * @return array
147
+ */
148
+ public function get() {
149
+ if ( ! $this->has_access() ) {
150
+ return array();
151
+ }
152
+
153
+ $option = $this->get_option();
154
+
155
+ // Only update if does not exist.
156
+ if ( empty( $option['update'] ) ) {
157
+ $this->update();
158
+ }
159
+
160
+ $events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
161
+ $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
162
+
163
+ return array_merge( $events, $feed );
164
+ }
165
+
166
+ /**
167
+ * Add a manual notification event.
168
+ *
169
+ * @since 2.6
170
+ *
171
+ * @param array $notification Notification data.
172
+ */
173
+ public function add( $notification ) {
174
+ if ( empty( $notification['id'] ) ) {
175
+ return;
176
+ }
177
+
178
+ $option = $this->get_option();
179
+
180
+ if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
181
+ return;
182
+ }
183
+
184
+ foreach ( $option['events'] as $item ) {
185
+ if ( $item['id'] === $notification['id'] ) {
186
+ return;
187
+ }
188
+ }
189
+
190
+ $notification = $this->verify( array( $notification ) );
191
+
192
+ update_option(
193
+ $this->option_name(),
194
+ array(
195
+ 'update' => $option['update'],
196
+ 'feed' => $option['feed'],
197
+ 'events' => array_merge( $notification, $option['events'] ),
198
+ 'dismissed' => $option['dismissed'],
199
+ )
200
+ );
201
+ }
202
+
203
+ /**
204
+ * Update notification data from feed.
205
+ *
206
+ * @since 2.6
207
+ */
208
+ public function update() {
209
+ $feed = $this->fetch_feed();
210
+ $option = $this->get_option();
211
+
212
+ update_option(
213
+ $this->option_name(),
214
+ array(
215
+ 'update' => time(),
216
+ 'feed' => $feed,
217
+ 'events' => $option['events'],
218
+ 'dismissed' => $option['dismissed'],
219
+ )
220
+ );
221
+ }
222
+
223
+ /**
224
+ * Do not enqueue anything extra.
225
+ *
226
+ * @since 2.6
227
+ */
228
+ public function enqueues() {
229
+
230
+ }
231
+
232
+ /**
233
+ * Output notifications on Form Overview admin area.
234
+ *
235
+ * @since 2.6
236
+ */
237
+ public function output() {
238
+ $notifications = $this->get();
239
+
240
+ if ( empty( $notifications ) ) {
241
+ return;
242
+ }
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(
252
+ 'em' => array(),
253
+ 'strong' => array(),
254
+ 'span' => array(
255
+ 'style' => array(),
256
+ ),
257
+ 'a' => array(
258
+ 'href' => array(),
259
+ 'target' => array(),
260
+ 'rel' => array(),
261
+ ),
262
+ );
263
+ $image_overlay = '';
264
+
265
+ foreach ( $notifications as $notification ) {
266
+ $type = sanitize_text_field( $notification['id'] );
267
+ $img_src = SBI_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
268
+ $content = '';
269
+ if ( ! empty( $notification['content'] ) ) {
270
+ $content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
271
+ }
272
+ $buttons = array();
273
+ if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
274
+ foreach ( $notification['btns'] as $btn_type => $btn ) {
275
+ if ( ! is_array( $btn['url'] ) ) {
276
+ $buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
277
+ } elseif ( is_array( $btn['url'] ) ) {
278
+ $buttons[ $btn_type ]['url'] = add_query_arg( $btn['url'] );
279
+ }
280
+
281
+ $buttons[ $btn_type ]['attr'] = '';
282
+ if ( ! empty( $btn['attr'] ) ) {
283
+ $buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"';
284
+ }
285
+
286
+ $buttons[ $btn_type ]['class'] = '';
287
+ if ( ! empty( $btn['class'] ) ) {
288
+ $buttons[ $btn_type ]['class'] = ' ' . $btn['class'];
289
+ }
290
+
291
+ $buttons[ $btn_type ]['text'] = '';
292
+ if ( ! empty( $btn['text'] ) ) {
293
+ $buttons[ $btn_type ]['text'] = wp_kses( $btn['text'], $content_allowed_tags );
294
+ }
295
+ }
296
+ }
297
+ if ( isset( $notification['image_overlay'] ) ) {
298
+ $image_overlay = '<div class="img-overlay">'. esc_html( $notification['image_overlay'] ).'</div>';
299
+ }
300
+ }
301
+ ?>
302
+
303
+ <div class="sbi_notice sbi_<?php echo esc_attr( $type ); ?>_notice">
304
+ <div class="sbi_thumb">
305
+ <img src="<?php echo esc_url( $img_src ); ?>" alt="notice">
306
+ <?php echo $image_overlay; ?>
307
+ </div>
308
+ <div class="sbi-notice-text">
309
+ <p style="padding-top: 4px;"><?php echo $content; ?></p>
310
+ <p class="links">
311
+ <?php foreach ( $buttons as $button ) : ?>
312
+ <a class="<?php echo esc_attr( $button['class'] ); ?>" href="<?php echo esc_attr( $button['url'] ); ?>"<?php echo $button['attr']; ?>><?php echo $button['text']; ?></a>
313
+ <?php endforeach; ?>
314
+ </p>
315
+ </div>
316
+ <a class="sbi_notice_close" href="<?php echo add_query_arg( array( 'sbi_dismiss' => $type ) ); ?>"><i class="fa fa-close"></i></a>
317
+ </div>
318
+ <?php
319
+ }
320
+
321
+ /**
322
+ * Hide messages permanently or some can be dismissed temporarily
323
+ *
324
+ * @since 2.6
325
+ */
326
+ public function dismiss() {
327
+ global $current_user;
328
+ $user_id = $current_user->ID;
329
+ $sbi_statuses_option = get_option( 'sbi_statuses', array() );
330
+
331
+ if ( isset( $_GET['sbi_ignore_rating_notice_nag'] ) ) {
332
+ if ( (int)$_GET['sbi_ignore_rating_notice_nag'] === 1 ) {
333
+ update_option( 'sbi_rating_notice', 'dismissed', false );
334
+ $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
335
+ update_option( 'sbi_statuses', $sbi_statuses_option, false );
336
+
337
+ } elseif ( $_GET['sbi_ignore_rating_notice_nag'] === 'later' ) {
338
+ set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
339
+ update_option( 'sbi_rating_notice', 'pending', false );
340
+ }
341
+ }
342
+
343
+ if ( isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ) {
344
+ $response = sanitize_text_field( $_GET['sbi_ignore_new_user_sale_notice'] );
345
+ if ( $response === 'always' ) {
346
+ update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
347
+
348
+ $current_month_number = (int)date('n', sbi_get_current_time() );
349
+ $not_early_in_the_year = ($current_month_number > 5);
350
+
351
+ if ( $not_early_in_the_year ) {
352
+ update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
353
+ }
354
+
355
+ }
356
+ }
357
+
358
+ if ( isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ) {
359
+ $response = sanitize_text_field( $_GET['sbi_ignore_bfcm_sale_notice'] );
360
+ if ( $response === 'always' ) {
361
+ update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', 'always' );
362
+ } elseif ( $response === date( 'Y', sbi_get_current_time() ) ) {
363
+ update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
364
+ }
365
+ update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
366
+ }
367
+
368
+ if ( isset( $_GET['sbi_dismiss'] ) ) {
369
+ if ( $_GET['sbi_dismiss'] === 'review' ) {
370
+ update_option( 'sbi_rating_notice', 'dismissed', false );
371
+ $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
372
+ update_option( 'sbi_statuses', $sbi_statuses_option, false );
373
+ } elseif ( $_GET['sbi_dismiss'] === 'discount' ) {
374
+ update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
375
+
376
+ $current_month_number = (int)date('n', sbi_get_current_time() );
377
+ $not_early_in_the_year = ($current_month_number > 5);
378
+
379
+ if ( $not_early_in_the_year ) {
380
+ update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
381
+ }
382
+ }
383
+ update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
384
+ }
385
+ }
386
+ }
inc/admin/class-sbi-notifications.php ADDED
@@ -0,0 +1,573 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SBI_Notifications.
4
+ *
5
+ * @since 2.6/5.9
6
+ */
7
+
8
+ // Exit if accessed directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ class SBI_Notifications {
14
+
15
+ /**
16
+ * Source of notifications content.
17
+ *
18
+ * @var string
19
+ */
20
+ const SOURCE_URL = 'http://plugin.smashballoon.com/notifications.json';
21
+
22
+ /**
23
+ * @var string
24
+ */
25
+ const OPTION_NAME = 'sbi_notifications';
26
+
27
+ /**
28
+ * JSON data contains notices for all plugins. This is used
29
+ * to select messages only meant for this plugin
30
+ *
31
+ * @var string
32
+ */
33
+ const PLUGIN = 'instagram';
34
+
35
+ /**
36
+ * Option value.
37
+ *
38
+ * @since 2.6/5.9
39
+ *
40
+ * @var bool|array
41
+ */
42
+ public $option = false;
43
+
44
+ /**
45
+ * Initialize class.
46
+ *
47
+ * @since 2.6/5.9
48
+ */
49
+ public function init() {
50
+ $this->hooks();
51
+ }
52
+
53
+ /**
54
+ * Use this function to get the option name to allow
55
+ * inheritance for the New_User class
56
+ *
57
+ * @return string
58
+ */
59
+ public function option_name() {
60
+ return self::OPTION_NAME;
61
+ }
62
+
63
+ /**
64
+ * Use this function to get the source URL to allow
65
+ * inheritance for the New_User class
66
+ *
67
+ * @return string
68
+ */
69
+ public function source_url() {
70
+ return self::SOURCE_URL;
71
+ }
72
+
73
+ /**
74
+ * Register hooks.
75
+ *
76
+ * @since 2.6/5.9
77
+ */
78
+ public function hooks() {
79
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ) );
80
+
81
+ add_action( 'sbi_admin_overview_before_table', array( $this, 'output' ) );
82
+
83
+ // on cron. Once a week?
84
+ add_action( 'sbi_notification_update', array( $this, 'update' ) );
85
+
86
+ add_action( 'wp_ajax_sbi_dashboard_notification_dismiss', array( $this, 'dismiss' ) );
87
+ }
88
+
89
+
90
+ /**
91
+ * Check if user has access and is enabled.
92
+ *
93
+ * @since 2.6/5.9
94
+ *
95
+ * @return bool
96
+ */
97
+ public function has_access() {
98
+ $access = false;
99
+
100
+ if ( current_user_can( 'manage_instagram_feed_options' ) ) {
101
+ $access = true;
102
+ }
103
+
104
+ return apply_filters( 'sbi_admin_notifications_has_access', $access );
105
+ }
106
+
107
+ /**
108
+ * Get option value.
109
+ *
110
+ * @since 2.6/5.9
111
+ *
112
+ * @param bool $cache Reference property cache if available.
113
+ *
114
+ * @return array
115
+ */
116
+ public function get_option( $cache = true ) {
117
+ if ( $this->option && $cache ) {
118
+ return $this->option;
119
+ }
120
+
121
+ $option = get_option( $this->option_name(), array() );
122
+
123
+ $this->option = array(
124
+ 'update' => ! empty( $option['update'] ) ? $option['update'] : 0,
125
+ 'events' => ! empty( $option['events'] ) ? $option['events'] : array(),
126
+ 'feed' => ! empty( $option['feed'] ) ? $option['feed'] : array(),
127
+ 'dismissed' => ! empty( $option['dismissed'] ) ? $option['dismissed'] : array(),
128
+ );
129
+
130
+ return $this->option;
131
+ }
132
+
133
+ /**
134
+ * Fetch notifications from feed.
135
+ *
136
+ * @since 2.6/5.9
137
+ *
138
+ * @return array
139
+ */
140
+ public function fetch_feed() {
141
+ $res = wp_remote_get( $this->source_url() );
142
+
143
+ if ( is_wp_error( $res ) ) {
144
+ return array();
145
+ }
146
+
147
+ $body = wp_remote_retrieve_body( $res );
148
+
149
+ if ( empty( $body ) ) {
150
+ return array();
151
+ }
152
+
153
+ return $this->verify( json_decode( $body, true ) );
154
+ }
155
+
156
+ /**
157
+ * Verify notification data before it is saved.
158
+ *
159
+ * @since 2.6/5.9
160
+ *
161
+ * @param array $notifications Array of notifications items to verify.
162
+ *
163
+ * @return array
164
+ */
165
+ public function verify( $notifications ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
166
+ $data = array();
167
+
168
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
169
+ return $data;
170
+ }
171
+
172
+ $option = $this->get_option();
173
+
174
+ foreach ( $notifications as $notification ) {
175
+
176
+ // The message and license should never be empty, if they are, ignore.
177
+ if ( empty( $notification['content'] ) || empty( $notification['type'] ) ) {
178
+ continue;
179
+ }
180
+
181
+ // Ignore if license type does not match.
182
+ $license = sbi_is_pro_version() ? 'pro' : 'free';
183
+
184
+ if ( ! in_array( $license, $notification['type'], true ) ) {
185
+ continue;
186
+ }
187
+
188
+ // Ignore if expired.
189
+ if ( ! empty( $notification['end'] ) && sbi_get_current_time() > strtotime( $notification['end'] ) ) {
190
+ continue;
191
+ }
192
+
193
+ // Ignore if notification has already been dismissed.
194
+ if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
195
+ continue;
196
+ }
197
+
198
+ // TODO: Ignore if notification existed before installing SBI.
199
+ // Prevents bombarding the user with notifications after activation.
200
+ $activated = false;
201
+ if ( ! empty( $activated )
202
+ && ! empty( $notification['start'] )
203
+ && $activated > strtotime( $notification['start'] ) ) {
204
+ continue;
205
+ }
206
+
207
+ $data[] = $notification;
208
+ }
209
+
210
+ return $data;
211
+ }
212
+
213
+ /**
214
+ * Verify saved notification data for active notifications.
215
+ *
216
+ * @since 2.6/5.9
217
+ *
218
+ * @param array $notifications Array of notifications items to verify.
219
+ *
220
+ * @return array
221
+ */
222
+ public function verify_active( $notifications ) {
223
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
224
+ return array();
225
+ }
226
+
227
+ // Remove notfications that are not active.
228
+ foreach ( $notifications as $key => $notification ) {
229
+ if ( ( ! empty( $notification['start'] ) && sbi_get_current_time() < strtotime( $notification['start'] ) )
230
+ || ( ! empty( $notification['end'] ) && sbi_get_current_time() > strtotime( $notification['end'] ) ) ) {
231
+ unset( $notifications[ $key ] );
232
+ }
233
+ }
234
+
235
+ return $notifications;
236
+ }
237
+
238
+ /**
239
+ * Get notification data.
240
+ *
241
+ * @since 2.6/5.9
242
+ *
243
+ * @return array
244
+ */
245
+ public function get() {
246
+ if ( ! $this->has_access() ) {
247
+ return array();
248
+ }
249
+
250
+ $option = $this->get_option();
251
+
252
+ // Update notifications using async task.
253
+ if ( empty( $option['update'] ) || sbi_get_current_time() > $option['update'] + DAY_IN_SECONDS ) {
254
+ $this->update();
255
+ }
256
+
257
+ $events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
258
+ $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
259
+
260
+ // If there is a new user notification, add it to the beginning of the notification list
261
+ $sbi_newuser = new SBI_New_User();
262
+ $newuser_notifications = $sbi_newuser->get();
263
+
264
+ if ( ! empty( $newuser_notifications ) ) {
265
+ $events = array_merge( $newuser_notifications, $events );
266
+ }
267
+
268
+ return array_merge( $events, $feed );
269
+ }
270
+
271
+ /**
272
+ * Get notification count.
273
+ *
274
+ * @since 2.6/5.9
275
+ *
276
+ * @return int
277
+ */
278
+ public function get_count() {
279
+ return count( $this->get() );
280
+ }
281
+
282
+ /**
283
+ * Add a manual notification event.
284
+ *
285
+ * @since 2.6/5.9
286
+ *
287
+ * @param array $notification Notification data.
288
+ */
289
+ public function add( $notification ) {
290
+ if ( empty( $notification['id'] ) ) {
291
+ return;
292
+ }
293
+
294
+ $option = $this->get_option();
295
+
296
+ if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
297
+ return;
298
+ }
299
+
300
+ foreach ( $option['events'] as $item ) {
301
+ if ( $item['id'] === $notification['id'] ) {
302
+ return;
303
+ }
304
+ }
305
+
306
+ $notification = $this->verify( array( $notification ) );
307
+
308
+ update_option(
309
+ 'sbi_notifications',
310
+ array(
311
+ 'update' => $option['update'],
312
+ 'feed' => $option['feed'],
313
+ 'events' => array_merge( $notification, $option['events'] ),
314
+ 'dismissed' => $option['dismissed'],
315
+ )
316
+ );
317
+ }
318
+
319
+ /**
320
+ * Update notification data from feed.
321
+ *
322
+ * @since 2.6/5.9
323
+ */
324
+ public function update() {
325
+ $feed = $this->fetch_feed();
326
+ $option = $this->get_option();
327
+
328
+ update_option(
329
+ 'sbi_notifications',
330
+ array(
331
+ 'update' => sbi_get_current_time(),
332
+ 'feed' => $feed,
333
+ 'events' => $option['events'],
334
+ 'dismissed' => $option['dismissed'],
335
+ )
336
+ );
337
+ }
338
+
339
+ /**
340
+ * Admin area Form Overview enqueues.
341
+ *
342
+ * @since 2.6/5.9
343
+ */
344
+ public function enqueues() {
345
+ if ( ! $this->has_access() ) {
346
+ return;
347
+ }
348
+
349
+ $notifications = $this->get();
350
+
351
+ if ( empty( $notifications ) ) {
352
+ return;
353
+ }
354
+
355
+ $min = '';
356
+
357
+ wp_enqueue_style(
358
+ 'sbi-admin-notifications',
359
+ SBI_PLUGIN_URL . "css/admin-notifications{$min}.css",
360
+ array(),
361
+ SBIVER
362
+ );
363
+
364
+ wp_enqueue_script(
365
+ 'sbi-admin-notifications',
366
+ SBI_PLUGIN_URL . "js/admin-notifications{$min}.js",
367
+ array( 'jquery' ),
368
+ SBIVER,
369
+ true
370
+ );
371
+ }
372
+
373
+ /**
374
+ * Fields from the remote source contain placeholders to allow
375
+ * some messages to be used for multiple plugins.
376
+ *
377
+ * @param $content string
378
+ * @param $notification array
379
+ *
380
+ * @return string
381
+ *
382
+ * @since 2.6/5.9
383
+ */
384
+ public function replace_merge_fields( $content, $notification ) {
385
+ $merge_fields = array(
386
+ '{plugin}' => 'Instagram Feed',
387
+ '{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '',
388
+ '{platform}' => 'Instagram',
389
+ '{lowerplatform}' => 'instagram',
390
+ '{review-url}' => 'https://wordpress.org/support/plugin/instagram-feed/reviews/',
391
+ '{slug}' => 'instagram-feed',
392
+ '{campaign}' => 'instagram-free'
393
+ );
394
+
395
+ if ( sbi_is_pro_version() ) {
396
+ $merge_fields['{campaign}'] = 'instagram-pro';
397
+ $merge_fields['{plugin}'] = 'Instagram Feed Pro';
398
+ }
399
+
400
+ foreach ( $merge_fields as $find => $replace ) {
401
+ $content = str_replace( $find, $replace, $content );
402
+ }
403
+
404
+ return $content;
405
+ }
406
+
407
+ /**
408
+ * Output notifications on Instagram Feed admin area.
409
+ *
410
+ * @since 2.6/5.9
411
+ */
412
+ public function output() {
413
+ $notifications = $this->get();
414
+
415
+ if ( empty( $notifications ) ) {
416
+ return;
417
+ }
418
+
419
+ $notifications_html = '';
420
+ $current_class = ' current';
421
+ $content_allowed_tags = array(
422
+ 'em' => array(),
423
+ 'strong' => array(),
424
+ 'span' => array(
425
+ 'style' => array(),
426
+ ),
427
+ 'a' => array(
428
+ 'href' => array(),
429
+ 'target' => array(),
430
+ 'rel' => array(),
431
+ ),
432
+ );
433
+
434
+ foreach ( $notifications as $notification ) {
435
+
436
+ // Buttons HTML.
437
+ $buttons_html = '';
438
+ if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
439
+ foreach ( $notification['btns'] as $btn_type => $btn ) {
440
+ if ( is_array( $btn['url'] ) ) {
441
+ $btn['url'] = add_query_arg( $btn['url'] );
442
+ }
443
+ if ( ! empty( $btn['attr'] ) ) {
444
+ $btn['target'] = '_blank';
445
+ }
446
+ $buttons_html .= sprintf(
447
+ '<a href="%1$s" class="button button-%2$s"%3$s>%4$s</a>',
448
+ ! empty( $btn['url'] ) ? esc_url( $this->replace_merge_fields( $btn['url'], $notification ) ) : '',
449
+ $btn_type === 'primary' ? 'primary' : 'secondary',
450
+ ! empty( $btn['target'] ) && $btn['target'] === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '',
451
+ ! empty( $btn['text'] ) ? sanitize_text_field( $btn['text'] ) : ''
452
+ );
453
+ }
454
+ $buttons_html = ! empty( $buttons_html ) ? '<div class="buttons">' . $buttons_html . '</div>' : '';
455
+ }
456
+
457
+ if ( empty( $notification['image'] ) ) {
458
+ $image_html = '<div class="bell">';
459
+
460
+ $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>';
461
+ $image_html .= '</div>';
462
+ } else {
463
+ if ( $notification['image'] === 'balloon'
464
+ || $notification['id'] === 'review'
465
+ || $notification['id'] === 'discount') {
466
+ $image_html = '<div class="bell">';
467
+
468
+ $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">';
469
+ $image_html .= ' <path d="M671.51004 492.9884C539.9423 433.8663 402.90125 345.5722 274.97656 304.47286c45.45163 108.39592 83.81332 223.88017 123.51 338.03105C319.308 702.00293 226.8217 748.19258 138.46278 798.51607c75.1914 74.32371 181.67968 117.34651 266.52444 182.01607-67.96124 83.86195-201.48527 171.01801-234.02107 247.01998 140.6922-17.6268 304.63688-46.21031 435.53794-52.00418 28.76427 144.58328 43.5987 303.09763 84.50756 435.53713 60.92033-175.26574 116.0014-356.37317 188.51594-520.0451 111.90644 46.2857 248.29012 102.72607 357.52902 130.01188-76.64636-107.5347-146.59346-221.76948-214.5166-338.02903 100.51162-72.83876 202.1718-144.52451 299.02538-221.02092-136.89514-12.61229-278.73428-20.28827-422.53618-25.99865-22.85288-148.33212-16.84826-325.51604-52.005-461.53983-53.19327 111.4882-115.96694 213.39155-175.51418 318.52497m65.00513 1228.60735c-18.0795 77.37586 41.4876 109.11326 32.50298 156.01215-58.8141-20.268-103.0576-30.67962-182.01567-19.50203 2.47018-60.37036 56.76662-68.90959 45.50432-143.0108C-208.90184 1619.4318-210.59186 99.02478 626.00572 5.44992c1046.0409-117.00405 1078.86445 1689.2596 110.50945 1716.14582" fill="#e34f0e"/>';
470
+ $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"/>';
471
+ $image_html .= '</svg>';
472
+ } else {
473
+ $image_html = '<div class="thumb">';
474
+ $img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
475
+ $image_html .= '<img src="'.esc_url( $img_src ).'" alt="notice">';
476
+
477
+ if ( isset( $notification['image_overlay'] ) ) {
478
+ $image_html .= '<div class="img-overlay">'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'</div>';
479
+ }
480
+ }
481
+ $image_html .= '</div>';
482
+
483
+ }
484
+
485
+ // Notification HTML.
486
+ $notifications_html .= sprintf(
487
+ '<div class="message%5$s" data-message-id="%4$s">' . $image_html . '
488
+ <h3 class="title">%1$s</h3>
489
+ <p class="content">%2$s</p>
490
+ %3$s
491
+ </div>',
492
+ ! empty( $notification['title'] ) ? $this->replace_merge_fields( sanitize_text_field( $notification['title'] ), $notification ) : '',
493
+ ! empty( $notification['content'] ) ? wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ) : '',
494
+ $buttons_html,
495
+ ! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
496
+ $current_class
497
+ );
498
+
499
+ // Only first notification is current.
500
+ $current_class = '';
501
+ }
502
+ ?>
503
+
504
+ <div id="sbi-notifications">
505
+ <a class="dismiss" title="<?php echo esc_attr__( 'Dismiss this message', 'instagram-feed' ); ?>"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
506
+
507
+ <div class="navigation">
508
+ <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>
509
+ <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>
510
+ </div>
511
+
512
+ <div class="messages">
513
+ <?php echo $notifications_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
514
+ </div>
515
+ </div>
516
+ <?php
517
+ }
518
+
519
+ /**
520
+ * Dismiss notification via AJAX. If it's a new user message, also dismiss it
521
+ * on all admin pages.
522
+ *
523
+ * @since 2.6/5.9
524
+ */
525
+ public function dismiss() {
526
+ // Run a security check.
527
+ check_ajax_referer( 'sbi-admin', 'nonce' );
528
+
529
+ // Check for access and required param.
530
+ if ( ! $this->has_access() || empty( $_POST['id'] ) ) {
531
+ wp_send_json_error();
532
+ }
533
+
534
+ $id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
535
+
536
+ if ( $id === 'review' ) {
537
+ $sbi_statuses_option = get_option( 'sbi_statuses', array() );
538
+
539
+ update_option( 'sbi_rating_notice', 'dismissed', false );
540
+ $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
541
+ update_option( 'sbi_statuses', $sbi_statuses_option, false );
542
+ } elseif ( $id === 'discount' ) {
543
+ update_user_meta( get_current_user_id(), 'sbi_ignore_new_user_sale_notice', 'always' );
544
+
545
+ $current_month_number = (int)date('n', sbi_get_current_time() );
546
+ $not_early_in_the_year = ($current_month_number > 5);
547
+
548
+ if ( $not_early_in_the_year ) {
549
+ update_user_meta( get_current_user_id(), 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
550
+ }
551
+ }
552
+
553
+ $option = $this->get_option();
554
+ $type = is_numeric( $id ) ? 'feed' : 'events';
555
+
556
+ $option['dismissed'][] = $id;
557
+ $option['dismissed'] = array_unique( $option['dismissed'] );
558
+
559
+ // Remove notification.
560
+ if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
561
+ foreach ( $option[ $type ] as $key => $notification ) {
562
+ if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons
563
+ unset( $option[ $type ][ $key ] );
564
+ break;
565
+ }
566
+ }
567
+ }
568
+
569
+ update_option( 'sbi_notifications', $option );
570
+
571
+ wp_send_json_success();
572
+ }
573
+ }
inc/admin/main.php CHANGED
@@ -794,6 +794,10 @@ function sb_instagram_settings_page() {
794
  </button>
795
  </div>
796
  <?php endif; ?>
 
 
 
 
797
  <div id="header">
798
  <h1><?php _e( 'Instagram Feed', 'instagram-feed' ); ?></h1>
799
  </div>
@@ -1165,7 +1169,7 @@ function sb_instagram_settings_page() {
1165
  <label><?php _e('Please enter the User ID for this Profile:', 'instagram-feed');?></label>
1166
  <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" />
1167
  </div>
1168
- <p id="sbi_no_js_warning" class="sbi_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>
1169
  <p class="sbi_submit" style="display: inline-block;"><input type="submit" name="sbi_submit" id="sbi_manual_submit" class="button button-primary" value="<?php _e('Connect This Account', 'instagram-feed' );?>"></p>
1170
  </div>
1171
  </td>
794
  </button>
795
  </div>
796
  <?php endif; ?>
797
+
798
+ <?php do_action( 'sbi_admin_overview_before_table' ); ?>
799
+
800
+
801
  <div id="header">
802
  <h1><?php _e( 'Instagram Feed', 'instagram-feed' ); ?></h1>
803
  </div>
1169
  <label><?php _e('Please enter the User ID for this Profile:', 'instagram-feed');?></label>
1170
  <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" />
1171
  </div>
1172
+ <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>
1173
  <p class="sbi_submit" style="display: inline-block;"><input type="submit" name="sbi_submit" id="sbi_manual_submit" class="button button-primary" value="<?php _e('Connect This Account', 'instagram-feed' );?>"></p>
1174
  </div>
1175
  </td>
inc/if-functions.php CHANGED
@@ -775,6 +775,10 @@ function sbi_hextorgb( $hex ) {
775
  return implode( ',', $rgb ); // returns the rgb values separated by commas
776
  }
777
 
 
 
 
 
778
 
779
  /**
780
  * Added to workaround MySQL tables that don't use utf8mb4 character sets
775
  return implode( ',', $rgb ); // returns the rgb values separated by commas
776
  }
777
 
778
+ function sbi_is_url( $input ) {
779
+ return (bool) filter_var( $input, FILTER_VALIDATE_URL );
780
+ }
781
+
782
 
783
  /**
784
  * Added to workaround MySQL tables that don't use utf8mb4 character sets
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.5
7
  Author: Smash Balloon
8
  Author URI: https://smashballoon.com/
9
  License: GPLv2 or later
@@ -23,11 +23,11 @@ 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.5' );
27
  }
28
  // Db version.
29
  if ( ! defined( 'SBI_DBVERSION' ) ) {
30
- define( 'SBI_DBVERSION', '1.5' );
31
  }
32
 
33
  // Upload folder name for local image files for posts
@@ -120,6 +120,14 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
120
 
121
  if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0
122
  && version_compare( get_bloginfo( 'version' ), '4.6' , '>=' ) ) {
 
 
 
 
 
 
 
 
123
  require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/addon-functions.php';
124
  require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/PluginSilentUpgrader.php';
125
  require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/PluginSilentUpgraderSkin.php';
@@ -263,6 +271,13 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
263
 
264
  sbi_update_option( 'sbi_usage_tracking', $usage_tracking, false );
265
  }
 
 
 
 
 
 
 
266
  }
267
 
268
  register_activation_hook( __FILE__, 'sb_instagram_activate' );
@@ -276,6 +291,7 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
276
  wp_clear_scheduled_hook( 'sb_instagram_twicedaily' );
277
  wp_clear_scheduled_hook( 'sb_instagram_cron_job' );
278
  wp_clear_scheduled_hook( 'sb_instagram_feed_issue_email' );
 
279
  }
280
 
281
  register_deactivation_hook( __FILE__, 'sb_instagram_deactivate' );
@@ -510,6 +526,18 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
510
  update_option( 'sbi_db_version', SBI_DBVERSION );
511
  }
512
 
 
 
 
 
 
 
 
 
 
 
 
 
513
 
514
  }
515
 
@@ -600,10 +628,11 @@ if ( function_exists( 'sb_instagram_feed_init' ) ) {
600
  " );
601
  delete_option( 'sbi_usage_tracking_config' );
602
  delete_option( 'sbi_usage_tracking' );
 
 
603
  delete_option( 'sbi_oembed_token' );
604
  delete_option( 'sbi_rating_notice' );
605
  delete_option( 'sbi_refresh_report' );
606
- delete_option( 'sbi_welcome_seen' );
607
 
608
  global $wp_roles;
609
  $wp_roles->remove_cap( 'administrator', 'manage_instagram_feed_options' );
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.5.1
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.5.1' );
27
  }
28
  // Db version.
29
  if ( ! defined( 'SBI_DBVERSION' ) ) {
30
+ define( 'SBI_DBVERSION', '1.6' );
31
  }
32
 
33
  // Upload folder name for local image files for posts
120
 
121
  if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0
122
  && version_compare( get_bloginfo( 'version' ), '4.6' , '>=' ) ) {
123
+ require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/class-sbi-notifications.php';
124
+ $sbi_notifications = new SBI_Notifications();
125
+ $sbi_notifications->init();
126
+
127
+ require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/class-sbi-new-user.php';
128
+ $sbi_newuser = new SBI_New_User();
129
+ $sbi_newuser->init();
130
+
131
  require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/addon-functions.php';
132
  require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/PluginSilentUpgrader.php';
133
  require_once trailingslashit( SBI_PLUGIN_DIR ) . 'inc/admin/PluginSilentUpgraderSkin.php';
271
 
272
  sbi_update_option( 'sbi_usage_tracking', $usage_tracking, false );
273
  }
274
+ if ( ! wp_next_scheduled( 'sbi_notification_update' ) ) {
275
+ $timestamp = strtotime( 'next monday' );
276
+ $timestamp = $timestamp + (3600 * 24 * 7);
277
+ $six_am_local = $timestamp + sbi_get_utc_offset() + (6*60*60);
278
+
279
+ wp_schedule_event( $six_am_local, 'sbiweekly', 'sbi_notification_update' );
280
+ }
281
  }
282
 
283
  register_activation_hook( __FILE__, 'sb_instagram_activate' );
291
  wp_clear_scheduled_hook( 'sb_instagram_twicedaily' );
292
  wp_clear_scheduled_hook( 'sb_instagram_cron_job' );
293
  wp_clear_scheduled_hook( 'sb_instagram_feed_issue_email' );
294
+ wp_clear_scheduled_hook( 'sbi_notification_update' );
295
  }
296
 
297
  register_deactivation_hook( __FILE__, 'sb_instagram_deactivate' );
526
  update_option( 'sbi_db_version', SBI_DBVERSION );
527
  }
528
 
529
+ if ( (float) $db_ver < 1.6 ) {
530
+ if ( ! wp_next_scheduled( 'sbi_notification_update' ) ) {
531
+ $timestamp = strtotime( 'next monday' );
532
+ $timestamp = $timestamp + (3600 * 24 * 7);
533
+ $six_am_local = $timestamp + sbi_get_utc_offset() + (6*60*60);
534
+
535
+ wp_schedule_event( $six_am_local, 'sbiweekly', 'sbi_notification_update' );
536
+ }
537
+
538
+ update_option( 'sbi_db_version', SBI_DBVERSION );
539
+ }
540
+
541
 
542
  }
543
 
628
  " );
629
  delete_option( 'sbi_usage_tracking_config' );
630
  delete_option( 'sbi_usage_tracking' );
631
+ delete_option( 'sbi_notifications' );
632
+ delete_option( 'sbi_newuser_notifications' );
633
  delete_option( 'sbi_oembed_token' );
634
  delete_option( 'sbi_rating_notice' );
635
  delete_option( 'sbi_refresh_report' );
 
636
 
637
  global $wp_roles;
638
  $wp_roles->remove_cap( 'administrator', 'manage_instagram_feed_options' );
js/admin-notifications.js ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * SBI Admin Notifications.
3
+ *
4
+ * @since 2.18
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ var SBIAdminNotifications = window.SBIAdminNotifications || ( function( document, window, $ ) {
10
+
11
+ /**
12
+ * Elements holder.
13
+ *
14
+ * @since 2.18
15
+ *
16
+ * @type {object}
17
+ */
18
+ var el = {
19
+
20
+ $notifications: $( '#sbi-notifications' ),
21
+ $nextButton: $( '#sbi-notifications .navigation .next' ),
22
+ $prevButton: $( '#sbi-notifications .navigation .prev' ),
23
+ $adminBarCounter: $( '#wp-admin-bar-wpforms-menu .sbi-menu-notification-counter' ),
24
+ $adminBarMenuItem: $( '#wp-admin-bar-sbi-notifications' ),
25
+
26
+ };
27
+
28
+ /**
29
+ * Public functions and properties.
30
+ *
31
+ * @since 2.18
32
+ *
33
+ * @type {object}
34
+ */
35
+ var app = {
36
+
37
+ /**
38
+ * Start the engine.
39
+ *
40
+ * @since 2.18
41
+ */
42
+ init: function() {
43
+ el.$notifications.find( '.messages a').each(function() {
44
+ if ($(this).attr('href').indexOf('dismiss=') > -1 ) {
45
+ $(this).addClass('button-dismiss');
46
+ }
47
+ })
48
+
49
+ $( app.ready );
50
+ },
51
+
52
+ /**
53
+ * Document ready.
54
+ *
55
+ * @since 2.18
56
+ */
57
+ ready: function() {
58
+
59
+ app.updateNavigation();
60
+ app.events();
61
+ },
62
+
63
+ /**
64
+ * Register JS events.
65
+ *
66
+ * @since 2.18
67
+ */
68
+ events: function() {
69
+
70
+ el.$notifications
71
+ .on( 'click', '.dismiss', app.dismiss )
72
+ .on( 'click', '.button-dismiss', app.buttonDismiss )
73
+ .on( 'click', '.next', app.navNext )
74
+ .on( 'click', '.prev', app.navPrev );
75
+ },
76
+
77
+ /**
78
+ * Click on a dismiss button.
79
+ *
80
+ * @since 2.18
81
+ */
82
+ buttonDismiss: function( event ) {
83
+ event.preventDefault();
84
+ app.dismiss();
85
+ },
86
+
87
+ /**
88
+ * Click on the Dismiss notification button.
89
+ *
90
+ * @since 2.18
91
+ *
92
+ * @param {object} event Event object.
93
+ */
94
+ dismiss: function( event ) {
95
+
96
+ if ( el.$currentMessage.length === 0 ) {
97
+ return;
98
+ }
99
+
100
+ // Update counter.
101
+ var count = parseInt( el.$adminBarCounter.text(), 10 );
102
+ if ( count > 1 ) {
103
+ --count;
104
+ el.$adminBarCounter.html( '<span>' + count + '</span>' );
105
+ } else {
106
+ el.$adminBarCounter.remove();
107
+ el.$adminBarMenuItem.remove();
108
+ }
109
+
110
+ // Remove notification.
111
+ var $nextMessage = el.$nextMessage.length < 1 ? el.$prevMessage : el.$nextMessage,
112
+ messageId = el.$currentMessage.data( 'message-id' );
113
+
114
+ if ( $nextMessage.length === 0 ) {
115
+ el.$notifications.remove();
116
+ } else {
117
+ el.$currentMessage.remove();
118
+ $nextMessage.addClass( 'current' );
119
+ app.updateNavigation();
120
+ }
121
+
122
+ // AJAX call - update option.
123
+ var data = {
124
+ action: 'sbi_dashboard_notification_dismiss',
125
+ nonce: sbi_admin.nonce,
126
+ id: messageId,
127
+ };
128
+
129
+ $.post( sbi_admin.ajax_url, data, function( res ) {
130
+
131
+ if ( ! res.success ) {
132
+ //SBIAdmin.debug( res );
133
+ }
134
+ } ).fail( function( xhr, textStatus, e ) {
135
+
136
+ //SBIAdmin.debug( xhr.responseText );
137
+ } );
138
+ },
139
+
140
+ /**
141
+ * Click on the Next notification button.
142
+ *
143
+ * @since 2.18
144
+ *
145
+ * @param {object} event Event object.
146
+ */
147
+ navNext: function( event ) {
148
+
149
+ if ( el.$nextButton.hasClass( 'disabled' ) ) {
150
+ return;
151
+ }
152
+
153
+ el.$currentMessage.removeClass( 'current' );
154
+ el.$nextMessage.addClass( 'current' );
155
+
156
+ app.updateNavigation();
157
+ },
158
+
159
+ /**
160
+ * Click on the Previous notification button.
161
+ *
162
+ * @since 2.18
163
+ *
164
+ * @param {object} event Event object.
165
+ */
166
+ navPrev: function( event ) {
167
+
168
+ if ( el.$prevButton.hasClass( 'disabled' ) ) {
169
+ return;
170
+ }
171
+
172
+ el.$currentMessage.removeClass( 'current' );
173
+ el.$prevMessage.addClass( 'current' );
174
+
175
+ app.updateNavigation();
176
+ },
177
+
178
+ /**
179
+ * Update navigation buttons.
180
+ *
181
+ * @since 2.18
182
+ */
183
+ updateNavigation: function() {
184
+
185
+ el.$currentMessage = el.$notifications.find( '.message.current' );
186
+ el.$nextMessage = el.$currentMessage.next( '.message' );
187
+ el.$prevMessage = el.$currentMessage.prev( '.message' );
188
+
189
+ if ( el.$nextMessage.length === 0 ) {
190
+ el.$nextButton.addClass( 'disabled' );
191
+ } else {
192
+ el.$nextButton.removeClass( 'disabled' );
193
+ }
194
+
195
+ if ( el.$prevMessage.length === 0 ) {
196
+ el.$prevButton.addClass( 'disabled' );
197
+ } else {
198
+ el.$prevButton.removeClass( 'disabled' );
199
+ }
200
+ },
201
+ };
202
+
203
+ return app;
204
+
205
+ }( document, window, jQuery ) );
206
+
207
+ // Initialize.
208
+ SBIAdminNotifications.init();
languages/instagram-feed.pot CHANGED
@@ -107,9 +107,9 @@ msgstr ""
107
  #: inc/admin/actions.php:1073
108
  #, php-format
109
  msgid ""
110
- "<b style=\"font-weight: 700;\">Exclusive offer!</b> We don't run promotions "
111
  "very often, but for a limited time we're offering <b style=\"font-weight: "
112
- "700;\">20% off</b> our Pro version to all users of our free Instagram Feed "
113
  "plugin."
114
  msgstr ""
115
 
@@ -124,9 +124,9 @@ msgstr ""
124
  #: inc/admin/actions.php:1091
125
  #, php-format
126
  msgid ""
127
- "<b style=\"font-weight: 700;\">Black Friday/Cyber Monday Deal!</b> Thank you "
128
  "for using our free Instagram Feed plugin. For a limited time, we're offering "
129
- "<b style=\"font-weight: 700;\">20% off</b> the Pro version for all of our "
130
  "users."
131
  msgstr ""
132
 
107
  #: inc/admin/actions.php:1073
108
  #, php-format
109
  msgid ""
110
+ "<b style=\"font-weight: 900;\">Exclusive offer!</b> We don't run promotions "
111
  "very often, but for a limited time we're offering <b style=\"font-weight: "
112
+ "900;\">60% off</b> our Pro version to all users of our free Instagram Feed "
113
  "plugin."
114
  msgstr ""
115
 
124
  #: inc/admin/actions.php:1091
125
  #, php-format
126
  msgid ""
127
+ "<b style=\"font-weight: 900;\">Black Friday/Cyber Monday Deal!</b> Thank you "
128
  "for using our free Instagram Feed plugin. For a limited time, we're offering "
129
+ "<b style=\"font-weight: 900;\">60% off</b> the Pro version for all of our "
130
  "users."
131
  msgstr ""
132
 
templates/feed.php CHANGED
@@ -3,7 +3,7 @@
3
  * Smash Balloon Instagram Feed Main Template
4
  * Creates the wrapping HTML and adds settings as attributes
5
  *
6
- * @version 2.2 Instagram Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
3
  * Smash Balloon Instagram Feed Main Template
4
  * Creates the wrapping HTML and adds settings as attributes
5
  *
6
+ * @version 2.5 Instagram Feed by Smash Balloon
7
  *
8
  */
9
  // Don't load directly
templates/footer.php CHANGED
@@ -3,7 +3,7 @@
3
  * Smash Balloon Instagram Feed Footer Template
4
  * Adds pagination and html for errors and resized images
5
  *
6
- * @version 2.2 Instagram Feed by Smash Balloon
7
  *
8
  */
9
 
@@ -26,7 +26,7 @@ $load_button_text = __( $settings['buttontext'], 'instagram-feed' );
26
  <?php if ( $use_pagination ) : ?>
27
  <a class="sbi_load_btn" href="javascript:void(0);" <?php echo $load_btn_style; ?>>
28
  <span class="sbi_btn_text"><?php echo esc_html( $load_button_text ); ?></span>
29
- <span class="sbi_loader sbi_hidden" style="background-color: rgb(255, 255, 255);"></span>
30
  </a>
31
  <?php endif; ?>
32
 
3
  * Smash Balloon Instagram Feed Footer Template
4
  * Adds pagination and html for errors and resized images
5
  *
6
+ * @version 2.5 Instagram Feed by Smash Balloon
7
  *
8
  */
9
 
26
  <?php if ( $use_pagination ) : ?>
27
  <a class="sbi_load_btn" href="javascript:void(0);" <?php echo $load_btn_style; ?>>
28
  <span class="sbi_btn_text"><?php echo esc_html( $load_button_text ); ?></span>
29
+ <span class="sbi_loader sbi_hidden" style="background-color: rgb(255, 255, 255);" aria-hidden="true"></span>
30
  </a>
31
  <?php endif; ?>
32
 
templates/header.php CHANGED
@@ -3,7 +3,7 @@
3
  * Smash Balloon Instagram Feed Header Template
4
  * Adds account information and an avatar to the top of the feed
5
  *
6
- * @version 2.2 Instagram Feed by Smash Balloon
7
  *
8
  */
9
 
3
  * Smash Balloon Instagram Feed Header Template
4
  * Adds account information and an avatar to the top of the feed
5
  *
6
+ * @version 2.5 Instagram Feed by Smash Balloon
7
  *
8
  */
9
 
templates/item.php CHANGED
@@ -3,7 +3,7 @@
3
  * Smash Balloon Instagram Feed Item Template
4
  * Adds an image, link, and other data for each post in the feed
5
  *
6
- * @version 2.2 Instagram Feed by Smash Balloon
7
  *
8
  */
9
 
3
  * Smash Balloon Instagram Feed Item Template
4
  * Adds an image, link, and other data for each post in the feed
5
  *
6
+ * @version 2.5 Instagram Feed by Smash Balloon
7
  *
8
  */
9