BitlyUrlPlugin.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. /**
  3. * StatusNet, the distributed open-source microblogging tool
  4. *
  5. * Plugin to use bit.ly URL shortening services.
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category Plugin
  23. * @package StatusNet
  24. * @author Craig Andrews <candrews@integralblue.com>
  25. * @author Brion Vibber <brion@status.net>
  26. * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
  27. * @copyright 2010 StatusNet, Inc http://status.net/
  28. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  29. * @link http://status.net/
  30. */
  31. if (!defined('STATUSNET')) {
  32. exit(1);
  33. }
  34. class BitlyUrlPlugin extends UrlShortenerPlugin
  35. {
  36. public $shortenerName = 'bit.ly';
  37. public $serviceUrl = 'http://api.bit.ly/v3/shorten?longUrl=%s';
  38. public $login; // To set a site-default when admins or users don't override it.
  39. public $apiKey;
  40. function onInitializePlugin(){
  41. parent::onInitializePlugin();
  42. if(!isset($this->serviceUrl)){
  43. // TRANS: Exception thrown when bit.ly URL shortening plugin was configured incorrectly.
  44. throw new Exception(_m('You must specify a serviceUrl for bit.ly URL shortening.'));
  45. }
  46. }
  47. /**
  48. * Add bit.ly to the list of available URL shorteners if it's configured,
  49. * otherwise leave it out.
  50. *
  51. * @param array $shorteners
  52. * @return boolean hook return value
  53. */
  54. function onGetUrlShorteners(&$shorteners)
  55. {
  56. if ($this->getLogin() && $this->getApiKey()) {
  57. return parent::onGetUrlShorteners($shorteners);
  58. }
  59. return true;
  60. }
  61. /**
  62. * Short a URL
  63. * @param url
  64. * @return string shortened version of the url, or null if URL shortening failed
  65. */
  66. protected function shorten($url) {
  67. common_log(LOG_INFO, "bit.ly call for $url");
  68. $response = $this->query($url);
  69. common_log(LOG_INFO, "bit.ly answer for $url is ".$response->getBody());
  70. return $this->decode($url, $response);
  71. }
  72. /**
  73. * Get the user's or site-wide default bit.ly login name.
  74. *
  75. * @return string
  76. */
  77. protected function getLogin()
  78. {
  79. $login = common_config('bitly', 'default_login');
  80. if (!$login) {
  81. $login = $this->login;
  82. }
  83. return $login;
  84. }
  85. /**
  86. * Get the user's or site-wide default bit.ly API key.
  87. *
  88. * @return string
  89. */
  90. protected function getApiKey()
  91. {
  92. $key = common_config('bitly', 'default_apikey');
  93. if (!$key) {
  94. $key = $this->apiKey;
  95. }
  96. return $key;
  97. }
  98. /**
  99. * Inject API key into query before sending out...
  100. *
  101. * @param string $url
  102. * @return HTTPResponse
  103. */
  104. protected function query($url)
  105. {
  106. // http://code.google.com/p/bitly-api/wiki/ApiDocumentation#/shorten
  107. $params = http_build_query(array(
  108. 'login' => $this->getLogin(),
  109. 'apiKey' => $this->getApiKey()), '', '&');
  110. $serviceUrl = sprintf($this->serviceUrl, urlencode($url)) . '&' . $params;
  111. $request = HTTPClient::start();
  112. return $request->get($serviceUrl);
  113. }
  114. /**
  115. * JSON decode for API result
  116. */
  117. protected function decode($url, $response)
  118. {
  119. $msg = "bit.ly returned unknown response with unknown message for $url";
  120. if ($response->isOk()) {
  121. $body = $response->getBody();
  122. common_log(LOG_INFO, $body);
  123. $json = json_decode($body, true);
  124. if ($json['status_code'] == 200) {
  125. if (isset($json['data']['url'])) {
  126. common_log(LOG_INFO, "bit.ly returned ".$json['data']['url']." as short URL for $url");
  127. return $json['data']['url'];
  128. }
  129. $msg = "bit.ly returned ".$json['status_code']." response, but didn't find expected URL $url in $body";
  130. }else{
  131. $msg = "bit.ly returned ".$json['status_code']." response with ".$json['status_txt']." for $url";
  132. }
  133. }
  134. common_log(LOG_ERR, $msg);
  135. return null;
  136. }
  137. function onPluginVersion(&$versions)
  138. {
  139. $versions[] = array('name' => sprintf('BitlyUrl (%s)', $this->shortenerName),
  140. 'version' => GNUSOCIAL_VERSION,
  141. 'author' => 'Craig Andrews, Brion Vibber',
  142. 'homepage' => 'http://status.net/wiki/Plugin:BitlyUrl',
  143. 'rawdescription' =>
  144. // TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly").
  145. sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'),
  146. $this->shortenerName));
  147. return true;
  148. }
  149. /**
  150. * Hook for RouterInitialized event.
  151. *
  152. * @param URLMapper $m path-to-action mapper
  153. * @return boolean hook return
  154. */
  155. public function onRouterInitialized(URLMapper $m)
  156. {
  157. $m->connect('panel/bitly',
  158. array('action' => 'bitlyadminpanel'));
  159. return true;
  160. }
  161. /**
  162. * If the plugin's installed, this should be accessible to admins.
  163. */
  164. function onAdminPanelCheck($name, &$isOK)
  165. {
  166. if ($name == 'bitly') {
  167. $isOK = true;
  168. return false;
  169. }
  170. return true;
  171. }
  172. /**
  173. * Add the bit.ly admin panel to the list...
  174. */
  175. function onEndAdminPanelNav($nav)
  176. {
  177. if (AdminPanelAction::canAdmin('bitly')) {
  178. $action_name = $nav->action->trimmed('action');
  179. $nav->out->menuItem(common_local_url('bitlyadminpanel'),
  180. // TRANS: Menu item in administration menus for bit.ly URL shortening settings.
  181. _m('bit.ly'),
  182. // TRANS: Title for menu item in administration menus for bit.ly URL shortening settings.
  183. _m('bit.ly URL shortening.'),
  184. $action_name == 'bitlyadminpanel',
  185. 'nav_bitly_admin_panel');
  186. }
  187. return true;
  188. }
  189. /**
  190. * Internal hook point to check the default global credentials so
  191. * the admin form knows if we have a fallback or not.
  192. *
  193. * @param string $login
  194. * @param string $apiKey
  195. * @return boolean hook return value
  196. */
  197. function onBitlyDefaultCredentials(&$login, &$apiKey)
  198. {
  199. $login = $this->login;
  200. $apiKey = $this->apiKey;
  201. return false;
  202. }
  203. }