| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Adds TightURL-like functionality to your site
|
| 7 |
* Some code
|
| 8 |
*/
|
| 9 |
|
| 10 |
/**
|
| 11 |
* Implementation of hook_help().
|
| 12 |
*/
|
| 13 |
function knurl_help($section) {
|
| 14 |
switch ($section) {
|
| 15 |
case 'admin/help#knurl':
|
| 16 |
return '<p>'. t('Knurl module provides functionality like TightURL service.') .'</p>';
|
| 17 |
}
|
| 18 |
}
|
| 19 |
|
| 20 |
/**
|
| 21 |
* Implementation of hook_perm().
|
| 22 |
*/
|
| 23 |
function knurl_perm() {
|
| 24 |
return array('create knurl', 'access knurl', 'remove knurl');
|
| 25 |
}
|
| 26 |
|
| 27 |
/**
|
| 28 |
* Implementation of hook_access().
|
| 29 |
*/
|
| 30 |
function knurl_access($op, $node) {
|
| 31 |
if ($op == 'create') return user_access('create knurl');
|
| 32 |
else if ($op == 'remove') return user_access('remove knurl');
|
| 33 |
else return user_access('access knurl');
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
| 37 |
* Implementation of hook_menu().
|
| 38 |
*/
|
| 39 |
function knurl_menu($may_cache) {
|
| 40 |
$items = array();
|
| 41 |
if($may_cache) {
|
| 42 |
$items[] = array(
|
| 43 |
'path' => 'knurl',
|
| 44 |
'title' => t('Create a new URL shortcut'),
|
| 45 |
'access' => user_access('create knurl'),
|
| 46 |
'callback' => 'drupal_get_form',
|
| 47 |
'callback arguments' => array ( 'knurl_add_form' )
|
| 48 |
);
|
| 49 |
$items[] = array(
|
| 50 |
'path' => 'knurl/show',
|
| 51 |
'title' => t('Show URL'),
|
| 52 |
'access' => user_access('access knurl'),
|
| 53 |
'callback' => 'knurl_show',
|
| 54 |
'type' => MENU_CALLBACK
|
| 55 |
);
|
| 56 |
$items[] = array(
|
| 57 |
'path' => 'knurl/remove',
|
| 58 |
'title' => t('Remove URL'),
|
| 59 |
'access' => user_access('remove knurl'),
|
| 60 |
'callback' => 'knurl_remove',
|
| 61 |
'type' => MENU_CALLBACK
|
| 62 |
);
|
| 63 |
$items[] = array(
|
| 64 |
'path' => 'url',
|
| 65 |
'title' => t('redirect'),
|
| 66 |
'access' => user_access('access knurl'),
|
| 67 |
'callback' => 'knurl_redirect',
|
| 68 |
'type' => MENU_CALLBACK
|
| 69 |
);
|
| 70 |
}
|
| 71 |
return $items;
|
| 72 |
}
|
| 73 |
|
| 74 |
/**
|
| 75 |
* Responds to /knurl/show to list all URL's
|
| 76 |
* and /knurl/show/${url} for one
|
| 77 |
*/
|
| 78 |
function knurl_show() {
|
| 79 |
$output = '<p>';
|
| 80 |
$url_limit = 75;
|
| 81 |
$args = func_get_args();
|
| 82 |
if( sizeof($args) == 1 ) {
|
| 83 |
$output .= l('show all', 'knurl/show');
|
| 84 |
$res = db_query("select * from {knurl} where short_url='%s'", end($args));
|
| 85 |
} else {
|
| 86 |
$output .= ' ';
|
| 87 |
$res = pager_query("select * from {knurl} order by tid desc", 50);
|
| 88 |
}
|
| 89 |
if(db_num_rows($res) == 0) return drupal_not_found();
|
| 90 |
$output .= '<table style="margin:0px;padding:0px;"><thead><tr>';
|
| 91 |
$output .= '<th style="width:80%">Target URL</th>';
|
| 92 |
$output .= '<th style="width:20%">knurl</th>';
|
| 93 |
//$output .= '<th style="width:20%">Action</th></tr></thead>';
|
| 94 |
while ($node = db_fetch_object($res)) {
|
| 95 |
$output .= '<tr><td>' . wordwrap($node->link, $url_limit, "<BR>", true) . '</td><td>';
|
| 96 |
$output .= l(_get_server_url() . '/url/' . $node->short_url, 'url/' . $node->short_url);
|
| 97 |
$output .= '</td>';//<td>' . l("delete", 'knurl/remove/' . $node->short_url) . '</td></tr>';
|
| 98 |
// why do we need to delete anyway? commented out by Sam Placette, 9-26-07
|
| 99 |
}
|
| 100 |
$output .= '</table>';
|
| 101 |
$output .= theme("pager", array( 2=>3 ), 50);
|
| 102 |
return $output;
|
| 103 |
}
|
| 104 |
|
| 105 |
/**
|
| 106 |
* Responds to /knurl/delete/${url}
|
| 107 |
*
|
| 108 |
* It handles knurl removal
|
| 109 |
*/
|
| 110 |
function knurl_remove() {
|
| 111 |
$short_url = end($args= func_get_args());
|
| 112 |
if (_knurl_is_unique_url($short_url)) {
|
| 113 |
drupal_set_message(t(sprintf('URL <b>%s</b> was not found', $short_url)));
|
| 114 |
return drupal_goto("knurl/show/");
|
| 115 |
}
|
| 116 |
else {
|
| 117 |
db_query("DELETE FROM {knurl} WHERE short_url='%s'", $short_url);
|
| 118 |
drupal_set_message(t( sprintf('URL <b>%s</b> was removed', $short_url) ));
|
| 119 |
return drupal_goto("knurl/show/");
|
| 120 |
}
|
| 121 |
}
|
| 122 |
|
| 123 |
/**
|
| 124 |
* Responds to /url/${url}
|
| 125 |
*
|
| 126 |
* Redirects the user to the given URL
|
| 127 |
*/
|
| 128 |
function knurl_redirect() {
|
| 129 |
$short_url = end($args = func_get_args());
|
| 130 |
$res = db_fetch_object(db_query("select * from {knurl} where short_url='%s'", $short_url));
|
| 131 |
if(!$res) return drupal_not_found();
|
| 132 |
else return drupal_set_header("Location: ".$res->link);
|
| 133 |
// else return drupal_set_html_head('<meta http-equiv="refresh" content="0;url='.$res->link.'"/>');
|
| 134 |
}
|
| 135 |
|
| 136 |
// form for adding a new knurl
|
| 137 |
function knurl_add_form() {
|
| 138 |
drupal_set_message( t(sprintf('Shorten long URLs by using a URL shortcut instead. Just enter the original URL (including http(s)://) and click Submit, and a new URL shortcut will be generated.')) );
|
| 139 |
drupal_set_message( t(sprintf('Now you can create knurls even easier than before. Just drag this <A HREF="javascript:void(location.href=\''._get_server_url().'/knurl?url=\'+location.href)">%s knurl</A> link to your toolbar. At the click of a button, a URL shortcut will be generated for the page you are currently at.', variable_get('site_name', 'Drupal'))));
|
| 140 |
$form['url'] = array( '#type' => 'textarea',
|
| 141 |
'#title' => t('Enter a fully qualified URL'),
|
| 142 |
'#default_value' => $_GET['url'],
|
| 143 |
'#required' => TRUE
|
| 144 |
);
|
| 145 |
$form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
|
| 146 |
if (isset($_GET['url']) && _knurl_is_valid_url($_GET['url'])) { // automagically submit if valid url is included in URI
|
| 147 |
$form_values['url'] = $_GET['url'];
|
| 148 |
knurl_add_form_submit( 0, $form_values);
|
| 149 |
}
|
| 150 |
return $form;
|
| 151 |
}
|
| 152 |
|
| 153 |
// callback for validating the form
|
| 154 |
function knurl_add_form_validate($form_id, $form_values) {
|
| 155 |
if(!_knurl_is_valid_url($form_values['url']) ) {
|
| 156 |
form_set_error('', t('Invalid URL'));
|
| 157 |
}
|
| 158 |
}
|
| 159 |
|
| 160 |
// callback executed on submit
|
| 161 |
function knurl_add_form_submit( $form_id, $form_values ) {
|
| 162 |
global $user;
|
| 163 |
$url_limit = 75;
|
| 164 |
$target_url = $form_values['url'];
|
| 165 |
// generate a unique URL
|
| 166 |
do {
|
| 167 |
$short_url = _knurl_random_url();
|
| 168 |
} while( !_knurl_is_unique_url( $short_url ) );
|
| 169 |
db_query("insert into {knurl} (uid, short_url, link) values (%d, '%s', '%s')", $user->uid, $short_url, $target_url);
|
| 170 |
|
| 171 |
if(strlen($target_url) > $url_limit) {
|
| 172 |
$target_url = "<BR>".wordwrap($form_values['url'], $url_limit, "<BR>", true);
|
| 173 |
}
|
| 174 |
if($_SERVER['HTTPS']) {
|
| 175 |
$protocol = "https://";
|
| 176 |
} else $protocol = "http://";
|
| 177 |
drupal_get_messages();
|
| 178 |
drupal_set_message( t(sprintf('The URL shortcut was successfully created. <A HREF="/url/%s">%s/url/%s</A> now links to %s.<P>You can use the URL shortcut anywhere you would use the original URL.', $short_url, _get_server_url(), $short_url, $target_url)) );
|
| 179 |
return drupal_goto( sprintf('knurl/show/%s', $short_url) );
|
| 180 |
}
|
| 181 |
|
| 182 |
/**
|
| 183 |
* Generates a random url
|
| 184 |
*
|
| 185 |
* based on horde, Auth::getRandomPassword
|
| 186 |
*/
|
| 187 |
function _knurl_random_url() {
|
| 188 |
$vowels = 'aeiouy';
|
| 189 |
$constants = 'bcdfghjklmnpqrstvwxz';
|
| 190 |
$numbers = '0123456789';
|
| 191 |
$chars[0] = substr($constants, mt_rand(0, strlen($constants) - 1), 1);
|
| 192 |
$chars[1] = substr($vowels, mt_rand(0, strlen($vowels) - 1), 1);
|
| 193 |
$chars[2] = substr($constants, mt_rand(0, strlen($constants) - 1), 1);
|
| 194 |
$chars[3] = substr($vowels, mt_rand(0, strlen($vowels) - 1), 1);
|
| 195 |
$chars[4] = substr($constants, mt_rand(0, strlen($constants) - 1), 1);
|
| 196 |
$chars[5] = substr($numbers, mt_rand(0, strlen($numbers) - 1), 1);
|
| 197 |
$chars[6] = substr($numbers, mt_rand(0, strlen($numbers) - 1), 1);
|
| 198 |
shuffle($chars);
|
| 199 |
return implode( '', $chars );
|
| 200 |
}
|
| 201 |
|
| 202 |
/**
|
| 203 |
* Checks if the given URL is valid
|
| 204 |
*/
|
| 205 |
function _knurl_is_unique_url( $url ) {
|
| 206 |
$result = db_num_rows( db_query("select short_url from {knurl} where short_url='%s'", $url) );
|
| 207 |
return $result == 0;
|
| 208 |
}
|
| 209 |
|
| 210 |
/**
|
| 211 |
* Check if the given URL is valid
|
| 212 |
*
|
| 213 |
* based on http://tighturl.com/sourcecode/tighturl.php
|
| 214 |
*/
|
| 215 |
function _knurl_is_valid_url( $url ) {
|
| 216 |
$validurlpattern = "/^(http|https|ftp|sftp)\:\/\/([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)";
|
| 217 |
$validurlpattern .= "*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])";
|
| 218 |
$validurlpattern .= "\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)";
|
| 219 |
$validurlpattern .= "\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)";
|
| 220 |
$validurlpattern .= "\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])";
|
| 221 |
$validurlpattern .= "|((([0-9A-F]{1,4}(((:[0-9A-F]{1,4}){5}::[0-9A-F]{1,4})|((:[0-9A-F]{1,4}){4}";
|
| 222 |
$validurlpattern .= "::[0-9A-F]{1,4}(:[0-9A-F]{1,4}){0,1})|((:[0-9A-F]{1,4}){3}::[0-9A-F]{1,4}";
|
| 223 |
$validurlpattern .= "(:[0-9A-F]{1,4}){0,2})|((:[0-9A-F]{1,4}){2}::[0-9A-F]{1,4}(:[0-9A-F]{1,4})";
|
| 224 |
$validurlpattern .= "{0,3})|(:[0-9A-F]{1,4}::[0-9A-F]{1,4}(:[0-9A-F]{1,4}){0,4})|(::[0-9A-F]{1,4}";
|
| 225 |
$validurlpattern .= "(:[0-9A-F]{1,4}){0,5})|(:[0-9A-F]{1,4}){7}))|(::[0-9A-F]{1,4}(:[0-9A-F]{1,4}";
|
| 226 |
$validurlpattern .= "){0,6}))|::)|((([0-9A-F]{1,4}(((:[0-9A-F]{1,4}){3}::([0-9A-F]{1,4}){1})";
|
| 227 |
$validurlpattern .= "|((:[0-9A-F]{1,4}){2}::[0-9A-F]{1,4}(:[0-9A-F]{1,4}){0,1})|((:[0-9A-F]{1,4})";
|
| 228 |
$validurlpattern .= "{1}::[0-9A-F]{1,4}(:[0-9A-F]{1,4}){0,2})|(::[0-9A-F]{1,4}(:[0-9A-F]{1,4}";
|
| 229 |
$validurlpattern .= "){0,3})|((:[0-9A-F]{1,4}){0,5})))|([:]{2}[0-9A-F]{1,4}(:[0-9A-F]{1,4}){0,4}))";
|
| 230 |
$validurlpattern .= ":|::)((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{0,2})\.){3}(25[0-5]|2[0-4][0-9]|";
|
| 231 |
$validurlpattern .= "[0-1]?[0-9]{0,2})";
|
| 232 |
$validurlpattern .= "|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org";
|
| 233 |
$validurlpattern .= "|biz|arpa|info|name|pro|aero|coop|museum|us|ca|uk|jp|ru|ua|fr|gr|de|dk|tr|ie";
|
| 234 |
$validurlpattern .= "|it|au|br|cc|ch|cn|es|fi|gr|hk|hu|il|in|kr|mx|my|nl|no|nu|nz|ph|pl";
|
| 235 |
$validurlpattern .= "|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm";
|
| 236 |
$validurlpattern .= "|bn|bo|bs|bt|bv|bw|by|bz|cf|cd|cg|ch|ci|ck|cl|cm|co|cr|cs|cu|cv|cx|cy|cz|dj";
|
| 237 |
$validurlpattern .= "|dm|do|dz|ec|ee|eg|eh|er|et|fj|fk|fm|fo|fx|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gp";
|
| 238 |
$validurlpattern .= "|gq|gs|gt|gu|gw|gy|hm|hn|hr|ht|id|io|iq|ir|is|jm|jo|ke|kg|kh|ki|km|kn|kp|kw";
|
| 239 |
$validurlpattern .= "|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq";
|
| 240 |
$validurlpattern .= "|mr|ms|mt|mu|mv|mw|mz|na|nc|ne|nf|ng|ni|np|nr|nt|om|pa|pe|pf|pg|pk|pm|pn|pr";
|
| 241 |
$validurlpattern .= "|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su";
|
| 242 |
$validurlpattern .= "|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|um|uy|uz|va";
|
| 243 |
$validurlpattern .= "|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zr|zw|eu";
|
| 244 |
$validurlpattern .= "|[a-zA-Z]{2}))(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\:\,\?\'\\\+&%\$#\=~_\-\s@]+))*$/";
|
| 245 |
return preg_match($validurlpattern, $url);
|
| 246 |
}
|
| 247 |
|
| 248 |
// return a link to the server, including protocol
|
| 249 |
function _get_server_url() {
|
| 250 |
if($_SERVER['HTTPS']) {
|
| 251 |
$protocol = "https://";
|
| 252 |
} else $protocol = "http://";
|
| 253 |
return $protocol.$_SERVER['HTTP_HOST'];
|
| 254 |
}
|