Version Description
- Tweak: Added support for improved dashboard notices on the plugin settings page.
- Tweak: HTML attribute rel="noopener noreferrer" added to all outbound links for extra security.
- Fix: Fixed PHP warning "non-numeric value encountered" when setting the tweet multiplier option to something that wasn't a number.
Download this release
Release Info
Developer | smashballoon |
Plugin | Custom Twitter Feeds |
Version | 1.6.1 |
Comparing to | |
See all releases |
Code changes from version 1.6 to 1.6.1
- README.txt +7 -2
- css/admin-notifications.css +171 -0
- css/ctf-admin-styles.css +43 -27
- custom-twitter-feed.php +15 -2
- img/ctf-icon.png +0 -0
- inc/CtfAdmin.php +1 -1
- inc/CtfFeed.php +22 -22
- inc/admin-hooks.php +2 -2
- inc/admin/class-ctf-new-user.php +396 -0
- inc/admin/class-ctf-notifications.php +581 -0
- inc/notices.php +1 -241
- js/admin-notifications.js +208 -0
- uninstall.php +2 -0
- views/admin/main.php +3 -1
README.txt
CHANGED
@@ -4,8 +4,8 @@ Contributors: smashballoon, craig-at-smash-balloon
|
|
4 |
Support Website: http://smashballoon/custom-twitter-feeds/
|
5 |
Tags: Twitter, Twitter feed, Twitter Tweets, Twitter widget, Custom Twitter Feed
|
6 |
Requires at least: 3.4
|
7 |
-
Tested up to: 5.
|
8 |
-
Stable tag: 1.6
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -233,6 +233,11 @@ If you're still having trouble displaying your Tweets after trying the common is
|
|
233 |
7. To display a Twitter feed just copy and paste the shortcode into a Twitter widget or page
|
234 |
|
235 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
236 |
= 1.6 =
|
237 |
* New: Updated icons in the feed to match Twitter.
|
238 |
* Tweak: Several CSS changes to make the Twitter feed text responsive with more themes.
|
4 |
Support Website: http://smashballoon/custom-twitter-feeds/
|
5 |
Tags: Twitter, Twitter feed, Twitter Tweets, Twitter widget, Custom Twitter Feed
|
6 |
Requires at least: 3.4
|
7 |
+
Tested up to: 5.6
|
8 |
+
Stable tag: 1.6.1
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
233 |
7. To display a Twitter feed just copy and paste the shortcode into a Twitter widget or page
|
234 |
|
235 |
== Changelog ==
|
236 |
+
= 1.6.1 =
|
237 |
+
* Tweak: Added support for improved dashboard notices on the plugin settings page.
|
238 |
+
* Tweak: HTML attribute rel="noopener noreferrer" added to all outbound links for extra security.
|
239 |
+
* Fix: Fixed PHP warning "non-numeric value encountered" when setting the tweet multiplier option to something that wasn't a number.
|
240 |
+
|
241 |
= 1.6 =
|
242 |
* New: Updated icons in the feed to match Twitter.
|
243 |
* Tweak: Several CSS changes to make the Twitter feed text responsive with more themes.
|
css/admin-notifications.css
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ctf-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 |
+
#ctf-notifications * {
|
13 |
+
box-sizing: border-box;
|
14 |
+
}
|
15 |
+
|
16 |
+
#ctf-notifications .bell,
|
17 |
+
#ctf-notifications .thumb{
|
18 |
+
position: absolute;
|
19 |
+
top: 15px;
|
20 |
+
left: 15px;
|
21 |
+
width: 42px;
|
22 |
+
height: 48px;
|
23 |
+
}
|
24 |
+
#ctf-notifications .thumb img {
|
25 |
+
max-width: 100%;
|
26 |
+
}
|
27 |
+
#ctf-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 |
+
#ctf-notifications .messages .message {
|
43 |
+
display: none;
|
44 |
+
}
|
45 |
+
|
46 |
+
#ctf-notifications .messages .message.current {
|
47 |
+
display: block;
|
48 |
+
}
|
49 |
+
|
50 |
+
#ctf-notifications .messages .message .title {
|
51 |
+
font-weight: bold;
|
52 |
+
font-size: 17px;
|
53 |
+
line-height: 20px;
|
54 |
+
margin: 0;
|
55 |
+
color: #444;
|
56 |
+
}
|
57 |
+
|
58 |
+
#ctf-notifications .messages .message .content {
|
59 |
+
font-weight: normal;
|
60 |
+
font-size: 13px;
|
61 |
+
line-height: 20px;
|
62 |
+
margin: 6px 0 40px 0;
|
63 |
+
}
|
64 |
+
|
65 |
+
#ctf-notifications .messages .message .buttons {
|
66 |
+
margin: -30px 80px 0 0;
|
67 |
+
}
|
68 |
+
|
69 |
+
#ctf-notifications .messages .message .buttons a {
|
70 |
+
margin: 0 6px 0 0;
|
71 |
+
padding: 8px 10px;
|
72 |
+
line-height: 13px;
|
73 |
+
font-size: 13px;
|
74 |
+
min-height: unset;
|
75 |
+
}
|
76 |
+
|
77 |
+
#ctf-notifications .messages .message .buttons .button-secondary {
|
78 |
+
border: 1px solid #0071A1;
|
79 |
+
}
|
80 |
+
|
81 |
+
#ctf-notifications .dismiss {
|
82 |
+
position: absolute;
|
83 |
+
top: 15px;
|
84 |
+
right: 15px;
|
85 |
+
width: 16px;
|
86 |
+
height: 16px;
|
87 |
+
color: #72777C;
|
88 |
+
font-size: 16px;
|
89 |
+
cursor: pointer;
|
90 |
+
text-align: center;
|
91 |
+
vertical-align: middle;
|
92 |
+
line-height: 16px;
|
93 |
+
}
|
94 |
+
|
95 |
+
#ctf-notifications .dismiss:hover {
|
96 |
+
color: #dc3232;
|
97 |
+
}
|
98 |
+
|
99 |
+
#ctf-notifications .navigation {
|
100 |
+
position: absolute;
|
101 |
+
bottom: 15px;
|
102 |
+
right: 15px;
|
103 |
+
width: 63px;
|
104 |
+
height: 30px;
|
105 |
+
}
|
106 |
+
|
107 |
+
#ctf-notifications .navigation a {
|
108 |
+
display: block;
|
109 |
+
width: 30px;
|
110 |
+
height: 30px;
|
111 |
+
border: 1px solid #7E8993;
|
112 |
+
border-radius: 3px;
|
113 |
+
font-size: 8px;
|
114 |
+
text-align: center;
|
115 |
+
vertical-align: middle;
|
116 |
+
line-height: 30px;
|
117 |
+
cursor: pointer;
|
118 |
+
background-color: #ffffff;
|
119 |
+
color: #41454A;
|
120 |
+
}
|
121 |
+
#ctf-notifications .navigation svg {
|
122 |
+
width: 8px;
|
123 |
+
height: 8px;
|
124 |
+
}
|
125 |
+
|
126 |
+
#ctf-notifications .navigation a:hover {
|
127 |
+
background-color: #f1f1f1;
|
128 |
+
}
|
129 |
+
|
130 |
+
#ctf-notifications .navigation .prev {
|
131 |
+
float: left;
|
132 |
+
}
|
133 |
+
|
134 |
+
#ctf-notifications .navigation .next {
|
135 |
+
float: right;
|
136 |
+
}
|
137 |
+
|
138 |
+
#ctf-notifications .navigation .disabled {
|
139 |
+
border-color: #dddddd;
|
140 |
+
color: #A0A5AA;
|
141 |
+
cursor: default;
|
142 |
+
}
|
143 |
+
|
144 |
+
#ctf-notifications .navigation .disabled:hover {
|
145 |
+
background-color: #ffffff;
|
146 |
+
}
|
147 |
+
|
148 |
+
@media screen and (max-width: 768px) {
|
149 |
+
#ctf-notifications {
|
150 |
+
padding: 15px 15px 15px 72px;
|
151 |
+
}
|
152 |
+
#ctf-notifications .messages .message .title {
|
153 |
+
margin: 0 30px 0 0;
|
154 |
+
}
|
155 |
+
#ctf-notifications .messages .message .content {
|
156 |
+
font-size: 16px;
|
157 |
+
line-height: 24px;
|
158 |
+
}
|
159 |
+
#ctf-notifications .messages .message .buttons {
|
160 |
+
margin: -30px 80px 0 0;
|
161 |
+
}
|
162 |
+
#ctf-notifications .messages .message .buttons a {
|
163 |
+
margin: 0;
|
164 |
+
display: table;
|
165 |
+
}
|
166 |
+
#ctf-notifications .messages .message .buttons .button-secondary {
|
167 |
+
margin-top: 6px;
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2Nzcy9hZG1pbi1ub3RpZmljYXRpb25zLmNzcyIsInNvdXJjZXMiOlsiYXNzZXRzL3Njc3MvYWRtaW4tbm90aWZpY2F0aW9ucy5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEFkbWluIG5vdGlmaWNhdGlvbiBzdHlsZXMuXG5cbiN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXG5cdHBvc2l0aW9uOiByZWxhdGl2ZTtcblx0YmFja2dyb3VuZDogI0ZGRkZGRiAwIDAgbm8tcmVwZWF0IHBhZGRpbmctYm94O1xuXHRib3gtc2hhZG93OiAwcHggNXB4IDE1cHggIzAwMDAwMDBEO1xuXHRib3JkZXItcmFkaXVzOiA2cHg7XG5cdG9wYWNpdHk6IDE7XG5cdG1pbi1oZWlnaHQ6IDQ4cHg7XG5cdHBhZGRpbmc6IDE1cHggMTAycHggMTVweCA3MnB4O1xuXHRtYXJnaW46IDAgMCAxNHB4IDA7XG5cblx0KiB7XG5cdFx0Ym94LXNpemluZzogYm9yZGVyLWJveDtcblx0fVxuXG5cdC5iZWxsIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdGxlZnQ6IDE1cHg7XG5cdFx0d2lkdGg6IDQycHg7XG5cdFx0aGVpZ2h0OiA0OHB4O1xuXHR9XG5cblx0Lm1lc3NhZ2VzIHtcblx0XHQubWVzc2FnZSB7XG5cdFx0XHRkaXNwbGF5OiBub25lO1xuXG5cdFx0XHQmLmN1cnJlbnQge1xuXHRcdFx0XHRkaXNwbGF5OiBibG9jaztcblx0XHRcdH1cblxuXHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IGJvbGQ7XG5cdFx0XHRcdGZvbnQtc2l6ZTogMTdweDtcblx0XHRcdFx0bGluZS1oZWlnaHQ6IDIwcHg7XG5cdFx0XHRcdG1hcmdpbjogMDtcblx0XHRcdFx0Y29sb3I6ICM0NDQ7XG5cdFx0XHR9XG5cblx0XHRcdC5jb250ZW50IHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IG5vcm1hbDtcblx0XHRcdFx0Zm9udC1zaXplOiAxM3B4O1xuXHRcdFx0XHRsaW5lLWhlaWdodDogMjBweDtcblx0XHRcdFx0bWFyZ2luOiA2cHggMCA0MHB4IDA7XG5cdFx0XHR9XG5cblx0XHRcdC5idXR0b25zIHtcblx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRhIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgNnB4IDAgMDtcblx0XHRcdFx0XHRwYWRkaW5nOiA4cHggMTBweDtcblx0XHRcdFx0XHRsaW5lLWhlaWdodDogMTNweDtcblx0XHRcdFx0XHRmb250LXNpemU6IDEzcHg7XG5cdFx0XHRcdFx0bWluLWhlaWdodDogdW5zZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9uLXNlY29uZGFyeSB7XG5cdFx0XHRcdFx0Ym9yZGVyOiAxcHggc29saWQgIzAwNzFBMTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC5kaXNtaXNzIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdHJpZ2h0OiAxNXB4O1xuXHRcdHdpZHRoOiAxNnB4O1xuXHRcdGhlaWdodDogMTZweDtcblx0XHRjb2xvcjogIzcyNzc3Qztcblx0XHRmb250LXNpemU6IDE2cHg7XG5cdFx0Y3Vyc29yOiBwb2ludGVyO1xuXHRcdHRleHQtYWxpZ246IGNlbnRlcjtcblx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdGxpbmUtaGVpZ2h0OiAxNnB4O1xuXG5cdFx0Jjpob3ZlciB7XG5cdFx0XHRjb2xvcjogI2RjMzIzMjtcblx0XHR9XG5cdH1cblxuXHQubmF2aWdhdGlvbiB7XG5cdFx0cG9zaXRpb246IGFic29sdXRlO1xuXHRcdGJvdHRvbTogMTVweDtcblx0XHRyaWdodDogMTVweDtcblx0XHR3aWR0aDogNjNweDtcblx0XHRoZWlnaHQ6IDMwcHg7XG5cblx0XHRhIHtcblx0XHRcdGRpc3BsYXk6IGJsb2NrO1xuXHRcdFx0d2lkdGg6IDMwcHg7XG5cdFx0XHRoZWlnaHQ6IDMwcHg7XG5cdFx0XHRib3JkZXI6IDFweCBzb2xpZCAjN0U4OTkzO1xuXHRcdFx0Ym9yZGVyLXJhZGl1czogM3B4O1xuXHRcdFx0Zm9udC1zaXplOiA4cHg7XG5cdFx0XHR0ZXh0LWFsaWduOiBjZW50ZXI7XG5cdFx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdFx0bGluZS1oZWlnaHQ6IDMwcHg7XG5cdFx0XHRjdXJzb3I6IHBvaW50ZXI7XG5cdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0Y29sb3I6ICM0MTQ1NEE7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZjFmMWYxO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC5wcmV2IHtcblx0XHRcdGZsb2F0OiBsZWZ0O1xuXHRcdH1cblxuXHRcdC5uZXh0IHtcblx0XHRcdGZsb2F0OiByaWdodDtcblx0XHR9XG5cblx0XHQuZGlzYWJsZWQge1xuXHRcdFx0Ym9yZGVyLWNvbG9yOiAjZGRkZGRkO1xuXHRcdFx0Y29sb3I6ICNBMEE1QUE7XG5cdFx0XHRjdXJzb3I6IGRlZmF1bHQ7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3NjhweCkge1xuXG5cdCN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXHRcdHBhZGRpbmc6IDE1cHggMTVweCAxNXB4IDcycHg7XG5cblx0XHQubWVzc2FnZXMge1xuXG5cdFx0XHQubWVzc2FnZSB7XG5cblx0XHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgMzBweCAwIDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuY29udGVudCB7XG5cdFx0XHRcdFx0Zm9udC1zaXplOiAxNnB4O1xuXHRcdFx0XHRcdGxpbmUtaGVpZ2h0OiAyNHB4XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9ucyB7XG5cdFx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRcdGEge1xuXHRcdFx0XHRcdFx0bWFyZ2luOiAwO1xuXHRcdFx0XHRcdFx0ZGlzcGxheTogdGFibGU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0LmJ1dHRvbi1zZWNvbmRhcnkge1xuXHRcdFx0XHRcdFx0bWFyZ2luLXRvcDogNnB4O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxBQUFBLHNCQUFzQixDQUFDO0VBRXRCLFFBQVEsRUFBRSxRQUFRO0VBQ2xCLFVBQVUsRUFBRSxpQ0FBaUM7RUFDN0MsVUFBVSxFQUFFLHNCQUFzQjtFQUNsQyxhQUFhLEVBQUUsR0FBRztFQUNsQixPQUFPLEVBQUUsQ0FBQztFQUNWLFVBQVUsRUFBRSxJQUFJO0VBQ2hCLE9BQU8sRUFBRSxvQkFBb0I7RUFDN0IsTUFBTSxFQUFFLFVBQVU7Q0FxSGxCOztBQTlIRCxBQVdDLHNCQVhxQixDQVdyQixDQUFDLENBQUM7RUFDRCxVQUFVLEVBQUUsVUFBVTtDQUN0Qjs7QUFiRixBQWVDLHNCQWZxQixDQWVyQixLQUFLLENBQUM7RUFDTCxRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULElBQUksRUFBRSxJQUFJO0VBQ1YsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtDQUNaOztBQXJCRixBQXdCRSxzQkF4Qm9CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQUFDO0VBQ1IsT0FBTyxFQUFFLElBQUk7Q0FvQ2I7O0FBN0RILEFBMkJHLHNCQTNCbUIsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLEFBR04sUUFBUSxDQUFDO0VBQ1QsT0FBTyxFQUFFLEtBQUs7Q0FDZDs7QUE3QkosQUErQkcsc0JBL0JtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FPUCxNQUFNLENBQUM7RUFDTixXQUFXLEVBQUUsSUFBSTtFQUNqQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxDQUFDO0VBQ1QsS0FBSyxFQUFFLElBQUk7Q0FDWDs7QUFyQ0osQUF1Q0csc0JBdkNtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FlUCxRQUFRLENBQUM7RUFDUixXQUFXLEVBQUUsTUFBTTtFQUNuQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxZQUFZO0NBQ3BCOztBQTVDSixBQThDRyxzQkE5Q21CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQXNCUCxRQUFRLENBQUM7RUFDUixNQUFNLEVBQUUsY0FBYztDQWF0Qjs7QUE1REosQUFpREksc0JBakRrQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FzQlAsUUFBUSxDQUdQLENBQUMsQ0FBQztFQUNELE1BQU0sRUFBRSxTQUFTO0VBQ2pCLE9BQU8sRUFBRSxRQUFRO0VBQ2pCLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLFNBQVMsRUFBRSxJQUFJO0VBQ2YsVUFBVSxFQUFFLEtBQUs7Q0FDakI7O0FBdkRMLEFBeURJLHNCQXpEa0IsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLENBc0JQLFFBQVEsQ0FXUCxpQkFBaUIsQ0FBQztFQUNqQixNQUFNLEVBQUUsaUJBQWlCO0NBQ3pCOztBQTNETCxBQWdFQyxzQkFoRXFCLENBZ0VyQixRQUFRLENBQUM7RUFDUixRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULEtBQUssRUFBRSxJQUFJO0VBQ1gsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtFQUNaLEtBQUssRUFBRSxPQUFPO0VBQ2QsU0FBUyxFQUFFLElBQUk7RUFDZixNQUFNLEVBQUUsT0FBTztFQUNmLFVBQVUsRUFBRSxNQUFNO0VBQ2xCLGNBQWMsRUFBRSxNQUFNO0VBQ3RCLFdBQVcsRUFBRSxJQUFJO0NBS2pCOztBQWhGRixBQTZFRSxzQkE3RW9CLENBZ0VyQixRQUFRLEFBYU4sTUFBTSxDQUFDO0VBQ1AsS0FBSyxFQUFFLE9BQU87Q0FDZDs7QUEvRUgsQUFrRkMsc0JBbEZxQixDQWtGckIsV0FBVyxDQUFDO0VBQ1gsUUFBUSxFQUFFLFFBQVE7RUFDbEIsTUFBTSxFQUFFLElBQUk7RUFDWixLQUFLLEVBQUUsSUFBSTtFQUNYLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7Q0FzQ1o7O0FBN0hGLEFBeUZFLHNCQXpGb0IsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLENBQUM7RUFDRCxPQUFPLEVBQUUsS0FBSztFQUNkLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7RUFDWixNQUFNLEVBQUUsaUJBQWlCO0VBQ3pCLGFBQWEsRUFBRSxHQUFHO0VBQ2xCLFNBQVMsRUFBRSxHQUFHO0VBQ2QsVUFBVSxFQUFFLE1BQU07RUFDbEIsY0FBYyxFQUFFLE1BQU07RUFDdEIsV0FBVyxFQUFFLElBQUk7RUFDakIsTUFBTSxFQUFFLE9BQU87RUFDZixnQkFBZ0IsRUFBRSxPQUFPO0VBQ3pCLEtBQUssRUFBRSxPQUFPO0NBS2Q7O0FBMUdILEFBdUdHLHNCQXZHbUIsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLEFBY0MsTUFBTSxDQUFDO0VBQ1AsZ0JBQWdCLEVBQUUsT0FBTztDQUN6Qjs7QUF6R0osQUE0R0Usc0JBNUdvQixDQWtGckIsV0FBVyxDQTBCVixLQUFLLENBQUM7RUFDTCxLQUFLLEVBQUUsSUFBSTtDQUNYOztBQTlHSCxBQWdIRSxzQkFoSG9CLENBa0ZyQixXQUFXLENBOEJWLEtBQUssQ0FBQztFQUNMLEtBQUssRUFBRSxLQUFLO0NBQ1o7O0FBbEhILEFBb0hFLHNCQXBIb0IsQ0FrRnJCLFdBQVcsQ0FrQ1YsU0FBUyxDQUFDO0VBQ1QsWUFBWSxFQUFFLE9BQU87RUFDckIsS0FBSyxFQUFFLE9BQU87RUFDZCxNQUFNLEVBQUUsT0FBTztDQUtmOztBQTVISCxBQXlIRyxzQkF6SG1CLENBa0ZyQixXQUFXLENBa0NWLFNBQVMsQUFLUCxNQUFNLENBQUM7RUFDUCxnQkFBZ0IsRUFBRSxPQUFPO0NBQ3pCOztBQUtKLE1BQU0sQ0FBQyxNQUFNLE1BQU0sU0FBUyxFQUFFLEtBQUs7RUFFbEMsQUFBQSxzQkFBc0IsQ0FBQztJQUN0QixPQUFPLEVBQUUsbUJBQW1CO0dBNkI1QjtFQTlCRCxBQU9HLHNCQVBtQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQUVQLE1BQU0sQ0FBQztJQUNOLE1BQU0sRUFBRSxVQUFVO0dBQ2xCO0VBVEosQUFXRyxzQkFYbUIsQ0FHckIsU0FBUyxDQUVSLFFBQVEsQ0FNUCxRQUFRLENBQUM7SUFDUixTQUFTLEVBQUUsSUFBSTtJQUNmLFdBQVcsRUFBRSxJQUNkO0dBQUM7RUFkSixBQWdCRyxzQkFoQm1CLENBR3JCLFNBQVMsQ0FFUixRQUFRLENBV1AsUUFBUSxDQUFDO0lBQ1IsTUFBTSxFQUFFLGNBQWM7R0FVdEI7RUEzQkosQUFtQkksc0JBbkJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FHUCxDQUFDLENBQUM7SUFDRCxNQUFNLEVBQUUsQ0FBQztJQUNULE9BQU8sRUFBRSxLQUFLO0dBQ2Q7RUF0QkwsQUF3Qkksc0JBeEJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FRUCxpQkFBaUIsQ0FBQztJQUNqQixVQUFVLEVBQUUsR0FBRztHQUNmIn0= */
|
css/ctf-admin-styles.css
CHANGED
@@ -198,7 +198,7 @@
|
|
198 |
}
|
199 |
|
200 |
/* Error notice */
|
201 |
-
#ctf-admin .
|
202 |
margin-top: 5px;
|
203 |
background: #f9ecda;
|
204 |
padding: 5px 10px;
|
@@ -209,14 +209,14 @@
|
|
209 |
-webkit-border-radius: 3px;
|
210 |
border-radius: 3px;
|
211 |
}
|
212 |
-
#ctf-admin .
|
213 |
color: #d85600;
|
214 |
}
|
215 |
-
#ctf-admin .
|
216 |
-
#ctf-admin .
|
217 |
color: #a34100;
|
218 |
}
|
219 |
-
#ctf-admin .
|
220 |
margin: 0;
|
221 |
padding: 5px 0;
|
222 |
font-size: 13px;
|
@@ -236,7 +236,7 @@
|
|
236 |
}
|
237 |
|
238 |
/* Review notice */
|
239 |
-
.
|
240 |
position: relative;
|
241 |
overflow: hidden;
|
242 |
max-width: 870px;
|
@@ -247,11 +247,9 @@
|
|
247 |
border: 1px solid #6AB074;
|
248 |
color: #214F28;
|
249 |
}
|
250 |
-
.
|
251 |
-
|
252 |
-
|
253 |
-
}
|
254 |
-
.ctf_review_notice img{
|
255 |
width: 74px;
|
256 |
margin: 0 0 0 -100% !important;
|
257 |
|
@@ -259,13 +257,31 @@
|
|
259 |
-webkit-border-radius: 4px;
|
260 |
border-radius: 4px;
|
261 |
}
|
262 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
float: left;
|
264 |
clear: none;
|
265 |
width: 100%;
|
266 |
padding: 0;
|
267 |
}
|
268 |
-
.
|
269 |
float: left;
|
270 |
clear: both;
|
271 |
width: auto;
|
@@ -273,37 +289,37 @@
|
|
273 |
padding: 2px 40px 2px 0;
|
274 |
line-height: 1.4;
|
275 |
}
|
276 |
-
.
|
277 |
margin-top: 4px !important;
|
278 |
}
|
279 |
-
.
|
280 |
display: inline-block;
|
281 |
padding: 0 8px;
|
282 |
color: #178529;
|
283 |
}
|
284 |
-
.
|
285 |
-
.
|
286 |
color: #0c7abf;
|
287 |
}
|
288 |
-
.
|
289 |
margin: 0 0 0 82px !important;
|
290 |
padding: 4px 0 0 0;
|
291 |
margin-top: 6px !important;
|
292 |
}
|
293 |
-
.
|
294 |
-
.
|
295 |
-
.
|
296 |
position: absolute;
|
297 |
top: 0;
|
298 |
right: 0;
|
299 |
padding: 10px;
|
300 |
line-height: 1;
|
301 |
}
|
302 |
-
.
|
303 |
-
.
|
304 |
color: #a34100;
|
305 |
}
|
306 |
-
.
|
307 |
padding: 4px 12px 6px 12px;
|
308 |
background: green;
|
309 |
color: #fff;
|
@@ -312,16 +328,16 @@
|
|
312 |
text-decoration: none;
|
313 |
margin-left: 0;
|
314 |
}
|
315 |
-
.
|
316 |
background: #049404;
|
317 |
color: #fff;
|
318 |
}
|
319 |
-
.
|
320 |
padding-top: 10px;
|
321 |
font-style: italic;
|
322 |
font-size: 12px;
|
323 |
}
|
324 |
-
.
|
325 |
padding: 0;
|
326 |
}
|
327 |
|
198 |
}
|
199 |
|
200 |
/* Error notice */
|
201 |
+
#ctf-admin .ctf_error_notice, .ctf_error_notice{
|
202 |
margin-top: 5px;
|
203 |
background: #f9ecda;
|
204 |
padding: 5px 10px;
|
209 |
-webkit-border-radius: 3px;
|
210 |
border-radius: 3px;
|
211 |
}
|
212 |
+
#ctf-admin .ctf_error_notice a, .ctf_error_notice a{
|
213 |
color: #d85600;
|
214 |
}
|
215 |
+
#ctf-admin .ctf_error_notice a:hover, .ctf_error_notice a:hover,
|
216 |
+
#ctf-admin .ctf_error_notice a:focus, .ctf_error_notice a:focus{
|
217 |
color: #a34100;
|
218 |
}
|
219 |
+
#ctf-admin .ctf_error_notice p, .ctf_error_notice p{
|
220 |
margin: 0;
|
221 |
padding: 5px 0;
|
222 |
font-size: 13px;
|
236 |
}
|
237 |
|
238 |
/* Review notice */
|
239 |
+
.ctf_notice {
|
240 |
position: relative;
|
241 |
overflow: hidden;
|
242 |
max-width: 870px;
|
247 |
border: 1px solid #6AB074;
|
248 |
color: #214F28;
|
249 |
}
|
250 |
+
.ctf_notice .ctf_thumb{
|
251 |
+
position: relative;
|
252 |
+
display: inline-block;
|
|
|
|
|
253 |
width: 74px;
|
254 |
margin: 0 0 0 -100% !important;
|
255 |
|
257 |
-webkit-border-radius: 4px;
|
258 |
border-radius: 4px;
|
259 |
}
|
260 |
+
.ctf_notice .ctf_thumb .img-overlay {
|
261 |
+
position: absolute;
|
262 |
+
top: 3px;
|
263 |
+
padding: 6px 5px;
|
264 |
+
font-size: 12px;
|
265 |
+
font-weight: bold;
|
266 |
+
background: #fff;
|
267 |
+
line-height: 1;
|
268 |
+
color: #000;
|
269 |
+
opacity: .8;
|
270 |
+
}
|
271 |
+
.ctf_notice img{
|
272 |
+
width: 74px;
|
273 |
+
|
274 |
+
-moz-border-radius: 4px;
|
275 |
+
-webkit-border-radius: 4px;
|
276 |
+
border-radius: 4px;
|
277 |
+
}
|
278 |
+
.ctf_notice .ctf-notice-text{
|
279 |
float: left;
|
280 |
clear: none;
|
281 |
width: 100%;
|
282 |
padding: 0;
|
283 |
}
|
284 |
+
.ctf_notice p{
|
285 |
float: left;
|
286 |
clear: both;
|
287 |
width: auto;
|
289 |
padding: 2px 40px 2px 0;
|
290 |
line-height: 1.4;
|
291 |
}
|
292 |
+
.ctf_notice .ctf-links{
|
293 |
margin-top: 4px !important;
|
294 |
}
|
295 |
+
.ctf_notice a{
|
296 |
display: inline-block;
|
297 |
padding: 0 8px;
|
298 |
color: #178529;
|
299 |
}
|
300 |
+
.ctf_notice a:hover,
|
301 |
+
.ctf_notice a:focus{
|
302 |
color: #0c7abf;
|
303 |
}
|
304 |
+
.ctf_notice .links{
|
305 |
margin: 0 0 0 82px !important;
|
306 |
padding: 4px 0 0 0;
|
307 |
margin-top: 6px !important;
|
308 |
}
|
309 |
+
.ctf_notice .ctf_notice_close,
|
310 |
+
.ctf_notice .ctf_bfcm_sale_notice_close,
|
311 |
+
.ctf_notice .ctf_new_user_sale_notice_close {
|
312 |
position: absolute;
|
313 |
top: 0;
|
314 |
right: 0;
|
315 |
padding: 10px;
|
316 |
line-height: 1;
|
317 |
}
|
318 |
+
.ctf_notice .ctf_notice_close:hover,
|
319 |
+
.ctf_notice .ctf_notice_close:focus{
|
320 |
color: #a34100;
|
321 |
}
|
322 |
+
.ctf_notice .ctf_offer_btn {
|
323 |
padding: 4px 12px 6px 12px;
|
324 |
background: green;
|
325 |
color: #fff;
|
328 |
text-decoration: none;
|
329 |
margin-left: 0;
|
330 |
}
|
331 |
+
.ctf_notice .ctf_offer_btn:hover, .ctf_notice .ctf_offer_btn:focus {
|
332 |
background: #049404;
|
333 |
color: #fff;
|
334 |
}
|
335 |
+
.ctf_notice .ctf_other_notice{
|
336 |
padding-top: 10px;
|
337 |
font-style: italic;
|
338 |
font-size: 12px;
|
339 |
}
|
340 |
+
.ctf_notice .ctf_other_notice a{
|
341 |
padding: 0;
|
342 |
}
|
343 |
|
custom-twitter-feed.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Custom Twitter Feeds
|
4 |
Plugin URI: http://smashballoon.com/custom-twitter-feeds
|
5 |
Description: Customizable Twitter feeds for your website
|
6 |
-
Version: 1.6
|
7 |
Author: Smash Balloon
|
8 |
Author URI: http://smashballoon.com/
|
9 |
Text Domain: custom-twitter-feeds
|
@@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
24 |
*/
|
25 |
|
26 |
define( 'CTF_URL', plugin_dir_path( __FILE__ ) );
|
27 |
-
define( 'CTF_VERSION', '1.6' );
|
28 |
define( 'CTF_TITLE', 'Custom Twitter Feeds' );
|
29 |
define( 'CTF_JS_URL', plugins_url( '/js/ctf-scripts.min.js?ver=' . CTF_VERSION , __FILE__ ) );
|
30 |
define( 'OAUTH_PROCESSOR_URL', 'https://api.smashballoon.com/twitter-login.php?return_uri=' );
|
@@ -57,6 +57,19 @@ function ctf_plugin_init() {
|
|
57 |
}
|
58 |
|
59 |
include_once trailingslashit( CTF_PLUGIN_DIR ) . 'inc/class-ctf-tracking.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
}
|
61 |
|
62 |
add_action( 'plugins_loaded', 'ctf_plugin_init' );
|
3 |
Plugin Name: Custom Twitter Feeds
|
4 |
Plugin URI: http://smashballoon.com/custom-twitter-feeds
|
5 |
Description: Customizable Twitter feeds for your website
|
6 |
+
Version: 1.6.1
|
7 |
Author: Smash Balloon
|
8 |
Author URI: http://smashballoon.com/
|
9 |
Text Domain: custom-twitter-feeds
|
24 |
*/
|
25 |
|
26 |
define( 'CTF_URL', plugin_dir_path( __FILE__ ) );
|
27 |
+
define( 'CTF_VERSION', '1.6.1' );
|
28 |
define( 'CTF_TITLE', 'Custom Twitter Feeds' );
|
29 |
define( 'CTF_JS_URL', plugins_url( '/js/ctf-scripts.min.js?ver=' . CTF_VERSION , __FILE__ ) );
|
30 |
define( 'OAUTH_PROCESSOR_URL', 'https://api.smashballoon.com/twitter-login.php?return_uri=' );
|
57 |
}
|
58 |
|
59 |
include_once trailingslashit( CTF_PLUGIN_DIR ) . 'inc/class-ctf-tracking.php';
|
60 |
+
|
61 |
+
if ( is_admin() ) {
|
62 |
+
if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0
|
63 |
+
&& version_compare( get_bloginfo('version'), '4.6' , '>' ) ) {
|
64 |
+
require_once trailingslashit( CTF_PLUGIN_DIR ) . 'inc/admin/class-ctf-notifications.php';
|
65 |
+
$ctf_notifications = new CTF_Notifications();
|
66 |
+
$ctf_notifications->init();
|
67 |
+
|
68 |
+
require_once trailingslashit( CTF_PLUGIN_DIR ) . 'inc/admin/class-ctf-new-user.php';
|
69 |
+
$ctf_new_user = new CTF_New_User();
|
70 |
+
$ctf_new_user->init();
|
71 |
+
}
|
72 |
+
}
|
73 |
}
|
74 |
|
75 |
add_action( 'plugins_loaded', 'ctf_plugin_init' );
|
img/ctf-icon.png
ADDED
Binary file
|
inc/CtfAdmin.php
CHANGED
@@ -124,7 +124,7 @@ class CtfAdmin
|
|
124 |
|
125 |
<?php elseif ( isset( $access_token_data['error'] ) && ! isset( $access_token_data['oauth_token'] ) ) : ?>
|
126 |
|
127 |
-
<p class="
|
128 |
<a href="<?php echo OAUTH_PROCESSOR_URL . admin_url( 'admin.php?page=custom-twitter-feeds' ); ?>" id="ctf-get-token"><i class="fa fa-twitter"></i><?php _e( 'Log in to Twitter and get my Access Token and Secret' ); ?></a>
|
129 |
<a class="ctf-tooltip-link" href="https://smashballoon.com/custom-twitter-feeds/token/?utm_campaign=twitter-free&utm_source=settings&utm_medium=errorconnecting" target="_blank"><?php _e( "Button not working?", 'custom-twitter-feeds' ); ?></a>
|
130 |
|
124 |
|
125 |
<?php elseif ( isset( $access_token_data['error'] ) && ! isset( $access_token_data['oauth_token'] ) ) : ?>
|
126 |
|
127 |
+
<p class="ctf_error_notice"><?php _e( 'There was an error with retrieving your access tokens. Please <a href="https://smashballoon.com/custom-twitter-feeds/token/?utm_campaign=twitter-free&utm_source=settings&utm_medium=errorconnecting" target="_blank">use this tool</a> to get your access token and secret.' ); ?></p><br>
|
128 |
<a href="<?php echo OAUTH_PROCESSOR_URL . admin_url( 'admin.php?page=custom-twitter-feeds' ); ?>" id="ctf-get-token"><i class="fa fa-twitter"></i><?php _e( 'Log in to Twitter and get my Access Token and Secret' ); ?></a>
|
129 |
<a class="ctf-tooltip-link" href="https://smashballoon.com/custom-twitter-feeds/token/?utm_campaign=twitter-free&utm_source=settings&utm_medium=errorconnecting" target="_blank"><?php _e( "Button not working?", 'custom-twitter-feeds' ); ?></a>
|
130 |
|
inc/CtfFeed.php
CHANGED
@@ -408,11 +408,11 @@ class CtfFeed
|
|
408 |
$this->feed_options['count'] = $this->feed_options['num'];
|
409 |
} else {
|
410 |
if ( $this->feed_options['num'] < 10 ) {
|
411 |
-
$this->feed_options['count'] = max( round( $this->feed_options['num'] * $this->feed_options['multiplier'] * 1.6 ), $min_tweets_to_retrieve );
|
412 |
} elseif ( $this->feed_options['num'] < 30 ) {
|
413 |
-
$this->feed_options['count'] = round( $this->feed_options['num'] * $this->feed_options['multiplier'] * 1.2 );
|
414 |
} else {
|
415 |
-
$this->feed_options['count'] = round( $this->feed_options['num'] * $this->feed_options['multiplier'] );
|
416 |
}
|
417 |
}
|
418 |
} else {
|
@@ -1378,9 +1378,9 @@ class CtfFeed
|
|
1378 |
$html .= '<div class="ctf-out-of-tweets">';
|
1379 |
$html .= '<p>' . __( "That's all! No more Tweets to load", 'custom-twitter-feeds' ) . '</p>';
|
1380 |
$html .= '<p>';
|
1381 |
-
$html .= '<a class="twitter-share-button" href="https://twitter.com/share" target="_blank" data-size="large" data-url="'.get_home_url().'">Share</a>';
|
1382 |
if ( !empty( $feed_options['screenname'] ) ) {
|
1383 |
-
$html .= '<a class="twitter-follow-button" href="https://twitter.com/' . $feed_options['screenname'] . '" target="_blank" data-show-count="false" data-size="large" data-dnt="true">Follow</a>';
|
1384 |
}
|
1385 |
$html .= '</p>';
|
1386 |
if ( !$feed_options['disableintents'] ) {
|
@@ -1442,7 +1442,7 @@ class CtfFeed
|
|
1442 |
}
|
1443 |
|
1444 |
if ( $feed_options['creditctf'] ) {
|
1445 |
-
$ctf_feed_html .= '<div class="ctf-credit-link"><a href="https://smashballoon.com/custom-twitter-feeds" target="_blank">' . ctf_get_fa_el( 'fa-twitter' ) . 'Custom Twitter Feeds Plugin</a></div>';
|
1446 |
}
|
1447 |
|
1448 |
$ctf_feed_html .= '</div>'; // closing div tag for #ctf
|
@@ -1472,7 +1472,7 @@ class CtfFeed
|
|
1472 |
|
1473 |
if ( $feed_options['type'] === 'usertimeline' ) {
|
1474 |
$ctf_header_html .= '<div class="ctf-header' . $ctf_no_bio . '" style="' . $feed_options['headerbgcolor'] . '">';
|
1475 |
-
$ctf_header_html .= '<a href="https://twitter.com/' . $tweet_set[0]['user']['screen_name'] . '" target="_blank" title="@' . $tweet_set[0]['user']['screen_name'] . '" class="ctf-header-link">';
|
1476 |
$ctf_header_html .= '<div class="ctf-header-text">';
|
1477 |
$ctf_header_html .= '<p class="ctf-header-user" style="' . $feed_options['headertextcolor'] . '">';
|
1478 |
$ctf_header_html .= '<span class="ctf-header-name">';
|
@@ -1516,7 +1516,7 @@ class CtfFeed
|
|
1516 |
$default_header_text = str_replace( ' -filter:retweets', '', $default_header_text );
|
1517 |
|
1518 |
$ctf_header_html .= '<div class="ctf-header ctf-header-type-generic" style="' . $feed_options['headerbgcolor'] . '">';
|
1519 |
-
$ctf_header_html .= '<a href="https://twitter.com/' . $url_part . '" target="_blank" class="ctf-header-link">';
|
1520 |
$ctf_header_html .= '<div class="ctf-header-text">';
|
1521 |
$ctf_header_html .= '<p class="ctf-header-no-bio" style="' . $feed_options['headertextcolor'] . '">' . $default_header_text . '</p>';
|
1522 |
$ctf_header_html .= '</div>';
|
@@ -1642,8 +1642,8 @@ class CtfFeed
|
|
1642 |
|
1643 |
if ( isset( $retweeter ) && ctf_show( 'retweeter', $feed_options ) ) {
|
1644 |
$tweet_html .= '<div class="ctf-context">';
|
1645 |
-
$tweet_html .= '<a href="https://twitter.com/intent/user?screen_name=' . $retweeter['screen_name'] . '" target="_blank" class="ctf-retweet-icon">' . ctf_get_fa_el( 'fa-retweet' ) . '<span class="ctf-screenreader">'.__( 'Retweet on Twitter', 'custom-twitter-feeds' ).'</span></a>';
|
1646 |
-
$tweet_html .= '<a href="https://twitter.com/' . $retweeter['screen_name'] . '" target="_blank" class="ctf-retweet-text" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">' . $retweeter['name'] . ' ' . $feed_options['retweetedtext'] . '</a>';
|
1647 |
$tweet_html .= '</div>';
|
1648 |
}
|
1649 |
|
@@ -1652,17 +1652,17 @@ class CtfFeed
|
|
1652 |
$tweet_html .= '<div class="ctf-author-box">';
|
1653 |
$tweet_html .= '<div class="ctf-author-box-link" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">';
|
1654 |
if ( ctf_show( 'avatar', $feed_options ) ) {
|
1655 |
-
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '" class="ctf-author-avatar" target="_blank" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">';
|
1656 |
$tweet_html .= '<img src="' . $post['user']['profile_image_url_https'] . '" alt="' . $post['user']['screen_name'] . '" width="48" height="48">';
|
1657 |
$tweet_html .= '</a>';
|
1658 |
}
|
1659 |
|
1660 |
if ( ctf_show( 'author', $feed_options ) ) {
|
1661 |
-
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '" target="_blank" class="ctf-author-name" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">' . $post['user']['name'] . '</a>';
|
1662 |
if ( $post['user']['verified'] == 1 ) {
|
1663 |
$tweet_html .= '<span class="ctf-verified" >' . ctf_get_fa_el( 'fa-check-circle' ) . '</span>';
|
1664 |
}
|
1665 |
-
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '" class="ctf-author-screenname" target="_blank" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">@' . $post['user']['screen_name'] . '</a>';
|
1666 |
$sep_style_att = ! empty( $feed_options['authortextsize'] ) ? ' style="' . $feed_options['authortextsize'] . '"' : '';
|
1667 |
$tweet_html .= '<span class="ctf-screename-sep"' . $sep_style_att . '>·</span>';
|
1668 |
}
|
@@ -1670,7 +1670,7 @@ class CtfFeed
|
|
1670 |
if ( ctf_show( 'date', $feed_options ) ) {
|
1671 |
$tweet_html .= '<div class="ctf-tweet-meta">';
|
1672 |
//https://twitter.com/EnterLaw/status/869452491041243137
|
1673 |
-
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '/status/' . $post['id_str'] . '" class="ctf-tweet-date" target="_blank" style="' . $feed_options['datetextsize'] . $feed_options['datetextweight'] . $feed_options['textcolor'] . '">' . ctf_get_formatted_date( $post['created_at'], $feed_options, $post['user']['utc_offset'] ) . '</a>';
|
1674 |
$tweet_html .= '</div>';
|
1675 |
} // show date
|
1676 |
$tweet_html .= '</div>';
|
@@ -1688,7 +1688,7 @@ class CtfFeed
|
|
1688 |
$tweet_html .= '<div class="ctf-tweet-content">';
|
1689 |
|
1690 |
if ( $feed_options['linktexttotwitter'] ) {
|
1691 |
-
$tweet_html .= '<a class="ctf-tweet-text-link" href="https://twitter.com/' .$post['user']['screen_name'] . '/status/' . $post['id_str'] . '" target="_blank">';
|
1692 |
$tweet_html .= '<p class="ctf-tweet-text" style="' . $feed_options['tweettextsize'] . $feed_options['tweettextweight'] . $feed_options['textcolor'] . '">' . nl2br( $post_text ) . $post_media_text .'</p>';
|
1693 |
$tweet_html .= '</a>';
|
1694 |
} else {
|
@@ -1702,7 +1702,7 @@ class CtfFeed
|
|
1702 |
if ( $feed_options['disablelinks'] ) {
|
1703 |
$tweet_html .= '<span class="ctf-tweet-text-media-wrap' . $multi_class . '">' . $post_media_text . '</span>' . '</p>';
|
1704 |
} else {
|
1705 |
-
$tweet_html .= '</p><a href="https://twitter.com/' .$post['user']['screen_name'] . '/status/' . $post['id_str'] . '" target="_blank" class="ctf-tweet-text-media-wrap' . $multi_class . '">' . $post_media_text . '</a>';
|
1706 |
}
|
1707 |
}
|
1708 |
} // link text to twitter option is selected
|
@@ -1711,7 +1711,7 @@ class CtfFeed
|
|
1711 |
} // show tweet text
|
1712 |
|
1713 |
if ( ctf_show( 'linkbox', $feed_options ) && isset( $quoted ) ) {
|
1714 |
-
$tweet_html .= '<a href="https://twitter.com/' . $quoted['user']['screen_name'] . '/status/' . $quoted['id_str'] . '" class="ctf-quoted-tweet" style="' . $feed_options['quotedauthorsize'] . $feed_options['quotedauthorweight'] . $feed_options['textcolor'] . '" target="_blank">';
|
1715 |
$tweet_html .= '<span class="ctf-quoted-author-name">' . $quoted['user']['name'] . '</span>';
|
1716 |
|
1717 |
if ($quoted['user']['verified'] == 1) {
|
@@ -1727,20 +1727,20 @@ class CtfFeed
|
|
1727 |
|
1728 |
$tweet_html .= '<div class="ctf-tweet-actions">';
|
1729 |
if ( ctf_show( 'actions', $feed_options ) ) {
|
1730 |
-
$tweet_html .= '<a href="https://twitter.com/intent/tweet?in_reply_to=' . $post['id_str'] . '&related=' . $post['user']['screen_name'] . '" class="ctf-reply" target="_blank" style="' . $feed_options['iconsize'] . $feed_options['iconcolor'] . '">' . ctf_get_fa_el( 'fa-reply' ) . '<span class="ctf-screenreader">Reply on Twitter ' . $post['id_str'] . '</span></a>';
|
1731 |
-
$tweet_html .= '<a href="https://twitter.com/intent/retweet?tweet_id=' . $post['id_str'] . '&related=' . $post['user']['screen_name'] . '" class="ctf-retweet" target="_blank" style="' . $feed_options['iconsize'] . $feed_options['iconcolor'] . '">' . ctf_get_fa_el( 'fa-retweet' ) . '<span class="ctf-screenreader">Retweet on Twitter ' . $post['id_str'] . '</span><span class="ctf-action-count ctf-retweet-count">';
|
1732 |
if ( $post['retweet_count'] > 0 ) {
|
1733 |
$tweet_html .= $post['retweet_count'];
|
1734 |
}
|
1735 |
$tweet_html .= '</span></a>';
|
1736 |
-
$tweet_html .= '<a href="https://twitter.com/intent/like?tweet_id=' . $post['id_str'] . '&related=' . $post['user']['screen_name'] . '" class="ctf-like" target="_blank" style="' . $feed_options['iconsize'] . $feed_options['iconcolor'] . '">' . ctf_get_fa_el( 'fa-heart' ) . '<span class="ctf-screenreader">Like on Twitter ' . $post['id_str'] . '</span><span class="ctf-action-count ctf-favorite-count">';
|
1737 |
if ( $post['favorite_count'] > 0 ) {
|
1738 |
$tweet_html .= $post['favorite_count'];
|
1739 |
}
|
1740 |
$tweet_html .= '</span></a>';
|
1741 |
}
|
1742 |
if ( ctf_show( 'twitterlink', $feed_options ) ) {
|
1743 |
-
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '/status/' . $post['id_str'] . '" class="ctf-twitterlink" style="' . $feed_options['textcolor'] . '" target="_blank">' . esc_html( $feed_options['twitterlinktext'] ) . ' <span class="ctf-screenreader">' . $post['id_str'] . '</span></a>';
|
1744 |
} // show twitter link or actions
|
1745 |
$tweet_html .= '</div>';
|
1746 |
$tweet_html .= '</div>';
|
@@ -1797,7 +1797,7 @@ class CtfFeed
|
|
1797 |
$error_html .= 'The error response from the Twitter API is the following:<br />';
|
1798 |
$error_html .= '<code>Error number: ' . $this->api_obj->api_error_no . '<br />';
|
1799 |
$error_html .= 'Message: ' . $this->api_obj->api_error_message . '</code>';
|
1800 |
-
$error_html .= '<a href="https://smashballoon.com/custom-twitter-feeds/docs/errors/?utm_campaign=twitter-free&utm_source=frontend&utm_medium=errormessage" target="_blank">Click here to troubleshoot</a></p>';
|
1801 |
|
1802 |
|
1803 |
}
|
408 |
$this->feed_options['count'] = $this->feed_options['num'];
|
409 |
} else {
|
410 |
if ( $this->feed_options['num'] < 10 ) {
|
411 |
+
$this->feed_options['count'] = max( round( $this->feed_options['num'] * (float)$this->feed_options['multiplier'] * 1.6 ), $min_tweets_to_retrieve );
|
412 |
} elseif ( $this->feed_options['num'] < 30 ) {
|
413 |
+
$this->feed_options['count'] = round( $this->feed_options['num'] * (float)$this->feed_options['multiplier'] * 1.2 );
|
414 |
} else {
|
415 |
+
$this->feed_options['count'] = round( $this->feed_options['num'] * (float)$this->feed_options['multiplier'] );
|
416 |
}
|
417 |
}
|
418 |
} else {
|
1378 |
$html .= '<div class="ctf-out-of-tweets">';
|
1379 |
$html .= '<p>' . __( "That's all! No more Tweets to load", 'custom-twitter-feeds' ) . '</p>';
|
1380 |
$html .= '<p>';
|
1381 |
+
$html .= '<a class="twitter-share-button" href="https://twitter.com/share" target="_blank" rel="noopener noreferrer" data-size="large" data-url="'.get_home_url().'">Share</a>';
|
1382 |
if ( !empty( $feed_options['screenname'] ) ) {
|
1383 |
+
$html .= '<a class="twitter-follow-button" href="https://twitter.com/' . $feed_options['screenname'] . '" target="_blank" rel="noopener noreferrer" data-show-count="false" data-size="large" data-dnt="true">Follow</a>';
|
1384 |
}
|
1385 |
$html .= '</p>';
|
1386 |
if ( !$feed_options['disableintents'] ) {
|
1442 |
}
|
1443 |
|
1444 |
if ( $feed_options['creditctf'] ) {
|
1445 |
+
$ctf_feed_html .= '<div class="ctf-credit-link"><a href="https://smashballoon.com/custom-twitter-feeds" target="_blank" rel="noopener noreferrer">' . ctf_get_fa_el( 'fa-twitter' ) . 'Custom Twitter Feeds Plugin</a></div>';
|
1446 |
}
|
1447 |
|
1448 |
$ctf_feed_html .= '</div>'; // closing div tag for #ctf
|
1472 |
|
1473 |
if ( $feed_options['type'] === 'usertimeline' ) {
|
1474 |
$ctf_header_html .= '<div class="ctf-header' . $ctf_no_bio . '" style="' . $feed_options['headerbgcolor'] . '">';
|
1475 |
+
$ctf_header_html .= '<a href="https://twitter.com/' . $tweet_set[0]['user']['screen_name'] . '" target="_blank" rel="noopener noreferrer" title="@' . $tweet_set[0]['user']['screen_name'] . '" class="ctf-header-link">';
|
1476 |
$ctf_header_html .= '<div class="ctf-header-text">';
|
1477 |
$ctf_header_html .= '<p class="ctf-header-user" style="' . $feed_options['headertextcolor'] . '">';
|
1478 |
$ctf_header_html .= '<span class="ctf-header-name">';
|
1516 |
$default_header_text = str_replace( ' -filter:retweets', '', $default_header_text );
|
1517 |
|
1518 |
$ctf_header_html .= '<div class="ctf-header ctf-header-type-generic" style="' . $feed_options['headerbgcolor'] . '">';
|
1519 |
+
$ctf_header_html .= '<a href="https://twitter.com/' . $url_part . '" target="_blank" rel="noopener noreferrer" class="ctf-header-link">';
|
1520 |
$ctf_header_html .= '<div class="ctf-header-text">';
|
1521 |
$ctf_header_html .= '<p class="ctf-header-no-bio" style="' . $feed_options['headertextcolor'] . '">' . $default_header_text . '</p>';
|
1522 |
$ctf_header_html .= '</div>';
|
1642 |
|
1643 |
if ( isset( $retweeter ) && ctf_show( 'retweeter', $feed_options ) ) {
|
1644 |
$tweet_html .= '<div class="ctf-context">';
|
1645 |
+
$tweet_html .= '<a href="https://twitter.com/intent/user?screen_name=' . $retweeter['screen_name'] . '" target="_blank" rel="noopener noreferrer" class="ctf-retweet-icon">' . ctf_get_fa_el( 'fa-retweet' ) . '<span class="ctf-screenreader">'.__( 'Retweet on Twitter', 'custom-twitter-feeds' ).'</span></a>';
|
1646 |
+
$tweet_html .= '<a href="https://twitter.com/' . $retweeter['screen_name'] . '" target="_blank" rel="noopener noreferrer" class="ctf-retweet-text" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">' . $retweeter['name'] . ' ' . $feed_options['retweetedtext'] . '</a>';
|
1647 |
$tweet_html .= '</div>';
|
1648 |
}
|
1649 |
|
1652 |
$tweet_html .= '<div class="ctf-author-box">';
|
1653 |
$tweet_html .= '<div class="ctf-author-box-link" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">';
|
1654 |
if ( ctf_show( 'avatar', $feed_options ) ) {
|
1655 |
+
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '" class="ctf-author-avatar" target="_blank" rel="noopener noreferrer" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">';
|
1656 |
$tweet_html .= '<img src="' . $post['user']['profile_image_url_https'] . '" alt="' . $post['user']['screen_name'] . '" width="48" height="48">';
|
1657 |
$tweet_html .= '</a>';
|
1658 |
}
|
1659 |
|
1660 |
if ( ctf_show( 'author', $feed_options ) ) {
|
1661 |
+
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '" target="_blank" rel="noopener noreferrer" class="ctf-author-name" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">' . $post['user']['name'] . '</a>';
|
1662 |
if ( $post['user']['verified'] == 1 ) {
|
1663 |
$tweet_html .= '<span class="ctf-verified" >' . ctf_get_fa_el( 'fa-check-circle' ) . '</span>';
|
1664 |
}
|
1665 |
+
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '" class="ctf-author-screenname" target="_blank" rel="noopener noreferrer" style="' . $feed_options['authortextsize'] . $feed_options['authortextweight'] . $feed_options['textcolor'] . '">@' . $post['user']['screen_name'] . '</a>';
|
1666 |
$sep_style_att = ! empty( $feed_options['authortextsize'] ) ? ' style="' . $feed_options['authortextsize'] . '"' : '';
|
1667 |
$tweet_html .= '<span class="ctf-screename-sep"' . $sep_style_att . '>·</span>';
|
1668 |
}
|
1670 |
if ( ctf_show( 'date', $feed_options ) ) {
|
1671 |
$tweet_html .= '<div class="ctf-tweet-meta">';
|
1672 |
//https://twitter.com/EnterLaw/status/869452491041243137
|
1673 |
+
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '/status/' . $post['id_str'] . '" class="ctf-tweet-date" target="_blank" rel="noopener noreferrer" style="' . $feed_options['datetextsize'] . $feed_options['datetextweight'] . $feed_options['textcolor'] . '">' . ctf_get_formatted_date( $post['created_at'], $feed_options, $post['user']['utc_offset'] ) . '</a>';
|
1674 |
$tweet_html .= '</div>';
|
1675 |
} // show date
|
1676 |
$tweet_html .= '</div>';
|
1688 |
$tweet_html .= '<div class="ctf-tweet-content">';
|
1689 |
|
1690 |
if ( $feed_options['linktexttotwitter'] ) {
|
1691 |
+
$tweet_html .= '<a class="ctf-tweet-text-link" href="https://twitter.com/' .$post['user']['screen_name'] . '/status/' . $post['id_str'] . '" target="_blank" rel="noopener noreferrer">';
|
1692 |
$tweet_html .= '<p class="ctf-tweet-text" style="' . $feed_options['tweettextsize'] . $feed_options['tweettextweight'] . $feed_options['textcolor'] . '">' . nl2br( $post_text ) . $post_media_text .'</p>';
|
1693 |
$tweet_html .= '</a>';
|
1694 |
} else {
|
1702 |
if ( $feed_options['disablelinks'] ) {
|
1703 |
$tweet_html .= '<span class="ctf-tweet-text-media-wrap' . $multi_class . '">' . $post_media_text . '</span>' . '</p>';
|
1704 |
} else {
|
1705 |
+
$tweet_html .= '</p><a href="https://twitter.com/' .$post['user']['screen_name'] . '/status/' . $post['id_str'] . '" target="_blank" rel="noopener noreferrer" class="ctf-tweet-text-media-wrap' . $multi_class . '">' . $post_media_text . '</a>';
|
1706 |
}
|
1707 |
}
|
1708 |
} // link text to twitter option is selected
|
1711 |
} // show tweet text
|
1712 |
|
1713 |
if ( ctf_show( 'linkbox', $feed_options ) && isset( $quoted ) ) {
|
1714 |
+
$tweet_html .= '<a href="https://twitter.com/' . $quoted['user']['screen_name'] . '/status/' . $quoted['id_str'] . '" class="ctf-quoted-tweet" style="' . $feed_options['quotedauthorsize'] . $feed_options['quotedauthorweight'] . $feed_options['textcolor'] . '" target="_blank" rel="noopener noreferrer">';
|
1715 |
$tweet_html .= '<span class="ctf-quoted-author-name">' . $quoted['user']['name'] . '</span>';
|
1716 |
|
1717 |
if ($quoted['user']['verified'] == 1) {
|
1727 |
|
1728 |
$tweet_html .= '<div class="ctf-tweet-actions">';
|
1729 |
if ( ctf_show( 'actions', $feed_options ) ) {
|
1730 |
+
$tweet_html .= '<a href="https://twitter.com/intent/tweet?in_reply_to=' . $post['id_str'] . '&related=' . $post['user']['screen_name'] . '" class="ctf-reply" target="_blank" rel="noopener noreferrer" style="' . $feed_options['iconsize'] . $feed_options['iconcolor'] . '">' . ctf_get_fa_el( 'fa-reply' ) . '<span class="ctf-screenreader">Reply on Twitter ' . $post['id_str'] . '</span></a>';
|
1731 |
+
$tweet_html .= '<a href="https://twitter.com/intent/retweet?tweet_id=' . $post['id_str'] . '&related=' . $post['user']['screen_name'] . '" class="ctf-retweet" target="_blank" rel="noopener noreferrer" style="' . $feed_options['iconsize'] . $feed_options['iconcolor'] . '">' . ctf_get_fa_el( 'fa-retweet' ) . '<span class="ctf-screenreader">Retweet on Twitter ' . $post['id_str'] . '</span><span class="ctf-action-count ctf-retweet-count">';
|
1732 |
if ( $post['retweet_count'] > 0 ) {
|
1733 |
$tweet_html .= $post['retweet_count'];
|
1734 |
}
|
1735 |
$tweet_html .= '</span></a>';
|
1736 |
+
$tweet_html .= '<a href="https://twitter.com/intent/like?tweet_id=' . $post['id_str'] . '&related=' . $post['user']['screen_name'] . '" class="ctf-like" target="_blank" rel="noopener noreferrer" style="' . $feed_options['iconsize'] . $feed_options['iconcolor'] . '">' . ctf_get_fa_el( 'fa-heart' ) . '<span class="ctf-screenreader">Like on Twitter ' . $post['id_str'] . '</span><span class="ctf-action-count ctf-favorite-count">';
|
1737 |
if ( $post['favorite_count'] > 0 ) {
|
1738 |
$tweet_html .= $post['favorite_count'];
|
1739 |
}
|
1740 |
$tweet_html .= '</span></a>';
|
1741 |
}
|
1742 |
if ( ctf_show( 'twitterlink', $feed_options ) ) {
|
1743 |
+
$tweet_html .= '<a href="https://twitter.com/' . $post['user']['screen_name'] . '/status/' . $post['id_str'] . '" class="ctf-twitterlink" style="' . $feed_options['textcolor'] . '" target="_blank" rel="noopener noreferrer">' . esc_html( $feed_options['twitterlinktext'] ) . ' <span class="ctf-screenreader">' . $post['id_str'] . '</span></a>';
|
1744 |
} // show twitter link or actions
|
1745 |
$tweet_html .= '</div>';
|
1746 |
$tweet_html .= '</div>';
|
1797 |
$error_html .= 'The error response from the Twitter API is the following:<br />';
|
1798 |
$error_html .= '<code>Error number: ' . $this->api_obj->api_error_no . '<br />';
|
1799 |
$error_html .= 'Message: ' . $this->api_obj->api_error_message . '</code>';
|
1800 |
+
$error_html .= '<a href="https://smashballoon.com/custom-twitter-feeds/docs/errors/?utm_campaign=twitter-free&utm_source=frontend&utm_medium=errormessage" target="_blank" rel="noopener noreferrer">Click here to troubleshoot</a></p>';
|
1801 |
|
1802 |
|
1803 |
}
|
inc/admin-hooks.php
CHANGED
@@ -59,7 +59,7 @@ add_action( 'ctf_admin_feed_settings_radio_extra', 'ctf_usertimeline_error_messa
|
|
59 |
function ctf_usertimeline_error_message( $args )
|
60 |
{ //sbi_notice sbi_user_id_error
|
61 |
if ( $args['name'] == 'usertimeline') : ?>
|
62 |
-
<div class="
|
63 |
<?php _e( "<p>Please use a single screenname or Twitter handle of numbers and letters. If you would like to use more than one screen name for your feed, please upgrade to our <a href='https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=settings&utm_medium=multiuser' target='_blank'>Pro version</a>.</p>" ); ?>
|
64 |
</div>
|
65 |
<?php endif;
|
@@ -68,7 +68,7 @@ function ctf_usertimeline_error_message( $args )
|
|
68 |
add_action( 'ctf_admin_feed_settings_search_extra', 'ctf_hashtag_error_message' );
|
69 |
function ctf_hashtag_error_message() {
|
70 |
?>
|
71 |
-
<div class="
|
72 |
<?php _e( "<p>Please use a single hashtag of numbers and letters. If you would like to use more than one hashtag or use search terms for your feed, please upgrade to our <a href='https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=settings&utm_medium=multisearch' target='_blank'>Pro version</a>.</p>" ); ?>
|
73 |
</div>
|
74 |
<?php
|
59 |
function ctf_usertimeline_error_message( $args )
|
60 |
{ //sbi_notice sbi_user_id_error
|
61 |
if ( $args['name'] == 'usertimeline') : ?>
|
62 |
+
<div class="ctf_error_notice ctf_usertimeline_error">
|
63 |
<?php _e( "<p>Please use a single screenname or Twitter handle of numbers and letters. If you would like to use more than one screen name for your feed, please upgrade to our <a href='https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=settings&utm_medium=multiuser' target='_blank'>Pro version</a>.</p>" ); ?>
|
64 |
</div>
|
65 |
<?php endif;
|
68 |
add_action( 'ctf_admin_feed_settings_search_extra', 'ctf_hashtag_error_message' );
|
69 |
function ctf_hashtag_error_message() {
|
70 |
?>
|
71 |
+
<div class="ctf_error_notice ctf_search_error">
|
72 |
<?php _e( "<p>Please use a single hashtag of numbers and letters. If you would like to use more than one hashtag or use search terms for your feed, please upgrade to our <a href='https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=settings&utm_medium=multisearch' target='_blank'>Pro version</a>.</p>" ); ?>
|
73 |
</div>
|
74 |
<?php
|
inc/admin/class-ctf-new-user.php
ADDED
@@ -0,0 +1,396 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* CTF_New_User.
|
4 |
+
*
|
5 |
+
* @since 2.18
|
6 |
+
*/
|
7 |
+
|
8 |
+
// Exit if accessed directly
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class CTF_New_User extends CTF_Notifications {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Source of notifications content.
|
17 |
+
*
|
18 |
+
* @since 2.18
|
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 = 'ctf_newuser_notifications';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Register hooks.
|
31 |
+
*
|
32 |
+
* @since 2.18
|
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.18
|
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.18
|
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 |
+
$ctf_statuses_option = get_option( 'ctf_statuses', array() );
|
99 |
+
$current_time = ctf_get_current_time();
|
100 |
+
|
101 |
+
// rating notice logic
|
102 |
+
$ctf_rating_notice_option = get_option( 'ctf_rating_notice', false );
|
103 |
+
$ctf_rating_notice_waiting = get_transient( 'custom_twitter_feeds_rating_notice_waiting' );
|
104 |
+
$should_show_rating_notice = ($ctf_rating_notice_waiting !== 'waiting' && $ctf_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( $ctf_statuses_option['rating_notice_dismissed'] ) ? ((int)$ctf_statuses_option['rating_notice_dismissed'] + ((int)$notifications['review']['wait'] * DAY_IN_SECONDS)) < $current_time + 1: true;
|
110 |
+
|
111 |
+
if ( isset( $ctf_statuses_option['first_install'] ) && $ctf_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, 'ctf_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 && $ctf_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, 'ctf_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( $ctf_statuses_option['first_install'] )
|
127 |
+
&& $current_time > (int)$ctf_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.18
|
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.18
|
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.18
|
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.18
|
227 |
+
*/
|
228 |
+
public function enqueues() {
|
229 |
+
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Output notifications on Form Overview admin area.
|
234 |
+
*
|
235 |
+
* @since 2.18
|
236 |
+
*/
|
237 |
+
public function output() {
|
238 |
+
// If the Instagram Feed plugin is active, notices only shown on CTF Settings pages
|
239 |
+
if ( function_exists( 'sb_instagram_activate' )
|
240 |
+
&& ! function_exists( 'sb_instagram_feed_pro_init' ) ) {
|
241 |
+
return;
|
242 |
+
}
|
243 |
+
|
244 |
+
if ( function_exists( 'cff_check_for_db_updates' ) ) {
|
245 |
+
return;
|
246 |
+
}
|
247 |
+
|
248 |
+
$notifications = $this->get();
|
249 |
+
|
250 |
+
if ( empty( $notifications ) ) {
|
251 |
+
return;
|
252 |
+
}
|
253 |
+
|
254 |
+
// new user notices included in regular settings page notifications so this
|
255 |
+
// checks to see if user is one of those pages
|
256 |
+
if ( ! empty( $_GET['page'] )
|
257 |
+
&& strpos( $_GET['page'], 'custom-twitter-feeds' ) !== false ) {
|
258 |
+
return;
|
259 |
+
}
|
260 |
+
|
261 |
+
$content_allowed_tags = array(
|
262 |
+
'em' => array(),
|
263 |
+
'strong' => array(),
|
264 |
+
'span' => array(
|
265 |
+
'style' => array(),
|
266 |
+
),
|
267 |
+
'a' => array(
|
268 |
+
'href' => array(),
|
269 |
+
'target' => array(),
|
270 |
+
'rel' => array(),
|
271 |
+
),
|
272 |
+
);
|
273 |
+
$image_overlay = '';
|
274 |
+
|
275 |
+
foreach ( $notifications as $notification ) {
|
276 |
+
$type = sanitize_text_field( $notification['id'] );
|
277 |
+
$img_src = CTF_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
|
278 |
+
$content = '';
|
279 |
+
if ( ! empty( $notification['content'] ) ) {
|
280 |
+
$content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
|
281 |
+
}
|
282 |
+
$buttons = array();
|
283 |
+
if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
|
284 |
+
foreach ( $notification['btns'] as $btn_type => $btn ) {
|
285 |
+
if ( ! is_array( $btn['url'] ) ) {
|
286 |
+
$buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
|
287 |
+
} elseif ( is_array( $btn['url'] ) ) {
|
288 |
+
$buttons[ $btn_type ]['url'] = add_query_arg( $btn['url'] );
|
289 |
+
}
|
290 |
+
|
291 |
+
$buttons[ $btn_type ]['attr'] = '';
|
292 |
+
if ( ! empty( $btn['attr'] ) ) {
|
293 |
+
$buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"';
|
294 |
+
}
|
295 |
+
|
296 |
+
$buttons[ $btn_type ]['class'] = '';
|
297 |
+
if ( ! empty( $btn['class'] ) ) {
|
298 |
+
$buttons[ $btn_type ]['class'] = ' ' . $btn['class'];
|
299 |
+
}
|
300 |
+
|
301 |
+
$buttons[ $btn_type ]['text'] = '';
|
302 |
+
if ( ! empty( $btn['text'] ) ) {
|
303 |
+
$buttons[ $btn_type ]['text'] = wp_kses( $btn['text'], $content_allowed_tags );
|
304 |
+
}
|
305 |
+
}
|
306 |
+
}
|
307 |
+
if ( isset( $notification['image_overlay'] ) ) {
|
308 |
+
$image_overlay = '<div class="img-overlay">'. esc_html( $notification['image_overlay'] ).'</div>';
|
309 |
+
}
|
310 |
+
}
|
311 |
+
?>
|
312 |
+
|
313 |
+
<div class="ctf_notice ctf_<?php echo esc_attr( $type ); ?>_notice">
|
314 |
+
<div class="ctf_thumb">
|
315 |
+
<img src="<?php echo esc_url( $img_src ); ?>" alt="notice">
|
316 |
+
<?php echo $image_overlay; ?>
|
317 |
+
</div>
|
318 |
+
<div class="ctf-notice-text">
|
319 |
+
<p style="padding-top: 4px;"><?php echo $content; ?></p>
|
320 |
+
<p class="links">
|
321 |
+
<?php foreach ( $buttons as $button ) : ?>
|
322 |
+
<a class="<?php echo esc_attr( $button['class'] ); ?>" href="<?php echo esc_attr( $button['url'] ); ?>"<?php echo $button['attr']; ?>><?php echo $button['text']; ?></a>
|
323 |
+
<?php endforeach; ?>
|
324 |
+
</p>
|
325 |
+
</div>
|
326 |
+
<a class="ctf_notice_close" href="<?php echo add_query_arg( array( 'ctf_dismiss' => $type ) ); ?>"><i class="fa fa-close"></i></a>
|
327 |
+
</div>
|
328 |
+
<?php
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Hide messages permanently or some can be dismissed temporarily
|
333 |
+
*
|
334 |
+
* @since 2.18
|
335 |
+
*/
|
336 |
+
public function dismiss() {
|
337 |
+
global $current_user;
|
338 |
+
$user_id = $current_user->ID;
|
339 |
+
$ctf_statuses_option = get_option( 'ctf_statuses', array() );
|
340 |
+
|
341 |
+
if ( isset( $_GET['ctf_ignore_rating_notice_nag'] ) ) {
|
342 |
+
if ( (int)$_GET['ctf_ignore_rating_notice_nag'] === 1 ) {
|
343 |
+
update_option( 'ctf_rating_notice', 'dismissed', false );
|
344 |
+
$ctf_statuses_option['rating_notice_dismissed'] = ctf_get_current_time();
|
345 |
+
update_option( 'ctf_statuses', $ctf_statuses_option, false );
|
346 |
+
|
347 |
+
} elseif ( $_GET['ctf_ignore_rating_notice_nag'] === 'later' ) {
|
348 |
+
set_transient( 'custom_twitter_feeds_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
|
349 |
+
update_option( 'ctf_rating_notice', 'pending', false );
|
350 |
+
}
|
351 |
+
}
|
352 |
+
|
353 |
+
if ( isset( $_GET['ctf_ignore_new_user_sale_notice'] ) ) {
|
354 |
+
$response = sanitize_text_field( $_GET['ctf_ignore_new_user_sale_notice'] );
|
355 |
+
if ( $response === 'always' ) {
|
356 |
+
update_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice', 'always' );
|
357 |
+
|
358 |
+
$current_month_number = (int)date('n', ctf_get_current_time() );
|
359 |
+
$not_early_in_the_year = ($current_month_number > 5);
|
360 |
+
|
361 |
+
if ( $not_early_in_the_year ) {
|
362 |
+
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', date( 'Y', ctf_get_current_time() ) );
|
363 |
+
}
|
364 |
+
|
365 |
+
}
|
366 |
+
}
|
367 |
+
|
368 |
+
if ( isset( $_GET['ctf_ignore_bfcm_sale_notice'] ) ) {
|
369 |
+
$response = sanitize_text_field( $_GET['ctf_ignore_bfcm_sale_notice'] );
|
370 |
+
if ( $response === 'always' ) {
|
371 |
+
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', 'always' );
|
372 |
+
} elseif ( $response === date( 'Y', ctf_get_current_time() ) ) {
|
373 |
+
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', date( 'Y', ctf_get_current_time() ) );
|
374 |
+
}
|
375 |
+
update_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice', 'always' );
|
376 |
+
}
|
377 |
+
|
378 |
+
if ( isset( $_GET['ctf_dismiss'] ) ) {
|
379 |
+
if ( $_GET['ctf_dismiss'] === 'review' ) {
|
380 |
+
update_option( 'ctf_rating_notice', 'dismissed', false );
|
381 |
+
$ctf_statuses_option['rating_notice_dismissed'] = ctf_get_current_time();
|
382 |
+
update_option( 'ctf_statuses', $ctf_statuses_option, false );
|
383 |
+
} elseif ( $_GET['ctf_dismiss'] === 'discount' ) {
|
384 |
+
update_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice', 'always' );
|
385 |
+
|
386 |
+
$current_month_number = (int)date('n', ctf_get_current_time() );
|
387 |
+
$not_early_in_the_year = ($current_month_number > 5);
|
388 |
+
|
389 |
+
if ( $not_early_in_the_year ) {
|
390 |
+
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', date( 'Y', ctf_get_current_time() ) );
|
391 |
+
}
|
392 |
+
}
|
393 |
+
update_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice', 'always' );
|
394 |
+
}
|
395 |
+
}
|
396 |
+
}
|
inc/admin/class-ctf-notifications.php
ADDED
@@ -0,0 +1,581 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* CTF_Notifications.
|
4 |
+
*
|
5 |
+
* @since 1.7/1.11
|
6 |
+
*/
|
7 |
+
|
8 |
+
// Exit if accessed directly
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class CTF_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 = 'ctf_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 = 'twitter';
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Option value.
|
37 |
+
*
|
38 |
+
* @since 1.7/1.11
|
39 |
+
*
|
40 |
+
* @var bool|array
|
41 |
+
*/
|
42 |
+
public $option = false;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Initialize class.
|
46 |
+
*
|
47 |
+
* @since 1.7/1.11
|
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 1.7/1.11
|
77 |
+
*/
|
78 |
+
public function hooks() {
|
79 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ) );
|
80 |
+
|
81 |
+
add_action( 'ctf_admin_overview_before_title', array( $this, 'output' ) );
|
82 |
+
|
83 |
+
// on cron. Once a week?
|
84 |
+
add_action( 'ctf_notification_update', array( $this, 'update' ) );
|
85 |
+
|
86 |
+
add_action( 'wp_ajax_ctf_dashboard_notification_dismiss', array( $this, 'dismiss' ) );
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Check if user has access and is enabled.
|
92 |
+
*
|
93 |
+
* @since 1.7/1.11
|
94 |
+
*
|
95 |
+
* @return bool
|
96 |
+
*/
|
97 |
+
public function has_access() {
|
98 |
+
$access = false;
|
99 |
+
|
100 |
+
if ( current_user_can( 'manage_options' ) ) {
|
101 |
+
$access = true;
|
102 |
+
}
|
103 |
+
|
104 |
+
return apply_filters( 'ctf_admin_notifications_has_access', $access );
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Get option value.
|
109 |
+
*
|
110 |
+
* @since 1.7/1.11
|
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 1.7/1.11
|
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 |
+
$body = str_replace( array( 'sbi_', 'sbi-' ), array( 'ctf_', 'ctf-' ), $body );
|
154 |
+
|
155 |
+
return $this->verify( json_decode( $body, true ) );
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Verify notification data before it is saved.
|
160 |
+
*
|
161 |
+
* @since 1.7/1.11
|
162 |
+
*
|
163 |
+
* @param array $notifications Array of notifications items to verify.
|
164 |
+
*
|
165 |
+
* @return array
|
166 |
+
*/
|
167 |
+
public function verify( $notifications ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
|
168 |
+
$data = array();
|
169 |
+
|
170 |
+
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
|
171 |
+
return $data;
|
172 |
+
}
|
173 |
+
|
174 |
+
$option = $this->get_option();
|
175 |
+
|
176 |
+
foreach ( $notifications as $notification ) {
|
177 |
+
|
178 |
+
// The message and license should never be empty, if they are, ignore.
|
179 |
+
if ( empty( $notification['content'] ) || empty( $notification['type'] ) ) {
|
180 |
+
continue;
|
181 |
+
}
|
182 |
+
|
183 |
+
// Ignore if license type does not match.
|
184 |
+
$license = ctf_is_pro_version() ? 'pro' : 'free';
|
185 |
+
|
186 |
+
if ( ! in_array( $license, $notification['type'], true ) ) {
|
187 |
+
continue;
|
188 |
+
}
|
189 |
+
|
190 |
+
// Ignore if expired.
|
191 |
+
if ( ! empty( $notification['end'] ) && ctf_get_current_time() > strtotime( $notification['end'] ) ) {
|
192 |
+
continue;
|
193 |
+
}
|
194 |
+
|
195 |
+
// Ignore if notification has already been dismissed.
|
196 |
+
if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
197 |
+
continue;
|
198 |
+
}
|
199 |
+
|
200 |
+
// TODO: Ignore if notification existed before installing CTF.
|
201 |
+
// Prevents bombarding the user with notifications after activation.
|
202 |
+
$activated = false;
|
203 |
+
if ( ! empty( $activated )
|
204 |
+
&& ! empty( $notification['start'] )
|
205 |
+
&& $activated > strtotime( $notification['start'] ) ) {
|
206 |
+
continue;
|
207 |
+
}
|
208 |
+
|
209 |
+
$data[] = $notification;
|
210 |
+
}
|
211 |
+
|
212 |
+
return $data;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Verify saved notification data for active notifications.
|
217 |
+
*
|
218 |
+
* @since 1.7/1.11
|
219 |
+
*
|
220 |
+
* @param array $notifications Array of notifications items to verify.
|
221 |
+
*
|
222 |
+
* @return array
|
223 |
+
*/
|
224 |
+
public function verify_active( $notifications ) {
|
225 |
+
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
|
226 |
+
return array();
|
227 |
+
}
|
228 |
+
|
229 |
+
// Remove notfications that are not active.
|
230 |
+
foreach ( $notifications as $key => $notification ) {
|
231 |
+
if ( ( ! empty( $notification['start'] ) && ctf_get_current_time() < strtotime( $notification['start'] ) )
|
232 |
+
|| ( ! empty( $notification['end'] ) && ctf_get_current_time() > strtotime( $notification['end'] ) ) ) {
|
233 |
+
unset( $notifications[ $key ] );
|
234 |
+
}
|
235 |
+
}
|
236 |
+
|
237 |
+
return $notifications;
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Get notification data.
|
242 |
+
*
|
243 |
+
* @since 1.7/1.11
|
244 |
+
*
|
245 |
+
* @return array
|
246 |
+
*/
|
247 |
+
public function get() {
|
248 |
+
if ( ! $this->has_access() ) {
|
249 |
+
return array();
|
250 |
+
}
|
251 |
+
|
252 |
+
$option = $this->get_option();
|
253 |
+
|
254 |
+
// Update notifications using async task.
|
255 |
+
if ( empty( $option['update'] ) || ctf_get_current_time() > $option['update'] + DAY_IN_SECONDS ) {
|
256 |
+
$this->update();
|
257 |
+
}
|
258 |
+
|
259 |
+
$events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
|
260 |
+
$feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
|
261 |
+
|
262 |
+
// If there is a new user notification, add it to the beginning of the notification list
|
263 |
+
$ctf_newuser = new CTF_New_User();
|
264 |
+
$newuser_notifications = $ctf_newuser->get();
|
265 |
+
|
266 |
+
if ( ! empty( $newuser_notifications ) ) {
|
267 |
+
$events = array_merge( $newuser_notifications, $events );
|
268 |
+
}
|
269 |
+
|
270 |
+
return array_merge( $events, $feed );
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Get notification count.
|
275 |
+
*
|
276 |
+
* @since 1.7/1.11
|
277 |
+
*
|
278 |
+
* @return int
|
279 |
+
*/
|
280 |
+
public function get_count() {
|
281 |
+
return count( $this->get() );
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Add a manual notification event.
|
286 |
+
*
|
287 |
+
* @since 1.7/1.11
|
288 |
+
*
|
289 |
+
* @param array $notification Notification data.
|
290 |
+
*/
|
291 |
+
public function add( $notification ) {
|
292 |
+
if ( empty( $notification['id'] ) ) {
|
293 |
+
return;
|
294 |
+
}
|
295 |
+
|
296 |
+
$option = $this->get_option();
|
297 |
+
|
298 |
+
if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
299 |
+
return;
|
300 |
+
}
|
301 |
+
|
302 |
+
foreach ( $option['events'] as $item ) {
|
303 |
+
if ( $item['id'] === $notification['id'] ) {
|
304 |
+
return;
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
$notification = $this->verify( array( $notification ) );
|
309 |
+
|
310 |
+
update_option(
|
311 |
+
'ctf_notifications',
|
312 |
+
array(
|
313 |
+
'update' => $option['update'],
|
314 |
+
'feed' => $option['feed'],
|
315 |
+
'events' => array_merge( $notification, $option['events'] ),
|
316 |
+
'dismissed' => $option['dismissed'],
|
317 |
+
)
|
318 |
+
);
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Update notification data from feed.
|
323 |
+
*
|
324 |
+
* @since 1.7/1.11
|
325 |
+
*/
|
326 |
+
public function update() {
|
327 |
+
$feed = $this->fetch_feed();
|
328 |
+
$option = $this->get_option();
|
329 |
+
|
330 |
+
update_option(
|
331 |
+
'ctf_notifications',
|
332 |
+
array(
|
333 |
+
'update' => ctf_get_current_time(),
|
334 |
+
'feed' => $feed,
|
335 |
+
'events' => $option['events'],
|
336 |
+
'dismissed' => $option['dismissed'],
|
337 |
+
)
|
338 |
+
);
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Admin area Form Overview enqueues.
|
343 |
+
*
|
344 |
+
* @since 1.7/1.11
|
345 |
+
*/
|
346 |
+
public function enqueues() {
|
347 |
+
if ( ! $this->has_access() ) {
|
348 |
+
return;
|
349 |
+
}
|
350 |
+
|
351 |
+
$notifications = $this->get();
|
352 |
+
|
353 |
+
if ( empty( $notifications ) ) {
|
354 |
+
return;
|
355 |
+
}
|
356 |
+
|
357 |
+
$min = '';
|
358 |
+
|
359 |
+
wp_enqueue_style(
|
360 |
+
'ctf-admin-notifications',
|
361 |
+
CTF_PLUGIN_URL . "css/admin-notifications{$min}.css",
|
362 |
+
array(),
|
363 |
+
CTF_VERSION
|
364 |
+
);
|
365 |
+
|
366 |
+
wp_enqueue_script(
|
367 |
+
'ctf-admin-notifications',
|
368 |
+
CTF_PLUGIN_URL . "js/admin-notifications{$min}.js",
|
369 |
+
array( 'jquery' ),
|
370 |
+
CTF_VERSION,
|
371 |
+
true
|
372 |
+
);
|
373 |
+
|
374 |
+
wp_localize_script( 'ctf-admin-notifications', 'ctf_admin', array(
|
375 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
376 |
+
'nonce' => wp_create_nonce( 'ctf-admin' )
|
377 |
+
)
|
378 |
+
);
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Fields from the remote source contain placeholders to allow
|
383 |
+
* some messages to be used for multiple plugins.
|
384 |
+
*
|
385 |
+
* @param $content string
|
386 |
+
* @param $notification array
|
387 |
+
*
|
388 |
+
* @return string
|
389 |
+
*
|
390 |
+
* @since 1.7/1.11
|
391 |
+
*/
|
392 |
+
public function replace_merge_fields( $content, $notification ) {
|
393 |
+
$merge_fields = array(
|
394 |
+
'{plugin}' => 'Custom Twitter Feeds',
|
395 |
+
'{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '',
|
396 |
+
'{platform}' => 'Twitter',
|
397 |
+
'{lowerplatform}' => 'twitter',
|
398 |
+
'{review-url}' => 'https://wordpress.org/support/plugin/custom-twitter-feeds/reviews/',
|
399 |
+
'{slug}' => 'custom-twitter-feed',
|
400 |
+
'{campaign}' => 'twitter-free'
|
401 |
+
);
|
402 |
+
|
403 |
+
if ( ctf_is_pro_version() ) {
|
404 |
+
$merge_fields['{campaign}'] = 'twitter-pro';
|
405 |
+
$merge_fields['{plugin}'] = 'Custom Twitter Feeds Pro';
|
406 |
+
}
|
407 |
+
|
408 |
+
foreach ( $merge_fields as $find => $replace ) {
|
409 |
+
$content = str_replace( $find, $replace, $content );
|
410 |
+
}
|
411 |
+
|
412 |
+
return $content;
|
413 |
+
}
|
414 |
+
|
415 |
+
/**
|
416 |
+
* Output notifications on Custom Twitter Feed admin area.
|
417 |
+
*
|
418 |
+
* @since 1.7/1.11
|
419 |
+
*/
|
420 |
+
public function output() {
|
421 |
+
$notifications = $this->get();
|
422 |
+
|
423 |
+
if ( empty( $notifications ) ) {
|
424 |
+
return;
|
425 |
+
}
|
426 |
+
|
427 |
+
$notifications_html = '';
|
428 |
+
$current_class = ' current';
|
429 |
+
$content_allowed_tags = array(
|
430 |
+
'em' => array(),
|
431 |
+
'strong' => array(),
|
432 |
+
'span' => array(
|
433 |
+
'style' => array(),
|
434 |
+
),
|
435 |
+
'a' => array(
|
436 |
+
'href' => array(),
|
437 |
+
'target' => array(),
|
438 |
+
'rel' => array(),
|
439 |
+
),
|
440 |
+
);
|
441 |
+
|
442 |
+
foreach ( $notifications as $notification ) {
|
443 |
+
|
444 |
+
// Buttons HTML.
|
445 |
+
$buttons_html = '';
|
446 |
+
if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
|
447 |
+
foreach ( $notification['btns'] as $btn_type => $btn ) {
|
448 |
+
if ( is_array( $btn['url'] ) ) {
|
449 |
+
$btn['url'] = add_query_arg( $btn['url'] );
|
450 |
+
}
|
451 |
+
if ( ! empty( $btn['attr'] ) ) {
|
452 |
+
$btn['target'] = '_blank';
|
453 |
+
}
|
454 |
+
$buttons_html .= sprintf(
|
455 |
+
'<a href="%1$s" class="button button-%2$s"%3$s>%4$s</a>',
|
456 |
+
! empty( $btn['url'] ) ? esc_url( $this->replace_merge_fields( $btn['url'], $notification ) ) : '',
|
457 |
+
$btn_type === 'primary' ? 'primary' : 'secondary',
|
458 |
+
! empty( $btn['target'] ) && $btn['target'] === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '',
|
459 |
+
! empty( $btn['text'] ) ? sanitize_text_field( $btn['text'] ) : ''
|
460 |
+
);
|
461 |
+
}
|
462 |
+
$buttons_html = ! empty( $buttons_html ) ? '<div class="buttons">' . $buttons_html . '</div>' : '';
|
463 |
+
}
|
464 |
+
|
465 |
+
if ( empty( $notification['image'] ) ) {
|
466 |
+
$image_html = '<div class="bell">';
|
467 |
+
|
468 |
+
$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>';
|
469 |
+
$image_html .= '</div>';
|
470 |
+
} else {
|
471 |
+
if ( $notification['image'] === 'balloon'
|
472 |
+
|| $notification['id'] === 'review'
|
473 |
+
|| $notification['id'] === 'discount') {
|
474 |
+
$image_html = '<div class="bell">';
|
475 |
+
|
476 |
+
$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">';
|
477 |
+
$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"/>';
|
478 |
+
$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"/>';
|
479 |
+
$image_html .= '</svg>';
|
480 |
+
} else {
|
481 |
+
$image_html = '<div class="thumb">';
|
482 |
+
$img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
|
483 |
+
$image_html .= '<img src="'.esc_url( $img_src ).'" alt="notice">';
|
484 |
+
|
485 |
+
if ( isset( $notification['image_overlay'] ) ) {
|
486 |
+
$image_html .= '<div class="img-overlay">'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'</div>';
|
487 |
+
}
|
488 |
+
}
|
489 |
+
$image_html .= '</div>';
|
490 |
+
|
491 |
+
}
|
492 |
+
|
493 |
+
// Notification HTML.
|
494 |
+
$notifications_html .= sprintf(
|
495 |
+
'<div class="message%5$s" data-message-id="%4$s">' . $image_html . '
|
496 |
+
<h3 class="title">%1$s</h3>
|
497 |
+
<p class="content">%2$s</p>
|
498 |
+
%3$s
|
499 |
+
</div>',
|
500 |
+
! empty( $notification['title'] ) ? $this->replace_merge_fields( sanitize_text_field( $notification['title'] ), $notification ) : '',
|
501 |
+
! empty( $notification['content'] ) ? wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ) : '',
|
502 |
+
$buttons_html,
|
503 |
+
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
|
504 |
+
$current_class
|
505 |
+
);
|
506 |
+
|
507 |
+
// Only first notification is current.
|
508 |
+
$current_class = '';
|
509 |
+
}
|
510 |
+
?>
|
511 |
+
|
512 |
+
<div id="ctf-notifications">
|
513 |
+
<a class="dismiss" title="<?php echo esc_attr__( 'Dismiss this message', 'custom-twitter-feeds' ); ?>"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
|
514 |
+
|
515 |
+
<div class="navigation">
|
516 |
+
<a class="prev disabled" title="<?php echo esc_attr__( 'Previous message', 'custom-twitter-feeds' ); ?>"><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>
|
517 |
+
<a class="next disabled" title="<?php echo esc_attr__( 'Next message', 'custom-twitter-feeds' ); ?>"><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>
|
518 |
+
</div>
|
519 |
+
|
520 |
+
<div class="messages">
|
521 |
+
<?php echo $notifications_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
522 |
+
</div>
|
523 |
+
</div>
|
524 |
+
<?php
|
525 |
+
}
|
526 |
+
|
527 |
+
/**
|
528 |
+
* Dismiss notification via AJAX. If it's a new user message, also dismiss it
|
529 |
+
* on all admin pages.
|
530 |
+
*
|
531 |
+
* @since 1.7/1.11
|
532 |
+
*/
|
533 |
+
public function dismiss() {
|
534 |
+
// Run a security check.
|
535 |
+
check_ajax_referer( 'ctf-admin', 'nonce' );
|
536 |
+
|
537 |
+
// Check for access and required param.
|
538 |
+
if ( ! $this->has_access() || empty( $_POST['id'] ) ) {
|
539 |
+
wp_send_json_error();
|
540 |
+
}
|
541 |
+
|
542 |
+
$id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
|
543 |
+
|
544 |
+
if ( $id === 'review' ) {
|
545 |
+
$ctf_statuses_option = get_option( 'ctf_statuses', array() );
|
546 |
+
|
547 |
+
update_option( 'ctf_rating_notice', 'dismissed', false );
|
548 |
+
$ctf_statuses_option['rating_notice_dismissed'] = ctf_get_current_time();
|
549 |
+
update_option( 'ctf_statuses', $ctf_statuses_option, false );
|
550 |
+
} elseif ( $id === 'discount' ) {
|
551 |
+
update_user_meta( get_current_user_id(), 'ctf_ignore_new_user_sale_notice', 'always' );
|
552 |
+
|
553 |
+
$current_month_number = (int)date('n', ctf_get_current_time() );
|
554 |
+
$not_early_in_the_year = ($current_month_number > 5);
|
555 |
+
|
556 |
+
if ( $not_early_in_the_year ) {
|
557 |
+
update_user_meta( get_current_user_id(), 'ctf_ignore_bfcm_sale_notice', date( 'Y', ctf_get_current_time() ) );
|
558 |
+
}
|
559 |
+
}
|
560 |
+
|
561 |
+
$option = $this->get_option();
|
562 |
+
$type = is_numeric( $id ) ? 'feed' : 'events';
|
563 |
+
|
564 |
+
$option['dismissed'][] = $id;
|
565 |
+
$option['dismissed'] = array_unique( $option['dismissed'] );
|
566 |
+
|
567 |
+
// Remove notification.
|
568 |
+
if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
|
569 |
+
foreach ( $option[ $type ] as $key => $notification ) {
|
570 |
+
if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons
|
571 |
+
unset( $option[ $type ][ $key ] );
|
572 |
+
break;
|
573 |
+
}
|
574 |
+
}
|
575 |
+
}
|
576 |
+
|
577 |
+
update_option( 'ctf_notifications', $option );
|
578 |
+
|
579 |
+
wp_send_json_success();
|
580 |
+
}
|
581 |
+
}
|
inc/notices.php
CHANGED
@@ -10,250 +10,10 @@ function ctf_get_current_time() {
|
|
10 |
|
11 |
// generates the html for the admin notices
|
12 |
function ctf_notices_html() {
|
13 |
-
|
14 |
-
if ( function_exists( 'sbi_notices_html' ) || function_exists( 'cff_notices_html' ) ) {
|
15 |
-
return;
|
16 |
-
}
|
17 |
-
|
18 |
-
$current_screen = get_current_screen();
|
19 |
-
$is_plugins_page = isset( $current_screen->id ) && $current_screen->id === 'plugins';
|
20 |
-
$page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
|
21 |
-
//Only show to admins
|
22 |
-
if ( ! current_user_can( 'manage_options' ) ) {
|
23 |
-
return;
|
24 |
-
}
|
25 |
-
|
26 |
-
$ctf_statuses_option = get_option( 'ctf_statuses', array() );
|
27 |
-
$current_time = ctf_get_current_time();
|
28 |
-
$ctf_bfcm_discount_code = 'happysmashgiving' . date('Y', $current_time );
|
29 |
-
|
30 |
-
// reset everything for testing
|
31 |
-
if ( false ) {
|
32 |
-
global $current_user;
|
33 |
-
$user_id = $current_user->ID;
|
34 |
-
delete_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice' );
|
35 |
-
//delete_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice' );
|
36 |
-
//$ctf_statuses_option = array( 'first_install' => strtotime( 'December 8, 2019' ) );
|
37 |
-
//$ctf_statuses_option = array( 'first_install' => time() );
|
38 |
-
|
39 |
-
//update_option( 'ctf_statuses', $ctf_statuses_option, false );
|
40 |
//delete_option( 'ctf_rating_notice');
|
41 |
//delete_transient( 'instagram_feed_rating_notice_waiting' );
|
42 |
-
|
43 |
-
//set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
|
44 |
-
//update_option( 'ctf_rating_notice', 'pending', false );
|
45 |
-
}
|
46 |
-
|
47 |
-
//$ctf_statuses_option['rating_notice_dismissed'] = time();
|
48 |
-
//update_option( 'ctf_statuses', $ctf_statuses_option, false );
|
49 |
-
// rating notice logic
|
50 |
-
$ctf_rating_notice_option = get_option( 'ctf_rating_notice', false );
|
51 |
-
$ctf_rating_notice_waiting = get_transient( 'custom_twitter_feeds_rating_notice_waiting' );
|
52 |
-
$should_show_rating_notice = ($ctf_rating_notice_waiting !== 'waiting' && $ctf_rating_notice_option !== 'dismissed');
|
53 |
-
|
54 |
-
// black friday cyber monday logic
|
55 |
-
$thanksgiving_this_year = ctf_get_future_date( 11, date('Y', $current_time ), 4, 4, 1 );
|
56 |
-
$one_week_before_black_friday_this_year = $thanksgiving_this_year - 7*24*60*60;
|
57 |
-
$one_day_after_cyber_monday_this_year = $thanksgiving_this_year + 5*24*60*60;
|
58 |
-
$has_been_two_days_since_rating_dismissal = isset( $ctf_statuses_option['rating_notice_dismissed'] ) ? ((int)$ctf_statuses_option['rating_notice_dismissed'] + 2*24*60*60) < $current_time : true;
|
59 |
-
|
60 |
-
$could_show_bfcm_discount = ($current_time > $one_week_before_black_friday_this_year && $current_time < $one_day_after_cyber_monday_this_year);
|
61 |
-
$should_show_bfcm_discount = false;
|
62 |
-
if ( $could_show_bfcm_discount && $has_been_two_days_since_rating_dismissal ) {
|
63 |
-
global $current_user;
|
64 |
-
$user_id = $current_user->ID;
|
65 |
-
|
66 |
-
$ignore_bfcm_sale_notice_meta = get_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice' );
|
67 |
-
$ignore_bfcm_sale_notice_meta = isset( $ignore_bfcm_sale_notice_meta[0] ) ? $ignore_bfcm_sale_notice_meta[0] : '';
|
68 |
-
|
69 |
-
/* Check that the user hasn't already clicked to ignore the message */
|
70 |
-
$should_show_bfcm_discount = ($ignore_bfcm_sale_notice_meta !== 'always' && $ignore_bfcm_sale_notice_meta !== date( 'Y', $current_time ));
|
71 |
-
}
|
72 |
-
|
73 |
-
// new user discount logic
|
74 |
-
$in_new_user_month_range = true;
|
75 |
-
$should_show_new_user_discount = false;
|
76 |
-
$has_been_one_month_since_rating_dismissal = isset( $ctf_statuses_option['rating_notice_dismissed'] ) ? ((int)$ctf_statuses_option['rating_notice_dismissed'] + 30*24*60*60) < $current_time + 1: true;
|
77 |
-
|
78 |
-
if ( isset( $ctf_statuses_option['first_install'] ) && $ctf_statuses_option['first_install'] === 'from_update' ) {
|
79 |
-
global $current_user;
|
80 |
-
$user_id = $current_user->ID;
|
81 |
-
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice' );
|
82 |
-
$ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
|
83 |
-
|
84 |
-
if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
|
85 |
-
$should_show_new_user_discount = true;
|
86 |
-
}
|
87 |
-
} elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal ) {
|
88 |
-
global $current_user;
|
89 |
-
$user_id = $current_user->ID;
|
90 |
-
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice' );
|
91 |
-
$ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
|
92 |
-
|
93 |
-
if ( $ignore_new_user_sale_notice_meta !== 'always'
|
94 |
-
&& isset( $ctf_statuses_option['first_install'] )
|
95 |
-
&& $current_time > (int)$ctf_statuses_option['first_install'] + 60*60*24*30 ) {
|
96 |
-
$should_show_new_user_discount = true;
|
97 |
-
}
|
98 |
-
}
|
99 |
-
|
100 |
-
// for debugging
|
101 |
-
if ( false ) {
|
102 |
-
global $current_user;
|
103 |
-
$user_id = $current_user->ID;
|
104 |
-
$ignore_bfcm_sale_notice_meta = get_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice' );
|
105 |
-
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice' );
|
106 |
-
|
107 |
-
var_dump( 'new user rating option', $ctf_rating_notice_option );
|
108 |
-
var_dump( 'new user rating transient', $ctf_rating_notice_waiting );
|
109 |
-
|
110 |
-
var_dump( 'should show new user rating notice?', $should_show_rating_notice );
|
111 |
-
|
112 |
-
var_dump( 'new user discount month range?', $in_new_user_month_range );
|
113 |
-
var_dump( 'should show new user discount?', $should_show_new_user_discount );
|
114 |
-
|
115 |
-
var_dump( 'Thanksgiving this year?', date('m/d/Y', $thanksgiving_this_year ) );
|
116 |
-
|
117 |
-
var_dump( 'could show bfcm discount?', $could_show_bfcm_discount );
|
118 |
-
var_dump( 'rating was dismissed?', date('m/d/Y', $ctf_statuses_option['rating_notice_dismissed'] ) );
|
119 |
-
|
120 |
-
var_dump( 'should show bfcm discount?', $should_show_bfcm_discount );
|
121 |
-
|
122 |
-
var_dump( 'ignore_bfcm_sale_notice_meta', $ignore_bfcm_sale_notice_meta );
|
123 |
-
var_dump( 'ignore_new_user_sale_notice_meta', $ignore_new_user_sale_notice_meta );
|
124 |
-
|
125 |
-
var_dump( $ctf_statuses_option );
|
126 |
-
}
|
127 |
-
|
128 |
-
|
129 |
-
if ( $should_show_rating_notice ) {
|
130 |
-
$other_notice_html = '';
|
131 |
-
$dismiss_url = add_query_arg( 'ctf_ignore_rating_notice_nag', '1' );
|
132 |
-
$later_url = add_query_arg( 'ctf_ignore_rating_notice_nag', 'later' );
|
133 |
-
if ( $should_show_bfcm_discount ) {
|
134 |
-
$other_notice_html = '<p class="ctf_other_notice">' . __( 'PS. We currently have a <a href="https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=adminnotice&utm_medium=bfcm&discount='.$ctf_bfcm_discount_code.'" target="_blank"><b style="font-weight: 700;">Black Friday deal</b></a> for 60% off the Pro version!', 'custom-twitter-feed' ) . '</p>';
|
135 |
-
|
136 |
-
$dismiss_url = add_query_arg( array(
|
137 |
-
'ctf_ignore_rating_notice_nag' => '1',
|
138 |
-
'ctf_ignore_bfcm_sale_notice' => date( 'Y', $current_time )
|
139 |
-
)
|
140 |
-
);
|
141 |
-
$later_url = add_query_arg( array(
|
142 |
-
'ctf_ignore_rating_notice_nag' => 'later',
|
143 |
-
'ctf_ignore_bfcm_sale_notice' => date( 'Y', $current_time )
|
144 |
-
)
|
145 |
-
);
|
146 |
-
}
|
147 |
-
|
148 |
-
echo "
|
149 |
-
<div class='ctf_notice ctf_review_notice'>
|
150 |
-
<img src='". CTF_PLUGIN_URL . 'img/ctf-icon.jpg' ."' alt='" . __( 'Custom Twitter Feed', 'custom-twitter-feed' ) . "'>
|
151 |
-
<div class='ctf-notice-text'>
|
152 |
-
<p style='padding-top: 4px;'>" . __( "It's great to see that you've been using the <strong style='font-weight: 700;'>Custom Twitter Feeds</strong> plugin for a while now. Hopefully you're happy with it! If so, would you consider leaving a positive review? It really helps to support the plugin and helps others to discover it too!", 'custom-twitter-feed' ) . "</p>
|
153 |
-
<p class='links'";
|
154 |
-
if( $should_show_bfcm_discount ) echo " style='margin-top: 0 !important;'";
|
155 |
-
echo ">
|
156 |
-
<a class='ctf_notice_dismiss' href='https://wordpress.org/support/plugin/custom-twitter-feeds/reviews/' target='_blank'>" . __( 'Sure, I\'d love to!', 'custom-twitter-feed' ) . "</a>
|
157 |
-
·
|
158 |
-
<a class='ctf_notice_dismiss' href='" .esc_url( $dismiss_url ). "'>" . __( 'No thanks', 'custom-twitter-feed' ) . "</a>
|
159 |
-
·
|
160 |
-
<a class='ctf_notice_dismiss' href='" .esc_url( $dismiss_url ). "'>" . __( 'I\'ve already given a review', 'custom-twitter-feed' ) . "</a>
|
161 |
-
·
|
162 |
-
<a class='ctf_notice_dismiss' href='" .esc_url( $later_url ). "'>" . __( 'Ask Me Later', 'custom-twitter-feed' ) . "</a>
|
163 |
-
</p>"
|
164 |
-
. $other_notice_html .
|
165 |
-
"</div>
|
166 |
-
<a class='ctf_notice_close' href='" .esc_url( $dismiss_url ). "'><i class='fa fa-close'></i></a>
|
167 |
-
</div>";
|
168 |
-
|
169 |
-
} elseif ( $should_show_new_user_discount ) {
|
170 |
-
global $current_user;
|
171 |
-
$user_id = $current_user->ID;
|
172 |
-
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice' );
|
173 |
-
if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
|
174 |
-
|
175 |
-
echo "
|
176 |
-
<div class='ctf_notice ctf_review_notice ctf_new_user_sale_notice'>
|
177 |
-
<img src='" . CTF_PLUGIN_URL . 'img/ctf-icon-offer.jpg' . "' alt='Custom Twitter Feed'>
|
178 |
-
<div class='ctf-notice-text'>
|
179 |
-
<p>" . __( '<b style="font-weight: 700;">Exclusive offer!</b> We don\'t run promotions very often, but for a limited time we\'re offering <b style="font-weight: 700;">60% off</b> our Pro version to all users of our free Custom Twitter Feeds plugin.', 'custom-twitter-feed' ) . "</p>
|
180 |
-
<p class='ctf-links'>
|
181 |
-
<a class='ctf_notice_dismiss ctf_offer_btn' href='https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=adminnotice&utm_medium=newuser&discount=twitterthankyou' target='_blank'><b>" . __( 'Get this offer', 'custom-twitter-feed' ) . "</b></a>
|
182 |
-
<a class='ctf_notice_dismiss' style='margin-left: 5px;' href='" . esc_url( add_query_arg( 'ctf_ignore_new_user_sale_notice', 'always' ) ) . "'>" . __( 'I\'m not interested', 'custom-twitter-feed' ) . "</a>
|
183 |
-
|
184 |
-
</p>
|
185 |
-
</div>
|
186 |
-
<a class='ctf_new_user_sale_notice_close' href='" . esc_url( add_query_arg( 'ctf_ignore_new_user_sale_notice', 'always' ) ) . "'><i class='fa fa-close'></i></a>
|
187 |
-
</div>
|
188 |
-
";
|
189 |
-
}
|
190 |
-
|
191 |
-
} elseif ( $should_show_bfcm_discount ) {
|
192 |
-
|
193 |
-
echo "
|
194 |
-
<div class='ctf_notice ctf_review_notice ctf_bfcm_sale_notice'>
|
195 |
-
<img src='". CTF_PLUGIN_URL . 'img/ctf-icon-offer.jpg' ."' alt='Custom Twitter Feed'>
|
196 |
-
<div class='ctf-notice-text'>
|
197 |
-
<p>" . __( '<b style="font-weight: 700;">Black Friday/Cyber Monday Deal!</b> Thank you for using our free Custom Twitter Feeds plugin. For a limited time, we\'re offering <b style="font-weight: 700;">60% off</b> the Pro version for all of our users.', 'custom-twitter-feed' ) . "</p>
|
198 |
-
<p class='ctf-links'>
|
199 |
-
<a class='ctf_notice_dismiss ctf_offer_btn' href='https://smashballoon.com/custom-twitter-feeds/?utm_campaign=twitter-free&utm_source=adminnotice&utm_medium=bfcmmain&discount=".$ctf_bfcm_discount_code."' target='_blank'><b>" . __( 'Get this offer', 'custom-twitter-feed' ) . "</b></a>
|
200 |
-
<a class='ctf_notice_dismiss' style='margin-left: 5px;' href='" .esc_url( add_query_arg( 'ctf_ignore_bfcm_sale_notice', date( 'Y', $current_time ) ) ). "'>" . __( 'I\'m not interested', 'custom-twitter-feed' ) . "</a>
|
201 |
-
</p>
|
202 |
-
</div>
|
203 |
-
<a class='ctf_bfcm_sale_notice_close' href='" .esc_url( add_query_arg( 'ctf_ignore_bfcm_sale_notice', date( 'Y', $current_time ) ) ). "'><i class='fa fa-close'></i></a>
|
204 |
-
</div>
|
205 |
-
";
|
206 |
-
|
207 |
-
}
|
208 |
-
|
209 |
-
}
|
210 |
-
add_action( 'admin_notices', 'ctf_notices_html', 12 ); // priority 8 for Instagram, priority 10 for Facebook
|
211 |
-
|
212 |
-
function ctf_process_nags() {
|
213 |
-
|
214 |
-
global $current_user;
|
215 |
-
$user_id = $current_user->ID;
|
216 |
-
$ctf_statuses_option = get_option( 'ctf_statuses', array() );
|
217 |
-
|
218 |
-
if ( isset( $_GET['ctf_ignore_rating_notice_nag'] ) ) {
|
219 |
-
if ( (int)$_GET['ctf_ignore_rating_notice_nag'] === 1 ) {
|
220 |
-
update_option( 'ctf_rating_notice', 'dismissed', false );
|
221 |
-
$ctf_statuses_option['rating_notice_dismissed'] = ctf_get_current_time();
|
222 |
-
update_option( 'ctf_statuses', $ctf_statuses_option, false );
|
223 |
-
|
224 |
-
} elseif ( $_GET['ctf_ignore_rating_notice_nag'] === 'later' ) {
|
225 |
-
set_transient( 'custom_twitter_feeds_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
|
226 |
-
update_option( 'ctf_rating_notice', 'pending', false );
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
-
if ( isset( $_GET['ctf_ignore_new_user_sale_notice'] ) ) {
|
231 |
-
$response = sanitize_text_field( $_GET['ctf_ignore_new_user_sale_notice'] );
|
232 |
-
if ( $response === 'always' ) {
|
233 |
-
update_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice', 'always' );
|
234 |
-
|
235 |
-
$current_month_number = (int)date('n', ctf_get_current_time() );
|
236 |
-
$not_early_in_the_year = ($current_month_number > 5);
|
237 |
-
|
238 |
-
if ( $not_early_in_the_year ) {
|
239 |
-
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', date( 'Y', ctf_get_current_time() ) );
|
240 |
-
}
|
241 |
-
|
242 |
-
}
|
243 |
-
}
|
244 |
-
|
245 |
-
if ( isset( $_GET['ctf_ignore_bfcm_sale_notice'] ) ) {
|
246 |
-
$response = sanitize_text_field( $_GET['ctf_ignore_bfcm_sale_notice'] );
|
247 |
-
if ( $response === 'always' ) {
|
248 |
-
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', 'always' );
|
249 |
-
} elseif ( $response === date( 'Y', ctf_get_current_time() ) ) {
|
250 |
-
update_user_meta( $user_id, 'ctf_ignore_bfcm_sale_notice', date( 'Y', ctf_get_current_time() ) );
|
251 |
-
}
|
252 |
-
update_user_meta( $user_id, 'ctf_ignore_new_user_sale_notice', 'always' );
|
253 |
-
}
|
254 |
-
|
255 |
}
|
256 |
-
add_action( '
|
257 |
|
258 |
function ctf_get_future_date( $month, $year, $week, $day, $direction ) {
|
259 |
if ( $direction > 0 ) {
|
10 |
|
11 |
// generates the html for the admin notices
|
12 |
function ctf_notices_html() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
//delete_option( 'ctf_rating_notice');
|
14 |
//delete_transient( 'instagram_feed_rating_notice_waiting' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
16 |
+
//add_action( 'admin_notices', 'ctf_notices_html', 12 ); // priority 8 for Instagram, priority 10 for Facebook
|
17 |
|
18 |
function ctf_get_future_date( $month, $year, $week, $day, $direction ) {
|
19 |
if ( $direction > 0 ) {
|
js/admin-notifications.js
ADDED
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* CTF Admin Notifications.
|
3 |
+
*
|
4 |
+
* @since 2.18
|
5 |
+
*/
|
6 |
+
|
7 |
+
'use strict';
|
8 |
+
|
9 |
+
var CTFAdminNotifications = window.CTFAdminNotifications || ( function( document, window, $ ) {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Elements holder.
|
13 |
+
*
|
14 |
+
* @since 2.18
|
15 |
+
*
|
16 |
+
* @type {object}
|
17 |
+
*/
|
18 |
+
var el = {
|
19 |
+
|
20 |
+
$notifications: $( '#ctf-notifications' ),
|
21 |
+
$nextButton: $( '#ctf-notifications .navigation .next' ),
|
22 |
+
$prevButton: $( '#ctf-notifications .navigation .prev' ),
|
23 |
+
$adminBarCounter: $( '#wp-admin-bar-wpforms-menu .ctf-menu-notification-counter' ),
|
24 |
+
$adminBarMenuItem: $( '#wp-admin-bar-ctf-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: 'ctf_dashboard_notification_dismiss',
|
125 |
+
nonce: ctf_admin.nonce,
|
126 |
+
id: messageId,
|
127 |
+
};
|
128 |
+
|
129 |
+
$.post( ctf_admin.ajax_url, data, function( res ) {
|
130 |
+
|
131 |
+
if ( ! res.success ) {
|
132 |
+
//CTFAdmin.debug( res );
|
133 |
+
}
|
134 |
+
} ).fail( function( xhr, textStatus, e ) {
|
135 |
+
|
136 |
+
//CTFAdmin.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 |
+
CTFAdminNotifications.init();
|
uninstall.php
CHANGED
@@ -17,6 +17,8 @@ if ( ! $ctf_preserve_settings ) {
|
|
17 |
delete_option( 'ctf_version' );
|
18 |
delete_option( 'ctf_rating_notice' );
|
19 |
delete_transient( 'custom_twitter_feeds_rating_notice_waiting' );
|
|
|
|
|
20 |
|
21 |
// delete tweet cache in transients
|
22 |
global $wpdb;
|
17 |
delete_option( 'ctf_version' );
|
18 |
delete_option( 'ctf_rating_notice' );
|
19 |
delete_transient( 'custom_twitter_feeds_rating_notice_waiting' );
|
20 |
+
delete_option( 'ctf_notifications' );
|
21 |
+
delete_option( 'ctf_newuser_notifications' );
|
22 |
|
23 |
// delete tweet cache in transients
|
24 |
global $wpdb;
|
views/admin/main.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<div id="ctf-admin" class="wrap">
|
2 |
-
<?php
|
|
|
|
|
3 |
$lite_notice_dismissed = get_transient( 'twitter_feed_dismiss_lite' );
|
4 |
|
5 |
if ( ! $lite_notice_dismissed ) :
|
1 |
<div id="ctf-admin" class="wrap">
|
2 |
+
<?php do_action( 'ctf_admin_overview_before_title' ); ?>
|
3 |
+
|
4 |
+
<?php
|
5 |
$lite_notice_dismissed = get_transient( 'twitter_feed_dismiss_lite' );
|
6 |
|
7 |
if ( ! $lite_notice_dismissed ) :
|