Advertisement
biranit

Blackbird Pie WP plugin modified

Dec 11th, 2011
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 19.85 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: Blackbird Pie
  4. Plugin URI: http://themergency.com/plugins/twitter-blackbird-pie/
  5. Description: MODIFIED!!!!!!! Add tweet visualizations to your site as can be found at http://media.twitter.com/blackbird-pie/.
  6. Version: 0.5.1
  7. Author: Brad Vincent
  8. Author URI: http://themergency.com
  9. License: GPL2
  10. */
  11.  
  12. class BlackbirdPie {
  13.  
  14.     /**
  15.      * Stores the Twitter handles for the users on the current blog.
  16.      */
  17.     var $handles = array();
  18.  
  19.     //constructor
  20.     function BlackbirdPie() {
  21.         define( 'BBP_NAME',  'blackbirdpie' );
  22.         define( 'BBP_REGEX', '/^(http|https):\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(\d+)$/' );
  23.         define( 'BBP_DIR', plugin_dir_path( __FILE__ ) );
  24.         define( 'BBP_URL', plugins_url( '/', __FILE__ ) );
  25.  
  26.         if(!class_exists('WP_Http'))
  27.             include_once(ABSPATH . WPINC . '/class-http.php');
  28.  
  29.         if (!is_admin()) {
  30.             //register shortcode
  31.             add_shortcode(BBP_NAME, array(&$this, 'shortcode'));
  32.             //register auto embed
  33.             wp_embed_register_handler( BBP_NAME, BBP_REGEX, array(&$this, 'blackbirdpie_embed_handler'), 10 );
  34.  
  35.             add_action( 'wp_head', array( &$this, 'embed_head'), -1 );
  36.         } else {
  37.             //setup twitter contact info in my profile screen
  38.             // add_filter( 'user_contactmethods', array(&$this, 'twitter_contactmethod'), 10, 1 );
  39.  
  40.             //setup WYSIWYG editor
  41.             $this->add_editor_button();
  42.         }
  43.     }
  44.  
  45.     /* function twitter_contactmethod( $contactmethods ) {
  46.         if ( empty( $contactmethods['twitter'] ) ) {
  47.             // Add Twitter
  48.             $contactmethods['twitter'] = 'Twitter';
  49.         }
  50.  
  51.         return $contactmethods;
  52.     } */
  53.  
  54.     /**
  55.      * Insert the neccessary Twitter JavaScript and CSS into HTML <head> if posts with twitter links exist.
  56.      * If tweets are present then queue the blackbird pie code.
  57.      *
  58.      * original code from twitter-blackbird-pie WordPress.com plugin
  59.      */
  60.     function embed_head() {
  61.         global $posts;
  62.  
  63.         if ( is_feed() || !is_array( $posts ) )
  64.             return;
  65.  
  66.         $load = false;
  67.         foreach ( $posts as $post ) {
  68.  
  69.             //first check if the post contains a blackbirdpie shortcode
  70.             if ( strpos( $post->post_content, '[blackbirdpie' ) >= 0 ) {
  71.                 $load = true;
  72.                 break;
  73.             }
  74.             else
  75.             //then check if the post contains a twitter link
  76.             if (  preg_match( '/(\n|\A)http(s|):\/\/twitter\.com(\/\#\!\/|\/)([a-zA-Z0-9_]{1,20})\/status(es)*\/(\d+)(\/|)/i', $post->post_content ) ) {
  77.                 $load = true;
  78.                 break;
  79.             }
  80.         }
  81.  
  82.         if ( $load ) {
  83.             add_action( 'wp_enqueue_scripts', array( &$this, 'load_scripts'), 20 );
  84.             add_action( 'wp_print_styles', array( &$this, 'load_styles'), 20 );
  85.  
  86.             /* if ( function_exists('get_user_meta') ) {
  87.  
  88.                 if ( ! $handles_cache = wp_cache_get( 'twitter-handles' ) ) {
  89.  
  90.                     if ( function_exists('get_users') ) {
  91.                         $users = get_users();
  92.                     } else {
  93.                         $users = get_users_of_blog();
  94.                     }
  95.  
  96.                     foreach ( $users as $user ) {
  97.                         $user_id = intval( $user->ID );
  98.                         $handle = get_user_meta( $user_id, 'twitter', true );
  99.                         if ( !empty( $handle ) )
  100.                             $this->handles[$user_id] = str_replace( 'http://twitter.com/', '', $handle );
  101.                     }
  102.  
  103.                     wp_cache_set( 'twitter-handles', $this->handles );
  104.                 } else {
  105.                     $this->handles = $handles_cache;
  106.                 }
  107.  
  108.             } */
  109.         }
  110.  
  111.         return;
  112.     }
  113.  
  114.     /**
  115.      * Loads the javascript needed by Twitter Blackbird Pie for loading the reply, retweet and favorite scripts
  116.      *
  117.      * original code from twitter-blackbird-pie WordPress.com plugin
  118.      */
  119.     function load_scripts() {
  120.         wp_register_script( BBP_NAME . '-js', BBP_URL . 'js/blackbirdpie.js',  array(), '20110404' );
  121.         wp_enqueue_script( BBP_NAME . '-js' );
  122.     }
  123.  
  124.     /**
  125.      * Loads the CSS needed by Twitter Blackbird Pie for the CSS sprites
  126.      *
  127.      * original code from twitter-blackbird-pie WordPress.com plugin
  128.      */
  129.     function load_styles() {
  130.         wp_register_style( BBP_NAME . '-css', BBP_URL . 'css/blackbirdpie.css',  array(), '20110416' );
  131.         wp_enqueue_style( BBP_NAME . '-css' );
  132.     }
  133.    
  134.     function add_editor_button() {
  135.         // Don't bother doing this stuff if the current user lacks permissions
  136.         if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
  137.             return;
  138.  
  139.         // Add only in Rich Editor mode
  140.         if ( get_user_option('rich_editing') == 'true' ) {
  141.             add_filter( 'mce_external_plugins', array(&$this, 'add_myplugin_tinymce_plugin') );
  142.             add_filter( 'teeny_mce_buttons', array(&$this, 'register_myplugin_button') );
  143.             add_filter( 'mce_buttons', array(&$this, 'register_myplugin_button') );
  144.         }
  145.     }
  146.    
  147.     function register_myplugin_button($buttons) {
  148.         array_push($buttons, 'separator', BBP_NAME);
  149.         return $buttons;
  150.     }
  151.      
  152.     // Load the TinyMCE plugin : editor_plugin.js (wp2.5)
  153.     function add_myplugin_tinymce_plugin($plugin_array) {
  154.         $plugin_array[BBP_NAME] = BBP_URL . 'tinymce/editor_plugin_blackbirdpie.js';
  155.         return $plugin_array;
  156.     }
  157.    
  158.     /*
  159.      * Calculates a textual representation of how long ago a date was.
  160.      * Supports "less than a minute ago", "1 minute ago or x minutes ago", and "about 1 hour ago" or "about x hours ago".
  161.      * If the date is older then this then we just display the date format according to the WordPress blog
  162.      *
  163.      * Based on ago() from Blackbird Pie v 0.3.2 and http://www.php.net/manual/en/function.time.php#96097
  164.      *
  165.      * code from WordPress.com blackbird pie plugin
  166.      *
  167.      * @param string $date The past date we are calculting the text string for
  168.      * @return string The textual representation of the date
  169.      */
  170.     function how_long_ago( $date ) {
  171.         $current = time();
  172.         $difference = $current - $date;
  173.  
  174.         if ( strtotime( '-1 min', $current ) < $date)
  175.             $output = 'less than a minute ago';
  176.         elseif ( strtotime( '-1 hour', $current ) < $date )
  177.             $output = ( floor($difference / 60 ) == 1 ) ? '1 minute ago' : floor( $difference / 60 ) . ' minutes ago';
  178.         elseif ( strtotime( '-1 day', $current ) < $date )
  179.             $output = ( floor( $difference / 60 / 60 ) == 1 ) ? 'about 1 hour ago' : 'about ' . floor( $difference / 60 / 60 ) . ' hours ago';
  180.         else
  181.             $output = date( get_option('date_format') . ' ' . get_option( 'time_format' ), ( $date + ( get_option('gmt_offset') * 3600 ) ) );
  182.  
  183.         return $output;
  184.     }
  185.    
  186.     function shortcode($atts) {
  187.  
  188.         // Extract the attributes
  189.         extract(shortcode_atts(array(
  190.             "id" => false,
  191.             "url" => false
  192.         ), $atts));
  193.  
  194.         //extract the status ID from $id (incase someone incorrectly used a shortcode like [blackbirdpie id="http://twitter..."])
  195.         if ($id) {
  196.             if (preg_match(BBP_REGEX, $id, $matches)) {
  197.                 $id = $matches[4];
  198.             }
  199.         }
  200.  
  201.         //extract the status ID from $url
  202.         if ($url) {
  203.             if (preg_match(BBP_REGEX, $url, $matches)) {
  204.                 $id = $matches[4];
  205.             }
  206.         }
  207.  
  208.         if ($id) {
  209.  
  210.             //are we inside the loop?
  211.             global $wp_query;
  212.             if ($wp_query->in_the_loop) {
  213.                 global $post;
  214.                 $post_id = $post->ID;
  215.             }
  216.  
  217.             if ($post_id > 0) {
  218.                 //try and get the tweet data from the post
  219.                 $args = get_post_meta( $post_id, '_'.BBP_NAME.'-'.$id );
  220.             }
  221.  
  222.             if ( empty($args) ) {
  223.                 //we need to get the tweet json data from twitter API
  224.                 $data = $this->get_tweet_details($id);
  225.  
  226.                 if ( !empty($data->text) ) {
  227.  
  228.                     //fix for non english tweets
  229.                     $data->text = addslashes($this->UTF8entities($data->text));
  230.                     $data->user->screen_name = addslashes($this->UTF8entities($data->user->screen_name));
  231.                     $data->user->name = addslashes($this->UTF8entities($data->user->name));
  232.  
  233.                     $timeStamp = strtotime($data->created_at);
  234.  
  235.                     $args = array(
  236.                         'id' => $id,
  237.                         'screen_name' => stripslashes($data->user->screen_name),
  238.                         'real_name' => stripslashes($data->user->name),
  239.                         'tweet_text' => stripslashes($this->autolink($data->text)),
  240.                         'source' => $data->source,
  241.  
  242.                         'profile_pic' => $data->user->profile_image_url,
  243.                         'profile_bg_color' => $data->user->profile_background_color,
  244.                         'profile_bg_tile' => $data->user->profile_background_tile,
  245.                         'profile_bg_image' => $data->user->profile_background_image_url,
  246.                         'profile_text_color' => $data->user->profile_text_color,
  247.                         'profile_link_color' => $data->user->profile_link_color,
  248.  
  249.                         'time_stamp' => $timeStamp,
  250.                         'utc_offset' => $data->user->utc_offset
  251.                     );
  252.  
  253.                     // save the tweet JSON data into a custom field
  254.                     if ($post_id > 0) {
  255.                         update_post_meta($post_id, '_'.BBP_NAME.'-'.$id, $args);
  256.                     }
  257.                 } //endif http_code == "200"
  258.                 else {
  259.                     return 'There was a problem connecting to Twitter.';
  260.                 }
  261.             } //endif $args is set
  262.             else {
  263.                 $args = $args[0];
  264.             }
  265.            
  266.             if ( !has_filter('bbp_create_tweet') )
  267.                 add_filter('bbp_create_tweet', array( &$this, 'create_tweet_html' ));
  268.  
  269.             return apply_filters('bbp_create_tweet', $args);
  270.         }
  271.  
  272.         return 'There was a problem with the blakbirdpie shortcode';
  273.     }
  274.  
  275.     function create_tweet_html( $tweet_details, $options = array()) {
  276.         global $post;
  277.        
  278.         /* PROFILE DATA */
  279.         $name = $tweet_details['screen_name'];                      //the twitter username
  280.         $real_name = $tweet_details['real_name'];                   //the user's real name
  281.         $profile_pic = esc_url($tweet_details['profile_pic']);      //url to the profile image
  282.         if ( !$tweet_details['profile_bg_tile'] )
  283.             $profile_bg_tile_HTML = " background-repeat:no-repeat"; //profile background tile
  284.         $profile_link_color = $tweet_details['profile_link_color']; //link color
  285.         $profile_text_color = $tweet_details['profile_text_color']; //text color
  286.         $profile_bg_color = $tweet_details['profile_bg_color'];     //background color
  287.         $profile_bg_image = esc_url($tweet_details['profile_bg_image']);     //background image
  288.         $profile_url = esc_url("http://twitter.com/intent/user?screen_name={$name}"); //the URL to the twitter profile
  289.  
  290.         /* GENERAL INFO */
  291.         $id = $tweet_details['id'];                                     //id of the actual tweet
  292.         $url = esc_url( "http://twitter.com/#!/{$name}/status/{$id}" ); //the URL to the tweet on twitter.com
  293.  
  294.         /* TIME INFO */
  295.         $time = $tweet_details['time_stamp'];                       //the time of the tweet
  296.         $date = date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ),
  297.                 $time + ( get_option('gmt_offset') * 3600 )  );     //the local time based on the GMT offset
  298.         $time_ago = $this->how_long_ago( $time );                   //the friendly version of the time e.g. "1 minute ago"
  299.  
  300.         /* SOURCE of the tweet */
  301.         $source = $tweet_details['source'];
  302.         preg_match( '`<a href="(http(s|)://[\w#!$&+,\/:;=?@.-]+)[^\w#!$&+,\/:;=?@.-]*?" rel="nofollow">(.*?)</a>`i', $source, $matches );
  303.         if( ! empty( $matches[1] ) || ! empty( $matches[3]) )
  304.             $source = '<a href="' . esc_url( $matches[1] ). '" rel="nofollow" target="blank">' . esc_html( $matches[3] ) . '</a>';
  305.         else
  306.             $source = esc_html( $source );
  307.  
  308.         //the plugin's base URL
  309.         $base_url = BBP_URL;
  310.  
  311.         // Tweet Action Urls
  312.         $retweet_url = esc_url( "https://twitter.com/intent/retweet?tweet_id={$id}" );
  313.         $reply_url = esc_url( "https://twitter.com/intent/tweet?in_reply_to={$id}" );
  314.         $favorite_url = esc_url( "https://twitter.com/intent/favorite?tweet_id={$id}" );
  315.  
  316.         // If we have a Twitter handle for this post author then we can mark them as 'related' to this tweet
  317.         /* if ( !empty ( $this->handles[$post->post_author] ) ) {
  318.             $retweet_url .= "&related=" . $this->handles[$post->post_author];
  319.             $reply_url .= "&related=" . $this->handles[$post->post_author];
  320.             $favorite_url .= "&related=" . $this->handles[$post->post_author];
  321.         } */
  322.  
  323.         $tweet = $tweet_details['tweet_text'];
  324.        
  325.         $tweetHTML = "<!-- tweet id : $id -->
  326.        
  327.        <div id='bbpBox_$id' class='bbpBox' style='clear:both;background-color:#fafafa;border:1px solid #e6e6e6;border-radius:5px;-moz-border-radius:5px; -webkit-border-radius:5px;'>
  328.            <div style='padding:10px;min-height:48px;color:#787878;'>
  329.                <div style='float:left;padding:0;margin:0 10px 10px 0;'>
  330.                    <a href='{$profile_url}'>
  331.                        <img style='width:48px;height:48px;padding-right:7px;border:none;background:none;margin:0' src='{$profile_pic}' />
  332.                    </a>
  333.                </div>
  334.                <div style='float:left;padding:0;margin:0;font-size:15px;'>
  335.                    <a style='font-weight:400' href='{$profile_url}'>@{$name}</a>
  336.                    <div style='margin:0;padding-top:7px;'>{$real_name}</div>
  337.                </div>
  338.                <div style='clear:both'></div>
  339.                <span style='width:100%;font-size:15px;line-height:140%;display:block;'>
  340.                    {$tweet}
  341.                </span>
  342.                <div class='bbp-actions' style='font-size:12px;width:100%;padding:5px 0 0;margin:10px 0 0;border-top:1px solid #e6e6e6;'>
  343.                    <img style='margin-bottom:-3px !important;margin-right:5px !important;' src='{$base_url}/images/bird.png' />
  344.                    <a title='tweeted on {$date}' href='{$url}' target='_blank'>{$time_ago}</a> via {$source}
  345.                    <a href='{$reply_url}' class='bbp-action bbp-reply-action' title='Reply'>
  346.                        <span><em style='margin-left:1em;margin-bottom:-2px;'></em><strong>Reply</strong></span>
  347.                    </a>
  348.                    <a href='{$retweet_url}' class='bbp-action bbp-retweet-action' title='Retweet'>
  349.                        <span><em style='margin-left:1em;margin-bottom:-2px;'></em><strong>Retweet</strong></span>
  350.                    </a>
  351.                    <a href='{$favorite_url}' class='bbp-action bbp-favorite-action' title='Favorite'>
  352.                        <span><em style='margin-left:1em;margin-bottom:-2px;'></em><strong>Favorite</strong></span>
  353.                    </a>
  354.                </div>
  355.                <div style='clear:both'></div>
  356.           </div>
  357.        </div>
  358.        
  359.        <!-- end of tweet -->";
  360.  
  361.         //remove any extra spacing and line breaks
  362.         $tweetHTML = preg_replace( '/\s*[\r\n\t]+\s*/', '', $tweetHTML );
  363.  
  364.         return $tweetHTML;
  365.     }
  366.  
  367.     /**
  368.      * Converts a normal line of text containing twitter functionality (@username, #hashtag)
  369.      * into a 'linked' line of text
  370.      * Supports @usernames, #hashtags, and @lists/lists.
  371.      * Normal auto linking of links is already handled by WordPress
  372.      *
  373.      * code from twitter-black-pie WordPress.com plugin
  374.      *
  375.      * @param string $tweet The text to convert
  376.      * @return string The linked text
  377.      */
  378.     function autolink( $tweet ) {
  379.         $tweet = make_clickable( $tweet );
  380.  
  381.         // Autolink hashtags (example: #wordpress will link to the search apge)
  382.         $tweet = preg_replace(
  383.                 '/(^|[^0-9A-Z&\/]+)(#|\xef\xbc\x83)([0-9A-Z_]*[A-Z_]+[a-z0-9_\xc0-\xd6\xd8-\xf6\xf8\xff]*)/iu',
  384.                 '${1}<a href="http://twitter.com/search?q=%23${3}" title="#${3}">${2}${3}</a>',
  385.                 $tweet
  386.         );
  387.  
  388.         // Autolink just usernames (example: @justinshreve)
  389.         $tweet = preg_replace(
  390.                 '/([^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',
  391.                 '${1}@<a href="http://twitter.com/intent/user?screen_name=${3}" class="twitter-action">${3}</a>',
  392.                 $tweet
  393.         );
  394.  
  395.         // Autolink lists (example: @justinshreve/wordpress-people)
  396.         $tweet = preg_replace(
  397.                 '$([@|@])([a-z0-9_]{1,20})(/[a-z][a-z0-9\x80-\xFF-]{0,79})?$i',
  398.                 '${1}<a href="http://twitter.com/${2}${3}">${2}${3}</a>',
  399.                 $tweet
  400.         );
  401.  
  402.         return $tweet;
  403.     }
  404.  
  405.     /*
  406.     found here : http://www.php.net/manual/en/function.htmlentities.php#92105
  407.     */
  408.     function UTF8entities($content) {
  409.         $contents = $this->unicode_string_to_array($content);
  410.         $swap = "";
  411.         $iCount = count($contents);
  412.         for ($o=0;$o<$iCount;$o++) {
  413.             $contents[$o] = $this->unicode_entity_replace($contents[$o]);
  414.             $swap .= $contents[$o];
  415.         }
  416.         if ( function_exists('mb_convert_encoding') )
  417.             return mb_convert_encoding( $swap, "UTF-8" ); //not really necessary, but why not.
  418.         else
  419.             return utf8_encode( $swap );
  420.     }
  421.  
  422.     function unicode_string_to_array( $string ) { //adjwilli
  423.         if ( function_exists('mb_strlen') )
  424.             $strlen = mb_strlen($string);
  425.         else
  426.             $strlen = strlen($string);
  427.         while ($strlen) {
  428.             $array[] = mb_substr( $string, 0, 1, "UTF-8" );
  429.             $string = mb_substr( $string, 1, $strlen, "UTF-8" );
  430.             if ( function_exists('mb_strlen') )
  431.                 $strlen = mb_strlen( $string );
  432.             else
  433.                 $strlen = strlen( $string );
  434.         }
  435.         return $array;
  436.     }
  437.  
  438.     function unicode_entity_replace($c) { //m. perez
  439.         $h = ord($c{0});    
  440.         if ($h <= 0x7F) {
  441.             return $c;
  442.         } else if ($h < 0xC2) {
  443.             return $c;
  444.         }
  445.        
  446.         if ($h <= 0xDF) {
  447.             $h = ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
  448.             $h = "&#" . $h . ";";
  449.             return $h;
  450.         } else if ($h <= 0xEF) {
  451.             $h = ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6 | (ord($c{2}) & 0x3F);
  452.             $h = "&#" . $h . ";";
  453.             return $h;
  454.         } else if ($h <= 0xF4) {
  455.             $h = ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12 | (ord($c{2}) & 0x3F) << 6 | (ord($c{3}) & 0x3F);
  456.             $h = "&#" . $h . ";";
  457.             return $h;
  458.         }
  459.     }  
  460.  
  461.     function get_tweet_details($id) {
  462.  
  463.         $request_url = "http://api.twitter.com/1/statuses/show.json?id={$id}";
  464.  
  465.         $request = new WP_Http;
  466.        
  467.         $result = $request->request($request_url);
  468.  
  469.         if (gettype($result) == "object" && get_class($result) == "WP_Error")
  470.             return NULL;
  471.  
  472.         return json_decode($result["body"]);
  473.     }
  474.  
  475.     function blackbirdpie_embed_handler( $matches, $attr, $url, $rawattr ) {
  476.         return $this->shortcode( array( 'url' => $url ) );
  477.     }
  478. }
  479.  
  480. if (!function_exists('json_decode')) {
  481.     function json_decode($content, $assoc=false) {
  482.         require_once ( dirname(__FILE__) . '/includes/json.php' );
  483.         if ($assoc) {
  484.             $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
  485.         }
  486.         else {
  487.             $json = new Services_JSON;
  488.         }
  489.         return $json->decode($content);
  490.     }
  491. }
  492.  
  493. add_action("init", create_function('', 'global $BlackbirdPie; $BlackbirdPie = new BlackbirdPie();'));
  494.  
  495. ?>
  496.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement