shorten.module in Shorten URLs 7
Same filename and directory in other branches
Shortens URLs via external services.
File
shorten.moduleView source
<?php
/**
* @file
* Shortens URLs via external services.
*/
/**
* Implements hook_help().
*/
function shorten_help($path, $arg) {
$output = '';
switch ($path) {
case 'admin/help#shorten':
$output = '<p>' . t('This module shortens URLs.') . '</p>';
break;
}
return $output;
}
/**
* Implements hook_menu().
*/
function shorten_menu() {
$items = array();
$items['admin/config/services/shorten'] = array(
'title' => 'Shorten',
'description' => 'Adjust certain display settings for Shorten.',
'page callback' => 'shorten_admin_form',
'access arguments' => array(
'administer site configuration',
),
'file' => 'shorten.admin.inc',
);
$items['admin/config/services/shorten/general'] = array(
'title' => 'General',
'type' => MENU_DEFAULT_LOCAL_TASK,
'access arguments' => array(
'administer site configuration',
),
'weight' => -1,
);
$items['admin/config/services/shorten/keys'] = array(
'title' => 'Shorten API Keys',
'description' => 'Fill in API keys to use certain services.',
'page callback' => 'shorten_keys_form',
'access arguments' => array(
'manage Shorten URLs API keys',
),
'type' => MENU_LOCAL_TASK,
'file' => 'shorten.admin.inc',
);
$items['shorten'] = array(
'title' => 'Shorten URLs',
'page callback' => 'shorten_form_shorten_form',
'page arguments' => array(
'shorten_form_shorten',
),
'access arguments' => array(
'use Shorten URLs page',
),
);
return $items;
}
/**
* Implements hook_block_info().
*/
function shorten_block_info() {
$blocks = array();
$blocks['shorten']['info'] = t('Shorten URLs');
$blocks['shorten']['visibility'] = 0;
$blocks['shorten']['pages'] = 'shorten';
$blocks['shorten_short']['info'] = t('Short URL');
$blocks['shorten_short']['cache'] = DRUPAL_CACHE_PER_PAGE;
return $blocks;
}
/**
* Implements hook_block_view().
*/
function shorten_block_view($delta = '') {
$block = array();
if ($delta == 'shorten') {
$block['subject'] = t('Shorten URLs');
$block['content'] = shorten_form_shorten_form();
return $block;
}
elseif ($delta == 'shorten_short') {
$block['subject'] = t('Short URL');
$block['content'] = shorten_current_form();
return $block;
}
}
/**
* Implements hook_block_configure().
*/
function shorten_block_configure($delta = '') {
if ($delta == 'shorten_short') {
drupal_set_message(t('This block displays the short URL for the page on which it is shown, which can slow down uncached pages in some instances.'), 'warning');
}
}
/**
* Implements hook_perm().
*/
function shorten_permission() {
return array(
'use Shorten URLs page' => array(
'title' => t('Use URL shortener page'),
),
'manage Shorten URLs API keys' => array(
'title' => t('Manage URL shortener API keys'),
'description' => t('Allow viewing and editing the API keys for third-party URL shortening services.'),
),
);
}
/**
* Implements hook_flush_caches().
*/
function shorten_flush_caches() {
if (variable_get('shorten_cache_clear_all', TRUE)) {
return array(
'cache_shorten',
);
}
return array();
}
/**
* Retrieves and beautifies the abbreviated URL.
* This is the main API function of this module.
*
* @param $original
* The URL of the page for which to create the abbreviated URL. If not passed
* uses the current page.
* @param $service
* The service to use to abbreviate the URL.
* For services available by default, see shorten_shorten_service().
* @return
* An abbreviated URL.
*/
function shorten_url($original = '', $service = '') {
if (!$original) {
$original = url($_GET['q'], array(
'absolute' => TRUE,
'alias' => !variable_get('shorten_use_alias', 1),
));
}
$original_for_caching = urlencode($original);
// https://www.drupal.org/node/2324925
if (!$service) {
$service = variable_get('shorten_service', 'is.gd');
}
$cached = cache_get($original_for_caching, 'cache_shorten');
if (!empty($cached->data) && REQUEST_TIME < $cached->expire) {
return $cached->data;
}
$services = module_invoke_all('shorten_service');
if (isset($services[$service])) {
$url = _shorten_get_url($original, $services[$service], $service);
}
// If the primary service fails, try the secondary service.
if (empty($url)) {
$service = variable_get('shorten_service_backup', 'TinyURL');
if (isset($services[$service])) {
$url = _shorten_get_url($original, $services[$service], $service);
}
// If the secondary service fails, use the original URL.
if (empty($url)) {
$url = $original;
}
}
$url = trim($url);
// Redundant for most services.
// Replace "http://" with "www." if the URL is abbreviated because it's shorter.
if ($url != $original && variable_get('shorten_www', FALSE)) {
if (strpos($url, 'http://') === 0) {
$url = drupal_substr($url, 7);
if (strpos($url, 'www.') !== 0) {
$url = 'www.' . $url;
}
}
elseif (strpos($url, 'https://') === 0) {
$url = drupal_substr($url, 8);
if (strpos($url, 'www.') !== 0) {
$url = 'www.' . $url;
}
}
}
$cache_duration = variable_get('shorten_cache_duration', 1814400);
// Only cache failed retrievals for a limited amount of time.
if ($url == $original) {
$expire = REQUEST_TIME + variable_get('shorten_cache_fail_duration', 1800);
}
elseif (is_numeric($cache_duration)) {
$expire = REQUEST_TIME + $cache_duration;
}
else {
$expire = CACHE_PERMANENT;
}
cache_set($original_for_caching, $url, 'cache_shorten', $expire);
module_invoke_all('shorten_create', $original, $url, $service);
return $url;
}
/**
* Shortens URLs. Times out after three (3) seconds.
*
* @param $original
* The URL of the page for which to retrieve the abbreviated URL.
* @param $api
* A string or array used to retrieve a shortened URL. If it is an array, it
* can have the elements 'custom,' 'url,' 'tag,' 'json,' and 'args.'
* @param $service
* The service to use to abbreviate the URL.
* For services available by default, see shorten_shorten_service().
* @return
* An abbreviated URL.
*/
function _shorten_get_url($original, $api, $service) {
$method = drupal_strtoupper(variable_get('shorten_method', _shorten_method_default()));
$service = t('an unknown service');
if (is_string($api)) {
$url = shorten_fetch($api . urlencode($original));
$service = $api;
}
elseif (is_array($api)) {
// Merge in defaults.
$api += array(
'custom' => FALSE,
'json' => FALSE,
);
if (!empty($api['url'])) {
$original = urlencode($original);
// Typically $api['custom'] == 'xml' although it doesn't have to.
if (!empty($api['tag'])) {
$url = shorten_fetch($api['url'] . $original, $api['tag']);
}
elseif (!empty($api['json'])) {
$url = shorten_fetch($api['url'] . $original, $api['json'], 'json');
}
elseif (!$api['custom']) {
$url = shorten_fetch($api['url'] . $original);
}
$service = $api['url'];
}
elseif (is_string($api['custom']) && function_exists($api['custom'])) {
$method = t('A custom method: @method()', array(
'@method' => $api['custom'],
));
if (!empty($api['args']) && is_array($api['args'])) {
$args = $api['args'];
array_unshift($args, $original);
$url = call_user_func_array($api['custom'], $args);
}
else {
$url = call_user_func($api['custom'], $original);
}
}
}
if ($url) {
if (drupal_substr($url, 0, 7) == 'http://' || drupal_substr($url, 0, 8) == 'https://') {
return $url;
}
}
watchdog('shorten', '%method failed to return an abbreviated URL from %service.', array(
'%method' => $method,
'%service' => $service,
), WATCHDOG_NOTICE, $url);
return FALSE;
}
/**
* Implements hook_shorten_service().
*/
function shorten_shorten_service() {
$services = array();
if (variable_get('shorten_budurl', '')) {
$services['budurl'] = array(
'url' => 'http://budurl.com/api/v1/budurls/shrink?api_key=' . variable_get('shorten_budurl', '') . '&format=txt&long_url=',
);
}
if (variable_get('shorten_ez', '')) {
$services['ez'] = array(
'url' => 'http://ez.com/api/v1/ezlinks/shrink?api_key=' . variable_get('shorten_ez', '') . '&format=txt&long_url=',
);
}
if (variable_get('shorten_bitly_login', '') && variable_get('shorten_bitly_key', '')) {
$services['bit.ly'] = 'https://api-ssl.bitly.com/v3/shorten?format=txt&login=' . variable_get('shorten_bitly_login', '') . '&apiKey=' . variable_get('shorten_bitly_key', '') . '&x_login=' . variable_get('shorten_bitly_login', '') . '&x_apiKey=' . variable_get('shorten_bitly_key', '') . '&longUrl=';
$services['j.mp'] = 'https://api-ssl.bitly.com/v3/shorten?format=txt&domain=j.mp&login=' . variable_get('shorten_bitly_login', '') . '&apiKey=' . variable_get('shorten_bitly_key', '') . '&x_login=' . variable_get('shorten_bitly_login', '') . '&x_apiKey=' . variable_get('shorten_bitly_key', '') . '&longUrl=';
}
if (variable_get('shorten_googl', '')) {
$services['goo.gl'] = array(
'custom' => '_shorten_googl',
);
}
$services += array(
'is.gd' => 'http://is.gd/api.php?longurl=',
'migre.me' => 'http://migre.me/api.txt?url=',
'Metamark' => 'http://metamark.net/api/rest/simple?long_url=',
'PeekURL' => 'http://peekurl.com/api.php?desturl=',
'qr.cx' => 'http://qr.cx/api/?longurl=',
'ri.ms' => 'http://ri.ms/api-create.php?url=',
'TinyURL' => 'http://tinyurl.com/api-create.php?url=',
);
if (variable_get('shorten_fwd4me', '')) {
$services['fwd4.me'] = 'http://api.fwd4.me/?key=' . variable_get('shorten_fwd4me', '') . '&url=';
}
if (module_exists('shurly')) {
$services['ShURLy'] = array(
'custom' => '_shorten_shurly',
);
}
// Alphabetize. ksort() is case-sensitive.
uksort($services, 'strcasecmp');
return $services;
}
/**
* Helps get a shortened URL from Goo.gl.
*/
function _shorten_googl($original) {
$url = 'https://www.googleapis.com/urlshortener/v1/url?key=' . variable_get('shorten_googl', '');
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'verify_host', TRUE);
$options = array(
'method' => 'POST',
'data' => json_encode(array(
'longUrl' => $original,
)),
'context' => $context,
'headers' => array(
'Content-type' => 'application/json',
),
);
$googl = shorten_fetch($url, 'id', 'json', $options);
if ($googl) {
return $googl;
}
watchdog('shorten', 'Error fetching shortened URL from goo.gl.', array(), WATCHDOG_ERROR, $url);
return FALSE;
}
/**
* Helps get a shortened URL via the ShURLy module.
*/
function _shorten_shurly($original) {
$result = shurly_shorten($original);
return $result['shortUrl'];
}
/**
* Downloads the response of the URL abbreviation service.
*
* @param $url
* The URL which will return an abbreviated URL from any service. Includes
* both the service and the URL to be shortened.
* @param $tag
* If the response is XML, the tag within which to look for the shortened URL.
* @param $special
* A special format the service will return. Currently only supports 'json.'
* @param $options
* An associative array of options to allow executing an advanced request.
* Valid keys include anything that would work with drupal_http_request()
* except that $options['context'] is only used with the PHP request method.
* @return
* An abbreviated URL or FALSE if fetching the abbreviated URL fails.
*/
function shorten_fetch($url, $tag = '', $special = '', $options = array()) {
$options += array(
'headers' => array(),
'method' => 'GET',
'data' => NULL,
'max_redirects' => 3,
'timeout' => variable_get('shorten_timeout', 3),
'context' => NULL,
);
if (variable_get('shorten_method', _shorten_method_default()) == 'php') {
$result = drupal_http_request($url, $options);
$contents = isset($result->data) && !isset($result->error) ? $result->data : NULL;
if (!empty($result->error)) {
watchdog('shorten', '@code error shortening the URL @url using the PHP request method. Error message: %error', array(
'@code' => $result->code,
'@url' => $url,
'%error' => $result->error,
), WATCHDOG_ERROR, $url);
}
}
elseif (variable_get('shorten_method', _shorten_method_default()) == 'curl') {
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, $options['timeout']);
// https://drupal.org/node/1481634
//if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
// curl_setopt($c, CURLOPT_FOLLOWLOCATION, TRUE);
//}
curl_setopt($c, CURLOPT_MAXREDIRS, $options['max_redirects']);
// defined() checks due to https://drupal.org/node/1469400
// Specifying the protocol is necessary to avoid malicious redirects to POP
// in libcurl 7.26.0 to 7.28.1
if (defined('CURLOPT_REDIR_PROTOCOLS') && defined('CURLPROTO_HTTP') && defined('CURLPROTO_HTTPS')) {
curl_setopt($c, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
}
curl_setopt($c, CURLOPT_URL, $url);
if ($options['method'] != 'GET') {
$uri = @parse_url($url);
if ($uri['scheme'] == 'http') {
curl_setopt($c, CURLOPT_PORT, isset($uri['port']) ? $uri['port'] : 80);
if (defined('CURLOPT_PROTOCOLS') && defined('CURLPROTO_HTTP')) {
curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP);
}
}
elseif ($uri['scheme'] == 'https') {
curl_setopt($c, CURLOPT_PORT, isset($uri['port']) ? $uri['port'] : 443);
if (defined('CURLOPT_PROTOCOLS') && defined('CURLPROTO_HTTPS')) {
curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
}
}
if (!empty($options['headers'])) {
$curl_headers = array();
foreach ($options['headers'] as $key => $value) {
$curl_headers[] = trim($key) . ': ' . trim($value);
}
curl_setopt($c, CURLOPT_HTTPHEADER, $curl_headers);
}
if ($options['method'] == 'POST') {
curl_setopt($c, CURLOPT_POST, TRUE);
curl_setopt($c, CURLOPT_POSTFIELDS, $options['data']);
}
else {
curl_setopt($c, CURLOPT_CUSTOMREQUEST, $options['method']);
}
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
}
$contents = curl_exec($c);
curl_close($c);
}
else {
return FALSE;
}
if (!$contents) {
return FALSE;
}
if ($tag) {
if (!$special) {
$contents = _shorten_xml($contents, $tag);
}
elseif ($special == 'json') {
$contents = json_decode($contents, TRUE);
$contents = $contents[$tag];
}
}
if (!$contents || $contents == $url) {
return FALSE;
}
return $contents;
}
/**
* Parses the value between tags in an XML document.
*
* @param $xml
* The contents of the XML document.
* @param $tag
* The tag to get the value from.
* @return
* The value from the specified tag, typically an abbreviated URL.
*/
function _shorten_xml($xml, $tag) {
$start = strpos($xml, $tag) + drupal_strlen($tag) + 1;
$end = strpos($xml, $tag, $start + 1) - 2;
$length = -(drupal_strlen($xml) - $end);
return drupal_substr($xml, $start, $length);
}
/**
* Returns HTML representing the shorten form.
*/
function shorten_form_shorten_form() {
$form = drupal_get_form('shorten_form_shorten');
return drupal_render($form);
}
/**
* Builds a form which allows shortening of a URL via the UI.
*/
function shorten_form_shorten($form, &$form_state) {
drupal_add_js(drupal_get_path('module', 'shorten') . '/shorten.js');
//Form elements between ['opendiv'] and ['closediv'] will be refreshed via AHAH on form submission.
$form['opendiv'] = array(
'#markup' => '<div id="shorten_replace">',
);
if (!isset($form_state['storage'])) {
$form_state['storage'] = array(
'step' => 0,
);
}
if (isset($form_state['storage']['short_url'])) {
// This whole "step" business keeps the form element from being cached.
$form['shortened_url_' . $form_state['storage']['step']] = array(
'#type' => 'textfield',
'#title' => t('Shortened URL'),
'#default_value' => $form_state['storage']['short_url'],
'#size' => 25,
'#attributes' => array(
'class' => array(
'shorten-shortened-url',
),
),
);
}
$form['url_' . $form_state['storage']['step']] = array(
'#type' => 'textfield',
'#title' => t('URL'),
'#default_value' => '',
'#required' => TRUE,
'#size' => 25,
'#maxlength' => 2048,
'#attributes' => array(
'class' => array(
'shorten-long-url',
),
),
);
//Form elements between ['opendiv'] and ['closediv'] will be refreshed via AHAH on form submission.
$form['closediv'] = array(
'#markup' => '</div>',
);
$last_service = NULL;
if (isset($form_state['storage']['service'])) {
$last_service = $form_state['storage']['service'];
}
$service = _shorten_service_form($last_service);
if (is_array($service)) {
$form['service'] = $service;
}
$form['shorten'] = array(
'#type' => 'submit',
'#value' => t('Shorten'),
'#ajax' => array(
'callback' => 'shorten_save_js',
'wrapper' => 'shorten_replace',
'effect' => 'fade',
'method' => 'replace',
),
);
return $form;
}
/**
* Validate function for the Shorten form.
* It's hard to really figure out what a valid URL is. We might reasonably
* expect http://example.com, https://example.com, www.example.com, or even
* just example.com to be correctly shortened by respective services. So instead
* of dealing with this logic ourselves, we just check that there is at least a
* period in the string, because there must be a TLD, and we check length.
*/
function shorten_form_shorten_validate($form, &$form_state) {
$url = $form_state['values']['url_' . $form_state['storage']['step']];
if (drupal_strlen($url) > 4) {
if (!strpos($url, '.', 1)) {
form_set_error('url', t('Please enter a valid URL.'));
}
}
else {
form_set_error('url', t('Please enter a valid URL.'));
}
}
/**
* Submit function for the Shorten form.
*/
function shorten_form_shorten_submit($form, &$form_state) {
$service = '';
if ($form_state['values']['service']) {
$service = $form_state['values']['service'];
}
$shortened = shorten_url($form_state['values']['url_' . $form_state['storage']['step']], $service);
if ($form_state['values']['service']) {
$_SESSION['shorten_service'] = $form_state['values']['service'];
}
drupal_set_message(t('%original was shortened to %shortened', array(
'%original' => $form_state['values']['url_' . $form_state['storage']['step']],
'%shortened' => $shortened,
)));
$form_state['rebuild'] = TRUE;
if (empty($form_state['storage'])) {
$form_state['storage'] = array();
}
$form_state['storage']['short_url'] = $shortened;
$form_state['storage']['service'] = $form_state['values']['service'];
if (isset($form_state['storage']['step'])) {
$form_state['storage']['step']++;
}
else {
$form_state['storage']['step'] = 0;
}
}
/**
* JS callback for submitting the Shorten form.
*/
function shorten_save_js($form, $form_state) {
$step = $form_state['storage']['step'];
$new_form = array();
$new_form['opendiv'] = $form['opendiv'];
$new_form['shortened_url_' . $step] = $form['shortened_url_' . $step];
$new_form['url_' . $step] = $form['url_' . $step];
$new_form['closediv'] = $form['closediv'];
return $new_form;
}
/**
* Form which displays a list of URL shortening services.
*
* @param $last_service
* The last service used on this page, if applicable.
*/
function _shorten_service_form($last_service = NULL) {
if (variable_get('shorten_show_service', FALSE) && _shorten_method_default() != 'none') {
$all_services = module_invoke_all('shorten_service');
$services = array();
$disallowed = variable_get('shorten_invisible_services', array());
foreach ($all_services as $key => $value) {
if (!$disallowed[$key]) {
$services[$key] = $key;
}
}
$default = variable_get('shorten_service', 'is.gd');
if ($default == 'none') {
$default = 'TinyURL';
}
// Remember the last service that was used.
if (isset($_SESSION['shorten_service']) && $_SESSION['shorten_service']) {
$default = $_SESSION['shorten_service'];
}
// Anonymous users don't have $_SESSION, so we use the last service used on this page, if applicable.
if (!empty($last_service)) {
$default = $last_service;
}
$count = count($services);
if ($count > 1) {
if (!$services[$default]) {
unset($default);
}
return array(
'#type' => 'select',
'#title' => t('Service'),
'#description' => t('The service to use to shorten the URL.'),
'#required' => TRUE,
'#default_value' => $default,
'#options' => $services,
);
}
elseif ($count) {
return array(
'#type' => 'value',
'#value' => array_pop($services),
);
}
return array(
'#type' => 'value',
'#value' => $default,
);
}
}
/**
* Returns HTML representing the short URL form.
*/
function shorten_current_form() {
$form = drupal_get_form('shorten_current');
return drupal_render($form);
}
/**
* Builds a textfield to show the short URL for the current page.
*/
function shorten_current($form, $form_state) {
drupal_add_js(drupal_get_path('module', 'shorten') . '/shorten.js');
$form['this_shortened'] = array(
'#type' => 'textfield',
'#size' => 25,
'#default_value' => shorten_url(),
);
return $form;
}
/**
* Determines the default method for retrieving shortened URLs.
* cURL is the preferred method, but sometimes it's not installed.
*/
function _shorten_method_default() {
if (function_exists('curl_exec')) {
return 'curl';
}
elseif (function_exists('file_get_contents')) {
return 'php';
}
return 'none';
}
/**
* Implements hook_token_info().
*/
function shorten_token_info() {
$info = array();
$info['tokens']['node']['short-url'] = array(
'name' => t('Short Url'),
'description' => t('The shortened URL for the node. <strong>Deprecated:</strong> use [node:url:shorten] or [node:url:unaliased:shorten] instead.'),
);
$info['tokens']['url']['shorten'] = array(
'name' => t('Shorten'),
'description' => t("Shorten URL using the default service."),
);
return $info;
}
/**
* Implements hook_tokens().
*/
function shorten_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
if ($type == 'node' && !empty($data['node']) && isset($tokens['short-url'])) {
$node = (object) $data['node'];
$replacements[$tokens['short-url']] = shorten_url(url('node/' . $node->nid, array(
'absolute' => TRUE,
'alias' => variable_get('shorten_use_alias', 1),
)));
}
// General URL token replacement
$url_options = array(
'absolute' => TRUE,
);
if (isset($options['language'])) {
$url_options['language'] = $options['language'];
$language_code = $options['language']->language;
}
else {
$language_code = NULL;
}
$sanitize = !empty($options['sanitize']);
// URL tokens.
if ($type == 'url' && !empty($data['path'])) {
$path = $data['path'];
if (isset($data['options'])) {
// Merge in the URL options if available.
$url_options = $data['options'] + $url_options;
}
foreach ($tokens as $name => $original) {
switch ($name) {
case 'shorten':
$value = url($path, $url_options);
$replacements[$original] = shorten_url($value);
break;
}
}
}
return $replacements;
}
Functions
Name | Description |
---|---|
shorten_block_configure | Implements hook_block_configure(). |
shorten_block_info | Implements hook_block_info(). |
shorten_block_view | Implements hook_block_view(). |
shorten_current | Builds a textfield to show the short URL for the current page. |
shorten_current_form | Returns HTML representing the short URL form. |
shorten_fetch | Downloads the response of the URL abbreviation service. |
shorten_flush_caches | Implements hook_flush_caches(). |
shorten_form_shorten | Builds a form which allows shortening of a URL via the UI. |
shorten_form_shorten_form | Returns HTML representing the shorten form. |
shorten_form_shorten_submit | Submit function for the Shorten form. |
shorten_form_shorten_validate | Validate function for the Shorten form. It's hard to really figure out what a valid URL is. We might reasonably expect http://example.com, https://example.com, www.example.com, or even just example.com to be correctly shortened by respective… |
shorten_help | Implements hook_help(). |
shorten_menu | Implements hook_menu(). |
shorten_permission | Implements hook_perm(). |
shorten_save_js | JS callback for submitting the Shorten form. |
shorten_shorten_service | Implements hook_shorten_service(). |
shorten_tokens | Implements hook_tokens(). |
shorten_token_info | Implements hook_token_info(). |
shorten_url | Retrieves and beautifies the abbreviated URL. This is the main API function of this module. |
_shorten_get_url | Shortens URLs. Times out after three (3) seconds. |
_shorten_googl | Helps get a shortened URL from Goo.gl. |
_shorten_method_default | Determines the default method for retrieving shortened URLs. cURL is the preferred method, but sometimes it's not installed. |
_shorten_service_form | Form which displays a list of URL shortening services. |
_shorten_shurly | Helps get a shortened URL via the ShURLy module. |
_shorten_xml | Parses the value between tags in an XML document. |