Twitter Widget Pro - Version 2.5.0

Version Description

Upgrade to the new Twitter API and add support for lists

Download this release

Release Info

Developer aaroncampbell
Plugin Icon wp plugin Twitter Widget Pro
Version 2.5.0
Comparing to
See all releases

Code changes from version 2.4.1 to 2.5.0

languages/twitter-widget-pro-nl_NL.mo ADDED
Binary file
languages/twitter-widget-pro-nl_NL.po ADDED
@@ -0,0 +1,380 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2012
2
+ # This file is distributed under the same license as the package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Twitter Widget Pro in dutch\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/twitter-widget-pro\n"
7
+ "POT-Creation-Date: 2012-10-10 18:44:11+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "Plural-Forms: nplurals=2;plural=n != 1;\n"
12
+ "PO-Revision-Date: 2012-10-11 11:18+0100\n"
13
+ "Last-Translator: \n"
14
+ "Language-Team: Marko Heijnen <info@markoheijnen.com>\n"
15
+ "X-Generator: Poedit 1.5.4\n"
16
+ "Language: Dutch\n"
17
+
18
+ #: range-plugin-framework.php:251
19
+ msgid "Update Options &raquo;"
20
+ msgstr "Bewerk opties &raquo;"
21
+
22
+ #: range-plugin-framework.php:297
23
+ msgid "Rate Plugin"
24
+ msgstr "Beoordeel Plugin"
25
+
26
+ #: range-plugin-framework.php:303
27
+ msgid "Support"
28
+ msgstr "Support"
29
+
30
+ #: range-plugin-framework.php:311
31
+ msgid "Donate to show your appreciation."
32
+ msgstr "Doneer om jouw waardering te tonen."
33
+
34
+ #: range-plugin-framework.php:322
35
+ msgid "Give it a good rating on WordPress.org."
36
+ msgstr "Geef het een goede beoordeling op WordPress.org."
37
+
38
+ #: range-plugin-framework.php:332
39
+ msgid "Settings"
40
+ msgstr "Instellingen"
41
+
42
+ #: range-plugin-framework.php:361
43
+ msgid "Like this Plugin?"
44
+ msgstr "Vind je deze plugin leuk?"
45
+
46
+ #: range-plugin-framework.php:364
47
+ msgid "Need Support?"
48
+ msgstr "Support nodig?"
49
+
50
+ #: range-plugin-framework.php:367
51
+ msgid "Latest news from Range"
52
+ msgstr "Laatste nieuws van Range"
53
+
54
+ #: range-plugin-framework.php:372
55
+ msgid "Then please do any or all of the following:"
56
+ msgstr "Dan zou je de één van de volgende kunnen doen: "
57
+
58
+ #: range-plugin-framework.php:377
59
+ msgid "Link to it so others can find out about it."
60
+ msgstr "Link naar het zodat andere het kunnen vinden."
61
+
62
+ #: range-plugin-framework.php:389
63
+ msgid ""
64
+ "If you have any problems with this plugin or ideas for improvements or "
65
+ "enhancements, please use the <a href=\"%s\">Support Forums</a>."
66
+ msgstr ""
67
+ "Als je problemen hebt met deze plugin of ideeën hebt voor verbeteringen of "
68
+ "uitbreidingen, gebruik dan de <a href=\"%s\">Support Forums</a>."
69
+
70
+ #: wp-twitter-widget.php:44
71
+ msgid "Follow a Twitter Feed"
72
+ msgstr "Volg een Twitter Feed"
73
+
74
+ #: wp-twitter-widget.php:51 wp-twitter-widget.php:197
75
+ msgid "Twitter Widget Pro"
76
+ msgstr "Twitter Widget Pro"
77
+
78
+ #: wp-twitter-widget.php:66 wp-twitter-widget.php:340
79
+ msgid "Twitter username:"
80
+ msgstr "Twitter gebruikersnaam:"
81
+
82
+ #: wp-twitter-widget.php:70 wp-twitter-widget.php:348
83
+ msgid "Give the feed a title ( optional ):"
84
+ msgstr "Geef de feed een titel ( optioneel ):"
85
+
86
+ #: wp-twitter-widget.php:74 wp-twitter-widget.php:356
87
+ msgid "How many items would you like to display?"
88
+ msgstr "Hoeveel regels wil je weergeven?"
89
+
90
+ #: wp-twitter-widget.php:84 wp-twitter-widget.php:370
91
+ msgid "Display profile image?"
92
+ msgstr "Toon profielafbeelding?"
93
+
94
+ #: wp-twitter-widget.php:86 wp-twitter-widget.php:374
95
+ msgid "Do not show"
96
+ msgstr "Niet tonen"
97
+
98
+ #: wp-twitter-widget.php:87 wp-twitter-widget.php:375
99
+ msgid "Mini - 24px by 24px"
100
+ msgstr "Klein - 24px by 24px"
101
+
102
+ #: wp-twitter-widget.php:88 wp-twitter-widget.php:376
103
+ msgid "Normal - 48px by 48px"
104
+ msgstr "Normaal - 48px by 48px"
105
+
106
+ #: wp-twitter-widget.php:89 wp-twitter-widget.php:377
107
+ msgid "Bigger - 73px by 73px"
108
+ msgstr "Groot - 73px by 73px"
109
+
110
+ #: wp-twitter-widget.php:90 wp-twitter-widget.php:378
111
+ msgid "Original"
112
+ msgstr "Orgineel"
113
+
114
+ #: wp-twitter-widget.php:96 wp-twitter-widget.php:429
115
+ msgid "Include retweets"
116
+ msgstr "Retweets tonen"
117
+
118
+ #: wp-twitter-widget.php:100 wp-twitter-widget.php:432
119
+ msgid "Hide @replies"
120
+ msgstr "Verberg @replies"
121
+
122
+ #: wp-twitter-widget.php:104 wp-twitter-widget.php:435
123
+ msgid "Hide sending applications"
124
+ msgstr "Verberg verstuur toepassing"
125
+
126
+ #: wp-twitter-widget.php:109 wp-twitter-widget.php:439
127
+ msgid "Show Tweet Intents (reply, retweet, favorite)"
128
+ msgstr "Toon Tweet soort (antwoord, retweet, favoriet)"
129
+
130
+ #: wp-twitter-widget.php:114 wp-twitter-widget.php:443
131
+ msgid "Show Follow Link"
132
+ msgstr "Toon volg link"
133
+
134
+ #: wp-twitter-widget.php:117 wp-twitter-widget.php:384
135
+ msgid "What to display when Twitter is down ( optional ):"
136
+ msgstr ""
137
+ "Wat moet er worden weergegeven wanneer Twitter offline is ( optioneel ):"
138
+
139
+ #: wp-twitter-widget.php:121 wp-twitter-widget.php:392
140
+ msgid "Number of seconds to wait for a response from Twitter ( default 2 ):"
141
+ msgstr ""
142
+ "Aantal seconden voor het wachten op een reactie van Twitter ( standaard 2 ):"
143
+
144
+ #: wp-twitter-widget.php:125 wp-twitter-widget.php:400
145
+ msgid "Show date/time of Tweet ( rather than 2 ____ ago ):"
146
+ msgstr "Toon datum/tijd van een tweet ( meer dan 2 ____ geleden ):"
147
+
148
+ #: wp-twitter-widget.php:127 wp-twitter-widget.php:404
149
+ msgid "Always"
150
+ msgstr "Altijd"
151
+
152
+ #: wp-twitter-widget.php:128 wp-twitter-widget.php:405
153
+ msgid "If over an hour old"
154
+ msgstr "Indien meer dan een uur oud"
155
+
156
+ #: wp-twitter-widget.php:129 wp-twitter-widget.php:406
157
+ msgid "If over a day old"
158
+ msgstr "Indien meer dan een dag oud"
159
+
160
+ #: wp-twitter-widget.php:130 wp-twitter-widget.php:407
161
+ msgid "If over a week old"
162
+ msgstr "Indien meer dan een week oud"
163
+
164
+ #: wp-twitter-widget.php:131 wp-twitter-widget.php:408
165
+ msgid "If over a month old"
166
+ msgstr "Indien meer dan een maand oud"
167
+
168
+ #: wp-twitter-widget.php:132 wp-twitter-widget.php:409
169
+ msgid "If over a year old"
170
+ msgstr "Indien meer dan een jaar oud"
171
+
172
+ #: wp-twitter-widget.php:133 wp-twitter-widget.php:410
173
+ msgid "Never"
174
+ msgstr "Nooit"
175
+
176
+ #: wp-twitter-widget.php:137 wp-twitter-widget.php:416
177
+ msgid ""
178
+ "Format to dispaly the date in, uses <a href=\"%s\">PHP date()</a> format:"
179
+ msgstr ""
180
+ "Opmaak om de datum te tonen, maakt gebruik van <a href=\"%s\">PHP date()</a> "
181
+ "formaat:"
182
+
183
+ #: wp-twitter-widget.php:142 wp-twitter-widget.php:446
184
+ msgid "Open links in a new window"
185
+ msgstr "Open links in een nieuw venster"
186
+
187
+ #: wp-twitter-widget.php:146 wp-twitter-widget.php:449
188
+ msgid "Show Link to Twitter Widget Pro"
189
+ msgstr "Toon link naar Twitter Widget Pro"
190
+
191
+ #: wp-twitter-widget.php:198
192
+ msgid "Twitter Widget"
193
+ msgstr "Twitter Widget"
194
+
195
+ #: wp-twitter-widget.php:262
196
+ msgid "There were no locks to clear!"
197
+ msgstr "Er waren geen blokkeringen om op te schonen"
198
+
199
+ #: wp-twitter-widget.php:264
200
+ msgid "Successfully cleared %d lock."
201
+ msgid_plural "Successfully cleared %d locks."
202
+ msgstr[0] "Succesvol %d blokkering verwijderd."
203
+ msgstr[1] "Succesvol %d blokkeringen verwijderd."
204
+
205
+ #: wp-twitter-widget.php:270
206
+ msgid "General Settings"
207
+ msgstr "Algemene instellingen"
208
+
209
+ #: wp-twitter-widget.php:271
210
+ msgid "Default Settings for Shortcodes"
211
+ msgstr "Standaard instellingen voor shortcodes"
212
+
213
+ #: wp-twitter-widget.php:280
214
+ msgid "HTTP vs HTTPS:"
215
+ msgstr "HTTP vs HTTPS:"
216
+
217
+ #: wp-twitter-widget.php:284
218
+ msgid "Use Twitter API via HTTPS"
219
+ msgstr "Gebruik Twitter API over HTTPS"
220
+
221
+ #: wp-twitter-widget.php:287
222
+ msgid "Use Twitter API via HTTP"
223
+ msgstr "Gebruik Twitter API over HTTP"
224
+
225
+ #: wp-twitter-widget.php:289
226
+ msgid ""
227
+ "Some servers seem to have issues connecting via HTTPS. If you're "
228
+ "experiencing issues with your feed not updating, try setting this to HTTP."
229
+ msgstr ""
230
+ "Sommige servers lijken problemen te hebben om via HTTPS te verbinden. Indien "
231
+ "je problemen ondervindt dat je feed niet update, probeer dan HTTP."
232
+
233
+ #: wp-twitter-widget.php:294
234
+ msgid "Clear Update Locks:"
235
+ msgstr "Schoon blokkeringen op:"
236
+
237
+ #: wp-twitter-widget.php:297
238
+ msgid "Clear Update Locks"
239
+ msgstr "Schoon blokkeringen op"
240
+
241
+ #: wp-twitter-widget.php:298
242
+ msgid ""
243
+ "A small perecntage of servers seem to have issues where an update lock isn't "
244
+ "getting cleared. If you're experiencing issues with your feed not updating, "
245
+ "try clearing the update locks."
246
+ msgstr ""
247
+ "Een klein percentage van servers lijkt problemen te hebben met een update "
248
+ "blokkering die niet word gewist. Als u problemen ondervindt met dat je feed "
249
+ "niet update, probeer dan zelf de update blokkeringen te wissen."
250
+
251
+ #: wp-twitter-widget.php:303
252
+ msgid "Current API Usage"
253
+ msgstr "Huidige API gebruik"
254
+
255
+ #: wp-twitter-widget.php:314
256
+ msgid "Used: %d"
257
+ msgstr "Gebruikt: %d"
258
+
259
+ #: wp-twitter-widget.php:315
260
+ msgid "Remaining: %d"
261
+ msgstr "Resterende: %d"
262
+
263
+ #: wp-twitter-widget.php:318
264
+ msgid "Limits reset in: %d minutes"
265
+ msgid_plural "Limits reset in: %d minutes"
266
+ msgstr[0] "Limieten hersteld in: %d minuut"
267
+ msgstr[1] "Limieten hersteld in: %d minuten"
268
+
269
+ #: wp-twitter-widget.php:320
270
+ msgid "This is overall usage, not just usage from Twitter Widget Pro"
271
+ msgstr ""
272
+ "Dit is het totale gebruik, niet alleen het gebruik van Twitter Widget Pro"
273
+
274
+ #: wp-twitter-widget.php:325
275
+ msgid "There was an error checking your rate limit."
276
+ msgstr "Er was een fout tijdens het controleren van je rate limiet."
277
+
278
+ #: wp-twitter-widget.php:336
279
+ msgid ""
280
+ "These settings are the default for the shortcodes and all of them can be "
281
+ "overridden by specifying a different value in the shortcode itself. All "
282
+ "settings for widgets are locate in the individual widget."
283
+ msgstr ""
284
+ "Deze instellingen zijn de standaard voor shortcodes en je kunt ze "
285
+ "overschrijven door een andere waarde aan de shortcode mee te geven. Alle "
286
+ "instellingen voor widgets zijn te vinden in de individuele widget."
287
+
288
+ #: wp-twitter-widget.php:424
289
+ msgid "Other Setting:"
290
+ msgstr "Overige indelingen"
291
+
292
+ #: wp-twitter-widget.php:637
293
+ msgid "No Tweets Available"
294
+ msgstr "Geen Tweets beschikbaar"
295
+
296
+ #: wp-twitter-widget.php:655
297
+ msgid "from %s"
298
+ msgstr "van %s"
299
+
300
+ #: wp-twitter-widget.php:659
301
+ msgid "in reply to %s"
302
+ msgstr "in reactie op %s"
303
+
304
+ #: wp-twitter-widget.php:676
305
+ msgid "Reply"
306
+ msgstr "Reageer"
307
+
308
+ #: wp-twitter-widget.php:682
309
+ msgid "Retweet"
310
+ msgstr "Retweet"
311
+
312
+ #: wp-twitter-widget.php:688
313
+ msgid "Favorite"
314
+ msgstr "Favoriet"
315
+
316
+ #: wp-twitter-widget.php:709
317
+ msgid "Follow %s"
318
+ msgstr "Volg %s"
319
+
320
+ #: wp-twitter-widget.php:723
321
+ msgid "Brought to you by Range - A WordPress design and development company"
322
+ msgstr "Aangeboden door Range - Een WordPress ontwerp en ontwikkeling bedrijf"
323
+
324
+ #: wp-twitter-widget.php:725
325
+ msgid "Powered by"
326
+ msgstr "Powered by"
327
+
328
+ #: wp-twitter-widget.php:794
329
+ msgid "Invalid Twitter Response."
330
+ msgstr "Incorrecte Twitter reactie."
331
+
332
+ #: wp-twitter-widget.php:804
333
+ msgid "Could not connect to Twitter"
334
+ msgstr "Kon niet met Twitter verbinden"
335
+
336
+ #: wp-twitter-widget.php:886
337
+ msgid "about %s year ago"
338
+ msgid_plural "about %s years ago"
339
+ msgstr[0] "ongeveer %s jaar geleden"
340
+ msgstr[1] "ongeveer %s jaar geleden"
341
+
342
+ #: wp-twitter-widget.php:887
343
+ msgid "about %s month ago"
344
+ msgid_plural "about %s months ago"
345
+ msgstr[0] "ongeveer %s maand geleden"
346
+ msgstr[1] "ongeveer %s maanden geleden"
347
+
348
+ #: wp-twitter-widget.php:888
349
+ msgid "about %s week ago"
350
+ msgid_plural "about %s weeks ago"
351
+ msgstr[0] "ongeveer %s week geleden"
352
+ msgstr[1] "ongeveer %s weken geleden"
353
+
354
+ #: wp-twitter-widget.php:889
355
+ msgid "about %s day ago"
356
+ msgid_plural "about %s days ago"
357
+ msgstr[0] "ongeveer %s dag geleden"
358
+ msgstr[1] "ongeveer %s dagen geleden"
359
+
360
+ #: wp-twitter-widget.php:890
361
+ msgid "about %s hour ago"
362
+ msgid_plural "about %s hours ago"
363
+ msgstr[0] "ongeveer %s uur geleden"
364
+ msgstr[1] "ongeveer %s uur geleden"
365
+
366
+ #: wp-twitter-widget.php:891
367
+ msgid "about %s minute ago"
368
+ msgid_plural "about %s minutes ago"
369
+ msgstr[0] "ongeveer %s minuut geleden"
370
+ msgstr[1] "ongeveer %s minuten geleden"
371
+
372
+ #: wp-twitter-widget.php:892
373
+ msgid "about %s second ago"
374
+ msgid_plural "about %s seconds ago"
375
+ msgstr[0] "ongeveer %s seconde geleden"
376
+ msgstr[1] "ongeveer %s seconden geleden"
377
+
378
+ #: wp-twitter-widget.php:944 wp-twitter-widget.php:1018
379
+ msgid "h:i:s A F d, Y"
380
+ msgstr "h:i:s j F Y"
lib/oauth-util.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class OAuthUtil {
3
+ public static function urlencode_rfc3986( $input ) {
4
+ if ( is_array( $input ) )
5
+ return array_map( array( 'OAuthUtil', 'urlencode_rfc3986' ), $input );
6
+ else if ( is_scalar( $input ) )
7
+ return str_replace( '+', ' ', str_replace( '%7E', '~', rawurlencode( $input ) ) );
8
+ else
9
+ return '';
10
+ }
11
+
12
+ // This decode function isn't taking into consideration the above
13
+ // modifications to the encoding process. However, this method doesn't seem to
14
+ // be used anywhere so leaving it as is.
15
+ public static function urldecode_rfc3986($string) {
16
+ return urldecode($string);
17
+ }
18
+
19
+ // Utility function for turning the Authorization: header into parameters, has
20
+ // to do some unescaping Can filter out any non-oauth parameters if needed
21
+ // (default behaviour)
22
+ public static function split_header($header, $only_allow_oauth_parameters = true) {
23
+ $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
24
+ $offset = 0;
25
+ $params = array();
26
+ while ( preg_match( $pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset ) > 0 ) {
27
+ $match = $matches[0];
28
+ $header_name = $matches[2][0];
29
+ $header_content = ( isset( $matches[5] ) ) ? $matches[5][0] : $matches[4][0];
30
+ if ( preg_match( '/^oauth_/', $header_name ) || ! $only_allow_oauth_parameters )
31
+ $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
32
+
33
+ $offset = $match[1] + strlen($match[0]);
34
+ }
35
+
36
+ if ( isset( $params['realm'] ) )
37
+ unset( $params['realm'] );
38
+
39
+ return $params;
40
+ }
41
+
42
+ // helper to try to sort out headers for people who aren't running apache
43
+ public static function get_headers() {
44
+ if ( function_exists( 'apache_request_headers' ) ) {
45
+ // we need this to get the actual Authorization: header because apache
46
+ // tends to tell us it doesn't exist
47
+ $headers = apache_request_headers();
48
+
49
+ // sanitize the output of apache_request_headers because we always want
50
+ // the keys to be Cased-Like-This and arh() returns the headers in the
51
+ // same case as they are in the request
52
+ $out = array();
53
+ foreach( $headers as $key => $value ) {
54
+ $key = str_replace( ' ', '-', ucwords( strtolower( str_replace( '-', ' ', $key ) ) ) );
55
+ $out[$key] = $value;
56
+ }
57
+ } else {
58
+ // otherwise we don't have apache and are just going to have to hope that
59
+ // $_SERVER actually contains what we need
60
+ $out = array();
61
+ if( isset( $_SERVER['CONTENT_TYPE'] ) )
62
+ $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
63
+ if( isset( $_ENV['CONTENT_TYPE'] ) )
64
+ $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
65
+
66
+ foreach ( $_SERVER as $key => $value ) {
67
+ if (substr($key, 0, 5) == "HTTP_") {
68
+ // this is chaos, basically it is just there to capitalize the first
69
+ // letter of every word that is not an initial HTTP and strip HTTP
70
+ // code from przemek
71
+ $key = str_replace( ' ', '-', ucwords( strtolower( str_replace( '_', ' ', substr( $key, 5 ) ) ) ) );
72
+ $out[$key] = $value;
73
+ }
74
+ }
75
+ }
76
+ return $out;
77
+ }
78
+
79
+ // This function takes a input like a=b&a=c&d=e and returns the parsed
80
+ // parameters like this array('a' => array('b','c'), 'd' => 'e')
81
+ public static function parse_parameters( $input ) {
82
+ if ( ! isset( $input ) || ! $input )
83
+ return array();
84
+
85
+ $pairs = explode( '&', $input );
86
+
87
+ $parsed_parameters = array();
88
+ foreach ( $pairs as $pair ) {
89
+ $split = explode( '=', $pair, 2 );
90
+ $parameter = OAuthUtil::urldecode_rfc3986( $split[0] );
91
+ $value = isset( $split[1] ) ? OAuthUtil::urldecode_rfc3986( $split[1] ) : '';
92
+
93
+ if ( isset( $parsed_parameters[$parameter] ) ) {
94
+ // We have already recieved parameter(s) with this name, so add to the
95
+ // list of parameters with this name
96
+
97
+ // This is the first duplicate, so transform scalar (string) into an
98
+ // array so we can add the duplicates
99
+ if ( is_scalar( $parsed_parameters[$parameter] ) )
100
+ $parsed_parameters[$parameter] = array( $parsed_parameters[$parameter] );
101
+
102
+ $parsed_parameters[$parameter][] = $value;
103
+ } else {
104
+ $parsed_parameters[$parameter] = $value;
105
+ }
106
+ }
107
+ return $parsed_parameters;
108
+ }
109
+
110
+ public static function build_http_query($params) {
111
+ if ( ! $params )
112
+ return '';
113
+
114
+ // Urlencode both keys and values
115
+ $keys = OAuthUtil::urlencode_rfc3986( array_keys( $params ) );
116
+ $values = OAuthUtil::urlencode_rfc3986( array_values( $params ) );
117
+ $params = array_combine( $keys, $values );
118
+
119
+ // Parameters are sorted by name, using lexicographical byte value ordering.
120
+ // Ref: Spec: 9.1.1 (1)
121
+ uksort( $params, 'strcmp' );
122
+
123
+ $pairs = array();
124
+ foreach ( $params as $parameter => $value ) {
125
+ if (is_array($value)) {
126
+ // If two or more parameters share the same name, they are sorted by
127
+ // their value Ref: Spec: 9.1.1 (1)
128
+ natsort($value);
129
+ foreach ($value as $duplicate_value) {
130
+ $pairs[] = $parameter . '=' . $duplicate_value;
131
+ }
132
+ } else {
133
+ $pairs[] = $parameter . '=' . $value;
134
+ }
135
+ }
136
+ // For each parameter, the name is separated from the corresponding value by
137
+ // an '=' character (ASCII code 61) Each name-value pair is separated by an
138
+ // '&' character (ASCII code 38)
139
+ return implode( '&', $pairs );
140
+ }
141
+ }
lib/wp-twitter.php ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once( 'oauth-util.php' );
3
+ class wpTwitter {
4
+ /**
5
+ * @var string Twitter App Consumer Key
6
+ */
7
+ private $_consumer_key;
8
+
9
+ /**
10
+ * @var string Twitter App Secret Key
11
+ */
12
+ private $_consumer_secret;
13
+
14
+ /**
15
+ * @var string Twitter Request or Access Token
16
+ */
17
+ private $_token;
18
+
19
+ private static $_api_url;
20
+
21
+ public function __construct( $args ) {
22
+ $defaults = array(
23
+ 'api-url' => 'https://api.twitter.com/',
24
+ );
25
+ $args = wp_parse_args( $args, $defaults );
26
+ $this->_consumer_key = $args['consumer-key'];
27
+ $this->_consumer_secret = $args['consumer-secret'];
28
+ self::$_api_url = $args['api-url'];
29
+ if ( !empty( $args['token'] ) )
30
+ $this->_token = $args['token'];
31
+ }
32
+
33
+ public static function get_api_endpoint( $method, $format = 'json', $version = '1.1' ) {
34
+ $method = preg_replace( '|[^\w/]|', '', $method );
35
+ if ( ! empty( $format ) )
36
+ $format = '.json';
37
+ if ( ! empty( $version ) )
38
+ $version .= '/';
39
+
40
+ return self::$_api_url . $version . $method . $format;
41
+ }
42
+
43
+ /**
44
+ * Get a request_token from Twitter
45
+ *
46
+ * @returns a key/value array containing oauth_token and oauth_token_secret
47
+ */
48
+ public function getRequestToken( $oauth_callback = null ) {
49
+ $parameters = array(
50
+ 'oauth_nonce' => md5( microtime() . mt_rand() ),
51
+ );
52
+ if ( ! empty( $oauth_callback ) )
53
+ $parameters['oauth_callback'] = add_query_arg( array('nonce'=>$parameters['oauth_nonce']), $oauth_callback );
54
+
55
+ $request_url = self::get_api_endpoint( 'oauth/request_token', '', '' );
56
+ $this->_token = $this->send_authed_request( $request_url, 'GET', $parameters );
57
+ if ( ! is_wp_error( $this->_token ) )
58
+ $this->_token['nonce'] = $parameters['oauth_nonce'];
59
+ return $this->_token;
60
+ }
61
+
62
+ private function _get_oauth_params() {
63
+ $params = array(
64
+ 'oauth_version' => '1.0',
65
+ 'oauth_nonce' => md5( microtime() . mt_rand() ),
66
+ 'oauth_timestamp' => time(),
67
+ 'oauth_consumer_key' => $this->_consumer_key
68
+ );
69
+
70
+ if ( ! empty( $this->_token['oauth_token'] ) )
71
+ $params['oauth_token'] = $this->_token['oauth_token'];
72
+
73
+ return $params;
74
+ }
75
+
76
+ /**
77
+ * Get the authorize URL
78
+ *
79
+ * @returns a string
80
+ */
81
+ public function get_authorize_url( $screen_name = '' ) {
82
+ if ( empty( $this->_token['oauth_token'] ) )
83
+ return false;
84
+
85
+ $query_args = array(
86
+ 'oauth_token' => $this->_token['oauth_token']
87
+ );
88
+ if ( !empty( $screen_name ) ) {
89
+ $query_args['screen_name'] = $screen_name;
90
+ $query_args['force_login'] = 'true';
91
+ }
92
+ return add_query_arg( $query_args, self::get_api_endpoint( 'oauth/authorize', '', '' ) );
93
+ }
94
+
95
+ /**
96
+ * Format and sign an OAuth / API request
97
+ */
98
+ public function send_authed_request( $request_url, $method, $parameters = array() ) {
99
+ $parameters = wp_parse_args( $parameters, $this->_get_oauth_params() );
100
+ if ( ! filter_var( $request_url , FILTER_VALIDATE_URL ) )
101
+ $request_url = self::get_api_endpoint( $request_url );
102
+ $this->sign_request( $parameters, $request_url );
103
+ switch ($method) {
104
+ case 'GET':
105
+ $request_url = $this->get_normalized_http_url( $request_url ) . '?' . OAuthUtil::build_http_query( $parameters );
106
+ $resp = wp_remote_get($request_url);
107
+ break;
108
+ default:
109
+ $resp = wp_remote_request($request_url, array( 'method'=>$method, 'body'=>$parameters));
110
+ }
111
+
112
+ if ( 'account/verify_credentials' == $method )
113
+ dump( $resp, '$resp' );
114
+
115
+ if ( !is_wp_error( $resp ) && $resp['response']['code'] >= 200 && $resp['response']['code'] < 300 ) {
116
+ $decoded_response = json_decode( $resp['body'] );
117
+ if ( empty( $decoded_response ) && ! empty( $resp['body'] ) )
118
+ $decoded_response = wp_parse_args( $resp['body'] );
119
+ return $decoded_response;
120
+ } else {
121
+ return new WP_Error( $resp['response']['code'], 'Could not recognize the response from Twitter' );
122
+ }
123
+ }
124
+
125
+ /**
126
+ * parses the url and rebuilds it to be
127
+ * scheme://host/path
128
+ */
129
+ public function get_normalized_http_url( $url ) {
130
+ $parts = parse_url( $url );
131
+
132
+ $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
133
+ $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
134
+ $host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
135
+ $path = (isset($parts['path'])) ? $parts['path'] : '';
136
+
137
+ if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80'))
138
+ $host = "$host:$port";
139
+
140
+ return "$scheme://$host$path";
141
+ }
142
+
143
+ public function sign_request( &$parameters, $request_url, $method = 'GET' ) {
144
+ $parameters['oauth_signature_method'] = 'HMAC-SHA1';
145
+ $parameters['oauth_signature'] = $this->build_signature( $parameters, $request_url, $method );
146
+ }
147
+
148
+ /**
149
+ * The request parameters, sorted and concatenated into a normalized string.
150
+ * @return string
151
+ */
152
+ public function get_signable_parameters( $parameters ) {
153
+ // Remove oauth_signature if present
154
+ // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
155
+ if ( isset( $parameters['oauth_signature'] ) )
156
+ unset( $parameters['oauth_signature'] );
157
+
158
+ return OAuthUtil::build_http_query( $parameters );
159
+ }
160
+
161
+ public function build_signature( $parameters, $request_url, $method = 'GET' ) {
162
+ $parts = array(
163
+ $method,
164
+ $this->get_normalized_http_url( $request_url ),
165
+ $this->get_signable_parameters( $parameters )
166
+ );
167
+
168
+ $parts = OAuthUtil::urlencode_rfc3986($parts);
169
+
170
+ $base_string = implode('&', $parts);
171
+ $token_secret = '';
172
+
173
+ if ( ! empty( $this->_token['oauth_token_secret'] ) )
174
+ $token_secret = $this->_token['oauth_token_secret'];
175
+
176
+ $key_parts = array(
177
+ $this->_consumer_secret,
178
+ $token_secret,
179
+ );
180
+
181
+ $key_parts = OAuthUtil::urlencode_rfc3986( $key_parts );
182
+ $key = implode( '&', $key_parts );
183
+
184
+ return base64_encode( hash_hmac( 'sha1', $base_string, $key, true ) );
185
+ }
186
+
187
+ /**
188
+ * Exchange request token and secret for an access token and
189
+ * secret, to sign API calls.
190
+ *
191
+ * @returns array containing oauth_token,
192
+ * oauth_token_secret,
193
+ * user_id
194
+ * screen_name
195
+ */
196
+ function get_access_token( $oauth_verifier = false ) {
197
+ $parameters = array(
198
+ 'oauth_nonce' => md5( microtime() . mt_rand() ),
199
+ );
200
+ if ( ! empty( $oauth_verifier ) )
201
+ $parameters['oauth_verifier'] = $oauth_verifier;
202
+
203
+ $request_url = self::get_api_endpoint( 'oauth/access_token', '', '' );
204
+ $this->_token = $this->send_authed_request( $request_url, 'GET', $parameters );
205
+ return $this->_token;
206
+ }
207
+
208
+ public function set_token( $token ) {
209
+ $this->_token = $token;
210
+ }
211
+ }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: twitter, widget, feed
5
  Requires at least: 3.0
