관리-도구
편집 파일: twitter-widget.php
<?php /** * Module Name: Twitter Widget * Module Description: Display the latest updates from a Twitter user inside your theme's widgets. * Sort Order: 20 * First Introduced: 1.1 */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ if ( !function_exists('wpcom_time_since') ) : /* * Time since function taken from WordPress.com */ function wpcom_time_since( $original, $do_more = 0 ) { // array of time period chunks $chunks = array( array( 60 * 60 * 24 * 365 , 'year' ), array( 60 * 60 * 24 * 30 , 'month' ), array( 60 * 60 * 24 * 7, 'week' ), array( 60 * 60 * 24 , 'day' ), array( 60 * 60 , 'hour' ), array( 60 , 'minute' ), ); $today = time(); $since = $today - $original; for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) { $seconds = $chunks[$i][0]; $name = $chunks[$i][1]; if ( ( $count = floor( $since / $seconds ) ) != 0 ) break; } $print = ( $count == 1 ) ? '1 ' . $name : "$count {$name}s"; if ( $i + 1 < $j ) { $seconds2 = $chunks[$i + 1][0]; $name2 = $chunks[$i + 1][1]; // add second item if it's greater than 0 if ( ( ( $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ) ) != 0 ) && $do_more ) $print .= ( $count2 == 1 ) ? ', 1 ' . $name2 : ", $count2 {$name2}s"; } return $print; } endif; class Wickett_Twitter_Widget extends WP_Widget { function Wickett_Twitter_Widget() { $widget_ops = array( 'classname' => 'widget_twitter', 'description' => __( 'Display your tweets from Twitter', 'jetpack' ) ); parent::WP_Widget( 'twitter', __( 'Twitter (Jetpack)', 'jetpack' ), $widget_ops ); } function widget( $args, $instance ) { extract( $args ); $account = trim( urlencode( $instance['account'] ) ); if ( empty($account) ) return; $title = apply_filters( 'widget_title', $instance['title'] ); if ( empty( $title ) ) $title = __( 'Twitter Updates', 'jetpack' ); $show = absint( $instance['show'] ); // # of Updates to show if ( $show > 200 ) // Twitter paginates at 200 max tweets. update() should not have accepted greater than 20 $show = 200; $hidereplies = (bool) $instance['hidereplies']; $include_retweets = (bool) $instance['includeretweets']; echo "{$before_widget}{$before_title}<a href='" . esc_url( "http://twitter.com/{$account}" ) . "'>" . esc_html($title) . "</a>{$after_title}"; if ( false === ( $tweets = get_transient( 'widget-twitter-' . $this->number ) ) ) { $params = array( 'screen_name'=>$account, // Twitter account name 'trim_user'=>true, // only basic user data (slims the result) 'include_entities' => true ); /** * The exclude_replies parameter filters out replies on the server. If combined with count it only filters that number of tweets (not all tweets up to the requested count) * If we are not filtering out replies then we should specify our requested tweet count */ if ( $hidereplies ) $params['exclude_replies'] = true; else $params['count'] = $show; if ( $include_retweets ) $params['include_rts'] = true; $twitter_json_url = esc_url_raw( 'http://api.twitter.com/1/statuses/user_timeline.json?' . http_build_query( $params ), array( 'http', 'https' ) ); unset( $params ); $response = wp_remote_get( $twitter_json_url, array( 'User-Agent' => 'WordPress.com Twitter Widget' ) ); $response_code = wp_remote_retrieve_response_code( $response ); if ( 200 == $response_code ) { $tweets = wp_remote_retrieve_body( $response ); $tweets = json_decode( $tweets, true ); $expire = 900; if ( !is_array( $tweets ) || isset( $tweets['error'] ) ) { $tweets = 'error'; $expire = 300; } } else { $tweets = 'error'; $expire = 300; set_transient( 'widget-twitter-response-code-' . $this->number, $response_code, $expire ); } set_transient( 'widget-twitter-' . $this->number, $tweets, $expire ); } if ( 'error' != $tweets ) : $before_timesince = ' '; if ( isset( $instance['beforetimesince'] ) && !empty( $instance['beforetimesince'] ) ) $before_timesince = esc_html( $instance['beforetimesince'] ); $before_tweet = ''; if ( isset( $instance['beforetweet'] ) && !empty( $instance['beforetweet'] ) ) $before_tweet = stripslashes( wp_filter_post_kses( $instance['beforetweet'] ) ); echo '<ul class="tweets">' . "\n"; $tweets_out = 0; foreach ( (array) $tweets as $tweet ) { if ( $tweets_out >= $show ) break; if ( empty( $tweet['text'] ) ) continue; $text = esc_html( $tweet['text'] ); // expand t.co links if ( !empty( $tweet['entities']['urls'] ) ) { foreach ( $tweet['entities']['urls'] as $entity_url ) { if ( !empty( $entity_url['expanded_url'] ) ) { $expanded = '<a href="' . esc_url( $entity_url['expanded_url'] ) . '"> ' . esc_html( $entity_url['display_url'] ) . '</a>'; $text = str_replace( $entity_url['url'], $expanded, $text ); } } } $text = make_clickable( $text ); /* * Create links from plain text based on Twitter patterns * @link http://github.com/mzsanford/twitter-text-rb/blob/master/lib/regex.rb Official Twitter regex */ $text = preg_replace_callback( '/(^|[^0-9A-Z&\/]+)(#|\xef\xbc\x83)([0-9A-Z_]*[A-Z_]+[a-z0-9_\xc0-\xd6\xd8-\xf6\xf8\xff]*)/iu', array( &$this, '_wpcom_widget_twitter_hashtag' ), $text ); $text = preg_replace_callback( '/([^a-zA-Z0-9_]|^)([@\xef\xbc\xa0]+)([a-zA-Z0-9_]{1,20})(\/[a-zA-Z][a-zA-Z0-9\x80-\xff-]{0,79})?/u', array( &$this, '_wpcom_widget_twitter_username' ), $text ); if ( isset( $tweet['id_str'] ) ) $tweet_id = urlencode( $tweet['id_str'] ); else $tweet_id = urlencode( $tweet['id'] ); $created_at = str_replace( '+0000', '', $tweet['created_at'] ) . ' UTC'; // Twitter's datetime format is strange, refactor for the sake of PHP4 echo "<li>{$before_tweet}{$text}{$before_timesince}<a href=\"" . esc_url( "http://twitter.com/{$account}/statuses/{$tweet_id}" ) . '" class="timesince">' . str_replace( ' ', ' ', wpcom_time_since( strtotime( $created_at ) ) ) . " ago</a></li>\n"; unset( $tweet_id ); $tweets_out++; } echo "</ul>\n"; else : if ( 401 == get_transient( 'widget-twitter-response-code-' . $this->number ) ) echo '<p>' . wp_kses( sprintf( __( 'Error: Please make sure the Twitter account is <a href="%s">public</a>.', 'jetpack' ), 'http://support.twitter.com/forums/10711/entries/14016' ), array( 'a' => array( 'href' => true ) ) ) . '</p>'; else echo '<p>' . esc_html__( 'Error: Twitter did not respond. Please wait a few minutes and refresh this page.', 'jetpack' ) . '</p>'; endif; echo $after_widget; } function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['account'] = trim( strip_tags( stripslashes( $new_instance['account'] ) ) ); $instance['account'] = str_replace( 'http://twitter.com/', '', $instance['account'] ); $instance['account'] = str_replace( '/', '', $instance['account'] ); $instance['account'] = str_replace( '@', '', $instance['account'] ); $instance['account'] = str_replace( '#!', '', $instance['account'] ); // account for the Ajax URI $instance['title'] = strip_tags( stripslashes( $new_instance['title'] ) ); $instance['show'] = absint( $new_instance['show'] ); $instance['hidereplies'] = isset( $new_instance['hidereplies'] ); $instance['includeretweets'] = isset( $new_instance['includeretweets'] ); $instance['beforetimesince'] = $new_instance['beforetimesince']; delete_transient( 'widget-twitter-' . $this->number ); delete_transient( 'widget-twitter-response-code-' . $this->number ); return $instance; } function form( $instance ) { //Defaults $instance = wp_parse_args( (array) $instance, array( 'account' => '', 'title' => '', 'show' => 5, 'hidereplies' => false, 'includeretweets' => false, 'beforetimesince' => '' ) ); $account = esc_attr( $instance['account'] ); $title = esc_attr( $instance['title'] ); $show = absint( $instance['show'] ); if ( $show < 1 || 20 < $show ) $show = 5; $hidereplies = (bool) $instance['hidereplies']; $include_retweets = (bool) $instance['includeretweets']; $before_timesince = esc_attr( $instance['beforetimesince'] ); echo '<p><label for="' . $this->get_field_id( 'title' ) . '">' . esc_html__( 'Title:', 'jetpack' ) . ' <input class="widefat" id="' . $this->get_field_id( 'title' ) . '" name="' . $this->get_field_name( 'title' ) . '" type="text" value="' . $title . '" /> </label></p> <p><label for="' . $this->get_field_id( 'account' ) . '">' . esc_html__( 'Twitter username:', 'jetpack' ) . ' <a href="http://support.wordpress.com/widgets/twitter-widget/#twitter-username" target="_blank">( ? )</a> <input class="widefat" id="' . $this->get_field_id( 'account' ) . '" name="' . $this->get_field_name( 'account' ) . '" type="text" value="' . $account . '" /> </label></p> <p><label for="' . $this->get_field_id( 'show' ) . '">' . esc_html__( 'Maximum number of tweets to show:', 'jetpack' ) . ' <select id="' . $this->get_field_id( 'show' ) . '" name="' . $this->get_field_name( 'show' ) . '">'; for ( $i = 1; $i <= 20; ++$i ) echo "<option value='$i' " . ( $show == $i ? "selected='selected'" : '' ) . ">$i</option>"; echo ' </select> </label></p> <p><label for="' . $this->get_field_id( 'hidereplies' ) . '"><input id="' . $this->get_field_id( 'hidereplies' ) . '" class="checkbox" type="checkbox" name="' . $this->get_field_name( 'hidereplies' ) . '"'; if ( $hidereplies ) echo ' checked="checked"'; echo ' /> ' . esc_html__( 'Hide replies', 'jetpack' ) . '</label></p>'; echo '<p><label for="' . $this->get_field_id( 'includeretweets' ) . '"><input id="' . $this->get_field_id( 'includeretweets' ) . '" class="checkbox" type="checkbox" name="' . $this->get_field_name( 'includeretweets' ) . '"'; if ( $include_retweets ) echo ' checked="checked"'; echo ' /> ' . esc_html__( 'Include retweets', 'jetpack' ) . '</label></p>'; echo '<p><label for="' . $this->get_field_id( 'beforetimesince' ) . '">' . esc_html__( 'Text to display between tweet and timestamp:', 'jetpack' ) . ' <input class="widefat" id="' . $this->get_field_id( 'beforetimesince' ) . '" name="' . $this->get_field_name( 'beforetimesince' ) . '" type="text" value="' . $before_timesince . '" /> </label></p>'; } /** * Link a Twitter user mentioned in the tweet text to the user's page on Twitter. * * @param array $matches regex match * @return string Tweet text with inserted @user link */ function _wpcom_widget_twitter_username( $matches ) { // $matches has already been through wp_specialchars return "$matches[1]@<a href='" . esc_url( 'http://twitter.com/' . urlencode( $matches[3] ) ) . "'>$matches[3]</a>"; } /** * Link a Twitter hashtag with a search results page on Twitter.com * * @param array $matches regex match * @return string Tweet text with inserted #hashtag link */ function _wpcom_widget_twitter_hashtag( $matches ) { // $matches has already been through wp_specialchars return "$matches[1]<a href='" . esc_url( 'http://twitter.com/search?q=%23' . urlencode( $matches[3] ) ) . "'>#$matches[3]</a>"; } } add_action( 'widgets_init', 'wickett_twitter_widget_init' ); function wickett_twitter_widget_init() { register_widget( 'Wickett_Twitter_Widget' ); }