Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

734 lines
22 KiB

  1. <?php
  2. /*
  3. Copyright (c) 2009, Beau Lebens
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without modification,
  6. are permitted provided that the following conditions are met:
  7. - Redistributions of source code must retain the above copyright notice, this
  8. list of conditions and the following disclaimer.
  9. - Redistributions in binary form must reproduce the above copyright notice,
  10. this list of conditions and the following disclaimer in the documentation
  11. and/or other materials provided with the distribution.
  12. - Neither the name of Dented Reality nor the names of the authors may be used
  13. to endorse or promote products derived from this software without specific
  14. prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22. ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. // Return options for Slinky_Service->url_get() and ->url_post()
  27. define( 'SLINKY_BODY', 1 ); // Default
  28. define( 'SLINKY_HEADERS', 2 ); // Not implemented yet
  29. define( 'SLINKY_FINAL_URL', 3 ); // Default for lengthening URLs
  30. // So that services may decide what to do with us
  31. define( 'SLINKY_USER_AGENT', 'Slinky v1.0 +http://dentedreality.com.au/projects/slinky/' );
  32. // How many seconds until remote requests should be cut?
  33. define( 'SLINKY_TIMEOUT', 10 );
  34. /**
  35. * Slinky allows you to go back and forth between "long" and shortened URLs
  36. * using popular URL shortening services.
  37. *
  38. * Slinky assumes you have cURL installed and working, and requires the JSON
  39. * extension installed if you're working with a service that uses JSON.
  40. *
  41. * Slinky will ONLY work with PHP5+
  42. *
  43. * It supports some of the more popular services, with easy extensibility for
  44. * adding your own relatively easily. It defaults to using TinyURL
  45. * for shortening URLs. If you want to use some of the other services, you need
  46. * to set some configuration options before actually shortening/lengthening
  47. * URLs. I'd strongly suggest that you cache results using memcached, a local
  48. * DB or whatever to avoid having to hit APIs etc every time you encounter a
  49. * URL.
  50. *
  51. * Slinky supports shortening, and auto-detection (for lengthening URLs)
  52. * using these services:
  53. * - Bit.ly
  54. * - Tr.im
  55. * - TinyURL
  56. * - Is.Gd
  57. * - Fon.gs
  58. * - Micurl.com
  59. * - ur1.ca
  60. * - Ptiturl
  61. * - Tighturl
  62. * - 2tu.us
  63. * - Snipr / Snipurl / Snurl.com / Sn.im
  64. *
  65. *
  66. * To use Slinky:
  67. *
  68. * $slinky = new Slinky( 'http://dentedreality.com.au/' );
  69. * - Creates a new Slinky instance, will default to using TinyURL for ->short();
  70. *
  71. * $slinky = new Slinky( 'http://dentedreality.com.au', new Slinky_Bitly() );
  72. * - Creates new Slinky, forces use of Bit.ly for ->short();
  73. *
  74. * $slinky = new Slinky( 'http://dentedreality.com.au/' );
  75. * echo $slinky->short();
  76. * - echos the short version of http://dentedreality.com.au/ (default to TinyURL)
  77. *
  78. * $slinky = new Slinky( 'http://tinyurl.com/jw5sh' );
  79. * echo $slinky->long();
  80. * - echos out the long version of http://tinyurl.com/jw5sh (which should be http://dentedreality.com.au/)
  81. *
  82. * $slinky = new Slinky( 'http://dentedreality.com.au/' );
  83. * echo $slinky->long();
  84. * - Attempts to lengthen the URL, but will not auto-detect which service it is
  85. * so it will just output the original URL. Useful for always attempting to
  86. * lengthen any URL you come across (fails gracefully)
  87. *
  88. * $slinky = new Slinky( 'http://dentedreality.com.au/' );
  89. * $slinky->set_cascade( array( new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) );
  90. * echo $slinky->short();
  91. * - Uses the powerful cascade mode to make sure that we get a short URL from
  92. * Tr.im, Is.Gd or TinyURL (in that order).
  93. *
  94. * See specific service class definitions below for examples of how to use them,
  95. * as some services allow (or require) additional properties before you can use
  96. * them (for authentication etc).
  97. *
  98. * To use a different service with Slinky, just create your own class and
  99. * extend Slinky_Service(). Make sure you implement url_is_short(), url_is_long(),
  100. * make_short() and make_long(). If you need to GET or POST a URL, you can use
  101. * ->url_get() and ->url_post(), which your class will have inherited.
  102. **/
  103. class Slinky {
  104. var $url = false;
  105. var $service = false;
  106. var $cascade = false;
  107. function __construct( $url = false, $service = false ) {
  108. $this->url = $url;
  109. $this->service = $service;
  110. }
  111. /**
  112. * Specify which URL Service to use
  113. *
  114. * @param Slinky_Service $service Packaged or custom Service object
  115. * @return void
  116. */
  117. public function set_service( $service = false ) {
  118. if ( is_object( $service ) ) {
  119. $this->service = $service;
  120. }
  121. }
  122. /**
  123. * If you pass an array of Slinky_Service objects to this method, they will
  124. * be used in order to try to get a short URL, so if one fails, it will
  125. * try the next and so on, until it gets a valid short URL, or it runs
  126. * out of options.
  127. *
  128. * @param array $services List of Slinky_Service objects as an array
  129. **/
  130. public function set_cascade( $services = false ) {
  131. if ( !$services || !is_array( $services ) )
  132. return false;
  133. $this->cascade = $services;
  134. }
  135. /**
  136. * Guess the URL service to use from known domains of short URLs
  137. *
  138. * @param string $url
  139. */
  140. public function set_service_from_url( $url = false ) {
  141. if ( !$url )
  142. $url = $this->url;
  143. $host = parse_url( $url, PHP_URL_HOST );
  144. switch ( str_replace( 'www.', '', $host ) ) {
  145. case 'bit.ly':
  146. if ( class_exists( 'Slinky_Bitly' ) ) {
  147. $this->service = new Slinky_Bitly();
  148. break;
  149. }
  150. case 'tr.im':
  151. if ( class_exists( 'Slinky_Trim' ) ) {
  152. $this->service = new Slinky_Trim();
  153. break;
  154. }
  155. case 'tinyurl.com':
  156. if ( class_exists( 'Slinky_TinyURL' ) ) {
  157. $this->service = new Slinky_TinyURL();
  158. break;
  159. }
  160. case 'is.gd':
  161. if ( class_exists( 'Slinky_IsGd' ) ) {
  162. $this->service = new Slinky_IsGd();
  163. break;
  164. }
  165. case 'fon.gs':
  166. if ( class_exists( 'Slinky_Fongs' ) ) {
  167. $this->service = new Slinky_Fongs();
  168. break;
  169. }
  170. case $this->get( 'yourls-url' ):
  171. if ( class_exists( 'Slinky_YourLS' ) ) {
  172. $this->service = new Slinky_YourLS();
  173. break;
  174. }
  175. case 'micurl.com':
  176. if ( class_exists( 'Slinky_Micurl' ) ) {
  177. $this->service = new Slinky_Micurl();
  178. break;
  179. }
  180. case 'ur1.ca':
  181. if ( class_exists( 'Slinky_Ur1ca' ) ) {
  182. $this->service = new Slinky_Ur1ca();
  183. break;
  184. }
  185. case 'ptiturl.com':
  186. if ( class_exists( 'Slinky_PtitURL' ) ) {
  187. $this->service = new Slinky_PtitURL();
  188. break;
  189. }
  190. case 'tighturl.com':
  191. case '2tu.us':
  192. if ( class_exists( 'Slinky_TightURL' ) ) {
  193. $this->service = new Slinky_TightURL();
  194. break;
  195. }
  196. case 'snipr.com':
  197. case 'snipurl.com':
  198. case 'snurl.com':
  199. case 'sn.im':
  200. if ( class_exists( 'Slinky_Snipr' ) ) {
  201. $this->service = new Slinky_Snipr();
  202. break;
  203. }
  204. default:
  205. $this->service = new Slinky_Default();
  206. break;
  207. }
  208. }
  209. /**
  210. * Take a long URL and make it short. Will avoid "re-shortening" a URL if it
  211. * already seems to be short.
  212. *
  213. * @param string $url Optional URL to shorten, otherwise use $this->url
  214. * @return The short version of the URL
  215. */
  216. public function short( $url = false ) {
  217. if ( $url )
  218. $this->url = $url;
  219. if ( !$this->service )
  220. $this->set_service( new Slinky_TinyURL() ); // Defaults to tinyurl because it doesn't require any configuration
  221. if ( !$this->cascade )
  222. $this->cascade = array( $this->service ); // Use a single service in cascade mode
  223. foreach ( $this->cascade as $service ) {
  224. if ( $service->url_is_short( $this->url ) )
  225. return trim( $this->url ); // Identified as already short, using this service
  226. $response = trim( $service->make_short( $this->url ) );
  227. if ( $response && $this->url != $response )
  228. return trim( $response );
  229. }
  230. return $this->url; // If all else fails, just send back the URL we already know about
  231. }
  232. /**
  233. * Take a short URL and make it long ("resolve" it).
  234. *
  235. * @param string $url The short URL
  236. * @return A long URL
  237. */
  238. public function long( $url = false ) {
  239. if ( $url )
  240. $this->url = $url;
  241. if ( !$this->service )
  242. $this->set_service_from_url();
  243. if ( $this->service->url_is_long( $this->url ) )
  244. return trim( $this->url );
  245. return trim( $this->service->make_long( $this->url ) );
  246. }
  247. }
  248. /**
  249. * Use this class to create a Service implementation for your own URL
  250. * shortening service. Extend the class and customize methods to suit your
  251. * service. Note that it is an "abstract" class, so there are certain methods
  252. * which you *must* define.
  253. **/
  254. abstract class Slinky_Service {
  255. /**
  256. * Determine, based on the input URL, if it's already a short URL, from
  257. * this particular service. e.g. a Bit.ly URL contains "bit.ly/"
  258. **/
  259. abstract function url_is_short( $url );
  260. /**
  261. * Determine if this is a "long" URL (just means it hasn't been shortened)
  262. * already. e.g. a no-Bit.ly URL would NOT contain "bit.ly/"
  263. **/
  264. abstract function url_is_long( $url );
  265. /**
  266. * Handle taking the $url and converting it to a short URL via whatever
  267. * means is provided at the remote service.
  268. **/
  269. abstract function make_short( $url );
  270. /**
  271. * Return the long/expanded version of a URL via any API means available
  272. * from this service. As a fallback, you might
  273. * consider just following the URL and using SLINKY_FINAL_URL as the
  274. * return method from a $this->url_get() call to find out.
  275. *
  276. * This one is optional for Services extending this class, if they don't
  277. * then the following implementation will work on most services anyway.
  278. **/
  279. public function make_long( $url ) {
  280. return $this->url_get( $url, SLINKY_FINAL_URL );
  281. }
  282. /**
  283. * Method for getting properties that you might need during the process
  284. * of shortening/lengthening a URL (e.g. auth credentials)
  285. **/
  286. public function get( $prop ) {
  287. if ( empty( $this->$prop ) )
  288. return null;
  289. return $this->$prop;
  290. }
  291. /**
  292. * Method for setting properties that you might need during the process
  293. * of shortening/lengthening a URL (e.g. auth credentials)
  294. **/
  295. public function set( $prop, $val ) {
  296. $this->$prop = $val;
  297. }
  298. /**
  299. * Internal helper for performing a GET request on a remote URL.
  300. *
  301. * @param string $url The URL to GET
  302. * @param const $return The return method [ SLINKY_BODY | SLINKY_FINAL_URL | SLINKY_HEADERS ]
  303. * @return Mixed, based on the $return var passed in.
  304. **/
  305. protected function url_get( $url, $return = SLINKY_BODY ) {
  306. $ch = curl_init( $url );
  307. curl_setopt( $ch, CURLOPT_USERAGENT, SLINKY_USER_AGENT );
  308. curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); // Don't stress about SSL validity
  309. curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); // Return the response, don't output it
  310. curl_setopt( $ch, CURLOPT_TIMEOUT, SLINKY_TIMEOUT ); // Limit how long we'll wait for a response
  311. //curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 ); // Allow following of redirections
  312. $r = curl_exec( $ch );
  313. if ( curl_errno( $ch ) ) {
  314. return false;
  315. }
  316. // Return whatever we were asked for
  317. if ( SLINKY_FINAL_URL == $return )
  318. return curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );
  319. else if ( SLINKY_BODY == $return )
  320. return $r;
  321. return false;
  322. }
  323. /**
  324. * Internal helper for performing a POST request on a remote URL.
  325. *
  326. * @param string $url The URL to POST to
  327. * @param array $payload Array containing name/value pairs of the parameters to POST
  328. * @param const $return The return method [ SLINKY_BODY | SLINKY_FINAL_URL | SLINKY_HEADERS ]
  329. * @return Mixed, based on the $return var passed in.
  330. **/
  331. protected function url_post( $url, $payload = array(), $return = SLINKY_BODY ) {
  332. $ch = curl_init( $url );
  333. curl_setopt( $ch, CURLOPT_POST, true );
  334. curl_setopt( $ch, CURLOPT_POSTFIELDS, (array) $payload );
  335. curl_setopt( $ch, CURLOPT_USERAGENT, SLINKY_USER_AGENT );
  336. curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); // Don't stress about SSL validity
  337. curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); // Return the response, don't output it
  338. curl_setopt( $ch, CURLOPT_TIMEOUT, SLINKY_TIMEOUT ); // Limit how long we'll wait for a response
  339. //curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 ); // Allow following of redirections
  340. $r = curl_exec( $ch );
  341. if ( curl_errno( $ch ) ) {
  342. return false;
  343. }
  344. // Return whatever we were asked for
  345. if ( SLINKY_FINAL_URL == $return )
  346. return curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );
  347. else if ( SLINKY_BODY == $return )
  348. return $r;
  349. return false;
  350. }
  351. }
  352. // This default service is used in cases when you try to do something based
  353. // on auto-detection, but we can't detect anything. It will also resolve URLs
  354. // to their "long" version by following all redirects.
  355. class Slinky_Default extends Slinky_Service {
  356. function url_is_short( $url ) {
  357. return false;
  358. }
  359. function url_is_long( $url ) {
  360. return false;
  361. }
  362. function make_short( $url ) {
  363. return $url;
  364. }
  365. }
  366. // Implementation of TinyURL as a Slinky Service
  367. class Slinky_TinyURL extends Slinky_Service {
  368. function url_is_short( $url ) {
  369. return stristr( $url, 'tinyurl.com/' );
  370. }
  371. function url_is_long( $url ) {
  372. return !stristr( $url, 'tinyurl.com/' );
  373. }
  374. function make_short( $url ) {
  375. return $this->url_get( 'http://tinyurl.com/api-create.php?url=' . urlencode( $url ) );
  376. }
  377. function make_long( $url ) {
  378. $bits = parse_url( $url );
  379. $result = $this->url_get( 'http://tinyurl.com/preview.php?num=' . substr( $bits['path'], 1 ) );
  380. if ( preg_match('/<a id="redirecturl" href="([^"]+)">/is', $result, $matches ) )
  381. return $matches[1];
  382. else
  383. return $url;
  384. }
  385. }
  386. // Implementation of Bit.ly as a Slinky Service
  387. /*
  388. To use Bit.ly, you MUST set your login and apiKey for the service first, e.g.
  389. $bitly = new Slinky_Bitly();
  390. $bitly->set( 'login', 'bitly_login' );
  391. $bitly->set( 'apiKey', 'bitly_apiKey' );
  392. $slinky = new Slinky( $url, $bitly );
  393. echo $slinky->short();
  394. You could also do this if the URL was already a bit.ly URL and you
  395. were going to make it longer, since Bitly is supported for auto-detection:
  396. $slinky = new Slinky( $url );
  397. $slinky->set_service_from_url();
  398. $slinky->service->set( 'login', 'bitly_login' );
  399. $slinky->service->set( 'apiKey', 'bitly_apiKey' );
  400. echo $slinky->long();
  401. */
  402. class Slinky_Bitly extends Slinky_Service {
  403. function url_is_short( $url ) {
  404. return stristr( $url, 'bit.ly/' );
  405. }
  406. function url_is_long( $url ) {
  407. return !stristr( $url, 'bit.ly/' );
  408. }
  409. function make_short( $url ) {
  410. // Can't do anything unless these 2 properties are set first
  411. if ( !$this->get( 'login' ) || !$this->get( 'apiKey' ) )
  412. return $url;
  413. $result = $this->url_post( 'http://api.bit.ly/shorten?version=2.0.1&format=json&login=' . $this->get( 'login' ) . '&apiKey=' . $this->get( 'apiKey' ) . '&longUrl=' . urlencode( $url ) );
  414. $result = json_decode( $result );
  415. if ( !$result->errorCode ) {
  416. foreach ( $result->results as $detail ) {
  417. return $detail->shortUrl;
  418. }
  419. } else {
  420. return false;
  421. }
  422. }
  423. function make_long( $url ) {
  424. // Can't do anything unless these 2 properties are set first
  425. if ( !$this->get( 'login' ) || !$this->get( 'apiKey' ) )
  426. return $url;
  427. $result = $this->url_post( 'http://api.bit.ly/expand?version=2.0.1&format=json&login=' . $this->get( 'login' ) . '&apiKey=' . $this->get( 'apiKey' ) . '&shortUrl=' . urlencode( $url ) );
  428. $result = json_decode( $result );
  429. if ( !$result->errorCode ) {
  430. foreach ( $result->results as $detail ) {
  431. return $detail->longUrl;
  432. }
  433. } else {
  434. return false;
  435. }
  436. }
  437. }
  438. // Implementation of Tr.im as a Slinky Service
  439. /*
  440. When using Tr.im, you MAY optionally set your username and password to tie
  441. URLs to your account, e.g.
  442. $trim = new Slinky_Trim();
  443. $trim->set( 'username', 'trim_username' );
  444. $trim->set( 'password', 'trim_password' );
  445. $slinky = new Slinky( $url, $trim );
  446. echo $slinky->short();
  447. You could also do this if the URL was already a tr.im URL and you
  448. were going to make it longer, since Tr.im is supported for auto-detection:
  449. $slinky = new Slinky( $url );
  450. $slinky->set_service_from_url();
  451. echo $slinky->long();
  452. */
  453. class Slinky_Trim extends Slinky_Service {
  454. function url_is_short( $url ) {
  455. return stristr( $url, 'tr.im/' );
  456. }
  457. function url_is_long( $url ) {
  458. return !stristr( $url, 'tr.im/' );
  459. }
  460. function make_short( $url ) {
  461. $url = 'http://api.tr.im/api/trim_simple?url=' . urlencode( $url );
  462. if ( $this->get( 'username' ) && $this->get( 'password' ) )
  463. $url .= '&username=' . urlencode( $this->get( 'username' ) ) . '&password=' . urlencode( $this->get( 'password' ) );
  464. return $this->url_get( $url );
  465. }
  466. function make_long( $url ) {
  467. $bits = parse_url( $url );
  468. $result = $this->url_get( 'http://api.tr.im/api/trim_destination.json?trimpath=' . substr( $bits['path'], 1 ) );
  469. $result = json_decode($result);
  470. if ( 'OK' == $result->status->result )
  471. return $result->destination;
  472. else
  473. return $url;
  474. }
  475. }
  476. // Implementation of Is.Gd as a Slinky Service
  477. class Slinky_IsGd extends Slinky_Service {
  478. function url_is_short( $url ) {
  479. return stristr( $url, 'is.gd/' );
  480. }
  481. function url_is_long( $url ) {
  482. return !stristr( $url, 'is.gd/' );
  483. }
  484. function make_short( $url ) {
  485. $response = $this->url_get( 'http://is.gd/api.php?longurl=' . urlencode( $url ) );
  486. if ( 'error' == substr( strtolower( $response ), 0, 5 ) )
  487. return false;
  488. else
  489. return $response;
  490. }
  491. }
  492. // Fon.gs
  493. class Slinky_Fongs extends Slinky_Service {
  494. function url_is_short( $url ) {
  495. return stristr( $url, 'fon.gs/' );
  496. }
  497. function url_is_long( $url ) {
  498. return !stristr( $url, 'fon.gs/' );
  499. }
  500. function make_short( $url ) {
  501. $response = $this->url_get( 'http://fon.gs/create.php?url=' . urlencode( $url ) );
  502. if ( 'OK:' == substr( $response, 0, 3 ) )
  503. return str_replace( 'OK: ', '', $response );
  504. else
  505. return $url;
  506. }
  507. }
  508. // yourls
  509. class Slinky_YourLS extends Slinky_Service {
  510. function url_is_short( $url ) {
  511. return stristr( $url, 'shit.li/' );
  512. }
  513. function url_is_long( $url ) {
  514. return !stristr( $url, 'shit.li/' );
  515. }
  516. function make_short( $url ) {
  517. echo $this->get( 'username' );
  518. $use_ssl = $this->get( 'ssl' );
  519. if ( $use_ssl )
  520. $use_ssl = 's';
  521. else
  522. $use_ssl = '';
  523. $result = $this->url_get( 'http'. $use_ssl . '://' . $this->get( 'yourls-url' ) . '/yourls-api.php?username=' . $this->get( 'username' ) . '&password=' . $this->get( 'password' ) . '&action=shorturl&format=simple&url=' . urlencode( $url ) );
  524. if ( 1 != $result && 2 != $result )
  525. return $result;
  526. else
  527. return $url;
  528. }
  529. }
  530. // Micu.rl
  531. class Slinky_Micurl extends Slinky_Service {
  532. function url_is_short( $url ) {
  533. return stristr( $url, 'micurl.com/' );
  534. }
  535. function url_is_long( $url ) {
  536. return !stristr( $url, 'micurl.com/' );
  537. }
  538. function make_short( $url ) {
  539. $result = $this->url_get( 'http://micurl.com/api.php?url=' . urlencode( $url ) );
  540. if ( 1 != $result && 2 != $result )
  541. return 'http://micurl.com/' . $result;
  542. else
  543. return $url;
  544. }
  545. }
  546. // ur1.ca
  547. class Slinky_Ur1ca extends Slinky_Service {
  548. function url_is_short( $url ) {
  549. return stristr( $url, 'ur1.ca/' );
  550. }
  551. function url_is_long( $url ) {
  552. return !stristr( $url, 'ur1.ca/' );
  553. }
  554. function make_short( $url ) {
  555. $result = $this->url_post( 'http://ur1.ca/', array( 'longurl' => $url ) );
  556. if ( preg_match( '/<p class="success">Your ur1 is: <a href="([^"]+)">/', $result, $matches ) )
  557. return $matches[1];
  558. else
  559. return $url;
  560. }
  561. }
  562. // PtitURL.com
  563. class Slinky_PtitURL extends Slinky_Service {
  564. function url_is_short( $url ) {
  565. return stristr( $url, 'ptiturl.com/' );
  566. }
  567. function url_is_long( $url ) {
  568. return !stristr( $url, 'ptiturl.com/' );
  569. }
  570. function make_short( $url ) {
  571. $result = $this->url_get( 'http://ptiturl.com/index.php?creer=oui&url=' . urlencode( $url ) );
  572. if ( preg_match( '/<pre><a href=\'?([^\'>]+)\'?>/', $result, $matches ) )
  573. return $matches[1];
  574. else
  575. return $url;
  576. }
  577. }
  578. // Tighturl.com
  579. class Slinky_TightURL extends Slinky_Service {
  580. function url_is_short( $url ) {
  581. return stristr( $url, 'tighturl.com/' )
  582. || stristr( $url, '2tu.us/' );
  583. }
  584. function url_is_long( $url ) {
  585. return !stristr( $url, 'tighturl.com/' )
  586. && !stristr( $url, '2tu.us/' );
  587. }
  588. function make_short( $url ) {
  589. $response = $this->url_get( 'http://tighturl.com/?save=y&url=' . urlencode( $url ) );
  590. if ( preg_match( '/Your tight URL is: <code><a href=\'([^\']+)\' target=\'_blank\'>/', $response, $matches ) ) {
  591. return $matches[1];
  592. } else {
  593. return $url;
  594. }
  595. }
  596. }
  597. // Snipr for Slinky
  598. /*
  599. To use Snipr, you MUST set your user_id and API (key) for the service first, e.g.
  600. $snipr = new Slinky_Snipr();
  601. $snipr->set( 'user_id', 'Snipr User ID' );
  602. $snipr->set( 'API', 'Snipr API Key' );
  603. $slinky = new Slinky( $url, $snipr );
  604. echo $slinky->short();
  605. NOTE: Snipr requires the SimpleXML extension to be installed for lengthening URLs
  606. */
  607. class Slinky_Snipr extends Slinky_Service {
  608. // Snipurl, Snurl, Snipr, Sn.im
  609. function url_is_short( $url ) {
  610. return stristr( $url, 'snipr.com/' ) || stristr( $url, 'snipurl.com/' ) || stristr( $url, 'snurl.com/' ) || stristr( $url, 'sn.im/' );
  611. }
  612. function url_is_long( $url ) {
  613. return !stristr( $url, 'snipr.com/' ) || !stristr( $url, 'snipurl.com/' ) || !stristr( $url, 'snurl.com/' ) || !stristr( $url, 'sn.im/' );
  614. }
  615. function make_short( $url ) {
  616. if ( !$this->get( 'user_id' ) || !$this->get( 'API' ) )
  617. return $url;
  618. $response = $this->url_post( 'http://snipr.com/site/getsnip', array( 'sniplink' => urlencode( $url ), 'snipuser' => $this->get( 'user_id'), 'snipapi' => $this->get( 'API' ), 'snipformat' => 'simple' ) );
  619. if ( 'ERROR' != substr( $response, 0, 5 ) )
  620. return $response;
  621. else
  622. return $url;
  623. }
  624. }
  625. // If you're testing things out, http://dentedreality.com.au/ should convert to:
  626. // - http://tinyurl.com/jw5sh
  627. // - http://bit.ly/hEkAD
  628. // - http://tr.im/sk1H
  629. // - http://is.gd/1yJ81
  630. // - http://fon.gs/tc1p8c
  631. // - http://micurl.com/qen3uub
  632. // - http://ur1.ca/7dcd
  633. // - http://ptiturl.com/?id=bac8fb
  634. // - http://tighturl.com/kgd
  635. // - http://snipr.com/nbbw3
  636. //
  637. // $slinky = new Slinky( 'http://dentedreality.com.au/' );
  638. // echo $slinky->short();