6
  Tested up to: 3.5
7
- Stable tag: 2.4.1
8
 
9
  A widget that properly handles twitter feeds, including parsing @username, #hashtags, and URLs into links.
10
 
@@ -130,6 +130,9 @@ Aparently the database queries required to display the friends feed was causing
130
 
131
  == Upgrade Notice ==
132
 
 
 
 
133
  = 2.4.1 =
134
  Better support for hashtags with international characters & new German translation
135
 
@@ -174,6 +177,11 @@ Fewer "could not connect to Twitter" messages, new links (reply, retweet, favori
174
 
175
  == Changelog ==
176
 
 
 
 
 
 
177
  = 2.4.1 =
178
  * Make sure hashtags are parsed UTF-8
179
  * Add German translation
4
  Tags: twitter, widget, feed
5
  Requires at least: 3.0
6
  Tested up to: 3.5
7
+ Stable tag: 2.5.0
8
 
9
  A widget that properly handles twitter feeds, including parsing @username, #hashtags, and URLs into links.
10
 
130
 
131
  == Upgrade Notice ==
132
 
133
+ = 2.5.0 =
134
+ Upgrade to the new Twitter API and add support for lists
135
+
136
  = 2.4.1 =
137
  Better support for hashtags with international characters & new German translation
138
 
177
 
178
  == Changelog ==
179
 
180
+ = 2.5.0 =
181
+ * Use the new Twitter API with oAuth
182
+ * Adds support for lists
183
+ * No longer supports non-https Twitter requests (Twitter API requirement)
184
+
185
  = 2.4.1 =
186
  * Make sure hashtags are parsed UTF-8
187
  * Add German translation
tlc-transients.php CHANGED
@@ -7,11 +7,15 @@ if ( !class_exists( 'TLC_Transient_Update_Server' ) ) {
7
  }
8
 
9
  public function init() {
10
- if ( isset( $_POST['_tlc_update'] ) ) {
11
- $update = get_transient( 'tlc_up__' . $_POST['key'] );
 
 
 
12
  if ( $update && $update[0] == $_POST['_tlc_update'] ) {
13
  tlc_transient( $update[1] )
14
  ->expires_in( $update[2] )
 
15
  ->updates_with( $update[3], (array) $update[4] )
16
  ->set_lock( $update[0] )
17
  ->fetch_and_cache();
@@ -20,25 +24,32 @@ if ( !class_exists( 'TLC_Transient_Update_Server' ) ) {
20
  }
21
  }
22
  }
23
- }
24
 
25
- new TLC_Transient_Update_Server;
 
26
 
27
  if ( !class_exists( 'TLC_Transient' ) ) {
28
  class TLC_Transient {
29
  public $key;
 
30
  private $lock;
31
  private $callback;
32
  private $params;
33
  private $expiration = 0;
 
34
  private $force_background_updates = false;
35
 
36
  public function __construct( $key ) {
37
- $this->key = substr( $key, 0, 37 );
 
 
 
 
 
38
  }
39
 
40
  public function get() {
41
- $data = get_transient( $this->key );
42
  if ( false === $data ) {
43
  // Hard expiration
44
  if ( $this->force_background_updates ) {
@@ -60,7 +71,7 @@ if ( !class_exists( 'TLC_Transient' ) ) {
60
 
61
  private function schedule_background_fetch() {
62
  if ( !$this->has_update_lock() ) {
63
- set_transient( 'tlc_up__' . $this->key, array( $this->new_update_lock(), $this->key, $this->expiration, $this->callback, $this->params ), 300 );
64
  add_action( 'shutdown', array( $this, 'spawn_server' ) );
65
  }
66
  return $this;
@@ -68,7 +79,7 @@ if ( !class_exists( 'TLC_Transient' ) ) {
68
 
69
  public function spawn_server() {
70
  $server_url = home_url( '/?tlc_transients_request' );
71
- wp_remote_post( $server_url, array( 'body' => array( '_tlc_update' => $this->lock, 'key' => $this->key ), 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) );
72
  }
73
 
74
  public function fetch_and_cache() {
@@ -81,7 +92,18 @@ if ( !class_exists( 'TLC_Transient' ) ) {
81
  $data = call_user_func_array( $this->callback, $this->params );
82
  $this->set( $data );
83
  } catch( Exception $e ) {
84
- $data = false;
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
  $this->release_update_lock();
87
  return $data;
@@ -89,9 +111,10 @@ if ( !class_exists( 'TLC_Transient' ) ) {
89
 
90
  public function set( $data ) {
91
  // We set the timeout as part of the transient data.
92
- // The actual transient has no TTL. This allows for soft expiration.
93
  $expiration = ( $this->expiration > 0 ) ? time() + $this->expiration : 0;
94
- set_transient( $this->key, array( $expiration, $data ) );
 
95
  return $this;
96
  }
97
 
@@ -103,7 +126,7 @@ if ( !class_exists( 'TLC_Transient' ) ) {
103
  }
104
 
105
  private function new_update_lock() {
106
- $this->lock = md5( uniqid( microtime() . mt_rand(), true ) );
107
  return $this->lock;
108
  }
109
 
@@ -132,6 +155,11 @@ if ( !class_exists( 'TLC_Transient' ) ) {
132
  return $this;
133
  }
134
 
 
 
 
 
 
135
  public function set_lock( $lock ) {
136
  $this->lock = $lock;
137
  return $this;
7
  }
8
 
9
  public function init() {
10
+ if ( isset( $_POST['_tlc_update'] )
11
+ && ( 0 === strpos( $_POST['_tlc_update'], 'tlc_lock_' ) )
12
+ && isset( $_POST['key'] )
13
+ ) {
14
+ $update = get_transient( 'tlc_up__' . md5( $_POST['key'] ) );
15
  if ( $update && $update[0] == $_POST['_tlc_update'] ) {
16
  tlc_transient( $update[1] )
17
  ->expires_in( $update[2] )
18
+ ->extend_on_fail( $update[5] )
19
  ->updates_with( $update[3], (array) $update[4] )
20
  ->set_lock( $update[0] )
21
  ->fetch_and_cache();
24
  }
25
  }
26
  }
 
27
 
28
+ new TLC_Transient_Update_Server;
29
+ }
30
 
31
  if ( !class_exists( 'TLC_Transient' ) ) {
32
  class TLC_Transient {
33
  public $key;
34
+ public $raw_key;
35
  private $lock;
36
  private $callback;
37
  private $params;
38
  private $expiration = 0;
39
+ private $extend_on_fail = 0;
40
  private $force_background_updates = false;
41
 
42
  public function __construct( $key ) {
43
+ $this->raw_key = $key;
44
+ $this->key = md5( $key );
45
+ }
46
+
47
+ private function raw_get() {
48
+ return get_transient( 'tlc__' . $this->key );
49
  }
50
 
51
  public function get() {
52
+ $data = $this->raw_get();
53
  if ( false === $data ) {
54
  // Hard expiration
55
  if ( $this->force_background_updates ) {
71
 
72
  private function schedule_background_fetch() {
73
  if ( !$this->has_update_lock() ) {
74
+ set_transient( 'tlc_up__' . $this->key, array( $this->new_update_lock(), $this->raw_key, $this->expiration, $this->callback, $this->params, $this->extend_on_fail ), 300 );
75
  add_action( 'shutdown', array( $this, 'spawn_server' ) );
76
  }
77
  return $this;
79
 
80
  public function spawn_server() {
81
  $server_url = home_url( '/?tlc_transients_request' );
82
+ wp_remote_post( $server_url, array( 'body' => array( '_tlc_update' => $this->lock, 'key' => $this->raw_key ), 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) );
83
  }
84
 
85
  public function fetch_and_cache() {
92
  $data = call_user_func_array( $this->callback, $this->params );
93
  $this->set( $data );
94
  } catch( Exception $e ) {
95
+ if ( $this->extend_on_fail > 0 ) {
96
+ $data = $this->raw_get();
97
+ if ( $data ) {
98
+ $data = $data[1];
99
+ $old_expiration = $this->expiration;
100
+ $this->expiration = $this->extend_on_fail;
101
+ $this->set( $data );
102
+ $this->expiration = $old_expiration;
103
+ }
104
+ } else {
105
+ $data = false;
106
+ }
107
  }
108
  $this->release_update_lock();
109
  return $data;
111
 
112
  public function set( $data ) {
113
  // We set the timeout as part of the transient data.
114
+ // The actual transient has a far-future TTL. This allows for soft expiration.
115
  $expiration = ( $this->expiration > 0 ) ? time() + $this->expiration : 0;
116
+ $transient_expiration = ( $this->expiration > 0 ) ? $this->expiration + 31536000 : 0; // 31536000 = 60*60*24*365 ~= one year
117
+ set_transient( 'tlc__' . $this->key, array( $expiration, $data ), $transient_expiration );
118
  return $this;
119
  }
120
 
126
  }
127
 
128
  private function new_update_lock() {
129
+ $this->lock = uniqid( 'tlc_lock_', true );
130
  return $this->lock;
131
  }
132
 
155
  return $this;
156
  }
157
 
158
+ public function extend_on_fail( $seconds ) {
159
+ $this->extend_on_fail = (int) $seconds;
160
+ return $this;
161
+ }
162
+
163
  public function set_lock( $lock ) {
164
  $this->lock = $lock;
165
  return $this;
wp-twitter-widget.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Twitter Widget Pro
4
  * Plugin URI: http://bluedogwebservices.com/wordpress-plugin/twitter-widget-pro/
5
  * Description: A widget that properly handles twitter feeds, including @username, #hashtag, and link parsing. It can even display profile images for the users. Requires PHP5.
6
- * Version: 2.4.1
7
  * Author: Aaron D. Campbell
8
  * Author URI: http://ran.ge/
9
  * License: GPLv2 or later
@@ -30,7 +30,7 @@
30
 
31
  require_once( 'tlc-transients.php' );
32
  require_once( 'range-plugin-framework.php' );
33
- define( 'TWP_VERSION', '2.4.0' );
34
 
35
  /**
36
  * WP_Widget_Twitter_Pro is the class that handles the main widget.
@@ -61,11 +61,59 @@ class WP_Widget_Twitter_Pro extends WP_Widget {
61
  public function form( $instance ) {
62
  $instance = $this->_getInstanceSettings( $instance );
63
  $wpTwitterWidget = wpTwitterWidget::getInstance();
 
 
 
64
  ?>
65
  <p>
66
  <label for="<?php echo $this->get_field_id( 'username' ); ?>"><?php _e( 'Twitter username:', $this->_slug ); ?></label>
67
- <input class="widefat" id="<?php echo $this->get_field_id( 'username' ); ?>" name="<?php echo $this->get_field_name( 'username' ); ?>" type="text" value="<?php esc_attr_e( $instance['username'] ); ?>" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  <p>
70
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Give the feed a title ( optional ):', $this->_slug ); ?></label>
71
  <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php esc_attr_e( $instance['title'] ); ?>" />
@@ -96,10 +144,12 @@ class WP_Widget_Twitter_Pro extends WP_Widget {
96
  <label for="<?php echo $this->get_field_id( 'showretweets' ); ?>"><?php _e( 'Include retweets', $this->_slug ); ?></label>
97
  </p>
98
  <p>
 
99
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'hidereplies' ); ?>" name="<?php echo $this->get_field_name( 'hidereplies' ); ?>"<?php checked( $instance['hidereplies'], 'true' ); ?> />
100
  <label for="<?php echo $this->get_field_id( 'hidereplies' ); ?>"><?php _e( 'Hide @replies', $this->_slug ); ?></label>
101
  </p>
102
  <p>
 
103
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'hidefrom' ); ?>" name="<?php echo $this->get_field_name( 'hidefrom' ); ?>"<?php checked( $instance['hidefrom'], 'true' ); ?> />
104
  <label for="<?php echo $this->get_field_id( 'hidefrom' ); ?>"><?php _e( 'Hide sending applications', $this->_slug ); ?></label>
105
  </p>
@@ -138,10 +188,12 @@ class WP_Widget_Twitter_Pro extends WP_Widget {
138
  <input class="widefat" id="<?php echo $this->get_field_id( 'dateFormat' ); ?>" name="<?php echo $this->get_field_name( 'dateFormat' ); ?>" type="text" value="<?php esc_attr_e( $instance['dateFormat'] ); ?>" />
139
  </p>
140
  <p>
 
141
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'targetBlank' ); ?>" name="<?php echo $this->get_field_name( 'targetBlank' ); ?>"<?php checked( $instance['targetBlank'], 'true' ); ?> />
142
  <label for="<?php echo $this->get_field_id( 'targetBlank' ); ?>"><?php _e( 'Open links in a new window', $this->_slug ); ?></label>
143
  </p>
144
  <p>
 
145
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'showXavisysLink' ); ?>" name="<?php echo $this->get_field_name( 'showXavisysLink' ); ?>"<?php checked( $instance['showXavisysLink'], 'true' ); ?> />
146
  <label for="<?php echo $this->get_field_id( 'showXavisysLink' ); ?>"><?php _e( 'Show Link to Twitter Widget Pro', $this->_slug ); ?></label>
147
  </p>
@@ -184,7 +236,10 @@ class WP_Widget_Twitter_Pro extends WP_Widget {
184
  * It also helps us avoid name collisions.
185
  */
186
  class wpTwitterWidget extends RangePlugin {
187
- private $_api_url;
 
 
 
188
 
189
  /**
190
  * @var wpTwitterWidget - Static property to hold our singleton instance
@@ -192,6 +247,8 @@ class wpTwitterWidget extends RangePlugin {
192
  static $instance = false;
193
 
194
  protected function _init() {
 
 
195
  $this->_hook = 'twitterWidgetPro';
196
  $this->_file = plugin_basename( __FILE__ );
197
  $this->_pageTitle = __( 'Twitter Widget Pro', $this->_slug );
@@ -214,6 +271,7 @@ class wpTwitterWidget extends RangePlugin {
214
  add_filter( 'widget_twitter_content', array( $this, 'linkHashtags' ) );
215
  add_filter( 'widget_twitter_content', 'convert_chars' );
216
  add_filter( $this->_slug .'-opt-twp', array( $this, 'filterSettings' ) );
 
217
  add_shortcode( 'twitter-widget', array( $this, 'handleShortcodes' ) );
218
 
219
  $twp_version = get_option( 'twp_version' );
@@ -222,9 +280,14 @@ class wpTwitterWidget extends RangePlugin {
222
  }
223
 
224
  protected function _post_settings_init() {
225
- if ( ! in_array( $this->_settings['twp']['http_vs_https'], array( 'http', 'https' ) ) )
226
- $this->_settings['twp']['http_vs_https'] = 'https';
227
- $this->_api_url = $this->_settings['twp']['http_vs_https'] . '://api.twitter.com/1/';
 
 
 
 
 
228
  }
229
 
230
  /**
@@ -254,84 +317,217 @@ class wpTwitterWidget extends RangePlugin {
254
  wp_safe_redirect( add_query_arg( $redirect_args, remove_query_arg( array( 'action', '_wpnonce' ) ) ) );
255
  exit;
256
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  }
258
 
259
  public function show_messages() {
260
- if ( ! empty( $_GET['message'] ) && 'clear-locks' == $_GET['message'] ) {
261
- if ( empty( $_GET['locks_cleared'] ) || 0 == $_GET['locks_cleared'] )
262
- $msg = __( 'There were no locks to clear!', $this->_slug );
263
- else
264
- $msg = sprintf( _n( 'Successfully cleared %d lock.', 'Successfully cleared %d locks.', $_GET['locks_cleared'], $this->_slug ), $_GET['locks_cleared'] );
265
- echo "<div class='updated'>" . esc_html( $msg ) . '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  }
267
  }
268
 
269
  public function add_options_meta_boxes() {
 
270
  add_meta_box( $this->_slug . '-general-settings', __( 'General Settings', $this->_slug ), array( $this, 'general_settings_meta_box' ), 'range-' . $this->_slug, 'main' );
271
  add_meta_box( $this->_slug . '-defaults', __( 'Default Settings for Shortcodes', $this->_slug ), array( $this, 'default_settings_meta_box' ), 'range-' . $this->_slug, 'main' );
272
  }
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  public function general_settings_meta_box() {
275
  $clear_locks_url = wp_nonce_url( add_query_arg( array( 'action' => 'clear-locks' ) ), 'clear-locks' );
276
  ?>
277
  <table class="form-table">
278
  <tr valign="top">
279
  <th scope="row">
280
- <?php _e( "HTTP vs HTTPS", $this->_slug );?>
281
  </th>
282
  <td>
283
- <input class="checkbox" type="radio" value="https" id="twp_http_vs_https_https" name="twp[http_vs_https]"<?php checked( $this->_settings['twp']['http_vs_https'], 'https' ); ?> />
284
- <label for="twp_http_vs_https_https"><?php _e( 'Use Twitter API via HTTPS', $this->_slug ); ?></label>
285
- <br />
286
- <input class="checkbox" type="radio" value="http" id="twp_http_vs_https_http" name="twp[http_vs_https]"<?php checked( $this->_settings['twp']['http_vs_https'], 'http' ); ?> />
287
- <label for="twp_http_vs_https_http"><?php _e( 'Use Twitter API via HTTP', $this->_slug ); ?></label>
288
- <br />
289
- <small><?php _e( "Some servers seem to have issues connecting via HTTPS. If you're experiencing issues with your feed not updating, try setting this to HTTP.", $this->_slug ); ?></small>
290
  </td>
291
  </tr>
292
- <tr>
293
  <th scope="row">
294
- <?php _e( "Clear Update Locks", $this->_slug );?>
295
  </th>
296
  <td>
297
- <a href="<?php echo esc_url( $clear_locks_url ); ?>"><?php _e( 'Clear Update Locks', $this->_slug ); ?></a><br />
298
- <small><?php _e( "A small percentage of servers seem to have issues where an update lock isn't getting cleared. If you're experiencing issues with your feed not updating, try clearing the update locks.", $this->_slug ); ?></small>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  </td>
300
  </tr>
 
 
 
301
  <tr>
302
  <th scope="row">
303
- <?php _e( 'Current API Usage', $this->_slug );?>
304
  </th>
305
  <td>
306
- <?php
307
- $limit_url = $this->_api_url . "account/rate_limit_status.json";
308
- $resp = wp_remote_request( $limit_url );
309
-
310
- if ( !is_wp_error( $resp ) && $resp['response']['code'] >= 200 && $resp['response']['code'] < 300 ) {
311
- $decodedResponse = json_decode( $resp['body'] );
312
- ?>
313
- <p>
314
- <?php echo sprintf( __( 'Used: %d', $this->_slug ), $decodedResponse->hourly_limit - $decodedResponse->remaining_hits ); ?><br />
315
- <?php echo sprintf( __( 'Remaining: %d', $this->_slug ), $decodedResponse->remaining_hits ); ?><br />
316
- <?php
317
- $minutes = ceil( ( $decodedResponse->reset_time_in_seconds - gmdate( 'U' ) ) / 60 );
318
- echo sprintf( _n( 'Limits reset in: %d minutes', 'Limits reset in: %d minutes', $minutes, $this->_slug ), $minutes );
319
- ?><br />
320
- <small><?php _e( 'This is overall usage, not just usage from Twitter Widget Pro', $this->_slug ); ?></small>
321
- </p>
322
- <?php
323
- } else {
324
- ?>
325
- <p><?php _e( 'There was an error checking your rate limit.', $this->_slug ); ?></p>
326
- <?php
327
- }
328
- ?>
329
  </td>
330
  </tr>
331
  </table>
332
  <?php
333
  }
334
  public function default_settings_meta_box() {
 
 
335
  ?>
336
  <p><?php _e( 'These settings are the default for the shortcodes and all of them can be overridden by specifying a different value in the shortcode itself. All settings for widgets are locate in the individual widget.', $this->_slug ) ?></p>
337
  <table class="form-table">
@@ -340,7 +536,56 @@ class wpTwitterWidget extends RangePlugin {
340
  <label for="twp_username"><?php _e( 'Twitter username:', $this->_slug ); ?></label>
341
  </th>
342
  <td>
343
- <input id="twp_username" name="twp[username]" type="text" class="regular-text code" value="<?php esc_attr_e( $this->_settings['twp']['username'] ); ?>" size="40" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  </td>
345
  </tr>
346
  <tr valign="top">
@@ -428,9 +673,11 @@ class wpTwitterWidget extends RangePlugin {
428
  <input class="checkbox" type="checkbox" value="true" id="twp_showretweets" name="twp[showretweets]"<?php checked( $this->_settings['twp']['showretweets'], 'true' ); ?> />
429
  <label for="twp_showretweets"><?php _e( 'Include retweets', $this->_slug ); ?></label>
430
  <br />
 
431
  <input class="checkbox" type="checkbox" value="true" id="twp_hidereplies" name="twp[hidereplies]"<?php checked( $this->_settings['twp']['hidereplies'], 'true' ); ?> />
432
  <label for="twp_hidereplies"><?php _e( 'Hide @replies', $this->_slug ); ?></label>
433
  <br />
 
434
  <input class="checkbox" type="checkbox" value="true" id="twp_hidefrom" name="twp[hidefrom]"<?php checked( $this->_settings['twp']['hidefrom'], 'true' ); ?> />
435
  <label for="twp_hidefrom"><?php _e( 'Hide sending applications', $this->_slug ); ?></label>
436
  <br />
@@ -442,9 +689,11 @@ class wpTwitterWidget extends RangePlugin {
442
  <input class="checkbox" type="checkbox" value="true" id="twp_showfollow" name="twp[showfollow]"<?php checked( $this->_settings['twp']['showfollow'], 'true' ); ?> />
443
  <label for="twp_showfollow"><?php _e( 'Show Follow Link', $this->_slug ); ?></label>
444
  <br />
 
445
  <input class="checkbox" type="checkbox" value="true" id="twp_targetBlank" name="twp[targetBlank]"<?php checked( $this->_settings['twp']['targetBlank'], 'true' ); ?> />
446
  <label for="twp_targetBlank"><?php _e( 'Open links in a new window', $this->_slug ); ?></label>
447
  <br />
 
448
  <input class="checkbox" type="checkbox" value="true" id="twp_showXavisysLink" name="twp[showXavisysLink]"<?php checked( $this->_settings['twp']['showXavisysLink'], 'true' ); ?> />
449
  <label for="twp_showXavisysLink"><?php _e( 'Show Link to Twitter Widget Pro', $this->_slug ); ?></label>
450
  </td>
@@ -622,7 +871,7 @@ class wpTwitterWidget extends RangePlugin {
622
  $widgetContent = $args['before_widget'] . '<div>';
623
 
624
  if ( empty( $args['title'] ) )
625
- $args['title'] = "Twitter: {$args['username']}";
626
 
627
  $args['title'] = apply_filters( 'twitter-widget-title', $args['title'], $args );
628
  $args['title'] = "<span class='twitterwidget twitterwidget-title'>{$args['title']}</span>";
@@ -700,7 +949,7 @@ class wpTwitterWidget extends RangePlugin {
700
  }
701
 
702
  $widgetContent .= '</ul>';
703
- if ( 'true' == $args['showfollow'] ) {
704
  $widgetContent .= '<div class="follow-button">';
705
  $linkText = "@{$args['username']}";
706
  $linkAttrs = array(
@@ -770,9 +1019,10 @@ class wpTwitterWidget extends RangePlugin {
770
  * @return array - Array of objects
771
  */
772
  private function _getTweets( $widgetOptions ) {
773
- $key = 'twp_' . md5( $this->_getFeedUrl( $widgetOptions ) );
774
  return tlc_transient( $key )
775
  ->expires_in( 300 ) // cache for 5 minutes
 
776
  ->updates_with( array( $this, 'parseFeed' ), array( $widgetOptions ) )
777
  ->get();
778
  }
@@ -784,43 +1034,41 @@ class wpTwitterWidget extends RangePlugin {
784
  * @return array
785
  */
786
  public function parseFeed( $widgetOptions ) {
787
- $feedUrl = $this->_getFeedUrl( $widgetOptions );
788
- $resp = wp_remote_request( $feedUrl, array( 'timeout' => $widgetOptions['fetchTimeOut'] ) );
789
 
790
- if ( !is_wp_error( $resp ) && $resp['response']['code'] >= 200 && $resp['response']['code'] < 300 ) {
791
- $decodedResponse = json_decode( $resp['body'] );
792
- if ( empty( $decodedResponse ) || ! is_array( $decodedResponse ) ) {
793
  if ( empty( $widgetOptions['errmsg'] ) )
794
- $widgetOptions['errmsg'] = __( 'Invalid Twitter Response.', $this->_slug );
795
- } elseif( !empty( $decodedResponse->error ) ) {
796
- if ( empty( $widgetOptions['errmsg'] ) )
797
- $widgetOptions['errmsg'] = $decodedResponse->error;
798
  } else {
799
- return $decodedResponse;
 
 
 
800
  }
801
- } else {
802
- // Failed to fetch url;
803
- if ( empty( $widgetOptions['errmsg'] ) )
804
- $widgetOptions['errmsg'] = __( 'Could not connect to Twitter', $this->_slug );
 
 
 
805
  }
806
- do_action( 'widget_twitter_parsefeed_error', $resp, $feedUrl, $widgetOptions );
 
 
 
807
  throw new Exception( $widgetOptions['errmsg'] );
808
  }
809
 
810
  /**
811
- * Gets the URL for the desired feed.
812
  *
813
  * @param array $widgetOptions - settings needed such as username, feet type, etc
814
- * @param string[optional] $type - 'rss' or 'json'
815
- * @param bool[optional] $count - If true, it adds the count parameter to the URL
816
- * @return string - Twitter feed URL
817
  */
818
- private function _getFeedUrl( $widgetOptions, $type = 'json', $count = true ) {
819
- if ( !in_array( $type, array( 'rss', 'json' ) ) )
820
- $type = 'json';
821
-
822
- $req = $this->_api_url . "statuses/user_timeline.{$type}";
823
-
824
  /**
825
  * user_id
826
  * screen_name *
@@ -835,17 +1083,23 @@ class wpTwitterWidget extends RangePlugin {
835
  * contributor_details
836
  */
837
 
838
- $req = add_query_arg( array( 'screen_name' => $widgetOptions['username'] ), $req );
839
- if ( $count )
840
- $req = add_query_arg( array( 'count' => $widgetOptions['items'] ), $req );
 
 
 
 
 
841
 
842
  if ( 'true' == $widgetOptions['hidereplies'] )
843
- $req = add_query_arg( array( 'exclude_replies' => 'true' ), $req );
844
 
845
  if ( 'true' == $widgetOptions['showretweets'] )
846
- $req = add_query_arg( array( 'include_rts' => 'true' ), $req );
 
 
847
 
848
- return $req;
849
  }
850
 
851
  /**
@@ -907,9 +1161,8 @@ class wpTwitterWidget extends RangePlugin {
907
  'href' => "http://twitter.com/{$user->screen_name}",
908
  'title' => $user->name
909
  );
910
- $img = $this->_api_url . 'users/profile_image';
911
- $img = add_query_arg( array( 'screen_name' => $user->screen_name ), $img );
912
- $img = add_query_arg( array( 'size' => $args['avatar'] ), $img );
913
 
914
  return $this->_buildLink( "<img alt='{$user->name}' src='{$img}' />", $linkAttrs, true );
915
  }
@@ -998,12 +1251,21 @@ class wpTwitterWidget extends RangePlugin {
998
  return $this->display( $attr );
999
  }
1000
 
 
 
 
 
 
 
1001
  public function filterSettings( $settings ) {
1002
  $defaultArgs = array(
 
 
1003
  'title' => '',
1004
  'errmsg' => '',
1005
  'fetchTimeOut' => '2',
1006
  'username' => '',
 
1007
  'http_vs_https' => 'https',
1008
  'hidereplies' => 'false',
1009
  'showretweets' => 'true',
@@ -1037,6 +1299,40 @@ class wpTwitterWidget extends RangePlugin {
1037
  public function getSettings( $settings ) {
1038
  return $this->fixAvatar( wp_parse_args( $settings, $this->_settings['twp'] ) );
1039
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1040
  }
1041
  // Instantiate our class
1042
  $wpTwitterWidget = wpTwitterWidget::getInstance();
3
  * Plugin Name: Twitter Widget Pro
4
  * Plugin URI: http://bluedogwebservices.com/wordpress-plugin/twitter-widget-pro/
5
  * Description: A widget that properly handles twitter feeds, including @username, #hashtag, and link parsing. It can even display profile images for the users. Requires PHP5.
6
+ * Version: 2.5.0
7
  * Author: Aaron D. Campbell
8
  * Author URI: http://ran.ge/
9
  * License: GPLv2 or later
30
 
31
  require_once( 'tlc-transients.php' );
32
  require_once( 'range-plugin-framework.php' );
33
+ define( 'TWP_VERSION', '2.5.0' );
34
 
35
  /**
36
  * WP_Widget_Twitter_Pro is the class that handles the main widget.
61
  public function form( $instance ) {
62
  $instance = $this->_getInstanceSettings( $instance );
63
  $wpTwitterWidget = wpTwitterWidget::getInstance();
64
+ $users = $wpTwitterWidget->get_users_list( true );
65
+ $lists = $wpTwitterWidget->get_lists();
66
+
67
  ?>
68
  <p>
69
  <label for="<?php echo $this->get_field_id( 'username' ); ?>"><?php _e( 'Twitter username:', $this->_slug ); ?></label>
70
+ <select id="<?php echo $this->get_field_id( 'username' ); ?>" name="<?php echo $this->get_field_name( 'username' ); ?>">
71
+ <option></option>
72
+ <?php
73
+ $selected = false;
74
+ foreach ( $users as $u ) {
75
+ ?>
76
+ <option value="<?php echo esc_attr( strtolower( $u['screen_name'] ) ); ?>"<?php $s = selected( strtolower( $u['screen_name'] ), strtolower( $instance['username'] ) ) ?>><?php echo esc_html( $u['screen_name'] ); ?></option>
77
+ <?php
78
+ if ( ! empty( $s ) )
79
+ $selected = true;
80
+ }
81
+ ?>
82
+ </select>
83
+ </p>
84
+ <p>
85
+ <label for="<?php echo $this->get_field_id( 'list' ); ?>"><?php _e( 'Twitter list:', $this->_slug ); ?></label>
86
+ <select id="<?php echo $this->get_field_id( 'list' ); ?>" name="<?php echo $this->get_field_name( 'list' ); ?>">
87
+ <option></option>
88
+ <?php
89
+ foreach ( $lists as $user => $user_lists ) {
90
+ echo '<optgroup label="' . esc_attr( $user ) . '">';
91
+ foreach ( $user_lists as $list_id => $list_name ) {
92
+ ?>
93
+ <option value="<?php echo esc_attr( $user . '::' . $list_id ); ?>"<?php $s = selected( $user . '::' . $list_id, strtolower( $instance['list'] ) ) ?>><?php echo esc_html( $list_name ); ?></option>
94
+ <?php
95
+ }
96
+ echo '</optgroup>';
97
+ }
98
+ ?>
99
+ </select>
100
  </p>
101
+ <?php
102
+ if ( ! $selected && ! empty( $instance['username'] ) ) {
103
+ $query_args = array(
104
+ 'action' => 'authorize',
105
+ 'screen_name' => $instance['username'],
106
+ );
107
+ $authorize_user_url = wp_nonce_url( add_query_arg( $query_args, $wpTwitterWidget->get_options_url() ), 'authorize' );
108
+ ?>
109
+ <p>
110
+ <a href="<?php echo esc_url( $authorize_user_url ); ?>" style="color:red;">
111
+ <?php _e( 'You need to authorize this account.', $this->_slug ); ?>
112
+ </a>
113
+ </p>
114
+ <?php
115
+ }
116
+ ?>
117
  <p>
118
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Give the feed a title ( optional ):', $this->_slug ); ?></label>
119
  <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php esc_attr_e( $instance['title'] ); ?>" />
144
  <label for="<?php echo $this->get_field_id( 'showretweets' ); ?>"><?php _e( 'Include retweets', $this->_slug ); ?></label>
145
  </p>
146
  <p>
147
+ <input type="hidden" value="false" name="<?php echo $this->get_field_name( 'hidereplies' ); ?>" />
148
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'hidereplies' ); ?>" name="<?php echo $this->get_field_name( 'hidereplies' ); ?>"<?php checked( $instance['hidereplies'], 'true' ); ?> />
149
  <label for="<?php echo $this->get_field_id( 'hidereplies' ); ?>"><?php _e( 'Hide @replies', $this->_slug ); ?></label>
150
  </p>
151
  <p>
152
+ <input type="hidden" value="false" name="<?php echo $this->get_field_name( 'hidefrom' ); ?>" />
153
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'hidefrom' ); ?>" name="<?php echo $this->get_field_name( 'hidefrom' ); ?>"<?php checked( $instance['hidefrom'], 'true' ); ?> />
154
  <label for="<?php echo $this->get_field_id( 'hidefrom' ); ?>"><?php _e( 'Hide sending applications', $this->_slug ); ?></label>
155
  </p>
188
  <input class="widefat" id="<?php echo $this->get_field_id( 'dateFormat' ); ?>" name="<?php echo $this->get_field_name( 'dateFormat' ); ?>" type="text" value="<?php esc_attr_e( $instance['dateFormat'] ); ?>" />
189
  </p>
190
  <p>
191
+ <input type="hidden" value="false" name="<?php echo $this->get_field_name( 'targetBlank' ); ?>" />
192
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'targetBlank' ); ?>" name="<?php echo $this->get_field_name( 'targetBlank' ); ?>"<?php checked( $instance['targetBlank'], 'true' ); ?> />
193
  <label for="<?php echo $this->get_field_id( 'targetBlank' ); ?>"><?php _e( 'Open links in a new window', $this->_slug ); ?></label>
194
  </p>
195
  <p>
196
+ <input type="hidden" value="false" name="<?php echo $this->get_field_name( 'showXavisysLink' ); ?>" />
197
  <input class="checkbox" type="checkbox" value="true" id="<?php echo $this->get_field_id( 'showXavisysLink' ); ?>" name="<?php echo $this->get_field_name( 'showXavisysLink' ); ?>"<?php checked( $instance['showXavisysLink'], 'true' ); ?> />
198
  <label for="<?php echo $this->get_field_id( 'showXavisysLink' ); ?>"><?php _e( 'Show Link to Twitter Widget Pro', $this->_slug ); ?></label>
199
  </p>
236
  * It also helps us avoid name collisions.
237
  */
238
  class wpTwitterWidget extends RangePlugin {
239
+ /**
240
+ * @var wpTwitter
241
+ */
242
+ private $_wp_twitter_oauth;
243
 
244
  /**
245
  * @var wpTwitterWidget - Static property to hold our singleton instance
247
  static $instance = false;
248
 
249
  protected function _init() {
250
+ require_once( 'lib/wp-twitter.php' );
251
+
252
  $this->_hook = 'twitterWidgetPro';
253
  $this->_file = plugin_basename( __FILE__ );
254
  $this->_pageTitle = __( 'Twitter Widget Pro', $this->_slug );
271
  add_filter( 'widget_twitter_content', array( $this, 'linkHashtags' ) );
272
  add_filter( 'widget_twitter_content', 'convert_chars' );
273
  add_filter( $this->_slug .'-opt-twp', array( $this, 'filterSettings' ) );
274
+ add_filter( $this->_slug .'-opt-twp-authed-users', array( $this, 'authed_users_option' ) );
275
  add_shortcode( 'twitter-widget', array( $this, 'handleShortcodes' ) );
276
 
277
  $twp_version = get_option( 'twp_version' );
280
  }
281
 
282
  protected function _post_settings_init() {
283
+ $oauth_settings = array(
284
+ 'consumer-key' => $this->_settings['twp']['consumer-key'],
285
+ 'consumer-secret' => $this->_settings['twp']['consumer-secret'],
286
+ );
287
+ $this->_wp_twitter_oauth = new wpTwitter( $oauth_settings );
288
+
289
+ // We want to fill 'twp-authed-users' but not overwrite them when saving
290
+ $this->_settings['twp-authed-users'] = apply_filters($this->_slug.'-opt-twp-authed-users', get_option('twp-authed-users'));
291
  }
292
 
293
  /**
317
  wp_safe_redirect( add_query_arg( $redirect_args, remove_query_arg( array( 'action', '_wpnonce' ) ) ) );
318
  exit;
319
  }
320
+
321
+ if ( 'authorize' == $_GET['action'] ) {
322
+ check_admin_referer( 'authorize' );
323
+ $auth_redirect = add_query_arg( array( 'action' => 'authorized' ), $this->get_options_url() );
324
+ $token = $this->_wp_twitter_oauth->getRequestToken( $auth_redirect );
325
+ if ( is_wp_error( $token ) )
326
+ return;
327
+ update_option( '_twp_request_token_'.$token['nonce'], $token );
328
+ $screen_name = empty( $_GET['screen_name'] )? '':$_GET['screen_name'];
329
+ wp_redirect( $this->_wp_twitter_oauth->get_authorize_url( $screen_name ) );
330
+ exit;
331
+ }
332
+ if ( 'authorized' == $_GET['action'] ) {
333
+ $redirect_args = array(
334
+ 'message' => strtolower( $_GET['action'] ),
335
+ 'authorized' => '',
336
+ );
337
+ if ( empty( $_GET['oauth_verifier'] ) || empty( $_GET['nonce'] ) )
338
+ wp_safe_redirect( add_query_arg( $redirect_args, $this->get_options_url() ) );
339
+
340
+ $this->_wp_twitter_oauth->set_token( get_option( '_twp_request_token_'.$_GET['nonce'] ) );
341
+ delete_option( '_twp_request_token_'.$_GET['nonce'] );
342
+
343
+ $token = $this->_wp_twitter_oauth->get_access_token( $_GET['oauth_verifier'] );
344
+ $this->_settings['twp-authed-users'][strtolower($token['screen_name'])] = $token;
345
+ update_option( 'twp-authed-users', $this->_settings['twp-authed-users'] );
346
+
347
+ $redirect_args['authorized'] = $token['screen_name'];
348
+ wp_safe_redirect( add_query_arg( $redirect_args, $this->get_options_url() ) );
349
+ exit;
350
+ }
351
  }
352
 
353
  public function show_messages() {
354
+ if ( ! empty( $_GET['message'] ) ) {
355
+ if ( 'clear-locks' == $_GET['message'] ) {
356
+ if ( empty( $_GET['locks_cleared'] ) || 0 == $_GET['locks_cleared'] )
357
+ $msg = __( 'There were no locks to clear!', $this->_slug );
358
+ else
359
+ $msg = sprintf( _n( 'Successfully cleared %d lock.', 'Successfully cleared %d locks.', $_GET['locks_cleared'], $this->_slug ), $_GET['locks_cleared'] );
360
+ } elseif ( 'authorized' == $_GET['message'] ) {
361
+ if ( ! empty( $_GET['authorized'] ) )
362
+ $msg = sprintf( __( 'Successfully authorized @%s', $this->_slug ), $_GET['authorized'] );
363
+ else
364
+ $msg = __( 'There was a problem authorizing your account.', $this->_slug );
365
+ }
366
+ echo "<div class='updated'><p>" . esc_html( $msg ) . '</p></div>';
367
+ }
368
+
369
+ if ( empty( $this->_settings['twp']['consumer-key'] ) || empty( $this->_settings['twp']['consumer-secret'] ) ) {
370
+ $msg = sprintf( __( 'You need to <a href="%s">set up your Twitter app keys</a>.', $this->_slug ), $this->get_options_url() );
371
+ echo '<div class="error"><p>' . $msg . '</p></div>';
372
+ }
373
+
374
+ if ( empty( $this->_settings['twp-authed-users'] ) ) {
375
+ $msg = sprintf( __( 'You need to <a href="%s">authorize your Twitter accounts</a>.', $this->_slug ), $this->get_options_url() );
376
+ echo '<div class="error"><p>' . $msg . '</p></div>';
377
  }
378
  }
379
 
380
  public function add_options_meta_boxes() {
381
+ add_meta_box( $this->_slug . '-oauth', __( 'Authenticated Twitter Accounts', $this->_slug ), array( $this, 'oauth_meta_box' ), 'range-' . $this->_slug, 'main' );
382
  add_meta_box( $this->_slug . '-general-settings', __( 'General Settings', $this->_slug ), array( $this, 'general_settings_meta_box' ), 'range-' . $this->_slug, 'main' );
383
  add_meta_box( $this->_slug . '-defaults', __( 'Default Settings for Shortcodes', $this->_slug ), array( $this, 'default_settings_meta_box' ), 'range-' . $this->_slug, 'main' );
384
  }
385
 
386
+ public function oauth_meta_box() {
387
+ $authorize_url = wp_nonce_url( add_query_arg( array( 'action' => 'authorize' ) ), 'authorize' );
388
+
389
+ ?>
390
+ <table class="widefat">
391
+ <thead>
392
+ <tr valign="top">
393
+ <th scope="row">
394
+ <?php _e( 'Username', $this->_slug );?>
395
+ </th>
396
+ <th scope="row">
397
+ <?php _e( 'Lists Rate Usage', $this->_slug );?>
398
+ </th>
399
+ <th scope="row">
400
+ <?php _e( 'Statuses Rate Usage', $this->_slug );?>
401
+ </th>
402
+ </tr>
403
+ </thead>
404
+ <?php
405
+ foreach ( $this->_settings['twp-authed-users'] as $u ) {
406
+ $this->_wp_twitter_oauth->set_token( $u );
407
+ $user_info = $this->_wp_twitter_oauth->send_authed_request( 'account/verify_credentials', 'GET' );
408
+ $style = $auth_link = '';
409
+ if ( is_wp_error( $user_info ) ) {
410
+ $query_args = array(
411
+ 'action' => 'authorize',
412
+ 'screen_name' => $u['screen_name'],
413
+ );
414
+ $authorize_user_url = wp_nonce_url( add_query_arg( $query_args ), 'authorize' );
415
+ $style = 'color:red;';
416
+ $auth_link = ' - <a href="' . esc_url( $authorize_user_url ) . '">' . __( 'Reauthorize', $this->_slug ) . '</a>';
417
+ }
418
+ ?>
419
+ <tr valign="top">
420
+ <th scope="row" style="<?php echo esc_attr( $style ); ?>">
421
+ <strong>@<?php echo esc_html( $u['screen_name'] ) . $auth_link; ?></strong>
422
+ </th>
423
+ <?php
424
+ $rates = $this->_wp_twitter_oauth->send_authed_request( 'application/rate_limit_status', 'GET', array( 'resources' => 'statuses,lists' ) );
425
+ if ( ! is_wp_error( $rates ) ) {
426
+ $display_rates = array(
427
+ __( 'Lists', $this->_slug ) => $rates->resources->lists->{'/lists/statuses'},
428
+ __( 'Statuses', $this->_slug ) => $rates->resources->statuses->{'/statuses/user_timeline'},
429
+ );
430
+ foreach ( $display_rates as $title => $rate ) {
431
+ ?>
432
+ <td>
433
+ <strong><?php echo esc_html( $title ); ?></strong>
434
+ <p>
435
+ <?php echo sprintf( __( 'Used: %d', $this->_slug ), $rate->limit - $rate->remaining ); ?><br />
436
+ <?php echo sprintf( __( 'Remaining: %d', $this->_slug ), $rate->remaining ); ?><br />
437
+ <?php
438
+ $minutes = ceil( ( $rate->reset - gmdate( 'U' ) ) / 60 );
439
+ echo sprintf( _n( 'Limits reset in: %d minutes', 'Limits reset in: %d minutes', $minutes, $this->_slug ), $minutes );
440
+ ?><br />
441
+ <small><?php _e( 'This is overall usage, not just usage from Twitter Widget Pro', $this->_slug ); ?></small>
442
+ </p>
443
+ </td>
444
+ <?php
445
+ }
446
+ } else {
447
+ ?>
448
+ <td>
449
+ <p><?php _e( 'There was an error checking your rate limit.', $this->_slug ); ?></p>
450
+ </td>
451
+ <td>
452
+ <p><?php _e( 'There was an error checking your rate limit.', $this->_slug ); ?></p>
453
+ </td>
454
+ <?php
455
+ }
456
+ ?>
457
+ </tr>
458
+ <?php
459
+ }
460
+ ?>
461
+ </table>
462
+ <?php
463
+ if ( empty( $this->_settings['twp']['consumer-key'] ) || empty( $this->_settings['twp']['consumer-secret'] ) ) {
464
+ ?>
465
+ <p>
466
+ <strong><?php _e( 'You need to fill in the Consumer key and Consumer secret before you can authorize accounts.', $this->_slug ) ?></strong>
467
+ </p>
468
+ <?php
469
+ } else {
470
+ ?>
471
+ <p>
472
+ <a href="<?php echo esc_url( $authorize_url );?>" class="button button-large button-primary"><?php _e( 'Authorize New Account', $this->_slug ); ?></a>
473
+ </p>
474
+ <?php
475
+ }
476
+ }
477
  public function general_settings_meta_box() {
478
  $clear_locks_url = wp_nonce_url( add_query_arg( array( 'action' => 'clear-locks' ) ), 'clear-locks' );
479
  ?>
480
  <table class="form-table">
481
  <tr valign="top">
482
  <th scope="row">
483
+ <label for="twp_consumer_key"><?php _e( 'Consumer key', $this->_slug );?></label>
484
  </th>
485
  <td>
486
+ <input id="twp_consumer_key" name="twp[consumer-key]" type="text" class="regular-text code" value="<?php esc_attr_e( $this->_settings['twp']['consumer-key'] ); ?>" size="40" />
 
 
 
 
 
 
487
  </td>
488
  </tr>
489
+ <tr valign="top">
490
  <th scope="row">
491
+ <label for="twp_consumer_secret"><?php _e( 'Consumer secret', $this->_slug );?></label>
492
  </th>
493
  <td>
494
+ <input id="twp_consumer_secret" name="twp[consumer-secret]" type="text" class="regular-text code" value="<?php esc_attr_e( $this->_settings['twp']['consumer-secret'] ); ?>" size="40" />
495
+ </td>
496
+ </tr>
497
+ <?php
498
+ if ( empty( $this->_settings['twp']['consumer-key'] ) || empty( $this->_settings['twp']['consumer-secret'] ) ) {
499
+ ?>
500
+ <tr valign="top">
501
+ <th scope="row">&nbsp;</th>
502
+ <td>
503
+ <strong><?php _e( 'Directions to get the Consumer Key and Consumer Secret', $this->_slug ) ?></strong>
504
+ <ol>
505
+ <li><a href="https://dev.twitter.com/apps/new"><?php _e( 'Add a new Twitter application', $this->_slug ) ?></a></li>
506
+ <li><?php _e( "Fill in Name, Description, Website, and Callback URL (don't leave any blank) with anything you want" ) ?></a></li>
507
+ <li><?php _e( "Agree to rules, fill out captcha, and submit your application" ) ?></a></li>
508
+ <li><?php _e( "Copy the Consumer key and Consumer secret into the fields above" ) ?></a></li>
509
+ <li><?php _e( "Click the Update Options button at the bottom of this page" ) ?></a></li>
510
+ </ol>
511
  </td>
512
  </tr>
513
+ <?php
514
+ }
515
+ ?>
516
  <tr>
517
  <th scope="row">
518
+ <?php _e( "Clear Update Locks", $this->_slug );?>
519
  </th>
520
  <td>
521
+ <a href="<?php echo esc_url( $clear_locks_url ); ?>"><?php _e( 'Clear Update Locks', $this->_slug ); ?></a><br />
522
+ <small><?php _e( "A small percentage of servers seem to have issues where an update lock isn't getting cleared. If you're experiencing issues with your feed not updating, try clearing the update locks.", $this->_slug ); ?></small>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523
  </td>
524
  </tr>
525
  </table>
526
  <?php
527
  }
528
  public function default_settings_meta_box() {
529
+ $users = $this->get_users_list( true );
530
+ $lists = $this->get_lists();
531
  ?>
532
  <p><?php _e( 'These settings are the default for the shortcodes and all of them can be overridden by specifying a different value in the shortcode itself. All settings for widgets are locate in the individual widget.', $this->_slug ) ?></p>
533
  <table class="form-table">
536
  <label for="twp_username"><?php _e( 'Twitter username:', $this->_slug ); ?></label>
537
  </th>
538
  <td>
539
+ <select id="twp_username" name="twp[username]">
540
+ <option></option>
541
+ <?php
542
+ $selected = false;
543
+ foreach ( $users as $u ) {
544
+ ?>
545
+ <option value="<?php echo esc_attr( strtolower( $u['screen_name'] ) ); ?>"<?php $s = selected( strtolower( $u['screen_name'] ), strtolower( $this->_settings['twp']['username'] ) ) ?>><?php echo esc_html( $u['screen_name'] ); ?></option>
546
+ <?php
547
+ if ( ! empty( $s ) )
548
+ $selected = true;
549
+ }
550
+ ?>
551
+ </select>
552
+ <?php
553
+ if ( ! $selected && ! empty( $this->_settings['twp']['username'] ) ) {
554
+ $query_args = array(
555
+ 'action' => 'authorize',
556
+ 'screen_name' => $this->_settings['twp']['username'],
557
+ );
558
+ $authorize_user_url = wp_nonce_url( add_query_arg( $query_args, $this->get_options_url() ), 'authorize' );
559
+ ?>
560
+ <p>
561
+ <a href="<?php echo esc_url( $authorize_user_url ); ?>" style="color:red;">
562
+ <?php _e( 'You need to authorize this account.', $this->_slug ); ?>
563
+ </a>
564
+ </p>
565
+ <?php
566
+ }
567
+ ?>
568
+ </td>
569
+ </tr>
570
+ <tr valign="top">
571
+ <th scope="row">
572
+ <label for="twp_list"><?php _e( 'Twitter list:', $this->_slug ); ?></label>
573
+ </th>
574
+ <td>
575
+ <select id="twp_list" name="twp[list]">
576
+ <option></option>
577
+ <?php
578
+ foreach ( $lists as $user => $user_lists ) {
579
+ echo '<optgroup label="' . esc_attr( $user ) . '">';
580
+ foreach ( $user_lists as $list_id => $list_name ) {
581
+ ?>
582
+ <option value="<?php echo esc_attr( $user . '::' . $list_id ); ?>"<?php $s = selected( $user . '::' . $list_id, strtolower( $this->_settings['twp']['list'] ) ) ?>><?php echo esc_html( $list_name ); ?></option>
583
+ <?php
584
+ }
585
+ echo '</optgroup>';
586
+ }
587
+ ?>
588
+ </select>
589
  </td>
590
  </tr>
591
  <tr valign="top">
673
  <input class="checkbox" type="checkbox" value="true" id="twp_showretweets" name="twp[showretweets]"<?php checked( $this->_settings['twp']['showretweets'], 'true' ); ?> />
674
  <label for="twp_showretweets"><?php _e( 'Include retweets', $this->_slug ); ?></label>
675
  <br />
676
+ <input type="hidden" value="false" name="twp[hidereplies]" />
677
  <input class="checkbox" type="checkbox" value="true" id="twp_hidereplies" name="twp[hidereplies]"<?php checked( $this->_settings['twp']['hidereplies'], 'true' ); ?> />
678
  <label for="twp_hidereplies"><?php _e( 'Hide @replies', $this->_slug ); ?></label>
679
  <br />
680
+ <input type="hidden" value="false" name="twp[hidefrom]" />
681
  <input class="checkbox" type="checkbox" value="true" id="twp_hidefrom" name="twp[hidefrom]"<?php checked( $this->_settings['twp']['hidefrom'], 'true' ); ?> />
682
  <label for="twp_hidefrom"><?php _e( 'Hide sending applications', $this->_slug ); ?></label>
683
  <br />
689
  <input class="checkbox" type="checkbox" value="true" id="twp_showfollow" name="twp[showfollow]"<?php checked( $this->_settings['twp']['showfollow'], 'true' ); ?> />
690
  <label for="twp_showfollow"><?php _e( 'Show Follow Link', $this->_slug ); ?></label>
691
  <br />
692
+ <input type="hidden" value="false" name="twp[targetBlank]" />
693
  <input class="checkbox" type="checkbox" value="true" id="twp_targetBlank" name="twp[targetBlank]"<?php checked( $this->_settings['twp']['targetBlank'], 'true' ); ?> />
694
  <label for="twp_targetBlank"><?php _e( 'Open links in a new window', $this->_slug ); ?></label>
695
  <br />
696
+ <input type="hidden" value="false" name="twp[showXavisysLink" />
697
  <input class="checkbox" type="checkbox" value="true" id="twp_showXavisysLink" name="twp[showXavisysLink]"<?php checked( $this->_settings['twp']['showXavisysLink'], 'true' ); ?> />
698
  <label for="twp_showXavisysLink"><?php _e( 'Show Link to Twitter Widget Pro', $this->_slug ); ?></label>
699
  </td>
871
  $widgetContent = $args['before_widget'] . '<div>';
872
 
873
  if ( empty( $args['title'] ) )
874
+ $args['title'] = sprintf( __( 'Twitter: %s', $this->_slug ), $args['username'] );
875
 
876
  $args['title'] = apply_filters( 'twitter-widget-title', $args['title'], $args );
877
  $args['title'] = "<span class='twitterwidget twitterwidget-title'>{$args['title']}</span>";
949
  }
950
 
951
  $widgetContent .= '</ul>';
952
+ if ( 'true' == $args['showfollow'] && ! empty( $args['username'] ) ) {
953
  $widgetContent .= '<div class="follow-button">';
954
  $linkText = "@{$args['username']}";
955
  $linkAttrs = array(
1019
  * @return array - Array of objects
1020
  */
1021
  private function _getTweets( $widgetOptions ) {
1022
+ $key = 'twp_' . md5( maybe_serialize( $this->_get_feed_request_settings( $widgetOptions ) ) );
1023
  return tlc_transient( $key )
1024
  ->expires_in( 300 ) // cache for 5 minutes
1025
+ ->extend_on_fail( 120 ) // On a failed call, don't try again for 2 minutes
1026
  ->updates_with( array( $this, 'parseFeed' ), array( $widgetOptions ) )
1027
  ->get();
1028
  }
1034
  * @return array
1035
  */
1036
  public function parseFeed( $widgetOptions ) {
1037
+ $parameters = $this->_get_feed_request_settings( $widgetOptions );
1038
+ $response = array();
1039
 
1040
+ if ( ! empty( $parameters['screen_name'] ) ) {
1041
+ if ( empty( $this->_settings['twp-authed-users'][strtolower( $parameters['screen_name'] )] ) ) {
 
1042
  if ( empty( $widgetOptions['errmsg'] ) )
1043
+ $widgetOptions['errmsg'] = __( 'Account needs to be authorized', $this->_slug );
 
 
 
1044
  } else {
1045
+ $this->_wp_twitter_oauth->set_token( $this->_settings['twp-authed-users'][strtolower( $parameters['screen_name'] )] );
1046
+ $response = $this->_wp_twitter_oauth->send_authed_request( 'statuses/user_timeline', 'GET', $parameters );
1047
+ if ( ! is_wp_error( $response ) )
1048
+ return $response;
1049
  }
1050
+ } elseif ( ! empty( $parameters['list_id'] ) ) {
1051
+ $user = array_shift( explode( '::', $widgetOptions['list'] ) );
1052
+ $this->_wp_twitter_oauth->set_token( $this->_settings['twp-authed-users'][strtolower( $user )] );
1053
+
1054
+ $response = $this->_wp_twitter_oauth->send_authed_request( 'statuses/user_timeline', 'GET', $parameters );
1055
+ if ( ! is_wp_error( $response ) )
1056
+ return $response;
1057
  }
1058
+
1059
+ if ( empty( $widgetOptions['errmsg'] ) )
1060
+ $widgetOptions['errmsg'] = __( 'Invalid Twitter Response.', $this->_slug );
1061
+ do_action( 'widget_twitter_parsefeed_error', $response, $parameters, $widgetOptions );
1062
  throw new Exception( $widgetOptions['errmsg'] );
1063
  }
1064
 
1065
  /**
1066
+ * Gets the parameters for the desired feed.
1067
  *
1068
  * @param array $widgetOptions - settings needed such as username, feet type, etc
1069
+ * @return array - Parameters ready to pass to a Twitter request
 
 
1070
  */
1071
+ private function _get_feed_request_settings( $widgetOptions ) {
 
 
 
 
 
1072
  /**
1073
  * user_id
1074
  * screen_name *
1083
  * contributor_details
1084
  */
1085
 
1086
+ $parameters = array(
1087
+ 'count' => $widgetOptions['items'],
1088
+ );
1089
+
1090
+ if ( ! empty( $widgetOptions['username'] ) )
1091
+ $parameters['screen_name'] = $widgetOptions['username'];
1092
+ elseif ( ! empty( $widgetOptions['list'] ) )
1093
+ $parameters['list_id'] = array_pop( explode( '::', $widgetOptions['list'] ) );
1094
 
1095
  if ( 'true' == $widgetOptions['hidereplies'] )
1096
+ $parameters['exclude_replies'] = 'true';
1097
 
1098
  if ( 'true' == $widgetOptions['showretweets'] )
1099
+ $parameters['include_rts'] = 'true';
1100
+
1101
+ return $parameters;
1102
 
 
1103
  }
1104
 
1105
  /**
1161
  'href' => "http://twitter.com/{$user->screen_name}",
1162
  'title' => $user->name
1163
  );
1164
+ $replace = ( 'original' == $args['avatar'] )? '':"_{$args['avatar']}.";
1165
+ $img = str_replace( '_normal.', $replace, $user->profile_image_url_https );
 
1166
 
1167
  return $this->_buildLink( "<img alt='{$user->name}' src='{$img}' />", $linkAttrs, true );
1168
  }
1251
  return $this->display( $attr );
1252
  }
1253
 
1254
+ public function authed_users_option( $settings ) {
1255
+ if ( ! is_array( $settings ) )
1256
+ return array();
1257
+ return $settings;
1258
+ }
1259
+
1260
  public function filterSettings( $settings ) {
1261
  $defaultArgs = array(
1262
+ 'consumer-key' => '',
1263
+ 'consumer-secret' => '',
1264
  'title' => '',
1265
  'errmsg' => '',
1266
  'fetchTimeOut' => '2',
1267
  'username' => '',
1268
+ 'list' => '',
1269
  'http_vs_https' => 'https',
1270
  'hidereplies' => 'false',
1271
  'showretweets' => 'true',
1299
  public function getSettings( $settings ) {
1300
  return $this->fixAvatar( wp_parse_args( $settings, $this->_settings['twp'] ) );
1301
  }
1302
+
1303
+ public function get_users_list( $authed = false ) {
1304
+ $users = $this->_settings['twp-authed-users'];
1305
+ if ( $authed ) {
1306
+ if ( ! empty( $this->_authed_users ) )
1307
+ return $this->_authed_users;
1308
+ foreach ( $users as $key => $u ) {
1309
+ $this->_wp_twitter_oauth->set_token( $u );
1310
+ $rates = $this->_wp_twitter_oauth->send_authed_request( 'application/rate_limit_status', 'GET', array( 'resources' => 'statuses,lists' ) );
1311
+ if ( is_wp_error( $rates ) )
1312
+ unset( $users[$key] );
1313
+ }
1314
+ $this->_authed_users = $users;
1315
+ }
1316
+ return $users;
1317
+ }
1318
+
1319
+ public function get_lists() {
1320
+ if ( ! empty( $this->_lists ) )
1321
+ return $this->_lists;
1322
+ $this->_lists = array();
1323
+ foreach ( $this->_settings['twp-authed-users'] as $key => $u ) {
1324
+ $this->_wp_twitter_oauth->set_token( $u );
1325
+ $user_lists = $this->_wp_twitter_oauth->send_authed_request( 'lists/list', 'GET', array( 'resources' => 'statuses,lists' ) );
1326
+
1327
+ if ( ! empty( $user_lists ) && ! is_wp_error( $user_lists ) ) {
1328
+ $this->_lists[$key] = array();
1329
+ foreach ( $user_lists as $l ) {
1330
+ $this->_lists[$key][$l->id] = $l->name;
1331
+ }
1332
+ }
1333
+ }
1334
+ return $this->_lists;
1335
+ }
1336
  }
1337
  // Instantiate our class
1338
  $wpTwitterWidget = wpTwitterWidget::getInstance();