BitlyUrlPlugin.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. $params = http_build_query(array(
  107. 'login' => $this->getLogin(),
  108. 'apiKey' => $this->getApiKey()), '', '&');
  109. $serviceUrl = sprintf($this->serviceUrl, urlencode($url)) . '&' . $params;
  110. $request = HTTPClient::start();
  111. return $request->get($serviceUrl);
  112. }
  113. /**
  114. * JSON decode for API result
  115. */
  116. protected function decode($url, $response)
  117. {
  118. $msg = "bit.ly returned unknown response with unknown message for $url";
  119. if ($response->isOk()) {
  120. $body = $response->getBody();
  121. common_log(LOG_INFO, $body);
  122. $json = json_decode($body, true);
  123. if ($json['status_code'] == 200) {
  124. if (isset($json['data']['url'])) {
  125. common_log(LOG_INFO, "bit.ly returned ".$json['data']['url']." as short URL for $url");
  126. return $json['data']['url'];
  127. }
  128. $msg = "bit.ly returned ".$json['status_code']." response, but didn't find expected URL $url in $body";
  129. }else{
  130. $msg = "bit.ly returned ".$json['status_code']." response with ".$json['status_txt']." for $url";
  131. }
  132. }
  133. common_log(LOG_ERR, $msg);
  134. return null;
  135. }
  136. function onPluginVersion(array &$versions)
  137. {
  138. $versions[] = array('name' => sprintf('BitlyUrl (%s)', $this->shortenerName),
  139. 'version' => GNUSOCIAL_VERSION,
  140. 'author' => 'Craig Andrews, Brion Vibber',
  141. 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BitlyUrl',
  142. 'rawdescription' =>
  143. // TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly").
  144. sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'),
  145. $this->shortenerName));
  146. return true;
  147. }
  148. /**
  149. * Hook for RouterInitialized event.
  150. *
  151. * @param URLMapper $m path-to-action mapper
  152. * @return boolean hook return
  153. */
  154. public function onRouterInitialized(URLMapper $m)
  155. {
  156. $m->connect('panel/bitly',
  157. array('action' => 'bitlyadminpanel'));
  158. return true;
  159. }
  160. /**
  161. * If the plugin's installed, this should be accessible to admins.
  162. */
  163. function onAdminPanelCheck($name, &$isOK)
  164. {
  165. if ($name == 'bitly') {
  166. $isOK = true;
  167. return false;
  168. }
  169. return true;
  170. }
  171. /**
  172. * Add the bit.ly admin panel to the list...
  173. */
  174. function onEndAdminPanelNav($nav)
  175. {
  176. if (AdminPanelAction::canAdmin('bitly')) {
  177. $action_name = $nav->action->trimmed('action');
  178. $nav->out->menuItem(common_local_url('bitlyadminpanel'),
  179. // TRANS: Menu item in administration menus for bit.ly URL shortening settings.
  180. _m('bit.ly'),
  181. // TRANS: Title for menu item in administration menus for bit.ly URL shortening settings.
  182. _m('bit.ly URL shortening.'),
  183. $action_name == 'bitlyadminpanel',
  184. 'nav_bitly_admin_panel');
  185. }
  186. return true;
  187. }
  188. /**
  189. * Internal hook point to check the default global credentials so
  190. * the admin form knows if we have a fallback or not.
  191. *
  192. * @param string $login
  193. * @param string $apiKey
  194. * @return boolean hook return value
  195. */
  196. function onBitlyDefaultCredentials(&$login, &$apiKey)
  197. {
  198. $login = $this->login;
  199. $apiKey = $this->apiKey;
  200. return false;
  201. }
  202. }