PageRenderTime 209ms CodeModel.GetById 101ms app.highlight 48ms RepoModel.GetById 52ms app.codeStats 1ms

/wp-content/plugins/retweet-anywhere/retweet-anywhere.php

https://bitbucket.org/openfarmtech/weblog-content
PHP | 538 lines | 409 code | 56 blank | 73 comment | 45 complexity | 7d8e702f9e113ade221dea66b550ce43 MD5 | raw file
  1<?php
  2/*
  3Plugin Name: Retweet Anywhere
  4Plugin URI: http://kovshenin.com/wordpress/plugins/retweet-anywhere/
  5Description: Retweet Anywhere for WordPress is a nice and easy way to allow your readers to instantly retweet your blog posts through their Twitter accounts
  6Author: Konstantin Kovshenin
  7Version: 0.1.2
  8Author URI: http://kovshenin.com/
  9
 10	License
 11
 12    Retweet Anywhere
 13    Copyright (C) 2010 Konstantin Kovshenin (kovshenin@live.com)
 14
 15    This program is free software: you can redistribute it and/or modify
 16    it under the terms of the GNU General Public License as published by
 17    the Free Software Foundation, either version 3 of the License, or
 18    (at your option) any later version.
 19
 20    This program is distributed in the hope that it will be useful,
 21    but WITHOUT ANY WARRANTY; without even the implied warranty of
 22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 23    GNU General Public License for more details.
 24
 25    You should have received a copy of the GNU General Public License
 26    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 27    
 28*/
 29
 30// JSON services for PHP4
 31if(!function_exists('json_encode'))
 32{
 33	include_once('json.php');
 34	$GLOBALS['JSON_OBJECT'] = new Services_JSON();
 35	function json_encode($value)
 36	{
 37		return $GLOBALS['JSON_OBJECT']->encode($value); 
 38	}
 39	
 40	function json_decode($value)
 41	{
 42		return $GLOBALS['JSON_OBJECT']->decode($value); 
 43	}
 44}
 45
 46class RetweetAnywhereWidget extends WP_Widget {
 47	function RetweetAnywhereWidget()
 48	{
 49		$widget_ops = array('classname' => 'widget-retweet-anywhere', 'description' => __("A retweet widget for your blog"));
 50		$this->WP_Widget('widget-retweet-anywhere', __('Retweet Anywhere'), $widget_ops);
 51	}
 52	
 53	function widget($args, $instance)
 54	{
 55		extract($args);
 56		$title = apply_filters('widget_title', $instance['title']);
 57		$format = $instance['format'];
 58		$width = $instance['width'];
 59		$height = $instance['height'];
 60		
 61		global $wp_query;
 62		if ($wp_query->in_the_loop || is_singular())
 63		{
 64			global $post;
 65			$post_id = $post->ID;
 66		}
 67		else
 68			$post_id = 0;
 69		
 70		echo $before_widget;
 71
 72		echo "<div class='retweet-anywhere-widget-box'>
 73			<style>.retweet-anywhere-widget-box em {display: none;}</style>
 74			<em class='post_id'>{$post_id}</em>
 75			<em class='title'>{$title}</em>
 76			<em class='format'>{$format}</em>
 77			<em class='width'>{$width}</em>
 78			<em class='height'>{$height}</em>
 79		</div>";
 80		
 81		echo $after_widget;
 82	}
 83	
 84	function update($new_instance, $old_instance)
 85	{
 86		return $new_instance;
 87	}
 88	
 89	function form($instance)
 90	{
 91		$instance = wp_parse_args((array) $instance, array('title' => 'Retweet', 'format' => '%s %l', 'width' => '200', 'height' => '70'));
 92		$title = $instance['title'];
 93		$format = $instance['format'];
 94		$width = $instance['width'];
 95		$height = $instance['height'];
 96?>
 97<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></label></p>
 98<p><label for="<?php echo $this->get_field_id('format'); ?>"><?php _e('Format:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('format'); ?>" name="<?php echo $this->get_field_name('format'); ?>" type="text" value="<?php echo esc_attr($format); ?>" /></label><br /><span class="description">Described in the <a href="http://kovshenin.com/wordpress/plugins/retweet-anywhere/#faq">FAQ</a></span></p>
 99<p><label for="<?php echo $this->get_field_id('width'); ?>"><?php _e('Width (in px):'); ?> <input class="widefat" id="<?php echo $this->get_field_id('width'); ?>" name="<?php echo $this->get_field_name('width'); ?>" type="text" value="<?php echo esc_attr($width); ?>" /></label></p>
100<p><label for="<?php echo $this->get_field_id('height'); ?>"><?php _e('Height (in px):'); ?> <input class="widefat" id="<?php echo $this->get_field_id('height'); ?>" name="<?php echo $this->get_field_name('height'); ?>" type="text" value="<?php echo esc_attr($height); ?>" /></label></p>
101<?php
102	}
103}
104
105// Main Retweet Anywhere class
106class RetweetAnywhere {
107
108	// Settings
109	var $settings = array();
110	var $default_settings = array();
111	var $shorteners = array();
112	
113	// Admin notices
114	var $notices = array();
115
116	function RetweetAnywhere()
117	{
118		// Default plugin settings
119		$this->default_settings = array(
120			"title" => "Retweet This Post",
121			"format" => "%s %l",
122			"shortener" => "none",
123			"placement" => "end",
124			"style" => "default",
125			"opacity" => "0.5",
126			"widget" => "no",
127		);
128		
129		// Load the plugin settings and merge with defaults
130		$this->settings = (array) get_option("retweet-anywhere");
131		$this->settings = array_merge($this->default_settings, $this->settings);
132		
133		// Action hooks
134		add_action("wp_enqueue_scripts", array(&$this, "wp_enqueue_scripts"));
135		
136		// AJAX hooks to get message
137		add_action("wp_ajax_rta_getmessage", array(&$this, "ajax_getmessage"));
138		add_action("wp_ajax_nopriv_rta_getmessage", array(&$this, "ajax_getmessage"));
139		
140		// Admin system customization (menus, notices, etc)
141		add_action("admin_menu", array(&$this, "admin_menu"));
142		add_action("admin_init", array(&$this, "admin_init"));
143		add_action("admin_notices", array(&$this, "admin_notices"));
144		
145		// Shortcode and content filters
146		if ($this->settings["placement"] != "manual")
147			add_filter("the_content", array(&$this, "the_content"));
148		add_shortcode("retweet-anywhere", array(&$this, "shortcode"));
149		
150		// Enable the shortcode for widget text if set in the settings
151		if ($this->settings["widget"] == "yes")
152		{
153			add_filter("widget_text", "do_shortcode");
154		}
155		
156		// Administration notices
157		if (empty($this->settings["api_key"]))
158			$this->notices[] = "Please configure your Twitter API key in order to use Retweet Anywhere: <a href='options-general.php?page=retweet-anywhere/retweet-anywhere.php'>Plugin Settings</a>";
159		if ($this->settings["shortener"] == "bitly" && (empty($this->settings["bitly_username"]) || empty($this->settings["bitly_api_key"])))
160			$this->notices[] = "Bit.ly requires a username and a valid API key in order to work. <a href='options-general.php?page=retweet-anywhere/retweet-anywhere.php'>Plugin Settings</a>";
161	}
162	
163	// Widget registration
164	function widgets_init()
165	{
166		register_widget("RetweetAnywhereWidget");
167	}
168	
169	// Settings management
170	function admin_init()
171	{
172		register_setting('retweet-anywhere', 'retweet-anywhere');
173	}
174	
175	// Plugin settings page
176	function admin_menu()
177	{
178		$page = add_submenu_page('options-general.php', 'Retweet Anywhere Settings', 'Retweet Anywhere', 'administrator', __FILE__, array(&$this, "settings_page"));
179		add_action("admin_print_scripts-{$page}", array(&$this, "admin_print_scripts"));
180	}
181	
182	// Admin panel scripts
183	function admin_print_scripts()
184	{
185		wp_enqueue_script("retweet-anywhere-admin", plugins_url("/js/admin.js", __FILE__), array("jquery"));
186	}
187	
188	// Settings page content
189	function settings_page()
190	{
191?>
192<div class="wrap">
193<h2>Retweet Anywhere Settings</h2>
194
195<form method="post" action="options.php">
196<?php
197	// Nonce fields and settings
198	wp_nonce_field('update-options');
199	settings_fields('retweet-anywhere');
200?>
201
202	<h3>General</h3>
203	<p class="description">These are the general settings used by the Retweet Anywhere plugin. Make sure you get the Twitter API key correct.</p>
204	<table class="form-table">
205		<tr valign="top">
206			<th scope="row">Twitter API Key</th>
207			<td><input type="text" class="regular-text" name="retweet-anywhere[api_key]" value="<?php echo $this->settings["api_key"]; ?>" /> <span class="description">The Twitter API key (<a href="http://kovshenin.com/wordpress/plugins/retweet-anywhere/#faq">How do I get one?</a>)</span></td>
208		</tr>
209		<tr valign="top">
210			<th scope="row">Popup Title</th>
211			<td><input type="text" class="regular-text" name="retweet-anywhere[title]" value="<?php echo $this->settings["title"]; ?>" /> <span class="description">Title goes above your tweet box, eg <code>Retweet This Post</code>.</span></td>
212		</tr>
213		<tr valign="top">
214			<th scope="row">Retweet Format</th>
215			<td><input type="text" class="regular-text" name="retweet-anywhere[format]" value="<?php echo $this->settings["format"]; ?>" /> <span class="description">The message format, eg: <code>%s %l (via @kovshenin)</code> described in the <a href="http://kovshenin.com/wordpress/plugins/retweet-anywhere/#faq">FAQ</a>.</span></td>
216		</tr>
217		<tr valign="top">
218			<th scope="row">Enable Widget Shortcode</th>
219			<?php $checked = ($this->settings["widget"] == "yes") ? 'checked="checked"' : ''; ?>
220			<td><input type="checkbox" name="retweet-anywhere[widget]" <?php echo $checked; ?> value="yes" /> <span class="description">If you're planning to use the shortcode in your text widgets, enable this.</span></td>
221			<?php unset($checked); ?>
222		</tr>
223
224	</table>
225	
226	<br /><h3>URL Shortening</h3>
227	<p class="description">Pick your favorite shortening service and provide us with your account details.</p>
228	<table class="form-table">
229		<tr valign="top">
230			<th scope="row">URL Shortener</th>
231			<td>
232				<?php
233					$selected[$this->settings["shortener"]] = 'selected="selected"';
234				?>
235					<select name="retweet-anywhere[shortener]" id="rta-shortener">
236						<option value="none" <?php echo @$selected["none"]; ?>>Don't shorten</option>
237						<option value="bitly" <?php echo @$selected["bitly"]; ?>>Bit.ly</option>
238						<?php							
239						// Additional shorteners							
240						$this->shorteners = apply_filters('retweet-anywhere-shorteners', $this->shorteners);
241						if ($this->shorteners)
242							foreach ($this->shorteners as $key => $shortener)
243								echo '<option value="' . $key . '" ' . @$selected[$key] . '>' . $shortener['name'] . '</option>';
244						?>
245					</select>
246				<?php
247					unset($selected);
248				?>
249				<span class="description">Pick your favorite URL shortener</span>
250			</td>
251		</tr>
252		<tr valign="top">
253			<th scope="row">Bit.ly Username</th>
254			<td><input type="text" class="regular-text rta-bitly" name="retweet-anywhere[bitly_username]" value="<?php echo $this->settings["bitly_username"]; ?>" /> <span class="description">A valid bit.ly account username (<a href="http://bit.ly/account/register">Register for a bit.ly account</a>)</span></td>
255		</tr>
256		<tr valign="top">
257			<th scope="row">Bit.ly API Key</th>
258			<td><input type="text" class="regular-text rta-bitly" name="retweet-anywhere[bitly_api_key]" value="<?php echo $this->settings["bitly_api_key"]; ?>" /> <span class="description">Your bit.ly API key (<a href="http://bit.ly/account/your_api_key/">Where do I find it?</a>)</span></td>
259		</tr>
260	</table>
261
262	<br /><h3>Look &amp; Feel</h3>
263	<p class="description">Customize the look and feel of your retweet button.</p>
264	<table class="form-table">
265		<tr valign="top">
266			<th scope="row">Placement</th>
267			<td>
268			<?php
269				$selected[$this->settings["placement"]] = 'selected="selected"';
270			?>
271				<select name="retweet-anywhere[placement]">
272					<option value="beginning" <?php echo @$selected["beginning"]; ?>>Beginning of post</option>
273					<option value="end" <?php echo @$selected["end"]; ?>>End of post</option>
274					<option value="manual" <?php echo @$selected["manual"]; ?>>Manual (PHP or Shortcode)</option>
275				</select>
276			<?php
277				unset($selected);
278			?>
279				<span class="description">Select where you'd like your retweet button to appear. Details described in the <a href="http://kovshenin.com/wordpress/plugins/retweet-anywhere/#faq">FAQ</a>.</span>
280			</td>
281		</tr>
282		<tr valign="top">
283			<th scope="row">Button Style</th>
284			<td>
285			<?php
286				$selected[$this->settings["style"]] = 'selected="selected"';
287			?>
288				<select name="retweet-anywhere[style]" id="rta-style">
289					<option value="default" <?php echo @$selected["default"]; ?>>Default</option>
290					<option value="text" <?php echo @$selected["text"]; ?>>Default Text</option>
291					<option value="html" <?php echo @$selected["html"]; ?>>Custom HTML</option>
292				</select>
293			<?php
294				unset($selected);
295			?>
296				<span class="description">This is a tricky one, default is a blue button, default text is simply a <code>Retweet</code> link. Use custom HTML to write your own.</span>
297			</td>
298		</tr>
299		<tr valign="top">
300			<th scope="row">Custom HTML</th>
301			<td><input type="text" class="regular-text rta-style-html" name="retweet-anywhere[style_html]" value="<?php echo htmlspecialchars($this->settings["style_html"]); ?>" /> <span class="description">Do not include the <code>&lt;a&gt; &lt;/a&gt;</code> tags, they're done for you. Write only what's inside.</span></td>
302		</tr>
303		<tr valign="top">
304			<th scope="row">Background Opacity</th>
305			<td>
306			<?php
307				$selected[$this->settings["opacity"]] = 'selected="selected"';
308			?>
309				<select name="retweet-anywhere[opacity]">
310					<option value="0.9" <?php echo @$selected["0.9"]; ?>>90% Black</option>
311					<option value="0.5" <?php echo @$selected["0.5"]; ?>>50% Black</option>
312					<option value="0.2" <?php echo @$selected["0.2"]; ?>>20% Black</option>
313					<option value="0" <?php echo @$selected["0"]; ?>>0% Black (No Fill)</option>
314				</select>
315			<?php
316				unset($selected);
317			?>
318				<span class="description">It's sometimes a good idea to fade the background so that retweeters could concentrate on the "Tweet" button ;)</span>
319			</td>
320		</tr>
321	</table>
322	<input type="hidden" name="action" value="update" />
323	<input type="hidden" name="page_options" value="retweet-anywhere[]" />
324	<p class="submit">
325		<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
326	</p>
327</form>
328</div>
329<?php
330	}
331
332	// the_content filter
333	function the_content($content)
334	{
335		// Let's see where we'd like to place the retweet button
336		switch ($this->settings["placement"])
337		{
338			case "beginning":
339				$content = "[retweet-anywhere]\r\n" . $content;
340				break;
341			case "end":
342				$content = $content . "\r\n[retweet-anywhere]";
343				break;
344		}
345
346		return $content;
347	}
348
349	// Shortcode
350	function shortcode($atts)
351	{
352		// Extract the attributes
353		extract(shortcode_atts(array(
354			"html" => false,
355			"format" => false,
356			"title" => false,
357		), $atts));
358
359		if (!$html) $html = $this->get_button();
360		if (!$format) $format = "";
361		if (!$title) $title = $this->settings["title"];
362		$message = '';
363		
364		// Let's see if we're inside the loop
365		global $wp_query;
366		if ($wp_query->in_the_loop || is_singular())
367		{
368			global $post;
369			return '<a href="http://twitter.com/?status=' . urlencode($post->post_title . " " . $post->guid) . '" class="retweet-anywhere" title="' . $title . '" rev="' . $format . '" rel="' . $post->ID . '">' . $html . '</a>';
370		}
371		else
372		{
373			// Not inside the loop, link to the current page
374			return '<a href="http://twitter.com/?status=' . urlencode(get_bloginfo("title") . " " . get_bloginfo("home")) . '" class="retweet-anywhere" title="' . $title . '" rev="' . $format . '" rel="0">' . $html . '</a>';
375		}
376	}
377	
378	// Echo the button according to the style
379	function get_button()
380	{
381		switch ($this->settings["style"])
382		{
383			case "default":
384				return '<img src="' . plugins_url("/images/retweet.png", __FILE__) . '" alt="Retweet" />';
385				break;
386			case "text":
387				return 'Retweet';
388				break;
389			case "html":
390				return $this->settings["style_html"];
391				break;
392		}
393	}
394
395	function wp_enqueue_scripts()
396	{
397		wp_enqueue_style("facebox", plugins_url("/css/facebox.css", __FILE__));
398	
399		$api_key = $this->settings["api_key"];
400		wp_enqueue_script("twitter-anywhere", "http://platform.twitter.com/anywhere.js?id={$api_key}&v=1");
401		wp_enqueue_script("facebox", plugins_url("/js/facebox.js", __FILE__), array("jquery"));
402		wp_enqueue_script("retweet-anywhere", plugins_url("/js/retweet-anywhere.js", __FILE__), array("jquery", "facebox"));
403		wp_localize_script("retweet-anywhere", "RetweetAnywhere", array(
404			"ajaxurl" => admin_url('admin-ajax.php'),
405			"loadingImage" => plugins_url("/images/facebox/loading.gif", __FILE__),
406			"closeImage" => plugins_url("/images/facebox/closelabel.gif", __FILE__),
407			"opacity" => $this->settings["opacity"],
408			"title" => $this->settings["title"]
409		));
410	}
411
412	// The AJAX call to retrieve the message
413	function ajax_getmessage()
414	{
415		// Get all the details
416		$post_id = $_POST["post_id"];
417		$format = $_POST["format"];
418
419		if (empty($format))
420			$format = $this->settings["format"];
421			
422		// If we don't need %s or %l data then we don't query for the post
423		if (strpos($format, "%s") === false && strpos($format, "%l") === false)
424		{
425			$message = $format;
426		}
427		else
428		{
429			if ($post_id == 0)
430			{
431				// If the post_id is 0 then link to the homepage
432				$title = get_bloginfo("title");
433				$url = get_bloginfo("home");
434			}
435			else
436			{
437				// Get the post data
438				$post = get_post($post_id);
439				$title = $post->post_title;
440				$url = get_permalink($post_id);
441			}
442			
443			// Shorten the link if we need to
444			if ($this->settings["shortener"] == "bitly")
445				$url = $this->shorten($url, $post_id);
446			elseif ($this->settings['shortener'] != 'none')
447			{
448				$this->shorteners = apply_filters('retweet-anywhere-shorteners', $this->shorteners);
449				if (function_exists($this->shorteners[$this->settings['shortener']]['callback']))
450				{
451					$f = $this->shorteners[$this->settings['shortener']]['callback'];
452					$url = $f($url);
453				}
454			}
455			// Format the message
456			$replace = array(
457				"%s" => $title,
458				"%l" => $url
459			);
460
461			$message = str_replace(array_keys($replace), array_values($replace), $format);
462		}
463		
464		// Format the response array
465		$response = array(
466			"message" => $message
467		);
468		
469		// JSON encode, print and die
470		echo json_encode($response);
471		die();
472	}
473	
474	// Shorten the URL via bit.ly
475	function shorten($url, $post_id = 0)
476	{
477		if ($post_id > 0)
478		{
479			$short = get_post_meta($post_id, 'rta-shorturl', true);
480			if (!empty($short))
481				return $short;
482		}
483
484		// Let's get the WP_Http class if we don't have one
485		if(!class_exists('WP_Http'))
486			include_once(ABSPATH . WPINC . '/class-http.php');
487		
488		// Encode the url
489		$url_encoded = urlencode($url);
490		
491		// Get the bit.ly settings
492		$bitly_login = urlencode(trim($this->settings["bitly_username"]));
493		$bitly_key = urlencode(trim($this->settings["bitly_api_key"]));
494		
495		// Init $http and fire the request
496		$http = new WP_Http();		
497		$result = $http->request("http://api.bit.ly/v3/shorten?login={$bitly_login}&apiKey={$bitly_key}&uri={$url_encoded}&format=json");
498		
499		if (gettype($result) == "object")
500			if (get_class($result) == "WP_Error")
501				return $url;
502				
503		// JSON decode the result body and return the data->url
504		$result = json_decode($result["body"]);
505		$result = $result->data;
506		$shorturl = $result->url;
507		
508		// Store the shortened URL
509		if (!empty($shorturl) && $post_id > 0)
510		{
511			$post = get_post($post_id);
512			//return print_r($post, true);
513			if ($post->post_status != 'draft' && $post->post_type != 'revision')
514				update_post_meta($post_id, 'rta-shorturl', $shorturl);
515		}
516		
517		return $shorturl;
518	}
519	
520	// Administration notices
521	function admin_notices()
522	{
523		$this->notices = array_unique($this->notices);
524		foreach($this->notices as $key => $value)
525		{
526			echo "<div id='rta-info' class='updated fade'><p><strong>Retweet Anywhere</strong>: " . $value . "</p></div>";
527		}
528	}
529}
530
531// Used for manual mode (PHP)
532function retweet_anywhere() {
533	echo do_shortcode("[retweet-anywhere]");
534}
535
536// Initialize the environment
537add_action("init", create_function('', 'global $RetweetAnywhere; $RetweetAnywhere = new RetweetAnywhere();'));
538add_action("widgets_init", create_function('', 'return register_widget("RetweetAnywhereWidget");'));