BitlyUrlPlugin.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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. const PLUGIN_VERSION = '2.0.0';
  37. public $shortenerName = 'bit.ly';
  38. public $serviceUrl = 'http://api.bit.ly/v3/shorten?longUrl=%s';
  39. public $login; // To set a site-default when admins or users don't override it.
  40. public $apiKey;
  41. function onInitializePlugin(){
  42. parent::onInitializePlugin();
  43. if(!isset($this->serviceUrl)){
  44. // TRANS: Exception thrown when bit.ly URL shortening plugin was configured incorrectly.
  45. throw new Exception(_m('You must specify a serviceUrl for bit.ly URL shortening.'));
  46. }
  47. }
  48. /**
  49. * Add bit.ly to the list of available URL shorteners if it's configured,
  50. * otherwise leave it out.
  51. *
  52. * @param array $shorteners
  53. * @return boolean hook return value
  54. */
  55. function onGetUrlShorteners(&$shorteners)
  56. {
  57. if ($this->getLogin() && $this->getApiKey()) {
  58. return parent::onGetUrlShorteners($shorteners);
  59. }
  60. return true;
  61. }
  62. /**
  63. * Short a URL
  64. * @param url
  65. * @return string shortened version of the url, or null if URL shortening failed
  66. */
  67. protected function shorten($url) {
  68. common_log(LOG_INFO, "bit.ly call for $url");
  69. $response = $this->query($url);
  70. common_log(LOG_INFO, "bit.ly answer for $url is ".$response->getBody());
  71. return $this->decode($url, $response);
  72. }
  73. /**
  74. * Get the user's or site-wide default bit.ly login name.
  75. *
  76. * @return string
  77. */
  78. protected function getLogin()
  79. {
  80. $login = common_config('bitly', 'default_login');
  81. if (!$login) {
  82. $login = $this->login;
  83. }
  84. return $login;
  85. }
  86. /**
  87. * Get the user's or site-wide default bit.ly API key.
  88. *
  89. * @return string
  90. */
  91. protected function getApiKey()
  92. {
  93. $key = common_config('bitly', 'default_apikey');
  94. if (!$key) {
  95. $key = $this->apiKey;
  96. }
  97. return $key;
  98. }
  99. /**
  100. * Inject API key into query before sending out...
  101. *
  102. * @param string $url
  103. * @return HTTPResponse
  104. */
  105. protected function query($url)
  106. {
  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. public function onPluginVersion(array &$versions): bool
  138. {
  139. $versions[] = array('name' => sprintf('BitlyUrl (%s)', $this->shortenerName),
  140. 'version' => self::PLUGIN_VERSION,
  141. 'author' => 'Craig Andrews, Brion Vibber',
  142. 'homepage' => GNUSOCIAL_ENGINE_REPO_URL . 'tree/master/plugins/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. ['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. }