Twitter. Bring your tweets into your blog and pass your blog posts to Twitter. Show your tweets in your sidebar, and post tweets from your WordPress admin. Version: 2.4 Author: Crowd Favorite Author URI: http://crowdfavorite.com */ // Copyright (c) 2007-2010 Crowd Favorite, Ltd., Alex King. All rights reserved. // // Released under the GPL license // http://www.opensource.org/licenses/gpl-license.php // // This is an add-on for WordPress // http://wordpress.org/ // // Thanks to John Ford ( http://www.aldenta.com ) for his contributions. // Thanks to Dougal Campbell ( http://dougal.gunters.org ) for his contributions. // Thanks to Silas Sewell ( http://silas.sewell.ch ) for his contributions. // Thanks to Greg Grubbs for his contributions. // // ********************************************************************** // 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. // ********************************************************************** /* TODO - update widget to new WP widget class - what should retweet support look like? - refactor digests to use WP-CRON - truncate super-long post titles so that full tweet content is < 140 chars */ define('AKTT_VERSION', '2.4'); load_plugin_textdomain('twitter-tools', false, dirname(plugin_basename(__FILE__)) . '/language'); if (!defined('PLUGINDIR')) { define('PLUGINDIR','wp-content/plugins'); } if (is_file(trailingslashit(ABSPATH.PLUGINDIR).'twitter-tools.php')) { define('AKTT_FILE', trailingslashit(ABSPATH.PLUGINDIR).'twitter-tools.php'); } else if (is_file(trailingslashit(ABSPATH.PLUGINDIR).'twitter-tools/twitter-tools.php')) { define('AKTT_FILE', trailingslashit(ABSPATH.PLUGINDIR).'twitter-tools/twitter-tools.php'); } define('AKTT_API_POST_STATUS', 'http://twitter.com/statuses/update.json'); define('AKTT_API_USER_TIMELINE', 'http://twitter.com/statuses/user_timeline.json'); define('AKTT_API_STATUS_SHOW', 'http://twitter.com/statuses/show/###ID###.json'); define('AKTT_PROFILE_URL', 'http://twitter.com/###USERNAME###'); define('AKTT_STATUS_URL', 'http://twitter.com/###USERNAME###/statuses/###STATUS###'); define('AKTT_HASHTAG_URL', 'http://search.twitter.com/search?q=###HASHTAG###'); function aktt_install() { global $wpdb; $aktt_install = new twitter_tools; $wpdb->aktt = $wpdb->prefix.'ak_twitter'; $tables = $wpdb->get_col(" SHOW TABLES LIKE '$wpdb->aktt' "); if (!in_array($wpdb->aktt, $tables)) { $charset_collate = ''; if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') ) { if (!empty($wpdb->charset)) { $charset_collate .= " DEFAULT CHARACTER SET $wpdb->charset"; } if (!empty($wpdb->collate)) { $charset_collate .= " COLLATE $wpdb->collate"; } } $result = $wpdb->query(" CREATE TABLE `$wpdb->aktt` ( `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `tw_id` VARCHAR( 255 ) NOT NULL , `tw_text` VARCHAR( 255 ) NOT NULL , `tw_reply_username` VARCHAR( 255 ) DEFAULT NULL , `tw_reply_tweet` VARCHAR( 255 ) DEFAULT NULL , `tw_created_at` DATETIME NOT NULL , `modified` DATETIME NOT NULL , UNIQUE KEY `tw_id_unique` ( `tw_id` ) ) $charset_collate "); } foreach ($aktt_install->options as $option) { add_option('aktt_'.$option, $aktt_install->$option); } add_option('aktt_update_hash', ''); } register_activation_hook(AKTT_FILE, 'aktt_install'); class twitter_tools { function twitter_tools() { $this->options = array( 'twitter_username' , 'create_blog_posts' , 'create_digest' , 'create_digest_weekly' , 'digest_daily_time' , 'digest_weekly_time' , 'digest_weekly_day' , 'digest_title' , 'digest_title_weekly' , 'blog_post_author' , 'blog_post_category' , 'blog_post_tags' , 'notify_twitter' , 'sidebar_tweet_count' , 'tweet_from_sidebar' , 'give_tt_credit' , 'exclude_reply_tweets' , 'tweet_prefix' , 'last_tweet_download' , 'doing_tweet_download' , 'doing_digest_post' , 'install_date' , 'js_lib' , 'digest_tweet_order' , 'notify_twitter_default' , 'app_consumer_key' , 'app_consumer_secret' , 'oauth_token' , 'oauth_token_secret' ); $this->twitter_username = ''; $this->create_blog_posts = '0'; $this->create_digest = '0'; $this->create_digest_weekly = '0'; $this->digest_daily_time = null; $this->digest_weekly_time = null; $this->digest_weekly_day = null; $this->digest_title = __("Twitter Updates for %s", 'twitter-tools'); $this->digest_title_weekly = __("Twitter Weekly Updates for %s", 'twitter-tools'); $this->blog_post_author = '1'; $this->blog_post_category = '1'; $this->blog_post_tags = ''; $this->notify_twitter = '0'; $this->notify_twitter_default = '0'; $this->sidebar_tweet_count = '3'; $this->tweet_from_sidebar = '1'; $this->give_tt_credit = '1'; $this->exclude_reply_tweets = '0'; $this->install_date = ''; $this->js_lib = 'jquery'; $this->digest_tweet_order = 'ASC'; $this->tweet_prefix = 'New blog post'; $this->app_consumer_key = ''; $this->app_consumer_secret = ''; $this->oauth_token = ''; $this->oauth_token_secret =''; // not included in options $this->update_hash = ''; $this->tweet_format = $this->tweet_prefix.': %s %s'; $this->last_digest_post = ''; $this->last_tweet_download = ''; $this->doing_tweet_download = '0'; $this->doing_digest_post = '0'; $this->oauth_hash = ''; $this->version = AKTT_VERSION; } function upgrade() { global $wpdb; $wpdb->aktt = $wpdb->prefix.'ak_twitter'; $col_data = $wpdb->get_results(" SHOW COLUMNS FROM $wpdb->aktt "); $cols = array(); foreach ($col_data as $col) { $cols[] = $col->Field; } // 1.2 schema upgrade if (!in_array('tw_reply_username', $cols)) { $wpdb->query(" ALTER TABLE `$wpdb->aktt` ADD `tw_reply_username` VARCHAR( 255 ) DEFAULT NULL AFTER `tw_text` "); } if (!in_array('tw_reply_tweet', $cols)) { $wpdb->query(" ALTER TABLE `$wpdb->aktt` ADD `tw_reply_tweet` VARCHAR( 255 ) DEFAULT NULL AFTER `tw_reply_username` "); } $this->upgrade_default_tweet_prefix(); // upgrade indexes 2.1 $index_data = $wpdb->get_results(" SHOW INDEX FROM $wpdb->aktt "); $indexes = array(); foreach ($index_data as $index) { $indexes[] = $index->Key_name; } if (in_array('tw_id', $indexes)) { $wpdb->query(" ALTER TABLE `$wpdb->aktt` DROP INDEX `tw_id` "); } if (!in_array('tw_id_unique', $indexes)) { $wpdb->query(" ALTER IGNORE TABLE `$wpdb->aktt` ADD UNIQUE KEY `tw_id_unique` ( `tw_id` ) "); $wpdb->query(" OPTIMIZE TABLE `$wpdb->aktt` "); } } function upgrade_default_tweet_prefix() { $prefix = get_option('aktt_tweet_prefix'); if (empty($prefix)) { $aktt_defaults = new twitter_tools; update_option('aktt_tweet_prefix', $aktt_defaults->tweet_prefix); } } function get_settings() { foreach ($this->options as $option) { $value = get_option('aktt_'.$option); if ($option != 'tweet_prefix' || !empty($value)) { $this->$option = $value; } } $this->tweet_format = $this->tweet_prefix.': %s %s'; } // puts post fields into object propps function populate_settings() { foreach ($this->options as $option) { $value = stripslashes($_POST['aktt_'.$option]); if (isset($_POST['aktt_'.$option]) && ($option != 'tweet_prefix' || !empty($value))) { $this->$option = $value; } } } // puts object props into wp option storage function update_settings() { if (current_user_can('manage_options')) { $this->sidebar_tweet_count = intval($this->sidebar_tweet_count); if ($this->sidebar_tweet_count == 0) { $this->sidebar_tweet_count = '3'; } foreach ($this->options as $option) { update_option('aktt_'.$option, $this->$option); } if (empty($this->install_date)) { update_option('aktt_install_date', current_time('mysql')); } $this->initiate_digests(); $this->upgrade(); $this->upgrade_default_tweet_prefix(); update_option('aktt_installed_version', AKTT_VERSION); delete_option('aktt_twitter_password'); } } // figure out when the next weekly and daily digests will be function initiate_digests() { $next = ($this->create_digest) ? $this->calculate_next_daily_digest() : null; $this->next_daily_digest = $next; update_option('aktt_next_daily_digest', $next); $next = ($this->create_digest_weekly) ? $this->calculate_next_weekly_digest() : null; $this->next_weekly_digest = $next; update_option('aktt_next_weekly_digest', $next); } function calculate_next_daily_digest() { $optionDate = strtotime($this->digest_daily_time); $hour_offset = date("G", $optionDate); $minute_offset = date("i", $optionDate); $next = mktime($hour_offset, $minute_offset, 0); // may have to move to next day $now = time(); while($next < $now) { $next += 60 * 60 * 24; } return $next; } function calculate_next_weekly_digest() { $optionDate = strtotime($this->digest_weekly_time); $hour_offset = date("G", $optionDate); $minute_offset = date("i", $optionDate); $current_day_of_month = date("j"); $current_day_of_week = date("w"); $current_month = date("n"); // if this week's day is less than today, go for next week $nextDay = $current_day_of_month - $current_day_of_week + $this->digest_weekly_day; $next = mktime($hour_offset, $minute_offset, 0, $current_month, $nextDay); if ($this->digest_weekly_day <= $current_day_of_week) { $next = strtotime('+1 week', $next); } return $next; } function ping_digests() { // still busy if (get_option('aktt_doing_digest_post') == '1') { return; } // check all the digest schedules if ($this->create_digest == 1) { $this->ping_digest('aktt_next_daily_digest', 'aktt_last_digest_post', $this->digest_title, 60 * 60 * 24 * 1); } if ($this->create_digest_weekly == 1) { $this->ping_digest('aktt_next_weekly_digest', 'aktt_last_digest_post_weekly', $this->digest_title_weekly, 60 * 60 * 24 * 7); } return; } function ping_digest($nextDateField, $lastDateField, $title, $defaultDuration) { $next = get_option($nextDateField); if ($next) { $next = $this->validateDate($next); $rightNow = time(); if ($rightNow >= $next) { $start = get_option($lastDateField); $start = $this->validateDate($start, $rightNow - $defaultDuration); if ($this->do_digest_post($start, $next, $title)) { update_option($lastDateField, $rightNow); update_option($nextDateField, $next + $defaultDuration); } else { update_option($lastDateField, null); } } } } function validateDate($in, $default = 0) { if (!is_numeric($in)) { // try to convert what they gave us into a date $out = strtotime($in); // if that doesn't work, return the default if (!is_numeric($out)) { return $default; } return $out; } return $in; } function do_digest_post($start, $end, $title) { if (!$start || !$end) return false; // flag us as busy update_option('aktt_doing_digest_post', '1'); remove_action('publish_post', 'aktt_notify_twitter', 99); remove_action('publish_post', 'aktt_store_post_options', 1, 2); remove_action('save_post', 'aktt_store_post_options', 1, 2); // see if there's any tweets in the time range global $wpdb; $startGMT = gmdate("Y-m-d H:i:s", $start); $endGMT = gmdate("Y-m-d H:i:s", $end); // build sql $conditions = array(); $conditions[] = "tw_created_at >= '{$startGMT}'"; $conditions[] = "tw_created_at <= '{$endGMT}'"; $conditions[] = "tw_text NOT LIKE '".$wpdb->escape($this->tweet_prefix)."%'"; if ($this->exclude_reply_tweets) { $conditions[] = "tw_text NOT LIKE '@%'"; } $where = implode(' AND ', $conditions); $sql = " SELECT * FROM {$wpdb->aktt} WHERE {$where} ORDER BY tw_created_at {$this->digest_tweet_order} "; $tweets = $wpdb->get_results($sql); if (count($tweets) > 0) { $tweets_to_post = array(); foreach ($tweets as $data) { $tweet = new aktt_tweet; $tweet->tw_text = $data->tw_text; $tweet->tw_reply_tweet = $data->tw_reply_tweet; if (!$tweet->tweet_is_post_notification() || ($tweet->tweet_is_reply() && $this->exclude_reply_tweets)) { $tweets_to_post[] = $data; } } $tweets_to_post = apply_filters('aktt_tweets_to_digest_post', $tweets_to_post); // here's your chance to alter the tweet list that will be posted as the digest if (count($tweets_to_post) > 0) { $content = '
'.__('Powered by Twitter Tools', 'twitter-tools').'
'; } $post_data = array( 'post_content' => $wpdb->escape($content), 'post_title' => $wpdb->escape(sprintf($title, date('Y-m-d'))), 'post_date' => date('Y-m-d H:i:s', $end), 'post_category' => array($this->blog_post_category), 'post_status' => 'publish', 'post_author' => $wpdb->escape($this->blog_post_author) ); $post_data = apply_filters('aktt_digest_post_data', $post_data); // last chance to alter the digest content $post_id = wp_insert_post($post_data); add_post_meta($post_id, 'aktt_tweeted', '1', true); wp_set_post_tags($post_id, $this->blog_post_tags); } } add_action('publish_post', 'aktt_notify_twitter', 99); add_action('publish_post', 'aktt_store_post_options', 1, 2); add_action('save_post', 'aktt_store_post_options', 1, 2); update_option('aktt_doing_digest_post', '0'); return true; } function tweet_download_interval() { return 600; } function do_tweet($tweet = '') { if (empty($tweet) || empty($tweet->tw_text)) { return; } $tweet = apply_filters('aktt_do_tweet', $tweet); // return false here to not tweet if (!$tweet) { return; } if (aktt_oauth_test() && ($connection = aktt_oauth_connection())) { $connection->post( AKTT_API_POST_STATUS , array( 'status' => $tweet->tw_text , 'source' => 'twittertools' ) ); if (strcmp($connection->http_code, '200') == 0) { update_option('aktt_last_tweet_download', strtotime('-28 minutes')); return true; } } return false; } function do_blog_post_tweet($post_id = 0) { // this is only called on the publish_post hook if ($this->notify_twitter == '0' || $post_id == 0 || get_post_meta($post_id, 'aktt_tweeted', true) == '1' || get_post_meta($post_id, 'aktt_notify_twitter', true) == 'no' ) { return; } $post = get_post($post_id); // check for an edited post before TT was installed if ($post->post_date <= $this->install_date) { return; } // check for private posts if ($post->post_status == 'private') { return; } $tweet = new aktt_tweet; $url = apply_filters('tweet_blog_post_url', get_permalink($post_id)); $tweet->tw_text = sprintf(__($this->tweet_format, 'twitter-tools'), @html_entity_decode($post->post_title, ENT_COMPAT, 'UTF-8'), $url); $tweet = apply_filters('aktt_do_blog_post_tweet', $tweet, $post); // return false here to not tweet if (!$tweet) { return; } $this->do_tweet($tweet); add_post_meta($post_id, 'aktt_tweeted', '1', true); } function do_tweet_post($tweet) { global $wpdb; remove_action('publish_post', 'aktt_notify_twitter', 99); $data = array( 'post_content' => $wpdb->escape(aktt_make_clickable($tweet->tw_text)) , 'post_title' => $wpdb->escape(trim_add_elipsis($tweet->tw_text, 30)) , 'post_date' => get_date_from_gmt(date('Y-m-d H:i:s', $tweet->tw_created_at)) , 'post_category' => array($this->blog_post_category) , 'post_status' => 'publish' , 'post_author' => $wpdb->escape($this->blog_post_author) ); $data = apply_filters('aktt_do_tweet_post', $data, $tweet); // return false here to not make a blog post if (!$data) { return; } $post_id = wp_insert_post($data); add_post_meta($post_id, 'aktt_twitter_id', $tweet->tw_id, true); wp_set_post_tags($post_id, $this->blog_post_tags); add_action('publish_post', 'aktt_notify_twitter', 99); } } class aktt_tweet { function aktt_tweet( $tw_id = '' , $tw_text = '' , $tw_created_at = '' , $tw_reply_username = null , $tw_reply_tweet = null ) { $this->id = ''; $this->modified = ''; $this->tw_created_at = $tw_created_at; $this->tw_text = $tw_text; $this->tw_reply_username = $tw_reply_username; $this->tw_reply_tweet = $tw_reply_tweet; $this->tw_id = $tw_id; } function twdate_to_time($date) { $parts = explode(' ', $date); $date = strtotime($parts[1].' '.$parts[2].', '.$parts[5].' '.$parts[3]); return $date; } function tweet_post_exists() { global $wpdb; $test = $wpdb->get_results(" SELECT * FROM $wpdb->postmeta WHERE meta_key = 'aktt_twitter_id' AND meta_value = '".$wpdb->escape($this->tw_id)."' "); if (count($test) > 0) { return true; } return false; } function tweet_is_post_notification() { global $aktt; if (substr($this->tw_text, 0, strlen($aktt->tweet_prefix)) == $aktt->tweet_prefix) { return true; } return false; } function tweet_is_reply() { // Twitter data changed - users still expect anything starting with @ is a reply // return !empty($this->tw_reply_tweet); return (substr($this->tw_text, 0, 1) == '@'); } function add() { global $wpdb, $aktt; $wpdb->query(" INSERT INTO $wpdb->aktt ( tw_id , tw_text , tw_reply_username , tw_reply_tweet , tw_created_at , modified ) VALUES ( '".$wpdb->escape($this->tw_id)."' , '".$wpdb->escape($this->tw_text)."' , '".$wpdb->escape($this->tw_reply_username)."' , '".$wpdb->escape($this->tw_reply_tweet)."' , '".date('Y-m-d H:i:s', $this->tw_created_at)."' , NOW() ) "); do_action('aktt_add_tweet', $this); if ($aktt->create_blog_posts == '1' && !$this->tweet_post_exists() && !$this->tweet_is_post_notification() && (!$aktt->exclude_reply_tweets || !$this->tweet_is_reply())) { $aktt->do_tweet_post($this); } } } function aktt_api_status_show_url($id) { return str_replace('###ID###', $id, AKTT_API_STATUS_SHOW); } function aktt_profile_url($username) { return str_replace('###USERNAME###', $username, AKTT_PROFILE_URL); } function aktt_profile_link($username, $prefix = '', $suffix = '') { return $prefix.''.$username.''.$suffix; } function aktt_hashtag_url($hashtag) { $hashtag = urlencode('#'.$hashtag); return str_replace('###HASHTAG###', $hashtag, AKTT_HASHTAG_URL); } function aktt_hashtag_link($hashtag, $prefix = '', $suffix = '') { return $prefix.''.htmlspecialchars($hashtag).' '.$suffix; } function aktt_status_url($username, $status) { return str_replace( array( '###USERNAME###' , '###STATUS###' ) , array( $username , $status ) , AKTT_STATUS_URL ); } function aktt_oauth_test() { global $aktt; return ( aktt_oauth_credentials_to_hash() == get_option('aktt_oauth_hash') ); } function aktt_ping_digests() { global $aktt; $aktt->ping_digests(); } function aktt_update_tweets() { global $aktt; // let the last update run for 10 minutes if (time() - intval(get_option('aktt_doing_tweet_download')) < $aktt->tweet_download_interval()) { return; } // wait 10 min between downloads if (time() - intval(get_option('aktt_last_tweet_download')) < $aktt->tweet_download_interval()) { return; } update_option('aktt_doing_tweet_download', time()); global $wpdb, $aktt; if (empty($aktt->twitter_username)) { update_option('aktt_doing_tweet_download', '0'); return; } if ( aktt_oauth_test() && ($connection = aktt_oauth_connection()) ) { $data = $connection->get(AKTT_API_USER_TIMELINE); if ($connection->http_code != '200') { update_option('aktt_doing_tweet_download', '0'); return; } } else { return; } // hash results to see if they're any different than the last update, if so, return $hash = md5($data); if ($hash == get_option('aktt_update_hash')) { update_option('aktt_last_tweet_download', time()); update_option('aktt_doing_tweet_download', '0'); do_action('aktt_update_tweets'); return; } $data = preg_replace('/"id":(\d+)/', '"id":"$1"', $data); // hack for json_decode on 32-bit PHP $tweets = json_decode($data); if (is_array($tweets) && count($tweets)) { $tweet_ids = array(); foreach ($tweets as $tweet) { $tweet_ids[] = $wpdb->escape($tweet->id); } $existing_ids = $wpdb->get_col(" SELECT tw_id FROM $wpdb->aktt WHERE tw_id IN ('".implode("', '", $tweet_ids)."') "); foreach ($tweets as $tw_data) { if (!$existing_ids || !in_array($tw_data->id, $existing_ids)) { $tweet = new aktt_tweet( $tw_data->id , $tw_data->text ); $tweet->tw_created_at = $tweet->twdate_to_time($tw_data->created_at); if (!empty($tw_data->in_reply_to_status_id)) { $tweet->tw_reply_tweet = $tw_data->in_reply_to_status_id; $url = aktt_api_status_show_url($tw_data->in_reply_to_status_id); $data = $connection->get($url); if (strcmp($connection->http_code, '200') == 0) { $status = json_decode($data); $tweet->tw_reply_username = $status->user->screen_name; } } // make sure we haven't downloaded someone else's tweets - happens sometimes due to Twitter hiccups if (strtolower($tw_data->user->screen_name) == strtolower($aktt->twitter_username)) { $tweet->add(); } } } } aktt_reset_tweet_checking($hash, time()); do_action('aktt_update_tweets'); } function aktt_reset_tweet_checking($hash = '', $time = 0) { if (!current_user_can('manage_options')) { return; } update_option('aktt_update_hash', $hash); update_option('aktt_last_tweet_download', $time); update_option('aktt_doing_tweet_download', '0'); } function aktt_reset_digests() { if (!current_user_can('manage_options')) { return; } update_option('aktt_doing_digest_post', '0'); } function aktt_notify_twitter($post_id) { global $aktt; $aktt->do_blog_post_tweet($post_id); } add_action('publish_post', 'aktt_notify_twitter', 99); function aktt_sidebar_tweets($limit = null, $form = null) { global $wpdb, $aktt; if (!$limit) { $limit = $aktt->sidebar_tweet_count; } if ($aktt->exclude_reply_tweets) { $where = "AND tw_text NOT LIKE '@%' "; } else { $where = ''; } $tweets = $wpdb->get_results(" SELECT * FROM $wpdb->aktt WHERE tw_text NOT LIKE '".$wpdb->escape($aktt->tweet_prefix.'%')."' $where ORDER BY tw_created_at DESC LIMIT $limit "); $output = ''.__('Posting tweet...', 'twitter-tools').'
'; } if ($aktt->give_tt_credit == '1') { $output .= ''.__('Powered by Twitter Tools', 'twitter-tools').'
'; } $output .= ''.__('Find additional Twitter Tools options on the Twitter Tools Options page.', 'twitter-tools').' '); } register_widget_control(array(__('Twitter Tools', 'twitter-tools'), 'widgets'), 'aktt_widget_control', 300, 100); } add_action('widgets_init', 'aktt_widget_init'); function aktt_init() { global $wpdb, $aktt; $wpdb->aktt = $wpdb->prefix.'ak_twitter'; $aktt = new twitter_tools; $aktt->get_settings(); if (($aktt->last_tweet_download + $aktt->tweet_download_interval()) < time()) { add_action('shutdown', 'aktt_update_tweets'); add_action('shutdown', 'aktt_ping_digests'); } if (!is_admin() && $aktt->tweet_from_sidebar && current_user_can('publish_posts')) { switch ($aktt->js_lib) { case 'jquery': wp_enqueue_script('jquery'); break; case 'prototype': wp_enqueue_script('prototype'); break; } } if (is_admin()) { global $wp_version; $update = false; if (isset($wp_version) && version_compare($wp_version, '2.5', '>=') && empty ($aktt->install_date)) { $update = true; } if (!get_option('aktt_tweet_prefix')) { update_option('aktt_tweet_prefix', $aktt->tweet_prefix); $update = true; } $installed_version = get_option('aktt_installed_version'); if ($installed_version != AKTT_VERSION) { $update = true; } if (!empty($installed_version) && version_compare($installed_version, '2.4', '<') && !aktt_oauth_test()) { add_action('admin_notices', create_function( '', "echo '
".sprintf(__('Twitter recently changed how it authenticates its users, you will need you to update your Twitter Tools settings. We apologize for any inconvenience these new authentication steps may cause.', 'twitter-tools'), admin_url('options-general.php?page=twitter-tools.php'))."
".sprintf(__('Please update your Twitter Tools settings', 'twitter-tools'), admin_url('options-general.php?page=twitter-tools.php'))."
'.__('Tweet posted.', 'twitter-tools').'
'.__('This will create a new \'tweet\' in Twitter using the account information in your Twitter Tools Options.', 'twitter-tools').'
'.aktt_tweet_form('textarea').''.__('Tweets updated.', 'twitter-tools').'
'.__('Tweet checking has been reset.', 'twitter-tools').'
'.__('Yay! We connected with Twitter.', 'twitter-tools').'
'.__('Authentication Failed. Please check your credentials and make sure Twitter is up and running.', 'twitter-tools').'
'.__('In order to get started, we need to follow some steps to get this site registered with Twitter. This process is awkward and more complicated than it should be. We hope to have a better solution for this in a future release, but for now this system is what Twitter supports. If you have any trouble, please use the Support button above to contact WordPress HelpCenter and provide code 14303.', 'twitter-tools').'
'); } else if ( aktt_oauth_test() ) { print(''.__('Send post to Twitter?', 'twitter-tools').' '; echo '
'; do_action('aktt_post_options'); } } function aktt_add_meta_box() { global $aktt; if ($aktt->notify_twitter) { add_meta_box('aktt_post_form', __('Twitter Tools', 'twitter-tools'), 'aktt_meta_box', 'post', 'side'); } } add_action('admin_init', 'aktt_add_meta_box'); function aktt_store_post_options($post_id, $post = false) { global $aktt; $post = get_post($post_id); if (!$post || $post->post_type == 'revision') { return; } $notify_meta = get_post_meta($post_id, 'aktt_notify_twitter', true); $posted_meta = $_POST['aktt_notify_twitter']; $save = false; if (!empty($posted_meta)) { $posted_meta == 'yes' ? $meta = 'yes' : $meta = 'no'; $save = true; } else if (empty($notify_meta)) { $aktt->notify_twitter_default ? $meta = 'yes' : $meta = 'no'; $save = true; } if ($save) { update_post_meta($post_id, 'aktt_notify_twitter', $meta); } } add_action('draft_post', 'aktt_store_post_options', 1, 2); add_action('publish_post', 'aktt_store_post_options', 1, 2); add_action('save_post', 'aktt_store_post_options', 1, 2); function aktt_menu_items() { if (current_user_can('manage_options')) { add_options_page( __('Twitter Tools Options', 'twitter-tools') , __('Twitter Tools', 'twitter-tools') , 10 , basename(__FILE__) , 'aktt_options_form' ); } if (current_user_can('publish_posts')) { add_submenu_page( 'post-new.php' , __('New Tweet', 'twitter-tools') , __('Tweet', 'twitter-tools') , 2 , basename(__FILE__) , 'aktt_admin_tweet_form' ); } } add_action('admin_menu', 'aktt_menu_items'); function aktt_plugin_action_links($links, $file) { $plugin_file = basename(__FILE__); if (basename($file) == $plugin_file) { $settings_link = ''.__('Settings', 'twitter-tools').''; array_unshift($links, $settings_link); } return $links; } add_filter('plugin_action_links', 'aktt_plugin_action_links', 10, 2); if (!function_exists('trim_add_elipsis')) { function trim_add_elipsis($string, $limit = 100) { if (strlen($string) > $limit) { $string = substr($string, 0, $limit)."..."; } return $string; } } if (!function_exists('ak_gmmktime')) { function ak_gmmktime() { return gmmktime() - get_option('gmt_offset') * 3600; } } /** based on: http://www.gyford.com/phil/writing/2006/12/02/quick_twitter.php * Returns a relative date, eg "4 hrs ago". * * Assumes the passed-in can be parsed by strtotime. * Precision could be one of: * 1 5 hours, 3 minutes, 2 seconds ago (not yet implemented). * 2 5 hours, 3 minutes * 3 5 hours * * This is all a little overkill, but copied from other places I've used it. * Also superfluous, now I've noticed that the Twitter API includes something * similar, but this version is more accurate and less verbose. * * @access private. * @param string date In a format parseable by strtotime(). * @param integer precision * @return string */ function aktt_relativeTime ($date, $precision=2) { $now = time(); $time = gmmktime( substr($date, 11, 2) , substr($date, 14, 2) , substr($date, 17, 2) , substr($date, 5, 2) , substr($date, 8, 2) , substr($date, 0, 4) ); $time = strtotime(date('Y-m-d H:i:s', $time)); $diff = $now - $time; $months = floor($diff/2419200); $diff -= $months * 2419200; $weeks = floor($diff/604800); $diff -= $weeks*604800; $days = floor($diff/86400); $diff -= $days * 86400; $hours = floor($diff/3600); $diff -= $hours * 3600; $minutes = floor($diff/60); $diff -= $minutes * 60; $seconds = $diff; if ($months > 0) { return date_i18n( __('Y-m-d', 'twitter-tools'), $time); } else { $relative_date = ''; if ($weeks > 0) { // Weeks and days $relative_date .= ($relative_date?', ':'').$weeks.' '.__ngettext('week', 'weeks', $weeks, 'twitter-tools'); if ($precision <= 2) { $relative_date .= $days>0? ($relative_date?', ':'').$days.' '.__ngettext('day', 'days', $days, 'twitter-tools'):''; if ($precision == 1) { $relative_date .= $hours>0?($relative_date?', ':'').$hours.' '.__ngettext('hr', 'hrs', $hours, 'twitter-tools'):''; } } } elseif ($days > 0) { // days and hours $relative_date .= ($relative_date?', ':'').$days.' '.__ngettext('day', 'days', $days, 'twitter-tools'); if ($precision <= 2) { $relative_date .= $hours>0?($relative_date?', ':'').$hours.' '.__ngettext('hr', 'hrs', $hours, 'twitter-tools'):''; if ($precision == 1) { $relative_date .= $minutes>0?($relative_date?', ':'').$minutes.' '.__ngettext('min', 'mins', $minutes, 'twitter-tools'):''; } } } elseif ($hours > 0) { // hours and minutes $relative_date .= ($relative_date?', ':'').$hours.' '.__ngettext('hr', 'hrs', $hours, 'twitter-tools'); if ($precision <= 2) { $relative_date .= $minutes>0?($relative_date?', ':'').$minutes.' '.__ngettext('min', 'mins', $minutes, 'twitter-tools'):''; if ($precision == 1) { $relative_date .= $seconds>0?($relative_date?', ':'').$seconds.' '.__ngettext('sec', 'secs', $seconds, 'twitter-tools'):''; } } } elseif ($minutes > 0) { // minutes only $relative_date .= ($relative_date?', ':'').$minutes.' '.__ngettext('min', 'mins', $minutes, 'twitter-tools'); if ($precision == 1) { $relative_date .= $seconds>0?($relative_date?', ':'').$seconds.' '.__ngettext('sec', 'secs', $seconds, 'twitter-tools'):''; } } else { // seconds only $relative_date .= ($relative_date?', ':'').$seconds.' '.__ngettext('sec', 'secs', $seconds, 'twitter-tools'); } } // Return relative date and add proper verbiage return sprintf(__('%s ago', 'twitter-tools'), $relative_date); } ?>