Version Description
Download this release
Release Info
Developer | aaroncampbell |
Plugin | Twitter Widget Pro |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- readme.txt +33 -0
- wp-twitter-widget.php +534 -0
readme.txt
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Twitter Widget Pro ===
|
2 |
+
Contributors: aaroncampbell
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40xavisys%2ecom&item_name=Twitter%20Widget%20Pro&no_shipping=0&no_note=1&tax=0¤cy_code=USD&lc=US&bn=PP%2dDonationsBF&charset=UTF%2d8
|
4 |
+
Tags: twitter, widget, feed
|
5 |
+
Requires at least: 2.5
|
6 |
+
Tested up to: 2.5.1
|
7 |
+
Stable tag: 1.0.0
|
8 |
+
|
9 |
+
A widget that properly handles twitter feeds (singlue user or including friends), including parsing @username and URLs into links. Requires PHP5.
|
10 |
+
|
11 |
+
== Description ==
|
12 |
+
|
13 |
+
A widget that properly handles twitter feeds, including @username and link
|
14 |
+
parsing. Feeds can be for a single user, or can include all their friends'
|
15 |
+
tweets as well (like their Twitter home page does). It supports displaying
|
16 |
+
profiles images, and even lets you control whether to display the time and date
|
17 |
+
of a tweet or how log ago it happened (about 5 hours ago, etc). Requires PHP5.
|
18 |
+
|
19 |
+
== Installation ==
|
20 |
+
|
21 |
+
1. Verify that you have PHP5, which is required for this plugin.
|
22 |
+
1. Upload the whole `twitter-widget-pro` directory to the `/wp-content/plugins/` directory
|
23 |
+
1. Activate the plugin through the 'Plugins' menu in WordPress
|
24 |
+
|
25 |
+
== Frequently Asked Questions ==
|
26 |
+
|
27 |
+
= Can I have use than one instance of this widget? =
|
28 |
+
|
29 |
+
Yes, Twitter Widget Pro employs the multi-widget pattern, which allows you to not only have more than one instance of this widget on your site, but even allows more than one instance of this widget in a single sidebar.
|
30 |
+
|
31 |
+
= Can I follow more than one feed? =
|
32 |
+
|
33 |
+
Absolutely, each instance of the widget can have different settings and track different feeds.
|
wp-twitter-widget.php
ADDED
@@ -0,0 +1,534 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Twitter Widget Pro
|
4 |
+
* Plugin URI: http://xavisys.com/wordpress-twitter-widget/
|
5 |
+
* Description: A widget that properly handles twitter feeds, including @username and link parsing, feeds that include friends or just one user, and can even display profile images for the users. Requires PHP5.
|
6 |
+
* Version: 1.0.0
|
7 |
+
* Author: Aaron D. Campbell
|
8 |
+
* Author URI: http://xavisys.com/
|
9 |
+
*/
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Changelog:
|
13 |
+
* 04/17/2008: 1.0.0
|
14 |
+
* - Released to wordpress.org repository
|
15 |
+
*
|
16 |
+
* 04/14/2008: 0.0.3
|
17 |
+
* - Fixed some of the settings used with Snoopy
|
18 |
+
* - Set a read timeout for fetching the files
|
19 |
+
*
|
20 |
+
* 04/14/2008: 0.0.2
|
21 |
+
* - Changed some function names
|
22 |
+
* - Moved form display to a separate function (_showForm)
|
23 |
+
* - Now uses wp_parse_args to handle defaults
|
24 |
+
* - Added comments
|
25 |
+
* - Added seconds to the _timeSince function so you can have something like "about 25 seconds ago"
|
26 |
+
*
|
27 |
+
* 04/11/2008: 0.0.1
|
28 |
+
* - Original Version
|
29 |
+
*/
|
30 |
+
|
31 |
+
/* Copyright 2006 Aaron D. Campbell (email : wp_plugins@xavisys.com)
|
32 |
+
|
33 |
+
This program is free software; you can redistribute it and/or modify
|
34 |
+
it under the terms of the GNU General Public License as published by
|
35 |
+
the Free Software Foundation; either version 2 of the License, or
|
36 |
+
(at your option) any later version.
|
37 |
+
|
38 |
+
This program is distributed in the hope that it will be useful,
|
39 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
40 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
41 |
+
GNU General Public License for more details.
|
42 |
+
|
43 |
+
You should have received a copy of the GNU General Public License
|
44 |
+
along with this program; if not, write to the Free Software
|
45 |
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
46 |
+
*/
|
47 |
+
/**
|
48 |
+
* wpTwitterWidget is the class that handles ALL of the plugin functionality.
|
49 |
+
* It helps us avoid name collisions
|
50 |
+
* http://codex.wordpress.org/Writing_a_Plugin#Avoiding_Function_Name_Collisions
|
51 |
+
*/
|
52 |
+
|
53 |
+
class wpTwitterWidget
|
54 |
+
{
|
55 |
+
/**
|
56 |
+
* User Agent to send when requesting the feeds
|
57 |
+
*
|
58 |
+
* @var string
|
59 |
+
*/
|
60 |
+
private $userAgent;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Read timeout to use when fetching the feeds. Defaults to 2 seconds.
|
64 |
+
*
|
65 |
+
* @todo make a set function for this
|
66 |
+
*
|
67 |
+
* @var int
|
68 |
+
*/
|
69 |
+
private $fetchTimeOut = 2;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Whether to use GZip when fetching feeds. Defaults to true
|
73 |
+
*
|
74 |
+
* @todo make a set function for this
|
75 |
+
*
|
76 |
+
* @var bool
|
77 |
+
*/
|
78 |
+
private $useGzip = true;
|
79 |
+
|
80 |
+
public function __construct() {
|
81 |
+
// Set the user agent to Wordpress/x.x.x
|
82 |
+
$this->userAgent = 'WordPress/' . $GLOBALS['wp_version'];
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Pulls the JSON feed from Twitter and returns an array of objects
|
87 |
+
*
|
88 |
+
* @param array $widgetOptions - settings needed to get feed url, etc
|
89 |
+
* @return array
|
90 |
+
*/
|
91 |
+
private function _parseFeed($widgetOptions) {
|
92 |
+
$feedUrl = $this->_getFeedUrl($widgetOptions);
|
93 |
+
$resp = $this->_fetch_remote_file($feedUrl);
|
94 |
+
if ( $resp->status >= 200 && $resp->status < 300 ) {
|
95 |
+
return json_decode($resp->results);
|
96 |
+
} else {
|
97 |
+
// Failed to fetch url;
|
98 |
+
return array();
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Gets the URL for the desired feed.
|
104 |
+
*
|
105 |
+
* @param array $widgetOptions - settings needed such as username, feet type, etc
|
106 |
+
* @param string[optional] $type - 'rss' or 'json'
|
107 |
+
* @param bool[optional] $count - If true, it adds the count parameter to the URL
|
108 |
+
* @return string - Twitter feed URL
|
109 |
+
*/
|
110 |
+
private function _getFeedUrl($widgetOptions, $type = 'json', $count = true) {
|
111 |
+
if (!in_array($type, array('rss', 'json'))) {
|
112 |
+
$type = 'json';
|
113 |
+
}
|
114 |
+
if ($count) {
|
115 |
+
$count = sprintf('?count=%u', $widgetOptions['items']);
|
116 |
+
} else {
|
117 |
+
$count = '';
|
118 |
+
}
|
119 |
+
return sprintf('http://twitter.com/statuses/%1$s_timeline/%2$s.%3$s%4$s',$widgetOptions['feed'], $widgetOptions['username'], $type, $count);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Replace @username with a link to that twitter user
|
124 |
+
*
|
125 |
+
* @param string $text - Tweet text
|
126 |
+
* @return string - Tweet text with @replies linked
|
127 |
+
*/
|
128 |
+
public function linkTwitterUsers($text) {
|
129 |
+
$text = preg_replace('/(^|\s)@(\w*)(\s|$)/i', '$1@<a href="http://twitter.com/$2" class="twitter-user">$2</a>$3', $text);
|
130 |
+
return $text;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Turn URLs into links
|
135 |
+
*
|
136 |
+
* @param string $text - Tweet text
|
137 |
+
* @return string - Tweet text with URLs repalced with links
|
138 |
+
*/
|
139 |
+
public function linkUrls($text) {
|
140 |
+
/**
|
141 |
+
* match protocol://address/path/file.extension?some=variable&another=asf%
|
142 |
+
* $1 is a possible space, this keeps us from linking href="[link]" etc
|
143 |
+
* $2 is the whole URL
|
144 |
+
* $3 is protocol://
|
145 |
+
* $4 is the URL without the protocol://
|
146 |
+
* $5 is the URL parameters
|
147 |
+
*/
|
148 |
+
$text = preg_replace("/(^|\s)(([a-zA-Z]+:\/\/)([a-z][a-z0-9_\..-]*[a-z]{2,6})([a-zA-Z0-9\/*-?&%]*))/i", "$1<a href=\"$2\">$2</a>", $text);
|
149 |
+
|
150 |
+
/**
|
151 |
+
* match www.something.domain/path/file.extension?some=variable&another=asf%
|
152 |
+
* $1 is a possible space, this keeps us from linking href="[link]" etc
|
153 |
+
* $2 is the whole URL that was matched. The protocol is missing, so we assume http://
|
154 |
+
* $3 is www.
|
155 |
+
* $4 is the URL matched without the www.
|
156 |
+
* $5 is the URL parameters
|
157 |
+
*/
|
158 |
+
$text = preg_replace("/(^|\s)(www\.([a-z][a-z0-9_\..-]*[a-z]{2,6})([a-zA-Z0-9\/*-?&%]*))/i", "$1<a href=\"http://$2\">$2</a>", $text);
|
159 |
+
|
160 |
+
return $text;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Uses snoopy class to pull file contents
|
165 |
+
*
|
166 |
+
* @param string $url - Url to get
|
167 |
+
* @param array $headers - Raw headers to pass
|
168 |
+
* @return Snoopy
|
169 |
+
*/
|
170 |
+
private function _fetch_remote_file ($url, $headers = "" ) {
|
171 |
+
require_once( ABSPATH . 'wp-includes/class-snoopy.php' );
|
172 |
+
// Snoopy is an HTTP client in PHP
|
173 |
+
$client = new Snoopy();
|
174 |
+
$client->agent = $this->userAgent;
|
175 |
+
$client->read_timeout = $this->fetchTimeOut;
|
176 |
+
$client->use_gzip = $this->useGzip;
|
177 |
+
if (is_array($headers) ) {
|
178 |
+
$client->rawheaders = $headers;
|
179 |
+
}
|
180 |
+
|
181 |
+
@$client->fetch($url);
|
182 |
+
return $client;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Gets tweets, from cache if possible
|
187 |
+
*
|
188 |
+
* @param array $widgetOptions - options needed to get feeds
|
189 |
+
* @return array - Array of objects
|
190 |
+
*/
|
191 |
+
private function _getTweets($widgetOptions) {
|
192 |
+
// Get cache of feed if it exists
|
193 |
+
$tweets = wp_cache_get($widgetOptions['feed'] . $widgetOptions['username'], 'widget_twitter');
|
194 |
+
// If there is no cache
|
195 |
+
if ($tweets == false) {
|
196 |
+
$tweets = $this->_parseFeed($widgetOptions);
|
197 |
+
// Cache for 60 seconds, Tweets are supposed to be current, so we don't cache for very long
|
198 |
+
wp_cache_set($widgetOptions['feed'] . $widgetOptions['username'], $tweets, 'widget_twitter', 60);
|
199 |
+
}
|
200 |
+
return $tweets;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Displays the Twitter widget, with all tweets in an unordered list.
|
205 |
+
* Things are classed but not styled to allow easy styling.
|
206 |
+
*
|
207 |
+
* @param array $args - Widget Settings
|
208 |
+
* @param array|int $widget_args - Widget Number
|
209 |
+
*/
|
210 |
+
public function display($args, $widget_args = 1) {
|
211 |
+
extract( $args, EXTR_SKIP );
|
212 |
+
if ( is_numeric($widget_args) )
|
213 |
+
$widget_args = array( 'number' => $widget_args );
|
214 |
+
$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
|
215 |
+
extract( $widget_args, EXTR_SKIP );
|
216 |
+
|
217 |
+
$options = get_option('widget_twitter');
|
218 |
+
if ( !isset($options[$number]) ) {
|
219 |
+
return;
|
220 |
+
}
|
221 |
+
|
222 |
+
// Validate our options
|
223 |
+
if (!isset($options[$number]['feed']) || !in_array($options[$number]['feed'], array('user', 'friends'))) {
|
224 |
+
$options[$number]['feed'] = 'user';
|
225 |
+
}
|
226 |
+
$options[$number]['items'] = (int) $options[$number]['items'];
|
227 |
+
if ( $options[$number]['items'] < 1 || 20 < $options[$number]['items'] ) {
|
228 |
+
$options[$number]['items'] = 10;
|
229 |
+
}
|
230 |
+
if (!isset($options[$number]['showts'])) {
|
231 |
+
$options[$number]['showts'] = 86400;
|
232 |
+
}
|
233 |
+
|
234 |
+
$options[$number]['avatar'] = (isset($options[$number]['avatar']) && $options[$number]['avatar']);
|
235 |
+
|
236 |
+
$tweets = $this->_getTweets($options[$number]);
|
237 |
+
$tweets = array_slice($tweets, 0, $options[$number]['items']);
|
238 |
+
|
239 |
+
echo $before_widget;
|
240 |
+
if ( file_exists(dirname(__FILE__) . '/rss.png') ) {
|
241 |
+
$icon = str_replace(ABSPATH, get_option('siteurl').'/', dirname(__FILE__)) . '/rss.png';
|
242 |
+
} else {
|
243 |
+
$icon = get_option('siteurl').'/wp-includes/images/rss.png';
|
244 |
+
}
|
245 |
+
$feedUrl = $this->_getFeedUrl($options[$number], 'rss', false);
|
246 |
+
$before_title .= "<a class='twitterwidget' href='{$feedUrl}' title='" . attribute_escape(__('Syndicate this content')) ."'><img style='background:orange;color:white;border:none;' width='14' height='14' src='{$icon}' alt='RSS' /></a>";
|
247 |
+
if (!empty($tweets)) {
|
248 |
+
$twitterLink = 'http://twitter.com/' . $tweets[0]->user->screen_name;
|
249 |
+
$before_title .= " <a class='twitterwidget' href='$twitterLink' title='" . attribute_escape("Twitter: {$tweets[0]->user->name}") . "'>";
|
250 |
+
$after_title = '</a>' . $after_title;
|
251 |
+
}
|
252 |
+
if ( !empty( $options[$number]['title'] ) ) { echo $before_title . $options[$number]['title'] . $after_title; } ?>
|
253 |
+
<ul><?php
|
254 |
+
if ( $options[$number]['feed'] == 'user' && !empty($tweets) ) {
|
255 |
+
echo '<li>';
|
256 |
+
if ( $options[$number]['avatar']) {
|
257 |
+
echo $this->_getProfileImage($tweets[0]->user);
|
258 |
+
}
|
259 |
+
echo '<div class="clear" />';
|
260 |
+
echo '</li>';
|
261 |
+
}
|
262 |
+
foreach ($tweets as $tweet) {
|
263 |
+
// Set our "ago" string which converts the date to "# ___(s) ago"
|
264 |
+
$tweet->ago = $this->_timeSince(strtotime($tweet->created_at), $options[$number]['showts']);
|
265 |
+
?>
|
266 |
+
<li>
|
267 |
+
<?php
|
268 |
+
if ( $options[$number]['feed'] == 'friends' ) {
|
269 |
+
if ( $options[$number]['avatar']) {
|
270 |
+
echo $this->_getProfileImage($tweet->user);
|
271 |
+
}
|
272 |
+
echo $this->_getUserName($tweet->user);
|
273 |
+
}
|
274 |
+
?>
|
275 |
+
<span class="entry-content"><?php echo apply_filters( 'widget_twitter_content', $tweet->text ); ?></span>
|
276 |
+
<span class="entry-meta">
|
277 |
+
<a href="http://twitter.com/<?php echo $tweet->user->screen_name; ?>/statuses/<?php echo $tweet->id; ?>">
|
278 |
+
<?php echo $tweet->ago; ?>
|
279 |
+
</a> from <?php
|
280 |
+
echo $tweet->source;
|
281 |
+
if (isset($tweet->in_reply_to)) {
|
282 |
+
echo $this->_getReplyTo($tweet->in_reply_to);
|
283 |
+
} ?>
|
284 |
+
</span>
|
285 |
+
</li>
|
286 |
+
<?php
|
287 |
+
} ?></ul>
|
288 |
+
<?php echo $after_widget; ?>
|
289 |
+
<?php
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Returns a "in reply to" link to the user passed
|
294 |
+
*
|
295 |
+
* @param object $replyTo - Tweet
|
296 |
+
* @return string - Link to Twitter user (XHTML)
|
297 |
+
*/
|
298 |
+
private function _getReplyTo($replyTo) {
|
299 |
+
return <<<replyTo
|
300 |
+
<a href="http://twitter.com/{$replyTo->user->screen_name}/statuses/{$replyTo->id}">
|
301 |
+
in reply to {$replyTo->user->screen_name}
|
302 |
+
</a>
|
303 |
+
replyTo;
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Returns the Twitter user's profile image, linked to that user's profile
|
308 |
+
*
|
309 |
+
* @param object $user - Twitter User
|
310 |
+
* @return string - Linked image (XHTML)
|
311 |
+
*/
|
312 |
+
private function _getProfileImage($user) {
|
313 |
+
return <<<profileImage
|
314 |
+
<a title="{$user->name}" href="http://twitter.com/{$user->screen_name}">
|
315 |
+
<img alt="{$user->name}" src="{$user->profile_image_url}" />
|
316 |
+
</a>
|
317 |
+
profileImage;
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Returns the user's screen name as a link inside strong tags.
|
322 |
+
*
|
323 |
+
* @param object $user - Twitter user
|
324 |
+
* @return string - Username as link (XHTML)
|
325 |
+
*/
|
326 |
+
private function _getUserName($user) {
|
327 |
+
return <<<profileImage
|
328 |
+
<strong>
|
329 |
+
<a title="{$user->name}" href="http://twitter.com/{$user->screen_name}">{$user->screen_name}</a>
|
330 |
+
</strong>
|
331 |
+
profileImage;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Sets up admin forms to manage widgets
|
336 |
+
*
|
337 |
+
* @param array|int $widget_args - Widget Number
|
338 |
+
*/
|
339 |
+
public function control($widget_args) {
|
340 |
+
global $wp_registered_widgets;
|
341 |
+
static $updated = false;
|
342 |
+
|
343 |
+
if ( is_numeric($widget_args) )
|
344 |
+
$widget_args = array( 'number' => $widget_args );
|
345 |
+
$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
|
346 |
+
extract( $widget_args, EXTR_SKIP );
|
347 |
+
|
348 |
+
$options = get_option('widget_twitter');
|
349 |
+
if ( !is_array($options) )
|
350 |
+
$options = array();
|
351 |
+
|
352 |
+
if ( !$updated && !empty($_POST['sidebar']) ) {
|
353 |
+
$sidebar = (string) $_POST['sidebar'];
|
354 |
+
|
355 |
+
$sidebars_widgets = wp_get_sidebars_widgets();
|
356 |
+
if ( isset($sidebars_widgets[$sidebar]) )
|
357 |
+
$this_sidebar =& $sidebars_widgets[$sidebar];
|
358 |
+
else
|
359 |
+
$this_sidebar = array();
|
360 |
+
|
361 |
+
foreach ( $this_sidebar as $_widget_id ) {
|
362 |
+
if ( array($this,'display') == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) {
|
363 |
+
$widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
|
364 |
+
if ( !in_array( "twitter-$widget_number", $_POST['widget-id'] ) ) // the widget has been removed.
|
365 |
+
unset($options[$widget_number]);
|
366 |
+
}
|
367 |
+
}
|
368 |
+
|
369 |
+
foreach ( (array) $_POST['widget-twitter'] as $widget_number => $widget_twitter ) {
|
370 |
+
if ( !isset($widget_twitter['username']) && isset($options[$widget_number]) ) // user clicked cancel
|
371 |
+
continue;
|
372 |
+
$widget_twitter['title'] = strip_tags(stripslashes($widget_twitter['title']));
|
373 |
+
$options[$widget_number] = $widget_twitter;
|
374 |
+
}
|
375 |
+
|
376 |
+
update_option('widget_twitter', $options);
|
377 |
+
$updated = true;
|
378 |
+
}
|
379 |
+
|
380 |
+
if ( -1 != $number ) {
|
381 |
+
$options[$number]['number'] = $number;
|
382 |
+
$options[$number]['title'] = attribute_escape($options[$number]['title']);
|
383 |
+
$options[$number]['username'] = attribute_escape($options[$number]['username']);
|
384 |
+
$options[$number]['avatar'] = (bool) $options[$number]['avatar'];
|
385 |
+
if (!isset($options[$number]['feed']) || !in_array($options[$number]['feed'], array('user', 'friends'))) {
|
386 |
+
$options[$number]['feed'] = 'user';
|
387 |
+
}
|
388 |
+
}
|
389 |
+
$this->_showForm($options[$number]);
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Registers widget in such a way as to allow multiple instances of it
|
394 |
+
*
|
395 |
+
* @see wp-includes/widgets.php
|
396 |
+
*/
|
397 |
+
public function register() {
|
398 |
+
if ( !$options = get_option('widget_twitter') )
|
399 |
+
$options = array();
|
400 |
+
$widget_ops = array('classname' => 'widget_twitter', 'description' => __('Follow a Twitter Feed'));
|
401 |
+
$control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'twitter');
|
402 |
+
$name = __('Twitter Feed');
|
403 |
+
|
404 |
+
$id = false;
|
405 |
+
foreach ( array_keys($options) as $o ) {
|
406 |
+
// Old widgets can have null values for some reason
|
407 |
+
if ( !isset($options[$o]['title']) || !isset($options[$o]['username']) )
|
408 |
+
continue;
|
409 |
+
$id = "twitter-$o"; // Never never never translate an id
|
410 |
+
wp_register_sidebar_widget($id, $name, array($this,'display'), $widget_ops, array( 'number' => $o ));
|
411 |
+
wp_register_widget_control($id, $name, array($this,'control'), $control_ops, array( 'number' => $o ));
|
412 |
+
}
|
413 |
+
|
414 |
+
// If there are none, we register the widget's existance with a generic template
|
415 |
+
if ( !$id ) {
|
416 |
+
wp_register_sidebar_widget( 'twitter-1', $name, array($this,'display'), $widget_ops, array( 'number' => -1 ) );
|
417 |
+
wp_register_widget_control( 'twitter-1', $name, array($this,'control'), $control_ops, array( 'number' => -1 ) );
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Displays the actualy for that populates the widget options box in the
|
423 |
+
* admin section
|
424 |
+
*
|
425 |
+
* @param array $args - Current widget settings and widget number, gets combind with defaults
|
426 |
+
*/
|
427 |
+
private function _showForm($args) {
|
428 |
+
|
429 |
+
$defaultArgs = array( 'title' => '',
|
430 |
+
'username' => '',
|
431 |
+
'avatar' => false,
|
432 |
+
'feed' => 'user',
|
433 |
+
'items' => 10,
|
434 |
+
'showts' => 60 * 60 * 24,
|
435 |
+
'number' => '%i%' );
|
436 |
+
$args = wp_parse_args( $args, $defaultArgs );
|
437 |
+
extract( $args );
|
438 |
+
?>
|
439 |
+
<p>
|
440 |
+
<label for="twitter-username-<?php echo $number; ?>"><?php _e('Twitter username:'); ?></label>
|
441 |
+
<input class="widefat" id="twitter-username-<?php echo $number; ?>" name="widget-twitter[<?php echo $number; ?>][username]" type="text" value="<?php echo $username; ?>" />
|
442 |
+
</p>
|
443 |
+
<p>
|
444 |
+
<label for="twitter-title-<?php echo $number; ?>"><?php _e('Give the feed a title (optional):'); ?></label>
|
445 |
+
<input class="widefat" id="twitter-title-<?php echo $number; ?>" name="widget-twitter[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" />
|
446 |
+
<input type="hidden" name="widget-twitter[<?php echo $number; ?>][submit]" value="1" />
|
447 |
+
</p>
|
448 |
+
<p>
|
449 |
+
<label for="twitter-items-<?php echo $number; ?>"><?php _e('How many items would you like to display?'); ?></label>
|
450 |
+
<select id="twitter-items-<?php echo $number; ?>" name="widget-twitter[<?php echo $number; ?>][items]">
|
451 |
+
<?php
|
452 |
+
for ( $i = 1; $i <= 20; ++$i ) {
|
453 |
+
echo "<option value='$i' ", selected($items, $i), ">$i</option>";
|
454 |
+
}
|
455 |
+
?>
|
456 |
+
</select>
|
457 |
+
</p>
|
458 |
+
<p>
|
459 |
+
<label for="twitter-showts-<?php echo $number; ?>"><?php _e('Show date/time of Tweet (rather than 2 ____ ago):'); ?></label>
|
460 |
+
<select id="twitter-showts-<?php echo $number; ?>" name="widget-twitter[<?php echo $number; ?>][showts]">
|
461 |
+
<option value="0" <?php echo selected($showts, '0'); ?>>Always</a>
|
462 |
+
<option value="3600" <?php echo selected($showts, '3600'); ?>>If over an hour old</a>
|
463 |
+
<option value="86400" <?php echo selected($showts, '86400'); ?>>If over a day old</a>
|
464 |
+
<option value="604800" <?php echo selected($showts, '604800'); ?>>If over a week old</a>
|
465 |
+
<option value="2592000" <?php echo selected($showts, '2592000'); ?>>If over a month old</a>
|
466 |
+
<option value="31536000" <?php echo selected($showts, '31536000'); ?>>If over a year old</a>
|
467 |
+
<option value="-1" <?php echo selected($showts, '-1'); ?>>Never</a>
|
468 |
+
</select>
|
469 |
+
</p>
|
470 |
+
<p>
|
471 |
+
<label for="twitter-feed-<?php echo $number; ?>-user"><input class="checkbox" type="radio" id="twitter-feed-<?php echo $number; ?>-user" name="widget-twitter[<?php echo $number; ?>][feed]" value="user"<?php checked($feed, 'user'); ?> /> <?php _e('Just User'); ?></label><br />
|
472 |
+
<label for="twitter-feed-<?php echo $number; ?>-friends"><input class="checkbox" type="radio" id="twitter-feed-<?php echo $number; ?>-friends" name="widget-twitter[<?php echo $number; ?>][feed]" value="friends"<?php checked($feed, 'friends'); ?> /> <?php _e('With Friends'); ?></label>
|
473 |
+
</p>
|
474 |
+
<p>
|
475 |
+
<label for="twitter-avatar-<?php echo $number; ?>"><input class="checkbox" type="checkbox" id="twitter-avatar-<?php echo $number; ?>" name="widget-twitter[<?php echo $number; ?>][avatar]"<?php checked($avatar, true); ?> /> <?php _e('Show Profile Image(s)'); ?></label>
|
476 |
+
</p>
|
477 |
+
<?php
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Twitter displays all tweets that are less than 24 with something like
|
482 |
+
* "about 4 hours ago" and ones older than 24 hours with a time and date.
|
483 |
+
* This function allows us to simulate that functionality, but lets us
|
484 |
+
* choose where the dividing line is.
|
485 |
+
*
|
486 |
+
* @param int $startTimestamp - The timestamp used to calculate time passed
|
487 |
+
* @param int $max - Max number of seconds to conver to "ago" messages. 0 for all, -1 for none
|
488 |
+
* @return string
|
489 |
+
*/
|
490 |
+
private function _timeSince($startTimestamp, $max) {
|
491 |
+
// array of time period chunks
|
492 |
+
$chunks = array(
|
493 |
+
array('seconds' => 60 * 60 * 24 * 365, 'name' => 'year'),
|
494 |
+
array('seconds' => 60 * 60 * 24 * 30, 'name' => 'month'),
|
495 |
+
array('seconds' => 60 * 60 * 24 * 7, 'name' => 'week'),
|
496 |
+
array('seconds' => 60 * 60 * 24, 'name' => 'day'),
|
497 |
+
array('seconds' => 60 * 60, 'name' => 'hour'),
|
498 |
+
array('seconds' => 60, 'name' => 'minute'),
|
499 |
+
array('seconds' => 1, 'name' => 'second')
|
500 |
+
);
|
501 |
+
|
502 |
+
$since = time() - $startTimestamp;
|
503 |
+
|
504 |
+
if ($max != '-1' && $since >= $max) {
|
505 |
+
return date('h:i:s A F d, Y', $startTimestamp);
|
506 |
+
}
|
507 |
+
|
508 |
+
// $j saves performing the count function each time around the loop
|
509 |
+
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
|
510 |
+
extract($chunks[$i]);
|
511 |
+
|
512 |
+
// finding the biggest chunk (if the chunk fits, break)
|
513 |
+
if (($count = floor($since / $seconds)) != 0) {
|
514 |
+
break;
|
515 |
+
}
|
516 |
+
}
|
517 |
+
|
518 |
+
$print = "{$count} {$name}";
|
519 |
+
if ($count > 1) {
|
520 |
+
$print .= 's';
|
521 |
+
}
|
522 |
+
|
523 |
+
return "about {$print} ago";
|
524 |
+
}
|
525 |
+
}
|
526 |
+
// Instantiate our class
|
527 |
+
$wpTwitterWidget = new wpTwitterWidget();
|
528 |
+
|
529 |
+
/**
|
530 |
+
* Add filters and actions
|
531 |
+
*/
|
532 |
+
add_action('widgets_init', array($wpTwitterWidget, 'register'));
|
533 |
+
add_filter('widget_twitter_content', array($wpTwitterWidget, 'linkTwitterUsers'));
|
534 |
+
add_filter('widget_twitter_content', array($wpTwitterWidget, 'linkUrls'));
|