]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/functions.php
More robust and smarter URL validation before adding to DB. Fixes issue 28.
[Github/YOURLS.git] / includes / functions.php
1 <?php\r
2 /*\r
3  * YOURLS\r
4  * Function library\r
5  */\r
6 \r
7 if (defined('YOURLS_DEBUG') && YOURLS_DEBUG == true) {\r
8         error_reporting(E_ALL);\r
9 } else {\r
10         error_reporting(E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING);\r
11 }\r
12 \r
13 // function to convert an integer (1337) to a string (3jk). Input integer processed as a string to beat PHP's int max value\r
14 function yourls_int2string( $id ) {\r
15         $str = yourls_base2base(trim(strval($id)), 10, YOURLS_URL_CONVERT);\r
16         if (YOURLS_URL_CONVERT <= 37)\r
17                 $str = strtolower($str);\r
18         return $str;\r
19 }\r
20 \r
21 // function to convert a string (3jk) to an integer (1337)\r
22 function yourls_string2int( $str ) {\r
23         if (YOURLS_URL_CONVERT <= 37)\r
24                 $str = strtolower($str);\r
25         return yourls_base2base(trim($str), YOURLS_URL_CONVERT, 10);\r
26 }\r
27 \r
28 // Make sure a link id (site.com/1fv) is valid.\r
29 function yourls_sanitize_string($in) {\r
30         if (YOURLS_URL_CONVERT <= 37)\r
31                 $in = strtolower($in);\r
32         return substr(preg_replace('/[^a-zA-Z0-9]/', '', $in), 0, 12);\r
33 }\r
34 \r
35 // A few sanity checks on the URL\r
36 function yourls_sanitize_url($url) {\r
37         // make sure there's only one 'http://' at the beginning (prevents pasting a URL right after the default 'http://')\r
38         $url = str_replace('http://http://', 'http://', $url);\r
39 \r
40         // make sure there's a protocol, add http:// if not\r
41         if ( !preg_match('!^([a-zA-Z]+://)!', $url ) )\r
42                 $url = 'http://'.$url;\r
43                 \r
44         return yourls_clean_url($url);\r
45 }\r
46 \r
47 // Function to filter all invalid characters from a URL. Stolen from WP's clean_url()\r
48 function yourls_clean_url( $url ) {\r
49         $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);\r
50         $strip = array('%0d', '%0a', '%0D', '%0A');\r
51         $url = yourls_deep_replace($strip, $url);\r
52         $url = str_replace(';//', '://', $url);\r
53         \r
54         return $url;\r
55 }\r
56 \r
57 // Perform a replacement while a string is found, eg $subject = '%0%0%0DDD', $search ='%0D' -> $result =''\r
58 // Stolen from WP's _deep_replace\r
59 function yourls_deep_replace($search, $subject){\r
60         $found = true;\r
61         while($found) {\r
62                 $found = false;\r
63                 foreach( (array) $search as $val ) {\r
64                         while(strpos($subject, $val) !== false) {\r
65                                 $found = true;\r
66                                 $subject = str_replace($val, '', $subject);\r
67                         }\r
68                 }\r
69         }\r
70         \r
71         return $subject;\r
72 }\r
73 \r
74 \r
75 // Make sure an id link is a valid integer (PHP's intval() limits to too small numbers)\r
76 function yourls_sanitize_int($in) {\r
77         return ( substr(preg_replace('/[^0-9]/', '', strval($in) ), 0, 20) );\r
78 }\r
79 \r
80 // Make sure a integer is safe\r
81 // Note: this is not checking for integers, since integers on 32bits system are way too limited\r
82 // TODO: find a way to validate as integer\r
83 function yourls_intval($in) {\r
84         return mysql_real_escape_string($in);\r
85 }\r
86 \r
87 \r
88 // Check to see if a given integer id is reserved (ie reserved URL or an existing page)\r
89 // Returns bool\r
90 function yourls_is_reserved_id($id) {\r
91         global $yourls_reserved_URL;\r
92         $keyword = yourls_int2string( yourls_intval($id) );\r
93         if ( in_array( $keyword, $yourls_reserved_URL)\r
94                 or file_exists(dirname(dirname(__FILE__))."/pages/$keyword.php")\r
95                 or is_dir(dirname(dirname(__FILE__))."$keyword")\r
96         )\r
97                 return true;\r
98         \r
99         return false;\r
100 }\r
101 \r
102 // Function: Get IP Address\r
103 function yourls_get_IP() {\r
104         if(!empty($_SERVER['HTTP_CLIENT_IP'])) {\r
105                 $ip_address = $_SERVER['HTTP_CLIENT_IP'];\r
106         } else if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {\r
107                 $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];\r
108         } else if(!empty($_SERVER['REMOTE_ADDR'])) {\r
109                 $ip_address = $_SERVER['REMOTE_ADDR'];\r
110         } else {\r
111                 $ip_address = '';\r
112         }\r
113         if(strpos($ip_address, ',') !== false) {\r
114                 $ip_address = explode(',', $ip_address);\r
115                 $ip_address = $ip_address[0];\r
116         }\r
117         return $ip_address;\r
118 }\r
119 \r
120 // Add the "Edit" row\r
121 function yourls_table_edit_row($id, $db) {\r
122         $id = yourls_intval($id);\r
123         $table = YOURLS_DB_TABLE_URL;\r
124         $url = $db->get_row("SELECT `url` FROM `$table` WHERE `id` = '$id';");\r
125         $safe_url = stripslashes($url->url);\r
126         $keyword = yourls_int2string($id);\r
127         if($url) {\r
128         $return = <<<RETURN\r
129 <tr id="edit-$id" class="edit-row"><td colspan="6">Edit: <strong>original URL</strong>:<input type="text" id="edit-url-$id" name="edit-url-$id" value="$safe_url" class="text" size="100" /><strong>short URL</strong>:<input type="text" id="edit-id-$id" name="edit-id-$id" value="$keyword" class="text" size="10" /></td><td colspan="1"><input type="button" id="edit-submit-$id" name="edit-submit-$id" value="Save" title="Save new values" class="button" onclick="edit_save('$id');" />&nbsp;<input type="button" id="edit-close-$id" name="edit-close-$id" value="X" title="Cancel editing" class="button" onclick="hide_edit('$id');" /></td></tr>\r
130 RETURN;\r
131         } else {\r
132                 $return = '<tr><td colspan="7">Invalid URL ID</td></tr>';\r
133         }\r
134         \r
135         return $return;\r
136 }\r
137 \r
138 // Add a link row\r
139 function yourls_table_add_row( $id, $keyword, $url, $ip, $clicks, $timestamp ) {\r
140         $date = date( 'M d, Y H:i', $timestamp+( YOURLS_HOURS_OFFSET * 3600) );\r
141         $clicks = number_format($clicks);\r
142         $www = YOURLS_SITE;\r
143         \r
144         return <<<ROW\r
145 <tr id="id-$id"><td id="keyword-$id">$keyword</td><td id="url-$id"><a href="$url" title="$url">$url</a></td><td id="shorturl-$id"><a href="$www/$keyword" title="$www/$keyword">$www/$keyword</a></td><td id="timestamp-$id">$date</td><td>$ip</td>             <td>$clicks</td><td class="actions"><input type="button" id="edit-button-$id" name="edit-button" value="Edit" class="button" onclick="edit('$id');" />&nbsp;<input type="button" id="delete-button-$id" name="delete-button" value="Del" class="button" onclick="remove('$id');" /></td></tr>\r
146 ROW;\r
147 }\r
148 \r
149 // Get next id a new link will have if no custom keyword provided\r
150 function yourls_get_next_decimal($db) {\r
151         $table = YOURLS_DB_TABLE_NEXTDEC;\r
152         return $db->get_var("SELECT `next_id` FROM `$table`");\r
153 }\r
154 \r
155 // Update id for next link with no custom keyword\r
156 function yourls_update_next_decimal($int = '', $db) {\r
157         $int = ( $int == '' ) ? 'next+1' : (int)$int ;\r
158         $table = YOURLS_DB_TABLE_NEXTDEC;\r
159         return $db->query("UPDATE `$table` set next_id=$int");\r
160 }\r
161 \r
162 // Delete a link in the DB\r
163 function yourls_delete_link_by_id($id, $db) {\r
164         $table = YOURLS_DB_TABLE_URL;\r
165         $id = yourls_intval($id);\r
166         return $db->query("DELETE FROM `$table` WHERE `id` = $id;");\r
167 }\r
168 \r
169 // SQL query to insert a new link in the DB. Needs sanitized data. Returns boolean for success or failure of the inserting\r
170 function yourls_insert_link_in_db($url, $id, $db) {\r
171         $table = YOURLS_DB_TABLE_URL;\r
172         $timestamp = date('Y-m-d H:i:s');\r
173         $ip = yourls_get_IP();\r
174         return $db->query("INSERT INTO `$table` VALUES($id, '$url', '$timestamp', '$ip', 0);");\r
175 }\r
176 \r
177 // Add a new link in the DB, either with custom keyword, or find one\r
178 function yourls_add_new_link($url, $keyword = '', $db) {\r
179         if ( !$url || $url == 'http://' || $url == 'https://' ) {\r
180                 $return['status'] = 'fail';\r
181                 $return['code'] = 'error:nourl';\r
182                 $return['message'] = 'Missing URL input';\r
183                 return $return;\r
184         }\r
185 \r
186         $table = YOURLS_DB_TABLE_URL;\r
187         $url = mysql_real_escape_string(yourls_sanitize_url($url));\r
188         $strip_url = stripslashes($url);\r
189         $url_exists = $db->get_row("SELECT id,url FROM `$table` WHERE `url` = '".$strip_url."';");\r
190         $ip = yourls_get_IP();\r
191         $return = array();\r
192 \r
193         // New URL : store it\r
194         if( !$url_exists ) {\r
195 \r
196                 // Custom keyword provided\r
197                 if ($keyword) {\r
198                         $keyword = mysql_real_escape_string(yourls_sanitize_string($keyword));\r
199                         if (!yourls_keyword_is_free($keyword, $db)) {\r
200                                 // This id either reserved or taken already\r
201                                 $return['status'] = 'fail';\r
202                                 $return['code'] = 'error:keyword';\r
203                                 $return['message'] = 'URL id '.$keyword.' already exists in database or is reserved';\r
204                         } else {\r
205                                 // all clear, store !\r
206                                 $id = yourls_string2int($keyword);\r
207                                 yourls_insert_link_in_db($url, $id, $db);\r
208                                 $return['url'] = array('id' => $id, 'keyword' => $keyword, 'url' => $strip_url, 'date' => date('Y-m-d H:i:s'), 'ip' => yourls_get_IP() );\r
209                                 $return['status'] = 'success';\r
210                                 $return['message'] = $strip_url.' added to database';\r
211                                 $return['html'] = yourls_table_add_row( $id, $keyword, $url, yourls_get_IP(), 0, time() );\r
212                                 $return['shorturl'] = YOURLS_SITE .'/'. $keyword;\r
213                         }\r
214 \r
215                 // Create random keyword        \r
216                 } else {\r
217                         $timestamp = date('Y-m-d H:i:s');\r
218                         $id = yourls_get_next_decimal($db);\r
219                         do {\r
220                                 $add_url = @yourls_insert_link_in_db($url, $id, $db);\r
221                                 $free = !yourls_is_reserved_id( $id );\r
222                                 $ok = ($free && $add_url);\r
223                                 if ( $ok === false && $add_url === 1 ) {\r
224                                         // we stored something, but shouldn't have (ie reserved id)\r
225                                         $delete = yourls_delete_link_by_id( $id, $db );\r
226                                         $return['extra_info'] .= '(deleted '.$id.')';\r
227                                 } else {\r
228                                         // everything ok, populate needed vars\r
229                                         $keyword = yourls_int2string($id);\r
230                                         $return['url'] = array('id' => $id, 'keyword' => $keyword, 'url' => $strip_url, 'date' => $timestamp, 'ip' => $ip);\r
231                                         $return['status'] = 'success';\r
232                                         $return['message'] = $strip_url.' added to database';\r
233                                         $return['html'] = yourls_table_add_row( $id, $keyword, $url, $ip, 0, time() );\r
234                                         $return['shorturl'] = YOURLS_SITE .'/'. $keyword;\r
235                                 }\r
236                                 $id++;\r
237                         } while (!$ok);\r
238                         @yourls_update_next_decimal($id, $db);\r
239                 }\r
240         } else {\r
241                 // URL was already stored\r
242                 $return['status'] = 'fail';\r
243                 $return['code'] = 'error:url';\r
244                 $return['message'] = $strip_url.' already exists in database';\r
245                 $return['shorturl'] = YOURLS_SITE .'/'. yourls_int2string( $url_exists->id );\r
246         }\r
247 \r
248         return $return;\r
249 }\r
250 \r
251 \r
252 // Edit a link\r
253 function yourls_edit_link($url, $id, $keyword='', $db) {\r
254         $table = YOURLS_DB_TABLE_URL;\r
255         $url = mysql_real_escape_string(yourls_sanitize_url($url));\r
256         $id = yourls_intval($id);\r
257         $strip_url = stripslashes($url);\r
258         $old_url = $db->get_var("SELECT `url` FROM `$table` WHERE `id` = '".$id."';");\r
259         \r
260         \r
261         // Check if new URL is not here already\r
262         if ($old_url != $url) {\r
263                 $url_exists = intval($db->get_var("SELECT id FROM `$table` WHERE `url` = '".$strip_url."';"));\r
264         } else {\r
265                 $url_exists = false;\r
266         }\r
267         \r
268         // Check if the new keyword is not here already\r
269         $newid = ( $keyword ? yourls_string2int($keyword) : $id );\r
270         if ($newid != $id) {\r
271                 $id_exists = intval($db->get_var("SELECT id FROM `$table` WHERE `id` = '".$newid."';"));\r
272                 $id_free = yourls_keyword_is_free($keyword, $db);\r
273                 $id_is_ok = ($id_exists == 0) && $id_free;\r
274         } else {\r
275                 $id_is_ok = true;\r
276         }\r
277         \r
278         // All clear, update\r
279         if($url_exists == 0 && $id_is_ok ) {\r
280                 $timestamp4screen = date( 'Y M d H:i', time()+( yourls_HOURS_OFFSET * 3600) );\r
281                 $timestamp4db = date('Y-m-d H:i:s', time()+( yourls_HOURS_OFFSET * 3600) );\r
282                 $update_url = $db->query("UPDATE `$table` SET `url` = '$url', `timestamp` = '$timestamp4db', `id` = '$newid' WHERE `id` = $id;");\r
283                 if($update_url) {\r
284                         $return['url'] = array('id' => $newid, 'keyword' => $keyword, 'shorturl' => YOURLS_SITE.'/'.$keyword, 'url' => $strip_url, 'date' => $timestamp4screen);\r
285                         $return['status'] = 'success';\r
286                         $return['message'] = 'Link updated in database';\r
287                 } else {\r
288                         $return['status'] = 'fail';\r
289                         $return['message'] = 'Error updating '.$strip_url.' (ID: '.$id.') to database';\r
290                 }\r
291         \r
292         // Nope\r
293         } else {\r
294                 $return['status'] = 'fail';\r
295                 $return['message'] = 'URL or keyword already exists in database';\r
296         }\r
297         \r
298         return $return;\r
299 }\r
300 \r
301 \r
302 // Check if keyword id is free (ie not already taken, and not reserved)\r
303 function yourls_keyword_is_free($str, $db) {\r
304         $table = YOURLS_DB_TABLE_URL;\r
305         $id = yourls_string2int($str);\r
306         if ( yourls_is_reserved_id($id) )\r
307                 return false;\r
308                 \r
309         $already_exists = intval($db->get_var("SELECT `id` FROM `$table` WHERE `id` = '".$id."';"));\r
310         if ( $already_exists )\r
311                 return false;\r
312 \r
313         return true;\r
314 }\r
315 \r
316 \r
317 // Display a page\r
318 function yourls_page($page) {\r
319         $include = dirname(dirname(__FILE__))."/pages/$page.php";\r
320         if (!file_exists($include)) {\r
321                 die("Page '$page' not found");\r
322         }\r
323         include($include);\r
324         die();  \r
325 }\r
326 \r
327 // Connect to DB\r
328 function yourls_db_connect() {\r
329         if (!defined('YOURLS_DB_USER')\r
330                 or !defined('YOURLS_DB_PASS')\r
331                 or !defined('YOURLS_DB_NAME')\r
332                 or !defined('YOURLS_DB_HOST')\r
333                 or !class_exists('ezSQL_mysql')\r
334         ) die ('DB config/class missing');\r
335         \r
336         $db =  new ezSQL_mysql(YOURLS_DB_USER, YOURLS_DB_PASS, YOURLS_DB_NAME, YOURLS_DB_HOST);\r
337         if ( $db->last_error )\r
338                 die( $db->last_error );\r
339         \r
340         return $db;\r
341 }\r
342 \r
343 // Return JSON output. Compatible with PHP prior to 5.2\r
344 function yourls_json_encode($array) {\r
345         if (function_exists('json_encode')) {\r
346                 return json_encode($array);\r
347         } else {\r
348                 require_once(dirname(__FILE__).'/functions-json.php');\r
349                 return yourls_array_to_json($array);\r
350         }\r
351 }\r
352 \r
353 // Return XML output.\r
354 function yourls_xml_encode($array) {\r
355         require_once(dirname(__FILE__).'/functions-xml.php');\r
356         $converter= new yourls_array2xml;\r
357         return $converter->array2xml($array);\r
358 }\r
359 \r
360 // Return array for API stat requests\r
361 function yourls_api_stats( $filter, $limit, $db ) {\r
362         switch( $filter ) {\r
363                 case 'bottom':\r
364                         $sort_by = 'clicks';\r
365                         $sort_order = 'asc';\r
366                         break;\r
367                 case 'last':\r
368                         $sort_by = 'timestamp';\r
369                         $sort_order = 'desc';\r
370                         break;\r
371                 case 'top':\r
372                 default:\r
373                         $sort_by = 'clicks';\r
374                         $sort_order = 'desc';\r
375                         break;\r
376         }\r
377         \r
378         $limit = intval( $limit );\r
379         $table_url = YOURLS_DB_TABLE_URL;\r
380         $results = $db->get_results("SELECT * FROM $table_url WHERE 1=1 ORDER BY $sort_by $sort_order LIMIT 0, $limit;");\r
381 \r
382         $return = array();\r
383         $i = 1;\r
384 \r
385         foreach ($results as $res) {\r
386                 $return['links']['link_'.$i++] = array(\r
387                         'shorturl' => YOURLS_SITE .'/'. yourls_int2string($res->id),\r
388                         'url' => $res->url,\r
389                         'timestamp' => $res->timestamp,\r
390                         'ip' => $res->ip,\r
391                         'clicks' => $res->clicks\r
392                 );\r
393         }\r
394 \r
395         $totals = $db->get_row("SELECT COUNT(id) as c, SUM(clicks) as s FROM $table_url WHERE 1=1");\r
396         $return['stats'] = array( 'total_links' => $totals->c, 'total_clicks' => $totals->s );\r
397 \r
398         return $return;\r
399 }\r
400 \r
401 // Return API result. Dies after this\r
402 function yourls_api_output( $mode, $return ) {\r
403         switch ( $mode ) {\r
404                 case 'json':\r
405                         header('Content-type: application/json');\r
406                         echo yourls_json_encode($return);\r
407                         break;\r
408                 \r
409                 case 'xml':\r
410                         header('Content-type: application/xml');\r
411                         echo yourls_xml_encode($return);\r
412                         break;\r
413                         \r
414                 case 'simple':\r
415                 default:\r
416                         echo $return['shorturl'];\r
417                         break;\r
418         }\r
419         die();\r
420 }\r
421 \r
422 // Display HTML head and <body> tag\r
423 function yourls_html_head( $context = 'index' ) {\r
424         // Load components as needed\r
425         switch ( $context ) {\r
426                 case 'bookmark':\r
427                         $share = true;\r
428                         $insert = true;\r
429                         $tablesorter = true;\r
430                         break;\r
431                         \r
432                 case 'index':\r
433                         $share = false;\r
434                         $insert = true;\r
435                         $tablesorter = true;\r
436                         break;\r
437                 \r
438                 case 'install':\r
439                 case 'login':\r
440                 case 'new':\r
441                 case 'tools':\r
442                         $share = false;\r
443                         $insert = false;\r
444                         $tablesorter = false;\r
445                         break;\r
446         }\r
447         \r
448         ?>\r
449 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
450 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r
451 <head>\r
452         <title>YOURLS &raquo; Your Own URL Shortener | <?php echo YOURLS_SITE; ?></title>\r
453         <link rel="icon" type="image/gif" href="<?php echo YOURLS_SITE; ?>/images/favicon.gif" />\r
454         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
455         <meta name="copyright" content="Copyright &copy; 2008-<?php echo date('Y'); ?> YOURS" />\r
456         <meta name="author" content="Ozh Richard, Lester Chan" />\r
457         <meta name="description" content="Insert URL &laquo; YOURLS &raquo; Your Own URL Shortener' | <?php echo YOURLS_SITE; ?>" />\r
458         <script src="<?php echo YOURLS_SITE; ?>/js/jquery-1.3.2.min.js" type="text/javascript"></script>\r
459         <link rel="stylesheet" href="<?php echo YOURLS_SITE; ?>/css/style.css" type="text/css" media="screen" />\r
460         <?php if ($tablesorter) { ?>\r
461                 <link rel="stylesheet" href="<?php echo YOURLS_SITE; ?>/css/tablesorter.css" type="text/css" media="screen" />\r
462                 <script src="<?php echo YOURLS_SITE; ?>/js/jquery.tablesorter.min.js" type="text/javascript"></script>\r
463         <?php } ?>\r
464         <?php if ($insert) { ?>\r
465                 <script src="<?php echo YOURLS_SITE; ?>/js/insert.js" type="text/javascript"></script>\r
466         <?php } ?>\r
467         <?php if ($share) { ?>\r
468                 <script src="<?php echo YOURLS_SITE; ?>/js/share.js" type="text/javascript"></script>\r
469         <?php } ?>\r
470 </head>\r
471 <body class="<?php echo $context; ?>">\r
472         <?php\r
473 }\r
474 \r
475 // Display HTML footer (including closing body & html tags)\r
476 function yourls_html_footer() {\r
477         ?>\r
478         <div id="footer"><p>Powered by <a href="http://yourls.org/" title="YOURLS">YOURLS</a> v<?php echo YOURLS_VERSION; ?></p></div>  \r
479         </body>\r
480         </html>\r
481         <?php\r
482 }\r
483 \r
484 // Display "Add new URL" box\r
485 function yourls_html_addnew( $url = '', $keyword = '' ) {\r
486         $url = $url ? $url : 'http://';\r
487         ?>\r
488         <div id="new_url">\r
489                 <div>\r
490                         <form id="new_url_form" action="" method="get">\r
491                                 <strong>Enter the URL</strong>:<input type="text" id="add-url" name="url" value="<?php echo $url; ?>" class="text" size="90" />\r
492                                 Optional: <strong>Custom short URL</strong>:<input type="text" id="add-keyword" name="keyword" value="<?php echo $keyword; ?>" maxlength="12" class="text" size="8" />\r
493                                 <input type="button" id="add-button" name="add-button" value="Shorten The URL" class="button" onclick="add();" />\r
494                         </form>\r
495                         <div id="feedback" style="display:none"></div>\r
496                 </div>\r
497         </div>\r
498         <?php\r
499 }\r
500 \r
501 // Display main table's footer\r
502 function yourls_html_tfooter( $params = array() ) {\r
503         extract( $params ); // extract $search_text, $page, $search_in_sql ...\r
504 \r
505         ?>\r
506         <tfoot>\r
507                 <tr>\r
508                         <th colspan="4" style="text-align: left;">\r
509                                 <form action="" method="get">\r
510                                         <div>\r
511                                                 <div style="float:right;">\r
512                                                         <input type="submit" id="submit-sort" value="Filter" class="button primary" />\r
513                                                         &nbsp;\r
514                                                         <input type="button" id="submit-clear-filter" value="Clear Filter" class="button" onclick="window.parent.location.href = 'index.php'" />\r
515                                                 </div>\r
516 \r
517                                                 Search&nbsp;for&nbsp;\r
518                                                 <input type="text" name="s_search" class="text" size="20" value="<?php echo $search_text; ?>" />\r
519                                                 &nbsp;in&nbsp;\r
520                                                 <select name="s_in" size="1">\r
521                                                         <!-- <option value="id"<?php if($search_in_sql == 'id') { echo ' selected="selected"'; } ?>>ID</option> -->\r
522                                                         <option value="url"<?php if($search_in_sql == 'url') { echo ' selected="selected"'; } ?>>URL</option>\r
523                                                         <option value="ip"<?php if($search_in_sql == 'ip') { echo ' selected="selected"'; } ?>>IP</option>\r
524                                                 </select>\r
525                                                 &ndash;&nbsp;Order&nbsp;by&nbsp;\r
526                                                 <select name="s_by" size="1">\r
527                                                         <option value="id"<?php if($sort_by_sql == 'id') { echo ' selected="selected"'; } ?>>ID</option>\r
528                                                         <option value="url"<?php if($sort_by_sql == 'url') { echo ' selected="selected"'; } ?>>URL</option>\r
529                                                         <option value="timestamp"<?php if($sort_by_sql == 'timestamp') { echo ' selected="selected"'; } ?>>Date</option>\r
530                                                         <option value="ip"<?php if($sort_by_sql == 'ip') { echo ' selected="selected"'; } ?>>IP</option>\r
531                                                         <option value="clicks"<?php if($sort_by_sql == 'clicks') { echo ' selected="selected"'; } ?>>Clicks</option>\r
532                                                 </select>\r
533                                                 <select name="s_order" size="1">\r
534                                                         <option value="asc"<?php if($sort_order_sql == 'asc') { echo ' selected="selected"'; } ?>>Ascending</option>\r
535                                                         <option value="desc"<?php if($sort_order_sql == 'desc') { echo ' selected="selected"'; } ?>>Descending</option>\r
536                                                 </select>\r
537                                                 &ndash;&nbsp;Show&nbsp;\r
538                                                 <input type="text" name="perpage" class="text" size="2" value="<?php echo $perpage; ?>" />&nbsp;rows<br/>\r
539                                                 \r
540                                                 Show links with\r
541                                                 <select name="link_filter" size="1">\r
542                                                         <option value="more"<?php if($link_filter === 'more') { echo ' selected="selected"'; } ?>>more</option>\r
543                                                         <option value="less"<?php if($link_filter === 'less') { echo ' selected="selected"'; } ?>>less</option>\r
544                                                 </select>\r
545                                                 than\r
546                                                 <input type="text" name="link_limit" class="text" size="4" value="<?php echo $link_limit; ?>" />clicks\r
547 \r
548                                                 \r
549                                         </div>\r
550                                 </form>\r
551                         </th>\r
552                         <th colspan="3" style="text-align: right;">\r
553                                 Pages (<?php echo $total_pages; ?>):\r
554                                 <?php\r
555                                         if ($page >= 4) {\r
556                                                 echo '<b><a href="'.$base_page.'?s_by='.$sort_by_sql.'&amp;s_order='.$sort_order_sql.$search_url.'&amp;perpage='.$perpage.'&amp;page=1'.'" title="Go to First Page">&laquo; First</a></b> ... ';\r
557                                         }\r
558                                         if($page > 1) {\r
559                                                 echo ' <b><a href="'.$base_page.'?s_by='.$sort_by_sql.'&amp;s_order='.$sort_order_sql.$search_url.'&amp;perpage='.$perpage.'&amp;page='.($page-1).'" title="&laquo; Go to Page '.($page-1).'">&laquo;</a></b> ';\r
560                                         }\r
561                                         for($i = $page - 2 ; $i  <= $page +2; $i++) {\r
562                                                 if ($i >= 1 && $i <= $total_pages) {\r
563                                                         if($i == $page) {\r
564                                                                 echo "<strong>[$i]</strong> ";\r
565                                                         } else {\r
566                                                                 echo '<a href="'.$base_page.'?s_by='.$sort_by_sql.'&amp;s_order='.$sort_order_sql.$search_url.'&amp;perpage='.$perpage.'&amp;page='.($i).'" title="Page '.$i.'">'.$i.'</a> ';\r
567                                                         }\r
568                                                 }\r
569                                         }\r
570                                         if($page < $total_pages) {\r
571                                                 echo ' <b><a href="'.$base_page.'?s_by='.$sort_by_sql.'&amp;s_order='.$sort_order_sql.$search_url.'&amp;perpage='.$perpage.'&amp;page='.($page+1).'" title="Go to Page '.($page+1).' &raquo;">&raquo;</a></b> ';\r
572                                         }\r
573                                         if (($page+2) < $total_pages) {\r
574                                                 echo ' ... <b><a href="'.$base_page.'?s_by='.$sort_by_sql.'&amp;s_order='.$sort_order_sql.$search_url.'&amp;perpage='.$perpage.'&amp;page='.($total_pages).'" title="Go to Last Page">Last &raquo;</a></b>';\r
575                                         }\r
576                                 ?>\r
577                         </th>\r
578                 </tr>\r
579         </tfoot>\r
580         <?php\r
581 }\r
582 \r
583 function yourls_share_box( $longurl, $shorturl, $title='', $text='' ) {\r
584         $text = ( $text ? '"'.$text.'" ' : '' );\r
585         $title = ( $title ? "$title " : '' );\r
586         $share = $title.$text.$shorturl ;\r
587         $_share = rawurlencode( $share );\r
588         $_url = rawurlencode( $shorturl );\r
589         $count = 140 - strlen( $share );\r
590         ?>\r
591         \r
592         <div id="shareboxes">\r
593 \r
594                 <div id="copybox" class="share">\r
595                 <h2>Your short link</h2>\r
596                         <p><input id="copylink" class="text" size="40" value="<?php echo $shorturl; ?>" /></p>\r
597                         <p><small>Original link: <a href="<?php echo $longurl; ?>"><?php echo $longurl; ?></a></small></p>\r
598                 </div>\r
599 \r
600                 <div id="sharebox" class="share">\r
601                         <h2>Quick Share</h2>\r
602                         <div id="tweet">\r
603                                 <span id="charcount"><?php echo $count; ?></span>\r
604                                 <textarea id="tweet_body"><?php echo $share; ?></textarea>\r
605                         </div>\r
606                         <p id="share_links">Share with \r
607                                 <a id="share_tw" href="http://twitter.com/home?status=<?php echo $_share; ?>" title="Tweet this!" onclick="share('tw');return false">Twitter</a>\r
608                                 <a id="share_fb" href="http://www.facebook.com/share.php?u=<?php echo $_url; ?>" title="Share on Facebook" onclick="share('fb');return false;">Facebook</a>\r
609                                 <a id="share_ff" href="http://friendfeed.com/share/bookmarklet/frame#title=<?php echo $_share; ?>" title="Share on Friendfeed" onclick="javascript:share('ff');return false;">FriendFeed</a>\r
610                         </p>\r
611                         </div>\r
612                 </div>\r
613         \r
614         </div>\r
615         \r
616         <?php\r
617 }\r