$result =''
// Stolen from WP's _deep_replace
function yourls_deep_replace($search, $subject){
$found = true;
while($found) {
$found = false;
foreach( (array) $search as $val ) {
while(strpos($subject, $val) !== false) {
$found = true;
$subject = str_replace($val, '', $subject);
}
}
}
return $subject;
}
// Make sure an integer is a valid integer (PHP's intval() limits to too small numbers)
// TODO FIXME FFS: unused ?
function yourls_sanitize_int($in) {
return ( substr(preg_replace('/[^0-9]/', '', strval($in) ), 0, 20) );
}
// Make sure a integer is safe
// Note: this is not checking for integers, since integers on 32bits system are way too limited
// TODO: find a way to validate as integer
function yourls_intval($in) {
return mysql_real_escape_string($in);
}
// Escape a string
function yourls_escape( $in ) {
return mysql_real_escape_string($in);
}
// Check to see if a given keyword is reserved (ie reserved URL or an existing page)
// Returns bool
function yourls_keyword_is_reserved( $keyword ) {
global $yourls_reserved_URL;
if ( in_array( $keyword, $yourls_reserved_URL)
or file_exists(dirname(dirname(__FILE__))."/pages/$keyword.php")
or is_dir(dirname(dirname(__FILE__))."/$keyword")
)
return true;
return false;
}
// Function: Get IP Address. Returns a DB safe string.
function yourls_get_IP() {
if(!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip_address = $_SERVER['HTTP_CLIENT_IP'];
} else if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if(!empty($_SERVER['REMOTE_ADDR'])) {
$ip_address = $_SERVER['REMOTE_ADDR'];
} else {
$ip_address = '';
}
if(strpos($ip_address, ',') !== false) {
$ip_address = explode(',', $ip_address);
$ip_address = $ip_address[0];
}
$ip_address = yourls_sanitize_ip( $ip_address );
return $ip_address;
}
// Sanitize an IP address
function yourls_sanitize_ip( $ip ) {
return preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip );
}
// Add the "Edit" row
function yourls_table_edit_row( $keyword ) {
global $ydb;
$table = YOURLS_DB_TABLE_URL;
$keyword = yourls_sanitize_string( $keyword );
$id = yourls_string2int( $keyword ); // used as HTML #id
$url = $ydb->get_row("SELECT `url` FROM `$table` WHERE `keyword` = '$keyword';");
$safe_url = stripslashes( $url->url );
$www = YOURLS_SITE;
if( $url ) {
$return = << ';
} ?>
Original URL: Short URL: $www/
RETURN;
} else {
$return = ' ';
}
return $return;
}
// Add a link row
function yourls_table_add_row( $keyword, $url, $ip, $clicks, $timestamp ) {
$keyword = yourls_sanitize_string( $keyword );
$id = yourls_string2int( $keyword ); // used as HTML #id
$date = date( 'M d, Y H:i', $timestamp+( YOURLS_HOURS_OFFSET * 3600) );
$clicks = number_format($clicks, 0, '', '');
$www = YOURLS_SITE;
$shorturl = YOURLS_SITE.'/'.$keyword;
$display_url = yourls_trim_long_string( $url );
$statlink = $shorturl.'+';
return <<Error, URL not found $keyword $display_url $date $ip $clicks
ROW;
}
// Get next id a new link will have if no custom keyword provided
function yourls_get_next_decimal() {
return (int)yourls_get_option( 'next_id' );
}
// Update id for next link with no custom keyword
function yourls_update_next_decimal( $int = '' ) {
$int = ( $int == '' ) ? yourls_get_next_decimal() + 1 : (int)$int ;
return yourls_update_option( 'next_id', $int );
}
// Delete a link in the DB
function yourls_delete_link_by_keyword( $keyword ) {
global $ydb;
$table = YOURLS_DB_TABLE_URL;
$keyword = yourls_sanitize_string( $keyword );
return $ydb->query("DELETE FROM `$table` WHERE `keyword` = '$keyword';");
}
// SQL query to insert a new link in the DB. Needs sanitized data. Returns boolean for success or failure of the inserting
function yourls_insert_link_in_db($url, $keyword) {
global $ydb;
$table = YOURLS_DB_TABLE_URL;
$timestamp = date('Y-m-d H:i:s');
$ip = yourls_get_IP();
$insert = $ydb->query("INSERT INTO `$table` VALUES('$keyword', '$url', '$timestamp', '$ip', 0);");
return (bool)$insert;
}
// Add a new link in the DB, either with custom keyword, or find one
function yourls_add_new_link( $url, $keyword = '' ) {
global $ydb;
if ( !$url || $url == 'http://' || $url == 'https://' ) {
$return['status'] = 'fail';
$return['code'] = 'error:nourl';
$return['message'] = 'Missing URL input';
$return['errorCode'] = '400';
return $return;
}
// Prevent DB flood
$ip = yourls_get_IP();
yourls_check_IP_flood( $ip );
$table = YOURLS_DB_TABLE_URL;
$url = mysql_real_escape_string( yourls_sanitize_url($url) );
$strip_url = stripslashes($url);
$url_exists = $ydb->get_row("SELECT keyword,url FROM `$table` WHERE `url` = '".$strip_url."';");
$return = array();
// New URL : store it -- or: URL exists, but duplicates allowed
if( !$url_exists || yourls_allow_duplicate_longurls() ) {
// Custom keyword provided
if ( $keyword ) {
$keyword = mysql_real_escape_string(yourls_sanitize_string($keyword));
if ( !yourls_keyword_is_free($keyword) ) {
// This shorturl either reserved or taken already
$return['status'] = 'fail';
$return['code'] = 'error:keyword';
$return['message'] = 'Short URL '.$keyword.' already exists in database or is reserved';
} else {
// all clear, store !
yourls_insert_link_in_db($url, $keyword);
$return['url'] = array('keyword' => $keyword, 'url' => $strip_url, 'date' => date('Y-m-d H:i:s'), 'ip' => $ip );
$return['status'] = 'success';
$return['message'] = $strip_url.' added to database';
$return['html'] = yourls_table_add_row( $keyword, $url, $ip, 0, time() );
$return['shorturl'] = YOURLS_SITE .'/'. $keyword;
}
// Create random keyword
} else {
$timestamp = date('Y-m-d H:i:s');
$id = yourls_get_next_decimal();
$ok = false;
do {
$keyword = yourls_int2string( $id );
$free = yourls_keyword_is_free($keyword);
$add_url = @yourls_insert_link_in_db($url, $keyword);
$ok = ($free && $add_url);
if ( $ok === false && $add_url === 1 ) {
// we stored something, but shouldn't have (ie reserved id)
$delete = yourls_delete_link_by_keyword( $keyword );
$return['extra_info'] .= '(deleted '.$keyword.')';
} else {
// everything ok, populate needed vars
$return['url'] = array('keyword' => $keyword, 'url' => $strip_url, 'date' => $timestamp, 'ip' => $ip );
$return['status'] = 'success';
$return['message'] = $strip_url.' added to database';
$return['html'] = yourls_table_add_row( $keyword, $url, $ip, 0, time() );
$return['shorturl'] = YOURLS_SITE .'/'. $keyword;
}
$id++;
} while (!$ok);
@yourls_update_next_decimal($id);
}
} else {
// URL was already stored
$return['status'] = 'fail';
$return['code'] = 'error:url';
$return['message'] = $strip_url.' already exists in database';
$return['shorturl'] = YOURLS_SITE .'/'. $url_exists->keyword;
}
$return['statusCode'] = 200; // regardless of result, this is still a valid request
return $return;
}
// Edit a link
function yourls_edit_link($url, $keyword, $newkeyword='') {
global $ydb;
$table = YOURLS_DB_TABLE_URL;
$url = mysql_real_escape_string(yourls_sanitize_url($url));
$keyword = yourls_sanitize_string( $keyword );
$newkeyword = yourls_sanitize_string( $newkeyword );
$strip_url = stripslashes($url);
$old_url = $ydb->get_var("SELECT `url` FROM `$table` WHERE `keyword` = '$keyword';");
$old_id = $id = yourls_string2int( $keyword );
$new_id = ( $newkeyword == '' ? $old_id : yourls_string2int( $newkeyword ) );
// Check if new URL is not here already
if ($old_url != $url) {
$new_url_already_there = intval($ydb->get_var("SELECT COUNT(keyword) FROM `$table` WHERE `url` = '$strip_url';"));
} else {
$new_url_already_there = false;
}
// Check if the new keyword is not here already
if ( $newkeyword != $keyword ) {
$keyword_is_ok = yourls_keyword_is_free( $newkeyword );
} else {
$keyword_is_ok = true;
}
// All clear, update
if ( ( !$new_url_already_there || yourls_allow_duplicate_longurls() ) && $keyword_is_ok ) {
//$timestamp4screen = date( 'Y M d H:i', time()+( YOURLS_HOURS_OFFSET * 3600) );
//$timestamp4db = date('Y-m-d H:i:s', time()+( YOURLS_HOURS_OFFSET * 3600) );
$update_url = $ydb->query("UPDATE `$table` SET `url` = '$url', `keyword` = '$newkeyword' WHERE `keyword` = '$keyword';");
if( $update_url ) {
$return['url'] = array( 'keyword' => $newkeyword, 'shorturl' => YOURLS_SITE.'/'.$newkeyword, 'url' => $strip_url, 'display_url' => yourls_trim_long_string( $strip_url ), 'new_id' => $new_id );
$return['status'] = 'success';
$return['message'] = 'Link updated in database';
} else {
$return['status'] = 'fail';
$return['message'] = 'Error updating '.$strip_url.' (Short URL: '.$keyword.') to database';
}
// Nope
} else {
$return['status'] = 'fail';
$return['message'] = 'URL or keyword already exists in database';
}
return $return;
}
// Check if keyword id is free (ie not already taken, and not reserved)
function yourls_keyword_is_free( $keyword ) {
global $ydb;
$table = YOURLS_DB_TABLE_URL;
if ( yourls_keyword_is_reserved($keyword) )
return false;
$already_exists = $ydb->get_var("SELECT COUNT(`keyword`) FROM `$table` WHERE `keyword` = '$keyword';");
if ( $already_exists )
return false;
return true;
}
// Display a page
function yourls_page( $page ) {
$include = dirname(dirname(__FILE__))."/pages/$page.php";
if (!file_exists($include)) {
yourls_die("Page '$page' not found", 'Not found', 404);
}
include($include);
die();
}
// Connect to DB
function yourls_db_connect() {
global $ydb;
if (!defined('YOURLS_DB_USER')
or !defined('YOURLS_DB_PASS')
or !defined('YOURLS_DB_NAME')
or !defined('YOURLS_DB_HOST')
or !class_exists('ezSQL_mysql')
) yourls_die ('DB config missigin, or could not find DB class', 'Fatal error', 503);
// Are we standalone or in the WordPress environment?
if ( class_exists('wpdb') ) {
$ydb = new wpdb(YOURLS_DB_USER, YOURLS_DB_PASS, YOURLS_DB_NAME, YOURLS_DB_HOST);
} else {
$ydb = new ezSQL_mysql(YOURLS_DB_USER, YOURLS_DB_PASS, YOURLS_DB_NAME, YOURLS_DB_HOST);
}
if ( $ydb->last_error )
yourls_die( $ydb->last_error, 'Fatal error', 503 );
if ( defined('YOURLS_DEBUG') && YOURLS_DEBUG === true )
$ydb->show_errors = true;
return $ydb;
}
// Return JSON output. Compatible with PHP prior to 5.2
function yourls_json_encode($array) {
if (function_exists('json_encode')) {
return json_encode($array);
} else {
require_once(dirname(__FILE__).'/functions-json.php');
return yourls_array_to_json($array);
}
}
// Return XML output.
function yourls_xml_encode($array) {
require_once(dirname(__FILE__).'/functions-xml.php');
$converter= new yourls_array2xml;
return $converter->array2xml($array);
}
// Return array of all informations associated with keyword. Returns false if keyword not found. Set optional $use_cache to false to force fetching from DB
function yourls_get_keyword_infos( $keyword, $use_cache = true ) {
global $ydb;
$keyword = yourls_sanitize_string( $keyword );
if( isset( $ydb->infos[$keyword] ) && $use_cache == true ) {
return $ydb->infos[$keyword];
}
$table = YOURLS_DB_TABLE_URL;
$infos = $ydb->get_row("SELECT * FROM `$table` WHERE `keyword` = '$keyword'");
if( $infos ) {
$infos = (array)$infos;
$ydb->infos[$keyword] = $infos;
} else {
$ydb->infos[$keyword] = false;
}
return $ydb->infos[$keyword];
}
// Return (string) selected information associated with a keyword. Optional $notfound = string default message if nothing found
function yourls_get_keyword_info( $keyword, $field, $notfound = false ) {
global $ydb;
$keyword = yourls_sanitize_string( $keyword );
$infos = yourls_get_keyword_infos( $keyword );
if ( isset($infos[$field]) && $infos[$field] !== false )
return $infos[$field];
return $notfound;
}
// Return long URL associated with keyword. Optional $notfound = string default message if nothing found
function yourls_get_keyword_longurl( $keyword, $notfound = false ) {
return yourls_get_keyword_info( $keyword, 'url', $notfound );
}
// Return number of clicks on a keyword. Optional $notfound = string default message if nothing found
function yourls_get_keyword_clicks( $keyword, $notfound = false ) {
return yourls_get_keyword_info( $keyword, 'clicks', $notfound );
}
// Return IP that added a keyword. Optional $notfound = string default message if nothing found
function yourls_get_keyword_IP( $keyword, $notfound = false ) {
return yourls_get_keyword_info( $keyword, 'ip', $notfound );
}
// Return timestamp associated with a keyword. Optional $notfound = string default message if nothing found
function yourls_get_keyword_timestamp( $keyword, $notfound = false ) {
return yourls_get_keyword_info( $keyword, 'timestamp', $notfound );
}
// Update click count on a short URL
function yourls_update_clicks( $keyword ) {
global $ydb;
$keyword = yourls_sanitize_string( $keyword );
$table = YOURLS_DB_TABLE_URL;
return $ydb->query("UPDATE `$table` SET `clicks` = clicks + 1 WHERE `keyword` = '$keyword'");
}
// Return array of stats. (string)$filter is 'bottom', 'last', 'rand' or 'top'. (int)$limit is the number of links to return
function yourls_get_links_stats( $filter = 'top', $limit = 10 ) {
global $ydb;
switch( $filter ) {
case 'bottom':
$sort_by = 'clicks';
$sort_order = 'asc';
break;
case 'last':
$sort_by = 'timestamp';
$sort_order = 'desc';
break;
case 'rand':
case 'random':
$sort_by = 'RAND()';
$sort_order = '';
break;
case 'top':
default:
$sort_by = 'clicks';
$sort_order = 'desc';
break;
}
$limit = intval( $limit );
if ( $limit == 0 )
$limit = 1;
$table_url = YOURLS_DB_TABLE_URL;
$results = $ydb->get_results("SELECT * FROM `$table_url` WHERE 1=1 ORDER BY `$sort_by` $sort_order LIMIT 0, $limit;");
$return = array();
$i = 1;
foreach ($results as $res) {
$return['links']['link_'.$i++] = array(
'shorturl' => YOURLS_SITE .'/'. $res->keyword,
'url' => $res->url,
'timestamp' => $res->timestamp,
'ip' => $res->ip,
'clicks' => $res->clicks,
);
}
$return['stats'] = yourls_get_db_stats();
$return['statusCode'] = 200;
return $return;
}
// Return array for API stat requests
function yourls_api_stats( $filter = 'top', $limit = 10 ) {
$return = yourls_get_links_stats( $filter, $limit );
$return['simple'] = 'Need either XML or JSON format for stats';
$return['message'] = 'success';
return $return;
}
// Expand short url to long url
function yourls_api_expand( $shorturl ) {
$keyword = str_replace( YOURLS_SITE . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc'
$keyword = yourls_sanitize_string( $keyword );
$longurl = yourls_get_keyword_longurl( $keyword );
if( $longurl ) {
return array(
'keyword' => $keyword,
'shorturl' => YOURLS_SITE . "/$keyword",
'longurl' => $longurl,
'simple' => $longurl,
'message' => 'success',
'statusCode' => 200,
);
} else {
return array(
'keyword' => $keyword,
'simple' => 'not found',
'message' => 'Error: short URL not found',
'errorCode' => 404,
);
}
}
// Get total number of URLs and sum of clicks. Input: optional "AND WHERE" clause. Returns array
function yourls_get_db_stats( $where = '' ) {
global $ydb;
$table_url = YOURLS_DB_TABLE_URL;
$totals = $ydb->get_row("SELECT COUNT(keyword) as count, SUM(clicks) as sum FROM `$table_url` WHERE 1=1 $where");
return array( 'total_links' => $totals->count, 'total_clicks' => $totals->sum );
}
// Return API result. Dies after this
function yourls_api_output( $mode, $return ) {
if( isset( $return['simple'] ) ) {
$simple = $return['simple'];
unset( $return['simple'] );
}
switch ( $mode ) {
case 'json':
header('Content-type: application/json');
echo yourls_json_encode($return);
break;
case 'xml':
header('Content-type: application/xml');
echo yourls_xml_encode($return);
break;
case 'simple':
default:
if( isset( $simple ) )
echo $simple;
break;
}
die();
}
// Display HTML head and tag
function yourls_html_head( $context = 'index' ) {
// All components to false, except when specified true
$share = $insert = $tablesorter = $tabs = false;
// Load components as needed
switch ( $context ) {
case 'infos':
$share = $tabs = true;
break;
case 'bookmark':
$share = $insert = $tablesorter = true;
break;
case 'index':
$insert = $tablesorter = true;
break;
case 'install':
case 'login':
case 'new':
case 'tools':
case 'upgrade':
break;
}
?>
Your short link', $share_title = '
Pages ():
= 4) {
echo '« First ... ';
}
if($page > 1) {
echo ' « ';
}
for($i = $page - 2 ; $i <= $page +2; $i++) {
if ($i >= 1 && $i <= $total_pages) {
if($i == $page) {
echo "[$i] ";
} else {
echo ''.$i.' ';
}
}
}
if($page < $total_pages) {
echo ' » ';
}
if (($page+2) < $total_pages) {
echo ' ... Last »';
}
?>
Quick Share
' ) {
$text = ( $text ? '"'.$text.'" ' : '' );
$title = ( $title ? "$title " : '' );
$share = htmlspecialchars_decode( $title.$text.$shorturl );
$_share = rawurlencode( $share );
$_url = rawurlencode( $shorturl );
$count = 140 - strlen( $share );
?>
num_queries;
}
// Compat http_build_query for PHP4
if (!function_exists('http_build_query')) {
function http_build_query($data, $prefix=null, $sep=null) {
return yourls_http_build_query($data, $prefix, $sep);
}
}
// from php.net (modified by Mark Jaquith to behave like the native PHP5 function)
function yourls_http_build_query($data, $prefix=null, $sep=null, $key='', $urlencode=true) {
$ret = array();
foreach ( (array) $data as $k => $v ) {
if ( $urlencode)
$k = urlencode($k);
if ( is_int($k) && $prefix != null )
$k = $prefix.$k;
if ( !empty($key) )
$k = $key . '%5B' . $k . '%5D';
if ( $v === NULL )
continue;
elseif ( $v === FALSE )
$v = '0';
if ( is_array($v) || is_object($v) )
array_push($ret,yourls_http_build_query($v, '', $sep, $k, $urlencode));
elseif ( $urlencode )
array_push($ret, $k.'='.urlencode($v));
else
array_push($ret, $k.'='.$v);
}
if ( NULL === $sep )
$sep = ini_get('arg_separator.output');
return implode($sep, $ret);
}
// Returns a sanitized a user agent string. Given what I found on http://www.user-agents.org/ it should be OK.
function yourls_get_user_agent() {
if ( !isset( $_SERVER['HTTP_USER_AGENT'] ) )
return '-';
$ua = strip_tags( html_entity_decode( $_SERVER['HTTP_USER_AGENT'] ));
$ua = preg_replace('![^0-9a-zA-Z\':., /{}\(\)\[\]\+@&\!\?;_\-=~\*\#]!', '', $ua );
return substr( $ua, 0, 254 );
}
// Redirect to another page
function yourls_redirect( $location, $code = 301 ) {
// Anti fool check: cannot redirect to the URL we currently are on
if( preg_replace('!^[^:]+://!', '', $location) != $_SERVER["SERVER_NAME"].$_SERVER['REQUEST_URI'] ) {
yourls_status_header( $code );
header("Location: $location");
die();
}
}
// Set HTTP status header
function yourls_status_header( $code = 200 ) {
if( headers_sent() )
return;
$protocol = $_SERVER["SERVER_PROTOCOL"];
if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
$protocol = 'HTTP/1.0';
$code = intval( $code );
$desc = yourls_get_HTTP_status($code);
@header ("$protocol $code $desc"); // This causes problems on IIS and some FastCGI setups
}
// Redirect to another page using Javascript. Set optional (bool)$dontwait to false to force manual redirection (make sure a message has been read by user)
function yourls_redirect_javascript( $location, $dontwait = true ) {
if( $dontwait ) {
echo <<
$message
"; yourls_html_footer(); die(); } // Check if YOURLS is installed function yourls_is_installed() { static $is_installed = false; if ( $is_installed === false ) { $check_14 = $check_13 = false; global $ydb; if( defined('YOURLS_DB_TABLE_NEXTDEC') ) $check_13 = $ydb->get_var('SELECT next_id FROM '.YOURLS_DB_TABLE_NEXTDEC); $check_14 = yourls_get_option( 'version' ); $is_installed = $check_13 || $check_14; } return $is_installed; }