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